AGENTS.md is the new canonical AI-agent entry point (FIFA17 active target, repo map, FIFA23->FIFA17 pivot history). README/CLAUDE/setup.sh get stale banners pointing to it. Retained pre-existing WIP brought forward.
9.7 KiB
AGENTS.md — OpenFUT
Read this first. It is the entry point for AI-assisted work on OpenFUT. It supersedes the
root README.md and CLAUDE.md, which are stale (they describe an earlier FIFA 23 plan).
Project
OpenFUT is a preservation / private-server project that restores offline, single-player FIFA Ultimate Team (FUT) after EA retired the online servers. You must own the game legitimately; the project does not bypass ownership checks — it only re-serves the dead online services locally.
Current active target: FIFA 17 (PC). A clean-room emulation of the full online + FUT stack
was proven working end-to-end on 2026-08-01 (auth → Blaze login → device-trust → FUT hub).
This lives in fifa17-recon/. The FIFA 17 work is explicitly the Rosetta Stone for FIFA 23
(identical Blaze/LSX/UTAS wire format), so FIFA 23 remains the eventual second target.
Three moving parts, kept strictly separate:
- The FIFA client — the retail game (FIFA 17 now). Unmodified except live cert-verify patches.
- The emulation layer — Python responders in
fifa17-recon/tools/(LSX, Blaze, UTAS, roster) that impersonate EA's online services on localhost. This is where all reverse engineering lives. - OpenFUT Core — a game-independent REST FUT economy backend (
openfut-core/), feature-complete and tested. Knows nothing about FIFA. Intended to eventually back the emulation layer's FUT data.
The emulation layer and Core are not yet wired together. The FIFA 17 UTAS server currently serves its own hardcoded/JSON payloads, not Core's API. See
docs/PROJECT_STATE.md.
Repository map
Monorepo. openfut-core, openfut-bridge, openfut-launcher, fifa-blaze are git submodules
(each with independent history — use tea/Gitea, not gh). fifa17-recon/ is a plain directory.
| Path | What it is | Status |
|---|---|---|
fifa17-recon/ |
The live path. FIFA 17 offline FUT emulation: Python responders, cert patcher, runbook, RE write-ups. | Working |
openfut-core/ |
Rust (Axum + SQLite) FUT economy backend. Game-independent REST API. | Working, tested |
openfut-bridge/ |
Rust FIFA 23 in-process hook / proxy RE effort. | Blocked (see below) |
fifa-blaze/ |
Rust Blaze protocol emulator scaffold for FIFA 23 (capture stub). | Milestone 1 stub |
openfut-launcher/ |
Rust egui/eframe desktop launcher (targets FIFA 23 hook flow). | Legacy plan |
docs/ |
Mirrors of the vault (OpenFUT-Vault), which is canonical. Direction pivots + context. |
— |
tools/ |
Host-side RE helpers (file-watch-diff, exporters, squad-injector) from the FLE-bridge idea. | Legacy plan |
setup.sh |
FIFA 23 full-stack orchestrator (core+bridge). | Legacy plan |
Legacy vs live: the project pivoted twice — (1) FIFA 23 Blaze backend → (2) FIFA 23 as a match
renderer driven by an FLE Lua bridge (docs/direction.md) → (3) FIFA 17 full online emulation,
which succeeded and is now the primary path (fifa17-recon/). Treat openfut-bridge,
openfut-launcher, fifa-blaze, tools/, setup.sh, and docs/direction.md as historical unless
a task explicitly targets the FIFA 23 port.
Architecture (live path)
FIFA 17 client (Wine/Proton, base 0x140000000)
│ autopatch.py NOPs two ProtoSSL cert-verify gates in /proc/PID/mem
├─ LSX 127.0.0.1:4216 → lsx_responder_v2.py (Origin login/profile/authcode)
├─ TLS 127.0.0.1:42127 → blaze_responder_v3b.py (Blaze redirector, via DNAT of 159.153.51.20)
├─ Blaze 42130 / Nucleus 42131 → blaze_responder_v3b.py (Fire2/Heat2 binary + login)
├─ easw.easports.com (→127.0.0.1) :8099 → utas_server.py (UTAS/RS4 FUT API + device-trust)
└─ roster :8081 → roster_server.py (FUT roster-update XML)
OpenFUT Core (openfut-core, :8080) ── clean REST FUT economy ── NOT YET CONNECTED to the above
Host arming (root_arm.sh via pkexec, volatile across reboot): ptrace_scope=0,
route_localnet=1, iptables DNAT 159.153.51.20→127.0.0.1:42127, /etc/hosts easw.easports.com.
Development commands (verified)
FIFA 17 emulation (from fifa17-recon/tools/):
- Start everything (idempotent; re-run after reboot):
./openfut-fut.sh start - Status / stop / restart:
./openfut-fut.sh status | stop | restart - Then launch the game fresh (
~/Desktop/launch-fifa17.sh) and pick Ultimate Team. - Logs:
/tmp/{lsx,blaze,roster,utas,autopatch}.log - Full procedure + gate-ladder troubleshooting:
fifa17-recon/FUT-RUNBOOK.md
OpenFUT Core (from openfut-core/): cargo run (creates openfut.db) · cargo test
(full in-memory integration suite; requires data/) · cargo test <name> for one ·
cargo clippy -- -D warnings · cargo fmt. Env: LISTEN_ADDR (127.0.0.1:8080), DATABASE_URL
(sqlite://openfut.db), DATA_DIR (data).
Other Rust crates (openfut-bridge, fifa-blaze, openfut-launcher): standard
cargo run/build/test/clippy/fmt from within each. fifa-blaze is a workspace (--bin blaze-server).
CI: only openfut-core has it (.gitea/workflows/ci.yml): fmt --check, clippy -D warnings,
build --locked, test --locked on push/PR to main. No CI on the other crates or the recon dir.
There is no install step, no Docker, no JS/TS frontend, no typecheck in this repo. Do not invent them.
Coding conventions
- Rust (Core): Axum 0.7 + SQLx 0.7 (SQLite, compile-time-checked queries). Strict layering —
routes/(handlers, extract state, call services) →services/(own all DB access + logic) →models/(pureSerde/FromRowdata). Errors viaAppError(src/error.rs) withIntoResponse. One file per domain acrossroutes/,services/,models/. Single-profile design: every service reads "the active profile" as the first DB row — intentional, don't parameterize it. Content is data-driven: JSON underdata/loaded at startup into Arc registries inAppState. Add content by dropping JSON files, not code. Migrations are numbered SQL inmigrations/. Keepclippy -D warningsandfmtclean (CI enforces). - Python (recon): stdlib-only servers, no framework. Each responder is a standalone script with the reverse-engineered contract documented in its module docstring (byte offsets, VAs, symbol names). When changing a responder, preserve byte-exactness — the client is the oracle.
- Clean-room, always. Every finding derives from binaries we own + live observation. Never use, reference, or reproduce leaked EA source. If a task seems to need it, stop and say so.
AI-agent rules
- Read this file before exploring the repo.
- Read the vault file relevant to the task (
../OpenFUT-Vault/), not the whole tree. Repodocs/files are mirrors of the vault — consult them for the same content, but treat the vault as canonical. - Don't scan the whole repository unless the knowledge base is clearly stale — if you find it
stale, update the vault, then its repo
docs/mirror. - Search the specific directory (
fifa17-recon/,openfut-core/src/<layer>/) before a repo-wide search. - Update the vault when architecture materially changes (and sync the matching
docs/mirror). - Don't refactor or rewrite unrelated working code.
- Prefer small, testable changes; run the narrowest relevant test first (
cargo test <name>). - Never invent EA/FIFA/Blaze protocol behavior. Values you don't know are
TODO/CONFIRM, not confident guesses. The live client is the only oracle for whether a gate is satisfied. - Clearly separate discovered behavior from hypotheses; record findings in
../OpenFUT-Vault/02 Reverse Engineering/FIFA 17/Protocol Findings.mdunder the right confidence tier — never silently promote a hypothesis to a fact. - Root
README.md/CLAUDE.mdandopenfut-bridge/CLAUDE.mddescribe superseded FIFA 23 plans; prefer vault + repository evidence over them when they conflict.
AI Session Bootstrap
Future agents should start with:
- Read
AGENTS.md. - Read the vault README (
../OpenFUT-Vault/README.md) to locate the canonical files. - Identify the subsystem the task affects and read the corresponding vault file: Architecture, Project State, Roadmap/Current Priorities, or Protocol Findings.
- Inspect only the relevant source directories.
- Check
../OpenFUT-Vault/02 Reverse Engineering/FIFA 17/Protocol Findings.mdbefore assuming anything about FIFA/EA behavior. - Check
../OpenFUT-Vault/06 Agent Memory/Project State.mdbefore assuming a feature exists. - Implement the smallest coherent change.
- Run the narrowest relevant tests.
- Update the vault (and its repo
docs/mirror) only if the change makes existing knowledge inaccurate.
Do not reread the entire repository during every session.
OpenFUT Knowledge Base
The OpenFUT Vault is the canonical project knowledge base. Repo docs/ files mirror it; the
vault wins on any disagreement. Consult it before starting substantial work and update it after
durable discoveries.
Vault location: ../OpenFUT-Vault/ — start at ../OpenFUT-Vault/README.md.
Canonical files:
- Dashboard:
00 Dashboard/OpenFUT.md - Architecture:
01 Architecture/Architecture.md(repo mirrordocs/ARCHITECTURE.md) - RE findings:
02 Reverse Engineering/FIFA 17/Protocol Findings.md(repo mirrordocs/research/KNOWN_FINDINGS.md) - Direction history:
04 Decisions/Direction History.md - Project State:
06 Agent Memory/Project State.md(repo mirrordocs/PROJECT_STATE.md) - Current Priorities:
06 Agent Memory/Current Priorities.md - Known Issues:
06 Agent Memory/Known Issues.md - Important Discoveries:
06 Agent Memory/Important Discoveries.md - Roadmap:
08 Roadmap/Roadmap.md(repo mirrordocs/ROADMAP.md)
When editing knowledge that exists in both places, edit the vault first, then update the matching
docs/ mirror so they stay in sync.