Files
OpenFUT/docs/fut-integration-options.md
funman300 1fb664710a docs: add FLE bridge direction pivot and squad-injection test tooling
Adds the app-centric FLE bridge direction (direction.md) replacing the
Blaze-backend route as primary plan, plus a corrected foundational test
procedure and snapshot/diff/apply tooling for reverse-engineering FLE's
Freeze Lineup write mechanism. Also picks up prior untracked research docs
(status-review, fut-integration-options, fifa23-startup-flow, track-c) and
existing capture/export tooling that hadn't been committed yet.
2026-06-30 13:19:27 -07:00

5.7 KiB

FUT Integration Options

How to connect FIFA 23 to the OpenFUT local simulator, ranked by safety and feasibility.

What it does: Use FIFA Live Editor's in-memory Lua API to read and write the game's database tables at runtime. FLE is already injected; no additional hooking needed.

Why it's the right path:

  • Fully offline, no EA servers touched
  • FLE is already trusted by the user (it's the launch mechanism)
  • GetDBTableRows / EditDBTableField expose the full Frostbite DB in memory
  • Scripts run inside the game process; no IPC complexity
  • Same mechanism used by modders for career mode edits today

Integration design:

openfut-core (SQLite)
      │
      │  HTTP REST (localhost)
      ▼
openfut-bridge (port 8080, plain HTTP, no TLS)
      │  pulls club/squad/player data as JSON
      ▼
FLE Lua bridge script
      │  calls GetDBTableRows, EditDBTableField
      ▼
FIFA 23 in-memory DB (Frostbite)

The Lua script polls openfut-core's REST API at intervals (or on FUT menu entry) and writes simulator data (coins, items, squad) into the appropriate DB tables.

Tables likely involved (to verify with export_squad.lua):

Table Expected FUT content
players Player attributes (OVR, potential, stats)
teams Club identity, stadium, colors
fut_clubs FUT club record (if in memory when FUT loads)
fut_items Card inventory (if in memory)
fut_squads Active squad (if in memory)

Steps to implement:

  1. Run tools/squad-exporter/export_squad.lua from FLE Lua Engine while in FUT to discover which tables are live
  2. Map openfut-core's data model to the discovered table fields
  3. Write a Lua polling script that fetches /api/v1/club, /api/v1/squad, etc. from openfut-core and calls EditDBTableField to populate them
  4. Optionally add a small HTTP client to the Lua script using LuaSocket (FLE ships with Lua 5.4)

Limitations:

  • Changes are in-memory only; they reset on game restart (acceptable for a simulator)
  • Only works while FLE is running (always true in our setup)
  • FUT tables may only be populated when the FUT hub is loaded; test with the exporter

Option B — Local save file injection (career mode proxy)

What it does: Generate or modify offline career mode save files that contain FUT-like squad/player data, using Frostbite's FBCHUNKS format.

Feasibility: Medium

  • FBCHUNKS format is not publicly documented but has been partially reverse-engineered by the Frosty Tool Suite project
  • Career saves are 16 MB — large and complex
  • Changes take effect only after a game restart

Best use: Pre-populating a career club with the same players as the FUT simulator squad, so offline Squad Battles use "your" players.

Steps:

  1. Use Frosty Tool Suite to open a career save and map the schema
  2. Build a Python exporter that writes a valid FBCHUNKS save with simulator squad data
  3. Test: replace the career save, launch FIFA, verify squad is correct

Option C — Local companion web UI

What it does: The user manages their FUT simulator entirely in a web browser (openfut-core already has this). A button exports the current squad/club state to a format that a Lua script or file injector can consume.

This is already implemented — openfut-core serves the FUT simulator REST API. The missing piece is the Lua bridge script (Option A) that reads from it.


Option D — Local proxy for non-secured local calls only

What it does: Intercept FIFA 23's calls to localhost:* or a known local endpoint (not EA servers) and respond with simulator data.

Feasibility: Low value in isolation

  • FIFA 23 does not make calls to localhost in normal operation (except EA App on port 10853)
  • All FUT API calls go to EA's servers over TLS
  • Intercepting those would require the approach we explicitly ruled out

Not recommended as a primary path. Could be combined with Option A if the Lua script exposes a local socket that a coordinator process writes to.


Option E — Memory bridge (Cheat Engine / FLE offsets)

What it does: Use known memory offsets (FLE's offset_cache.json) to read/write FUT state directly in FIFA23.exe's heap.

Feasibility: Medium — FLE already does this for career mode

  • FLE's offset_cache.json contains addresses for many game structures
  • FUT in-memory structs are separate from career structs and may not be mapped yet
  • This is fragile (offsets change with game updates)

Not recommended unless Options A and B both fail — too brittle.


Recommendation

Start with Option A (FLE Lua scripting).

  1. Run tools/squad-exporter/export_squad.lua in-game to discover which DB tables exist in FUT mode
  2. Use tools/file-watch-diff/watch.sh to snapshot file state entering FUT and identify any new local files
  3. Use tools/network-metadata-logger/netlog.sh to log which EA hosts FIFA contacts at FUT entry (metadata only, no decryption)
  4. Map findings back to openfut-core's data model
  5. Implement the Lua bridge script that calls openfut-core's REST API and writes to discovered tables

If FUT tables are not exposed by FLE's DB API (they may not be — FUT data lives server-side in online mode), fall back to Option B (career save injection) to provide a squad that mirrors the simulator's club.


Safety boundary

The following are out of scope and must not be implemented:

  • Decrypting or inspecting EA's TLS traffic
  • Spoofing EA domain names or impersonating EA servers
  • Sending modified clients to EA's production services
  • Bypassing EA App login or account verification
  • Anything that could constitute online cheating or violate EA's ToS for online play

All integration must remain local/offline/single-player.