Custom maps

From Glitch City Wiki
(Redirected from Custom map)
Jump to navigation Jump to search

Using arbitrary code execution and mass memory editing of the RAM, it is possible to create custom maps in the Pokémon games.

In Generation I

This article is incomplete. Please feel free to add any missing information about the subject.
"Twinleaf Town" recreation in Pokémon Yellow

Depending on the tileset, each map is based on a configuration of tiles 2x2 steps wide/high. These combinations are known as map blocks of which there are 256 possible combinations (although only a limited number are valid/used) for each tileset.

Example:

The index numbers of the individual tiles 0x00-0x7F used in the tile blocks can be looked up in BGB's VRAM viewer. When loaded into VRAM, these are stored at 0:9000-0:97FF.

Example:

The little endian pointer to the top-left map block on the screen is stored at D35F/D360 (D35E/D35D in Yellow) and is adjusted when the player is walking around. This pointer can be changed to RAM by adjusting item 33 and item 33 quantity. This method while applying the changes while the menu is opened, does not immediately do so while the menu is closed (unless the player walks around to load the new data). However, the data can be applied by using glitch item 9F (0x5E) in English Yellow, or by swapping an X Attack x18 into item 41 in English Red/Blue (the latter forces the map script to load it).

Normally, D35F/D360 points to RAM anyway and the game writes to the relevant address after a normal map is loaded. Hence, an alternative method for creating a custom map is to write to the intended RAM address (for example the region around C6F9+ in Pallet Town). To create a sense of permanency, the player can use a meta map script in RAM to call copydata to constantly write to this data, even after leaving and returning to the map (as long as the altered meta map script is kept).

Additional features to the map can be added by making the arbitrary code execution program alter the following addresses:

  • D887 (or D886): The start of the wild grass Pokémon data (see Datacrystal). The player needs to be on the same sub-tile stored in D535 (known as the "grass tile"), which is normally 0x52.
  • D8A4 (or D8A3): The start of wild water Pokémon data. All maps use sub-tile 0x14 as the water-tile.
  • D36C-D36D (or D36B-D36C): The text pointer table location for each NPC. This two byte pointer should point to an address itself a list of two byte pointers in the map's text box index number order (when reading a sign/talking to an NPC this is stored at FF8C).
  • D36E-D36F (or D36D-D36F): The "level-script pointer". It is basically a little endian pointer to a script that is run continuously when the menu is closed (which is also an ideal arbitrary code execution method through adjusting item 41 in the expanded inventory). The bank of the script for pointers ranging between 4000-7FFF depends on the currently loaded map at D35E/D (see this article on Bulbapedia for each map's bank).
  • D35E (or D35D): The currently stored map. Upon changing it, this will control the palette, Town Map name/position on map; however, this will not warp the player automatically (the player can however warp instantly using the previously mentioned 9F or X Attack x18 methods but data like coordinates D361-D362 (-1), coordinate block D363-D364 (-1) may have to be adjusted with it).
  • D367 (or D366): "wCurMapTileset", although changes will not be applied to the tileset. This address however modifies field move permissions. 0x00 indicates that the player can Fly and Teleport away. 0x06 is used for buildings where it is impossible to escape with any field move. 0x11 is for dungeons/in-door places where it is possible to Dig or Escape Rope away.
  • D35B/A: Music played on map. These changes are not automatic, so including code in the map script to play it may be a reasonable idea.[elaboration needed] A list of values can be found in the Pastebin paste here
  • D35C/B: Bank for music. Valid banks can again be found on the above pastebin link (note: bank 0x20 is bank 0x28 in the Japanese version of Yellow).
  • The following addresses (-1 in Yellow) control tileset data. To properly apply the changes, it may be required to open and close the Pokédex. An example use for this is to view this region in a memory viewer in a cave, note the data down and then copy it on another map to bring up the cave tileset in an unintended way. Custom tilesets may theoretically be possible, which might allow for a map that looks like it's from an entirely different game.
wTilesetBank:: ; d52b

	ds 1

wTilesetBlocksPtr:: ; d52c

; maps blocks (4x4 tiles) to tiles

	ds 2

wTilesetGfxPtr:: ; d52e

	ds 2

wTilesetCollisionPtr:: ; d530

; list of all walkable tiles

	ds 2

wTilesetTalkingOverTiles:: ; d532

	ds 3
  • Additional text boxes can be 'added' by adjusting the following (-1 in Yellow). Note although there are only intended to be a maximum of 16 signs, more can be forced although this will assume the wSignCoords and wSignTextIDs are beyond the buffer. wSignTextID is the text box index (the FF8C value) for each sign in order.
wNumSigns:: ; d4b0

; number of signs in the current map (up to 16)

	ds 1

wSignCoords:: ; d4b1

; 2 bytes each

; Y, X

wSignTextIDs:: ; d4d1

Others (-1 in Yellow). Note: When adjusting wWarpEntries, the warp must be a suitable tile to function, such as a door or ladder.

wCurMapHeight:: ; d368
; blocks
	ds 1

wCurMapWidth:: ; d369
; blocks
	ds 1

wMapDataPtr:: ; d36a
	ds 2

wMapConnections:: ; d370
; connection byte
	ds 1

wMapConn1Ptr:: ; d371
	ds 1

wNorthConnectionStripSrc:: ; d372
	ds 2

wNorthConnectionStripDest:: ; d374
	ds 2

wNorthConnectionStripWidth:: ; d376
	ds 1

wNorthConnectedMapWidth:: ; d377
	ds 1

wNorthConnectedMapYAlignment:: ; d378
	ds 1

wNorthConnectedMapXAlignment:: ; d379
	ds 1

wNorthConnectedMapViewPointer:: ; d37a
	ds 2

wMapConn2Ptr:: ; d37c
	ds 1

wSouthConnectionStripSrc:: ; d37d
	ds 2

wSouthConnectionStripDest:: ; d37f:
	ds 2

wSouthConnectionStripWidth:: ; d381
	ds 1

wSouthConnectedMapWidth:: ; d382
	ds 1

wSouthConnectedMapYAlignment:: ; d383
	ds 1

wSouthConnectedMapXAlignment:: ; d384
	ds 1

wSouthConnectedMapViewPointer:: ; d385
	ds 2

wMapConn3Ptr:: ; d387
	ds 1

wWestConnectionStripSrc:: ; d388
	ds 2

wWestConnectionStripDest:: ; d38a
	ds 2

wWestConnectionStripHeight:: ; d38c
	ds 1

wWestConnectedMapWidth:: ; d38d
	ds 1

wWestConnectedMapYAlignment:: ; d38e
	ds 1

wWestConnectedMapXAlignment:: ; d38f
	ds 1

wWestConnectedMapViewPointer:: ; d390
	ds 2

wMapConn4Ptr:: ; d392
	ds 1

wEastConnectionStripSrc:: ; d393
	ds 2

wEastConnectionStripDest:: ; d395
	ds 2

wEastConnectionStripHeight:: ; d397
	ds 1

wEastConnectedMapWidth:: ; d398
	ds 1

wEastConnectedMapYAlignment:: ; d399
	ds 1

wEastConnectedMapXAlignment:: ; d39a
	ds 1

wEastConnectedMapViewPointer:: ; d39b
	ds 2

wSpriteSet:: ; d39d
; sprite set for the current map (11 sprite picture ID's)
	ds 11

wSpriteSetID:: ; d3a8
; sprite set ID for the current map
	ds 1

wObjectDataPointerTemp:: ; d3a9
	ds 2

	ds 2

wMapBackgroundTile:: ; d3ad
; the tile shown outside the boundaries of the map
	ds 1

wNumberOfWarps:: ; d3ae
; number of warps in current map
	ds 1

wWarpEntries:: ; d3af
; current map warp entries
	ds 128

wDestinationWarpID:: ; d42f
; if $ff, the player's coordinates are not updated when entering the map
	ds 1

	ds 128

In Generation II

This article or section is a stub. You can help Glitch City Wiki by expanding it.
A custom map in Pokémon Gold and Silver

As documented by Crystal_ custom maps are possible in Pokémon Gold, Silver and Crystal by using a specific glitch map with a map group pointer in RAM (i.e. map D003 is suitable). NPC sprites and wild Pokémon are also possible.

YouTube video by Crystal_