Iron Shell — 2.5D mechanized-drone combat game in Godot 4. Network latency is a core mechanic, not a problem. JP-1 PoC.
  • GDScript 91.3%
  • Shell 6.5%
  • GDShader 2.2%
Find a file
Justin Aquino 9597598116 docs: add measured agent processing time; correct the "~1h40m" figure
Mike asked for agent processing activity. The earlier ~1h40m was the sum of
filesystem WRITE windows, which is a different measure and should not be
quoted as processing time -- it understates thinking and overstates waiting
(a 19-minute template download is a write window with no agent in it).

New section 03b measures the agents themselves, from the session stores:
opencode.db (SQLite, per-message timestamps + tokens + cost) for DS, and the
Claude .jsonl transcripts. Same gap-capped rule applied to both (intervals
capped at 5 min; anything longer is a human not replying).

  DS Stage 1 (08-02)   3h35m49s wall   28m29s processing   13.2%   $0.0805
  Claude    (08-02)    7h15m15s wall   25m03s processing    5.8%
                                       53m32s total measured

DS's own "~30 min" estimate for Stage 1 lands within 90 seconds of measured.
Measured as full assistant-message spans instead, DS is 48m08s -- the delta is
almost entirely one 18m49s span that is the 1.9 GB template download waiting
on a mirror, not a model thinking. Both numbers are in the report, labelled.

Duty cycle is 5.8-13.2%: agent wall-clock here is dominated by waiting for a
human, not by working.

Honest limit, stated prominently: four of the six sessions -- INCLUDING THE
ENTIRE CREATE, the thing Mike asked about -- have no recoverable transcript.
A full-text scan of all 9,367 parts finds only two sessions mentioning Iron
Shell, both from 08-02. The create phase remains bounded (<=5h44m elapsed) but
its processing time is unknowable after the fact. Section 06 now recommends
archiving the session store, which would have made this report complete.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 21:11:22 +08:00
client Stage 1: export presets + Linux server/client binaries + Windows client 2026-08-02 17:26:04 +08:00
docs docs: add measured agent processing time; correct the "~1h40m" figure 2026-08-02 21:11:22 +08:00
server Stage 1: export presets + Linux server/client binaries + Windows client 2026-08-02 17:26:04 +08:00
shared Phase 01: Fix RPC routing + add rpc_relay signal architecture 2026-08-01 22:27:33 +08:00
tests Initial commit: Iron Shell MVP-0 2026-08-01 22:10:53 +08:00
.gitignore Initial commit: Iron Shell MVP-0 2026-08-01 22:10:53 +08:00
DECISIONS.md Initial commit: Iron Shell MVP-0 2026-08-01 22:10:53 +08:00
README.md Initial commit: Iron Shell MVP-0 2026-08-01 22:10:53 +08:00
sync_shared.sh Initial commit: Iron Shell MVP-0 2026-08-01 22:10:53 +08:00

Iron Shell — JP-1 PoC

2.5D mechanized-drone combat game in Godot 4 where network latency is a core mechanic, not a problem to minimize.

Status: 🟡 MVP-0 build complete; RPC path resolution debugging in progress (2026-08-01).


Purpose & Context

Justin is developing Iron Shell, a 2.5D mechanized-drone combat game built in Godot 4 where network latency is a core mechanic — not a problem to minimize, but a diegetic element woven into gameplay. Players are Drone Operators controlling Combat Shells remotely from underground habitation networks; lag is canonically real signal travel time. Defense is achieved through lag-induced uncertainty rather than armor.

The current focus is a proof-of-concept milestone (JP-1 / POC in JPN) deployed on a Contabo VPS in Japan (port 19099, 10 Hz server ticks), with three test operators profiled at varying latencies (Philippines ~120 ms, New Jersey ~300 ms).

Three Design Pillars

  1. Prediction over Reaction — Players lead targets through the lag window; proximity-fused rounds reward anticipation
  2. Tactical Cohesion — No single shell wins alone; class complementarity (Scout, Skirmisher, Striker, Fortress) is essential
  3. Mass is Destiny — Every loadout component has real weight, trading mobility for firepower

Victory Condition

Not just survival — resource-to-kill efficiency. Ammo spent, shells lost, and time elapsed versus enemies destroyed and objectives secured.

Default Mode: PvE Co-op (PvP comes after the lag system is validated).


Key Domain Areas

  • Godot 4 multiplayer networking
  • Server-authoritative architecture
  • Real-time game systems
  • Lore-integrated UX design

Current State

Justin is actively building and documenting the JP-1 PoC across four phases (Phase 0003), covering:

Phase What Status
00 Dual-project Godot 4 structure (server + client), ENet setup, headless export 🟡 MVP-0 built
01 Server-authority input node pattern, 10 Hz tick loop, lag visualizer
02 Player/world state RPC design with UDP packet optimization
03 Clock synchronization, client-side interpolation, projectile hit resolution

The Uncertainty Field (UF) Model

The lag visualization model is a positional probability field — a rendered cloud centered on the drone's most recently confirmed position, with radius expanding proportional to total lag experienced by that operator. The center is the highest-probability position; the outer edge is the plausible limit of where the drone could be given its last known velocity and heading.

This is compound lag: operator-to-server latency plus the drone's own sensor/perception delay. A drone deep in contested terrain with degraded sensors contributes its own uncertainty on top of the operator's connection quality.

Core Mechanics

  • Lag as defense: A fast, erratic drone has a wide, diffuse probability field — harder to saturate. A slow Fortress shell has a tight, dense field — easier to hit precisely. Heavier shells are more durable in absolute terms but less defensible through uncertainty.
  • Uncertainty over armor: Defense is achieved by making the enemy uncertain of your position, not by absorbing damage.
  • Proximity weapons preferred: Burst fire, buckshot patterns, and explosive splash aren't a workaround for bad aim — they're the correct engineering response to operating in a probability-field environment. An HE round that detonates within kill radius of a probability cloud is the mechanically sound choice.

Lore Foundation

Operators are remote pilots running drones from underground habitation networks. The lag is diegetic: real signal travel time between the operator's console and their drone on the surface. "Uncertainty field" is the in-universe term — tactical displays show it as a rendered probability overlay, the same way radar shows a contact with an uncertainty cone. Both friendly and enemy drones show this field.


Key Learnings & Principles

  • Lag as mechanic, not flaw: Latency is diegetically justified and tactically meaningful — the UF system makes this a strategic layer, not a UX compromise
  • Compound lag model: The UF reflects both operator connection latency and in-lore drone sensor delay, keeping mechanics and lore consistent
  • Server authority is non-negotiable: Iron Shell's architecture is explicitly server-authoritative; client prediction/reconciliation flows from this
  • Uncertainty over armor: A distinctive design principle that shapes all related systems

Approach & Patterns

  • Version-controlled documents in YYMMDD-v## format for traceability
  • Synthesizes external references (tutorials, guides) into structured internal documentation
  • Makes substantive design corrections mid-session and expects full integration into outputs
  • Prefers consolidated, phase-structured technical guides as working artifacts

On the Horizon

  • Completing and validating all four PoC phases against the JP-1 server
  • Phase 03 bandwidth measurement using per-field budget table
  • Potential further iteration on UF mechanics and glass fiber terrain contamination system (progressive UF widening from battlefield contamination, inspired by modern drone warfare)
  • Ongoing document version control as design evolves

Tools & Resources

Category Details
Engine Godot 4.3+ (bundled 4.6.2 binary)
Networking ENet, RPC, UDP port 19099
Infrastructure Contabo VPS (Japan), headless export, Tailscale VPN for dev
Reference AndrooDev authority model guide, Godot multiplayer API docs

Project Structure

Iron-Shell/
├── README.md                       ← this file
├── DECISIONS.md                    ← spec ambiguities resolved
├── sync_shared.sh                  ← copies shared/ → server/ + client/
├── shared/
│   ├── config.gd                   ← all constants
│   ├── flight_motion.gd            ← pure movement math (static, no nodes)
│   ├── net_protocol.gd             ← packet pack/unpack
│   └── world_gen.gd                ← deterministic landmark placement
├── server/
│   ├── project.godot               ← headless, no rendering
│   ├── scenes/server.tscn
│   ├── scripts/server.gd           ← relay + validation gate
│   └── scripts/net_stats.gd        ← byte/packet counters
├── client/
│   ├── project.godot               ← 3D free-flight + HUD
│   ├── scenes/                     ← main.tscn, avatar.tscn, world.tscn
│   ├── scripts/                    ← net_client, local_player, remote_avatar, world, hud, main
│   └── shaders/grid.gdshader       ← world-space ground grid
├── tests/
│   ├── test_motion.gd              ← 8 unit tests (FlightMotion)
│   ├── test_bot_runner.gd          ← headless integration bot launcher
│   ├── test_bot_node.gd            ← bot flight script + assertions
│   └── run_local_test.sh           ← end-to-end test script
└── docs/
    ├── iron-shell-mvp0-godot-spec-260801-v01.md    ← build spec
    ├── iron-shell-mvp0-deploy-vpn-260801-v01.md    ← deployment plan
    └── iron-shell-concept-250403-v02.docx           ← concept document

Quick Start

# 1. Sync shared code into both projects
./sync_shared.sh

# 2. Run unit tests
godot --headless --path server/ --script res://tests/test_motion.gd

# 3. Start server
godot --headless --path server/

# 4. Connect (on same machine)
godot --path client/

Command-Line Flags

Server: --port=<n> (default 19099), --max-clients=<n> (default 8) Client: --ip=<addr> (default 127.0.0.1), --port=<n> (default 19099)


Deployment (MVP-0)

See docs/iron-shell-mvp0-deploy-vpn-260801-v01.md for the 5-stage plan:

Stage What Proves
1 Native binary, loopback client Build runs outside editor
2 Native binary, LAN client Real UDP over real NIC
3 Tailscale, one friend connects VPN transport works
4 Docker container on desktop Deployment parity with JP-1
5 Same container on Contabo JP-1 Real latency profiles

Server port: 19099 (UDP)


For Mike — Deploying

  1. Clone this repo to any Linux machine with Docker
  2. Run ./sync_shared.sh
  3. Build: godot --headless --path server/ --export-release "Linux" build/ironshell_server.x86_64
  4. docker compose up -d --build (Dockerfile + compose.yml in docs/)
  5. Server listens on UDP port 19099
  6. Friends connect with: godot --path client/ -- --ip=<server-ip> --port=19099

Open Questions

  • At what field radius does the probability cloud stop being useful tactical information and start being visual noise?
  • Should the field shape be circular (isotropic uncertainty) or directional — elongated along the drone's last known heading?
  • Phase 03 bandwidth budget: what's the minimum packet size per shell per tick at real JP-1 latency from PH?

Iron Shell — 260801-v01 — Justin Aquino