Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- =====>>>>> Cave Story+ (Switch) credits warps, explained <<<<=====
- Both the Normal Ending and Best Ending credits warps start with what I'll call
- "Core Escape": By pausing the game while cutscene-skipping the pre-Core fight cutscene,
- the cutscene continues to run, but certain things like animations are frozen, including
- that of the main shutter. After the fight, you are able to escape the room without
- having to drown first.
- Note that this cutscene-pause bug does not exist in the JP version of the game, and so
- these credits warp setups will not work in that version.
- After escaping the Core room, drowning in other rooms does crazy things instead of killing
- the player. In particular:
- >>> To warp to the Normal Ending:
- 1) Perform Core Escape.
- 2) Backtrack to Labyrinth W and drown.
- 3) ???
- 4) Profit
- >>> To warp to the Best Ending:
- 1) Perform Core Escape, then save in Dark Place.
- 2) Enter Mimiga Village (in any save file, though if your glitched save is in Curly Story,
- you must use a Curly Story save file), quit, reload back into Dark Place, and drown.
- This takes you to either First Cave (if you loaded the main story's Mimiga Village)
- or Assembly Hall (if you loaded Curly Story's Mimiga Village).
- Make your way to Start Point and save there.
- 3) Run Curly Story's normal ending (in any save file). Technically, the best ending
- would also work here, but the normal ending is obviously easier to get to. :)
- Quit in the "Fall" map (which, for normal ending, loads when the screen cuts to black
- after the island falls, and for best ending, loads shortly after Balrog says
- "A little beat up..."). Reload into Start Point, enter First Cave, and drown to
- trigger the credits warp.
- Below is a breakdown of everything that's happening to make this all work.
- I will not be assuming any knowledge of Cave Story modding, but if you have any
- experience at all with that, everything will be a lot easier to understand.
- ===== Why does drowning after Core Escape do weird things? =====
- Each map in the game has an associated TSC (Text SCript) file (named after its *.tsc
- file extension in the game's data files) that contains the scripting for all of the
- "events" that happen in that map.
- For example, the Life Capsule event in the TSC file for First Cave looks like this:
- #0400
- <PRI<SOU0022<DNP0400<CMU0016
- <MSG<GIT1006
- Obtained a Life Capsule.<WAI0160<NOD<RMU<ML+0003
- Max life increased by 3.<NOD<END
- The game also stores an array of "flags", numbered 0 to 7999 (though not all of them are
- actually used), in order to keep track of the game's progression state. Each flag is a
- single bit, meaning it can either be set (1) or unset (0).
- At the end of the post-Core fight cutscene (where Misery shows up to teleport the Core
- away), flag 4000 gets set:
- [stuff]
- <MSG<FAC0121
- MISERY!!<FAC0221<NOD<CLR<FAC0121
- What are you doing?!?
- Move the Core to the lab NOW!<FAC0221<NOD<CLR<FAC0121
- While you still have time!<FAC0221<NOD<CLO<FAC0000
- <ANP0400:0013:0002<WAI0050
- <CNP0400:0082:0002<WAI0020
- <ANP0400:0025:0002<FMU
- <MSG
- WUUUUUUUH!!<WAI0050<NOD<CLO
- <BOA0600<WAI0030
- <ANP0400:0020:0002
- <ANP0402:0030:0000
- <ANP0410:0030:0000
- <ANP0450:0020:0002<DNA0181<DNA0182
- <CMP0040:0015:0047<CMP0040:0016:0047
- <WAI0100<CMU0000<FOM0016
- <FL+4000<FL+0832<FL+0341<FL+0783<FL+0837<END
- ^^^^^^^^
- |
- ----------- right here
- Flag 4000 has a special treatment in the game's engine: Whenever the player runs out of
- air while underwater, the game checks the state of flag 4000. In most cases, flag 4000
- will not be set, so in that case the game will drown the player and run event #0041:
- #0041
- <KEY<CMU0000<WAI0040<PRI<WAI0040<CMU0003
- <MSG
- You have drowned.<NOD<CLR
- Want to retry?<YNJ0049<CLO
- <FAO0001<WAI0050<FLJ0431:0048<INI<END
- However, if flag 4000 is set, the game will *not* kill the player, but instead run
- event #1100. It's intended that the only place that you can drown with flag 4000 set is
- in the Core:
- ----- notice, flag 4000 is unset here (this is the only place it ever gets unset)
- |
- #1100 v
- <KEY<FL-4000<FAO0004<WAI0050
- <MSG
- Losing... consciousness...<NOD<CLO
- <DNP0450
- <FL+0830<FL-0825<FL+0829<FL-0827
- <FL+0800<FL+0801<FL+0372<FL+0411
- <FL+0340<FL+0159<FL+0838
- <FL-1642<FL+1643<FL-0839
- <ITJ0030:1101<EVE1110
- With the Core Escape glitch, you're able to carry flag 4000 out of the Core room.
- By drowning in a different map, you can run event #1100 in that map's TSC file.
- However, most maps don't even have an event #1100, so this is where things get
- interesting.
- ===== TSC parsing =====
- The game keeps a buffer in memory where it stores the script for the current area.
- When a new map is loaded, the game loads the contents of head.tsc into the buffer,
- followed by the contents of that map's TSC file, followed by a null character (to denote
- the end of the script).
- When a request is made to run event number N, the game looks for it in the TSC buffer
- in the following way:
- 1) A "scan cursor" (so to speak) is placed at the beginning of the buffer.
- 2) The game scans the buffer, one character at a time, looking for the '#' character.
- 3) If a '#' is found:
- a) The scan cursor is advanced to the next character.
- b) The game peeks at the next 4 characters (without moving the scan cursor),
- converts them to a number, and checks whether that number is equal to N.
- c) If that number DOES equal N, we found the event we're looking for: The scan cursor
- is advanced to the beginning of the next line, in preparation for the event to be
- run.
- e) If that number is greater than N, we passed where the event should have been
- (events are supposed to be numbered in order in the TSC file). The game stops
- scanning at this point. [This case never occurs in normal gameplay.]
- f) Otherwise, we keep going (go to step 2).
- 4) If, while scanning, the game encounters a null character (meaning we hit the end of the
- script), it stops scanning. [This case also never occurs in normal gameplay.]
- Here's the kicker: After these steps, regardless of whether the game actually found the
- correct event or not, it will start executing TSC beginning at wherever the scan cursor
- stopped scanning.
- Let's see how this lets us do credits warps:
- ===== Normal Ending credits warp =====
- The Normal Ending warp is simple: All you have to do is drown in Labyrinth W after doing
- Core Escape.
- Recall that drowning while flag 4000 is set runs event #1100. Let's take a look at
- Labyrinth W's TSC file and see if has that event number:
- [stuff]
- #1000
- <KEY<FOB0000:0016<WAI0250<CMU0000
- <MS3<CMU0015
- Defeated Monster X!<FOM0016<WAI0160<NOD<CLO<CMU0037
- <ACH0036
- <CNP0300:0000:0000<FL+0680<END
- #1200
- <KEY<ANP1200:0020:0002
- <FON1200:0016<FAI0001
- <WAI0100<FAO0001<TRA0047:1200:0038:0016
- Uh-oh! Labyrinth W doesn't have a #1100. That means that when the game goes to look for
- it, it will find the '#' in "#1200", advance the scan cursor to the '1' in "1200", and
- then check to see if 1200 == 1100. Since 1200 > 1100, the game gives up looking
- for 1100...but as explained earlier, it'll start executing TSC from the current scan
- cursor location anyways. Since the scan cursor stopped at the '1' in "1200", this results
- in the text "1200" being printed to an invisible message box, followed by the commands
- that normally get executed for event #1200.
- Event #1200 is part of the normal ending "break down" cutscene...you know the rest.
- ===== The TSC overflow (over-read) glitch =====
- Suppose that, instead of drowning in Labyrinth W to trigger the Normal Ending warp, one
- were to drown in Dark Place. What would happen?
- As before, drowning with flag 4000 set runs event #1100 instead of killing the player.
- Let's see what Dark Place's script looks like:
- [stuff]
- We can't pass through here.<FAC0025<NOD<FAC0125
- We're going to have to keep
- moving forward.<FAC0025<NOD<CLO
- <ANP0300:0003:0002<WAI0141
- <ANP0300:0020:0002<WAI0010
- <SOU0011<ANP0110:0000:0002<WAI0020
- <DNP0300<WAI0020
- <SOU0011<ANP0110:0000:0000<FL+0820<END
- #0300
- #0330 <---------------- if you don't recognize this event, that's because it's unused :)
- <PRI<MSG
- There's a switch.<NOD<SOU0043<CLR<MSG
- You flip it.<NOD<CLO
- <WAI0050
- <SOU0071
- <CMP0010:0035:0000
- <CMP0011:0035:0000
- <CMP0029:0031:0111
- <WAI0050<END
- Dark Place, just like Labyrinth W, doesn't have an event #1100. In the case of
- Labyrinth W, the TSC scan cursor stopped at the next-highest event (#1200) while searching
- for #1100. However, Dark Place doesn't have any event numbers higher than #1100.
- That means that the scan cursor will instead end up at the null character at the end of
- the script. So, when the TSC parser goes to execute the script there, it'll start by
- printing a null character to an invisible message box...and then it'll be out of bounds.
- What happens next? Well, the key thing to know here is that the game never clears the
- TSC buffer, even when loading a new area or quitting to the title screen -- it just
- overwrites the new script on top of the old script. So, what ends up happening when the
- game starts executing out-of-bounds TSC will be part of the last script that was loaded
- that's longer than the current area's script.
- So, going back to this example, suppose we drown in Dark Place after entering from the
- Core (which has a longer script). Dark Place's script is 1320 bytes long, meaning that its
- script when loaded replaces the first 1320+1 characters of the Core's script (the +1 is to
- account for the terminating null character).
- The TSC buffer will thus look something like this:
- [stuff]
- #0330
- <PRI<MSG
- There's a switch.<NOD<SOU0043<CLR<MSG
- You flip it.<NOD<CLO
- <WAI0050
- <SOU0071
- <CMP0010:0035:0000
- <CMP0011:0035:0000
- <CMP0029:0031:0111
- <WAI0050<END
- [null character; end of Dark Place script]<MSG
- >_ OPEN BLAST DOOR?<YNJ0000<CLR<FL+0825<2MV0001
- >_ OPENING BLAST DOOR.<NOD<CLO<WAI0040
- <ANP0256:0010:0001<WAI0050<ANP0301:0003:0002<ANP0302:0003:0002<WAI0078<DNP0256
- <MSG
- >_ BLAST DOOR OPENED.<NOD<END
- [stuff]
- Thus, drowning will trigger the Core's ">_ OPEN BLAST DOOR?" computer. Nothing
- particularly interesting will happen if you say "yes", because the entities that it tries
- to animate don't exist in Dark Place.
- For the sake of terminology, I'll call this a "TSC overflow from Dark Place into the Core
- script".
- We can manipulate the contents of the TSC buffer to overflow into a different map's script
- by saving in Dark Place, opening up that map (in any save file), then quitting and
- reloading back into Dark Place to drown. For hopefully obvious reasons, this only works
- for maps whose script is longer than Dark Place's script.
- For example, we can overflow into Mimiga Village rather than Core by loading
- Mimiga Village, then quitting out and reloading into Dark Place to drown. If we do that,
- the TSC buffer will look like this:
- [stuff]
- #0330
- <PRI<MSG
- There's a switch.<NOD<SOU0043<CLR<MSG
- You flip it.<NOD<CLO
- <WAI0050
- <SOU0071
- <CMP0010:0035:0000
- <CMP0011:0035:0000
- <CMP0029:0031:0111
- <WAI0050<END
- [null character; end of Dark Place script]009
- #0110
- <PRI<FAO0000<TRA0012:0090:0055:0009
- #0111
- <KEY<FL+0327<FL+0443<MSG<FAC0109
- What did you say?!?<FAC0009<NOD<FAC0109
- Toroko's been kidnapped?!<FAC0009<NOD<FAC0109
- That's terrible!!<FAC0009<NOD<FAC0109
- We have to inform King!!!<FAC0009<NOD<CLO
- [stuff]
- So, the overflow will print
- [null character]009
- #0110
- to an invisible message box, then fades the screen out and transports the player to
- map number 12...which is First Cave. (That event number, #0110, is actually just the door
- to First Cave.)
- One last thing to be aware of: Avoid opening the inventory while performing a
- TSC overflow. The inventory has its own (massively long) script, which loads into the same
- TSC buffer when opened and will clobber everything and mess up your setup. You'll end up
- overflowing into the inventory script instead of what you wanted (unless overflowing into
- the inventory IS what you wanted :thinking:).
- ===== Best Ending credits warp =====
- At its core (no pun intended), the Best Ending credits warp is simply just a TSC overflow
- from First Cave into Curly Story's "Fall" map (which is the map where the Curly-falling-
- out-of-the-sky cutscene takes place, and also the map where Quote and Curly fly on top of
- Balrog's head).
- In order to get to First Cave, however, we first have to get out of the Labyrinth.
- The usual ways of exiting the Labyrinth aren't available when doing Core Escape: The
- Waterway entrance will still be blocked off, and the Labyrinth B teleporter will still
- have no power.
- So, in order to escape the Labyrinth, we instead do a TSC overflow from
- Dark Place into Mimiga Village (explained above), which gets us out of the Labyrinth
- (conveniently, directly into First Cave).
- Note: If you're playing in Curly Story (which uses a different set of scripts),
- the Dark Place to Mimiga Village overflow will send you to Assembly Hall instead:
- [stuff]
- <CMP0029:0031:0111
- <WAI0050<END
- <END
- [null character; end of Dark Place]O0004<TRA0019:0094:0010:0010
- [stuff]
- (You get <TRA'ed to map 19, which is Assembly Hall)
- Regardless, once you're out of the Labyrinth, you want to save in Start Point. Then, all
- that's left to do is another overflow from First Cave into Curly Story's "Fall" map.
- The easiest way to get there is by running Curly Story's normal ending. If you're already
- playing in Curly Story, you can do that by going to Bushlands and drowning, which triggers
- breakdown in exactly the same way that drowning in Labyrinth W triggers breakdown for the
- Normal Ending credits warp:
- [stuff]
- <WAI0200<MSG
- It wooooooooooooon't stop!!!!!!<WAI0050<NOD<CMU0005
- <DNP0450<FL-0523<FL+0225<END
- #1200
- <KEY<ANP1200:0020:0002
- <FON1200:0016<FAI0001
- <WAI0100<FAO0001<TRA0010:1200:0050:0034
- (When scanning for event #1100, the scan cursor ends up at #1200 and runs that instead.
- Event #1200 is part of the breakdown cutscene.)
- Quit out any time after the screen goes black after the island falls, but before the
- credits roll (this is the Fall map), reload into Start Point, and head to First Cave to
- drown and trigger the Best Ending credits warp:
- [stuff]
- #0400
- <PRI<SOU0022<DNP0400<CMU0016
- <MSG<GIT1006
- Obtained a Life Capsule.<WAI0160<NOD<RMU<ML+0003
- Max life increased by 3.<NOD<END
- [null character; end of First Cave]100:0004:0015
- #0120
- <KEY<CMU0000
- <FON0240:0016
- <CNP0230:0356:0002
- <DNP0220<WAI0200 |----- Flag 2000 is what determines Normal vs. Best Ending credits
- <FAI0001 v
- <MSG<FAC0105<FL+2000<FL+1460
- Close!<FAC0005<NOD<CLR<FAC0105
- Such a narrow escape.<FAC0005<NOD<CLR<FAC1119
- I thought I was scrap
- metal this time.<FAC1019<NOD<FAC1119
- [stuff]
Add Comment
Please, Sign In to add comment