Devlog · Loop 0
Loop 0 — Project Foundation
Loop 0 turned a repository containing a three-line README into the persistent source of truth for DUST: what the game is, what must remain true, what is decided and what is not, how the engine, server, hosting and AI-driven development are meant to work, and how each loop is delivered. It implemented no gameplay. Files are named in code style; they live in the repository, not on this website.
Starting state
Before this loop the repository (sonixz/dust-game, branch main) held two files and two commits:
README.md— three lines in French, saying the project is a web game: a showcase site plus a playable game under/play..gitignore— a Node-oriented ignore list (Node modules, environment files, infrastructure output, editor files).- Commits
08e9b55(Initial commit: README and .gitignore) and923a56a(README: remove reference to missing infra/). Both stay untouched; Loop 0 adds one commit on top of them.
There was no code, no engine project, no documentation and no website.
The development machine was one Azure VM: dust-dev-vm, size Standard_B1ms (1 vCPU, 2 GB RAM, 4 GB swap), Ubuntu 24.04.5 LTS, region Canada East, private IP only. It already had git, Node.js, Docker, python3, tmux and several AI coding CLIs (Claude Code, Codex, OpenCode, agent-manager). Godot was not installed. Nginx was not installed. The VM has no display, no GPU, and no Azure CLI or Bicep tooling.
Loop 0 objective
Turn the minimal repository into the persistent source of truth for DUST, so that a capable AI coding agent with no previous conversation can clone it and understand what DUST is, what its design laws are, what is decided and what is still unknown, how the engine, the authoritative server, the Azure host and the development model are meant to work — and then safely begin Loop 1.
The foundation stack this loop had to establish:
VISION
+ REPOSITORY CONTRACT
+ AI DEVELOPMENT MODEL
+ GODOT FOUNDATION
+ AZURE HOSTING DIRECTION
+ PUBLIC WEBSITE
+ HTML DEVLOG
+ DOCUMENTATION
+ GIT DELIVERY DISCIPLINE
Loop 0 implements no gameplay. Every gameplay system is recorded as direction, design status or backlog, and nothing more (see Intentionally out of scope).
The test the owner set for the loop: a capable coding agent can clone DUST tomorrow, read the repository and understand what must be built without access to any previous conversation; a visitor opening the landing page understands the fantasy of DUST without being promised gameplay that does not exist; and the Azure VM is useful infrastructure, but the repository remains more important than the machine.
What the repository contains at the end of the loop:
/
├── README.md entry point: maturity, documentation map, quick start
├── GAME_VISION.md level 1 — vision and design laws (owner-controlled)
├── AGENTS.md agent development contract
├── CLAUDE.md short Claude Code entry point (points to AGENTS.md)
├── .gitignore Godot, Node tooling, secrets, AI tool local state, editors
├── client/ Godot 4 project: bootstrap scene only
├── server/README.md authoritative server direction — no implementation
├── infra/README.md Azure host and future Bicep — documentation only
├── ops/ nginx/dust.conf.example, deploy-public.sh, README.md
├── docs/ DECISIONS.md, GAME_DESIGN.md, ARCHITECTURE.md, BACKLOG.md
├── public/ canonical public web root: index.html, assets/, devlog/, play/
└── tools/ install-godot.sh, README.md
Game vision established
Recorded in GAME_VISION.md, documentation level 1: owned by the human owner; agents may propose changes but never apply them on their own (D010). DUST is a working title — not a commercial title, a trademark, a Steam identity, a domain or permanent branding (D013).
A persistent real-time 2D survival PvP MMO taking place in procedurally generated worlds that continue running 24/7.
The game is viewed from above. The world begins largely unknown. The player must explore, gather, hunt, loot, build, craft, progress technologically, protect possessions and interact with other players in a persistent physical world that does not pause when they disconnect.
Core loop
NEED → LEAVE SAFETY → EXPLORE → GATHER / HUNT / LOOT → FIND VALUE → ACCEPT RISK
→ RETURN ALIVE → STORE → CRAFT / BUILD / RESEARCH → BECOME MORE CAPABLE → LEAVE AGAIN
Foundational rule: THE PLAYER MUST LEAVE SAFETY TO PROGRESS.
Six pillars
- SURVIVE — the character physically exists in a dangerous world; detailed formulas remain TBD.
- DISCOVER — knowledge moves through
UNKNOWN → DISCOVERED → EXPLORED → MAPPED; exploration and geography must matter. - POSSESS — players accumulate physical value worth protecting.
- BUILD & DEFEND — bases exist physically in the persistent world.
- PVP — PvP emerges naturally from resources, travel, monuments, territory, possession and raids.
- PERSIST — the world does not pause when an individual player disconnects.
Ten design laws
- The server is authoritative.
- The world does not pause.
- Risk creates value.
- Players must leave safety to progress.
- Exploration must matter.
- PvP emerges from the world.
- Bases physically exist.
- Procedural generation must create geography worth learning.
- 2D is a deliberate game-design choice.
- Scale must be earned.
An implementation that violates a law is a bug, even if it works.
Directions recorded, not implemented
The vision also records the procedural world direction (procedural does not mean random noise), monuments, the visibility and information model (top-down is not omniscience; long term the server decides what a player is allowed to know), sound as imperfect information, technology / industry / automation (survival world first, automation second — D024), dynamic physical markets (nothing valuable should magically bypass the world — D025) and MMO scale (scale must be earned — D008). The design status of every system is tracked in docs/GAME_DESIGN.md with the markers Known TBD Open question. At the end of Loop 0, none of it is implemented.
Architecture established
Recorded in docs/ARCHITECTURE.md and server/README.md. The long-term concept:
GODOT CLIENT a view plus input; sends intents, never results
↓
REAL-TIME NETWORK protocol TBD
↓
AUTHORITATIVE WORLD SERVER movement, inventory, loot, combat, visibility,
structures, survival, interactions
↓
PERSISTENCE store TBD
- The server is authoritative (LAW 1, D002). No client-supplied state is trusted; the server validates every intent and sends each client only what that player may know. This holds in design even for local prototypes: simulation code stays separable from presentation code so it can move server-side without a rewrite.
- Godot is the client engine (D001), pinned to 4.7.2-stable on the dev host (D027). The project uses the GL Compatibility renderer because it is the only renderer supported by Godot Web export.
- A headless Godot process is an acceptable initial direction for the authoritative server. It is not locked: nothing in the repository may assume Godot server-side until a decision is recorded.
server/README.mdlists what a future loop must decide first: runtime, transport, message model, persistence, player identity, shared simulation code, operation on the host. - Persistence is required, the store is TBD (D003, D023). World state must survive process restarts and host rebuilds. Files, an embedded database and an external database are all possible; none has been evaluated; no production database is built.
- Public web model (D016–D019):
INTERNET → NGINX → /(landing page),/devlog/,/play/(future Godot Web export), future API / WebSocket routes. The Web client is served by the Linux host but executes in the player's browser, as a view. - Scale must be earned (LAW 10, D008). First target: one process, one world. Chunks, regions, zones, interest management and distributed simulation are possible futures only; nothing distributed is built.
State at the end of Loop 0: no game server, no networking, no persistence, no authentication. The twenty-eight decisions D001–D028 in docs/DECISIONS.md were all recorded in this loop, each with its rationale.
AI operating contract
AGENTS.md is the canonical development contract for every AI coding agent, whatever the model or vendor (D014): Claude, Codex, OpenCode, open-weight models and future providers. CLAUDE.md is a short entry point for Claude Code that points to it and to GAME_VISION.md without duplicating the contract.
A LOOP IS NOT COMPLETE UNTIL IMPLEMENTATION, VERIFICATION, REQUIRED DOCUMENTATION, HTML DEVLOG, GIT COMMIT AND PUSH ARE COMPLETE — OR AN EXACT BLOCKER HAS BEEN REPORTED.
Documentation hierarchy
| Level | Files | Who changes it |
|---|---|---|
| 1 — Vision | GAME_VISION.md | Human owner only; agents may propose |
| 2 — Decisions | docs/DECISIONS.md | Loop Owner, appending entries; vision-level decisions need owner direction |
| 3 — Evolving docs | docs/GAME_DESIGN.md, docs/ARCHITECTURE.md, docs/BACKLOG.md, area README.md files | Any agent, within its loop |
| 4 — Implementation | code, assets, runtime configuration | Any agent, within its loop |
Lower levels conform to higher levels. Implementation accidents must never silently rewrite the vision. The repository is the only shared context (D009): nothing important may live in chat history, vendor memory, private scratchpads or undocumented machine state.
Roles
The human owner is Game Director, Product Owner, Systems Designer, Architecture Authority, AI Orchestrator, Artistic Director and Final Decision-Maker. Agents implement, test, investigate, document, automate and generate assets and tools; they do not own product vision. The project does not depend on the owner manually writing code or producing most graphical assets (D015).
Loop contract
IMPLEMENT → VERIFY → PLAYTEST WHEN RELEVANT → UPDATE DOCUMENTATION
→ UPDATE DECISIONS / BACKLOG → CREATE HTML DEVLOG ENTRY → UPDATE DEVLOG INDEX
→ REVIEW GIT DIFF → COMMIT → PUSH → REPORT
One loop, one primary objective, one Loop Owner, one coherent commit; push is part of the contract (D011, D012).
Obligations of every agent
A summary of the twenty obligations in AGENTS.md:
- Inspect repository state before acting; read
GAME_VISION.md,docs/DECISIONS.mdand the documentation relevant to the loop; read the latest devlog entry; inspect the machine instead of assuming a tool is installed. - Work toward one loop objective; avoid speculative rewrites and speculative infrastructure; preserve the server-authoritative direction and architectural evolvability.
- Update documentation when behaviour changes; record important decisions.
- Test honestly and never fake success; if GUI execution is impossible, validate headless and say so; playtest when relevant.
- Write the loop's HTML devlog entry with no fabricated progress; review the full diff; make one coherent commit; push; report blockers exactly.
- Never depend on hidden AI memory; never assume manual coding or art from the owner; follow the Loop Owner / specialist model where it helps and work alone where it does not.
Git and security
Work on main unless the loop says otherwise; never force-push, rewrite, squash or delete history; repository content and commit messages in English (D026). Never commit SSH keys, git credentials, API keys, .env secrets, vendor credentials, tokens or agent-manager state. Never expose Claude Code, Codex, OpenCode, Agent Manager or any development port to the public Internet. Only public/ is public.
Specialist-agent model
Recorded in AGENTS.md §4 (D021).
HUMAN OWNER → LOOP OWNER → SPECIALISTS → QA / REVIEW → LOOP OWNER INTEGRATION
→ DOCS, DEVLOG, COMMIT, PUSH
Rules: the human owner owns the vision; one Loop Owner owns each loop; specialists stay within their assigned domain and cannot redefine GAME_VISION.md; multiple agents must not casually modify the same primary worktree at the same time, and isolated branches or worktrees are used when real parallel implementation becomes necessary; the Loop Owner reviews and integrates specialist contributions; QA / review must be able to challenge an implementation independently; multi-agent complexity is optional; do not use five agents when one can safely solve the task. Potential specialties: Gameplay / Godot, World Simulation / Networking, Backend / Persistence, Azure / Infrastructure, QA / Performance, Visual Pipeline, Architecture / Review. No larger role framework was created.
The host also has agent-manager, a tmux-based manager for CLI agents. It is optional tooling: it needs no repository configuration and DUST must never depend on it.
How this loop was actually done
Loop 0 used the model it documents. One Loop Owner agent inspected the host and the repository, planned the loop, installed Godot and Nginx on the host, wrote the anchor documents (GAME_VISION.md, AGENTS.md, docs/DECISIONS.md, README.md, client/README.md) and the Godot bootstrap, then delegated the remaining documentation and the web pages to specialist writer agents. Each specialist received the owner's full brief and the anchor documents, and was restricted to a fixed, disjoint set of files, with no permission to touch other files or to commit. Independent reviewer agents checked the results against the brief and the anchor documents. The Loop Owner reviewed and integrated everything, performed the validations recorded below, and is responsible for the single commit and push. This is recorded as what happened, not as a recommendation; whether the coordination was worth its cost compared with a single agent is for the owner to judge over later loops.
Azure integrated-host direction
Recorded in infra/README.md, ops/README.md and docs/ARCHITECTURE.md (D020, D022, D023).
AZURE LINUX VM dust-dev-vm Standard_B1ms: 1 vCPU, 2 GB RAM
├── ~/dust git checkout — the source of truth
├── AI coding tools never exposed publicly
├── Godot 4.7.2 headless validates client/; candidate runtime for a future server process
├── Nginx 1.24 :80 serves /var/www/dust/, the deployed copy of public/ (ops/)
├── /play/ future Godot Web export — reserved, nothing served
├── game server future — not implemented
├── API / backend future — not implemented
└── persistence future — not implemented
- One VM, two roles. It is the development host and the early runtime host at the same time. This is deliberate. If the VM stops, the early DUST environment stops; that is acceptable. High availability is not solved and must not be solved now. Development / runtime separation happens when a real need appears (D022), not before.
- No public IP today. The NIC has a private address only; only
sshd(22) and Nginx (80) listen. Once the DUST site is activated, the website will therefore be reachable only from the VM itself or its private network. Making it reachable from the Internet needs Azure-side work — a public IP or a fronting service, plus network security group rules — that Loop 0 does not do. No domain name is assumed (D013); no TLS is configured. - The VM is replaceable (D023). The repository is the source of truth; anything needed to rebuild the host lives in git, docs and scripts:
tools/install-godot.shfor Godot,ops/nginx/dust.conf.exampleandops/deploy-public.shfor the website. Rebuild lifecycle:CREATE AZURE HOST → BOOTSTRAP LINUX → CLONE REPOSITORY → INSTALL / CONFIGURE SERVICES → START DUST. - Bicep is the preferred infrastructure-as-code direction and
infra/will own it. Todayinfra/contains only its README: no Bicep exists, the host has no Azure CLI or Bicep tooling, and nothing speculative was written. - Nginx serves a deployed copy, not the checkout (D028).
/home/dustis not readable bywww-data, soops/deploy-public.shsyncspublic/to/var/www/dust/; the exact activation steps are inops/README.md. Both were run at the end of Loop 0: the DUST site replaced the Ubuntu default site and/var/www/dust/holds the deployed copy (see Validation). Onlypublic/is ever public; development tooling is never proxied.
Godot bootstrap
Recorded in client/README.md and tools/README.md (D001, D027).
- Engine install. Godot was absent from the host.
tools/install-godot.shdownloads the official Godot 4.7.2-stable Linux x86_64 editor binary from the GitHub release, verifies it against the releaseSHA512-SUMS.txt, installs it under~/.local/opt/godot/4.7.2-stable/and symlinks~/.local/bin/godot. User space, no root, idempotent. The version is pinned; changing it is a recorded decision, not an accident. - Project.
client/is a minimal Godot 4 project:project.godot(GL Compatibility renderer, 1280×720 base resolution,canvas_itemsstretch), a placeholdericon.svg,scenes/bootstrap.tscnas the main scene, showing “DUST / Prototype Foundation” and a status line with the loop number and engine version, andscripts/bootstrap.gd, which prints one bootstrap line on_ready(). The import cacheclient/.godot/is git-ignored; the generated.importand.uidsidecar files are committed. There is no gameplay code of any kind. - Headless validation. The host has no display and no GPU, so a GUI run is not possible there; validation is headless only, one process at a time:
The second command ran the bootstrap scene and printedgodot --headless --path client --import godot --headless --path client --quit-after 3
with exit code 0. This was observed by the Loop Owner on the dev host on 2026-09-12. That line is the validation signal for the foundation and must stay stable.[DUST] bootstrap ready | loop 0 | Godot 4.7.2-stable (official) | headless=true
Public website
Recorded under public/ (D016, D017, D018, D019). public/ is the canonical public web root; nothing public lives outside it.
- Landing page —
public/index.html. A static, responsive, single-page presentation of the concept: “DUST — A Persistent 2D Survival MMO. Explore a world you do not know. Bring home what you can. Build something worth protecting. The world continues without you.” It communicates SURVIVE / DISCOVER / POSSESS and the concepts of a persistent world, procedural geography, exploration, loot, crafting, bases, PvP, raids and technological progression. It contains no screenshots, testimonials, player counts or released features, does not lock an art style, and reaches this devlog without making it a primary call to action (D017). - Devlog —
public/devlog/. This site:index.html(a static, newest-first list that works without JavaScript),style.css,entries/(one HTML page per loop; this page is the first),assets/(empty for now) anddata/index.json, a minimal machine-readable mirror of the index for future automation. The static index is the source of truth; the JSON mirrors it. /play/—public/play/. Reserved for the Godot Web client (D019). It holds a README describing the pathGodot project → Web export → public/play/ → Nginx → player browser, and nothing else. No export was attempted; the route serves nothing.
Serving on the host goes through ops/ (see Azure integrated-host direction). The DUST site configuration was activated and public/ deployed at the end of Loop 0 (see Validation). The site is reachable only from the VM until it is exposed; no external check is possible or claimed.
Validation
Observed on the dev host by the Loop Owner between 2026-09-12 and 2026-09-13 (UTC); several checks were also re-run independently by reviewer agents. Only checks that were actually run are listed, each with its observed result; what was not checked is stated last.
- Godot.
godot --headless --path client --importfollowed bygodot --headless --path client --quit-after 3: both exit code 0, no warning or error printed; the second prints[DUST] bootstrap ready | loop 0 | Godot 4.7.2-stable (official) | headless=true. A reviewer agent followingclient/README.mdexactly obtained the same output.tools/install-godot.shwas executed twice: against the existing install (idempotent branch: "already installed", symlink refreshed, version printed) and with a temporaryHOME(full download, SHA512 checkOK, install, symlink,4.7.2.stable.official.ed1daf0bfprinted, exit code 0). - Repository. Branch
main, the two preserved commits08e9b55and923a56aintact, no history rewritten; the tree matches the layout above;client/.godot/is ignored whileicon.svg.importandbootstrap.gd.uidare tracked. Agrepover the tree (excluding.git/andclient/.godot/) for private-key headers, GitHub / OpenAI / AWS token patterns, hard-codedpassword/secret/tokenassignments and SSH key material matched nothing; no.env,.pemor key file is present. - Documentation coherence. A script resolved every relative Markdown link and every local HTML
href/srcin the repository (root-relative links are rejected): none broken. Every decision ID cited anywhere (D001–D028) exists indocs/DECISIONS.md; the ten laws are word-for-word identical inGAME_VISION.md,docs/GAME_DESIGN.mdand this page; noTODOor placeholder marker remains. - Website and devlog. A Python
html.parserpass over the three pages (public/index.html,public/devlog/index.html, this entry): tags balanced, no duplicateid,lang, charset, viewport, title and description present. The pages load no external resource of any kind (no CDN, no font, no remote script).node --checkpasses onpublic/assets/site.jsand on the inline script ofpublic/devlog/index.html; this entry contains no script.python3 -m json.tool public/devlog/data/index.jsonparses; its single entry has the same path, title, date and tags as the static list. Page weight: landing page 17 KB of HTML, 9 KB CSS, 5 KB JS, 0.5 KB favicon. - Nginx — activated.
ops/nginx/dust.conf.examplewas copied to/etc/nginx/sites-available/dust.confand enabled, the Ubuntu default site disabled;sudo nginx -treported syntax is ok / test is successful; Nginx reloaded;ops/deploy-public.shcreated/var/www/dust/and reported the DUST title athttp://127.0.0.1/.curlfrom the VM:/200text/htmlwith<title>DUST — A Persistent 2D Survival MMO</title>;/devlog/200; this entry 200;/devlog/data/index.json200application/json;/assets/style.css200text/css;/assets/site.js200;/assets/favicon.svg200image/svg+xml;/play/403 withCross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corp;/play/README.md404 (README files are not deployed);/.git/configand/.dust-web-root403; an unknown path 404. Responses carryServer: nginxwithout a version,X-Content-Type-Options,Referrer-PolicyandX-Frame-Options. Listening sockets after activation: still only 22 and 80. - Not performed. No GUI run of the Godot project (no display, no GPU). No browser rendering of the website: responsive behaviour was checked by reading the stylesheets (breakpoints at 900, 640 and 380 px on the landing page, 520 px on the devlog), not by rendering them. No request from outside the VM (no public IP). No Godot Web export. The final git diff review, the commit and the push happen after this page is written and are reported in the loop report, not here.
Open questions
Genuinely undecided at the end of Loop 0. Each needs an owner decision recorded in docs/DECISIONS.md before work commits to an answer. The full lists are in docs/GAME_DESIGN.md §12, docs/ARCHITECTURE.md §4, server/README.md §7 and infra/README.md §12.
- Server implementation and protocol. Headless Godot or another runtime; if Godot, the same project as
client/or a separate one. Transport: Godot high-level multiplayer, ENet, WebSocket or WebRTC — a browser cannot use raw UDP. Message model and tick rate. Whether game traffic goes through Nginx. - Persistence store. Files, an embedded database or an external database; what must be stored beyond the world seed; backups.
- World size and reset policy. How large a world is, whether worlds ever reset, whether several worlds exist.
- Survival formulas. Which needs exist, their rates, and what death costs (death and respawn are undecided too).
- Public exposure of the VM. Public IP or fronting service; which network security group rules (the current rules are not recorded in the repository, because the host has no Azure CLI to read them); domain name (none decided); whether to expose the site before there is something to play.
- Art direction. Nothing is locked; the landing page presents the concept, not a visual style.
- Whether development and runtime hosts split later. One VM for both until a measured need appears (D022).
Intentionally out of scope
Documented as direction and backlog only, not implemented, by the owner's explicit instruction. Being listed in docs/BACKLOG.md is not permission to start any of them.
- player movement
- procedural terrain
- survival stats
- inventory
- loot
- crafting
- weapons
- combat
- base building
- industry
- automation
- market
- multiplayer
- authentication
- production database
- MMO networking
- world partitioning
- Kubernetes
- AKS
- distributed infrastructure
Next
Recommended next loop (not started): Loop 1 — Procedural World & Exploration Prototype.
DETERMINISTIC WORLD + PROCEDURAL GEOGRAPHY + TOP-DOWN MOVEMENT + CAMERA
+ UNKNOWN / DISCOVERED WORLD + BASIC VISIBILITY + FIRST LANDMARK
This is a recommendation recorded at the end of Loop 0, not a commitment, a date or a release plan. The owner defines the exact scope when the loop starts. Even if Loop 1 runs entirely inside one local Godot process, the server remains authoritative in design (LAW 1) and simulation code stays separable from presentation code, so the world and its rules can move server-side later without a rewrite. Networking, multiplayer, persistence, survival, inventory, combat and bases are not in its expected scope.