| ▲ | DonHopkins 6 hours ago | |
I've been porting Micropolis (SimCity Classic) to WASM / WebGPU / Svelte 5. Emscripten + Embind compile the C++ engine and glue it to TypeScript/Svelte/Runes/Reactivity; TypeScript owns UI, rendering, and callback handlers. I agree with the article's main lessons: wasm32 pointer size, don't serialize structs with pointers, debug native 32-bit when you can, WebGL/WebGPU is stricter than desktop GL, Emscripten export flags still bite. I hit some of the same categories; the parts that were actually tricky for Micropolis are below. Svelte 5 runes ($state, $derived, etc.) work in plain .ts modules, not just .svelte templates. That matters because the WASM bridge is a reactive module the HUD, command bus, and Vitest all import -- not a component-only trick. The file has to be MicropolisReactive.svelte.ts so runes compile under the same Vite/SvelteKit pipeline as the app; plain .ts breaks in Node with "$state is not defined". Embind API surface -- what to expose and what to leave out: https://github.com/SimHacker/MicropolisCore/blob/main/packag...
The comments in that file go on to describe the strategy for wrapping: Core Simulation Logic, Memory and Performance Considerations, Direct Memory Access, User Interface and Rendering, Callbacks and Interactivity, and Optimizations.The engine callback virtual interface bridged C++ to JS via JSCallback: https://github.com/SimHacker/MicropolisCore/blob/main/packag... In the old NeWS/Hyperlook, TCL/Tk/X11, SWIG/Python/PyGTK, and SWIG/Python/TurboGears/AMF/Flash versions, this callback interface used to be a stringly typed general purpose event callback interface, which I tightened up into a strict C++ interface and corresponding typescript interface, so embind could help me integrate it safely and cleanly with TypeScript and Svelte Runes. TypeScript handlers that update rune-backed state (sendMessage, didTool, budget hooks, etc.): https://github.com/SimHacker/MicropolisCore/blob/main/apps/m... Simulator attach/detach, singleton engine load, wiring JSCallback into Micropolis: https://github.com/SimHacker/MicropolisCore/blob/main/apps/m... The pattern: C++ fires callbacks with enough context for the UI; TS updates $state; components read micropolisReactive (peek / poke / memory / getSnapshot) instead of calling Embind or touching HEAP* directly. That is where the rubber hits the road for interactivity. Heap access is its own footgun. Emscripten may expose Module.wasmMemory, HEAPU16, or neither until init; some getters throw if you read too early. Centralized helper: https://github.com/SimHacker/MicropolisCore/blob/main/apps/m... Bridge design, Vitest against real WASM, teardown order with Embind lifetimes: https://github.com/SimHacker/MicropolisCore/blob/main/docume... Map rendering: WebGPU tile renderer with canvas fallback (legacy WebGL frozen, now reimplementing in WebGPU). The renderer reads 16 bit flags + tile indices from direct simulator memory views into WASM linear memory (mapData / mopData), not per-frame Embind copies. https://github.com/SimHacker/MicropolisCore/blob/main/packag... https://github.com/SimHacker/MicropolisCore/blob/main/docume... City saves are a defined binary format (.cty), not fwrite of engine structs. Live map data is views into WASM linear memory (mapData / mopData), not embedded native pointers -- same idea as the article's side-table fix, but that is how this codebase is already structured. Why I find this stack interesting: original SimCity engine lineage, narrow Embind surface on purpose, reactive TS facade so automation and UI share one sim without reviving the old Python/SWIG/pyGTK path. Sprites (trains, choppers, generic orange monsters wrecking chaos and havoc -- definitely not Godzilla [TM], but possibly Trump adjacent) simulate in C++; compositing them in the WebGPU path is still work in progress. The WebGPU renderer is being built as a general stack with pluggable layers, including Sims content rendering (characters, animations, terrain, objects, walls, floors, ui effects, etc). Character animation demo: VitaMoo code: https://github.com/SimHacker/MicropolisCore/tree/main/packag... Unified WebGPU Renderer: https://github.com/SimHacker/MicropolisCore/blob/main/docume... Render Core Package: https://github.com/SimHacker/MicropolisCore/blob/main/docume... Renderer Plugin Roadmap: https://github.com/SimHacker/MicropolisCore/blob/main/docume... Live Micropolis tile renderer and simulator demo (no other ui yet, work in progress): Demo of the simulator, cellular automata, and tile engine to Jerry Martin's music: https://www.youtube.com/watch?v=319i7slXcbI Repo: | ||