Add a New Map to the Game - pret/pokered GitHub Wiki

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

3. Create the following file: /data/maps/headers/TestMap1.asm


	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.

4. Create the following file: /data/maps/objects/TestMap1.asm

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.

6. Edit /data/maps/map_header_pointers.asm

Just like the last file, find the corresponding line and then replace it:

-	dw SilphCo2F_h ; UNUSED_MAP_F4
+	dw TestMap1_h

7. Create the following file: /scripts/TestMap1.asm

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 it's a new map

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!