-
Notifications
You must be signed in to change notification settings - Fork 995
Add a New Map to the Game
Date created: 2020-12-01 Updated 14th June 2023
This tutorial is for adding a new map to the game. This is NOT a map making tutorial--this tutorial shows the exact files that need edited to add a map into the game. Therefore it is assumed that you have already created your own custom map. I'll be using the name 'TestMap1' for the tutorial, but you should swap in your own map name.
1. Put your .blk map file (TestMap1.blk) in the /maps/ folder
2. Edit /constants/map_constants.asm
Look for a line that says 'UNUSED'.
You need to pay attention to which line you use, because you'll need to replace that exact same line in a few other files later.
For this tutorial, I am replacing 'UNUSED_MAP_F4' with my custom map.
Replace that line with a line like so:
- mapconst UNUSED_MAP_F4, 0, 0 ; $F4
+ mapconst TEST_MAP_1, 6, 5 ; $F4
- The first part 'mapconst' is required and can't be changed
- The second part 'TEST_MAP_1' is where you put the name of your map
- NOTE: You should follow the same naming format the other maps use to avoid issues down the road
- The two numbers after the name are the height and width of the map
- This needs to match the height and width you used when creating the .blk map file
- Anything after a semi-colon at the end of a line is a comment, it's not actual code and just used for reference
map_header TestMap1, TEST_MAP_1, CEMETERY, 0
end_map_header
Change 'CEMETERY' to whatever tileset your map uses.
Keep the rest the same (use your map's name in place of TestMap1 of course).
Remember to follow the naming scheme--if they use all caps and underscores, do the same thing.
TestMap1_Object:
db $0 ; border block
def_warp_events
warp_event 4, 11, REDS_HOUSE_2F, 1
def_bg_events
def_object_events
def_warps_to TEST_MAP_1
- The first line, 'db $0' sets the block used for the outside border of the map
- The next section, 'def_warp_events' is for setting up warps
- The word 'warp_event' is required at the beginning of each warp
- The first and second numbers are coordinates of where the warp is on the map
- Use a map editor like Polished Map to find map coordinates
- The fourth number is a 'warp ID' that indicates which warp to go to on the following map
- Warps are counted in the order they are listed in the file, starting from 0
- So the first warp in a file has an ID of 0, the second has an ID of 1, etc.
- In my example, I'm warping from my TestMap1 to REDS_HOUSE_2F. If you open data/maps/objects/RedsHouse2F.asm and look at the list of warps, you'll only see one warp (the stairway going downstairs). This is the first (and only) warp on that map, so it's ID is 0
- The name after the warp ID is the name of the map you are warping to
- Notice the capitalization and underscores, this is required
- The next section, 'def_bg_events' is for setting up signs that display text
- This is not required and isn't covered in this tutorial
- The next section, 'def_object_eventss' is for setting up objects (NPCs, trainers, etc)
- This is not required and isn't covered in this tutorial
- At the end of the file you need the 'def_warps_to' line
- I believe this sets up any maps that warp to your map, but I'm not sure
5. Edit /data/maps/map_header_banks.asm
Remember that line I told you to remember earlier? You need to find that line in this file, and then replace it:
- db $11 ; UNUSED_MAP_F4
+ db BANK(TestMap1_h)
You don't have to use 'UNUSED_MAP_F4', you can replace any map including maps that already exist in the game.
Just like the last file, find the corresponding line and then replace it:
- dw SilphCo2F_h ; UNUSED_MAP_F4
+ dw TestMap1_h
TestMap1_Script:
jp EnableAutoTextBoxDrawing
TestMap1_TextPointers:
text_end ; unused
As far as I can tell, these two parts are required, even if you have no scripts or texts for the map
8. Edit /maps.asm
We need to include our map's files in this list somewhere. I decided to add mine after the last map in the file, which is Agatha's Room. Look for the line AgathasRoom_Blocks: INCBIN "maps/AgathasRoom.blk" and add the following underneath:
INCLUDE "data/maps/headers/AgathasRoom.asm"
INCLUDE "scripts/AgathasRoom.asm"
INCLUDE "data/maps/objects/AgathasRoom.asm"
AgathasRoom_Blocks: INCBIN "maps/AgathasRoom.blk"
+INCLUDE "data/maps/headers/TestMap1.asm"
+INCLUDE "scripts/TestMap1.asm"
+INCLUDE "data/maps/objects/TestMap1.asm"
+TestMap1_Blocks: INCBIN "maps/TestMap1.blk"
9. Edit /data/maps/hide_show_data.asm
For this step, we need to say if there will be any "hideable" or "showable" objects on our map. For example, all the Rockets in Saffron City are hideable, since after you defeat Giovanni in the Silph Co. all of the Rockets will disappear (become hidden). This is accomplished through the use of the function HideObject
(or conversely ShowObject
).
For simplicity, we will not have any hideable/showable objects in our new map. So make the following change in regards to our map UNUSED_MAP_F4
:
- dw UnusedMapF4HS
+ dw NoHS
Later in the file, delete the following lines:
-UnusedMapF4HS:
- db UNUSED_MAP_F4, $02, SHOW
If we did want hideable/showable objects, then we would need to keep this part of the code and use dw UnusedMapF4HS
instead of dw NoHS
; although, we should use TestMap1HS
for the name to stay consistent. In the assembly instruction, db UNUSED_MAP_F4, $02, SHOW
, the first byte UNUSED_MAP_F4
is the map where the hideable/showable objects will be. The second byte $02$
indicates that the second object in data/maps/objects/TestMap1.asm
under def_object_events
will be the hideable/showable object. And lastly, SHOW
indicates that the object will be shown. If you wanted the object to start out hidden, then we would instead use, HIDE
.
That's all the required steps to add a new map. All you need to do is set up a warp to your map from another map.
At this point you'll probably want to add trainers, NPCs, text etc. There should already be some tutorials out there for those, but I may make my own tutorials later if need be.
If you're adding a new map, all the above applies, only you just need to add to the end of a file instead of replace.
However, you will also need to edit data\wild\grass_water.asm
like so:
WildDataPointers:
table_width 2, WildDataPointers
dw NothingWildMons ; PALLET_TOWN
...
dw CeruleanCave1FWildMons
dw NothingWildMons
dw NothingWildMons
+ dw NothingWildMons ; Or whatever is equivalent
If your map needs wild data, use dw NamehereWildMons
, where "Namehere" is the name of your map, and then add this to the bottom of the file:
; wild pokemon data is divided into two parts.
; first part: pokemon found in grass
; second part: pokemon found while surfing
; each part goes as follows:
; if first byte == 0, then
; no wild pokemon on this map
; if first byte != 0, then
; first byte is encounter rate
; followed by 20 bytes:
; level, species (ten times)
INCLUDE "data/wild/maps/nothing.asm"
INCLUDE "data/wild/maps/PowerPlant.asm"
INCLUDE "data/wild/maps/Route23.asm"
INCLUDE "data/wild/maps/VictoryRoad2F.asm"
INCLUDE "data/wild/maps/VictoryRoad3F.asm"
INCLUDE "data/wild/maps/VictoryRoad1F.asm"
+INCLUDE "data/wild/maps/Namehere.asm"
If you are doing this, make a wild data file in the maps
folder you'll see in the same area. Here's an example;
CeruleanCave1FWildMons:
def_grass_wildmons 10 ; encounter rate
db 46, GOLBAT
db 46, HYPNO
db 46, MAGNETON
db 49, DODRIO
db 49, VENOMOTH
db 52, ARBOK
db 49, KADABRA
db 52, PARASECT
db 53, RAICHU
db 53, CLEFAIRY
end_grass_wildmons
def_water_wildmons 0 ; encounter rate
end_water_wildmons
Switch def_water_wildmons
to 10 to enable water encounters.
If your map has water and you want to make it have Rod encounters, go to super_rod.asm
and edit like so:
; super rod encounters
SuperRodData:
; map, fishing group
dbw PALLET_TOWN, .Group1
dbw VIRIDIAN_CITY, .Group1
dbw CERULEAN_CITY, .Group2
...
dbw CERULEAN_CAVE_1F, .Group9
+ dbw NAME_HERE, .GroupHere
You can make your own fishing groups by simply making them like this;
.Group8:
db 4
db 15, STARYU
db 15, HORSEA
db 15, SHELLDER
db 15, GOLDEEN
You will also want to add an entry to data/maps/songs.asm
, like so;
MapSongBanks::
table_width 2, MapSongBanks
db MUSIC_PALLET_TOWN, 0 ; PALLET_TOWN
...
db MUSIC_DUNGEON1, 0 ; CERULEAN_CAVE_2F
db MUSIC_DUNGEON1, 0 ; CERULEAN_CAVE_B1F
db MUSIC_DUNGEON1, 0 ; CERULEAN_CAVE_1F
db MUSIC_CITIES2, 0 ; NAME_RATERS_HOUSE
db MUSIC_CITIES1, 0 ; CERULEAN_BADGE_HOUSE
+ db MUSIC_NAMEHERE, 0 ; NAME_HERE (it's helpful trust me)
Another thing you want to keep in mind is editing data/maps/town_map_entries.asm
, in order for your map to be shown in the proper location on the town map.
This is the minimum necessary to ensure an entirely new map can build, but it's worth poking around to see where you can get the most out of your new map. For example, dungeon_maps.asm
can change the wild encounter animations, badge_maps.asm
has gym leader associations, and there are various town map associations as well. Experimentation is encouraged - there's a lot you can do here!