Skip to content

Dot Hop: Plain-Text Levels with a Godot Import Plugin

This is a draft/outline! Plz don’t read yet. Coming soon!

Heya! Today I’m writing up one of my favorite recent additions to Dot Hop: a plain-text level format (.puzz) backed by a custom Godot import plugin.


.puzz files are plain text — one line per row of the puzzle grid. Each character maps to a cell type:

CharacterMeaning
.Empty cell
oDot (collectable)
xPlayer start
tTarget / goal

A minimal puzzle looks like this:

.......
.xooot.
.......

Here’s what a real .puzz file looks like in a text editor:

The format is intentionally readable — you can author or tweak puzzles by hand, and diffing changes in version control is trivial.


Godot’s EditorImportPlugin system lets you register a custom file extension and teach the editor how to import it. Once registered, any .puzz file in the project is automatically imported whenever it changes — exactly like a PNG or WAV.

After import, the result appears in Godot’s FileSystem dock as a proper PuzzleSetData resource — inspectable, preloadable, and type-safe:


The import plugin produces a PuzzleSetData resource. A few supporting scripts handle the rest:

One of the nicest wins here was deleting the GameDef class entirely. It had been an awkward in-betweener — a bag of parsed data that nothing else quite knew how to treat. Once .puzz files became proper Godot resources, preload() and load() just work, and GameDef had nothing left to do.


With PuzzleSetData as a real resource, the puzzle browser tool came together quickly. Here’s a happy accident from that work — what happens when you forget to remove the old puzzle node before adding a new one:


Stretch Goal: A Minimal Reproducible Example

Section titled “Stretch Goal: A Minimal Reproducible Example”

A standalone Godot project demonstrating just the import plugin would be a clean way to share this pattern. For now, the full implementation lives in the Dot Hop repo — it’s open source and the relevant addon should be easy to find:


Thanks for reading! If you’re building something with Godot and want to talk plain-text level formats or import plugins, find me online — happy to chat.

Happy trails, game devs!