If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!
This article has a talk page!

Cave Story

From The Cutting Room Floor
Jump to navigation Jump to search

Title Screen

Cave Story

Also known as: Doukutsu Monogatari (JP)
Developer: Studio Pixel
Publishers: Studio Pixel (Windows), Nicalis (WiiWare, Cave Story+)
Platforms: Windows, Mac OS X, Linux, WiiWare, Nintendo Switch
Released internationally: November 22, 2011 (Windows/Mac), December 13, 2011 (Linux)
Released in JP: December 20, 2004 (Windows)
Released in US: March 22, 2010 (WiiWare)
Released in EU: December 10, 2010 (WiiWare)


AreasIcon.png This game has unused areas.
CodeIcon.png This game has unused code.
DevTextIcon.png This game has hidden development-related text.
EnemyIcon.png This game has unused enemies.
GraphicsIcon.png This game has unused graphics.
ItemsIcon.png This game has unused items.
TextIcon.png This game has unused text.
DebugIcon.png This game has debugging material.
RegionIcon.png This game has regional differences.
Carts.png This game has revisional differences.


ProtoIcon.png This game has a prototype article
PrereleaseIcon.png This game has a prerelease article

Cactus Story
This page focuses primarily on the original Windows release, not the Nicalis-produced versions.
You can find info on the console and PC remakes in the Sub-Pages.
Additionally, this page focuses on the (half-official) English translation of the game.

Cave Story is an indie game released for free from Japan, with program, art, music, character design, and everything all coming from a single man in his spare time. It was later picked up by publisher Nicalis which made several ports of the game for WiiWare, Mac App Store, DSiWare, Steam, Nintendo Switch, and 3DS (one retail version and one eShop version based on the DSiWare port).

This page primarily covers the original Windows release. For other versions, check the Sub-Pages.

Hmmm...
To do:
  • More information, more images.
  • The released prototype screenshots and music.
  • The Wii version also has unused content and remixes the unused theme.
  • Version differences. There are also 16 (!) test versions that were available about two months before the game's release. So if anyone manages to find one of these lying around, they should give it to the internet to dissect.
  • Add the rest of the unused functions.
  • More images for the re-purposed objects?
  • There might still be a few more differences from 1.0.0.5 to 1.0.0.6.
  • Unused carets:
    • 4 (looks like the Snake's projectile trail)
    • 14 (broken - might be related to the 'large dissipation effect' described in this article)
    • 17 ('PUSH JUMP KEY!')
  • Background type 0 also appears to be unused.

Sub-Pages

Read about prototype versions of this game that have been released or dumped.
Prototype Info
Read about prerelease information and/or media for this game.
Prerelease Info

Resources

CaveStory-riverme.png
Unused Graphics
Quote! It's me!
TextIcon.png
Unused Text
Oh, you got me...

Re-Releases

Cave-wiirough.png
Windows vs. Wii
Despite not being much more than a copy-pasted port, there are some differences.
Cave-wiifinal.png
Wii versions
The initial Wii release was so rushed, they made a second version to fix some of the problems of the original. They later updated the North American version with these changes.
CaveStory-Eshop quote.png
DSiWare
The second official port, and first on a handheld.
Cave-wiifinal.png
Cave Story+
The PC port of WiiWare, touched up with some bonus content.
CaveStory-Eshop quote.png
eShop version
That one version on the 3DS that isn't 3D.
CaveStory-SwitchQuoteanim.gif
Nintendo Switch version
Even though it has some little tweaks, this version is the most superior.

Unused Entities

5A/#90 Unknown

An entity whose only coding is to display a single sprite. Given the size of its framerects (as well as its coded behaviour) match up with the Debug Cat entity, it's theorised this was a possible early version of it.

0A/#10 Balrog (Shooting)

Balrog, a recurring miniboss throughout the game, has several objects for when he's doing different things, including one for dropping in from the ceiling, one for bursting in through the wall, one for standard cutscene animations, one for every boss battle, and even a major boss for when he transforms into a giant frog.

This object in particular is one of the miniboss battle versions of him which was never used. It consists of a very simple pattern of shooting three of his energy bubble projectiles, jumping to the opposite side of the room in one giant leap, shooting three more, jumping all the way back, and repeating.

Various forms of Balrog can be seen in the prototype art and screenshots, so this AI is left over from a much earlier version of him as seen here.

BD/#189 CaveStory-homingflame.gif Homing Flame

A few seconds after entering a room with this object, it slowly moves toward and swerves around the player, occasionally hitting them. Sprites for this are found in both NpcSym.pbm and NpcAlmond.pbm, suggesting it was originally going to be used in the Core fight. The enemy that remains in the game reads from NpcSym.pbm and uses the sprite positioning of the blue flame found on that sheet.

01 2F/#303 Curly's Machine Gun

Seems to be a clone of #181, the machine gun Curly wields in the Labyrinth. However, there is no code attached for it to actually fire, and has to be spawned by a "parent" NPC. May have been intended for a cutscene.

Objects Repurposed From Earlier Iterations

The original Linux port contains a complete set of debug symbols, including the names of every variable in the game. Over the course of the game's development, Pixel's variable naming scheme changed. This allows us to determine the age of various objects:

Notably, the oldest objects in the game (dating back to before the development reset) name their spritesheet bounding boxes "rect_left" and "rect_right", while newer objects use "rcLeft" and "rcRight".

Here's a list of these recycled objects in order (hypothetical, but these seem to match up with what we know about the versions prior to the restart of development):

  • 09, 0A, 0B, 0C, 13, 24, 44, A9 - All of these are objects for Balrog, who was repurposed from the earlier versions, being a common character.
  • 1A - Black bat that goes in circles.
  • 21 - Balrog projectile.
  • 33 - Crow holding a Skull Head.
  • 41 - Blue bat.
  • 54 - Basu's projectiles.
  • 6C - Balfrog projectile (this was likely repurposed from a scrapped enemy, as far as it is known, Balfrog wasn't in the earlier versions).
  • 94 - Critter projectile.
  • 9C - Gaudi projectile.
  • AE - Armoured Gaudi projectile.
  • B2 - Core projectile (spinning) (the core was repurposed from the earlier versions).
  • B3 - Core projectile (wisp).
  • BB - Fuzz core.
  • BC - Fuzz baby.
  • CA - Zombie Dragon projectile (likely repurposed from an old enemy).
  • CE - Counter Bomb from Egg Corridor(?)
  • D1 - Basu's projectiles from Egg Corridor(?) (deal more damage)
  • E8 - Orangebell.
  • E9 - Orangebell's smaller bats.
  • F2 - Red bat.
  • F8 - Misery vanishing during her boss battle (Misery is based off of another scrapped character, although the actual boss was changed, this seemed to stay the same...)

Hidden Objects

These are difficult to find even with a map editor because Pixel's work style is to make an object for every single event, including ones that don't need a new object to function.

There are many many objects scattered throughout all of the maps, and you can't even depend on the object type to determine if it is used or not because an event might change them into something else to make them "appear".

Pixel also probably couldn't fully delete objects from his maps as he was making them, so instead he simply reused them as something else, set them to have an event and type value of 0, or pushed them into a wall where they would not be noticed.

This section is for looking at the latter of those. The objects which are set to all 0 are not worth listing.

Start Point

Located exactly 6 tiles underneath the player's starting point is an invisible trigger that runs event 200, which is the opening cutscene. Perhaps it was originally placed on the player, and that's how the cutscene was initiated, whereas the final game is hardcoded to run event 200 when the player starts a new game. Further supporting this idea, this is the only place in the entire game where flag 430 (set when the cutscene plays) is taken into account, as this trigger despawns if that flag is set.

First Cave

Unused wall spikes revealed.

This screen contains some spikes surrounding the lion head doorway near the bottom. When pushed out of the wall in the direction they're set to face, you see them on either side above the lion's head, providing some interesting atmosphere and a slight jumping challenge to cross the gap there.

It also seems that, since the map "Pole" (the Hermit Gunsmith's abode, where you get the polar star) is so late in the map list, and there is a deleted NPC above the doorway, originally there was simply a chest there which contained your first weapon, probably the Snake. As the Snake cannot break the tiles blocking the exit, there is also another deleted NPC on top of the uppermost of the three blocks, which was probably used as either a vertical script trigger or something similar to the laser system seen in Egg Corridor, which would block you from exiting without a weapon despite the breakable blocks not being there. The Snake was probably replaced by the Polar Star there later, but the Pole map still was not necessary until the Spur came into existence, so this chest probably lasted a long while.

A nearby mostly-deleted and probably related NPC pushed into the wall on top of the spikes carries the unused event number 220. This was likely a talking NPC of some kind (and less likely a second chest) which would have been situated on the far ledge, as 1xx events are used for doors, 3xx events are used for items like the beast fang, 4xx events are used for life capsules, events 200 and 201 actually already exist in the script for the original chest (containing only <END), and the 2xx range of events seems to be used for those general purposes.

Arthur's House

CaveStory ArthursHouse Kazuma.png

Kazuma's NPC for typing on the computer - as seen in the beginning cutscenes - can be found in Arthur's House. However, it has no assigned event and is set to disappear upon flag activation, with its assigned flag being 0... which, due to the way the game works, is impossible to avoid being set by the time one reaches Arthur's House.

Unused Items

05 CaveStory 05.png Beast Fang

AGTP Translation Official Translation
A sharp fang found at the
Yamashita Farm. Is its owner still
alive...?
You're not supposed to find this.
How'd you do it?
Location of the Beast Fang in Yamashita Farm.

Found in the Yamashita Farm, as the description states. It is one tile below the ground where the Life Capsule now rests, suggesting that is where it was originally placed. The text that should appear when you collect it is:

AGTP Translation Official Translation
You see something gleaming...
Got the =Beast Fang=.
You don't see anything...
How did you get the Beast Fang?
...

Both sets of associated dialogue are changed in the Nicalis translation to reference its unused nature.

Pixel has confirmed that the fang is from the Red Ogre in the Last Cave:

http://i.imgur.com/iO6ET.png
Oh.. I forgot.. but it's right..

— Pixel's BBS

and from what this shoddily Google Translated webpage says, it was supposed to act as foreshadowing. Another idea tossed around was for it to be used in Jenka's soup.

06 CaveStory 06.png Life Capsule

A life capsule.

This is used for the small image in the dialogue box when you collect one, but never is available in the inventory. Despite this, it still has text for the inventory screen, which cannot be seen.

Unused Scripts

Hmmm...
To do:
There's more.

Shootable Block Tutorial

#0150
<KEY<MYD0000<CMU0008<FAI0004
<WAI0030
<SOU0012<CMP0050:0035:0067<WAI0020
<SOU0012<CMP0050:0036:0067<WAI0020
<END

This script in the First Cave, when activated, will create two shootable blocks outside of the Hermit Gunsmith's entrance and make you look at them. The blocks block the way out, forcing you to shoot them. Pixel probably decided that this was too handholdy (and random!), especially when you still have to shoot the blocks earlier in the level to get past them (although these may have been added later).

Alternate Sand Zone Residence Entrance

#0101
<PRI<SOU0011<DNP0101<FAO0000<TRA0029:0090:0018:0009

<FLJ0560:0102
#0102
<PRI<SOU0011<DNP0101<FAO0000<TRA0031:0090:0018:0009

The script for entering the Sand Zone Residence has a flag jump command placed after the command that transports the player, which results in it not being run. If flag 560 (set while battling Curly Brace) is set, this command would've run unused event 102, which transports the player to... the Main Artery?!

Given the Main Artery's map ID's close proximity to the Sand Zone maps, as opposed to the Labyrinth maps, this suggests that this map was originally used for a version of the Residence without the boss objects, before the final game optimized this to just one map, leaving an unused space for when Pixel eventually needed to add a new map.

Waterway to Reservoir

#0110
<KEY<FON0200:0016<WAI0010<FAO0000<FOM0016<FLJ850:0111
<FL+0850<MSG
Something's coming!!<NOD<MYD0000<TRA0031:0092:0030:0008

#0111
<KEY<CSS<TRA0015:0093:0014:0001

The trigger for the Ironhead boss fight, in Waterway. Normally when you go past the trigger, it transports you to the Main Artery. When the script is activated a second time, it jumps to event 0111, which takes you to the top of Reservoir (falling down into the water), suggesting that you would originally be able to go back into the Waterway, for whatever reason.

Notably, there's an error in this script:

<FLJ850:0111

It should instead read:

<FLJ0850:0111

This might not seem like a big deal, but due to the script system in Cave Story always expecting parameters to be 4 digits with any 1 character in-between each parameter, this causes this instruction to look to see if flag 8510 (flag "850:", the ":" is read as 10) is set, which is only a non-issue despite flag 8510 being out-of-bounds (highest in-bounds flag is 7999) because the bit in the memory position of flag 8510 is always off.

This error is a leftover from version 1.0.0.5 and earlier: while it was fixed in the Japanese v1.0.0.6, the AGTP translation accidentally retained it when it was updated. Interestingly, this error also carries over into the Nicalis translation for the Steam and Wiiware versions, however it is fixed in Cave Story 3D and future versions. (This is likely to do with Nicalis being provided an earlier version of the game to work with initially.)

Main Artery to Core

#0100
<KEY<FAO0001<CSS<TRA0047:0091:0008:0009

Takes you to the Core with an upwards fade, and spawns you in midair next to the computer on the left.

A leftover from an earlier version, perhaps?

Egg No. 00 to Arthur's House

#0300
<PRI<FAO0004<TRA0001:0094:0005:0007

Located right underneath the used event 300 (the computer screen that states the egg is ready to be hatched), this script warps the player back to Arthur's house. Either this is a debug leftover, or the player was originally going to be able to get back to Arthur's house without backtracking.

Plantation

#0323
<PRI<EQ+0064<END

Freezes the game, and then equips the Mimiga Mask. Probably for testing purposes.

Little Man's House

#0200
<PRI
<FLJ1373:0206
<FLJ1372:0202

The script used by the Little Man has an extra flag jump command meant for flag 1373. Given that the used flag is 1372, this is likely just an earlier version of the branch that is triggered when the player has already traded the Blade for the Nemesis. But, that's not the most interesting thing found in this room's script file...

#0500
<KEY<CNP0250:<FAI0000<END

There's also this bizarre script, which seemingly would've been triggered if a flag was set when entering the room. Notably, the <CNP command is incomplete, as it lacks the latter input of the command. Due to how the game reads its scripts, this leads it to try to change this non-existent NPC into an NPC with ID 14395, which crashes the game.

Unused Map Data

Cook.pxm

CaveStory-Cook.png

There is only one unused map in the game, and it has neither an entity or script file to go with it. The date modified on the .pxm (PiXel Map) file is August 7, 2002, a mere two months after the development reset, meaning Pixel scrapped this one pretty early on.

The map's theme is that of a 3 floor metal building, with a door on the left of the second floor, and a slot for a fireplace in the room just to the left of it. The only places to use the metal building theme in the final are some Grasstown rooms and Jenka's house in the Sand Zone. Judging from the name, it had something to do with cooking.

New.pxe

Cent.pxe New.pxe
Plantation (Cent.pxe)

Plantation (New.pxe)

This seems to be the .pxe (PiXel Event) file for an earlier version of the Plantation, as it's the closest match and yet only some of the doors line up. Apparently Pixel didn't even get around to naming the place before scrapping this version of the layout.

555.pxe

Yet another unused .pxe (PiXel Event) file. Seems to be not contain any entities, given that it is only 8 bytes. It only appears for Version 1.0.0.6, as it is not present in the files for Version 1.0.0.5.

Version Differences

There were a lot of versions of Cave Story released through the years, unfortunately, most of them have fallen through the depths of time, but we have just about 5 versions.

Version 1.0.0.7

This version improves text support for Chinese and other languages, it was created for fan translations, otherwise identical to 1.0.0.6.

Version 1.0.0.6

This is the most common and up-to-date version of Cave Story, and it's the version Pixel still distributes.

Version 1.0.0.5

This is the earliest full version we have, there's not very many differences, but they are there.

  • For some reason, there's a missing Sleep call in the function to draw the window, where it also waits for the next frame. This causes the game to use as much CPU as it can, making it very slow.
  • The open chest object's code is screwed, the flashing seems a bit faster, and it disappears for a split second when it does flash.
  • Title.pbm's layout is different from in 1.0.0.6.

Version 1.0.0.4

Well... we don't *actually* have version 1.0.0.4 in its original form, but we do have it anyhow.
The Linux port! That's right, the Linux Port by Simon Parzer and Peter Mackay, when Pixel gave him the source to Cave Story, he gave him the source for version 1.0.0.4. How do we know this? On top of their own confirmation, there's quite a few differences between this version and 1.0.0.5.

  • The Behemoth is missing its effects when enraged, this being the smoke and screen shaking effects.

But the real smoking gun? On the title screen, it refers to itself as Version 1.0.0.4. Unfortunately, we don't seem to have any of the original assets that came with it, and of course, all the code that's changed to use SDL can't be referred to.

Version 1.0.0.0

Hmmm...
To do:
Compare to 1.0.0.4/5

The initial release of Cave Story

  • For some reason, there's a missing Sleep call in the function to draw the window, where it also waits for the next frame. This causes the game to use as much CPU as it can, making it very slow.
  • DoConfig.exe does not have options for selecting 24 bit or 32 bit color full screen modes
  • The fanfares that play when getting items (FANFALE1.org), collecting a heart container (FANFALE2.org), or defeating bosses (FANFALE3.org) will loop and play again after 13:46, 17:34, and 13:46 respectively. This is because in 1.0.0.0 the org files are 255 measures long and are set to loop the whole track. In later versions they are configured to only be as many measures as they need to be and to endlessly loop a single measure of silence instead.
  • Toroko's Theme has 2 additional notes at the very beginning that were removed in later versions.

Toroko's Theme (TOROKO.org)

1.0.0.0 1.0.0.5 and later

There are 2 additional notes at the very beginning that were removed in later versions. The background track starting at 18 seconds is also louder.

Debug Functions

The game has a number of hidden debug features:

Mute

Creating a blank file named "mute" (no file extension) in the same folder as the executable will add an extra option to the menu bar, titled 'Mute'. Selecting it will give you this:

CaveStory Mute menu.png

The tick-boxes will disable certain audio channels in the music.

The game's sound engine (Organya) actually has 14 audio channels, with the last 6 being reserved for drums, so this menu will only let you mute the melody channels. (Normally Organya has 16 channels with 8 for drums, but Cave Story only has 6 hard-coded drums that are assigned to the first 6 drum tracks, rather than making a selection of drums available for each track like in the OrgMaker and OrgMaker2 programs.)

Debug Save

This menu cannot be enabled with a file, as there's no check for it in the game's code. It can be restored, however, with a modification to the game's executable: Using a hex-editor, change the two bytes at 0x12D4D to EB0F. Doing so will add a 'Debug Save' option to the menu bar, which reveals this menu:

CaveStory Debug Save menu.png

This allows you to create save files at any time, with any filename. The game contains an unused drag-and-drop handling function that allows save files to be loaded by dragging-and-dropping them onto the game window. However, the game's window does not have the "supports drag and drop" flag enabled, so this behavior goes unused.

Hmmm...
To do:
  • Find a way to re-enable this function.
  • Document said function in the "Unused Functions" section.

Framerate Counter

Same as before, creating a blank file named "fps" in the same folder as the executable will enable an FPS counter at the top-right of the window. The freeware release ran at 50FPS, so the number will average at around this.

Unused Code & Functions

Hmmm...
To do:
There are a lot more of these.

Littered throughout Cave Story's executable are functions that are unused in the actual game, some from the versions before development reset, and some that were just scrapped.

KillAll

Most likely a debug feature, KillAll is an invisible bullet that deals 10,000 damage in a 200x200 tile range.

Turbocharge and Spur

If the player holds both the Turbocharge and the Spur (impossible legitimately due to the Turbocharge only being obtainable if you have the Machine Gun) the Turbocharge affects the Spur, making it charge 1.5x times faster.

PitMyChar

This function moves the player down by 2 tiles (32 pixels). The simplicity of this function implies that this was supposed to be a TSC command, though it's unknown what it would have been used for...

void PitMyChar()
{
	gMC.y += 0x4000;
}

Weapon Ammo

Interestingly, a lot of Cave Story's weapons which don't ever get any ammo (infinite) still have code to handle ammo. Most of these weapons are just copied from the pre-development reset versions, where all weapons had ammo. The behavior when you run out of ammo also varies.

Snake

The Snake, which comes from the beta's "Frontier". Each shot uses 1 ammo, and when it runs out it switches to your first weapon. This was actually the standard behavior of when you run out of ammo until later in development, according to the Revisional BBS (Pixel 2004/01/30-09:23). Interestingly, there's what appears to be ammo for it in NpcSym.pbm.

Polar Star

The Polar Star, originally the "Doggy Gun". Each shot uses 1 ammo, and when it runs out it plays the "empty" sound, but oddly doesn't create the "EMPTY" effect.

Fireball

The Fireball. Each shot uses 1 ammo, and when it runs out it switches to your first weapon. Interestingly, there's what appears to be ammo for it in NpcSym.pbm.

Nemesis

The Nemesis. Each shot uses 1 ammo, and when it runs out it switches to your first weapon. This behavior likely comes from copying the code from elsewhere, as the Nemesis is not known to have come from the beta or to have ever had ammo.

Spur

The Spur has its shooting code copied from the Polar Star, so its behavior is identical to it.

More Ammo Drops?

In the function "SetBulletObject", which handles creating the missile drops when an enemy is defeated, the code suggests that more weapons were intended to have ammo dropped for them. Additionally, there are unused sprites in NpcSym.pbm that appear to be for Fireball and Snake ammo drops.

int tamakazu_ari[10];
int t = 0;

memset(tamakazu_ari, 0, sizeof(tamakazu_ari));

for (n = 0; n < 8; ++n)
{
	switch (gArmsData[n].code)
	{
		case 5: /* Missile Launcher */
			tamakazu_ari[t++] = 0;
			break;

		case 10: /* Super Missile Launcher */
			tamakazu_ari[t++] = 1;
			break;

		default:
			tamakazu_ari[t] = 0;
			break;
	}
}

if (t == 0)
	return FALSE;

n = Random(1, 10 * t);
bullet_no = tamakazu_ari[n % t];

As can be seen, the code handles the Missile Launcher and the Super Missile Launcher, and randomly chooses one of them to drop. It'd be weird for Pixel to just write the code like this just for the two Missile Launchers, especially since you can't have both at the same time. Once again, it was likely intended for there to be ammo drops for more weapons, like the Fireball and Snake.

Hidden Control Option

Creating a file named "s_reverse" in the same folder as Doukutsu.exe will cause the weapon-toggle keys to be reversed. It's odd that this isn't simply an option in the DoConfig tool.

Main Artery's Secret

Cave Story Main Artery.png

In the Main Artery, where you fight a boss from Ikachan, it looks as though you're traveling through an infinite canal. If you use a map editor, though, you can see that the action only really happens in a small 23×16 rectangle, with a scrolling background. However, Pixel felt like using some more space.

To the left of the main rectangle is a pixel-art Ikachan made of iron blocks, and to the right is some text written in iron blocks as well, that reads "→ No damage." in both the original Japanese version and the English patch. In-game, you can see this using the map. As such, it is most likely intended to be a hint for how to meet Ikachan and receive the Alien Badge (defeat the boss without taking damage), given only to players clever enough to attempt to view the map in this particular area.

Quick Tidbits

  • There is an unused duplicate of the door to the second jail in the Plantation, under the first block of the tunnel that leads to the hideout.
  • When Sue's mother tells you that the Mimigas on the Plantation can't talk to humans, she asks "Are you with me so far?" After that, the current script ends and another starts that continues the conversation. This split indicates that there might have been a Yes/No prompt.
  • The filename for the music that plays during the fight with the Core is ironH.org, suggesting the song was originally meant for the Ironhead boss fight, instead. In OrgView versions 2 to 4, the song was indeed a remix of the Ironhead boss theme in Ikachan, but in later versions the song was remixed beyond recognition, with only the intro retaining some semblance of the original song.
  • In a zip file of several old OrgView versions, Balrog's Theme from OrgV11-OrgV13 is named "銀助(仮称)のテーマ" (which translates to "Ginsuke (Temporary Name)'s Theme"), meaning Balrog's name was likely Ginsuke for a short period of development. The internal name for Balrog's Theme in the final is still ginsuke.org.
  • There's a bug when rendering dialogue portraits in-game, causing the top three rows of pixels to be cut off. This is due to the portrait being rendered with the same clipping rectangle that is used by the text.
  • In the NPC attributes table (npc.tbl), the Gravekeeper is assigned to have a contact damage value of 2. However, in the final game, his damage is hardcoded to 0 when he spawns, only changing to 10 when he swings his knife.
Hmmm...
To do:
Add a demonstration image?
  • In the Sand Zone tileset, there are two blank spaces next to the spike tiles. Interestingly, when looking at the tile attributes, these blank tiles are also assigned to be spikes. It's likely that these were originally sideways-facing spikes, since the Sand Zone only has rightside-up and upside-down spikes in the final game, and given these blank tiles' close proximity to said spikes.