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.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# Foundational test — live custom XI via Freeze Lineup
|
||||
|
||||
**Status: PENDING — test has not yet been run.**
|
||||
|
||||
This is build-order step 1 from `docs/direction.md`: the test everything else
|
||||
in the direction pivot depends on.
|
||||
|
||||
## What changed since the first draft of this doc
|
||||
|
||||
The first version of this test guessed at a "selection bias" DB field and a
|
||||
candidate squad/lineup table name, based on general FIFA-modding precedent
|
||||
that turned out not to hold for FLE's documented API — no such field appears
|
||||
anywhere in FLE's actual Lua API docs or its own example scripts. While
|
||||
researching an unrelated hotkey issue, a **confirmed, FLE-documented**
|
||||
mechanism for forcing a starting XI turned up instead: the **Formation
|
||||
Editor's "Freeze Lineup" feature** (FLE wiki, `Formation-Editor.md`):
|
||||
|
||||
> This feature can be used in player career mode if you want to manage the
|
||||
> starting lineup of your team. Can be also used in manager career mode to
|
||||
> manually manage your next opponent's starting lineup.
|
||||
|
||||
Steps (GUI, no scripting): open Formation Editor for a team → arrange players
|
||||
on the pitch → tick **Freeze Lineup** → `Data → Save`.
|
||||
|
||||
This is real and documented, but it's GUI-only — there is no Lua function for
|
||||
it, and what DB write it actually performs under the hood is undocumented.
|
||||
This test is now two phases: confirm the GUI feature works at all, then
|
||||
reverse the DB write it makes so it can be replicated programmatically
|
||||
(required for the app→game bridge in build-order step 2, which needs this
|
||||
driven from outside the game, not from a person clicking checkboxes).
|
||||
|
||||
Also fixed in this pass: `EditDBTableField`'s real signature, confirmed from
|
||||
FLE's own docs and `lua/scripts/99ovr_99pot.lua`, is
|
||||
`EditDBTableField(cell)` where `cell` is `row["fieldname"]` with `.value`
|
||||
mutated in place — **not** `EditDBTableField(table, row_index, field, value)`
|
||||
as originally (incorrectly) written into the first draft of the injector
|
||||
script.
|
||||
|
||||
## What this test settles
|
||||
|
||||
Whether a *specific, externally-chosen* 11 players can be forced into a
|
||||
career (or Kick-Off) match's starting lineup, live, with no restart — and
|
||||
whether the mechanism that does it (Freeze Lineup's underlying DB write) can
|
||||
be driven by a script instead of a person clicking through the Formation
|
||||
Editor UI.
|
||||
|
||||
If Freeze Lineup itself doesn't actually hold under match start (the wiki
|
||||
doesn't show it being tested against a live match, only "you should be able
|
||||
to see... when you play against them"), the whole bridge architecture in
|
||||
`docs/direction.md` §3 needs rethinking — there is no other documented
|
||||
mechanism for forcing a lineup.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- FIFA 23 launched normally (FLE injected, EAAC neutralized — same baseline
|
||||
as `track-c-fut-table-test.md`)
|
||||
- A career save loaded (Freeze Lineup is documented for career mode
|
||||
specifically — confirm separately whether it does anything in Kick-Off,
|
||||
don't assume it does)
|
||||
- Note 11 player IDs from your club (`tools/squad-exporter/export_squad.lua`
|
||||
output, `playerid` field) that are NOT currently your starting XI
|
||||
|
||||
## Phase 1 — confirm Freeze Lineup actually holds into a match
|
||||
|
||||
This has zero scripting and should be done first since everything else is
|
||||
wasted effort if it fails.
|
||||
|
||||
1. Open the Live Editor overlay (F9, or `Windows → Settings` from the
|
||||
overlay's own menu bar if the hotkey isn't registering — see the umu/Wine
|
||||
hotkey note below).
|
||||
2. `Features → Teams` → find your team → `Edit`.
|
||||
3. `Team → Formation` to open the Formation Editor.
|
||||
4. Swap players around on the pitch so the XI differs from your current
|
||||
actual starting XI in some checkable way (e.g. swap two outfield players'
|
||||
positions, or bench/start a specific player).
|
||||
5. Tick **Freeze Lineup**.
|
||||
6. `Data → Save`.
|
||||
7. Hide Live Editor (F9), save your career **on a new slot** (don't overwrite
|
||||
your main save in case this corrupts something), exit to main menu, reload
|
||||
that save, and check the team's lineup screen / play a match and watch who
|
||||
starts.
|
||||
|
||||
**Record in the Results table below whether the frozen lineup actually took
|
||||
the pitch.** If not, stop here — Phase 2 is moot.
|
||||
|
||||
## Phase 2 — find the underlying DB write
|
||||
|
||||
Only proceed if Phase 1 confirmed Freeze Lineup works.
|
||||
|
||||
1. In FLE's Lua Engine, run `tools/squad-injector/snapshot_lineup_tables.lua`.
|
||||
This dumps every DB table whose name contains `squad`, `lineup`,
|
||||
`formation`, `tactic`, `teamsheet`, `selection`, `players`, or `teams` to
|
||||
`C:\FIFA 23 Live Editor\openfut_snapshot_<timestamp>.json`. Note this
|
||||
filename — this is your **before** snapshot.
|
||||
2. Without restarting or reloading, repeat the Formation Editor steps from
|
||||
Phase 1 (steps 2–6 only — open Formation Editor, change the lineup, tick
|
||||
Freeze Lineup, `Data → Save`). Don't save/reload the career between
|
||||
snapshot and this step — keep it to a single live session so the diff
|
||||
isn't polluted by other state changes.
|
||||
3. Run `snapshot_lineup_tables.lua` again. This is your **after** snapshot.
|
||||
4. Copy both JSON files out of the Wine prefix (same path pattern as
|
||||
`track-c-fut-table-test.md`: `~/Games/umu/.../drive_c/FIFA 23 Live
|
||||
Editor/`) and run:
|
||||
|
||||
```bash
|
||||
python3 tools/squad-injector/diff_snapshots.py before.json after.json
|
||||
```
|
||||
|
||||
5. The output shows exactly which table(s) and field(s) changed. This is the
|
||||
real, confirmed write Freeze Lineup performs — record it in the Results
|
||||
table below.
|
||||
|
||||
## Phase 3 — replicate the write via script
|
||||
|
||||
1. Open `tools/squad-injector/apply_lineup_write.lua` and fill in
|
||||
`TARGET_TABLE` and `TARGET_FIELDS` using Phase 2's diff output.
|
||||
2. Edit `C:\FIFA 23 Live Editor\openfut_test_xi.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"team_id": 12345,
|
||||
"xi": [
|
||||
{ "player_id": 111111, "position": 0 },
|
||||
{ "player_id": 222222, "position": 5 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Use 11 entries. Position codes are **confirmed numeric 0–27**
|
||||
(`GK=0, SW=1, RWB=2, RB=3, RCB=4, CB=5, LCB=6, LB=7, LWB=8, RDM=9, CDM=10,
|
||||
LDM=11, RM=12, RCM=13, CM=14, LCM=15, LM=16, RAM=17, CAM=18, LAM=19,
|
||||
RF=20, CF=21, LF=22, RW=23, RS=24, ST=25, LS=26, LW=27`) — from
|
||||
`lua/scripts/export_season_stats.lua`'s `get_pos_name` table in FLE's own
|
||||
repo, not a guess.
|
||||
3. Run `apply_lineup_write.lua` from FLE's Lua Engine.
|
||||
4. Repeat the save-to-new-slot / reload / check-lineup verification from
|
||||
Phase 1, but this time without ever opening the Formation Editor — the
|
||||
write was made entirely from the script.
|
||||
|
||||
## Classification criteria
|
||||
|
||||
### "Confirmed — full mechanism works"
|
||||
|
||||
Phase 1 holds, Phase 2 finds a clean diff, Phase 3's scripted write produces
|
||||
the same in-match result as the manual GUI path.
|
||||
|
||||
**Verdict:** Build-order step 1 done. Proceed to step 2 (bridge transport) in
|
||||
`docs/direction.md`.
|
||||
|
||||
### "GUI works, script doesn't"
|
||||
|
||||
Phase 1 holds but Phase 3's replicated write doesn't stick, even though the
|
||||
diffed fields matched what changed in Phase 2.
|
||||
|
||||
**Verdict:** Freeze Lineup likely does more than a single DB field write
|
||||
(e.g. an internal engine call beyond `EditDBTableField`'s reach, or a second
|
||||
write the diff missed because it happened in a table outside the `KEYWORDS`
|
||||
filter in `snapshot_lineup_tables.lua` — widen the filter and redo Phase 2).
|
||||
|
||||
### "Freeze Lineup doesn't hold at all"
|
||||
|
||||
Phase 1 fails — the lineup reverts to the game's own AI-picked XI regardless.
|
||||
|
||||
**Verdict:** No confirmed mechanism exists for forcing a lineup. This kills
|
||||
the bridge architecture as designed in `direction.md` §3 and needs a return
|
||||
to first principles — there is no fallback documented anywhere in FLE's wiki
|
||||
for this specific case.
|
||||
|
||||
## A note on the umu/Wine F9/F11 hotkey issue
|
||||
|
||||
If FLE's F9 (hide/show) hotkey isn't registering under umu, this is plausibly
|
||||
a Wine keyboard-hook limitation (FLE's global hotkey detection likely uses a
|
||||
low-level hook that doesn't translate cleanly through Wine's input layer) —
|
||||
not something documented anywhere in FLE's own troubleshooting docs, which
|
||||
don't mention Linux/Wine at all. F11 specifically has **no documented FLE
|
||||
function** — F9 is the only documented toggle. Workaround: click directly
|
||||
into the FLE overlay window (it should still be visible/clickable even if the
|
||||
hotkey doesn't fire) and use its own menu bar instead of relying on the
|
||||
hotkey.
|
||||
|
||||
## Results
|
||||
|
||||
*(To be filled in after the test is run.)*
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Date run | — |
|
||||
| Phase 1: Freeze Lineup holds into a match? | — |
|
||||
| Phase 2: table(s)/field(s) changed | — |
|
||||
| Phase 3: scripted write reproduces Phase 1 result? | — |
|
||||
| **Classification** | **PENDING** |
|
||||
Reference in New Issue
Block a user