Walk a live isometric world with your ENS identity and USDC wallet built in.
bitopia.world is a browser-based isometric multiplayer world where people sign in, get a real onchain identity, and share live rooms together — walking around, chatting, and moving money, all in the same space.
You enter through a single sign-in powered by Privy, which gives every player an embedded Ethereum wallet without seed phrases or extensions. After signing in you pick a username, and the world mints it for you as a real ENS subname on Ethereum mainnet — <username>.bitopiaworld.eth — with your wallet address and avatar written into its records. Your name in the world is your name onchain.
The world itself is rendered isometrically with Three.js: rooms made of floor and wall tiles, characters you move by clicking the ground. Everyone in a room sees everyone else in real time over a socket connection — players appearing, walking, and leaving — plus a shared chat. The server is authoritative over positions, so every client agrees on where each person stands.
Money is real and built in. Your wallet HUD shows your live USDC and ETH balances. You can deposit USDC through an on-ramp, send USDC to another player you meet in a room, or withdraw — and because gas is sponsored, you never need ETH on hand to transact. Everything that touches identity or value happens on Ethereum mainnet, while the moment-to-moment world (movement, chat, presence) runs off-chain for instant feel.
In short: a small social world you can walk around in, where your identity is an ENS name and your wallet comes along with you.
bitopia.world is an isometric multiplayer world where humans roam shared rooms together in real time. Players sign in with an embedded wallet, get a real ENS subname as their identity, and can hold and send USDC — all on Ethereum mainnet.
bitopia is a TypeScript npm-workspaces monorepo (shared / server / client). shared/ holds the contract between modules — the entity/room types and the socket.io event protocol — so the rendering, realtime, and identity layers could be built independently against one frozen interface.
Rendering is Vite + React + Three.js. We hand-rolled the isometric view instead of using a game engine: an orthographic camera at a fixed dimetric angle, rooms built from floor and wall tiles, and characters as boxes. Movement is click-to-move — a raycast picks the ground point, which gets clamped to the walkable floor area. World state and rendering are decoupled, so the renderer just consumes entity snapshots.
Realtime multiplayer runs on socket.io. Auth isn't an event — the client connects with io(url, { auth: { privyToken } }) and the server verifies the Privy token in handshake middleware before any enterRoom / move / chat is allowed. The server broadcasts presence (entityJoined / entityMoved / entityLeft), full roomState, and chat. The server is authoritative for spawn positions so every client agrees on where each character stands. Rooms, users, and usernames persist in SQLite (better-sqlite3).
Identity — Privy + ENS, on Ethereum mainnet. Players sign in with Privy embedded wallets. On signup they pass a username gate, then the server (holding the parent name's key) mints <username>.bitopiaworld.eth as a real wrapped ENS subname on mainnet via the NameWrapper, points the subname's addr record at the player's wallet, and sets an avatar text record (chain/ens.ts). It degrades gracefully: with no parent key configured it just stores the username off-chain instead of failing.
Money — USDC. The wallet HUD reads live USDC + ETH balances via viem (chain/balances.ts), degrading to dashes on RPC failure rather than crashing. USDC transfers go through one shared path (chain/transfer.ts) used for both withdrawals and player-to-player sends — built on Privy's sendTransaction with sponsored gas, so players need no ETH to move funds. A Blink integration provides a USDC on-ramp, with the server signing the deposit payload.
Tests are written in vitest across the shared, server, and client packages. Deployed via Railway.
Stack: TypeScript, Vite + React + Three.js, socket.io, Privy (embedded wallets + handshake auth), ENS subnames, viem, USDC transfers, Blink on-ramp, SQLite, vitest.

