Submission Text Full Submission Page
This is a TAS of Cave Story 3D for the Nintendo 3DS. It uses glitches to skip basically everything, reaching the credits in just three and a half minutes.

General Info

  • Emulator used: Bizhawk 2.10
  • Game version: USA. The Japanese version does not have the glitch that makes this run possible
  • This run starts from a state where the Time Attack mode is unlocked. To unlock it from a clean state, you can run this movie: UserFiles/Info/638726632528766715
  • Aims to reach any version of the credits as fast as possible by any means
    • In this case, the run ends up achieving the "Normal Ending".
  • Played on Normal difficulty (it doesn't make any difference aside from the time it takes to menu to the other difficulty options)
  • Major skip glitch
  • Rerecord count: The count in the movie file seems quite low; I wonder how Bizhawk/TAStudio counts rerecords?

Comments

Ever since 3DS TASing became possible on Bizhawk, I knew that this game was due to have a TAS of this. So I took it upon myself to make it!
I've included some subtitles in the movie file; they're pretty lazily placed so feel free to adjust the timings or otherwise edit them however you like.

Inventory Glitch Explanation

This is the main glitch that is used to break the game and skip everything. Depending on who you talk to, you may also hear this referred to as the "item quit glitch" or "Beast Fang glitch". The latter name likely arises from early forum discussions following the discovery of the glitch; at the time, the most interesting application that was known was using it to obtain the "Beast Fang" item, which exists in all versions of Cave Story but is buried inside the floor of Yamashita Farm making it normally unobtainable. In this game, inspecting the description of this item reads "You're not supposed to find this. How'd you do it?".

Background

Level data in Cave Story is divided into multiple files. For simplicity, I'll break it down into three main parts:
  • Map data—defines the level geometry
  • NPC data—specifies the type and placement of objects and enemies inside the level, along with any special properties they may have (such as being interactable)
  • TSC (Text SCript)—contains scripting for cutscenes and interactable entities.
For our purposes, we'll be mainly concerning ourselves with the interaction between these last two parts.
As an example, consider the exit door in Start Point. The NPC data for the map contains the following information about this door:
  • NPC type: 18 (Door)
  • Location: (10, 3)
  • NPC flag: 0 (irrelevant for our purposes)
  • Event ID: 100
  • Properties: Is interactable
When the player pushes down in front of the door to interact with it, the game executes the TSC event according to the event ID of the door (100, in this case). This is what that looks like in the Start Point script:
#0100
<PRI<CNP0100:0000:0000
<SOU0011<FAO0001
<TRA0012:0091:0037:0011
You don't have to understand this completely, but basically, what this event does is:
  • <PRI: Lock the player controls and freeze the game
  • <CNP0100:0000:0000: Change the NPC with event ID 100 into type 0 (this simulates the door opening by turning it into an NPC with no sprite, although with the 3D layer on top of everything, you don't get to see that in this version of the game)
  • <SOU0011: Play sound 11 (door opening sound)
  • <FAO0001: Fade the screen out with direction 1
  • <TRA0012:0091:0037:0011: Transport the player to map 12 (First Cave) at coordinates (37, 11), and then run event 91 in that map (which handles the rest of the transition into the level).
The important point here is that the entire link between the door object in the map and the behavior of the door when interacted with is through its event ID. If one were to edit the event ID of the door, or what event #0100 in the script does (hint), then the door would do something different.

The Inventory Glitch

The inventory screen also uses a script, which is where all of the weapon/item names and descriptions are written. This script isn't loaded separately when using the inventory; rather, there is a single buffer in memory for "the current script". During normal gameplay, this buffer would contain the script for the current map, but when opening the inventory, the buffer is overwritten with the inventory script. In order to ensure that the map script is restored properly afterwards, the game does the following (simplified slightly):
  1. When opening the inventory, the game remembers the name of the current map script
  2. The game then loads the inventory script into the script buffer
  3. When the inventory is closed, the game reloads the script that it remembered from step (1).
There is a bug with the inventory: If you quit to the main menu while the inventory is open, and then load back into the game (via any save file or Time Attack), the inventory will still be open upon entering the game. Closing the inventory then potentially reloads the wrong script!
Here's how that works (see the run breakdown below for concrete examples):
  1. Suppose the player is in map A, and opens the inventory. As explained above, the game now remembers that map A was the current script, so it can reload that when the inventory is closed.
  2. With the inventory open, the player then quits to the title screen menu. (In shorthand, these first two steps are referred to as an "Item Quit" (IQ) from map A.)
  3. The player then loads a save file in map B. At this point, the game loads with the inventory still open, but map B's script as the current script. (Note, this means that interacting with the inventory will run events from map B instead of displaying the inventory items correctly. This isn't used in this run, but it does have applications in other contexts.)
  4. When the inventory is closed, the game reloads map A's script, which is the script that it remembered from step (1). Now the player is in map B, but with map A's script! That means that interactable NPCs in map B will run whatever event in map A's script happens to match their event ID. With the right combinations, this can be used to bypass door locks and item checks, trigger progression events early, obtain extra health or items...really, the sky is the limit here. This run really is only scratching the surface of what's possible with the inventory glitch!

Run Breakdown

General Techniques

This game is quite similar to the original Cave Story in terms of mechanics, but also different in one very important way: Although the game physics runs 60 times per second, the game renders frames and polls inputs only 30 times per second. Effectively, this means that I can only change inputs every other "frame", and any input I do can only be held for an even number of "frames". This limitation makes TASing this game much more annoying compared to the original—there were many instances throughout the TAS where I really wanted to jump on a particular frame, but that frame was an "in-between" frame so I couldn't jump there; also, not being able to do one-frame left/right adjustments has ramifications for the kinds of speed manipulation setups that are possible.
Besides that, all of the physics, mechanics, and techniques are the same as the original Cave Story, so please give nitsuja's TAS of the original game a watch if you want to learn more about that. Even the fact that this game is in 3D doesn't affect anything aside from making it visually harder to see where the edges of the platforms are; the underlying map data format and collision physics are still the same as the original, and in fact the data files can even be copy/pasted into the original game to make "Cave Story 3D but in 2D".

Start Point

Jumping to the door might look unoptimal since I land well past the leftmost point that's possible to interact with, but I'm actually jumping to avoid a tutorial trigger that was added to this version of the game.
Fun fact, that trigger was supposed to extend one block higher, which would have made it impossible(?) to avoid, but the developers mistakenly set an NPC property that makes it spawn one block lower than its placement in the map editor. So actually, half of that trigger ends up inside the ground and the other half only covers one block next to the door.

First Cave

The 30 Hz input polling restriction made optimizing this stage quite annoying, because I would have loved to borrow inputs from TASes of the original game, but I can't replicate all of their setups because of 1-frame button presses that I can't do, or inputs that would need to occur on a "skipped" frame that would not work if I did them on either of the neighboring frames. I ultimately had to make several concessions and forgo a number of optimizations that I simply could not find a way to pull off under the constraints. Nevertheless, when considering the section from entering First Cave to emerging out of the tunnel before Hermit Gunsmith, the movement in this run is about 3 frames faster than nitsuja's Best Ending TAS, after normalizing for framerate. The way back isn't as comparable since I don't need the Life Capsule for this run, but for the parts that are the same, I think I more-or-less broke even compared to nitsuja's TAS.
Also, the evil eye door at the end is one block to the right compared to the original, which makes it harder to get early shots on it. At the same time, the extra distance meant that I had time to shoot a bunch while landing onto that platform and walking towards the door. In the end, the door died right as I reached the doorway, so I think it more-or-less balanced out.
You may wonder if it's possible to skip any of the gameplay here. Indeed, if we could run event #0103 or #0104 from the First Cave script, then the Polar Star would not be needed at all. Unfortunately, in this early stage of the game, there are really only two maps that we can readily load into after an item quit (Start Point and Time Attack), and neither of those maps contains an interactable NPC with either of those event IDs. (Technically, it's also possible to enter the Shelter by letting the opening cutscene play out a bit before closing the inventory. However, this cutscene places the player above the ceiling of the level, so we can't actually get inside. Also, that room doesn't have any NPCs with event ID 103 or 104 anyways.)
There are other more advanced methods for manipulating TSC (which I won't get into here); I looked into the possibilities for that as well but couldn't come up with anything useful on that front.

Inventory Quit Setup #1: Breaking Into Arthur's House

Upon entering Mimiga Village, the first step is to get into Arthur's House, which has connections to many other areas of the game. The door to Arthur's House is locked, so the intended sequence here is to go into the Reservoir to get the Silver Locket, then go into the Shack to watch a cutscene that grants access to the Cemetery where the key is located. However, with the inventory glitch and the help of the Time Attack mode, we can skip all of this.
Here is the part of the Mimiga Village script relating to Arthur's door:
#0100
<PRI<FLJ0324:0102
<ITJ0001:0101
<MSG
It's locked.<NOD<END
#0101
<SOU0022<GIT1001<FL+0324<FL+0441
<MSG
Used Arthur's Key.<NOD<GIT0000<CLO<EVE0102
#0102
<SOU0011<CNP0100:0000:0000<FAO0004<TRA0001:0094:0017:0008
The door itself has event ID 100, and we can see that event #0100 in the script does the following:
  1. If we've already unlocked the door (<FLJ0324:0102), then jump to event #0102, which is the event that transports the player to Arthur's House (<TRA0001:0094:0017:0008)
  2. Otherwise, if we have Arthur's Key (<ITJ0001:0101), then jump to event #0101 which unlocks the door and then jumps to event #0102 (<EVE0102) to take the player to Arthur's House
  3. Otherwise, display a message saying that the door is locked.
Thus, to bypass the key check, we simply need to directly run either event #0101 or #0102 with Mimiga Village's script loaded. This is where Time Attack comes into play: By IQing from Mimiga Village and loading Time Attack, this loads the Mimiga Village script in the starting Time Attack room. The Fireball chest in this room conveniently has an event ID of 101, matching the event number that unlocks Arthur's door. Presto! Now we're inside Arthur's House.
By the way, saving here would have no effect, since we're technically still in the Time Attack mode, which has no associated save file slot.

Inventory Quit Setup #2: Entering Sand Zone

From Arthur's House, we IQ and start a new game (after all, we never even saved the first game to begin with). The opening cutscene tries to play here, but closing the inventory also cancels this event, so we don't have to watch that again. Once again, it's important here that I jump over the tutorial trigger—stepping on it in this state would run an event from Arthur's House, which we really don't want! (It's Jack's dialogue after returning from Egg Corridor, if you're wondering.)
We interact with the door, which as mentioned earlier has event ID 100. Now, by convention most maps have event ID 100 assigned to their "main exit", and if this was the case for Arthur's House as well, then this event would have probably taken us back out into Mimiga Village. However, curiously enough, Arthur's House is one of the few maps that doesn't follow this convention—the door in that map actually has event ID 102. (Annotations surrounded by /* */ were added by me):
#0100
<PRI<FAO0004<TRA0010:0094:0018:0032 /* Transport to map 10: Sand Zone */
#0101
<PRI<FAO0004<TRA0012:0094:0037:0011 /* Transport to map 12: First Cave */
#0102
/* Transport to map 11: Mimiga Village */
<FLJ0155:0103<PRI<SOU0011<DNP0102<FAO0004<TRA0011:0094:0016:0053
#0103
/* Transport to map 11: Mimiga Village (cutscene after Egg Corridor) */
<PRI<SOU0011<CMU0000<DNP0102<FAO0004<TRA0011:0400:0016:0053
All of this is to say, even though Arthur's House has an event #0100, it's actually an unused event that warps to Sand Zone at some rather odd coordinates. But this ends up being quite useful for us!
(If you're wondering, event #0101 is also unused and leads to First Cave, at the coordinates of the Start Point door.)

Inventory Quit Setup #3: Warping to the Ending Sequence

We IQ from Sand Zone and start a new game (we still never saved). In addition to the tutorial trigger next to the exit door, there is also another trigger that runs the same tutorial event, located next to the health refill and save point. This is what I jump into since it's closer than the one next to the door.
The tutorial trigger has event ID 527. For those who haven't played this game, this is what it says (from the Start Point script):
#0527
<DNP0527<SKJ0022:0000<SK+0022
<0CS<PRI<MS3
Press Down on the +Control Pad
to activate Save Points, collect
items and enter doors.<NOD<END
However, we don't have the Start Point script loaded anymore, so this is not the event that runs. With Sand Zone's script now loaded, this is what the script looks like:
#0501
<PRI<DNP0501<SOU0022<CMU0016
<MSG<GIT1006
Obtained a Life Capsule.<WAI0160<NOD<RMU<ML+0005
Max life increased by 5.<NOD<END


#1200
<KEY<ANP1200:0020:0001
<FON1200:0016<FAI0001
<WAI0100<FAO0001<TRA0039:1200:0061:0012
You'll notice that Sand Zone doesn't have an event labeled #0527. What happens in this case? Well, TSC events are always written in order, so when looking for event 527, the TSC parser stops once it sees event #1200, since 527 should have come before 1200. The TSC parser then returns that it failed to find event 527...and then proceeds to completely ignore this error condition and start executing TSC anyways, starting from the last position that it reached during its search (which would be at the 1 in #1200).
This results in the text "1200" being printed to an invisible textbox (which explains the text typing sounds that you hear), and then the TSC of event #1200 executes. This event in Sand Zone is part of the normal ending "break down" cutscene, where the game pans across the maps you've traveled through during your quest while the island is falling. This cutscene is supposed to start from jumping off the edge of the Balcony, so jumping into the middle of it like this messes up the camera and some other things. Nevertheless, the cutscene plays out to the end and ultimately leads into the credits. Congrats, the game has now been beaten(?)!

Possible Improvements

Really the only nontrivial gameplay in this run is in First Cave. If it weren't for the 30 Hz input restriction, the movement from Start Point to Hermit Gunsmith would be improvable by at least 4 frames. I wonder how many of those frames could still be squeezed out in spite of the restriction?
The movement in the Time Attack room would also be improvable if there was a way to pause-buffer a lower jump, which would allow for landing earlier after each boost. (Note, due to the 30 Hz input polling, the lowest jump I can do before starting a boost is effectively 2 frames of jump followed by 2 frames of releasing jump before starting the boost.) I tried pausing with the Start menu and with the inventory, but in both cases it seemed to have no effect on the jump height, so I guess either it doesn't work or there's a particular timing or method that I didn't consider.
Also in the Time Attack room, I tried boosting down to land earlier to refuel the Booster, boosting down onto the chest instead of releasing the boost early and falling down naturally, boosting down into the side of the starting platform to get a rightward push from it, and various other ideas along those lines, but none of those ideas seemed to save any time.

Other Comments

Special acknowledgments go to the Cave Story modding community; it is thanks to their work in advancing our knowledge of the game over the past 20 years that putting together this run was simply a matter of recording the inputs for it.
I leave the screenshot to community suggestion and/or publisher's discretion.


TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 15764
Location: 127.0.0.1
This topic is for the purpose of discussing #9496: periwinkle's 3DS Cave Story 3D "game end glitch" in 03:26.45
GJTASer2018
He/Him
Joined: 1/24/2018
Posts: 314
Location: Stafford, NY
Yet another game we can put in the "credits longer than gameplay" category!
c-square wrote:
Yes, standard runs are needed and very appreciated here too
Dylon Stejakoski wrote:
Me and the boys starting over our games of choice for the infinityieth time in a row because of just-found optimizations
^ Why I don't have any submissions despite being on the forums for years now...
Patashu
He/Him
Joined: 10/2/2005
Posts: 4048
Nice work. I'd love to see glitched best ending and glitchless best ending TASes too, if you ever get the itch to come back.
Puzzle gamedev https://patashu.itch.io Famitracker musician https://soundcloud.com/patashu Programmer, DDR grinder, enjoys the occasional puzzle game/shmup.
ikuyo
She/Her
Judge, Experienced player (534)
Joined: 7/8/2021
Posts: 102
I look away for like two days and you beat me to the punch for this one! Nice work. Glad to see CS3D get the love it deserves!
CoolHandMike
He/Him
Editor, Judge, Experienced player (945)
Joined: 3/9/2019
Posts: 779
Very cool skipping to credits using incorrectly loaded and executed scripts!
discord: CoolHandMike#0352

1737742897