Developers Popular Post Haru,, Posted May 18, 2023 Developers Popular Post Share Posted May 18, 2023 An Overview Pokemon Reborn (and Pokemon Rejuvenation/Desolation by direct association) is unique in the fact that it was one of the first fangames that used Pokemon Essentials as a base to almost entirely deviate off the standard Essentials system. As a result, sometimes following the Essentials wiki page gets a little complicated and leaves things uncertain. Especially when the game has been around for almost a decade and current Essentials wiki is many many versions ahead. So, as a dev who started as a modder, I'm here to give a neat little big tutorial on how modding works for Reborn E19. NOTE: This tutorial, while covering many baselines, requires some semblance of understanding coding, knowing how to read error messages if and when they occur, and does not directly apply to Pokemon Desolation, Pokemon Rejuvenation, or any future versions of Pokemon Reborn past the creation of this post. A follow-up post will be made covering them some time after Rejuvenation V13.5 is released, or possibly after we release Reborn's backend update. NOTE 2: I will assume the previous base line has been met. If you want my honest advice, just throw stuff at the code and see what happens. That's how I learned and that's why I'm a developer for the team. NOTE 3: I do not check the forums often. Users may be of assistance here. However, you will get quicker responses from me or from other knowledgeable users over on our Discord server. NOTE 4: This tutorial is created using WINDOWS. While I know the game can run on Linux and MacOS, certain steps may not be reproduceable in the same manner. I have zero experience in MacOS or Linux. Sorry. Not really. NOTE 5: It should be known that editing any part of the game makes using any online function have a high chance of breaking things. Please do not use any online functions. NOTE 6: I will NOT be covering ANYTHING inside of RPG Maker XP. There are tons of tutorials already existing which have not changed since this decrepit software was released. Things like Trainers are super simple to grasp if you've followed through the tutorial. Additionally, you can use the tried and true rule of "copy paste then change values" to get results. It works very well. Getting Started So! You want to mod, huh? Cool. Here are a few steps to get you started. Download the PBS files from the imbedded link. Download a text editor other than Notepad. I personally recommend Visual Studio Code, as it is what I will be using. You'll also want a clean copy of Pokemon Reborn, meaning nothing has been changed and no mods are added. Before we get started on doing anything, I'll walk you through setting up your workspace. Step 1 Take the PBS folder you downloaded and extract the contents to Reborn's root folder. After that, your folder should look like this: Spoiler Step 2 Once that's been done, we're going to set up the console. The console window will not let you interact with the game, instead it prints out additional information and lets you utilize a separate print feature that does not cause pop-ups. Steps: Spoiler 1. Right click Game.exe 2. Click Create Shortcut 3. Right click the shortcut that was just made. On a clean install it should be labeled Game.exe - Shortcut 4. There will be a text field labeled Target. Select that text field, and go to the end of the text there. Type debug at the end like so: 5. Click Apply and then close the window. You can now launch the game from the shortcut and it will show with a second screen that we call the console. Step 3 Lastly, we will set up our workspace. Editors such as Notepad++ should have similar capabilities, but for the purposes of this tutorial, I will be using Visual Studio Code, as linked above. Spoiler 1. Open Visual Studio Code. Press File > Open Folder. Navigate to Reborn's folder and select the Scripts folder inside. 2. On a first launch of VSC, it will prompt you to install a plugin for the language being used. It should automatically find the correct plugin, but you're simply looking for one named Ruby. Here's the link: https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby 3. There should also be another pop-up prompting you to open a workspace. You'll want to go ahead and allow that as well. It should be labeled Perry Script workfolder.code-workspace. This will let you edit the PBS files from VSC as well. Ignore the rest of Step 3 if this is the case. 4. If it is not included, we need to create a workspace. Click File > Add Folder to Workspace and select the PBS folder Click File > Save Workspace As... And that's that! You're ready to start modding! 12 1 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 18, 2023 Author Developers Share Posted May 18, 2023 Adding a Pokemon So. Let's start with the be-all end-all of Pokemon. Themselves. Creating a Pokemon is quite easy, and by far the most common mod in the Mod Market. Let's break it down. Pokemon in their default forms are found in the PBS folder inside pokemon.txt whereas their forms are found within MultipleForms.rb. The methods, things the game uses, that define a Pokemon are found within the file PokeBattle_Pokemon.rb and PokemonMultipleForms.rb. Creating a New Pokemon To start, open up pokemon.txt inside your workspace. Next, we'll go ahead and copy the block of code for Bulbasaur: Spoiler [1] Name=Bulbasaur InternalName=BULBASAUR Type1=GRASS Type2=POISON BaseStats=45,49,49,45,65,65 GenderRate=FemaleOneEighth GrowthRate=Parabolic BaseEXP=64 EffortPoints=0,0,0,0,1,0 Rareness=45 Happiness=70 Abilities=OVERGROW,CHLOROPHYLL Moves=1,TACKLE,3,GROWL,7,LEECHSEED,9,VINEWHIP,13,POISONPOWDER,13,SLEEPPOWDER,15,TAKEDOWN,19,RAZORLEAF,21,SWEETSCENT,25,GROWTH,27,DOUBLEEDGE,31,WORRYSEED,33,SYNTHESIS,37,SEEDBOMB EggMoves=AMNESIA,CHARM,CURSE,ENDURE,GIGADRAIN,GRASSWHISTLE,GRASSYTERRAIN,INGRAIN,LEAFSTORM,MAGICALLEAF,NATUREPOWER,PETALDANCE,POWERWHIP,SKULLBASH,SLUDGE Compatibility=Monster,Grass StepsToHatch=5355 Height=0.7 Weight=6.9 Color=Green Habitat=Grassland Kind=Seed Pokedex=Bulbasaur can be seen napping in bright sunlight. There is a seed on its back. By soaking up the sun's rays, the seed grows progressively larger. BattlerPlayerY=28 BattlerEnemyY=25 BattlerAltitude=0 Evolutions=IVYSAUR,Level,16 Then, you'll want to paste that all the way down at the end of the file, right after Eternatus. "Hey! Wait! Eternatus isn't in the game!" While that is true, its implementation actually is in the game, it just lacks sprites and is impossible to obtain. We decided it was easier to leave them in at the time of creation since Desolation, which was being developed for its latest release, and Rejuvenation, both had plans for Pokemon from the Galar Region. You can delete everything from after to Zeraora to Eternatus if you don't want a massive gap in your Pokedex. Back to adding a new Pokemon.... Everything part of that Bulbasaur is what we're going to call a field. Each field is customizable. So, for our new Pokemon, let's use a fakemon called Beatote from the spriter Samson. You can find his old account on PokeCommunity, but almost all sprites have been taken down due to age. I took these straight out of ROM hacks of old that used them. The first things you'll need, of course, are a sprite, icon, and cry. I'll provide them for this Pokemon. You can find them here. These must be named with their ID, which will be explained below. Take the image with just the number, and move that to Graphics/Battlers. Take the other image and drag that to Graphics/Icons. Finally, take the audio file and drag that to Audio/SE. NOTE: If you delete the Galar Pokemon, you MUST rename these files to their new ID. Secondly, you'll need to start editing the new Pokemon code you pasted. The first field, [1], should be changed to the next available ID. The second field, Name, is the display name. The third field, InternalName, is the name used in the code. Type1 is the primary typing. It can be any type defined in the code. Type2 is the secondary typing. BaseStats are the Pokemon stats, of the order HP, Attack, Defense, Speed, Special Attack, Special Defense. GenderRate is what defines the gender ratio. The possible options are AlwaysMale, FemaleOneEighth, Female25Percent, Female50Percent, Female75Percent, FemaleSevenEighths, AlwaysFemale, and Genderless. GrowthRate determines how fast the Pokemon levels up. The options are Medium or MediumFast, Erratic, Fluctuating, Parabolic or MediumSlow, Fast, and Slow. You can learn more about growth rates on any wiki website. BaseEXP is the amount of EXP earned from defeating a Pokemon. It can be any whole number greater than zero. EffortPoints is the EV yield granted when defeated. It follows the same order as BaseStats. They can be any whole number greater than zero. Rareness is the catch rate. It can be any whole number between 0 and 255 Happiness is the base friendship a Pokemon has. This typically is not changed from 70 Abilities are the main abilities a Pokemon can have. They can be 1-2 abilities from any ability defined in PBS/abilities.txt HiddenAbility is the hidden ability. This feature is not present and simply a possible ability a Pokemon can have. Moves is the list of moves a Pokemon can learn by level up. They are formatted as a whole number, followed by the name of the move. EggMoves is the list of moves a Pokemon can learn through breeding. Compatibility is the Pokemon's egg group. The possible egg groups are: Monster Water1 Bug Flying Field Fairy Grass Humanlike Water3 Mineral Amorphous Water2 Ditto Dragon Undiscovered. StepsToHatch is the amount of steps require to hatch from an egg. Do not use any commas or decimals to indicate thousands, and it must be a whole number. Height can be any positive number. They use the American system of using decimal points. Weight can be any positive number. They use the American system of using decimal points. Color is typically the main color of the Pokemon. It's used solely by the Pokedex. It can be Red, Blue, Yellow, Green, Black, Brown, Purple, Gray, White, or Pink. Habitat is the cosmetic "location" a Pokemon can be found. This field can be ignored. Kind is the type listed in the Pokedex. This can be anything. Pokedex is the Pokedex entry displayed in the Pokedex itself. This can be anything. WildItemCommon, WildItemUncommon, and WildItemRare make up the chance of holding an item, being 50%, 5%, and 1% respectively. If all three of these fields exist AND are the same item, the Pokemon will always spawn with that item. It can be any item defined in PBS/items.txt BattlerPlayerY and BattlerEnemyY can be left the same. They need to be any whole number. These can be adjusted to suit your needs to change the position. BattlerAltitude determines the height in battle. Should typically be left at 0. Can be any number greater or equal to 0. Shows a shadow if greater than zero. Evoltuions is what defines how the Pokemon can evolve. Evolutions have 3 parts: Pokemon, Evolution Method, and Evolution Parameter, in that order. A full list of evolution methods and their parameters can be found in PokemonEvolution.rb. We will discuss these later. The premade data for Beatote can be found below: Spoiler [891] Name=Beatote InternalName=BEATOTE Type1=BUG Type2=GROUND BaseStats=75,85,90,80,50,85 GenderRate=AlwaysMale GrowthRate=Erratic BaseEXP=184 EffortPoints=0,0,2,0,0,0 Rareness=45 Happiness=70 Abilities=ILLUMINATE,SWARM HiddenAbility=PRANKSTER Moves=1,FLASH,1,TACKLE,5,DOUBLETEAM,8,CONFUSERAY,12,QUICKATTACK,15,STRUGGLEBUG,19,MOONLIGHT,22,TAILGLOW,26,SIGNALBEAM,29,PROTECT,33,ZENHEADBUTT,36,HELPINGHAND,40,BUGBUZZ,43,PLAYROUGH,47,DOUBLEEDGE,50,INFESTATION EggMoves=BATONPASS,BUGBUZZ,DIZZYPUNCH,ENCORE,LUNGE,SEISMICTOSS,SILVERWIND,TRICK Compatibility=Bug,Humanlike StepsToHatch=4080 Height=1.4 Weight=42.3 Color=Yellow Kind=Groundfly Pokedex=Beatote live underground, taking over the colonies of the Nincada that live in the area by blinding them. WildItemUncommon=BRIGHTPOWDER BattlerPlayerY=23 BattlerEnemyY=19 BattlerAltitude=0 Evolutions= So now we're done, right? Not so fast! Now that we've created a Pokemon, we need to compile. To compile, you want to Launch the game via the shortcut created earlier. Press F6 and type pbCompilePokemonData, then press enter. Alternatively: Open any save Pause the game, select Debug Scroll to "Compile All Data" and select it After either option, restart the game. You'll pretty much want to do this any time you add new things to the game via the PBS. Once you relaunch the game, you can give yourself your new Beatote via debug! Either go to the debug menu and hit Add Pokemon, or push F6 and enter the script: pbAddPokemon(PBSpecies::BEATOTE,5) Spoiler 5 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 18, 2023 Author Developers Share Posted May 18, 2023 Adding a Move Probably the next big thing, moves. Moves are defined in PBS/moves.txt. They're a lot more complicated to set up, but quite fun to make. Let's break down the structure before we add any. The first field is the ID. They are typically in ascending order, but sometimes have gaps. The internal name is next. This is what you'll be using in the scripts and PBS files. The next field is the display name. The next field is the move function. I will explain this later. Next is the Base Power. 0 means no base power. 1 means custom power. Anything else is fair game. Typing. Any available type from PBS/types.txt Category. Physical/Special/Status. If defined as status, the base power MUST be zero. If defined as Physical/Special, the base power MUST be non zero. Accuracy. Number from 0 to 100. 0 never misses. Max PP. Any number. This number is before PP Ups. PP Ups are calculated automatically Effect chance. Percent chance for a secondary effect to trigger. Target Selection. Which Pokemon the move can target. Spoiler 00 - Single Pokémon other than the user 01 - No target (i.e. Counter, Metal Burst, Mirror Coat, Curse) 02 - Single opposing Pokémon selected at random (i.e. Outrage, Petal Dance, Thrash, Uproar) 04 - All opposing Pokémon 08 - All Pokémon other than the user 10 - User 20 - Both sides (e.g. Sunny Day, Trick Room) 40 - User's side (e.g. Light Screen, Mist) 80 - Opposing side (i.e. Spikes, Toxic Spikes, Stealth Rocks) 100 - User's partner (i.e. Helping Hand) 200 - Single Pokémon on user's side (i.e. Acupressure) 400 - Single opposing Pokémon (i.e. Me First) 800 - Single opposing Pokémon directly opposite of user Move Priority. Used in determining turn order, values range from -6 to 6. Flags. By far the stupidest system of doing this but here we are. This includes aspects like sound, contact, high crit rate, etc. It can be any combination of letters a through n Spoiler a - The move makes physical contact with the target. b - The target can use Protect or Detect to protect itself from the move. c - The target can use Magic Coat to redirect the effect of the move. Use this flag if the move deals no damage but causes a negative effect on the target. (Flags c and d cannot both be used) d - The target can use Snatch to steal the effect of the move. Use this flag for most moves that target the user. (Flags c and d cannot both be used) e - The move can be copied by Mirror Move. f - The move has a 10% chance of making the opponent flinch if the user is holding a King's Rock/Razor Fang. Use this flag for all damaging moves that don't already have a flinching effect. g - If the user is frozen, the move will thaw it out before it is used. h - The move has a high critical hit rate. i - The move is a biting move (powered up by the ability Strong Jaw). j - The move is a punching move (powered up by the ability Iron Fist). k - The move is a sound-based move. l - The move is a powder-based move (Grass-type Pokémon are immune to them). m - The move is a pulse-based move (powered up by the ability Mega Launcher). n - The move is a bomb-based move (resisted by the ability Bulletproof). Description. Move description. Now that we have these, we can create our own move. For an example, we'll be creating a move for our Beatote named "Bug Strike". It will have a high crit ratio, contact, get affected by protect, be affected by mirror move, flinch with king's rock, and have a chance to paralyze. We can define that by: 772,BUGSTRIKE,Bug Strike,189,70,BUG,Physical,100,10,20,00,0,abef,"The user strikes the target with a tough appendage. Critical hits land more easily." But wait! Function 189? What's that? This is where the hard part comes in. We need to go to the file PokeBattle_MoveEffects.rb. This is where all of our move functions are defined. To make things simple, we will copy the code from Thunder. In case that file is not labeled with each move (You should definitely do this), you can find the function in PBS/moves.txt and search for it in PokeBattle_MoveEffects.rb. At the end, the code should look like this: # Bug Strike class PokeBattle_Move_189 < PokeBattle_Move def pbAdditionalEffect(attacker,opponent) return false if !opponent.pbCanParalyze?(false) opponent.pbParalyze(attacker) @battle.pbDisplay(_INTL("{1} was paralyzed! It may be unable to move!",opponent.pbThis)) return true end end Since we've defined a chance to proc an additional effect, we need to use the method pbAdditionalEffect. If we were to look at a status move or something like Superpower or Drain Punch, they use pbEffect. Moves like Thunder Fang with two effects require an additional method called pbSecondAdditionalEffect. If you were to want a move to have more than 2 additional effects with separate chances, you'd need to find where each of these methods are called in the game's scripts and add in new methods for that. Alternatively, you can add in a new random roll inside the effect. While you don't need to use pbAdditionalEffect and can just use pbEffect, it's better to stick with conventions and use them as intended. Finally, to use the move, we need to give it to a Pokemon. We can simply add at the front of our Moves field in the Pokemon data "1,BUGSTRIKE" An example of adding the move will be hidden below. Spoiler Moves=1,BUGSTRIKE,1,FLASH,1,TACKLE,5,DOUBLETEAM,8,CONFUSERAY,12,QUICKATTACK,15,STRUGGLEBUG,19,MOONLIGHT,22,TAILGLOW,26,SIGNALBEAM,29,PROTECT,33,ZENHEADBUTT,36,HELPINGHAND,40,BUGBUZZ,43,PLAYROUGH,47,DOUBLEEDGE,50,INFESTATION After that, we can compile all! Many types of effects are found within PokeBattle_MoveEffects.rb, such as Flying Press's multityped aspect, defining moves able to used while asleep, along with a lot more. The only thing that limits what you can do here is your own coding ability, understanding, and the small fact that you can only affect active battlers. 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 19, 2023 Author Developers Share Posted May 19, 2023 Adding an Ability Next up, abilities. Abilities, as you'd expect, are defined in PBS/abilities.txt. They're very straightforward on the PBS end of things, only requiring an ID, Internal Name, Display Name, and Description. On the other hand, the entire implementation is code based. To fit in with Beatote's Pokedex entry of preying on Nincada, let's have its ability make its attack increase by 50% against Bug-type Pokemon. To start, defining its ability in the PBS: 330,SCAVENGER,Scavenger,"Deal increased damage to Bug-type Pokémon." Next, we'll give that ability to Beatote. HiddenAbility=SCAVENGER Now we can compile, and Beatote will now have the Scavenger ability! Spoiler And now, we need to implement it! There's a lot to do here, so bear with me and try to follow along. We want to head to the file PokeBattle_Move.rb. This file is where all damage calculation takes place, and where the magic mainly happens. You'll want to head down to around line 1448, which is after all the field effect code. You'll be looking for a line that says: case attacker.ability when PBAbilities::GUTS In here, we'll want to add a few lines so we end up with: case attacker.ability when PBAbilities::SCAVENGER atkmult=(atkmult*1.5).round if opponent.hasType?(:BUG) when PBAbilities::GUTS I'll explain what's going on here. This is a method called pbCalcDamage. Inside of it, it takes three parameters in addition to an optional hitnum named parameter. While the parameters options and hitnum are inconsequential, attacker and opponent are what we really care about here. Both attacker and opponent will be PokeBattle_Battler objects, found inside PokeBattle_Battler.rb. Any method or attribute in there can be called and utilized for creating a damaging move. The method hasType? takes a type and returns if the object has it or not. pbCalcDamage is split into parts: Spoiler Initialization, including exiting if base damage is 0, pulling base damage from PBS, etc. Calculate the base damage. Abilities, such as Sheer Force and Pixilate. Items, such as gems, plates, and legendary orbs (Griseous Orb, Soul Dew, etc) More effects conditionally, being Charge, Helping Hand, Mud/Water Sport, Kalos Legend Abilities, Knock Off, and Lunala Z vs Minimize. Field effect changes. Calculate the attacker's attack stat comes next, being the Pokemon using the move. Determine if physical or special. Adjust for Unaware/Hustle/Power Spot. More field effects. Conditional attack modifier abilities (Starters, Swarm). Attack modifier abilities (Scavenger, Huge Power, Guts, Flash Fire, etc). Item modifiers, such as Light Ball, Thick Club, Choice items Thick Fat must be done LAST. Calculate the corresponding defense stat. Same shtick applies here. Very repetitive. Calculate the effective, or actual, damage. Multihit moves Generic field boosts, such as type matching. Primal Abilities return 0 damage here if nullified by respective weather. Field transformations, such as Crystal Cave > Dark Crystal Cave or Factory Field Sun/Rain Crit calculation Damage rolls STAB calculation Type effectiveness check Gem message + Burn/Water Bubble Effective damage mods, such as Screens, Multiscale, Friend Guard, Life Orb, Berries, etc. Calculate final damage using above methods. Now your ability functions. But only for the player. The AI does not know what's actually going on with your ability, it simply sees nothing, We need to head to the file "PokeBattle_AI_2.rb". This file is a wonder. It's incredibly complicated and I won't bore you trying to teach it. The gist is, you need to find similar functioning abilities and insert your new ability in. If you look at where we inserted Scavenger in the PokeBattle_Move.rb, we should look for spots where those abilities are and copy them, provided we ignore any field-specific effects for them. This will apply similar logic to before. I'll state which methods we'll be modifying. This part doesn't need to be done, but should if you plan on making the AI have a fair chance. Certain abilities should be more weighted heavily in the first location, a method called getAbilityDisruptScore, which is the score the AI gets for whether or not it should "counter" the ability. We'll place this right near where the code for Huge Power is. The multiplier here is typically the same. when PBAbilities::SCAVENGER abilityscore*=1.5 if opponent.hasType?(:BUG) The next spot is where we calculate ability score for the AI to find the best switch for. It can be found by searching abilityscore in the file. It starts at around line 8035 on clean code. Pretty much anywhere after the line case i.ability we will be adding the code: when PBAbilities::SCAVENGER abilityscore+=30 if @opponent.hasType?(:BUG) The amount to add here is pretty subjective. The general process is 10 for "hey this is better than no ability" or a much higher number for "hey this is a really freaking good idea do this." However much you want to add for your own abilities is up to you. The final spot where it's required is much further down labeled with a comment tag ############ ATTACKER ABILITY CHECKS ############ You can search for this to find it. We'll be adding this line into the code there. It can be anywhere after Technician but before Type Changing Abilities. Typically group like changes together. #Scavenger elsif attacker.ability == PBAbilities::SCAVENGER if opponent.hasType?(:BUG) atk=(atk*1.5).round end Congrats! You've taken your first real step into full content mods with this! There's still a whole lot going on here behind the scenes, but I'm not going to explain it solely based on the fact it would take way too long to explain everything. I've explained the important stuff, much of it has labels, and much of it is very self-explanatory thanks to our wonderful developers (humblebrag). Let's hop into the next topic. 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 20, 2023 Author Developers Share Posted May 20, 2023 Evolutions Now. I'm sure you've thought Beatote is familiar at this point. It's actually a fake evolution of Volbeat! For our evolution method, we will be having Volbeat need to know Tail Glow and be at least level 30. Let's code that in! To start, we need to head to PokemonEvolution.rb Our first step is to define a new evolution constant. These are what you'll see immediately into opening the file. At the end of that list, you'll want to this add the code. Beatote = 33 Feel free to make the spaces match. Next, we'll want to add to the EVONAMES array. Just add a "Beatote" entry right after where it says "Custom7". Finally, to finish the definition, we need to add to the EVOPARAM array. What each number means is defined right above it. All we want for that is an integer, which is to say another 1. Below is what the two arrays should look like: Spoiler EVONAMES=["Unknown", "Happiness","HappinessDay","HappinessNight","Level","Trade", "TradeItem","Item","AttackGreater","AtkDefEqual","DefenseGreater", "Silcoon","Cascoon","Ninjask","Shedinja","Beauty", "ItemMale","ItemFemale","DayHoldItem","NightHoldItem","HasMove", "HasInParty","LevelMale","LevelFemale","Location","TradeSpecies", "BadInfluence","Affection","LevelRain","LevelDay","LevelNight","Custom6","Custom7", "Beatote" ] # 0 = no parameter # 1 = Positive integer # 2 = Item internal name # 3 = Move internal name # 4 = Species internal name # 5 = Type internal name EVOPARAM=[0, # Unknown (do not use) 0,0,0,1,0, # Happiness, HappinessDay, HappinessNight, Level, Trade 2,2,1,1,1, # TradeItem, Item, AttackGreater, AtkDefEqual, DefenseGreater 1,1,1,1,1, # Silcoon, Cascoon, Ninjask, Shedinja, Beauty 2,2,2,2,3, # ItemMale, ItemFemale, DayHoldItem, NightHoldItem, HasMove 4,1,1,1,4, # HasInParty, LevelMale, LevelFemale, Location, TradeSpecies 1,1,1,1,1,1,1, # Custom 1-7 1 # Beatote ] Now, to actually implement our evolution method, we need to head down to the method pbMiniCheckEvolution. The method takes in 4 parameters, being the Pokemon object, its evolution method, the parameter defined in PBS/pokemon.txt, and the species it evolves into. Following the structure shown in pbMiniCheckEvolution, we want to do the same for our new one, making sure our Pokemon is above the level and has the required move. That will look like this: when PBEvolution::Beatote return poke if pokemon.level >= level && pokemon.knowsMove?(:TAILGLOW) Lastly, we need to add the evolution method to Volbeat in PBS/pokemon.txt. It's very simple, all that needs to be done is filling out the evolution field in Volbeat's block. Reminder you can push Ctrl + F to search through a file. Evolutions=BEATOTE,Beatote,30 After that, you can compile, and the evolution will work. Spoiler 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 20, 2023 Author Developers Share Posted May 20, 2023 Adding a Type This one's easy. Unfortunately, it's also incredibly broken. You'll need to download this file to make the type compiler work. Our bad. Anyway. Light Type. Simple and quick. On brand to a Volbeat line. Heading over to PBS/types.txt,we see a few parameters, being: Name InternalName IsSpecialType, which decides if a type is physical or special on Glitch field Weaknesses, which types it is weak to Resistances, which types it resists Immunities, which types it is immune to We can pretty much throw anything at it. Here's what I did [19] Name=Light InternalName=LIGHT IsSpecialType=true Weaknesses=DARK,NORMAL Resistances=BUG,ELECTRIC,LIGHT Immunities=FIRE Additionally, I added Light to Dark's Weakness field to make them weak to each other. Then we'll go ahead and replace Beatote's Ground typing with Light in PBS/pokemon.txt, and then compile. The last thing we need is an image for the type. I'll provide that, and it needs to replace the one in Graphics/Pictures. You'll need an editor such as paint.NET if you want to do it yourself. Spoiler And there's a new type! Probably the easiest thing so far. There are other graphics where a light type might need its own image, such as in the field notes or in battle. Those are in Graphics/Icons and Graphics/Pictures/Battle respectively. 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 20, 2023 Author Developers Share Posted May 20, 2023 Adding Items We'll add 2 different items here. A new TM, and a new battle item. Items are defined in PBS/items.txt and TM compatibility is stored in PBS/tm.txt. We'll cover tm.txt later, so let's focus on items.txt for now. The format for items is comprised of: ID Internal Name Display Name Item Pocket (Items, Medicine, Poke Balls, TMs, Berries, Crystals, Battle Items, Key Items, being represented by a number 0 through 7 in order) Item Price Item Description Item Use From Bag Spoiler 0 - No use 1 - One time use with party screen (Potions) 2 - One time use (Repel, Escape Rope) 3 - TMs 4 - TMX (HMs) 5 - Multi-use party screen (Legendary items, Flutes) Item Use In Battle Spoiler 0 - No use 1 - Single use (Potions, Elixirs) 2 - Single use without target (X Items, PokeBalls, PokeDoll) 3 - Flutes Item Type Spoiler 0 - Other 1 - Mail (Unused) 2 - Mail 3 - Snag Ball (Unused) 4 - Poke Ball 5 - Berry 6 - Key Item 7 - Z Crystal (bag item) 8 - Z Crystal (held item) TM Move if applicable For a TM, let's create a TM for Megahorn. To do this, we need to first search through the list of items and find the last created TM. In our case, that would be TM101. Then, we head down to the end of and get our next ID, giving us: 874,TM101,TM101,4,7500,"Using a tough and impressive horn, the user rams into the target with no letup.",3,0,0,MEGAHORN After that, we need to head to PBS/tm.txt. There, we can use the format shown to add the compatibility. [INTERNALNAME] POKEMON,POKEMON,... We'll then compile and have a new working TM! Spoiler Now, for our battle item. This item will reset all negative stat changes. Seems simple enough, no? First, our icon: Next, we'll go create an entry in the text file for our item: 875,XRESET,X Reset,7,500,"Removes all negative stat changes.",0,2,0 Then we can compile, and the item exists. But we still need to code its function. Here comes the doozy of a file named PokemonItemEffects.rb. In here we have our ItemHandlers. We're going to want to head down to where it's labeled BattleUseOnBattler, which is where flag 2 of field 8 has all its items. To know what to do here requires decent knowledge of each method available to a battler, item, and scene. In short, a battler has every attribute and method listed in PokeBattle_Battler.rb, an item is the item ID, and the scene will let you print messages in battle. Our code should look something like this: Spoiler ItemHandlers::BattleUseOnBattler.add(:XRESET,lambda{|item,battler,scene| playername=battler.battle.pbPlayer.name itemname=PBItems.getName(item) scene.pbDisplay(_INTL("{1} used the {2}.",playername,itemname)) reducedstats=false for i in 1..7 if battler.stages[i]<0 battler.stages[i]=0; reducedstats=true end end if reducedstats scene.pbDisplay(_INTL("{1}'s negative stats were reset!",battler.name)) return true end scene.pbDisplay(_INTL("But it had no effect!")) return false }) To explain a little further what's going on here: We access the Trainer name through the battler's battle accessor, through the pbPlayer method, and then accessing the name flag of the Player. Which, if you took a second to look at any other code, is very stupid. This will be fixed in the next game update. Get the item name Print a use message using _INTL. You can mark variables using curly brackets and numbers. {1} means it will pull the first variable enclosed in the given arguments. _INTL is what most display text uses, and runs through a text formatter. We copy the code from White Herb elsewhere in the code. Essentially, we check every stat that is not HP to see if it has been reduced, if so, we toggle a flag and reset it. If the flag has been switched on, we confirm use. If not, we deny use. Explanation aside, we can now compile for another working item! ItemHandlers are how items are coded functionally. Looking through a few examples like Poke Balls and Potions will help give a better understanding, Certain items, like Poke Balls, utilize shortcuts to account for every type of ball to generalize them. Those Poke Ball catch rates are handled during the battle. Others, such as Evolution Stone items, copy the handler for one item on to every other one of its type. Spoiler 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 20, 2023 Author Developers Share Posted May 20, 2023 Modifying Encounters These explanations will start to get shorter as there is less and less to cover. In PBS/encounters.txt, there exists a section for every map with valid encounters. Unfortunately, there is no way to modify what maps have encounters and what tiles are encounter tiles without the use of RPG Maker XP. I will never advocate for buying this unfortunate piece of software, but the things talented people can do will never cease to amaze me. Back to encounters, they are very simply formatted. Map ID Land Encounter Rate, Cave Encounter Rate, Water Encounter Rate. This line is optional, and defaults to 25,10,10. These are divided by 180 for encounter rate. Encounter Type List of Pokemon, Min Level, Max Level, matching to the amount of encounters defined in PokemonEncounters.rb The valid encounter types are: Spoiler Land Cave (Cannot exist with any Land encounters or Bug Contest Water RockSmash OldRod GoodRod SuperRod HeadbuttLow HeadbuttHigh LandMorning LandDay LandNight BugContest While you can't add encounter types without RMXP, you CAN edit the available slots you can have. By default, you can only have slots as listed by the array EnctypeChance. You can modify these entries to allow for more than the given amount. Be warned, that you may encounter issues on places that don't have the new number you set them to, as each slot must be filled. Each sub array of EnctypeChance is based in percentages. EnctypeDensities stores the default values for encounter rate. You can ignore this. And I'm honestly not too sure what EnctypeCompileDens is for if I'm being honest. These are all fairly old as far as I'm aware and there's little need to touch any of it. The same process as before applies to changing encounters. Replace a Pokemon, change their possible levels, compile, and test! 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 20, 2023 Author Developers Share Posted May 20, 2023 Forms Forms are a complete mess and I apologize to any modders out there who deal with them. As the one who rewrote them for Desolation, I feel your pain. Sob story aside, they are quite easy to implement! The file we need is MultipleForms.rb. While I don't have an example for this one, I'll more accurately go into how they work. First, there's a small array at the top called FormCopy. This array contains smaller arrays of [Base, Clone] to save repetition. It'll take anything listed in the Base and copy it over to the Clone. Second, the actual meat of forms. Rather than array, this uses a hash and symbols, something the current Reborn is almost switched over to. Ruby was built to use them, so we are. Each entry is called a key, and they are using the ID number of each Pokemon listed. Each key stores another value, in this case being a hash with different keys inside of it. These new level of keys are: :FormName, :OnCreation, :MegaForm, :PulseForm, :DefaultForm, :UltraForm, and the string of any form name to pull data from. :FormName contains keys, corresponding to form number, which return a form name :OnCreation is a proc{} block that is used when generating encounters to check what form it should generate. Examples include Unown generating randomly and Rattata generating Alolan/Kantonian based on the map. :MegaForm, :PulseForm, :DefaultForm, :UltraForm all correspond to their namesake form and return the specific form ID. Exclusions are Mewtwo and Charizard, who have 2 separate forms. Each form name has its own hash tied to it, with keys overriding the base Pokemon's traits Dex Entry, Type 1, Type 2, Base Stats, Ability, Movelist, Egg Moves, Height, Weight, Evolution, Wild Held Items, Catch Rate, and EV Yield There is even further room for customization if you want to put the effort in, but I do not recommend it. And that's everything directly related to Pokemon covered! You did it! Woohoo! 3 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted May 20, 2023 Author Developers Share Posted May 20, 2023 Afterword Very useful and very powerful commands I have not explained are the puts and print commands. Puts will print out messages to the console you have opened in the background. Print will pop up and pause the game with a message window. If anything you code ever doesn't work, litter these all across your code to see what went wrong. You can use them to show variables at certain times in the code or just to label where in the code you are so you know what's not getting run. I know I use them literally all the time. I know the other devs that work with us do too. There should still be some littered about the code. If you understood anything that was said throughout this whole thing, congrats! You've got it in you to make some really freakin cool mods. If not, don't sweat it! Maybe coding isn't for you. Maybe you're an artist. Maybe you're the ideas person! Maybe you just need to read this through one last time to really digest it. Ctrl + Shift + F is one of your best friends in VSC. Tutorials like these were what got me into Minecraft modding. Applying those skills towards Rejuvenation got me into making my first mod, the original Randomizer. That got me to the Challenge Pack (what a mess it was), and then on to the dev team for the Rebornian games. Now I'm creating a guide for you all. What I've shown you is by no means the limit. Look at Moto's mods. Look at my other mods. Look at the SWM Modular Modpacks. Look at AllGen. The possibilities are countless. It just takes time to understand what you can do. Please don't get too frustrated at not being able to do something. Calmly think it through. Brainstorm what you want to do, then try to find places in the code where you think you accomplish it. Copy pasting is your friend. It's back to the dungeon for me though, I have other projects to work on. Happy modding and lots of love~ Haru~ 5 Link to comment Share on other sites More sharing options...
suzume Posted August 8, 2023 Share Posted August 8, 2023 Thank you so much for the tutorial! Really appreciate the time and effort you took to make this! I'm super new to all of this and it's been so helpful and educational! If you don't mind, I was wondering if you teach us how to add custom regional forms to the sprite sheet(especially if there's already another form like with megas) please? I tried searching for tutorials on how to do it but I could only find them for previous verions of the game from back when the sprites were still seperate. Link to comment Share on other sites More sharing options...
Developers Haru,, Posted August 9, 2023 Author Developers Share Posted August 9, 2023 On 8/8/2023 at 2:39 AM, suzume said: Thank you so much for the tutorial! Really appreciate the time and effort you took to make this! I'm super new to all of this and it's been so helpful and educational! If you don't mind, I was wondering if you teach us how to add custom regional forms to the sprite sheet(especially if there's already another form like with megas) please? I tried searching for tutorials on how to do it but I could only find them for previous verions of the game from back when the sprites were still seperate. It's super easy. The file is arranged so that each Pokemon occupies a 192x192 square, with the backsprite being below it and the shinies being to the right. While it does require some know-how of working with art programs, and I recommend paint.NET or Piskel, all you're really doing is hitting the program-equivalent "Canvas Size..." button and increasing that value by 192 then placing in your sprites. On the topic of, say, Galarian Slowpoke and Slowbro, our standard has largely been to just shift the Mega Form down 384 pixels and place the Galarian form between them, so as to prevent issues arising with evolutions pulling the wrong graphic. This does require the addition of changing Mega Slowpoke's form value to 2 instead of 1, but there should be a self explanatory field in the file for forms. While you don't particularly need to shift around existing forms, it does make the sprite sheet look like it has less "empty space," even though it's not much of a difference either way. Sometimes, however, you'll have a sprite that exceeds the bounds of the 192x192 square. As of current Reborn E19, I believe these cases are handled specifically in the various bitmap methods (very easily findable looking for mentions of Exeggutor, Necrozma, Guzzlord, etc). You'll need to add your own exception to that list as well and properly label the sprite in the files in 4 separate images when applicable (For a Bulbasaur: "001_1.png", "001b_1.png", "001s_1.png", "001sb_1.png"). You'll also need a similar extra file when dealing with gender differences as well, simply adding an "_f" before the file extension. While thinking about it, I'm not exactly sure how a sprite that is too big would be handled with gender differences. Oh well. 1 1 Link to comment Share on other sites More sharing options...
suzume Posted August 11, 2023 Share Posted August 11, 2023 On 8/9/2023 at 5:23 PM, Haru,, said: It's super easy. The file is arranged so that each Pokemon occupies a 192x192 square, with the backsprite being below it and the shinies being to the right. While it does require some know-how of working with art programs, and I recommend paint.NET or Piskel, all you're really doing is hitting the program-equivalent "Canvas Size..." button and increasing that value by 192 then placing in your sprites. On the topic of, say, Galarian Slowpoke and Slowbro, our standard has largely been to just shift the Mega Form down 384 pixels and place the Galarian form between them, so as to prevent issues arising with evolutions pulling the wrong graphic. This does require the addition of changing Mega Slowpoke's form value to 2 instead of 1, but there should be a self explanatory field in the file for forms. While you don't particularly need to shift around existing forms, it does make the sprite sheet look like it has less "empty space," even though it's not much of a difference either way. Sometimes, however, you'll have a sprite that exceeds the bounds of the 192x192 square. As of current Reborn E19, I believe these cases are handled specifically in the various bitmap methods (very easily findable looking for mentions of Exeggutor, Necrozma, Guzzlord, etc). You'll need to add your own exception to that list as well and properly label the sprite in the files in 4 separate images when applicable (For a Bulbasaur: "001_1.png", "001b_1.png", "001s_1.png", "001sb_1.png"). You'll also need a similar extra file when dealing with gender differences as well, simply adding an "_f" before the file extension. While thinking about it, I'm not exactly sure how a sprite that is too big would be handled with gender differences. Oh well. I managed to do it! Thank you so much! If you don't mind me asking another question, how do you get mega stones working in the game? I followed your guide and managed to get the item in the game but I'm kind of lost as to where to code its function. Link to comment Share on other sites More sharing options...
suzume Posted August 11, 2023 Share Posted August 11, 2023 20 hours ago, suzume said: I managed to do it! Thank you so much! If you don't mind me asking another question, how do you get mega stones working in the game? I followed your guide and managed to get the item in the game but I'm kind of lost as to where to code its function. Never mind, I figured it out! For anyone who's curious I was trying to give a custom regional variant a mega form. I got it working after adding the custom mega stone in PBStuff.rb. Thank you again to @Haru,, for your help, I really do appreciate it! 1 Link to comment Share on other sites More sharing options...
CorruptedJ98 Posted August 14, 2023 Share Posted August 14, 2023 I Know This Probably Wont Get seen but i need help with trying to make an ability like blaze that fuctions for dragon and fairy type moves but i cant figure it out plz help. Link to comment Share on other sites More sharing options...
Lillietea Posted August 16, 2023 Share Posted August 16, 2023 On 8/15/2023 at 1:29 AM, CorruptedJ98 said: I Know This Probably Wont Get seen but i need help with trying to make an ability like blaze that fuctions for dragon and fairy type moves but i cant figure it out plz help. I've had trouble with making abilities at first too, so far it seems that all (or almost all) functionality of abilities is done in the scripts that start with "PokeBattle", just go through all of them and search for abilities that work similarly (like Blaze, which you mentioned), and then copy, paste and edit I wish I could've explained it better, but other than that you just have to understand or at least guess (which I am doing ahah) what the code means and which part does what, etc., which I can't really explain to you (since I don't understand it myself and just do what I found out through trial and error) Anyway, hope that helps! Link to comment Share on other sites More sharing options...
BeautifulSinner Posted August 18, 2023 Share Posted August 18, 2023 Hi I have been trying to add a mon into reatomized and i keep getting this error pop up Everytime I try to debug the Mon into the game Link to comment Share on other sites More sharing options...
The 11th Dimension Posted September 5, 2023 Share Posted September 5, 2023 I've been trying to add hydrabond from all gen reborn to my custom mega hydreigon but when I go to click an attack I get this message I checked where it says the error is but there doesn't seem to be any error only in game Link to comment Share on other sites More sharing options...
Developers Haru,, Posted September 19, 2023 Author Developers Share Posted September 19, 2023 On 9/5/2023 at 12:02 PM, JacobBasque said: I've been trying to add hydrabond from all gen reborn to my custom mega hydreigon but when I go to click an attack I get this message I checked where it says the error is but there doesn't seem to be any error only in game You'll need to actually define the move inside the effects code. You didn't properly get all the code from All Gen. You'll be easily able to find everything by just searching through the code for PBEffects::HydraBond 1 Link to comment Share on other sites More sharing options...
Developers Haru,, Posted September 19, 2023 Author Developers Share Posted September 19, 2023 On 8/18/2023 at 7:34 PM, BeautifulSinner said: Hi I have been trying to add a mon into reatomized and i keep getting this error pop up Everytime I try to debug the Mon into the game It's difficult to tell what exactly is going here. I very recommend not having your game stored in your computer's Temp directory in the first place. From the looks of it, something broke during compilation. Link to comment Share on other sites More sharing options...
ganksnroses Posted September 30, 2023 Share Posted September 30, 2023 How do i add an animation to a custom move??? Link to comment Share on other sites More sharing options...
bihh3024 Posted October 21, 2023 Share Posted October 21, 2023 So I have been trying to add a custom forme along with a mega evolution for that form. I successfully implemented the form in MultipleForms.rb, tested them out using debug mode, but whenever I mega evolve them in battle and exit, attempting to open my party or get into another battle with it gives me a big error message: looking at the console gives me this error message: I thought it had something to do with the spritesheet I created, but after re-doing it many times over, including the icons, I still have no dice. Here is my spritesheet: Here are the icons I used: and here is the form set up in MultipleForms.rb: I have tried getting help on the Discord, but I haven't been able to receive any help there, so I am hoping I can get help here. Thank you for any help you can give me. Link to comment Share on other sites More sharing options...
Karvanha Posted October 25, 2023 Share Posted October 25, 2023 @bihh3024 The cause of the error is the fact that you've made :DefaultForm correspond to a hash (as in :DefaultForm => {PBItems::MANECTITE => 0}) instead of an integer (as in :DefaultForm => 0). If you want to use a hash for the DefaultForm, you'll have to modify the "makeUnmega" function in the PokemonMultipleForms.rb script Link to comment Share on other sites More sharing options...
Recommended Posts