Files
OpenFUT/AGENTS.md
T
funman300 d71234b03d docs: add AGENTS.md canonical entry point; mark FIFA23 README/CLAUDE/setup stale
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.
2026-08-20 16:06:28 +00:00

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/ (pure Serde/FromRow data). Errors via AppError (src/error.rs) with IntoResponse. One file per domain across routes/, 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 under data/ loaded at startup into Arc registries in AppState. Add content by dropping JSON files, not code. Migrations are numbered SQL in migrations/. Keep clippy -D warnings and fmt clean (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

  1. Read this file before exploring the repo.
  2. Read the vault file relevant to the task (../OpenFUT-Vault/), not the whole tree. Repo docs/ files are mirrors of the vault — consult them for the same content, but treat the vault as canonical.
  3. 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.
  4. Search the specific directory (fifa17-recon/, openfut-core/src/<layer>/) before a repo-wide search.
  5. Update the vault when architecture materially changes (and sync the matching docs/ mirror).
  6. Don't refactor or rewrite unrelated working code.
  7. Prefer small, testable changes; run the narrowest relevant test first (cargo test <name>).
  8. 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.
  9. Clearly separate discovered behavior from hypotheses; record findings in ../OpenFUT-Vault/02 Reverse Engineering/FIFA 17/Protocol Findings.md under the right confidence tier — never silently promote a hypothesis to a fact.
  10. Root README.md / CLAUDE.md and openfut-bridge/CLAUDE.md describe superseded FIFA 23 plans; prefer vault + repository evidence over them when they conflict.

AI Session Bootstrap

Future agents should start with:

  1. Read AGENTS.md.
  2. Read the vault README (../OpenFUT-Vault/README.md) to locate the canonical files.
  3. Identify the subsystem the task affects and read the corresponding vault file: Architecture, Project State, Roadmap/Current Priorities, or Protocol Findings.
  4. Inspect only the relevant source directories.
  5. Check ../OpenFUT-Vault/02 Reverse Engineering/FIFA 17/Protocol Findings.md before assuming anything about FIFA/EA behavior.
  6. Check ../OpenFUT-Vault/06 Agent Memory/Project State.md before assuming a feature exists.
  7. Implement the smallest coherent change.
  8. Run the narrowest relevant tests.
  9. 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 mirror docs/ARCHITECTURE.md)
  • RE findings: 02 Reverse Engineering/FIFA 17/Protocol Findings.md (repo mirror docs/research/KNOWN_FINDINGS.md)
  • Direction history: 04 Decisions/Direction History.md
  • Project State: 06 Agent Memory/Project State.md (repo mirror docs/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 mirror docs/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.