Skip to content

Notes · 4

Today I Learned

One problem and the fix, a few lines each. Things I ran into while building games, web products and AI tools, written down so the next person searching for them finds an answer.

How do I build an ECS where mechanics can be swapped while the game runs?

Keep all state in components as plain data and all code in modules that own no state. A snapshot is then just the stores, and swapping a mechanic is just swapping the systems that read them.

ts
world.add(e, 'Napping', {}) // state: plain data, saved in every snapshot

export default defineModule({
  id: 'siesta', version: '1.1.0',
  components: { Napping: { version: 2, migrate: { 1: old => ({ ...old, since: 0 }) } } },
  install(ctx) { /* one-time world changes */ },
  setup(ctx) { ctx.extend(ACTIONS_REGISTRY, 'siesta_nap', nap) }, // runs on every attach: never writes the world
  systems: [{ id: 'wake', every: 10, run(ctx) { /* query, then mutate */ } }],
})

In Glimtide every mechanic, even hunger, is a module installed into the live world between two ticks. The rules that make it work: no state in closures (an upgrade drops it), randomness only from the world's seeded RNG and time only from ticks, or a trial run on a snapshot can't be compared. More in the Glimtide write-up and the ECS FAQ.

How to make a narrated explainer video for a side project from one prompt

My tool pages explained everything in text, and I wasn't going to record and edit a video for each of them by hand.

I used Animator, a Python CLI that turns one prompt into a hand-drawn whiteboard video with narration:

bash
pip install -r requirements.txt   # plus FFmpeg on PATH and GEMINI_API_KEY in .env
python -m animator --prompt "How tabs-broadcast lets browser tabs talk to each other" --scenes 4 -o tabs_broadcast.mp4

Gemini writes the storyboard, draws each scene, voices it and finds every icon in the frame. A local CPU engine then draws each icon while its sentence is being spoken. A 4–5 scene video takes about a minute.

That's how I got the videos on tabs-broadcast, XPLOIT Game UI, Steam AI Disclosure and Contract Red-Flag Scanner: one command each, uploaded to YouTube as is.

If a caption shows up before it's spoken, rerun with --save-storyboard and fix the beat in scene_XX.regions.json. The art style and the script tone are plain-text prompts in animator/prompts/, so you can change them without touching code.

How should I organize a Claude project so it stops forgetting context?

A Claude project works best when each kind of context has exactly one home. Otherwise you end up explaining the same thing in every chat.

How I split it for my site:

  • One project per long-running goal ("build my personal site"), not one per task.
  • Project instructions hold what never changes. Keep them short:
text
Owner: Ravy. Reply in Russian; everything on the site is in English.
Code: github.com/Rovniy/ravy.pro. Edit my local checkout, never commit unless asked.
Never publish anything from my private notes.
Rules about the code itself live in the repo's CLAUDE.md, not here.
One chat or thread per task. "Add a press kit" and "fix the OG images" never share a chat, so neither drags the other's history along. A finished task gets closed.
  • Decisions go into memory or a file in the project the moment they're made ("the music is presented openly as AI work"). A new chat reads them instead of asking me again.
  • Code rules live in the repo, next to the code they protect, so every tool that opens the repo sees them. -The test: open a fresh chat, ask for the next feature, and see whether it has to ask you anything it should already know.

Docs: What are projects?

Asking Claude to "add feature X" gets you X.

The loop I use on ravy.pro:

  1. Keep a CLAUDE.md in the repo: the architecture, plus the rules that are easy to break (where data lives, what must stay prerendered, which analytics events exist).
  2. Ask for ideas against a goal, not for a feature:
text
Read CLAUDE.md and the site. My goal: companies hiring a CTO should find me.
Propose 10 features ranked by impact vs. effort.
For each: what it is, why it helps, which files it touches.
  1. Pick one and let it build the whole thing: code, tests, lint, a production build, then screenshots to check the layout.

This feed is item 10 on that list. The ⌘K search and the press kits for my games came from the same list.

What made it work: every rule goes into CLAUDE.md the day it bites. Claude reads that file at the start of every session, so the same mistake rarely comes back.

Docs: How Claude remembers your project

Newsletter

Occasional notes on engineering, game tech, and new tools — no spam, unsubscribe anytime.

Ravy

Engineering manager, founder, and software developer building web platforms, game systems, real-time services, and automation tools. 15 years of shipped work — currently at Gaijin.net.

Get in Touch

Building an MVP, shipping a game feature, or automating a team workflow? Open source or paid — let's talk.

Contact Me
© 2020-2026 XPLOIT FZE. All trademarks, names and logos belong to their respective copyright holders.