A Minecraft-style multiplayer building game. Three.js voxel client, Python WebSocket game server, nginx in front for production. No build step, no asset files — textures and sounds are generated procedurally at runtime.
In-game captures (here running the optional real-world terrain mode, built from NRW open elevation + land-use data):
![]() |
![]() |
| Rolling terrain, forests and field paths at midday | Low evening sun over the hills |
![]() |
![]() |
| Streams, trees and the hotbar HUD at ground level | Night falls — stars, moonlight and clouds |
./run.sh
# open http://localhost:8080 in one or more browser tabsThe script creates a venv and installs the single dependency (websockets)
on first run.
- Infinite procedural terrain (hills, lakes, beaches, trees, snowy peaks, coal and iron ore underground) from a shared seed
- Multiplayer: see other players move and build in real time, chat
- Survival loop: mine blocks (timed, tool-dependent) for drops, craft tools, place workbenches and furnaces for advanced recipes; tools have durability; three tool tiers (wood → stone → iron)
- Mobs: chickens, dogs, sheep and cows by day; zombies, skeletons and spiders at night — zombies and skeletons burn at sunrise, spiders turn passive
- Inventory (E): 36 slots, stacking to 64, right-click splits stacks; persisted per player name on the server
- Crafting menu: recipe book with have/need counts; Blocks tab: creative palette with free stacks of every block (tools must be crafted)
- Physics: gravity, jumping, swimming, sprinting, sneaking, flying
- Health with hearts HUD, knockback, regeneration, respawn
- Rebindable controls via in-game menu (F5), persisted per browser
- Admin console (F6) — type
/helpfor the command list - Day/night cycle, ambient occlusion, block highlight, hotbar, debug overlay (F3)
- World persists across server restarts (
server/data/world.json)
| Key | Action |
|---|---|
| WASD / Space | move / jump |
| Shift | sprint |
| Ctrl | sneak (slower, lowered camera; fly down while flying) |
| F or double-Space | toggle fly (Space/Ctrl = up/down) |
| Left click | mine block (hold) / attack mob |
| Right click | place block |
| E | inventory · crafting · block palette |
| 1–9 or mouse wheel | select hotbar slot |
| T or Enter | chat |
| F3 | debug overlay |
| F5 | key bindings menu |
| F6 | admin console |
| Esc | release cursor |
- Punch a tree (logs break by hand in ~2.5 s) → craft planks → sticks
- 4 planks → workbench; place it — tool recipes need one within 4 blocks
- Craft wooden tools: pickaxe (mining stone requires one), axe (wood faster), shovel (dirt/sand faster), sword (more damage vs. mobs)
- Mine stone → cobblestone → stone tools + a furnace (8 cobble)
- Dig for ore: coal in the upper stone layers, iron below y≈28 (iron ore needs at least a stone pickaxe)
- Smelt at the furnace: 1 iron ore + 1 coal → iron ingot; also 4 cobble + 1 coal → 4 bricks for fancy building
- Iron tools: fastest mining, 250 durability, iron sword does 10 damage
Blocks won't drop without the required tool/tier. Tool stats live in
client/js/items.js, recipes in client/js/crafting.js.
/help lists everything: /time day|night|0..1, /tp x y z or /tp player,
/players, /spawn chicken|dog|zombie [n], /mobs on|off, /butcher,
/clear (wipe all edits), /kick player, /say msg, /seed, /save.
Every player may use the console — fine for a friends server, lock it down
before hosting strangers.
browser ── static files ── nginx (prod) or python (dev)
│
└─ /ws (WebSocket) ── python game server ── data/world.json
- The server is authoritative for block edits, player presence, chat and mob simulation.
- Terrain is generated client-side from the server's seed (deterministic
integer-hash noise), so the server only stores the diff (player edits) and
the protocol stays tiny.
server/terrain.pyis a bit-exact Python port of the same noise so mobs walk on the ground clients actually render. - Positions and mob snapshots are relayed at 10 Hz; clients interpolate.
| Direction | Message |
|---|---|
| C→S | hello {name}, move {p,r}, block {x,y,z,id}, chat {text}, hit {id,item}, cmd {text}, inv {s} |
| S→C | init {id,seed,time,edits,inv,players}, join {player}, leave {id}, moves {pl}, block, chat {from,text}, sys {text}, mobs {l}, mob_die {id}, hurt {dmg,from}, con {text}, time {time}, teleport {p}, wipe |
-
Run the game server as a service, e.g. with systemd:
# /etc/systemd/system/buildcraft.service [Unit] Description=BuildCraft game server After=network.target [Service] User=www-data WorkingDirectory=/opt/buildcraft ExecStart=/opt/buildcraft/server/.venv/bin/python /opt/buildcraft/server/main.py Environment=BUILDCRAFT_HOST=127.0.0.1 BUILDCRAFT_PORT=8080 Restart=on-failure [Install] WantedBy=multi-user.target
-
Install the nginx site from
nginx/buildcraft.conf(adjust therootpath), thennginx -t && systemctl reload nginx.
nginx serves the static client and proxies only /ws to Python. For TLS,
put certbot/LE on the server block as usual — the client automatically uses
wss: when served over https.
| Env var | Default | Meaning |
|---|---|---|
BUILDCRAFT_HOST |
0.0.0.0 |
bind address |
BUILDCRAFT_PORT |
8080 |
HTTP + WebSocket port |
World data lives in server/data/world.json (saved every 30 s when dirty and
on shutdown). Delete it to regenerate a fresh world with a new seed.
tools/build_map.py builds the world from real elevation data instead of a
seed. Example — the Rursee area in the Eifel from NRW open data
(opengeodata.nrw.de, DGM1, licence DL-DE Zero):
server/.venv/bin/pip install tifffile imagecodecs numpy
# download some 1 km tiles (UTM32 E314-316 / N5610-5612 = Rursee):
curl -O https://www.opengeodata.nrw.de/produkte/geobasis/hm/dgm1_tiff/dgm1_tiff/dgm1_32_315_5611_1_nw_2021.tif
server/.venv/bin/python tools/build_map.py dgm1_32_*.tif
# restart the server — it logs "heightmap loaded"Scaling is 4 m per block (true proportions); the lowest terrain (a lake
surface) lands just below the water line, so real lakes become water.
Delete server/data/map.bin and map.json to go back to seed terrain.
BuildCraft is free to use under two complementary licenses:
- Source code — MIT License. Covers
client/,server/,tools/,tests/,nginx/, and the build/run scripts. Maximally permissive and compatible with the wider open-source ecosystem. - Documentation & assets — CC BY 4.0. Covers the prose
docs (this README,
CLAUDE.md), the procedurally generated textures and sounds, and any bundled world/map data. Free to share and adapt, even commercially, as long as you give attribution.
The optional real-world terrain uses NRW open data (DGM1 elevation, ALKIS), published under DL-DE Zero 2.0. That data is downloaded by the user, not redistributed here.
Creative Commons recommends against using CC licenses for software, so the code is MIT and only the non-code material is CC BY.



