Tag: lessons-learned

  • The grammar of what’s possible

    There’s a Yu-Gi-Oh game on PS1 where you can fuse two cards together. The result isn’t random. There are rules. But you don’t know the rules yet — you just know that two inputs produce a third thing that neither input was, and that the third thing surprises you even when it shouldn’t.

    That’s the hook. Not the surprise alone. The realization underneath the surprise that the system has depth. That there’s a grammar to what’s possible, and you can learn it.

    I’ve been building toward that feeling ever since.

    Jade Cocoon does the same thing with monsters — merge two creatures, watch the result carry both parents in its design. Dragon Quest Monsters runs on fusion too. Yu-Gi-Oh Forbidden Memories taught me that combination-as-discovery is its own mechanic, separate from any theme it wears. Everything Is Crab is the roguelike version: you absorb what you fight, you become it, you discover what you’re becoming one encounter at a time. No Man’s Sky showed me that procedural generation has finally caught up to what those PS1 games were reaching toward — creatures that feel like they emerged from a system rather than a designer’s hand.

    The mechanic isn’t genetics. Genetics is just the implementation I keep reaching for. What I’m actually trying to build is a machine that produces controlled emergence — outcomes that surprise you within a system deep enough to eventually master.

    Pure RNG is a slot machine. You can’t get better at it. Pure determinism is a calculator. You can solve it and put it down. The games I keep returning to live between those poles: consistent enough to reward learning, deep enough to keep producing novelty.

    TurboShells was an attempt at this. Turtles whose bodies expressed their genomes at render time — shell radius, leg length, color emerging from a sequence. The faster ones bred. Over generations you watched the population drift. The system had rules. The outcomes still surprised you.

    SlimeGarden chose basic shapes deliberately. If the creature is simple enough, even small variation reads as meaningful. The shape IS the information. You can see the grammar in the design.

    The version I haven’t built yet is closer to Jade Cocoon meets Dragon Quest Monsters — creatures with traceable visual lineage, combination mechanics with real strategic depth, the initial surprise and the eventual mastery running in parallel. Everything Is Crab proves the roguelike format can carry it. NMS proves the procedural layer is tractable.

    I’m still building toward it. Every system I’ve made in this space has been a step closer to understanding the grammar well enough to write it myself.

    The hook was a PS1 card game in the late nineties. The project is still open.

  • Zero Wasn’t Zero

    My design reviewer had been poking the same hole in my strategy for weeks. Small gaps, pointed out one at a time — the analytics weren’t catching traffic well, the numbers I was quoting didn’t have the resolution to support the decisions I was hanging on them. So one night I finally sat down to actually read my Google Analytics dashboard, instead of glancing at it and feeling vaguely behind. The goal was real details. Another step in the right direction.

    Eight active users for the week. Four of them from Council Bluffs, Iowa.

    I don’t know anyone in Council Bluffs, Iowa. Google does, though — it’s the site of one of their largest data centers. Half of my “users” were crawlers pinging my site and getting logged as people. So my real week was three, maybe four humans. Organic search: zero. Qualified leads: zero. Converted leads: zero.

    I run a consulting intake form on that site. Multi-step wizard, dialer platforms, pain points, contact info — the funnel’s entire bottom end. And here’s the part I have to be honest about: when the work to wire it into analytics finally started, and the agent running the directive stopped cold to report that the intake page had never loaded the analytics tag at all — not one recorded page view, ever — I wasn’t shocked. I’d been told it probably wasn’t tied in. I half knew. The stop report wasn’t a discovery. It was confirmation of a suspicion I’d been carrying around for weeks instead of spending ten minutes to check.

    That’s the actual lesson, and it’s less flattering than “I found a bug.” Some projects get real developmental commitment. My website isn’t one of them — it gets passing attention, and known holes survive a remarkably long time in projects that only get passing attention. I prefer a clean repo the way everyone prefers a clean kitchen, and like everyone, I have a room I just don’t go in.

    What surprised me wasn’t the hole. It was noticing what the zeros had been doing to me anyway. I *knew* the instrumentation was suspect — and the row of zeros under “leads” still read like a verdict every single time I glanced at it. A gauge you know is broken still lies to you, and you still flinch. “Nobody wants this” and “you never measured it” produce the exact same dashboard, and even when you suspect it’s the second one, your gut reads the first.

    The fix took one evening once it stopped being deferred: tag on the page, a `generate_lead` event on successful submission, fallback paths so analytics can never break the form itself. The funnel now reports both of its ends — views and submissions — so the two failure modes finally look different. Views without submissions means the page doesn’t convert. No views means nothing sends anyone there. Opposite problems, opposite fixes, indistinguishable until this week.

    Instrument the conversion point before you judge the funnel. And if you suspect a gauge is broken — confirm it today, because you’re going to keep reading it either way.

    Data starts now. The next zero on that dashboard will be a real one. Weirdly, I’m looking forward to it.

  • A side effect of a side effect

    In 2016 I uploaded a review of Hybrid Animals to YouTube. It got 353 views. Then I stopped.

    I was in phone sales. Still a bachelor. I liked the idea of being a content creator — it looks cool, it sounds cool — but I knew pretty quickly it wasn’t really for me. Making videos was work, and the work wasn’t interesting enough to justify itself. I wanted to play games. I didn’t want to make content about playing games.

    So I stopped.

    Ten years later I have a YouTube channel publishing daily Shorts across six different games. I didn’t change my mind about content creation. I changed what content creation costs me.

    ContentPipeline records the session, transcribes it with Whisper, identifies the moments worth keeping, generates the captions, assembles the video, and schedules the upload. I play games. The pipeline does the rest. The channel exists because I removed the friction, not because I developed a passion for it.

    The clips are a side effect of playing games. The channel is a side effect of building a pipeline. Any revenue from it would be a side effect of a side effect.

    That framing used to feel like an admission of something. Like I wasn’t taking it seriously enough. Now it feels like the honest version of what most creators won’t say.

    Most YouTube advice is about optimizing for the channel. Titles, thumbnails, posting frequency, audience retention. I don’t think about any of that. I think about whether the pipeline is producing good clips and whether the games are interesting. The channel takes care of itself.

    The goal I’d actually care about is streaming — not because of the audience but because of the engineering challenge. Building a live pipeline, managing the session, making it work technically. That’s the interesting problem. The viewers would be incidental.

    I’m not a content creator. I’m someone who plays games and built infrastructure. The YouTube channel is what the infrastructure produces.

    There’s a version of this where the channel grows, the clips find an audience, and the side effect generates real income alongside the consulting work, the games, and everything else running in parallel. That would be a quiet bonus. A small thread alongside many others.

    I’d rather be the developer who has a YouTube channel than the YouTuber who also codes.

    The pipeline makes that possible. I just play games.

  • Teaching Pong to Play Itself: My First Neural Network Experiment

    Teaching Pong to Play Itself: My First Neural Network Experiment

    Pong is the right choice for a first experiment because it has almost no variables. Two paddles. One ball. If you can’t teach an AI to play Pong, you can’t teach an AI anything.

    I used NEAT — NeuroEvolution of Augmenting Topologies. It doesn’t just adjust weights on a fixed network structure. It evolves the topology itself, starting minimal and adding complexity only when it helps. The training runs headless at 500x real-time speed; a separate visual mode exists purely to verify that what trained actually works. Generation 0: random paddle movement, 0% win rate. Generation 50: 98% win rate, predictive tracking.

    The difference between reacting and anticipating is memory. Standard feedforward networks see the current frame. Recurrent Neural Networks carry memory of previous states — ball velocity, trajectory history. That’s what gives the Gen 50 agent its characteristic quality: it moves to where the ball will be, not where it is. The RNN is what upgrades NEAT from “learns to respond” to “learns to predict.”


    The first training approach was pure ELO. Score points, survive, reproduce. The population converged fast — too fast. By generation 20, every agent played the same way. Safe returns, center positioning. They’d found a local maximum and stopped. No one was discovering anything.

    Novelty search fixed it. Instead of rewarding only performance, you reward uniqueness — points for behaviors the population hasn’t tried. The diversity pressure kept agents exploring. Agents with strange positioning, unusual angles, aggressive strategies started appearing — and some of them turned out to be genuinely superior. The “wrong” strategy was actually better. Pure optimization would never have found it.

    Any system without diversity pressure converges on the same answer. It finds the local maximum and calls it done. That lesson applies well beyond neural networks.


    What didn’t work: high mutation rates to accelerate training. The population collapsed — agents changed faster than they could build on what worked. Every generation erased what the previous one had learned. Slowing it down made the evolution meaningful. Some processes can’t be accelerated without destroying the thing that makes them work.


    This was the first project. Everything since has the same shape: variation, selection, emergence you didn’t design. TurboShells encoded the same loop into turtle genetics. rpgCore formalized it into a composable system. VoidDrift runs it as a drone dispatch loop.

    The Pong agent that discovered a non-obvious return angle at generation 47 is the ancestor of all of it. I just didn’t know that yet.