Spelunky is © 2008, 2009 Derek Yu and Mossmouth, LLC, and is used under the [Spelunky User License v1.1b](https://spelunky.ai/LICENSE.txt). spelunky.ai is an unofficial fan project, not affiliated with or endorsed by Mossmouth. The game and its assets may not be sold.

Music by George Buzinkai and Jonathan Perry; sound effects made in SFXR. From Spelunky Classic 1.1, © 2008, 2009 Derek Yu and Mossmouth, LLC.

# Lost sign messages

From the spelunky.ai wiki: <https://spelunky.ai/wiki/lost-sign-messages>. Verified against the spelunky.ai port [v0.1.13](https://github.com/851-labs/spelunky/releases/tag/v0.1.13) on 28 October 2026.

Lost sign messages is a quirk of Spelunky Classic in which a custom level saved with no entrance and no exit loses its signs' messages.

| Quirk     |                                                                                                                                                                                                                        |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Status    | GML + Oracle                                                                                                                                                                                                           |
| Where     | [`objects/oLevelEditor/keypress_Y.gml:48-61`](https://spelunky.ai/wiki/source/objects/oLevelEditor/keypress_Y#L48-L61)                                                                                                 |
| Pinned by | `fidelity/replays/editor-sign-no-exit.txt`                                                                                                                                                                             |
| Row       | [docs/quirks.md §1, Bugs and leftovers in the 1.1 source](https://github.com/851-labs/spelunky/blob/main/docs/quirks.md#1-bugs-and-leftovers-in-the-11-source): “A saved level without exits loses its sign messages.” |

A sign in a custom level shows a message when the player walks past it, set in the [level editor](https://spelunky.ai/wiki/level-editor)
with E. The editor saves each level's exit labels and sign messages after its tiles. A level with no entrance and no
exit has no labels to save, and then the file comes out in a shape the game reads differently: opened again, in
the editor or from the menu, its signs have no message.

## What happens

A level with one sign, which says HELLO, and neither an entrance nor an exit opens in the editor, which draws the
message at the sign. The player saves it, past the warnings that it has no entrance and no exit, and opens it
again: the sign is blank[^1].

**Clip: A level without exits loses its sign's message.** A level with a sign that says HELLO, and no entrance or exit, opens in the level editor. The player saves it and opens it again: the sign has no message. ([video](https://spelunky.ai/wiki/media/clips/quirks/sign-message-lost/clip.mp4))

## Why

Saving, the editor writes how many exit labels there are, the labels, how many signs there are, and their messages.
It only ends the labels' count with a line end if there are labels:

```gml objects/oLevelEditor/keypress_Y.gml:48-61
    file_text_write_string(file, string(exitNamesID));
    if (exitNamesID > 0) file_text_writeln(file);
    for (i = 0; i < exitNamesID; i += 1)
    {
        file_text_write_string(file, exitNames[i]);
        if (i < exitNamesID) file_text_writeln(file);
    }
    file_text_write_string(file, string(signNamesID));
    if (signNamesID > 0) file_text_writeln(file);
    for (i = 0; i < signNamesID; i += 1)
    {
        file_text_write_string(file, signNames[i]);
        if (i < signNamesID-1) file_text_writeln(file);
    }
```

[`objects/oLevelEditor/keypress_Y.gml:48-61`](https://spelunky.ai/wiki/source/objects/oLevelEditor/keypress_Y#L48-L61), from `spelunky.gmk`, Spelunky Classic 1.1's source, © 2008, 2009 Derek Yu and Mossmouth, LLC ([Spelunky User License v1.1b](https://spelunky.ai/LICENSE.txt)).

Entrances and exits both count as labels. With neither, the sign count goes on the same line as the label count:
0 labels and 1 sign come out as `01`, and 3 signs as `03`. Reading the level back, the editor and the game read
that line as that many labels, take the signs' messages for them, and find no sign count after them, so no sign
gets a message[^2][^3][^4]. A sign without one is blank[^5]. The test button
saves the level to play it the same way, with the same line[^6]. With an
entrance or an exit, every label is followed by a line end, as the reader expects.

## Reproducing it

Put a sign in a level with no entrance and no exit, give it a message, and save the level; then open it again or
play it from the menu. It only happens to a level saved with neither, which can't be finished, so mostly to one
still being built. In the clip's replay the sign says HELLO when the level opens on frame 226; the level is saved on
250, and when it opens again on 286, the sign's message is empty[^7]. In another, the saved level is played from the
menu, and its sign has no message there either[^8].

## In the port

The spelunky.ai port reproduces it exactly: it's in docs/quirks.md's list of the 1.1 source's bugs[^4], and the oracle's fingerprints of the two replays pin the signs' messages. The files the
replays save match the original's byte for byte. No option turns it off.

## FAQ

### Why did my signs lose their messages in the Spelunky Classic level editor?

The level was saved with no entrance and no exit. The editor then writes the file so that, read back, the signs' messages are taken for exits' labels and the signs get none.

### How do you keep a custom level's sign messages?

Give the level an entrance or an exit before saving it. With either, the file is written the way it's read, and every sign keeps its message. A level needs both to be played properly anyway.

### Where do the lost messages go?

They're read as the exits' labels. With no exit or entrance to take them, they're dropped, and the next save writes the signs with no message.

## See also

- **Related:** [Level editor](https://spelunky.ai/wiki/level-editor)

## References

[^1]: Clip quirks/sign-message-lost

[^2]: [`objects/oLevelEditor/keypress_anykey.gml:32-61`](https://spelunky.ai/wiki/source/objects/oLevelEditor/keypress_anykey#L32-L61)

[^3]: [`scripts/scrLoadLevel.gml:61-90`](https://spelunky.ai/wiki/source/scripts/scrLoadLevel#L61-L90)

[^4]: Quirk 1 (docs/quirks.md)

[^5]: [`objects/oMsgSign/create.gml:3-7`](https://spelunky.ai/wiki/source/objects/oMsgSign/create#L3-L7)

[^6]: [`scripts/scrTestLevel.gml:69-70`](https://spelunky.ai/wiki/source/scripts/scrTestLevel#L69-L70)

[^7]: Replay `fidelity/replays/editor-sign-no-exit-reopen.txt`

[^8]: Replay `fidelity/replays/editor-sign-no-exit.txt`

### Source code

- [`objects/oLevelEditor/keypress_Y.gml`](https://spelunky.ai/wiki/source/objects/oLevelEditor/keypress_Y)
- [`objects/oLevelEditor/keypress_anykey.gml`](https://spelunky.ai/wiki/source/objects/oLevelEditor/keypress_anykey)
- [`scripts/scrTestLevel.gml`](https://spelunky.ai/wiki/source/scripts/scrTestLevel)
- [`scripts/scrLoadLevel.gml`](https://spelunky.ai/wiki/source/scripts/scrLoadLevel)
- [`objects/oMsgSign/create.gml`](https://spelunky.ai/wiki/source/objects/oMsgSign/create)
