Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Haru,, last won the day on September 19

Haru,, had the most liked content!


94 Samaritan


Profile Information

  • Alias
  • Gender

Contact Methods

  • Discord

Recent Profile Visitors

4450 profile views
  1. 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.
  2. 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
  3. 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.
  4. Pretty much. We can force autosaves on certain story beats but that won't fix anything. I expect this to be resolved before beta testing, definitely before release. The issue is we can't catch these crashes because it's an underlying system error that will override any catching we try to do.
  5. Testing these things is great because my pc doesn't crash and the crashes are almost all unreproducible.
  6. To correct Zumi (sorry zumi), while it does happen while speed up is active, it is likely not using speed up does not avoid the issue. The main culprit is MKXP-Z being updated to Ruby 3.1 which had known issues for Reborn during E19 testing. Unfortunately downgrading is current broken and the MKXP-Z developer just started a month long vacation. So. We're in for a time.
  7. 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~
  8. 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!
  9. 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: 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!
  10. 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 Item Use In Battle Item Type 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! 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: 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.
  11. 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. 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.
  12. 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: 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.
  13. 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! 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: 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.
  14. 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. 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 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. 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.
  15. 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: 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: 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)
  • Create New...