Day 2

Choosing the tech stack


Once the decision was made to bring Buildom back, the very first architectural question came up: what tech stack do you put around it today?

That it had to be a canvas game was clear from the start. A 2D pixel world needs direct control over rendering, frames, and sprite drawing. But a game today is rarely just a raw canvas floating in a void.

I wanted Buildom to be a solid, reliable web application. That meant having all the strengths of a modern single-page application: instant state updates, clean modular UI, fluid navigation, and developer tooling that does not get in the way.

I looked at different setups, from standalone game engine frameworks to classic web stacks. In the end, I chose Next.js and React for the project.

Why Next.js when the game itself runs on a canvas?

Because the canvas only handles the actual rendering loop. Everything around it: menus, inventory overlays, settings, account tools, and editor panels, benefits massively from a modern component-based SPA architecture. React makes building complex UI overlays straightforward, while Next.js gives me fast hot reloading, a clean project structure, and great performance right out of the box.

Smart storage: local vs. session

Building a game in the browser also means thinking through persistence early. What belongs in long-term storage, and what should reset with each session?

I separated the two clearly:

  • Local storage: Reserved for permanent game saves and world state. When a player builds a base or digs a tunnel, that world data is written to localStorage so progress stays intact across visits.
  • Session storage: Perfect for transient UI states. Open sidebars, selected hotbar slots, dev overlays, and zoom levels are kept in sessionStorage. They stay remembered across quick page reloads, but start fresh when you open a new tab or restart the browser.

This distinction keeps the game fast, prevents state clutter, and avoids hydration mismatches between server and client.

Multilingual from day one

Another requirement from the start was proper internationalization (i18n). Retro pixel games have a global audience, and retrofitting translations into a mature codebase later is always painful.

With Next.js and next-intl, localized routing and message catalogs (like German and English) work out of the box. UI labels, tooltips, dialogs, and notifications all run through a central translation registry. Switching languages is instantaneous, without breaking the game canvas or resetting the active state.

Ready for the backend

There is another big reason for Next.js: backend flexibility. Even if I do not need custom server endpoints right away, I know for sure that API routes, save state sync, and backend integrations will come down the road. Having API routes built directly into the same framework without having to spin up and maintain a separate backend service keeps things lean and ready for what comes next.

With the application shell, storage layers, and localization locked in, the foundation is ready. I’m learning a lot just from comparing frameworks and thinking through what this game actually needs. Next step: getting the core canvas rendering loop up and running with the first pixel grid.