s3k-disasm Navigation Guide
This skill provides guidance on finding, identifying, and interpreting items in the Sonic 3 & Knuckles disassembly (docs/skdisasm/).
Directory Structure
S3K is organized very differently from S1/S2 — per-zone directories under Levels/:
| Directory | Contents | Notes |
|---|---|---|
Levels/{ZONE}/ | Per-zone data | AIZ, HCZ, MGZ, CNZ, FBZ, ICZ, LBZ, MHZ, SOZ, LRZ, HPZ, SSZ, DEZ, DDZ |
Levels/{ZONE}/KosinskiM Art/ | Kosinski Moduled compressed art | Primary art compression type |
Levels/{ZONE}/Nemesis Art/ | Nemesis compressed art | Secondary art compression |
Levels/{ZONE}/Tiles/ | Raw tile patterns | Uncompressed tile data |
Levels/{ZONE}/Blocks/ | 16x16 block mappings | Per-zone chunk definitions |
Levels/{ZONE}/Chunks/ | 128x128 chunk mappings | Per-zone block definitions |
Levels/{ZONE}/Layout/ | Level layouts | 1.bin, 2.bin per act |
Levels/{ZONE}/Object Pos/ | Object placement | Per-act object positions |
Levels/{ZONE}/Ring Pos/ | Ring placement | Per-act ring positions |
Levels/{ZONE}/Palettes/ | Zone palettes | Zone-specific color data |
Levels/{ZONE}/Collision/ | Collision data | Zone collision indices |
Levels/{ZONE}/Misc Object Data/ | Zone-specific object maps/anims | Map - Name.asm, Anim - Name.asm |
General/Sprites/{NAME}/ | Shared sprite data | Art/, Map, DPLC, Anim files |
Sound/ | Z80 sound driver | SMPS audio data |
Key Source Files
| File | Contents |
|---|---|
sonic3k.asm | Main assembly source (~203K lines, all object code inline) |
sonic3k.constants.asm | RAM addresses, object field names |
sonic3k.macros.asm | Assembly macros |
s3.asm | Sonic 3 standalone variant |
Compression Types
| Type | Directory/Label Suffix | Tool Flag | Description |
|---|---|---|---|
| Kosinski Moduled | KosinskiM Art/, _KosM suffix | kosm | Primary art compression (dominant in S3K) |
| Nemesis | Nemesis Art/, ArtNem_ prefix | nem | Secondary art compression |
| Kosinski | ArtKos_ prefix | kos | Used for some shared data |
| Uncompressed | Various .bin | bin | Raw tile data, palettes |
Note: S3K encodes compression type in the label suffix (e.g., AIZ1_8x8_Primary_KosM) rather than the file extension. The RomOffsetFinder tool auto-infers the correct type from the label when the file extension is .bin.
Finding Items with RomOffsetFinder
Important: All RomOffsetFinder commands for Sonic 3 & Knuckles require the --game s3k flag.
Search Command (Most Common)
# Search by partial name mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search AIZ" -q # Search for zone-specific items mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search MHZ" -q # Search for palettes mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search Pal_" -q # Search for specific object art mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search ArtKosM_" -q
List Command
# List all Nemesis-compressed items mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k list nem" -q # List all Kosinski Moduled items mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k list kosm" -q # List all compression types mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k list" -q
Verify and Export
# Verify a single offset mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k verify ArtNem_TitleScreenText" -q # Batch verify all Nemesis items mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k verify-batch nem" -q # Export as Java constants mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k export nem ART_" -q
Label Naming Conventions
S3K uses different label prefixes from S1 and S2:
| S3K Prefix | Meaning | Example |
|---|---|---|
ArtKosM_ | Kosinski Moduled art | ArtKosM_AIZEndBoss |
ArtNem_ | Nemesis art | ArtNem_TitleScreenText |
ArtKos_ | Kosinski art | ArtKos_LevelResults |
Pal_ | Palette | Pal_AIZ1, Pal_Sonic |
AnPal_ | Animated palette | AnPal_AIZ1 |
Obj_ | Object code | Obj_AIZEndBoss |
Map_ / Map - | Sprite mappings | In General/Sprites/ or Misc Object Data/ |
DPLC_ | Dynamic Pattern Load Cue | In General/Sprites/ |
Anim_ / Anim - | Animation scripts | In General/Sprites/ or Misc Object Data/ |
PLC_ | Pattern Load Cue | PLC_AIZ |
Comparison with S1 and S2
| S3K Prefix | S2 Equivalent | S1 Equivalent |
|---|---|---|
ArtKosM_ | (no equivalent) | (no equivalent) |
ArtNem_ | ArtNem_ | Nem_ |
ArtKos_ | ArtKos_ | Kos_ |
Pal_ | Pal_ | Pal_ |
AnPal_ | (inline cycling) | (inline cycling) |
Obj_ | Obj_ | ObjXX / Obj_ |
Map_ | MapUnc_ | Map_ |
DPLC_ | (inline) | DPLC_ |
Zone Abbreviations
| Abbrev | Full Name | Zone ID |
|---|---|---|
| AIZ | Angel Island Zone | 0x00 |
| HCZ | Hydrocity Zone | 0x01 |
| MGZ | Marble Garden Zone | 0x02 |
| CNZ | Carnival Night Zone | 0x03 |
| FBZ | Flying Battery Zone | 0x04 |
| ICZ | Icecap Zone | 0x05 |
| LBZ | Launch Base Zone | 0x06 |
| MHZ | Mushroom Hill Zone | 0x07 |
| SOZ | Sandopolis Zone | 0x08 |
| LRZ | Lava Reef Zone | 0x09 |
| SSZ | Sky Sanctuary Zone | 0x0A |
| DEZ | Death Egg Zone | 0x0B |
| DDZ | Doomsday Zone | 0x0C |
| HPZ | Hidden Palace Zone | 0x0D |
Bonus/Special Zones
| Abbrev | Full Name | Notes |
|---|---|---|
| Gumball | Gumball Machine | Bonus stage |
| Pachinko | Pachinko | Bonus stage |
| Slots | Slot Machine | Bonus stage |
| CGZ | Chrome Gadget Zone | S3-only |
| BPZ | Balloon Park Zone | S3-only |
| DPZ | Desert Palace Zone | S3-only |
| EMZ | Endless Mine Zone | S3-only |
| ALZ | Azure Lake Zone | S3-only competition |
Object Code Organization
Unlike S1 (separate files per object) and S2 (inline in s2.asm), S3K objects are:
- •Inline in
sonic3k.asmasObj_routines - •Zone-specific objects appear near their zone's code section
- •Shared sprites have data in
General/Sprites/{Name}/(Art, Map, DPLC, Anim) - •Zone-specific maps/anims are in
Levels/{ZONE}/Misc Object Data/
Finding Object Code
# Search for object by name in the main ASM grep -n "Obj_AIZEndBoss" docs/skdisasm/sonic3k.asm # Search for all objects in a zone grep -n "Obj_AIZ" docs/skdisasm/sonic3k.asm # Find object sprite data ls docs/skdisasm/General/Sprites/ ls "docs/skdisasm/Levels/AIZ/Misc Object Data/"
Object File Locations
| Data Type | Location | Example |
|---|---|---|
| Object code | sonic3k.asm (inline) | Obj_AIZEndBoss: |
| Shared sprite art | General/Sprites/{Name}/Art/ | General/Sprites/Rhinobot/Art/ |
| Shared sprite maps | General/Sprites/{Name}/Map | General/Sprites/Rhinobot/Map - Rhinobot.asm |
| Shared sprite DPLC | General/Sprites/{Name}/DPLC | General/Sprites/Rhinobot/DPLC - Rhinobot.asm |
| Shared sprite anim | General/Sprites/{Name}/Anim | General/Sprites/Rhinobot/Anim - Rhinobot.asm |
| Zone-specific maps | Levels/{ZONE}/Misc Object Data/ | Levels/AIZ/Misc Object Data/Map - Zipline.asm |
| Zone-specific anim | Levels/{ZONE}/Misc Object Data/ | Levels/AIZ/Misc Object Data/Anim - Zipline.asm |
Object System Reference
Object Status Table Offsets
S3K uses S2-style field names (same as S2, different from S1):
| Field | Offset | Size | Description |
|---|---|---|---|
code | 0x00 | long | Object code pointer |
render_flags | 0x04 | byte | Render flags |
routine | 0x05 | byte | Current routine |
height_pixels | 0x06 | byte | Sprite height |
width_pixels | 0x07 | byte | Sprite width |
x_pos | 0x10 | word/long | X position |
y_pos | 0x14 | word/long | Y position |
x_vel | 0x18 | word | X velocity |
y_vel | 0x1A | word | Y velocity |
mapping_frame | 0x22 | byte | Current frame |
routine | 0x24 | byte | Current routine (alternate ref) |
collision_flags | 0x28 | byte | TT SSSSSS (type + size) |
collision_property | 0x29 | byte | Hit count for bosses |
shield_reaction | 0x2B | byte | Shield-specific reactions (S3K-only) |
subtype | 0x2C | byte | Object subtype |
routine_secondary | 0x3C | byte | Secondary routine |
parent | 0x42 | word | Parent object address |
Object size: $4A bytes (larger than S2's $4A).
S3K-Specific Features
Shield reactions (shield_reaction at offset 0x2B):
| Bit | Shield | Effect |
|---|---|---|
| 3 | Bounce | Bounce shield attack reaction |
| 4 | Fire | Fire shield immunity/reaction |
| 5 | Lightning | Lightning shield reaction |
| 6 | Bubble | Bubble shield negation |
Child sprite system via mainspr_childsprites at offset +$16:
- •Up to 8 inline child sprites per object
- •Children share the parent object's RAM slot
- •Used for multi-piece visual objects (e.g., boss segments)
Character ID (character_id field):
| Value | Character |
|---|---|
| 0 | Sonic |
| 1 | Tails |
| 2 | Knuckles |
Object Routine Pattern
Obj_Example:
moveq #0,d0
move.b routine(a0),d0
move.w Obj_Example_Index(pc,d0.w),d1
jmp Obj_Example_Index(pc,d1.w)
Obj_Example_Index:
dc.w Obj_Example_Init - Obj_Example_Index ; routine 0
dc.w Obj_Example_Main - Obj_Example_Index ; routine 2
Sprite Mappings Format (S2/S3K Format)
S3K uses the same 6-byte per piece format as S2 (not S1's 5-byte):
Frame header: dc.w <piece_count> ; Word header (same as S2) Per piece (6 bytes): dc.b <y_offset> ; Signed byte dc.b <size> ; bits 0-1: width-1, bits 2-3: height-1 dc.w <pattern> ; Pattern index + flags (priority, palette, flip) dc.w <x_offset> ; Signed word (S1 uses byte)
Size byte encoding (same as S1/S2):
- •
0x00= 1x1 (8x8 pixels) - •
0x05= 2x2 (16x16 pixels) - •
0x0F= 4x4 (32x32 pixels)
Common Search Patterns
Finding Badnik Art
# Search for specific badnik mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search Rhinobot" -q # Find all Kosinski Moduled art mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search ArtKosM_" -q # Find all Nemesis art mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search ArtNem_" -q
Finding Zone Data
# All AIZ resources mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search AIZ" -q # Zone palette mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search Pal_AIZ" -q # Animated palette mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s3k search AnPal_AIZ" -q
Finding Object Code
# Search for object in main ASM grep -n "Obj_Rhinobot" docs/skdisasm/sonic3k.asm # Find all boss objects grep -n "Obj_.*Boss" docs/skdisasm/sonic3k.asm # Find sprite data directory ls "docs/skdisasm/General/Sprites/Rhinobot/"
RAM Address Reference
Key RAM addresses from sonic3k.constants.asm:
| Address | Name | Description |
|---|---|---|
| (dynamic) | Object_RAM | Object status table (dynamically allocated) |
Current_zone | Current zone | Current zone ID |
Current_zone_and_act | Zone and act | Combined zone/act value |
Camera_X_pos | Camera X | Camera X position |
Camera_Y_pos | Camera Y | Camera Y position |
Ring_count | Rings | Current ring count |
Zone-specific variables exist for special mechanics:
- •
AIZ1_palette_cycle_flag- AIZ fire palette cycling - •
SOZ_darkness_level- SOZ Act 2 darkness - •
MHZ_pollen_counter- MHZ pollen effect
Quick Reference Card
Search: --game s3k search <pattern> Find items by name List: --game s3k list [type] List items (nem/kos/kosm/bin) Test: --game s3k test <offset> <type> Test decompression Verify: --game s3k verify <label> Check calculated offset Export: --game s3k export <type> [prefix] Generate Java constants
Troubleshooting
Address Verification
Like S1, addresses derived from skdisasm labels may not always match the compiled ROM binary exactly. Use verify to check calculated offsets against the actual ROM data.
"Item not found"
- •Check spelling and case sensitivity
- •Try partial names (e.g., "Rhino" instead of "Rhinobot")
- •S3K labels use
ArtKosM_for Kosinski Moduled,ArtNem_for Nemesis - •Compression type is encoded in the label suffix for some items
- •Use
listcommand to see all items of a type
Compression Detection
- •S3K primarily uses Kosinski Moduled (
kosm) rather than regular Kosinski - •Label suffix
_KosMindicates Kosinski Moduled compression - •
ArtNem_prefix indicates Nemesis compression - •
ArtKos_prefix indicates regular Kosinski compression - •When the file extension is
.bin, the tool infers compression from the label