Loading works…
GDD Editor
Writing a game design document in raw HTML meant digging through tags to fix a single sentence. So I built a tool that edits the finished page itself. The messy HTML a browser produces never reaches the file. On every save a Python engine re-renders the document to a fixed set of rules.
Screenshots
Why I built it
I write game design documents as HTML slide decks. They look right, but fixing one sentence meant hunting through tags, and checking the result meant opening a browser separately.
Moving to a word processor breaks the document's format. So I built an editor for that one kind of document.
The one rule that matters
Let a browser edit a document through contenteditable and it will quietly insert <div> wrappers and inline styles. Save that as-is and the document is rubble within a few rounds.
So the HTML the browser produces is never saved. A Python engine re-reads the edit as blocks and rewrites the document using only an approved set of tags and classes. What survives inline is bold, italic, highlight, line break, link and a TODO marker. Nothing else.
Text size and colour are chosen from fixed steps, not px values or a colour picker. Nothing disappears into the background in dark mode, and one stylesheet edit changes the whole document.
Keeping what the rules cannot express
Hand-drawn SVG diagrams and screen mockups cannot be expressed as blocks. For those the engine gives up on parsing and locks the source verbatim. Only the text inside can be clicked and edited; not one character of the tags or coordinates changes.
That lets structured prose and hand-drawn artwork live in the same file without one save flattening the other.
Free placement that does not break the flow
A design document is read top to bottom. Switching a whole slide into free-placement mode throws that away.
So instead a single block is detached from the flow. It freezes exactly where it was on screen, and its position is written as a percentage horizontally and pixels vertically. The ratio survives a different window width, and the position does not drift when the text above it grows or shrinks.
Losslessness kept by a test
The real danger in a tool that rewrites documents is that merely opening and closing one changes it a little.
So there is a check that reads every chapter, rewrites it with no edits applied, and compares byte for byte against the original. If that check does not pass, nothing gets committed. In practice, saving without editing leaves the files untouched, and the change never shows up in version history at all.
Make-up
Python standard library and vanilla JavaScript only. There is nothing to install.
- engine.py (~1,800 lines): reads HTML into blocks and rewrites it to the rules. Works with no UI at all.
- server.py (~590 lines): a
127.0.0.1-only local server. It demands a one-time key and shuts itself down when the editor goes quiet. - web/ (~2,900 lines): the editing surface, the toolbar and a self-test.
Saving chains into table-of-contents generation, manifest sync and an integrity check, with the results logged at the bottom of the screen.
Current state
I use it for my own documents. The game design document and the editor's own design document are both edited with it.
It is not a shipped product. It is a local tool I use alone: no concurrent editing, no accounts. The only browser engine it has been checked against is Chromium.


