Realm of Echoes is a real-time 3D fantasy MMORPG that runs in a normal desktop browser tab. Players can choose a Warrior or Mage and enter as a guest, so testing the game does not begin with a download or account form.
You can try the live build here.
This is less a launch announcement than an architecture field note: what is working, where the boundaries are, and what has been difficult about putting an authoritative shared world behind a Three.js client.
Why make an MMORPG for the browser?
The browser removes the biggest source of friction for early playtesting. A link can take someone from curiosity to movement and combat in seconds, and guest identity lets the game demonstrate value before asking the player to keep an account.
That convenience creates constraints too:
- the renderer, UI, networking, audio, and game loop all share one tab
- backgrounding and focus changes are normal
- integrated graphics and modest laptops need to remain viable
- controls must coexist with browser behavior
- a client that is easy to open is also easy to inspect, so it cannot be trusted as the authority
Those constraints shaped the architecture more than any individual framework choice.
The current architecture
The system has three main boundaries:
Browser
Three.js 0.185.0 + TypeScript UI
|
| WebSocket
v
Cloudflare Durable Object
authoritative shared-world state
|
+-- Rust gameplay worker compiled to WebAssembly
+-- D1 account and recovery persistence
Separate TypeScript Worker
public client and authentication surface
The browser owns presentation, input, and immediate feedback. Three.js renders the world, characters, animation, spell effects, and combat presentation.
The gameplay worker is written in Rust and compiled to WebAssembly. A Cloudflare Durable Object owns the authoritative live-world state, while WebSockets keep connected players synchronized. A separate TypeScript Worker serves the public client and authentication surface, and D1 supports persisted account and recovery data.
The important rule is simple: the client can make the game feel responsive, but it does not decide the durable outcome of combat or progression.
Keeping authority without making combat feel remote
A purely round-trip-driven combat interface feels sluggish. A purely client-authoritative one is not acceptable for a persistent multiplayer game.
The useful boundary is intent versus outcome. Input and local presentation can react immediately: targeting feedback, animation starts, cast indicators, and UI state should not wait for a network round trip. The authoritative world still decides whether the action is valid and what changed.
That makes reconciliation a product concern, not just a networking concern. When the server disagrees, the correction must be legible. Silent snapping or unexplained cooldown changes feel like bugs even when the server is technically correct.
The work is therefore split between:
- keeping identifiers and state transitions stable enough to reconcile;
- limiting how much speculative presentation can get ahead;
- making corrections understandable in the HUD and world;
- testing under imperfect latency rather than only on a local connection.
Guest-first onboarding is an identity problem
Guest play looks like a UI feature, but it reaches deep into persistence.
The current flow lets a player name a hero and start immediately. Account linking is optional and can retain that guest hero. That means the system needs a clean transition from temporary identity to persisted identity without duplicating a character, losing progress, or making the first session feel like a registration funnel.
The design principle has been to postpone commitment, not value. The player should encounter movement, combat, quests, loot, and other online heroes before being asked to preserve the session.
Content scale changes the debugging problem
The current campaign contains eight onboarding quests plus 180 regional quests across nine regions, with a progression path toward level 30.
At that scale, a content bug is rarely isolated. A broken quest condition can be a state-schema issue, a region-routing issue, an authoritative simulation issue, or simply unclear UI feedback. The fastest debugging path has been to treat content as data with explicit identifiers and to test the transition edges: accepting, progressing, completing, reconnecting, and changing regions.
The same applies to multiplayer systems such as parties, trading, guilds, chat, professions, bosses, and personal loot. Each feature is manageable on its own; the difficult bugs appear where two persistent systems meet.
Three.js lessons so far
The rendering challenge is not drawing one attractive scene. It is keeping a full MMO-style scene and interface predictable while characters, effects, labels, world objects, and network updates change continuously.
A few priorities have mattered repeatedly:
- stable frame pacing is more useful than impressive peak quality
- effects need explicit lifetime and disposal rules
- combat readability should win over effect density
- integrated graphics are a first-class test target
- reconnects and region changes must not leave duplicate scene objects behind
- the HUD needs to explain authoritative state without covering the world
The current screenshots are useful, but the more valuable test is a ten-minute session with movement, targeting, a boss, inventory interaction, and a reconnect.
What I would like feedback on
If you try the build, I am especially interested in four things:
- Does the first five minutes explain enough?
- Does Warrior or Mage combat feel responsive and readable?
- Where does browser performance first become uncomfortable?
- Which part of the architecture or implementation would be most useful to unpack in a follow-up post?
The game is live at realm-of-echoes-auth.realmofechoes.workers.dev, and longer-form feedback is welcome in the Realm of Echoes Discord.
Transparency: generative tools were used in parts of the project's image and audio asset pipeline.
Top comments (0)