Skip to content
CJ Kucera edited this page Jul 3, 2024 · 35 revisions

AnimalWell.sav is a monolithic file containing "global" state info (figurines, etc), individual save slots, and game options all wrapped up into one. It has a fixed size of 479,360 bytes (at least at time of writing), so any given bit of information can be hardcoded with an index, if you're looking to look something up.

Note that the best source of information about the save file are the hex editor patterns out in the main area of the github repo. The most-canonical version is likely to be the 010 Editor Template, but the ImHex Pattern should be good as well.

This document will strive to be reasonably complete, though, and and offer some more in-depth documentation about the various bits of data. Some information in here might be useful for someone looking to develop a tool to alter the data.

Header Info

The first u32 of the file is a version field – was 2 at one point during pre-release, and as of writing is 9. Probably worth checking this if you're writing any tools.

The next u32 (at 0x04) holds the achievements that have been earned. It's not known if merely setting these values in the save will cause the achievements to be applied to your Steam account. The bitfield is structured like so:

  • 0x000001 - (unused? Marked as "Platinum" on the 010 Template)
  • 0x000002 - EXPLORER (Find the map)
  • 0x000004 - SECRET EGG (Find a secret egg)
  • 0x000008 - EGG ENJOYER (Find 8 secret eggs)
  • 0x000010 - EGG HOBBYIST (Find 16 secret eggs)
  • 0x000020 - EGG LORD (Find 32 secret eggs)
  • 0x000040 - EGG WELL (Find all secret eggs)
  • 0x000080 - SECRET RABBIT (Find a secret rabbit)
  • 0x000100 - CHAMELEON (Find the V. flame)
  • 0x000200 - GHOST (Find the P. flame)
  • 0x000400 - SEAHORSE (Find the B. flame)
  • 0x000800 - OSTRICH (Find the G. flame)
  • 0x001000 - CANDLE BRIGHT (Light all candles)
  • 0x002000 - MANTICORE (Release the Manticore)
  • 0x004000 - SNEAK (Sneak up on a squirrel)
  • 0x008000 - GOOD ENDING (Get crushed by a chinchilla)
  • 0x010000 - BACK AND FORTH FOREVER (Find a new way to get around)
  • 0x020000 - BUBBLE ECSTASY (Pop 1000 bubbles)
  • 0x040000 - TRAVEL FLUTE (Find another way to get around)
  • 0x080000 - WALK THE DOG (Find a different way to get around)
  • 0x100000 - EXIT (Leave the well)

The next u32 (at 0x08) is the "Frame Seed." This is a counter which starts when the game is booted and ends when the last flame disappears in the intro, and is presumably used in various RNG seeds throughout the game. Probably the most noticeable effect is that this value determines which Bunny Mural segment will be shown to the player. That will be the Frame Seed modulo 50. So, changing this value 50 times should let you see all segments in a singleplayer session.

The next u8 (at 0xC) is the last-active save slot (0, 1, or 2), used by the main menu "continue" option.

The next u8 (at 0xD) is an XOR-based checksum of the entire file. If the checksum doesn't match, the game will spawn a Manticore friend to help you play with your internal organs more efficiently. Fortunately it's simple to compute: simply start with 0, and walk through the file XORing each byte into the previous result (making sure to skip any existing checksum byte in the file).

Code examples for fixing the checksum:

The next u8 (at 0xE) is used during the game runtime, to indicate whether an invalid hash was seen. It's not actually used from the savefile.

The next u32 (at 0x10) is a bitfield containing global unlocks, including the various figurines in the game:

  • 0x000001 - Stopwatch
  • 0x000002 - Pedometer
  • 0x000004 - Pink Phone
  • 0x000008 - Souvenir Cup
  • 0x000010 - Origami Figurines
  • 0x000020 - Rabbit Figurine (Two Rabbits)
  • 0x000040 - Owl Figurine
  • 0x000080 - Cat Figurine
  • 0x000100 - Fish Figurine
  • 0x000200 - Donkey Figurine
  • 0x000400 - "DecoRabbit" Figurine
  • 0x000800 - mama cha
  • 0x001000 - Giraffe Figurine
  • 0x002000 - Incense Burner
  • 0x004000 - Peacock Figurine
  • 0x008000 - Otter Figurine
  • 0x010000 - Duck Figurine
  • 0x020000 - (unused)
  • 0x040000 - "PedometerWChest" (not sure what this one means)
  • 0x080000 - (unused)

The rest of the header is either unknown or padding.

Slot Data

Each save slot has a static offset in the file, and each slot is structured identically. The offsets are:

  • 0x00018 - Slot 1
  • 0x27028 - Slot 2
  • 0x4E038 - Slot 3

Each slot is exactly 159,760 bytes. The game options start immediately after, at 0x75048.

NOTE: When I mention any file indexes from here on out in the "Slot Data" section, they'll be relative to the save slot. So if I say something's at 0x108, that means that for slot 1 it lives at 0x120, for slot 2 it lives at 0x27130, etc.

General Info

  • Load Screen timestamp: 0x0 from the slot start
    • Two bytes for the year, and then one each for month, day, hour, minute, and second.
  • Step Count: u32 at 0x108 from the slot start
  • Total Firecrackers Picked Up: u16 at 0x1A2 from the slot start
  • Total Bubbles Popped: u16 at 0x1A4 from the slot start
  • Times saved: u16 at 0x1A8 from the slot start
  • Keys in inventory: u8 at 0x1B1 from the slot start
  • Matches in inventory: u8 at 0x1B2 from the slot start
  • Firecrackers in inventory: u8 at 0x1B3 from the slot start
    • Note that merely adding firecrackers to your inventory will not allow you to use firecrackers as an item; you will need to unlock them via the Equipment bitfield as well.
  • Hits Taken: u16 at 0x1E2 from the slot start
  • Total Deaths: u16 at 0x1E4 from the slot start
    • The skulls in the B.B. Wand / Souvenir Cup / Pink Phone / Smiley Code / Skull room dynamically change depending on this value
  • Berries Eaten While Full: u16 at 0x26FFA from the slot start
    • Resets when hit, or when the player eats a blue berry
  • Nuts Stolen from Squirrels: u8 at 0x1AE from the slot start. This is related to one of the unicode-message hints.

Health

Health (number of hearts) is stored as a u8 at 0x1B4 from the slot start. Any health above the player's current "base" health will show up as temporary blue hearts.

Gold hearts can be acquired from the Groundhog if the system clock is set to Groundhog Day (February 2), and the number of gold hearts is stored as a u8 at 0x1B5 from the slot start.

The game also keeps track of the last year in which a gold heart was redeemed from the groundhog. This value is stored as a u16 at 0x1B6 from the slot start.

Time In Game

Time in the game is measured in "ticks," and stored as a u32. The game runs at 60fps, so the unit is not milliseconds. Don't try to just plug it into a usual date-handling library without accounting for that first!

There are technically two fields for time spent in game. The first is stored at 0x1BC from the start of the slot, and describes only the in-game tick count, discounting any paused time. This doesn't seem to be used for anything obvious to the player. The second value, at 0x1C0 from the start of the save slot, also includes time spent in pause menus, and this is what the game uses for the speedrunning figurines, and what gets shown on the "load game" screen.

Spawnpoint

The player's spawnpoint is stored as a pair of u32 values, at 0x1D4 from the start of the slot, with the X value first, and Y value second. Note that the upper-left room on the map is coordinate (2, 4). If there is a phone in the room specified, the player will spawn next to the phone -- otherwise, they will spawn in the most upper-left corner available. (Note that technically the player will spawn at "Tile ID 16," for folks who have been diving into map editing. That tile tends to be placed next to the phone, but it can technically be moved around anywhere, or even added to other rooms with the proper tools, though that's outside the remit of the save format.)

Spawning outside the map boundaries just gives you a featureless black screen and an inability to do anything but access the Esc pause menu, alas.

Map Data

Cranks

Crank data is stored at 0x8 from the slot start, as a list of 23 u16 values. The min/max values haven't yet been catalogued, but you can see the hex editor templates for the specific room mappings for all 23. The puzzle-specific cranks are listed here, though:

  • Indexes 7 and 8 are for the water reservoir puzzle at (7, 11)
    • One "solved" state for these would be 464, 64624
  • Indexes 13, 14, and 15 are for the water reservoir puzzle at (4, 15)
    • One "solved" state for these would be 63840, 1584, 32
  • Indexes 16 and 17 are for the seahorse boss reservoir puzzle at (2, 17)
    • This one doesn't have a fully-solved state since solving the puzzle requires moving them around to make use of the seahorse
  • Indexes 19, 20, and 21 are for the levers at the sine wave puzzle at (15, 17)
    • One "solved" state for these would be 40, 168, 140

Chest Bitfields

Chest-opening status is encoded as a 128-bit value starting at 0x120 from the start of the slot. These have not been fully mapped yet, but known room coordinates can be seen in the hex editor templates. It looks like only the first 102 bits are used in this field.

There's also a separate bitfield to store the chest status for chests found in Layer 1 (which is Collector's Edition Temple). There's only the one chest (which holds the Two Rabbits Figurine), but it's a single byte at 0x1AF from the start of the slot.

Doors

There are five categories of openable doors/walls in the game:

  1. "Regular" doors which are opened via button presses, water reservoir puzzles, or other environmental puzzles.
  2. "Unlockable" doors which are opened using the "generic" keys you can store in your inventory.
  3. Moveable walls which are stored in the same kind of structure as the Unlockable Doors
  4. Egg Chamber Doors
  5. Other "special" doors like the House, Office, and Closet doors, whose states are actually controlled via "quest" flags, rather than a dedicated door structure.

Regular Door Bitfields (Buttons/Reservoirs/Puzzles)

The first category of doors are the ones opened by puzzles, be they buttons, water reservoirs, or other such things. These are stored in a 128-bit bitfield starting at 0x130 from the start of the slot data. These haven't been entirely mapped out yet, but you can get many room mappings from the hex editor patterns. It looks like only the first 94 bits are used in this field.

Note that the door state is completely independent from the button/puzzle states. You can toggle the doors to be open without having any of the buttons pressed down, and the doors will stay open.

Unlockable Doors and Moveable Walls

Unlockable Doors (of the sort which are unlocked via "generic" inventory keys) and moveable walls are stored using very similar data structures in the game, which the hex editor patterns call TileID. Each TileID structure consists of:

  • Room Y coordinate: u8
  • Room X coordinate: u8
  • Tile Y coordinate: u8
  • Tile X coordinate: u8 (but only the bottom six bits)
  • Map Layer: The top two bits of the Tile X coordinate

Note that the data stores the Y coordinates first, instead of X.

In practice, all known instances of TileID structures in the game have used map layer 0, but the engine does check for those top two bits, specifically looking for layer 1.

Additionally, the game stores the "next index" for the array, used by the engine to know where to write the next bit of data, but this index is stored rather far away from the arrays themselves, and uses a different byte width between the Doors and Walls arrays.

Unlockable Doors are stored starting at 0x88 from the slot start, and the "next index" is stored as a u16 at 0x1AA from the slot start. There are 16 TileID entries available. There are only six "valid" lockable door entries in the game, which are listed here with coordinates in the more-normal x, y order, rather than the y, x order they are stored in:

  • Room (7, 4), Tile (9, 5), Layer 0
  • Room (15, 8), Tile (38, 6), Layer 0
  • Room (16, 10), Tile (4, 5), Layer 0
  • Room (14, 13), Tile (6, 16), Layer 0
  • Room (14, 15), Tile (27, 6), Layer 0
  • Room (14, 15), Tile (32, 6), Layer 0

Moveable Walls are stored starting at 0xC8 from the slot start, and the "next index" is stored as a u8 at 0x1B8 from the slot start. There are 16 TileID entries available. Interestingly, there are technically 17 moveable walls in the game (three of which are only available via cheating), and the game's bounds checks for this data structure are not good. Triggering the 17th wall opening will cause the engine to repeatedly increment the "next index" and write the new value over a large chunk of savegame data. As of 2024-06-04, that has not yet been fixed.

The 14 "valid" moveable wall entries are:

  • Room (2, 5), Tile (2, 1), Layer 0
  • Room (15, 5), Tile (6, 3), Layer 0
  • Room (6, 6), Tile (16, 14), Layer 0
  • Room (7, 6), Tile (16, 1), Layer 0
  • Room (7, 6), Tile (5, 14), Layer 0
  • Room (13, 7), Tile (29, 1), Layer 0
  • Room (10, 8), Tile (16, 17), Layer 0
  • Room (2, 9), Tile (1, 6), Layer 0
  • Room (9, 10), Tile (39, 6), Layer 0
  • Room (8, 11), Tile (33, 19), Layer 0
  • Room (13, 11), Tile (39, 17), Layer 0
  • Room (6, 13), Tile (36, 7), Layer 0
  • Room (2, 19), Tile (9, 7), Layer 0
  • Room (2, 19), Tile (31, 7), Layer 0

The 3 "illegal" entries which could potentially fill up the array and cause an overflow if not removed, are:

  • Room (12, 4), Tile (29, 4), Layer 0
  • Room (3, 7), Tile (5, 3), Layer 0
  • Room (13, 13), Tile (11, 8), Layer 0

Egg Chamber Doors

The four doors in the egg chamber get their own 8-bit field at 0x1B9 from the start of the slot data. These doors will automatically open when you have the requisite number of eggs, but they can also be set to open via this bitfield. The first four bits control the doors, in order -- the other four are unused (as far as we know).

Buttons

There are four colors of buttons in the game which are stored in the save data:

  • Yellow buttons stay pressed down when pressed once
  • Purple buttons will pop back up without constant pressure (until all buttons in the relevant puzzle have been pushed down at the same time, at which time they'll stay down)
  • Green buttons control fans, instead of doors
  • Pink buttons control moveable walls, instead of doors

The button states are technically independent of the doors/walls that they're associated with, but if you set the correct buttons to be pressed down, the associated door will open up automatically when you next enter the room (even the ones controlled by purple buttons). Not all of these have been exhaustively mapped, but you can get room mappings for many by looking at the hex editor patterns.

These are all stored in bitfields, and grouped by their colors.

  • Yellow buttons are a 192-bit field starting at 0x140 from the start of the slot, and seem to use 134 of those bits.
    • Additionally, a separate bitfield to store the state of yellow buttons in Layer 2 (Space / Bunny Island) can be found as a single byte at 0x1B0 from the start of the slot. There's only the four teleporation torus buttons which get stored there.
  • Purple buttons are a 64-bit field starting at 0x160 from the start of the slot, and seem to use 27 of those bits.
  • Green buttons are a 64-bit field starting at 0x168 from the start of the slot, and seem to use just 7 of those bits.
  • Pink buttons are a 16-bit field starting at 0x1AC from the start of the slot, and ten of those are used by the game. See the section on moveable walls for some caveats about hitting all of these, since the moveable-wall section can overflow and corrupt saves!
    • 0x001 - Illegal Bunny 1
    • 0x002 - Spike Bunny
    • 0x004 - Floor is Lava Bunny
    • 0x008 - Illegal Bunny 2
    • 0x010 - Map Number Bunny
    • 0x020 - Elevator Dog Wheel
    • 0x040 - Chinchilla Bunny
    • 0x080 - Bulb Bunny
    • 0x100 - Illegal Bunny 3
    • 0x200 - Lower Portal Nexus

Water Reservoirs

The fill levels for the water reservoir puzzles are stored at 0x10C from the slot start as an array of 16 u8 values. The values are 0 when empty and 80 (decimal) when filled.

Even though there is room for 16 of them, there are only five in the game, stored in this order:

  • Room (7, 11)
  • Room (5, 15)
  • Three in Room (2,17) *(ordered left to right)

Picked-Fruit Bitfield

Fruit only respawns in the game when your character dies, so the savegame keeps track of exactly which fruit has been picked. This is done via a 128-bit field starting at 0x170 from the start of the slot data. Fruits are stored in the xy room order => yx tile order. Be aware that they are filed under xy_id room coordinates in the template. 115 of the bits are in use, covering all in-game fruit: 80 pink, 31 blue, 4 large blue fruit. Some fruit names are missing from the template at the time of writing but they have all been identified.

Firecracker Bitfield

Like fruit, firecrackers only respawn in the game when your character dies, so the savegame keeps track of those, too. This is done via a 64-bit field starting at 0x180 from the start of the slot data. These have not been fully mapped, but you can get many room mappings from the hex editor patterns. All 64 bits are used.

Lit Candle Bitfield

The candles which the player has lit are stored in a u16 bitfield at 0x1E0 from the start of the slot. See the hex editor template for room mappings. The first 9 bits of the field are used for the 9 candles in the game.

Detonators/Explosions Bitfield

Detonators and the explosive charges they set off are technically stored in two separate bitfields in the game data. Setting them to enabled will result in the appropriate wall-destroying effect in game, but clearing out the fields will not recover destroyed walls; that would have to be done via the destruction map, instead.

The explosive statuses are stored in a 32-bit field starting at 0x190 from the start of the slot data. Only 10 bits are actually used in there. See the hex editor patterns for room mappings.

The detonator statuses are stored in a 32-bit field starting at 0x194 from the start of the slot data. Only 9 bits are actually used in there. See the hex editor patterns for room mappings.

Frightened Ghosts Bitfield

Frightened ghosts will respawn on player death (unless a candle has been lit in their room), and this is stored in a u16 bitfield at 0x1E6 from the start of the slot. 11 of the bits are used.

  • Ghost at Room (08,06)
  • Ghost at Room (04,07)
  • Ghost at Room (06,07)
  • Ghost at Room (06,09)
  • Ghost at Room (15,09) (top)
  • Ghost at Room (15,09) (left)
  • Ghost at Room (15,09) (right)
  • Ghost at Room (05,13)
  • Ghost at Room (10,13)
  • Ghost at Room (16,13)
  • Ghost at Room (07,14)

Frightened Squirrels Bitfield

Frightened-squirrel state is stored as a 16-bit field at 0x19C from the start of the slot data. See the hex editor pattern for specific room mappings. Only 13 of the bits are actually used.

Caged Cats / Mother Lynx

The 16-bit bitfield which controls which cat cages are open, and whether the Wheel cage is open (in Mother Lynx's lair) is at 0x19E from the start of the slot data. There are only six bits actually used in the field:

  • 0x01: Caged Cat 1 at Room (16,18)
  • 0x02: Caged Cat 2 at Room (16,18)
  • 0x04: Caged Cat 3 at Room (16,18)
  • 0x08: Caged Cat 1 at Room (14,19)
  • 0x10: Caged Cat 2 at Room (14,19)
  • 0x20: Wheel Cage

Elevators / Moving Platforms

The state of the game's elevators and moving platforms is stored via a variety of structures. First, at 0x3A8 from the start of the slot data, there are 8 pairs of four-byte floats:

  • First, the elevator position
  • Second, the elevator speed

(The specifics of what the specific values mean hasn't really been documented.)

Then, at 0x3E8 from the start of the slot, there's a u8 bitfield to determine the currently-selected direction of the variable-direction elevators. The known values:

  • 0x01 - Blue Rat (0 down, 1 up)
  • 0x02 - Red Rat (0 right, 1 left)
  • 0x04 - Ostrich (0 right, 1 left)
  • 0x08 - Dog (0 down, 1 up)

Then, finally, at 0x3E9 from the slot start, there's another u8 bitfield which defines which elevators are inactive. A 0 in this field indicates that the elevator is moving as per usual, and a 1 indicates that it's been stopped. These have not really been mapped out much yet, but the known values are:

  • 0x001 - Elevator1
  • 0x002 - Elevator2
  • 0x004 - Wheel Ostrich Elevator (gets disabled when the Wheel Ostrich is freed)
  • 0x008 - Elevator4
  • 0x010 - Elevator5 (Disabled from game start)
  • 0x020 - Elevator6 (Disabled from game start)
  • 0x040 - Elevator7 (Disabled from game start)
  • 0x080 - Elevator8

The ones disabled from the game start are likely to be the ones which only move when using the Wheel equipment.

Stalactites / Stalagmites / Icicles

The state of the destructible harmful environmental hazards like stalactites, stalagmites, and icicles, are stored in a few different areas.

First, "big" stalactite state is stored starting at 0x26F77 from the start of the slot, and consists of 16 u8 values which should be one of the following values:

  • 0: Default
  • 1: Cracked Once
  • 2: Cracked Twice
  • 3: On the Floor
  • 4: On the Floor, Cracked Once
  • 5: On the Floor, Cracked Twice
  • 6: Broken

See the hex editor pattern for specific room mappings for these.

Next, starting at 0x26F98 from the start of the slot, is a series of 8 u64 bitfields (or a single 512-byte bitfield, if you like) describing small stalactites/stalagmites that have been destroyed. The hex editor patterns have room mappings for all of those.

Finally, starting at 0x26FD8 from the start of the slot, there is a series of 4 u64 bitfields (or a single 256-byte bitfield, if you like) describing icicles that have been destroyed. At time of writing, these haven't been mapped into rooms at all yet, but check the hex editor patterns in case that's changed.

Character/Collectibles Data

Equipment Bitfield

The unlocked equipment avilable to the player is stored as a u16 bitfield at 0x1DC from the start of the slot data. The available masks are:

  • 0x02: Firecrackers
  • 0x04: Animal Flute
  • 0x08: Lantern
  • 0x10: Top
  • 0x20: Disc (Note: if you give this to yourself without also setting the relevant quest statuses, you can find yourself with ghost dog hunting you down)
  • 0x40: B. Wand
  • 0x80: Yoyo
  • 0x100: Slink
  • 0x200: Remote
  • 0x400: Ball
  • 0x800: Wheel
  • 0x1000: UV Light

If you're editing equipment into a character which did not have equipment already (such as a fresh save), make sure to also alter the "selected equipment" field below! It can be difficult to get equipment selected unless the value is set right away.

Selected Equipment

The currently-selected equipment is stored as a u8 at 0x1EA from the start of the save slot. Valid values are:

  • 0x0: None
  • 0x1: Firecracker
  • 0x2: Animal Flute
  • 0x3: Lantern
  • 0x4: Top
  • 0x5: Disc
  • 0x6: B. Wand
  • 0x7: Yoyo
  • 0x8: Slink
  • 0x9: Remote
  • 0xA: Ball
  • 0xB: Wheel
  • 0xC: UV Light

If you unlock any equipment via save editing but leave this field at 0x00 (such as if you're editing a brand-new slot before it's picked up any equipment), equipment-swapping will be in a semi-non-working state. Next/Prev equipment buttons won't work, and if you only have a single equipment item, you can't enable it via the inventory screen, either. If you have more than one equipment item in your inventory, you can select one of them from the inventory screen, at which point all the equipment keys should work as intended. Bottom line, if you're enabling equipment with save editing, just be sure to make sure this field is set to one of the items you've added to the save.

Other Inventory Bitfield

Other items which show up in your inventory are stored in a u8 bitfield at 0x1DE from the start of the slot. This includes a few items which are no longer used in the game. Valid values are:

  • 0x01: Mock Disc
  • 0x02: S. Medal
  • 0x04: Cake (from the alpha, unused)
  • 0x08: House Key
  • 0x10: Office Key
  • 0x20: Closet Key (from the alpha, unused)
  • 0x40: E. Medal
  • 0x80: F. Pack

Egg Bitfield

The eggs you acquire are stored in a 64-bit field starting at 0x188 from the start of the slot data, and all 64 bits are used. The bitfield is set up like so:

  • 0x0000000000000001: Reference Egg
  • 0x0000000000000002: Brown Egg
  • 0x0000000000000004: Raw Egg
  • 0x0000000000000008: Pickled Egg
  • 0x0000000000000010: Big Egg
  • 0x0000000000000020: Swan Egg
  • 0x0000000000000040: Forbidden Egg
  • 0x0000000000000080: Shadow Egg
  • 0x0000000000000100: Vanity Egg
  • 0x0000000000000200: Egg as a Service
  • 0x0000000000000400: Depraved Egg
  • 0x0000000000000800: Chaos Egg
  • 0x0000000000001000: Upside Down Egg
  • 0x0000000000002000: Evil Egg
  • 0x0000000000004000: Sweet Egg
  • 0x0000000000008000: Chocolate Egg
  • 0x0000000000010000: Value Egg
  • 0x0000000000020000: Plant Egg
  • 0x0000000000040000: Red Egg
  • 0x0000000000080000: Orange Egg
  • 0x0000000000100000: Sour Egg
  • 0x0000000000200000: Post Modern Egg
  • 0x0000000000400000: Universal Basic Egg
  • 0x0000000000800000: Laissez-Faire Egg
  • 0x0000000001000000: Zen Egg
  • 0x0000000002000000: Future Egg
  • 0x0000000004000000: Friendship Egg
  • 0x0000000008000000: Truth Egg
  • 0x0000000010000000: Transcendental Egg
  • 0x0000000020000000: Ancient Egg
  • 0x0000000040000000: Magic Egg
  • 0x0000000080000000: Mystic Egg
  • 0x0000000100000000: Holiday Egg
  • 0x0000000200000000: Rain Egg
  • 0x0000000400000000: Razzle Egg
  • 0x0000000800000000: Dazzle Egg
  • 0x0000001000000000: Virtual Egg
  • 0x0000002000000000: Normal Egg
  • 0x0000004000000000: Great Egg
  • 0x0000008000000000: Gorgeous Egg
  • 0x0000010000000000: Planet Egg
  • 0x0000020000000000: Moon Egg
  • 0x0000040000000000: Galaxy Egg
  • 0x0000080000000000: Sunset Egg
  • 0x0000100000000000: Goodnight Egg
  • 0x0000200000000000: Dream Egg
  • 0x0000400000000000: Travel Egg
  • 0x0000800000000000: Promise Egg
  • 0x0001000000000000: Ice Egg
  • 0x0002000000000000: Fire Egg
  • 0x0004000000000000: Bubble Egg
  • 0x0008000000000000: Desert Egg
  • 0x0010000000000000: Clover Egg
  • 0x0020000000000000: Brick Egg
  • 0x0040000000000000: Neon Egg
  • 0x0080000000000000: Iridescent Egg
  • 0x0100000000000000: Rust Egg
  • 0x0200000000000000: Scarlet Egg
  • 0x0400000000000000: Sapphire Egg
  • 0x0800000000000000: Ruby Egg
  • 0x1000000000000000: Jade Egg
  • 0x2000000000000000: Obsidian Egg
  • 0x4000000000000000: Crystal Egg
  • 0x8000000000000000: Golden Egg

Bunny Bitfield

The bunnies that you've collected are stored in a 32-bit field starting at 0x198 from the start of the slot. Technically all 32 bits are used, but unlocking any of the "illegal" bunnies will make BDTP impossible to solve and prevent you from executing it entirely, "since the BDTP path is xored with your bunny flags" to see if you're on the right path. (Explanation by: @Randomiser on Discord)

The valid bunny bitmasks are:

  • 0x00000001: Tutorial Bunny (#4)
  • 0x00000004: Origami Bunny (#17)
  • 0x00000008: Crow Bunny (#10)
  • 0x00000010: Ghost Bunny (#9)
  • 0x00000040: Fish Mural Bunny (#8)
  • 0x00000080: Map Numbers Bunny (#5)
  • 0x00000100: TV Bunny (#16)
  • 0x00000200: UV Bunny (#7)
  • 0x00000400: Bulb Bunny (#13)
  • 0x00000800: Chinchilla Bunny (#2)
  • 0x00008000: Bunny Mural Bunny (#1)
  • 0x00400000: Duck Bunny (#11)
  • 0x02000000: Ghost Dog Bunny (#18)
  • 0x10000000: Dream Bunny (#12)
  • 0x40000000: Floor Is Lava Bunny (#14)
  • 0x80000000: Spike Room Bunny (#20)

The "illegal" bunny bitmasks are:

  • 0x00000002: Illegal 1
  • 0x00000020: Illegal 2
  • 0x00001000: Illegal 3
  • 0x00002000: Illegal 4
  • 0x00004000: Illegal 5
  • 0x00010000: Illegal 6
  • 0x00020000: Illegal 7
  • 0x00040000: Illegal 8
  • 0x00080000: Illegal 9
  • 0x00100000: Illegal 10
  • 0x00200000: Illegal 11
  • 0x00800000: Illegal 12
  • 0x01000000: Illegal 13
  • 0x04000000: Illegal 14
  • 0x08000000: Illegal 15
  • 0x20000000: Illegal 16

Quests / Progression

There's no "quests" in the game per se; perhaps "progression" is a better term. Regardless, there are a couple of bitfields to store that information.

General Quest State

The main bitfield which is involved with quests/progression is a u32 bitfield starting at 0x1EC past the slot start. There are a fair number of unknown fields in here which are probably not actually used by the game. This also includes some door states for the office area, etc.

  • 0x00000001: House Open
  • 0x00000002: Office Open
  • 0x00000004: Closet Open
  • 0x00000008: (unknown)
  • 0x00000010: (unknown)
  • 0x00000020: (unknown)
  • 0x00000040: (unknown)
  • 0x00000080: (unknown)
  • 0x00000100: Global Switch State (0 is right, 1 is left)
  • 0x00000200: Map Unlocked
  • 0x00000400: Stamps Unlocked
  • 0x00000800: Pencil Unlocked
  • 0x00001000: Defeated Chameleon
  • 0x00002000: Cheater's Ring
  • 0x00004000: Eaten by Chameleon
  • 0x00008000: Inserted S. Medal
  • 0x00010000: Inserted E. Medal
  • 0x00020000: Wings / Flying Unlocked
  • 0x00040000: Woke Up (start of game)
  • 0x00080000: B.B. Wand Upgrade
  • 0x00100000: Egg 65
  • 0x00200000: All Candles Lit (opens door under candle grid)
  • 0x00400000: Teleport Torus Active
  • 0x00800000: Manticore Egg Placed
  • 0x01000000: Defeated Bat
  • 0x02000000: Freed Ostrich
  • 0x04000000: Defeated Ostrich
  • 0x08000000: Fighting Eel
  • 0x10000000: Defeated Eel
  • 0x20000000: No Disc in Dog Shrine (the one that unlocks P. Flame)
  • 0x40000000: No Disc in Dog Head Statue (where the Disc is acquired)
  • 0x80000000: (unknown)

Note that the "Defeated Ostrich" mask (0x4000000) controls both the ground-based ostrich guarding the Yoyo area, and the wheel ostrich guarding the G. Flame. If attempting to clear out the Defeated/Freed Ostrich flags, be sure to un-press at least one of the relevant buttons, otherwise the Wheel Ostrich will automatically free itself again when you next enter the room. Also note that freeing the Wheel Ostrich will stop its relevant elevator, so that data might need cleaning up.

Also note that in a vanilla game, both the "Freed Ostrich" and "Defeated Ostrich" flags will be set after the encounter. For the Eel encounter, though, the "Fighting Eel" flag will be cleared out once "Defeated Eel" is set.

Disc / Mock Disc Details

The couple of quest states relating to the Disc / Mock Disc are of particular interest, because the game state can vary quite a bit depending on the state of those two flags, the presence of the Disc in your Equipment, and the presence of the Mock Disc in your inventory. Setting things improperly can lead to the player being chased by the ghost dog. A full sheet describing all possible combinations and their effect on the game can be found on Google Drive. A condensed version which only includes "valid" game states is shown below:

Has Mock Disc Has Disc No-Statue No-Shrine State
N N N N Start of Game
Y N Y Y Picked up Mock Disc
N Y N Y Swapped Mock Disc
N Y Y N Moved Mock Disc to Shrine
N N Y N Replaced Disc with M. Disc in Shrine

There are some other combinations which are valid at runtime but which are never ordinarily found in savefiles, since the player can't save the game while the ghost dog is active. Other combinations simply can't be achieved without save/memory editing. See the sheet for full details.

So, if you're developing a tool which can give the player the Disc or Mock Disc, make sure to provide some avenue to set the quest states properly too!

Chameleon Details

Setting the Defeated Chameleon flag (0x1000) will also remove the chameleon at (14, 9) and the chameleon statue at (14, 10), in addition to the main boss at (13, 5). Likewise, clearing the flag will cause all three to reappear.

Another Progress Bitfield

There's a separate u16 bitfield at 0x21C from the slot start which defines some other quest-like parameters. These are mostly related to very early game, but they also have a flag for having the house key drop, after the first set of credits. The known possible flags:

  • 0x01 - Game Started
  • 0x02 - (unknown)
  • 0x04 - Ready To Hatch
  • 0x08 - Show HP Bar
  • 0x10 - Drop House Key

Manticores

Both the Blue and Red Manticore states are tracked in a pair of u8 values. The Blue Manticore is at 0x1F0 from the slot start, and the Red Manticore is at 0x1F1 from the slot start. Valid values appear to be one of these three:

  • 0: Default/Unknown
  • 1: In Overworld (will attack the player)
  • 2: In Space (will be peaceful)

Kangaroo Encounters / K. Shards

It's a bit difficult to know whether this should got in the map area, the player status area, or the quest/progression area. Anyway, here it is for now.

The Kangaroo will drop three K. Shards which together are used to unlock the K. Medal Circular Recess. The save format will store the exact location of any dropped shards which have yet to be picked up, and will retain that information in the structure after the player has picked up and/or placed the shards. The combined state of all three of these structures will determine when the K. Medal door opens.

Each of the three encounters has the same structure:

  • A float (four byte) defining the in-room X position of the dropped bag
  • A float (four byte) defining the in-room Y position of the dropped bag
  • A u8 defining the room X coordinate in which the bag's found
  • A u8 defining the room Y coordinate in which the bag's found
  • A u8 defining the shard state. This will be one of four values:
    • 0: Not Present
    • 1: Dropped by Kangaroo
    • 2: Picked Up
    • 3: Inserted
  • A u8 "Encounter ID." This will be a value from 0 to 4, and the IDs correspond to specific room values (so the room coordinates will always match up to the same IDs).
    • 0: Room (6, 6) (one potential valid in-room position: 38, 104)
    • 1: Room (9, 11) (one potential valid in-room position: 156, 136)
    • 2: Room (12, 11) (one potential valid in-room position: 16, 144)
    • 3: Room (9, 13) (one potential valid in-room position: 147, 144)
    • 4: Room (16, 16) (one potential valid in-room position: 154, 128)

The three encounters start at 0x1F4 past the slot start.

After the final encounter, there are two more bits of data. First, a u8 defining the next encounter where the Kangaroo will show up (at 0x218 past the start of the slot data). The ID will match the Encounter IDs enumerated above. Then, at 0x219 past the slot start, another u8 will define the current Kangaroo state, which should be one of these values:

  • 0: Idle
  • 1: Running Away
  • 2: Attacking

In my own testing, I found those statuses to be somewhat difficult to predict apart from "Attacking" (though perhaps I was just making some silly mistakes), so to ensure that the Kangaroo shows up immediately at a particular location, set its status to Attacking.

Flame States

Flame states are stored as four u8 values, starting at 0x21E from the slot start. The valid values appear to be:

  • 0: Sealed (the default state)
  • 1: Cracked
  • 2: Cracked More
  • 3: Glass Broken
  • 4: Flame Collected (in player inventory)
  • 5: Flame Placed

The order of u8 values is:

  1. B. Flame
  2. P. Flame
  3. V. Flame
  4. G. Flame

Teleport / Portal Bitfields

There are two bitfields which respectively define which portals have been "seen" (and will therefore open up when the player next plays the flute at the control area), and which portals are already open. These are u8 bitfields, and the "seen" field is at 0x223 past the start of the slot, and the "active" field is at 0x224 past the start of the slot. The masks are:

  • 0x01 - (unused)
    • Does not control the Eel/Bonefish portal; that is done via a Quest flag instead.
  • 0x02 - Frog
  • 0x04 - Fish
  • 0x08 - Bear
  • 0x10 - Dog
  • 0x20 - Bird
  • 0x40 - Squirrel
  • 0x80 - Hippo

Bunny Mural

(As mentioned far above in the header section, note that the section of the mural shown to the player depends on the Frame Seed)

There are a few bits of information stored about the Bunny Mural. First, a pair of u8 values at 0x3EA and 0x3EB from the start of the slot data which describe the currently-selected X/Y position of the mural, when using the controls to alter it.

Then, the actual mural data is much later in the file, starting at 0x26EAF past the slot start. The mural is 40x20 in resolution. The data is essentially arranged like an image, which each pixel taking two bits of data to describe (which results in four possible colors per pixel). Since four pixels can fit inside a byte, a 40-pixel row will fit into 10 bytes. At 20 rows, that means the mural data takes up 200 bytes total.

"Local" Unlocks

There is a u16 bitfield starting at 0x26FF8 from the start of the slot which seems to mimic some of the data from the "global" unlocks section (ie: figurines, stopwatch, pedometer, etc). It's not fully understood how this one works at time of writing, or if it even has an effect.

Minimap Data

Stamps

Stamps are stored starting at 0x225 from the slot start. The first u8 there describes how many stamps have been placed. Immediately after is a u16 which stores the stamp icon that's currently selected by the player. The values are:

  • 0: Chest
  • 1: Heart
  • 2: Skull
  • 3: Diamond-or-whatever
  • 4: Spiral
  • 5: Flame
  • 6: Diamond "grid"
  • 7: Question Mark

Then after that are 64 slots for stamp descriptions. The game will compact them into a consecutive list as stamps are deleted, so editors don't need to check for "null" stamps or anything; just read in however many the save says are there. The format of each stamp is:

  1. u16 - X coordinate (in minimap pixels)
  2. u16 - Y coordinate (in minimap pixels)
  3. u16 - Icon, using the same values as above

When the player deletes a stamp in the game, the engine will copy the last stamp into the deleted index and then decrement the index, so deletions will only re-order the last stamp in the list.

Revealed Data

"Basic" minimap data is stored as a single bit for each "pixel" of the minimap. The game engine fills in the colors as-appropriate, and will update the map depending on the actual game state (if walls have been demolished, etc).

Each minimap room is 40x22 pixels, so that's five bytes for a single row across a room, and 110 bytes total for the room. Even though the playable game area is 16x16 rooms, the minimap (and the actual map, technically), is 20x24, with the 16x16 playable area centered in there. There are four empty rows of rooms on the top+bottom, and two columns of empty rooms on the sides. So, that yields 52,800 bytes of info for the minimap as a whole.

Structurally, it's stored sort of like an image; one big row at a time. So the entire first row comes first (for all rooms at the "top"), then the next row down, etc. The minimap data starts at 0x3EC.

Pencil Layer

The minimap pencil layer is structure identically to the "revealed" minimap data, and it starts at 0xD22D from the start of the slot data. Note that there is a single unused byte inbetween the main "revealed" data and the pencil data.

Destruction Layer

The game also keeps track of which tiles have been destroyed (whether via the top, Manticore lasers, detonators, or whatever) in another identical format to the minimap. This starts at 0x1A06E from the start of the slot data. Like with the Pencil layer, note that there's an empty byte inbetween the Pencil data and the destruction layer.

Game Options

The game options start at the very end of the file, at position 0x75048. First up, at that address, is a u16 bitfield with the following known values:

  • 0x0001 - Scanlines
  • 0x0002 - Fullscreen
  • 0x0004 - Show Time
  • 0x0008 - Show Steps
  • 0x0010 - Vibration
  • 0x0020 - Forced Save Mode
  • 0x0040 - Reduce Flashing
  • 0x0080 - Override Controller Style
  • 0x0200 - Swap Confirm/Cancel
  • 0x0400 - Ignore BG Input
  • 0x0800 - Gamepad Speaker Off (possibly reverted?)

Then at pos 0x7504A is a u8 value which defines the language used:

  • 0: English
  • 1: Spanish
  • 2: French
  • 3: Italian
  • 4: German
  • 5: Chinese
  • 6: Korean
  • 7: Japanese
  • 8: Portuguese
  • 9: Ukrainian
  • 10: Russian

Next, starting at 0x7504B are five u8 values which are best left alone. The first is a possible demo mode toggle, which crashes the game, the second seems to always be 1, and the other three are unknown.

After that, at 0x75050 and 0x75054 are float values to define the volume for SFX and Music, respectively.

Next, the controller style is a u8 at 0x75058 and should be one of these values:

  • 0: PS5
  • 1: XBox
  • 2: Nintendo
  • 3: Keyboard

Finally, the u8 at 0x75059 describes the current graphics setting:

  • 0: Good
  • 1: Better
  • 2: Best

The remainder of the header appears to just be null-byte padding.