From 97498c560ef06b3a42c4016e40515898c5e5da85 Mon Sep 17 00:00:00 2001 From: funman300 Date: Sat, 22 Aug 2026 01:01:47 +0000 Subject: [PATCH] docs(re): refute the contract:7 effect source; record the competing development reading Two corrections found while trying to close the effect boundary statically. 1. `contract: 7` IS OUR OWN PLACEHOLDER. fut_store.py:232's generic _item() factory -- which builds every item the oracle serves -- hardcodes playStyle 250 / contract 7 / fitness 99 on players and consumables alike. The staging GK reads back exactly those three constants. So the production catalog's contract:7 for resource 5001004 is an oracle placeholder round-tripped through an observed profile, not an EA value. Its status is not INFERRED, it is KNOWN-BOGUS as a source. Had the effect been implemented on it, it would have been a fabricated game rule wearing observed-data clothing. 2. fcc_contractcards is NOT amount-less. An earlier note here claimed it "has no amount column, so this value comes from observed data". It has 13 rows with gold/silver/bronze/rating, 6 player + 6 manager paired by rating plus a 99/99/99 special. The sibling fcc_healingcards shares every column except that it carries a single `amount`, which argues the differing columns ARE the effect payload (per target tier). Against that: the values are non-monotonic across tiers, which suits weights better than amounts; and no column of 5001004 is 7, so neither reading explains the placeholder. The reader that would settle amount-vs-weight is in FIFA17.exe, not CardsDLL (the table and column literals are absent from the DLL), so this stays EFFECT_UNKNOWN rather than being guessed. Also records, in content_taxonomy.rs, the competing reading of `development`: fut_consumables.py's TYPE_CATEGORIES groups it as card-categories {6,7,8,9,10} (modifiers only), explicitly flagged there as inferred from UI-bucket names and never observed on the wire. Different enum space from the CONSUMABLE_TYPE switch that actually emits the segment, and the switch gives formation/position/ playStyle/managerLeagueModifier their own segments rather than folding them into development -- so the unfiltered reading is better supported, but it is still a reading and the doc now says so instead of sounding settled. 248 adapter tests, fmt clean. No behaviour change. --- fifa17-recon/docs/CLIENT_ROUTE_SURFACE.md | 51 +++++++++++++++++++ .../src/fut/content_taxonomy.rs | 17 +++++++ 2 files changed, 68 insertions(+) diff --git a/fifa17-recon/docs/CLIENT_ROUTE_SURFACE.md b/fifa17-recon/docs/CLIENT_ROUTE_SURFACE.md index 9cd2b22..20bedd4 100644 --- a/fifa17-recon/docs/CLIENT_ROUTE_SURFACE.md +++ b/fifa17-recon/docs/CLIENT_ROUTE_SURFACE.md @@ -249,3 +249,54 @@ own switch says otherwise. Literal table at `0x1801f5a38` (under bucket — index 0 of an `enum + 1` table — i.e. the unfiltered view; the eight typed segments already reach all thirteen families exactly once, so it owns no family privately and maps to their union. + +## Contract effect — the `contract: 7` inference is REFUTED at the source + +Do not implement a contract effect from the catalog's `contract: 7`. + +`fifa17-recon/tools/fut_store.py:232` — the generic `_item()` factory that builds +EVERY item the oracle serves — hardcodes: + +```python +"playStyle": 250, +"contract": 7, +"fitness": 99, +``` + +These are blanket placeholders on every item, players and consumables alike. The +staging squad's GK reads back `contract 7 / fitness 99 / playStyle 250`: the same +three constants. So the `contract: 7` carried in the production catalog for +resource 5001004 is **our own oracle placeholder round-tripped through an +observed profile**, not an EA value. Its evidence level is not INFERRED; it is +KNOWN-BOGUS as a source of the effect. + +### What the client's own table does say + +`fcc_contractcards` (13 rows) is NOT amount-less, contrary to an earlier note +here. Columns: `carddbid, cardsubtype, weightrare, cardassetid, gold, rating, +bronze, silver`. + +| rating | player (201) | manager (202) | gold | silver | bronze | +|---|---|---|---|---|---| +| 50 | 5001001 | 5001007 | 1 | 2 | 8 | +| 65 | 5001002 | 5001008 | 8 | 10 | 10 / 8 | +| 80 | 5001003 | 5001009 | 13 | 11 | 15 / 11 | +| 60 | 5001004 | 5001010 | 3 | 6 | 15 | +| 70 | 5001005 | 5001011 | 18 | 24 | 20 / 18 | +| 90 | 5001006 | 5001012 | 28 | 24 | 28 / 24 | +| 90 | 5001013 | — | 99 | 99 | 99 | + +Compare the sibling `fcc_healingcards`, which shares `carddbid, cardsubtype, +weightrare, cardassetid, rating` and differs only by carrying a single `amount`. +So `weightrare` is the drop weight and the differing column(s) are the effect +payload — which would make gold/silver/bronze a per-target-tier amount. + +AGAINST that reading: the values are not monotonic across tiers (5001005 is gold +18, silver 24, bronze 20; 5001003 is gold 13, silver 11, bronze 15), which is +odd for an amount and unremarkable for a weight. Note also that **no column of +5001004 equals 7**, so nothing here explains the placeholder either way. + +Unresolved, and NOT to be guessed: the fcc tables are loaded by `FIFA17.exe`, not +CardsDLL (the table-name and column literals are absent from the DLL), so the +reader that would settle amount-vs-weight lives in the EXE. Status stays +**EFFECT_UNKNOWN**. diff --git a/openfut-adapter-fifa17/src/fut/content_taxonomy.rs b/openfut-adapter-fifa17/src/fut/content_taxonomy.rs index 13d6506..311e9ff 100644 --- a/openfut-adapter-fifa17/src/fut/content_taxonomy.rs +++ b/openfut-adapter-fifa17/src/fut/content_taxonomy.rs @@ -247,6 +247,23 @@ pub fn consumable_needs(family: &str) -> ConsumableNeeds { /// and maps to every family — which is consistent, since the eight TYPED /// segments already reach all thirteen families exactly once. /// +/// COMPETING INFERENCE, recorded rather than buried. `fut_consumables.py`'s +/// `TYPE_CATEGORIES` maps `development` to card-categories `{6,7,8,9,10}` +/// (formation/position/playstyle/manager-league) — i.e. the modifier families +/// only, not everything. That grouping is explicitly flagged there as INFERRED +/// from `FUN_180048780`'s UI-bucket names, with "the tab-to-arm binding has +/// NEVER been observed on the wire". +/// +/// They are not the same enum: the oracle's is the 0..10 CARD-category space of +/// `FUN_18013f4d0`, this is the 0..24 CONSUMABLE_TYPE space that actually +/// produces the URL segment. The tiebreaker is the switch itself — it gives +/// formation (16), position (17), playStyle (23) and managerLeagueModifier (24) +/// their OWN segment strings, so those types are not folded into `development`, +/// which is what the oracle's grouping would require. The unfiltered reading is +/// therefore the better-supported one, but it is still a reading: what the +/// SCREEN expects to list has not been observed, and one live capture of the +/// development tab would settle it. +/// /// `training` and `contracts` are CONFIRMED on the wire, `development` was /// observed live, and the singular `contract` is accepted because the client has /// used both spellings. Segments are matched lower-cased.