PHO - Pokémon Hackers Online
Go Back   PHO - Pokémon Hackers Online > Hacking Suite > Resources and Tutorials > Generation 1 & 2


Generation 1 & 2 RBY and GSC Resources and Tutorials. Mostly for disassembly.

User Tag List

Thread Tools Display Modes
Old 20th September 2016, 02:12 AM   #1
Pia Carrot
Orange Developer
Pia Carrot's Avatar
Join Date: Aug 2010
Location: Valencia Island
Age: 27
Posts: 366
Pia Carrot Pia Carrot Pia Carrot Pia Carrot Pia Carrot
Default pokecrystal For Dummies (OUTDATED)

Table of Contents:

I. Introduction
II. Installation
III. Mapping
IV. Editing Graphics
V. Adding/Editing Pokémon
VI. Scripting/Battles
VII. Wild Pokémon Editing/Legendary Encounters
VIII. Tips And Tricks
X. Resources
XI. Conclusion

I. Introduction

Hello there, hacker! My name is Pia Carrot, although I prefer to go by Aizawa these days. Today I would like to introduce to you the Pokemon Crystal disassembly and the potential it has for ROM hackers.

You may remember me from my older tutorial, Pokéred for Dummies, which was not complete. I aim to release a complete guide this time, and I am rather confident I can complete this one.

I would like to thank Rangi, Mateo, comet, Mmmmm, and so many more for help and information on how many things in the disassembly work, so a big shoutout to them for making this guide possible. Please keep in mind all my guides are for Windows, I can not help with issues relating to Linux and Mac. Without further ado, let's begin!

II. Installation

My last installation guide was a bit of a mess, and I did not go through the steps accurately, which resulted in a lot of confusion and frustration for users. For a completely clarified, cannot mess up guide please check out ShantyTown's video, but use the pokecrystal url instead of pokered:

On top of this I recommend you use a program like Notepad++ to edit files. It's much more useful than standard Notepad and has very useful functions like find + replace all.

III. Mapping

Once you have the disassembly installed, you will need to install Crowdmap, by Yenatch. You could also edit maps in hex but I do not recommend this.

the following is transcribed from All credit to Leonardo Petrucci.

Editing and adding maps is thankfully one of the easiest jobs to do thanks to tools developed by the community, however it might still be kind of tricky, so I’m going to try to explain everything.

1. Add Maps

Assuming that you already have your Cygwin set up and the disassembly downloaded, adding maps should be fairly easy. In this we will be adding a new area connected to New Bark Town, so that it will be easier for you to test out.

Let’s start it off simple enough by setting up Crowdmap, this neat little program will give you a visual of your maps without having to build the game every time, it will also help you add new maps and edit them. You can find the download here, drop the crowdmap folder into your pokecrystal directory, it should look something like this pokecrystal/crowdmap/. The instructions to start Crowdmap are fairly simple and are explained dirctly in the github page.

Once set up, you should be able the fairly simple to use interface. Let’s click on + New Map to add a new map. I’m going to set the name to Route101, you can use whatever you want. The map group is going to define how your map is ordered with the others, I set Mapgroup24, since it’s the one where New Bark Town already is.

This will automatically add the lines I explain how to add next, so when following those steps, make sure not to add any additional lines, but edit the already existing one instead. CTRL+F should find your newly added map fairly easily.

There are a few .ASM files that you will need to edit to add a new area, these are:



Open up your map_header.asm, to make it easier, we’re going to copy what has already been set-up for Route 29. Let’s just ctrl+f the file, and find this line:

Once you find it, copy it and paste it right under it. Let’s, of course, change the name so that it won’t interfere with the already existing one. I’m going to call my new area Route 101, you can call it whatever you want, just make sure the name isn’t already used. Once edited you should have something similar to this:

This not only sets the name for the map, but also the tileset it’s using (TILESET_JOHTO_1), the name your map is going to be referred to in the code (ROUTE_101), the music (MUSIC_ROUTE_29). The other entries can be looked over, these are the most important.

Once that is done, open up constants/map_constants.asm, as with before, ctrl+f to find the already existing ROUTE_29 entry, copy it and paste a copy right under it. It should look something like this:

mapgroup ROUTE_101, 10, 10
This is going to be used to define the size of your map, 10 and 10 being my X and Y.

Once that is done move over to maps/second_map_headers.asm, as we already did before, let’s copy the already existing Route 29 entry and trim it down a little bit, since we won’t need all the entries it has. Our route only has one entry point, from the south of New Bark Town, which means that New Bark Town will need a connection to the south, and our map will need one to the north. Your area entry should look something like this.

map_header_2 Route101, ROUTE_101, $5, NORTH
connection north, NEW_BARK_TOWN, NewBarkTown, 0, 0, 10, ROUTE_101
Of course here you have the name of your route, the name of your file, what defines what fills the sides of your map ($5), and where the connection is going to be (NORTH). On the next line you will define the connection to the north. NEW_BARK_TOWN, of course, is the name of the file you want to connect to, NewBarkTown is the name of the map. 0/0/10 are what defines where your connection starts, let’s call them X, Y and Z. X will move where the connection to the map starts, 0 will be perfect center, 1 will move it to the right, and -1 moves it to the left. Y does the exact thing as X, just on another axis, 1 will move it up, -1 will move it down and 0 will be exactly at the center. Z is probably the most important, it’s what defines the size of the connection.

This might require you some fiddling, but you should be able to figure it out fairly easily trough trial and error.

This just added a connection from your area to New Bark Town, but obviously you also need a way to go to your area from New Bark. So let’s just add a connection to the already existing code. At the moment it should look something like this:

map_header_2 NewBarkTown, NEW_BARK_TOWN, 5, WEST | EAST
Let’s add a connection to the south by adding | south.

map_header_2 NewBarkTown, NEW_BARK_TOWN, 5, WEST | EAST | SOUTH
And then just add a connection under that:

connection south, ROUTE_101, Route101, 0, 0, 10, NEW_BARK_TOWN
Should be the same as the first one you added for your area, just with the names inverted.

I’m going to make it perfectly clear that despite Crowdmap being listed as an option, it is an extremely powerful tool that YOU SHOULD USE. Download it and set it up, it will help you a lot.

2. Edit Maps

In order to edit maps in Crowdmap, simply follow the instructions from the readme.

Clone inside your pokecrystal repo. Then:

python png gfx/tilesets/*.2bpp.lz gfx/tilesets/roofs/*.2bpp gfx/overworld/*.2bpp
touch gfx/tilesets/*.2bpp gfx/tilesets/roofs/*.2bpp gfx/overworld/*.2bpp
touch gfx/tilesets/*.2bpp.lz

Then run python crowdmap/ 8000 and go to
From there, you can edit the maps as you would any other map editor! It's still missing a lot of features, such as a block editor, but it does what it needs to do! If you are having issues getting it to save, spam click save and tell the notifications to stop, and if you are getting off graphical errors on your maps, clear your cache. The only downside to browser map editing.

3. Warps

Warps are probably the most simple thing to add into a map. All the warps are contained directly into the ASM for the map you’re currently editing, in our case, Route101.asm.

If your file was created through Crowdmap, this is what you’re going to see the first time you open it up to edit it:

As you can probably imagine, your warps are going to be placed under .Warps: db 0

Let’s add a warp between New Bark Town and the new map. First off, let’s add a way to visually tell the player that there is a warp in New Bark, this can be done by many means, I decided to go for the pink patterns.

Next, in the map for New Bark town (NewBarkTown.asm), and under warps let’s add two warps generating at coordinates 1, 1 that connect themselves to our new map, ROUTE_101:

.Warps: db 6
warp_def 3, 6, 1, ELMS_LAB
warp_def 5, 13, 1, KRISS_HOUSE_1F
warp_def 11, 3, 1, KRISS_NEIGHBORS_HOUSE
warp_def 13, 11, 1, ELMS_HOUSE
warp_def 1, 1, 1, ROUTE_101
warp_def 1, 1, 1, ROUTE_101
Did you notice that I also changed db 4 to db 6? The number after db should always be the same number as the number of events listed after it.

Now you have two options: Either manually change the X and Y values of your warps to bring them to where you want them OR go into crowdmap and drag them where you need them. As you can see, right now, the warps are positioned at X1 and Y1. Just move them where you want them in crowdmap.

Now let’s move on to our new map and do what we just did for New Bark here. This is pretty straight forward, the editing is pretty much the same, but in a different file. The only thing you should look out for is the third number used after the X and Y positions that we will call Z. Z is there to tell the game on which warp the player should come out once they walk into one. If Z is 1, once the player enters in the warp in ROUTE_101, he will end up coming out of Elm’s Lab. In this case you either want to set Z as 5 or 6, so that the player will come out of the same warp they came in.

4. Signs

Signs are fairly simple, and will give you a general understanding of how text works. Similarly to warps, they are added from the map’s ASM file. Find this line:

.BGEvents: db 0
And add this dummy placeholder right under it. Of course, don’t forget to edit db 0 to the number of events you will add under BGEvents,

signpost 3, 11, SIGNPOST_READ, TestMapSign
As discussed with warps, the two numbers after signpost are the X and Y coordinates of the event. You can either edit them from the code, or move them around in crowdmap.

Now, for whatever reason, you can’t directly point a sign directly to the test, so before going on to writing the text, you will have to add a way to jump to the text on the sign. It doesn’t matter where you add this, but you will need to do it this way, any other way will crash the game. Add this at the bottom of the code:

jumptext TestMapSignText

text "TEST MAP"

para "This is actually"
line "Working!"

para "I can hardly"
line "believe it"
cont "myself!"
Text is the start of the text, it should always be what starts your text. Para will start a new paragraph, while Line will continue writing automatically under para without input. Cont will instead only appear if input is received. Done is of course what ends the text, it should always be at the end.

?. Bugfixes

1. ‘Tileset Data *’ is too big

I first encountered this right after adding my first map. This is caused by problems with the compression script that handles some of the tilesets, and unfortunately there isn’t an easy fix.

What you can do is open up all your Data_*.asm files and move things between them until the error isn’t there anymore. This might take a while, but it’s unlikely you will experience it again once fixed. It’s mostly done trough trial and error, so I can’t help you much on that front.

2. Unable to load fixed ROMX section

This is a similar problem to the one described before. As far as I’ve noticed, it’s caused because too much data is being uploaded to a single Bank. The fix for this is the same for the one before, but unlike with the previously described error, the terminal will not tell you which file is too big, and it will be up to you to figure out.

But, luckily enough, I stumbled upon what defines the $XX numbers the error gives out and was able to understand what file they’re connected to. Here’s the possibilities:

BANK $06 = Data_1.asm

BANK $07 = Data_2.asm

BANK $08 = Data_3.asm

BANK $0C = Data_4.asm

BANK $2D = Data_5.asm

BANK $37 = Data_6.asm

BANK $77 = Data_7.asm

BANK $78 = Data_8.asm

3. Nothing to be done for ‘all’

Pretty simple fix. Just write:

rm pokecrystal.gbc
In your Cygwin terminal, and then run “make” again.

IV. Editing Graphics

Okay, so you've made a few maps, moved some events around, and you're ready to make your rival battle or change that Rattata into a Bidoof. Maybe you want to add that swanky new tree tile, or change your player's appearance? Well, here is how you can do it.

Any and all graphical assets are going to be found in the gfx folder, obviously. I'll leave it up to you to find what you need, since most of it is obvious, but if you cant find that weird interface graphic or that player backsprite, it's probably in misc.

Most files are compressed, so unlike pokered you won't be able to immediately edit them. To decompress them, simply call:

python png gfx/folderyouwant/fileyouwant.2bpp.lz
You can also decompress whole folders:

python png gfx/folderyouwant/*.2bpp.lz
Upon recompiling you may run into the issue of full space, this can be fixed by finding what bank the file in question is. For Pokemon and trainer sprites, this will be gfx/pics.asm

Once you decompress your image, you can edit it, although if it compiles and your new sprite palette does not change, you'll have to edit the sprites .pal file, which can also be found in gfx. You can do this in Notepad ++. To find the RGB values you need, simply divide the corresponding RGB values in Paint by 8.

Also, if you want to disable sprite animations for a Pokemon sprite you've changed, because the animation no longer looks right, for obvious reasons, you simply edit the files gfx/pics/anims.asm and gfx/pics/extras.asm. Replace each Pokémon's "INCLUDE" line with just "endanim". You can also edit bitmasks.asm, kanto_frames.asm, and johto_frames.asm, removing the "INCLUDE"s entirely, since they're no longer needed. Credit to Rangi for this method.

VileplumeAnimation:  endanim "gfx/pics/vileplume/anim0.asm"

V. Adding/Editing Pokémon

So I'm not actually going to get too in depth about adding new Pokemon, since it isn't really something I've looked into, due to restrictions the engine has placed on itself, however, hopefully this will soon be remedied.

However, as for replacing existing Pokémon, I can help you there.

So assuming you now know how to change a Pokémon's sprite from the last section, I'll be getting into how to change the name, base stats, etc. Please note I'm not sure how cries work at this time so I can't help you there.

Most of the Pokémon's info can be found in the data folder, under base_stats, pokedex/entries, pokemon_names.asm, and so on. Not much else to say about this, it's very easy to do.

VI. Scripting/Battles

Scripting might take a bit to learn, I still haven't mastered it but you if open up any maps .asm file in the maps folder, you can see each one has a set of scripts. If you've ever used PKSV or XSE it should come pretty easily to you. Battle might require a bit more effort to set up but not impossible at all. Just reference some battle code on Route 30, or your rival in Cherrygrove City for some ideas. If you refer to the mapping section Leonardo goes over adding signs, this is a very easy way to get started with scripting.

This section will eventually be redone once I have an in depth scripting guide prepared for it.

VII. Wild Pokémon Editing/Legendary Encounters

Wild Pokemon data can be edited in data/wild. As far as I know there is no way to make different water encounters for every route, but if someone decides to create a way and decides to share it, let me know so I can include it here.

The code for Entei and Raikou's roaming can be found in engine/wildmons.asm

As for legendary battles like Lugia, Ho-oh, etc, reference their code from Tin Tower and Whirl Islands. Creating your own is very simple!

	db 0

	db 1

	; callbacks


	iftrue .NoAppear
	checkitem SILVER_WING
	iftrue .Appear
	jump .NoAppear



	writetext LugiaText
	cry LUGIA
	pause 15
	loadwildmon LUGIA, 60

	text "Gyaaas!"

	; filler
	db 0, 0

	db 1
	warp_def $d, $9, 3, WHIRL_ISLAND_B2F

	db 0

	db 0

	db 1

VIII. Tips And Tricks
  • You can search for code in the actual disassembly, in the search bar at the top of:
  • It's recommended you set up a fork on github, I personally do not do this.
  • A lot of code is pretty spaghetti, so don't get too upset if something is frustrating to work with.
  • Have any more?


Ask away!

X. Resources

Large pack of Pokemon sprites compiled by me: Download
Skeetendo Forums: Click Here
My Deviantart (Check the people I've featured on my page): Click Here

XI. Conclusion

I hope this guide has helped you with your interest in Gen II hacking and if you did be sure to leave a thanks and spread the word. I had a lot of fun writing it, and I can only hope it will help others get started with the disassembly. Thanks for looking!

Pia Carrot is offline   Reply With Quote
Sponsored Links

dummies, outdated, pokecrystal

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT. The time now is 09:17 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2022, vBulletin Solutions, Inc. User Alert System provided by Advanced User Tagging (Lite) - vBulletin Mods & Addons Copyright © 2022 DragonByte Technologies Ltd.
Feedback Buttons provided by Advanced Post Thanks / Like (Lite) - vBulletin Mods & Addons Copyright © 2022 DragonByte Technologies Ltd.
Pokémon characters and images belong to Pokémon USA, Inc. and Nintendo.
Pokémon Hackers Online (PHO) is in no way affiliated with or endorsed by Nintendo LLC, Creatures, GAMEFREAK inc,
The Pokémon Company, Pokémon USA, Inc., The Pokémon Company International, or Wizards of the Coast.
All forum/site content (unless noted otherwise) and site designs are © 2006-2013 Pokémon Hackers Online (PHO).
Green Charizard Christos TreeckoLv100

"Black 2" by ARTPOP. Kyurem artwork by XOUS.

no new posts