PDA

View Full Version : [Tutorial] Pokémon Gold/Silver Scripting Tutorial


miksy91
April 24th, 2011, 11:55 PM
First of all, scripting in second generation games can be done by only hex editing bytes or using a scripting tool beside with your hex editor. I prefer doing it myself the second way. Then again, using only a tool (by this time, I believe only PKSV supports 2nd gen games) is not an option. PKSV is mostly designed for editing games of third generation and doesn't recognize several commands as working scripts in second gen games.


Pokémon G/S/C Scripting Tutorial


Let's get started but the beginning of this explanation is going to be somewhat "out of the topic" because you should understand the specifics of Map Headers before moving on to scripting. Now that Johtomap is out though, it's not 100% necessary...

Each map contains its Primary Header.
Primary Header for example defines:
1) The music played on that map
2) Tileset used
3) Where the map belongs to (for example, player's house belongs to 01 which stands for NEW BARK TOWN)
4) Type of the map (I think this determines whether you can use Dig and Fly, maybe other commands too)
5) Pointer to map's Secondary Header

Secondary Header is a structure that tells the game:
1) Border tile
2) Width & Height
3) Where the map data is located
4) Where the events are
5) Where is the map's Script Header (this is usually marked as 00 00 just before the script data that different events on that map point to)
6) Map connections


Now, as you probably know (or not), events itself have their own script pointers to their scripts. To understand the data structure of events better, read "event structure" part in Tauwasser's Scripting Compendium (http://hax.iimarck.us/files/scriptingcodes_eng.htm).

So, as you can see (by reading that part of the scripting compendium), "Trigger events", "Signposts" and "People" events have a 2-byte pointer to their script data. By calculating the pointed offset with that pointer (by understanding GB/C Pointers first), you're able to find the script.



Scripting

When you've gotten the hang of Map Headers and completely understand how GB/C Pointers work, you can move on to scripting.
Then again, if you're not there yet, study how the base structures work first.

Let's start with some basic scripts.
Most people events point to structures of this kind:

1) 51 XX YY

As you can see in the compendium, that basically makes the talked-to person turn towards HIRO (6A), load font (47), display text (4C) through a 2-byte pointer (XX YY), close text (53), load moving sprites (49) and end the script (90).

Game uses command 51 XX YY to save space as it clearly uses less space than 6A 47 4C XX YY 53 49 90.


Now, let's move on to more difficult scripts.

2) "Give item" -script

As you can see in the compendium,

1F give item code:
-------------------

Gives item (item no) amount times.
Gives feedback: 00 = bag full, 01 = OK

Structure:
[1F][amount]


This time there are actually four "key commands" you're going to have to use.

[31] [Bit no (2-byte)]
[09] [2byte pointer]
[1F] [amount]
[33] [Bit no (2-byte)]

As an example, I changed the script pointer of the fat man in New Bark Town to 00 70 so that it would point to a blank space to offset 0x123000.
There, I started writing a "give item" -script.

$123000
31 43 06 09 1A 70 6A 47 4C 40 70 53 1F AD 01 33 43 06 49 90

$12301A
51 20 70

$123020
"U already got a Berry!"

$123040
"Hey, take Berry!"


Now, this calls for a brief explanation now doesn't it :D ?
"43 06" is the [I]Flag Bit I decided to use.
Check this thread (http://www.pokecommunity.com/showthread.php?t=127374) that Koolboyman has created.
You can see that bit number 4306 stands for one item ball in Violet City.
In case this man also uses flag bit 4306 so that item ball should be made un-obtainable to avoid glitches.

"AD" is the byte used for Berry which I picked up from Giegue's Master Hacking Guide (http://www.romhacking.net/docs/75).


About the script itself though, the first part of the script "31 43 06" checks if flag bit 4306 has been activated or not. This information will be sent to another part in RAM memory (00 = Flag bit not activated, 01 = Flag bit activated). So basically, the game is told to write either 00 or 01 into a place in RAM where the game checks with code 09 if the value in that offset is different from 0.

"09: When [RAM] <> 0, go to the pointed script. Else resume interpreting after the pointer."

*In this case, RAM is different from 0 if it's 01.


Now, if flag bit 4306 is activated, the game will continue at offset $12301A (because 2byte pointer 1A 70 points to it). At offset $12301A, you can find a similar script as explained above.

Anyway, if the flag bit is not activated, the main script will go on and as you can see, the talked-to person faces HIRO, loads font, displays text at offset $123040, closes text box and gives you an item (one Berry).
After that, flag bit 4306 is activated with code 33.
In the end, moving sprites are loaded and script is ended.

Here is a video of the script and a small enhancement to it.

AIHGGUXQsHE



Here is what the script looks like in PKSV.

http://img508.imageshack.us/img508/6227/scriptm.png


As you can see, this is a more user-friendly way to show it but your biggest problem with PKSV can be the fact, you don't understand what different scripting commands mean (for example jumptextfaceplayer which stands for 51). This is one reason why it's best to use a hex editor with this tool.

Besides, there are several types of scripts that you can't edit with PKSV because only part of their code is normal script data, the rest isn't (for example trainer scripts, item scripts and scripts of script header).




[I]3) Pokemon battle event

Here is another example.
This time, I made the fat man point to another script in offset 0x123100 (by changing his script pointer to 00 71).

$123100
6A 47 4C 20 71 53 83 06 00 1E 03 07 5C 06 01 5E 5F 6D 03 49 90


$123120
"CHAAR!!!"

In this script, the talked-to person faces HIRO, displays text at offset 0x123120, closes text box, plays Charizard's cry (83 06 00), loads a shiny pokemon fight (1E 03 07), loads the pokemon data of the encountered pokemon (5C 06 01), starts battle (5E), returns to ingame engine after battle (5F), hides person (6D 03), loads moving sprites and ends the script.


http://img23.imageshack.us/img23/8650/73061894.png


This time, you're going to have to give the flag bit to the person event itself, not to the script. If there is a flag bit for a person event that is being made hidden, that event won't show anymore if the map is entered again. This is mostly used for items but in occasions like this, you're going to have to do the exact same thing. In this case, I changed the flag bit of that fat man to 1700. It doesn't make any difference which flag bit you use if some other script doesn't use the exact same flag.

miksy91
April 29th, 2011, 11:51 AM
Somewhat disappointed to see that nobody replied - should have guessed as most people hack 3rd gen anyways.

I thought that I could nevertheless expand this tutorial by putting up new script examples and probably tell something about the script header and such.
If someone actually wants to see more, ask !

machomuu
April 29th, 2011, 01:05 PM
Wow Milksy, I might give this a shot. I've never used PKSV, I've always been an XSE man myself, but I think I'll try it out, thanks for the excellent tutorial :D.

Chimchar 9
April 29th, 2011, 01:24 PM
Finally, there's a scripting Tutorial for G/S/C! I've been waiting for one for ages. I shall try it out soon! Thank you and please add more if you can! :D

Jack Cayman
April 29th, 2011, 01:28 PM
I might try this when it is more known and is slightly easier to do. I usually don't use hex editors too often, but this may make it seem a little interesting.

Sawakita
April 29th, 2011, 04:17 PM
Good tutorial Miksy! I hope this will convince more people to enjoy GSC scripting and hacking.

On a side note: I think you're allowed to post external links as long as they're relevant to the thread (this is actually the right case), as you can see in this sadly forgotten thread (http://www.pokecommunity.com/showthread.php?t=120599).

miksy91
April 29th, 2011, 11:20 PM
Thanks for all the positive comments :)

By request, I happened to write another example.
In it, you encounter a shiny Charizard and I might put up a video of it too.
Check the bottom of the first post to see what it could look like.

itari
May 8th, 2011, 02:43 AM
This is a great tutorial! It's pretty cool that you can have any Pokemon be shiny for a battle. I thought it was special for the gyarados only.

FireSlasher
June 13th, 2011, 12:24 PM
this is slightly off AND on topic. im trying to teach myself to hex edit, and i was attempting to use goldfinger. im completely lost and curious if icould get some help from anybody familiar with goldfinger or any other program

TheOrangePichu
June 30th, 2011, 06:46 PM
Saw your tutorial and I also saw a pretty old tutorial made by cooley. Are these two scripting procedures the same? (using the same commands) or is there something different both of you guys did?

miksy91
July 7th, 2011, 11:44 AM
Saw your tutorial and I also saw a pretty old tutorial made by cooley. Are these two scripting procedures the same? (using the same commands) or is there something different both of you guys did?
If you meant, "did you use different commands to explain it ?", then yes but both of us used Tauwasser's Scripting Compendium as base.

Cheesewig
July 18th, 2011, 12:23 PM
Just wondering if anyone could help me make a script.

The script is like the Guide gent script.
I need the player to follow the character around the map.
Could anyone help me?

HackChu
August 26th, 2011, 07:02 PM
Very good thread. Thanks Milksy, this helps alot my friend.

hinkage
September 3rd, 2011, 04:02 PM
Hey thanks. It's not as long as some GBA ones but it was nice of you to do this. Too bad editing random Trainers requires hex editing. I REALLY loathe hex editing. It's so obsolete when writing programs, and only good for hacking >_>

miksy91
September 14th, 2011, 11:01 AM
I'm still checking this thread every once in a while so in case you have questions about scripting, feel free to ask.

RPD490
September 30th, 2012, 07:11 PM
Wow, I just realized how much more harder it is for me to get one script down, when I was able to do 3-4 types of scripts for FireRed. Anyway I just wanna be able to do a test script for within the Safari Zone, if you saw in the Skeetendo Forum, I posted a pic of a redesigned version of the unused Safari Zone and I wouldn't put anything special in it, just a place you can visit, as well as catch Pokemon in the back, kinda of like the National Park, only this one is in Kanto and is much smaller XD

Anyway if I wanna be able to get more event data to work within there, would I wanna repoint the Map Event Data to maybe the National Park's since the Safari Zone uses the tiles and block data from the National Park. Because really learning how to repoint data is pretty much the barrier thats in my way before I can get into scripting. XD

miksy91
September 30th, 2012, 08:24 PM
Wow, I just realized how much more harder it is for me to get one script down, when I was able to do 3-4 types of scripts for FireRed. Anyway I just wanna be able to do a test script for within the Safari Zone, if you saw in the Skeetendo Forum, I posted a pic of a redesigned version of the unused Safari Zone and I wouldn't put anything special in it, just a place you can visit, as well as catch Pokemon in the back, kinda of like the National Park, only this one is in Kanto and is much smaller XD

Anyway if I wanna be able to get more event data to work within there, would I wanna repoint the Map Event Data to maybe the National Park's since the Safari Zone uses the tiles and block data from the National Park. Because really learning how to repoint data is pretty much the barrier thats in my way before I can get into scripting. XD
You could check out a pointer tutorial I've written and yes, to make Safari Zone actually like a playable map, you'll have to repoint event data to blank space (00 00 00...) and write your own events there and have their script pointers point to blank space in the same rom bank and fill the wanted scripts in there. It's not that complicated once you get used to it.

RPD490
October 1st, 2012, 05:16 PM
Well after learning how to do all this, and thanks to Mateo's tutorial on adding events to Goldmap, I was able to repoint the event data to a free space. So now I just need to do is add scripting to the people I placed in there, as well as the signpost, and adding wild Pokemon data to the park.

jackiekis
October 8th, 2012, 01:31 AM
Oh, please, tell me... I spent months trying to figure out how to modify the Learnset and the level at which pokémon evolve in Gold Edition. Do you use any kind of software, or you do it by code? I would be forever indebted to you if you help me :(

theoblivinator
October 13th, 2012, 06:44 PM
Oh, please, tell me... I spent months trying to figure out how to modify the Learnset and the level at which pokémon evolve in Gold Edition. Do you use any kind of software, or you do it by code? I would be forever indebted to you if you help me :(

You can edit the evolutions and the learnsets of Pokemon using a HEX editor.

In Pokemon Gold go to offset 0x427BD. There will be a table of 251 two-byte pointers that point to the learnset and evolution data for each Pokemon, in Pokedex order. For instance the first pointer is Bulbasaur's and is B3 69 which points to offset 0x429B3.

Go to offset 0x429B3 and you will find Bulbasaur's evolution and learnset data in this format:

[Evolution Data] 00 [Attack Data] 00

Evolution Data is defined like this:

[Evolution Type] [Trigger] [What Pokemon to evolve into]

Evolution types:

0x01 = Level evolution. Your trigger will be the level you want the Pokemon to evolve at.

0x02 = Item evolution. Your trigger will be the item you need to use on the Pokemon to evolve it.

0x03 = Held item trade evolution. Your trigger will be the item your Pokemon needs to be holding while traded to evolve. If you don't need an item the value is 0xFF.

0x04 = Happiness evolution. Your trigger will be any of these values: 0x01 can evolve at any time of day, 0x02 can evolve during the morning or day, 0x03 can evolve at night.

0x05 = Stat evolution (at a certain level). Your trigger will be two bytes long, the first byte will be your level, the second byte will be any of these values: 0x01 for Attack > Defense, 0x02 for Attack < Defense, 0x3 Attack = Defense.

Attack Data is defined like this:

[Level] [Attack]

Remember all your values need to be in hexadecimal.

hakinfreak
March 10th, 2014, 05:40 AM
<p>thanks alot for such a tutorial. Can u tell a bit about flags and how they work? </p><p>&nbsp;</p>

masterxy
April 10th, 2014, 02:53 AM
Nice Tutorial :)
Seeing as there's no real script editor for second gen I might add that to the Tool I'm writing atm. But it will have low priority. Of course I'd need to find out what all the bytes mean first too ^^
But indeed a nice starting point to GSC Scripting :)

com3tiin
April 11th, 2014, 03:13 PM
PKSV works perfectly for the second generation games, only a few commands are different, but the truth is that it works 100%

Thanks to your tutorials I learned to use pKSV

miksy91
April 12th, 2014, 11:45 AM
Nice Tutorial :)
Seeing as there's no real script editor for second gen I might add that to the Tool I'm writing atm. But it will have low priority. Of course I'd need to find out what all the bytes mean first too ^^
But indeed a nice starting point to GSC Scripting :)
We've got all the information right here :)
http://hax.iimarck.us/files/scriptingcodes_eng.htm

Tauwasser has explained a few codes wrong. For instance codes "0A and 0B" should be swapped in terms of what they do, but apart from those small errors, that document is brilliant.

PKSV works perfectly for the second generation games, only a few commands are different, but the truth is that it works 100%

Thanks to your tutorials I learned to use pKSV
Well actually, pskv has a few bugs in it and some things could be implemented better in it as well. But it works well for the most stuff. Only things I can remember it "does" wrong are "fruittree" and some phone call command.

<p>thanks alot for such a tutorial. Can u tell a bit about flags and how they work? </p><p>&nbsp;</p>
Not sure if you're still around or not, but flags are 16-bit values that tell, which value to check from a table that starts in ram address $D7B7.

For example, flag "2A 03" represents for "0x32A"th flag which would be in address: $D7B7 + 0x32A / 0x8

*that dividing by 0x8 comes from the fact that we have to convert the bit value to hexadecimal first before we can sum that to the start of the table ($d7b7).

Once you set a bit number / flag, "1" is written to the address where the flag "points to" and when you reset a flag, "0" is written to that same address. So flags simply point to a single bit in ram.

Amonvangrell
August 27th, 2014, 12:37 AM
Thank you!!! It really looks so cool, I love 2 gen games, for me they're the best!

Dramon Knight
September 7th, 2014, 01:15 PM
Ah, I know you. I've seen you on Romhacking and I watched your G/S/C tutorials on Youtube before. Planning to watch them again as it's been a while since I touched any type of ROM hacking, they were always helpful.

Am still debating on what to do for a hack. I don't want to go mad with big, grand ideas and try things that are too complex in a beginner hack, but it's also pointless if I'm not learning new hacking techniques. Gen 2 deserves more hacks.