Download Game! Currently 124 players and visitors. Last logged in:TigerlilyHopeahapsiSlimyByleth

Blitzer's Blog >> 72135

Back to blogs index
Posted: 06 Sep 2026 10:37 [ permalink ]
This is a fantastic initiative. Looking through Realm3DEd.txt, I can
absolutely see how this works and why you consider it strong for its time.
Building a realtime, meshable, and automatically interpolating 3D grid in
20102015 was no small feat, especially handling the complexities of dynamic
chunking and custom smoothing algorithms.
Here is my analysis of your C++ architecture and a blueprint for how we can
bring it back to life natively in the browser using WebGL.
1. Engine Analysis: How Realm3DEd Works
Based on the bundled headers, you built a highly structured, OOP-driven
voxel/mesh hybrid engine. You weren't just rendering blocks; you were
calculating dynamic, smooth surfaces based on grid points.
 * The Grid and Chunking: The world is managed by CCubeMap. You implemented a
chunking system where data is batched into buffers (bufferMaxSizeX = 8, etc.).
This keeps memory segmented and rendering efficient, as chunks are only
rebuilt when modified.
 * Data Representation: CCubeData represents individual cells, tracking if
they are filled and holding surface data. The actual vertices are driven by
CCubePoint, which is where the magic happens: points aren't just static
coordinates; they have types like ECPT_Smooth and ECPT_Slope. This indicates
an algorithm (similar to Marching Cubes or Dual Contouring) that interpolates
the mesh for sloped and smooth terrain.
 * Mesh Generation: CCubeBuffer takes the raw cube and point data and compiles
it into scene::SMeshBuffer for Irrlicht. It dynamically calculates normals
(both hard and soft) and UV coordinates from a custom CTextureAtlas.
 * Interactive Tooling: CCubeSelector isn't just a basic raycaster; it
maintains its own mesh buffers to draw wireframes or highlights depending on
the selection mode (Cubes, Sides, Edges, or Points).
 * Look-up Tables (LUTs): You used hardcoded structs like SSideLookupTable and
SSPLT to heavily optimize spatial queries and point generation without
expensive math operations.
2. The Optimal WebGL Strategy
To translate this 1:1 while modernizing the stack, we should map your C++
architecture directly to a modern WebGL ecosystem.
 * Language: TypeScript. It will give you the strict typing, interfaces, and
OOP paradigms you used in C++ (like virtual functions and namespaces), making
the port straightforward.
 * Rendering Engine: Three.js or Babylon.js.
   * Recommendation: Babylon.js. Its architecture is heavily inspired by
classical game engines (very similar to Irrlicht). It handles custom meshes,
sub-meshes, and dynamic vertex updates exceptionally well.
 * Physics: Ammo.js. Since you originally used BulletPhysics, Ammo.js is the
exact same C++ Bullet engine compiled directly to WebAssembly (WASM). Your
physics logic will port almost perfectly.
 * Memory & Performance: When writing the new CCubeBuffer, you will want to
construct the mesh buffers using standard JavaScript Float32Array and
Uint16Array. Structuring the vertex, UV, and normal data at this low level
will feel right at home alongside your experience writing VM opcodes and lexer
engines in Node.js. It requires the same precise, lock-free memory management
mindset to keep the mesh rebuilds blazing fast.
3. Designing the Remake from Scratch
If we rebuild this from the ground up to expose similar data points and
top-level function calls, here is a proposed architecture for the modernized
Web client:
 * Core Data Abstraction (The State):
   * Keep CCubeMap and CCubeData, but decouple them entirely from the
rendering engine. They should be pure logical data structures.
   * We can use Web Workers to process the chunk generation and smoothing
(CCubePoint.recalc()) on a separate thread. This is crucial for JavaScript, as
rebuilding complex geometry on the main thread will cause stuttering. Using
asynchronous message passing (much like SPSC ring buffers in a
high-performance Fastify API gateway) will allow the heavy lifting to happen
in the background.
 * The Rendering Layer (The View):
   * Create a ChunkRenderer class (the equivalent of CCubeBuffer) that listens
for updates from the Web Worker.
   * When a chunk changes, the worker passes back flat TypedArrays. The
ChunkRenderer simply updates the WebGL buffer attributes (position, normal,
uv).
 * The API Interface:
   * Expose a clean API for top-level apps: insertCubes(start, end),
deleteCubes(start, end), and setPointType(pos, type).
   * Because it runs in the browser, top-level UI (menus, toolbars) can be
handled by standard HTML/CSS or React, fully replacing CInterface and
Irrlicht's GUI environment.
This is a highly viable and exciting project. You have all the structural
logic already solved in your C++ headers; it's mostly a matter of adapting the
memory paradigms to the web and swapping Irrlicht for a modern WebGL wrapper.
To kick off the design phase: would you prefer to start by strictly porting
the core data structures (like CCubeData and CCubePoint) to TypeScript to
ensure the logic matches perfectly, or would you rather start by setting up
the WebGL rendering loop and physics world first?