-
Posts
149 -
Joined
-
Last visited
-
Days Won
17
Haru,, last won the day on November 17
Haru,, had the most liked content!
Reputation
157 BenefactorProfile Information
-
Alias
Haru
-
Gender
Non-binary
Contact Methods
-
Discord
kay.haru
Recent Profile Visitors
8191 profile views
-
carnivine. lumineon. elemonkeys. they're just goofy guys and I love them. 1. Eizen. 2. There are tons of YT videos about it. I myself haven't even played any of V13.5 haha 3. Eizen. 4. He would be a-
-
S.S. Oceana. very.
-
p.s.s. reborn modding tutorial will be updated soonish
-
i had a joke for the title and forgot it because i already wrote this once hey majors. turn on your lo-fi and kick back cuz we got another coding post after a while. saves yeah so saves were brutal. i actually changed these a while ago but we kinda never spoke about it? those file sizes were awful. especially once we figured out we were saving a lot of map data to the save. like. too much that includes the current map, any neighboring maps, and connected maps, the last like 2 maps you were on, and a bunch of other nonsense. i took that out and we got the nicer numbers you see: ain't that neat. DOH. data object hash. doh. the new pbs files. last time you heard about these they were very in progress. the astute among you might notice rejuv and deso had these. the even more astute of you will realize that the community release has even more changes the even mostest astute of you will realize i'm not cass. hi. different code sorceress here. sup. anyway. we've cleaned up a lot things here and there with the doh files. and i made a lot more changes to the mon doh. you're welcome modders. i'm to blame there but you'll come around when you see them: megas are now form specific. no more hard coded them in the mega code. also. evolutions also now look cleaner. and function better. now they're explained! because i really hated long arrays that don't really explain anything. and also forms. while this is rejuv code, you can now like. add form evolutions. real easily. randomizer yeaaah!! that's the thing i do! so if you read the patch notes you'll see a lot has changed. i did the thing again where i rewrote it from scratch haha ha. i'm not really gonna talk about those changes. i'm gonna talk about the stuff that i have planned and some changes i really like there was this thing where the randomizer didn't work a lot. and couldn't be tested reliably. so i changed it. this is a really cool thing. it lets me read info from your save file, load up the random class for your save, and regenerate your entire data files, using a settings seed if this sounds familiar that's because the regular ol' randomizer for the main games does a similar system. pretty hot right? it gets better. you know that whole random thing. how it changes things. you can read those changes now. that's what i'm talking about. ain't that cool. neat. quirky, or even cool. one last thing fun tool for devs color your console output. very nice. very cool. yeah. that's it for this wednesday. p.s. we did not fire her
- 4 comments
-
- 24
-
jadeemporer started following Haru,,
-
Afro Artorius started following Haru,,
-
Now that the word "debug" is no longer being prohibited in the Discord server, I figure it's high time I release a super trimmed debug mod that will appease the masses and stop them from bricking their saves. This is a GBA/DS cheat code style mod, with a plethora of features accessed just by hitting the H button by default. All the keybinds are changeable, but only through modifying the mod file itself at the current date. Features include: Download (You must be signed in!): HMD - Cheat Mode.rb This mod should also work with Desolation, with minor adjustments, namely the outfit picker being tailored explicitly at Rejuv at the moment.
-
Miscellaneous Info Here I'll explain a little more on how hashes work and some other features that I'll add to later down the line if I can think of anything. Hashes Hashes are just a super fancy array in essence. They're definitely not a replacement for arrays, as each have their own use, but they are much better for storing large quantities of data as they have keys that point to data rather than simple integers. An example of this would be your hash containing every bit of Pokemon data. Sure, some are fine with remembering all 900+ dex numbers and know that number 492 is Shaymin and 156 is Quilava. But many aren't! I wish there was way to tell the data that I want Quilava data and it gives us Quilava data instead of having to tell it "Give me data entry 156!" That's where hashes come from. They're broken down into two parts: a key and a value. The key can be any value of integer, string, symbol, or even user defined class. However that class must have implemented the hash and eql? functions. The value can be any syntactically correct value: variables, hashes, objects, integers, strings, booleans, etc. If you're trying to create storage for a few values it might be better to use an array as they use less space than a hash. However hashes are much more readable than arrays for bigger cases. Aliasing Aliasing is another very powerful tool in Ruby. It's best to think of it along the lines of overloading a method. Its main use though is hijacking a method to add code before or after the method would usually end. We can set up an alias in two different ways: alias new_name old_method This one is used outside of a class or module for generic methods. An example of such is as follows: def dothis print "I did this" end dothis # Output: I did this alias didthat dothis def dothis didthat print " with aliasing" end dothis # Output: I did this with aliasing The most immediately relevant connection to the games I can make is our achievement system. They all alias various methods to have them process normally, then make changes to achievements in the same method. An example of it running code before hand is a quick little randomizer I had written up on Rejuv V13.5's release: class PokeBattle_Pokemon alias __core_init initialize def initialize(*args) args[0] = $cache.pkmn.keys[rand($cache.pkmn.length)-1] __core_init(*args) end end This will override the initialize method, change the species being passed, and then continue as normal. The other method of aliasing is for modules: module The def self.output puts "Output 1" end self.singleton_class.send(:alias_method, :output1, :output) def self.output puts "Output 2" end end The.output1 The.output # Output: Output 1 # Output 2 Modules work a little differently than classes, so any public methods like these must use the send method to alias them. As shown above, it is not required to used the old method in the new definition and you can even use the old method any time you like, not contained to the class/module you're modifying through alias. Where this gets super handy is for making even more modular mods. Mod authors don't need to combine methods to make a "Compatibility Patch" and instead just need to work around each others methods. The general naming syntax used from Essentials and thus adopted by us is __core_methodName. You'll have seen in some of my later Reborn/Rejuv mods for the last version that I had used __hmd_methodName. In reality it doesn't really matter what you use. Parameters You'll notice above I used a weird parameter for the method signature. *args. To explain this, we'll need to break down method parameters a little bit more. Method parameters will take any value on a 1 to 1 basis, with defined names for each value. But some times, you don't know how many arguments a user will input. That's where we use *args, also known as a splat operator. A splat operator essentially transforms an array into arguments matching the parameters of the method, provided it does not go past the amount of parameters defined. args is just a regular array without the splat operator as well, meaning you can modify it as you would a regular array. To reuse in an aliased method you must reinclude the splat operator. Parameters throughout our code also make use of default values, for when the user does not pass an argument. An easy example of this is our method: def Kernel.pbItemBall(item,quantity=1,pural=nil); ...; end This means our method is expecting anywhere from 1 to 3 arguments. If we give 0, then it will break, if we give 4, then it will break, If we only give the first parameter, then the method will default quantity to 1 and plural to nil. There's also another way of adding in optional parameters, which was added in Ruby 2.0 (original Essentials runs on Ruby 1.8.1): def myMethod(optional: false) puts optional end myMethod # Ouput: false myMethod(true) # Output: true This is more in line with JSON object notation, which you may be more familiar with.
-
Defining a Boss Bosses are the capstone of our work on Rejuvenation. They're defined in BossInfo.rb and compiled by compileBosses. Once again, like :trainereffects from Trainers above, they are already heavily detailed inside the first boss template, so I will not be explaining them here. I've made a custom boss that will make a little more sense once we get through our custom shield break mechanic. After that you can compile. You'll see a new key there in the break effects, :paralyzePlayer. Let's go ahead an code that in. For our purposes, we'll be looking for the file PokemonBossBattle.rb, and the method pbShieldEffects. To avoid clashing with anything else, we'll be adding our new effect after any stat changes but before any :CustomMethod handling. Quickly, since custom methods aren't explained, you can write some code and throw it in a string, then our break effect handling will run that code. It's a very powerful tool and used for one of our....mechanics. You'll see if you look a little into it but we recommend not doing that! Anyway, Time for our code: This will look through every active battler, check if it can paralyze, check if its your Pokemon, then paralyze them. Then it will iterate through your party and attempt to paralyze those as well. You'll also need to be able to fight these bosses. There's actually two different ways of doing so: through a wild battle and through a trainer. For a wild battle you simply need to call the boss name through the regular call like so: pbWildBattle(:BOSSZAPDOS,1) The level (the number there) does not matter as everything about the Pokemon will be pulled from the boss data. This applies to trainers too. In place of a Pokemon you can simply add in the :boss key where the value is the name of the boss. I strongly recommend putting in basic information there for clarity's sake, though. After that you'd make a call to battle a trainer and it would send out the boss all the same.
-
Defining a Trainer Trainers are the most complicated of the DOH, excluding bosses, while also being the easiest to create. Trainer definitions can be found in trainertext.rb. Trainers are defined as an array of hashes, where each hash has 6 components: :teamid - An array of the trainer name, class, and identifier for matching names/classes. :items - An array of items the trainer has access to in battle :ace - A string displayed in battle when the trainer sends out their last Pokemon :defeat - A string displayed at the end of battle when the trainer is defeated :mons - An array of hashes containing data for each Pokemon. Attributes such as species, level, ability, item, moves, nature, EVs, happiness, and IVs may be changed. IVs will be spread across the board, and an IV value of 32 is used for Trick Room teams to give a 0 speed IV while the rest are 31. :trainereffect - A hash which contains effects similar to bosses. These are explained at the top of Rejuvenation's trainertext.rb so I will not be diving into them here. If you'd like to expand on these I will be adding a new break effect on bosses, which should provide insight as to what you're expected to look for to add a new effect here. Trainers are compiled via the line compileTrainers, and called via pbTrainerBattle or pbDoubleTrainerBattle. Each of their parameters can be found by looking at their definitions. Trainer Classes Classes are what makes a trainer a trainer. They contain all sorts of useful information, and can be found in ttypetext.rb. These do in fact have a symbol identifier, and can be named anything. The following is the list of attributes that can be used: :ID - The number assigned to the trainer's graphic in the Graphics/Characters folder, following the word "trainer" :title - The display name of the trainer class :skill - the level of AI used out of 100, default 30 :moneymult - the multiplier of money earned based on the trainer's highest level Pokemon, default 30 :trainerID - An override of the PokeBattle_Trainer object trainerID. Used exclusively for flavor. :battleBGM - A string containing the name of the battle music for the trainer, found in Audio/BGM :winBGM - A string containing the name of the victory music for the trainer, found in Audio/BGM :player - A boolean based on if the trainer is a playable character. Once again, given the skill you can add anything you want here. Trainer classes are compiled by compileTrainerTypes.
-
Adding a Pokemon Probably the most drastic change from previous versions, Pokemon are now easier than ever to implement. Pokemon species and forms are now located inside the file montext.rb, a much more graceful solution than two separate files or one file and not easily modifiable at all. Creating a New Pokemon To start, open up montext.rb inside your workspace, located in your specific game's subfolder. We'll discuss the structure for a Pokemon first. Each field is broken down in the code block below, with further explanation where needed afterwards. Hidden Abilities are not actually implemented in Rebornverse games, however the ability to add them does exist if you wanted to override our hidden ability override. You'll see some Pokemon use the :HiddenAbility flag. Abilities in this flag are automatically added to the ability list and do not count as real hidden abilities. Growth Rates can be the following values: :Erratic, :Fluctuating, :MediumSlow, :Fast, :MediumFast, :Slow. Further info about these can be gained from sites like Bulbapedia. Gender Ratios can be the following values: :Genderless, :MaleZero, :FemZero, :FemEighth, :FemQuarter, :FemHalf, :MaleQuarter. These values are, in order: Genderless, Always Female, Always Male, 1/8th Female, 1/4th Female, 50/50, 1/4th Male. The creation changing is really useful! It was mainly used to generalize generating regional forms. We use them only for returning form number, but they can be used for a lot of neat things and I'm interested in seeing what you guys can come up with. The general formatting is such: :OnCreation => proc{ next $game_map && Rattata.include?($game_map.map_id) ? 1 : 0 }, We check to make sure $game_map is defined and then check if the current map id matches those included in each regional form array defined in the file SystemConstants.rb found in the game-specific subfolder. We'll add a new Pokemon called Beatote, created by the spriter Samson on PokeCommunity, which is free to use. You likely will be unable to find these sprites without ripping them out of GBA games that already have them. Again, the provided images are located at the start of the thread. These must be named with their dex number, with their respective Battler, Icon, and SE files. Next, you'll need to fill out the Pokemon data. I'll provide the fully written out one here. After that you can compile via compileMons and give yourself a new Beatote! The Pokedex will get automatically updated if it detects there are more species in the DOH than in the Pokedex itself. For custom forms, you'll need to manually refresh the Pokedex. Adding a Form We've successfully added a new Pokemon with a new type. But how can you add a new type without having Arceus's approval? Let's help them out. We're going to do a little cheating and instead of having the plate/Z-Crystal change Arceus's type, we'll change the form based on if you have a Light-type Pokemon or move in your party when encountering it. Unfortunately, though, Arceus (and Silvally) signature moves are tied to their items at the moment. So, we're going to need to override that. Back in Battle_MoveEffects.rb, we need to find PokeBattle_Move_09F. We'll need to throw in a check for our new Arceus form in the pbType method like such: if attacker.species == :ARCEUS && $cache.pkmn[:ARCEUS].forms[attacker.form] == "Light" return super(attacker,:LIGHT) end This should go before any check to avoid needless chance to write over things we aren't accounting for. After that we can go back to montext.rb and define the new form: You should be removing the current :OnCreation attribute already there with this one. This proc will check your party for the above defined conditions and return the form that Light is assigned to. You'll want to compile one more time and then your beautiful Light-type Arceus works! You can do a lot of fun stuff with procs. If you are so inclined, you can even add a new proc to them (make sure you follow my handling of :OnCreation procs!!!!!) and pass in the Pokemon object itself and make direct edits to it if you so desired. Very similar to how EncounterModifier works, actually. I wouldn't recommend this though as handling the dat files of the games is very finnicky if you don't know what you're doing. Were you not loaded into a save when you compiled? No worries! You can just run the command: $Trainer.pokedex.refreshDex to refresh every dex entry, or: $Trainer.pokedex.updateGenderFormEntries to update specifically forms/genders of existing dex entries. With that, we've covered the basics of modding for the Rebornverse games. Next we will get into bosses, trainers, and extra coding tips!
-
Adding an Ability Abilities are where it starts to get...complicated. If you want to properly set things up you'll need to modify the AI and Battle files for them to work properly. Fortunately, we can kind of cheat. If you're trying to make a new ability, chances are that some ability accomplishes a similar thing, and we can find where those abilities activate and insert our own. Before we code in an ability, let's break down ability application in Battle_Move.rb with the function pbCalcDamage. It's. A lot. And some of it seems counter productive! But it's the beautiful thing we get to work with. So. New ability time. We'll make a new ability that empowers Light type moves in preparation for our new Pokemon being added later. To do that, we need to crack open abiltext.rb and define our new ability, like so: You'll notice two new flags inside this file, :fulldesc and :fullname. These are used for the expanded summary screen. When on the Stats summary page, you can press [C], or whatever your rebinded "A" button is, to view an expanded name and description if one is provided. The team has largely used this to detail exact values for abilities. IDs are also largely irrelevant, still a leftover from the old ID systems, but if you need them they free up at ID 268 as of writing this post, and then again at whatever value the custom abilities per game stop at. Once that's added, you can compile via compileAbilities. Now we'll need to code in this ability. For our case, we're heading to Step 4 as detailed above. Anywhere in that first run through of abilities we can add in the line: when :FLUORESCENT then basemult*=1.2 if @type==:LIGHT Once we're done with this we do not need to do anymore work, however if you intend to properly balance things we need to make edits to the AI as well in the file Battle_AI.rb. The AI is far too large for me to detail in this post, but here's the part where we look for abilities that have similar effects and copy their code for our needs. Luckily, we only need to add a few lines of code to a single section for this ability. We'll be editing where STAB is calculated in the AI for when it gets move scoring. A little of the way down you'll see calculations for Water Bubble, Adaptability, and Steelworker. We'll be adding our code there, or more specifically, copying Water Bubble's code and changing it for Fluorescent. The AI now properly gets the damage information when a Pokemon has Fluorescent. There is tons of AI nonsense to look through if you want to really balance something, and a good chunk of it is fields. Try checking out what abilities, fields, and moves effect which parts of the AI scores if you're looking for more information.
-
Adding an Item Items are another straightforward process thanks to our changes to the code. In here we'll be adding 3 different items. A Z-Crystal, a TM, and a battle item. The same processes apply to all items and just need certain flags to function as such. First, we can find all our items in itemtext.rb (Are you beginning to see a pattern here?). Here is all the flags for items: Once again, they follow the standard procedure of having a symbol identifier for the item. You can also add your own flags to say that X group of items are from a specific mod. For our items, we'll create them here. We need a Z-Crystal for Light type moves, a TM for them, then a status item. I've written the code here: After that you can compile with compileItems and you'll be able to give yourself items via the command Kernel.pbItemBall(:ITEM), where :ITEM is replaced by the symbol you added. Lightinium-Z does not need any further implementation. Our TM needs to be added to the :compatiblemoves attribute of any Pokemon you'd like to learn it, which will be discussed later. The Reset X however does need its full implementation still. We'll be revisiting ItemEffects.rb for this. To explain this file, we need to know a few things. Items use what are known as ItemHandlers. This module is defined in Items.rb and contains all the relevant information we need. There are 6 handlers and 1 extra constant for items you can use multiple of at once. Out of the six handlers; UseFromBag, UseInField, UseOnPokemon, BattleUseOnBattler, BattleUseOnPokemon, and UseInBattle, the one we're interested in BattleUseOnBattler. These handlers are all self explanatory, except for maybe the difference of the battle handlers. BattleUseOnBattler applies to the active Pokemon, BattleUseOnPokemon pull up the party menu in battle, and UseInBattle is for items that affect the field/enemy. Anyway, we'll need to add an effect for our X Reset. The parameters for every item handler is the symbol for the item and a lambda, which is similar to a proc (which will be explained later) except that it only yields values true or false. I've gone ahead and written the code already so you can use it as an example, but each handler uses a different amount of parameters for the lambda. The item itself, the battler, which is a derivative of the Pokemon object used for battles, and the battle scene, which is used to play animations and send messages to the battle scene. The code is as follows: Since this is strictly scripting, we have nothing to compile. These changes take place immediately. And now you've written some items! I'm sure you can figure out the other kinds of items by trial and error.
-
Adding a Move Moves are fairly simple to add, but get a little extra complicated as you dive deeper. Let's start by breaking down all the flags a move can have. Similar to the above, every move is defined by a symbol for their identifier and flags, as shown by the other moves in movetext.rb. Those flags are: Base Damage can be any value. Values of 0 are reserved for status moves and values of 1 are reserved for moves with custom damage formulas such as Dragon Rage, Heavy Slam, and Nature's Madness. Accuracy can also be any value. Values of 0 are moves that bypass the accuracy check. Target is for selecting targets in double battles. These values are: :SingleNonUser, :AllOpposing, :User, :RandomOpposing, :AllNonUsers, :NoTarget, :BothSides, :UserSide, :OppositeOpposing, :OpposingSide, :UserOrPartner, :Partner, :SingleOpposing, :DragonDarts You can, of course, add in your own flags here. For instance, if you wanted to make a section of moves for an ability that boosted liquid based moves, you could add a :liquid flag for every liquid move! Move functions are the bulk of moves. They are defined by a 3 digit hexadecimal number starting with 0x. Moves free up starting at 0x18A, and we'll be using that one here. They're defined in Battle_MoveEffects.rb and each are subclasses of the general PokeBattle_Move class. You can override every function that PokeBattle_Move calls for your own needs. Move functions must use the respective 3 digit hexadecimal number for its class. We'll be making a move named Photon Slash. It will go off the highest attack and have a chance to lower defense. It'll be defined here: In addition, the class we'll need will be defined as such, copy and pasting code from Photon Geyser and Tail Whip: After that, you can run compileMoves and see your move in game! For a quick method of teaching it to a Pokemon, open F6 and type in $Trainer.party[0].pbLearnMove(:PHOTONSLASH) to teach it to the first Pokemon in your party, forgetting the first move it has. Adding a Z-Move Z-Moves are quite simple to add with our new setup. The main bulk is editing various files which I will detail. First, we need to create another new move for our Z-Move. You really only need to copy an existing Z-Move and change values to match your intentions. I've gone ahead and done that for you: Add that to movetext.rb and compile. Then we can move on to the tedious part. If you've added a new type when doing this, you may want add a new form to Silvally or Arceus. Those will be found in Battle_MoveEffects.rb and Battler.rb/Pokemon.rb. They modify the Judgment/Multi Attack and Arceus/Silvally forms respectively. I'll get into adding forms later, however I won't be detailing the animation editor, which can be found in the bottom of the debug menu. I simply have never touched it and therefore will not attempt to explain something I don't know. Back to Z-Moves. The first file we're going to want to check out is ItemEffects.rb. You'll find a line of code in there that says: ItemHandlers::UseOnPokemon.copy(:NORMALIUMZ, :FLYINIUMZ, :GROUNDIUMZ, :BUGINIUMZ, :STEELIUMZ, :WATERIUMZ, :ELECTRIUMZ, :ICIUMZ, :DARKINIUMZ, :FIGHTINIUMZ, :POISONIUMZ, :ROCKIUMZ, :GHOSTIUMZ, :FIRIUMZ, :GRASSIUMZ, :PSYCHIUMZ, :DRAGONIUMZ, :FAIRIUMZ) We'll simply add :LIGHTINIUMZ to the end of this list for the name of our item, which we'll add later. The next place to look is in the file PBStuff.rb. This file is an amalgam of lists used in various places throughout the files. The hashes we're concerned with right now are TYPETOZCRYSTAL, MOVETOZCRYSTAL, and CRYSTALTOZMOVE. We can ignore MOVETOZCRYSTAL as we are making a type based Z-Move and not a Pokemon specific one, but the same process as below applies, just making sure to follow the formatting shown in the hash. To add our Z-Move, we'll need to add the following two lines to TYPETOZCRYSTAL and CRYSTALTOZMOVE respectively. :LIGHT => :LIGHTINIUMZ :LIGHTINIUMZ => :BLINDINGLIGHT I cannot stress this enough but do not forgot to use commas. Commas need to separate hash and array entries, and the code will not run if you forget commas. You'll see this constantly if you're doing big edits at once and forget commas here and there (trust me, everyone on the dev team is guilty of this). Now that we've done this, we can move on to items.
-
Adding a Type The first thing we'll do is probably the easiest. We'll add a new type to the game. We'll call it the Light type, to match our new Pokemon later on down the line. A type is defined as such: To make ours, we need to open the typetext.rb file, and add our new type at the end. I've gone and typed it out for you. After that, we'll need a few different images. I've gone and made them for you already as detailed at the top of post. From there, we can start to compile. Hit F6 and type compileTypes Hit enter and fully close the game You've set up the type! We'll add a new move next.
-
Converting PBS Files The Rebornverse games no longer use the PBS files from Essentials, but rather a new data format we've elected to call Data Object Hashes, or DOH. It's a rather straightforward name, the objects are stored in cache as subclasses of the DataObject class, and they are stored as hash files. I have done my best to ensure that the conversion is as simple as possible, but there are still a few things that need to be done by hand unfortunately. This post is strictly for content modders not wishing to lose all of their progress, despite how streamlined modding is now. If this does not apply to you, carry on. Before I detail the steps, here are the things that won't be converted automatically: Types. There's hardly any and they're very easy to set up. Abilities. There's a lot, and when most are adding Gen 8/PLA abilities, we already have them in the game. They're also even easier to set up than types. Items. The formatting is far too different and the amount of flags we have added for items doesn't convert directly from the PBS files. Moves. Same reason for items and abilities. Forms. Unfortunately, literally impossible. If you wanted to manually convert them to Reborn E19.16 format then you could *possibly* convert them to current DOH format, but that's way more effort than just making a new form. Conversion Process To start things off, here's the file for the converter. To use it, place the file in the Data/Mods folder. Open the game Hit F6 and type convertPBS This will open a small little menu where you can select the things to convert being; Pokemon, Trainer Types/Teams, Encounters, Map Connections, and Metadata. I strongly recommend only using Pokemon conversion, but I know those with lots of encounter changes and trainer changes would be left out. Pokemon should largely be unaffected as they merge the PBS into the existing DOH. Trainers do not have their defeat lines included from conversion, which means those need to be manually added. Encounters should be fine to use provided map data has not changed (looking at you, Rejuv). The same applies for Connections and Metadata. Connections should most likely be ignored for most modders and was really only because it was super easily convertible. And that's that for converting. Anything not mentioned will be explained later in the posts.