I started this as a toy. Type words, get a picture. It turned into a text-to-scene engine, a retrieval system, and a small pile of things that kept breaking.
The one-line pitch
Texograph is simple to describe and annoying to build.
You type, and a pencil-sketch scene appears in real time. No diffusion model. No GPU. No waiting. Every pixel comes from a real human sketch that gets retrieved, arranged, and rendered by rules.
Type flork:facepalm:rage "monday" / flork:celebrate:love "friday" and you get a two-panel comic.
That is the entire point.
The thing I got wrong first
My first instinct was the obvious one: text to meme means image generation.
It does not.
A generative model gives you one image and you take what you get. What I actually wanted was something you could think with. Something where the words map to a little world you can rearrange. Make the dragon bigger. Move the cat behind the castle. Add a moon.
So the real question became:
What is the minimum structure for an arrangement of symbols to still read as a coherent scene?
That reframing changed everything. Texograph is part search engine, part visual reasoning engine, wearing a doodle costume.
The architecture
The runtime is boring on purpose:
text -> retrieval -> scene graph -> layout -> render
Most of the intelligence is precomputed offline. At runtime it is mostly lookups.
Words become vectors. Vectors become concepts. Concepts become a scene graph with spatial relations. The graph becomes a layout. The layout renders retrieved strokes with a pencil texture.
That is why the matching step stays fast, and why the same phrase always produces the same drawing.
Deterministic rendering matters more than people think. It makes share links, previews, and repeatable puzzles possible. The phrase is the state.
The characters
The dataset was the hard part.
Crowd-sourced doodles are noisy and inconsistent. Great for recognition, terrible for composition. So I stopped trying to retrieve memes and started constructing them.
Every character is generated from parametric code, with each stroke labelled at creation. A jaw knows it is a jaw. A leg knows it is a leg.

Then I built a proper character kit: one skeleton, three skins, multiple poses, and a bunch of expressions. stickman:celebrate:love resolves to exactly that drawing.

The part I am most proud of
The blend engine is the nicest piece.
Type cat-dragon and it does not just draw both. It fuses them. And because there is rarely one correct answer, it offers a few valid arrangements you can cycle through with the arrow keys.
I think of it as a kind of quantum autocomplete. The drawing stays in superposition until you pick one.

Under the hood it is a small operator table: substitute, tuck, graft, overlay. The rule that kept saving me was simple:
no floating stubs
After any blend, every limb has to actually connect to the new silhouette. If it does not, the candidate gets thrown away.
That one geometric rule kills most of the nonsense.
Teaching it what a head is
Geometry alone gets you plausible shapes. It does not get you meaning.
A hat on a cat should sit on the cat's head, not float through its face. So I added a world-knowledge layer: around thirty classes with part schemas, and roughly 11,000 concepts assigned to them in bulk using the embeddings I already had.
That is the trick. You do not hand-label 11,000 words. You label 30 classes and let distributional semantics do the rest.
Once symbols know their own anatomy, operators stop being guesses and start being role mappings.

Everything that broke
The polished version would be dishonest, so here is the messy one.
- The sync wars. My project folder lived in OneDrive, and OneDrive would occasionally hand the server a half-written JavaScript file. Truncated mid-function. I lost real hours to that.
- The 14-token bug. Adding a long speech bubble once made the next character vanish. The whole quote was being sent to the matcher, which only reads the first 14 words. The speech balloon should never have been treated like a concept.
- The mush phase. The first blend engine produced beautiful garbage. Two torsos fused into one blob. The no-floating-stubs rule fixed most of that.
- The security hole. My admin analytics page was "protected" by a proxy assumption that was not actually authentication. Behind a reverse proxy, everything looked local. It was not.
- The analytics reality check. For a while I thought the project had real traffic. Then I noticed the spike days were the days I was building features. I was the traffic.
Where it is now
It is live.
You can find it at texograph.com.
You can type a scene and watch it draw, blend two things, stage a multi-panel comic with a filmstrip, drag characters and speech bubbles into place, and export the result as an animation that draws itself in.
The moat was never the sketches. Anyone can download sketches.
The moat is this:
given language, infer a plausible little world, then compose visual primitives so they read as coherent
That is the hard part. That is the fun part.
If you want to break it, that is kind of the point.