diff --git a/docs/CARD_TAXONOMY.md b/docs/CARD_TAXONOMY.md new file mode 100644 index 0000000..17e867a --- /dev/null +++ b/docs/CARD_TAXONOMY.md @@ -0,0 +1,142 @@ +# FIFA 17 FUT — Card Taxonomy (single source of truth) + +Status: verified 2026-08-12. This document supersedes every earlier scattered +taxonomy claim in the repo (see "Superseded taxonomy" at the bottom). + +Evidence labels: **OBSERVED** = read directly from a shipped table or decompiled +function; **INFERRED** = derived from OBSERVED facts; **HYPOTHESIS** = plausible, +not yet proven. `UNKNOWN` is a valid answer and is stated as such. + +## Provenance + +- Authoritative tables: `10.10.0.105:/home/alex/Documents/OpenFUT/fifa17-recon/data/tables/`, + copied byte-identical into this repo at `fifa17-recon/data/tables/`. + SHA-256 manifest + verification: `docs/evidence/fifa17-recon/table-hashes.sha256` + (36 files: 31 `fcc_*.json` + 5 staff tables; combined hash-of-hashes + `10f239add919089354d8dbff873fc9737b0a0f80f6ac41b1aa2a096c0ec8d331`). +- Each table file is a DECODED dump `{table, source, rowcount, schema[], rows[]}`; + card instances are in `rows[]`, one object per card. Row counts and id ranges + below were re-extracted from the in-repo `.120` copies. +- Semantic (subtype→kind) labels are decompiler-derived, carried in + `fifa17-recon/tools/fut_consumables.py` (`BY_SUBTYPE`, `_DOC`), generated by + `tools/build_consumables.py` from `FUN_1800d8330`, `FUN_18013f4d0`, + `FUN_1801bfac0`, `FUN_1801aa230`, `FUN_180048780` + the fcc tables. +- Staff family selection: `fifa17-recon/docs/CARD_SYSTEM.md` (2026-08-04/05 blocks) + and `fifa17-recon/tools/fut_staff.py` / `fut_coaches.py`. + +## Family selector (OBSERVED, binary) + +Before registering an item, `FUN_180141660` merges the client's local DB. It +switches on record `+0x4c` (`cardtype`), which `FUN_1800d8330` derives from JSON +atom `0x6c cardsubtypeid` alone: + +``` +cardsubtypeid 0..3 -> cardtype 1 players + 4 -> cardtype 2 managercards + 5 -> cardtype 3 headcoachcards + 6 -> cardtype 10 gkcoachcards + 7 -> cardtype 5 physiocards + 8 -> cardtype 4 fitnesscoachcards + 0x1e,0x1f,0x91..0x96,0xe7..0xe9,0xec -> cardtype 9 club items + misc + absent (default 342) -> cardtype 0 no merge +``` + +Key: `carddbid == resourceId` for non-player families (queried RAW, no mask); +players are queried by `playerid = resourceId & 0xffffff` (atom `0x287`), and +`assetId` (atom `0x23`) is never read by the merge. + +## Consumable & staff families — evidence table (OBSERVED, `.120` tables) + +| Family | Table | Rows | carddbid range | cardsubtype set | cardassetid (ART) | +|---|---|---|---|---|---| +| Contracts | `fcc_contractcards.json` | 13 | 5001001–5001013 | {201, 202} | {7, 8} | +| Fitness + Healing | `fcc_healingcards.json` | 27 | 5002001–5002030 | {211,212,213,215,216,217,218,219,220} | {9, 10} | +| Training (6 sub-families) | `fcc_trainingcards.json` | 143 | 5003001–5003159 | 51-57, 61-67, 91-110, 121-136, 250-273, 300-340 | {1,3,32,34,35,50,51} | +| Misc | `fcc_misccards.json` | 42 | 5004001–5004042 | {231, 232, 233, 236} | {43, 44, 45, 46} | +| Badges | `fcc_badgecards.json` | 656 | 6000000–6000656 | (none in row) | {39} | +| Stadiums | `fcc_stadium.json` | 78 | 6200000–6200077 | (none in row) | {36} | +| Kits | `fcc_kitcards.json` | 1482 | 6300000–6400654 | (none in row) | {35} | +| League logos | `fcc_leaguelogos.json` | 44 | 8010000–8010044 | (none in row) | {40} | +| League logo stickers | `fcc_leaguelogostickers.json` | 39 | 8010000–8010039 | (none in row) | {40} | +| Balls | `fcc_balls.json` | 42 | 8120194–8120236 | (none in row) | {37} | +| Managers | `managercards.json` | 417 | 1000001–1001552 | (staff; by cardsubtypeid 4) | (assetid col) | +| Head coaches | `headcoachcards.json` | 124 | 2000004–2000328 | (staff; subtype 5) | — | +| GK coaches | `gkcoachcards.json` | 121 | 9000001–9000324 | (staff; subtype 6) | — | +| Physios | `physiocards.json` | 51 | 4000002–4000259 | (staff; subtype 7) | — | +| Fitness coaches | `fitnesscoachcards.json` | 115 | 3000019–3000328 | (staff; subtype 8) | — | + +Notes: +- **Contracts (5001xxx)** — 201 = player_contract, 202 = manager_contract + (OBSERVED, `BY_SUBTYPE`). +- **Fitness + Healing (5002xxx)** — subtype **214 is a valid enum value but ships + ZERO rows** (OBSERVED: 214 absent from `rows[]`). Enum split (OBSERVED, + `BY_SUBTYPE`): healing = 211-218, player_fitness = 219, squad_fitness = 220. + The `+0x58 rareflag == 1` trap flips subtype 219 to squad-fitness. +- **Training (5003xxx)** — SIX sub-families, all OBSERVED in `rows[]` and labelled + in `BY_SUBTYPE`: + - `gk_training` 51-57 (7) + - `player_training` 61-67 (7) + - `position_mod` 91-110 (20) + - `formation_mod` 121-136 (16) + - chem/play styles 250-273 (24): `player_playstyle` 250-268 (19) + + `gk_playstyle` 269-273 (5) + - `manager_league` 300-**341** in the client enum (42), but the shipped table + contains only 300-340 (41 rows) — 341 is defined, not shipped. + - Client enum also defines vestigial/unshipped ranges NOT in the table: + `manager_formation_mod` 71-86, and `DEAD_ZONE` + 58-60,68-70,87-90,111-120,203-210 (28). These have no rows. +- **Misc (5004xxx)** — subtypes {231,232,233,236}; cardassetid ART 43-46. + cardsubtype 231 = 0xe7 anchors the 0xe7..0xe9 block to misc via `FUN_1800d8330`. +- **Club items (badges/stadiums/kits/logos/balls)** carry no `cardsubtype` in the + row; they are keyed by `carddbid` range and distinguished on the wire by ART + `cardassetid` (badges 39, stadium 36, kits 35, logos 40, balls 37). **Kits live + at 6300000–6400654 and are NOT badges** (badges are 6000xxx). The client-side + subtype→family map (which of 0x1e,0x1f,0x91..0x96 is ball vs stadium vs badge vs + kit) is **UNKNOWN** — it is in none of the dumped tables and cardtype 9 has no + miss-fill arm (see `CARD_SYSTEM.md`, "Club items", 2026-08-05). + +## Staff — subtype/cardtype selectors (OBSERVED, binary) + +| cardsubtypeid | cardtype | Family | Table | Rows | carddbid range | +|---|---|---|---|---|---| +| 4 | 2 | Manager | `managercards.json` | 417 | 1000001–1001552 | +| 5 | 3 | Head coach | `headcoachcards.json` | 124 | 2000004–2000328 | +| 6 | 10 | GK coach | `gkcoachcards.json` | 121 | 9000001–9000324 | +| 7 | 5 | Physio | `physiocards.json` | 51 | 4000002–4000259 | +| 8 | 4 | Fitness coach | `fitnesscoachcards.json` | 115 | 3000019–3000328 | + +`cardsubtypeid -> rec+0x50` is the only family selector; `FUN_1800d8330` maps it to +`rec+0x4c cardtype`. Manager merge = `FUN_1801356c0` (queries `managercards` by +`carddbid` raw); coach merges live in the respective tables (`fut_coaches.py`). +All five render live with real photos/bonuses, zero "DB Error" (CARD_SYSTEM.md, +2026-08-05). + +## Players (context, out of taxonomy scope here) + +Players use cardsubtypeid 0..3 -> cardtype 1; merged by `playerid = resourceId & +0xffffff` against the local `players` table. Identity/name/nation/team come from +the client DB; rating/position/attributes come from our item JSON. See +`CARD_SYSTEM.md` and the migration work in `openfut-adapter-fifa17`. + +## Superseded taxonomy (report only — no other files edited) + +The earlier working taxonomy (in prior agent-session notes / long-term memory, and +partially in the original `TablesTaxonomy` scout output) got four things wrong. +Corrected here: + +1. **Chemistry / play styles are 250-273, NOT 91-136.** 91-110 = `position_mod`, + 121-136 = `formation_mod`. (OBSERVED in `fcc_trainingcards` + `BY_SUBTYPE`.) +2. **6300xxx/6400xxx are KITS, not badges.** Badges are 6000xxx. (OBSERVED.) +3. **5004xxx misc cards exist** (subtypes 231/232/233/236, ART 43-46). Previously + omitted. (OBSERVED, `fcc_misccards`.) +4. **8010xxx league logos exist** (+ stickers), ART 40. Previously omitted. + (OBSERVED, `fcc_leaguelogos`.) + +**Repo blast-radius of the superseded values: NONE.** A repo-wide grep +(`docs/`, `openfut-adapter-fifa17/`, `openfut-core/`, `fifa17-recon/`) for the wrong +claims (`91-136` chem styles; `6300/6400xxx` as badges) returns zero hits. +`fifa17-recon/docs/CARD_SYSTEM.md` and `plan-2026-08-06-card-subsystem.md` already +use the correct `250..273` for chem styles and the correct staff subtypes 4-8; +`CARD_SYSTEM.md` is a mechanism log, not a taxonomy, and asserts none of the wrong +ranges. The superseded values therefore live only in non-repo agent memory, which +should be corrected to point at this document. diff --git a/docs/evidence/fifa17-recon/table-hashes.sha256 b/docs/evidence/fifa17-recon/table-hashes.sha256 new file mode 100644 index 0000000..6d38d06 --- /dev/null +++ b/docs/evidence/fifa17-recon/table-hashes.sha256 @@ -0,0 +1,44 @@ +# FIFA 17 card-table provenance manifest +# Source (authoritative): 10.10.0.105:/home/alex/Documents/OpenFUT/fifa17-recon/data/tables/ +# Dest (this repo): fifa17-recon/data/tables/ +# Verified 2026-08-12: source and dest byte-identical (sha256), order-independent. +# Combined hash-of-hashes: 10f239add919089354d8dbff873fc9737b0a0f80f6ac41b1aa2a096c0ec8d331 +# 31 fcc_*.json + 5 staff tables = 36 files. Files are DECODED tables: +# each carries {table, source, rowcount, schema[], rows[]}; card instances live in rows[]. +# +0d1c9af7ae654c3e4363f18bb89bad03a0631056d36425c84b9a680fa989618c fcc_managerbonusvalues.json +0e5d5309cd1d9322476f8047fc6eaf4a88f4f19211b8ea01fe4d28ddd3733134 fcc_healingcards.json +1da80e390169ebb8ee8a6543e14b1191d9151f675797f01e23628f6c24d434c5 fcc_misccards.json +2212b0ee8d962f0fb6bd346bee35fff6566e22539e397cc2e42bb6efd4dc3ad3 fcc_textposvalues_hd.json +2a8e22ddb000b2c08f1a3e5eb47bc56ecf43f733ce6e7519498d332e4f439746 headcoachcards.json +3a323e1c0688a4068ccd21be0c9d8e88a875ab10ce2158d3aed79fc14e65f0fb fcc_chemlinkcalc.json +4a60bc4c0d8cb8d2b903e152a3dd5302348753568630818fde059b2de41f82ab fcc_leaguelogos.json +5304114078200da4564d33612c955598f12a44bdf52f18274184b98922229b8b fcc_GrandStandPlayers.json +5503291e381fee5008120615cd6d30a732b97636d4694a88f943eb14cb992741 fcc_leaguelogostickers.json +550739c124ca915fb294954afe3d9d04fb7d1faf2b0c96930b2dcdb1bfe7ac8f fcc_formationcardspositions_kc.json +5a5aabec1d40ffa21b8effb84f79e4b788cb42352aa592d71d95eba1db0d209e fcc_trainingcards.json +6476e396f166905857d2ada4f12cc37645ca42efdca121e8e74270fbf7422336 managercards.json +6546f602024973e20d04522a857c6c243473a177cab5b3be8400390651a42fab fcc_navcoords_hd.json +6b0209647383e4e940d2af2c3bbb2185a4aac7ac0e799fe6b50ae52e7625710d fcc_contractcards.json +6c52c83aafd9d9d3406e21c656762ac5cc0ba4522002f424e5593430bc5190f5 physiocards.json +765687d7f1e5c6c989adf45b174a0fdab0f65597c83132304b53b9f859c02586 fcc_stadium.json +79e50b07eecc47a0edf4d2a87782e904785e653937698cc712258a82fdf8b079 fcc_formationcardspositions_hd.json +7d36e0fbb9349eabd4267215bacbe29d78ff621deeb8cab3380dcac72c535eb9 fcc_preferredformationcalcmid.json +8122a4070901662fac97f675a3e4194dd5fd7e02194fdab204989af42676e268 fitnesscoachcards.json +828f8b90241672b9f62a9bbd3cb219a1d3bd8856bd160cc46284f2958e08f7d4 fcc_discardcoins.json +852bb82ed373881373d8610e6f4f2ca4406bac13da4bda9d6abba693d7cafc56 fcc_myclubscategories.json +974dcbbe6a46c02dc97c77df6c270c9a7f09ba23bee23005ecf95fd114ee66a7 gkcoachcards.json +9aa4b3b3f226202b21d2e9f96a1508ecce56abba64372099e090df101fce5eeb fcc_nationcalc.json +9b6797991520c05f7448b28e66d160f96afc73eefd661ed8272b0a093b6ba89f fcc_kitcards.json +9e8e6595fa8d3bcf963eb25bd9f9ea5d131aa92ed0e7e4ae3089adf5e1d55927 fcc_preferredformationcalcst.json +a4e8ac2ba0a6db45f1f59fe384fbd39a8cee8fb72a72f846e52daca44f1c7ff9 fcc_myclubs.json +bbf405e3a63b6fd03da1237b8b118764c57a40c797faf85d1e4691a1c95a840e fcc_balls.json +ca1184bd85cff3308af0104077feda4357ef483fae6335fa964922eea4e94330 fcc_navcoords_kc.json +ca3e4ab0f7892aac7473b774de4699c067c54647ca4a82cdd5fd1108c56ed894 fcc_badgecards.json +ccdda8ad0a15f73a056fa336abde8739b346d12b78cb8adbea0f0677487bb598 fcc_preferredpositioncalc.json +dbf95bddd456137e4b90a44bdd1f637458f4846ecd5c3ba6747d3f069c3f590f fcc_textposvalues_kc.json +dd8c2c860b18d999877c37e0f63dac64ef7bb57bff5a2173960cde71242f9a34 fcc_bonusvalues.json +df5b997b153941a5bb760ad5bb0fb23dc16cf8612b300559be23ac929b55eec6 fcc_leagues.json +e4619db324a7848639a8ba53f513cf3ea153eeaf698de05d71e56c319b3cc424 fcc_coinrewards.json +e6b1ca3ecb7c3923d77e73bda2e6c3f9794b9158354d566112f7979b33b4422c fcc_preferredformationcalcgk.json +f54814d61b72dd2b6186e9e414df4fbfbdbea1732da6a4622f001a1ff03bc12a fcc_preferredformationcalcback.json