Sonic 2 Hacking Guide
Binary - Level Editing

The object layout consists of the X and Y coordinates, as well as a 16-bit object type definition. In the floor layout section, you can edit the floor layout in a level from a selection of 256 different 128x128 tiles (zero being a null selection).

Object Layout
Rings don't work by placing them one by one. Instead, you can choose how many rings in a row or column from 1 to 8 (each ring being separated by 24 pixels). Rings in a set depend on the Y position of the set of rings. For an example, using 0400 for the Y position will yield 1 ring. If you use 1400 for the Y position, the game will yield 2 rings. The first 8 sets will place rings in a horizontal row, while the last 8 are used for a vertical column. If you use "FF FF", the game will stop reading any further placements.

0E4300 - List of 16-bit offset pointers for each level/act

0E4344 - EHZ1 rings (example)
0E456A - EHZ2 rings
- MZ1 rings
0E4A2A - MZ2 rings
0E4C48 - MZ3 rings
0E6454 - WFZ rings
0E4D74 - HTZ1 rings
0E4EAA - HTZ2 rings
- HPZ1 rings
0E525A - HPZ2 rings
0E5260 - OOZ1 rings
0E5422 - OOZ2 rings
0E5598 - MCZ1 rings
0E570E - MCZ2 rings
0E5944 - CNZ1 rings
0E5B7E - CNZ2 rings
0E5E2C - CPZ1 rings
0E5F9E - CPZ2 rings
0E6150 - DEZ rings
0E6294 - ARZ1 rings
0E642E - ARZ2 rings
0E6684 - SCZ rings

#1 #2 #3 #4

1 + 2 - X offset
3 + 4 - Y offset

Other objects work similar to rings. Like the rings, the first 4 bytes define the X and Y coordinates. You can't place objects in rows like you can rings though. You will also have an additional 2 bytes afterwards to which define what the object is. The first one sets the main object value. The second one is used to give the object specific properties. You can add 8000 to the Y value to make the object so that it doesn't respawn after being destroyed. This is usually the case for enemies and monitors. Also, make sure that the object are placed in order of X and Y. If you have an object at X position 0B, and then another object after that at X position 04, the object at position 04 will not display because it reads it 'after' you get to the object at X position 0B. So, it's reading an object at a position you have already passed. If you have multiple objects at the same X position, then you must have them in order by Y position. This is useful however, because if you use "FFFF 0000 0000", then the game will know that you don't want any other objects to be used for the level.

#1 #2 #3 #4 #5 #6

1 + 2 - X offset
3 + 4 - Y offset
5 - Object
6 - Object type/properties

0E684A - EHZ1
0E6B7A - EHZ2
0E6F34 - MZ1
0E73C0 - MZ2
0E78EE - MZ3
0E7F48 - WFZ
0E8302 - HTZ1
0E8668 - HTZ2
0E8C80 - HPZ1
0E8D94 - HPZ2
0E8DA0 - OOZ1
0E9214 - OOZ2
0E968E - MCZ1
0E99A0 - MCZ2
0E9D1E - CNZ1
0EA3D8 - CNZ2
0EA9D2 - CPZ1
0EB230 - DEZ
0EB25A- ARZ1
0EB6A4 - ARZ2

Click here for object list

Here are two very useful pointers. These point to the sections that have been explained above. This is useful information if you want to move the object and/or ring layout to another location in the ROM. This also helps give expandability.

0172D0 - Ring layout pointer
017AC6 - Object layout pointer

If you are designing your own level, it may help you to select the size of the level. This way, you won't be so limited.

00C056 - Level sizes

The first set of bytes (2) will tell the X size. After that will tell how much to cut off of the left side of the play area (generally none cut off). the next set is the Y size. After that is how much to cut off of the top of the play area. If the Y size is 08 00 or higher, you can change the last set to FF 00 to have the level wrap! This works with X sizes to, but is very buggy.

00C0D6 - Level start positions.

Start positions are very easy to work with. The first 2 bytes define the X position, and the next 2 bytes define the Y position. There are two start positions for each level (act 1 and act 2).

004584 - HPZ1
004586 - HPZ2
004588 - GCZ1
00458A - GCZ2
00458C - OOZ1
00458E - OOZ2
004590 - MCZ1
004592 - MCZ2
004594 - CNZ1
004596 - CNZ2
004598 - CPZ1
00459A - CPZ2
00459C - DEZ1
00459E - DEZ2
0045A0 - ARZ1
0045A2 - ARZ2
0045A4 - SCZ1
0045A6 - SCZ2

Water height definitions use 16-bits for each individual act to define how high the water initially is. Although, only HPZ and up have water height definitions. The water height can be set by using the screen Y position (bottom-right cordinates of the score in debug mode) as a base to work from.

Floor Layout
The floor layout in Sonic 2 is heavily compressed. However, if you really want to understand how this format works, take a look at
Brett Kosinski's notes. He's the one who was the first to fully understand the format.

045A80 - List of 16-bit offset pointers for each level/act

045AC4 - EHZ1
045C84 - EHZ2
045E84 - MZ1
0462A4 - MZ2
046684 - MZ3
046B04 - WFZ
046DD4 - HTZ1
047044 - HTZ2
047404 - OOZ1
047784 - OOZ2
047B24 - MCZ1
047D24 - MCZ2
047FF4 - CNZ1
0483C4 - CNZ2
048774 - CPZ1
048A84 - CPZ2
048DE4 - DEZ
048E94 - ARZ1
049264 - ARZ2
049634 - SCZ

Check out these pages to see the many different 128x128 blocks available.

Emerald Hill
Chemical Plant
Hill Top
Mystic Cave