11 KiB
Flying Jib
Fully decentralized peer-to-peer Minecraft — no master servers, ever.
NOTE: THIS REPO IS NOT YET READY TO BE USED! THIS NOTICE WILL BE REMOVED WHEN TESTING MAY HAPPEN
Flying Jib is a Bare/Pear application that runs Flying Squid inside Bare (via bare-node-runtime), bound only to 127.0.0.1. Friends join through encrypted Holepunch tunnels. Worlds stay private (capability invites) or enroll into a federated mesh of linked regions with border migration and inventory handoff.
| Version | 0.1.0 |
| License | Apache-2.0 |
| Runtime | Bare / Pear only — end users do not install Node.js (ADR-0013) |
| Product shell | Pear desktop GUI primary (ADR-0014); Bare CLI secondary |
| Default MC | Flying Squid 1.21.1 (Java Edition) |
| Status | Phases 1–5 core; Phase 6 Pear GUI in progress |
Living truth: living_docs/CURRENT_STATUS.md · living_docs/ROADMAP.md
Why “Flying Jib”?
A flying jib is a sail that works with the main sail — not above it as a master. Each peer runs its own local server; the mesh is coordination among equals, never a company-operated game server.
What works today
| Area | Status |
|---|---|
Pear desktop GUI (npm start / pear run) |
Scaffolded (host / join / worlds MVP) |
Local Flying Squid on 127.0.0.1 |
Working |
Private worlds (host / join HyperDHT tunnel + fj1. invites) |
Working |
| Invite TTL (default 7 days), role hint, mint / rotate / revoke | Working |
Side-channel chat + presence (/peers) |
Working |
| Mesh registry (Autobase), border migrate, inventory handoff (anti-dupe) | Working |
| Soft-reconnect banners / stable localhost port on migrate | Working |
| Standalone CLI binary (~151 MiB default prune; ~98 MiB minimal) | Working |
Gitea rolling release (RELEASE_TOKEN) + GitHub integrate CI |
Wired |
| Threat model + playtest runbook | Written |
| Automated tests | npm test |
Not done yet: live Pear seed with real multisig keys, full GUI, enforced viewer ACL, two-machine Java playtest sign-off.
Architecture (one paragraph)
Java Edition always connects to localhost. The Bare app owns Squid’s lifecycle and a HyperDHT byte-pipe tunnel for remote peers (capability header on the stream). Mesh membership uses Autobase + Hyperbee; borders use session migration and inventory handoff — not a global voxel CRDT. Runtime is Bare + pear-runtime only. Stack: Hyperswarm, HyperDHT, Protomux, Corestore, Flying Squid / Prismarine.
flowchart LR
Java[Java Edition] --> Local["127.0.0.1:port"]
Local --> Squid["Flying Squid in Bare"]
Squid <-->|"HyperDHT tunnel Noise"| Peers["Remote peers<br/>same architecture"]
Deep dive: living_docs/ARCHITECTURE_OVERVIEW.md · developer_docs/ARCHITECTURE.md
Quick start (developers)
git clone <this-repo>
cd flying-jib
npm install
# Primary — Pear desktop GUI
npm start # pear run -d .
# Secondary — Bare CLI
npm run start:cli -- create home
npm run start:cli -- host home --port 25565 --name Alice
# → fj1.… invite; Java Edition → 127.0.0.1:25565
npm run start:cli -- --storage /tmp/fj-b join 'fj1.…' --name Bob
Mesh border (two regions)
BARE=./node_modules/bare-runtime/bin/bare
# Host A — create mesh + enroll bounds
$BARE bin.mjs --storage /tmp/fj-a host west --mesh \
--min-x 0 --max-x 99 --min-z 0 --max-z 99 \
--mc-name Steve --name Alice
# Host B — join mesh invite + enroll adjacent region
$BARE bin.mjs --storage /tmp/fj-b host east --mesh-invite 'fj1.…' \
--min-x 100 --max-x 199 --min-z 0 --max-z 99 \
--mc-name Alex --name Bob
Guest joins a world invite; crossing the border kicks with reconnect instructions, retargets the tunnel, and applies inventory handoff. Manual scenarios: developer_docs/PLAYTEST.md.
CLI reference
Global flags: --storage <dir>, --version / -v, --help / -h.
| Command | Purpose |
|---|---|
create <name> |
Create a local world under storage |
list |
List worlds |
start <name> |
Local Squid only (no P2P share) |
host <name> |
Squid + HyperDHT share; print fj1. invite |
join <invite> |
Guest tunnel to a private world |
invite <name> |
Mint invite without starting Squid (default TTL 7d) |
rotate-cap <name> |
New tunnel capability — invalidates outstanding invites |
revoke <name> <cap-or-invite> |
Audit fingerprint on local revoke ledger |
status |
Storage path, worlds, meshes |
mesh-create / mesh-open / mesh-admit / mesh-enroll / mesh-list |
Mesh registry CLI |
Useful host / invite flags: --ttl 24h, --no-expire, --role player|viewer, --mesh, --mesh-invite, --mc-name, --name (chat display).
Invites are secrets. Prefer short TTL for events; after a leak run rotate-cap then mint a new invite. Details: user_docs/INVITES_AND_CAPABILITIES.md.
Standalone binary (no Node on PATH)
npm run make:standalone # current host → out/flying-jib-<host>/flying-jib
npm run make:standalone:all # all supported 64-bit hosts
npm run size:report # artifact sizes + prune guidance
# Slimmer pack (default MC version only)
FJ_MC_DATA_MINIMAL=1 npm run make:standalone
# Smoke without system Node
env -i PATH=/usr/bin:/bin HOME="$HOME" TMPDIR=/tmp \
./out/flying-jib-darwin-arm64/flying-jib --storage /tmp/fj-smoke create demo
| Pack mode | Approx size (darwin-arm64) |
|---|---|
Unpruned (full PC + bedrock minecraft-data) |
~498 MiB |
| Default prune (Squid PC versions, no bedrock) | ~151 MiB |
Minimal (FJ_MC_DATA_MINIMAL=1 → 1.21.1) |
~98 MiB |
Packer: scripts/bare-standalone.cjs (peardock-style bare-pack + imports). Release notes: developer_docs/BUILD_AND_RELEASE.md.
Tests & quality gates
npm test # brittle-node, full suite
npm run test:bare # when bare test runner is available
npm run docs:check # scaffold paths present
npm run pear:check # Pear OTA config structure (placeholders OK)
npm run pear:check:strict
npm run license:check # ADR-0012: no AGPL/SSPL/holesail
CI (.github/workflows/integrate.yml): unit tests + docs + pear/license checks, then standalone matrix (linux-x64, linux-arm64 pack, darwin-arm64, win32-x64) with create/list smoke where native.
Non-negotiables
- No central/master game servers or company matchmaking control planes
- Minecraft TCP only on
127.0.0.1(bind-guard + tests) - Bare/Pear only — no system Node for the product; no Node child for Squid
- CI product: single standalone executables + Pear stage/seed OTA
- Documentation updated with every significant change
- ADRs before architecture / protocol / security model changes
- Apache-2.0 — no AGPL hard dependencies (in-house HyperDHT tunnel, not Holesail)
See agent/RULES.md and agent/SECURITY.md.
Roadmap (summary)
| Phase | Focus | Status |
|---|---|---|
| 0 | Research, ADRs, docs/agent scaffold | Done |
| 1 | Bare shell + Squid on loopback | Core done (graceful stop polish open) |
| 2 | Private worlds via HyperDHT + fj1. |
Core done (two-machine Java playtest open) |
| 3 | Presence + side-channel chat | CLI done (GUI planned) |
| 4 | Mesh registry + border migrate + handoff | Core done |
| 5 | Security, standalone CI, Pear OTA, polish | In progress |
Full checklist: living_docs/ROADMAP.md.
Documentation map
| Tree | Audience |
|---|---|
| living_docs/ | Current truth — status, roadmap, progress, changelog, open questions |
| user_docs/ | Players — getting started, private worlds, invites, mesh, FAQ |
| developer_docs/ | Contributors — setup, architecture, protocol, modules, testing, playtest, release |
| agent/ | Humans & AI — rules, workflow, security, ADRs |
Recommended reading order
- living_docs/CURRENT_STATUS.md
- user_docs/GETTING_STARTED.md / PRIVATE_WORLDS.md
- agent/ADRs/0013-bare-pear-only-runtime-and-distribution.md
- developer_docs/PROTOCOL.md · PLAYTEST.md
- developer_docs/security/THREAT_MODEL.md
Project layout (high level)
flowchart TB
Root[flying-jib]
Root --> Bin["bin.mjs — CLI Bare"]
Root --> App["app.js — lifecycle"]
Root --> Lib["lib/ — tunnel invite mesh handoff"]
Root --> Plugins["plugins/ — bind-guard mesh-border"]
Root --> Scripts["scripts/ — pack prune checks"]
Root --> Test[test/]
Root --> Living[living_docs/]
Root --> Dev[developer_docs/]
Root --> User[user_docs/]
Root --> Agent[agent/]
Security snapshot
- Invites (
fj1.…), tunnel seeds, and caps are secrets — do not commit them or paste them into public logs - Default invite lifetime: 7 days;
rotate-capinvalidates outstanding private invites - Minecraft is never intentionally exposed on
0.0.0.0 - Dependency license gate:
npm run license:check - Threat model: developer_docs/security/THREAT_MODEL.md
Contributing
- Read agent/RULES.md and agent/WORKFLOW.md
- Prefer small PRs with tests + doc updates in the same change (agent/DOCUMENTATION_POLICY.md)
- Architecture changes need an ADR under agent/ADRs/
- Setup details: developer_docs/SETUP.md · CONTRIBUTING.md
License
Flying Squid and Prismarine remain under their upstream licenses; Holepunch modules under theirs. This project does not hard-depend on AGPL networking stacks (e.g. Holesail).