6.6 KiB
Architecture Overview
High-level picture of Flying Jib. For deep detail see developer_docs/ARCHITECTURE.md.
Update this file whenever the design changes (same PR as code/ADRs).
Last updated: 2026-07-31
Design name: Local Authority + Capability Tunnel + Federated Regions
Runtime: Bare / Pear only (ADR-0013)
Product shell: Pear desktop GUI primary (ADR-0014); Bare CLI secondary
Mesh status: Registry + border migrate + inventory handoff + dual-Squid e2e + offline UX
Security: Invite TTL (default 7d), role hint, cap rotate + revoke ledger, log redaction
Goals (non-negotiable)
- Never master/central game servers we operate.
- Every participant runs a local Minecraft server (Flying Squid) on
127.0.0.1only. - Users launch a single Bare/Pear distributable — no system Node.js, no Node child process for Squid.
- Worlds are private (capability invite) or enrolled into a mesh of linked regions.
- Discovery and transport use Hyperswarm / HyperDHT only (public DHT bootstrap nodes are infrastructure, not app control planes).
- CI releases produce single standalone executables (
bare-build --standalone) plus Pear app-drive OTA (stage/seed/provision/multisig).
System diagram
flowchart TB
Java["Java Edition Client"]
Java -->|"TCP MC protocol<br/>localhost only"| Loop["127.0.0.1:25565"]
subgraph FJ["Flying Jib — single Bare / Pear app"]
direction TB
Main["Main Bare<br/>CLI / UI / lifecycle"]
Worker["Worker Bare + pear-runtime<br/>Hyperswarm / HyperDHT<br/>Protomux / Autobase / OTA"]
Squid["Flying Squid in Bare<br/>host 127.0.0.1 only<br/>Anvil on disk"]
Tunnel["World Tunnel HyperDHT<br/>byte pipe to local MC port"]
Main <-->|"framed IPC"| Worker
Main -->|"createMCServer<br/>bare-node-runtime"| Squid
Worker --> Tunnel
Tunnel <-->|"pipe"| Squid
end
Loop --> Squid
Peers["Other peers<br/>same Bare architecture"]
Peers <-->|"Noise / secretstream<br/>no app matchmaking"| Tunnel
Design pillars
0. Bare/Pear-only runtime (ADR-0013)
- Production code runs on Bare.
- Flying Squid loads under
bare-node-runtime(Node API → Bare modules), notnodesubprocess. - Release:
hello-pear-barepatterns +bare-build --standalone+ Pear deploy layers. - Electron Forge is not the default distribution path.
1. Local authority
Each peer’s Squid is authoritative for its world/region. There is no global block database and no single simulation spanning the mesh.
2. Capability tunnel (private worlds)
- Host listens on HyperDHT with a world keypair.
- Remote peers connect with an invite (
fj1.…) and get a TCP byte pipe to the host’s loopback Squid. - Invites default to 7-day TTL; host may
rotate-cap(new shared secret, same world key) to invalidate outstanding invites. - Java clients on every machine still only talk to their own localhost.
3. Federated regions (mesh)
- Peers enroll regions into a mesh registry (Autobase + Hyperbee view).
- Each region has bounds/offset, tunnel key + cap, seed metadata.
- Crossing a border migrates the player session to the neighbor’s Squid:
- Capture inventory/state (
lib/player-handoff.js) - Protomux
migratefirst; kick delayed ~1.2s - Guest tunnel retarget (prefer same localhost port) + reconnect banner
- Guest
handoff-apply→ neighbor applies onspawned
- Capture inventory/state (
- Offline neighbor: clear UX, restore previous tunnel, stash handoff — never fail over to a master (
lib/migrate.js).
4. Side-channel communication
Chat and presence use Protomux over Hyperswarm/DHT streams.
Process model
| Role | Runtime | Responsibility |
|---|---|---|
| Main entry | Bare | CLI/UI host, lifecycle, config |
| Worker | Bare + pear-runtime | P2P, tunnels, Autobase, OTA |
| Squid | Bare (+ bare-node-runtime) | MC simulation, Anvil, 127.0.0.1 |
flowchart LR
Main["Main Bare<br/>CLI / UI / lifecycle"]
Worker["Worker Bare<br/>pear-runtime / P2P / OTA"]
Squid["Squid Bare<br/>MC + Anvil loopback"]
Main <-->|"IPC"| Worker
Main --> Squid
Distribution model
| Artifact | Tooling |
|---|---|
| Standalone binary per OS/arch | scripts/bare-standalone.cjs (bare-pack + embed) |
| CI matrix | GitHub Actions: linux-x64, linux-arm64 (pack), darwin-arm64, win32-x64 |
| P2P OTA app drive | pear stage → seed → provision → multisig (Planned full verify) |
| Upgrade channel | pear link in app metadata (upgrade) |
flowchart LR
Source[Source tree] --> Pack["bare-pack / bare-standalone"]
Pack --> Bin["Standalone executable<br/>per host"]
Pack --> Stage[pear stage]
Stage --> Seed[pear seed]
Seed --> Prov[provision]
Prov --> Multi[multisig]
Multi --> OTA["pear-runtime OTA<br/>in running Bare app"]
Users never install Node.js to play.
Data at rest (sketch)
flowchart TB
Root["APP_STORAGE"]
Root --> CS[corestore]
Root --> ID[identity]
Root --> Worlds[worlds]
Root --> Mesh[mesh]
Root --> Inv[invites]
Worlds --> W1["worldId"]
W1 --> Anvil[anvil]
W1 --> Meta[meta.json]
W1 --> Secrets["tunnel.json / revocations"]
Mesh --> M1["meshId"]
What we explicitly do not build
- Central matchmaking or “master mesh node”
- Fully replicated global voxel array
- Single authoritative multi-peer tick across all regions
- Public Minecraft TCP listen on WAN interfaces
- System Node.js or Node child process as app runtime
- Electron Forge as the primary shipping vehicle (optional experiment only with ADR)
Related ADRs
- 0013 Bare/Pear only ← runtime & release
- 0014 Pear GUI primary ← product shell
- 0002 Flying Squid on Bare
- 0003 P2P stack
- 0004 — superseded by 0013
- 0005 Local bind
- 0006 Tunnel
- 0007 Region registry
- 0008 Border migration
- 0011 — superseded primary path by 0013