docs(fifa17): the caption path is not in CardsDLL, and a 4th definitionId check

Chased the league-logo lead to a useful boundary and stopped there.
FUN_180119bd0 — the cardtype-7 caption resolver the whole club-item story rests
on — has ZERO references anywhere in CardsDLL: no call, no jmp, address never
taken in .text/.rdata/.data. It is nonetheless a real function. An unreferenced
real function in a DLL is almost certainly an export, which puts its caller in
FIFA17.exe. So the owned cardtype-9 caption path is not in CardsDLL and looking
for it there is wasted effort; the launch probe remains far cheaper than parsing
the export table and 79 MB of EXE.

Also verified definitionId a fourth way, by a different method than the existing
three: every real atom name appears exactly once in CardsDLL's .rdata
(resourceId, cardsubtypeid, itemState, assetId, cardassetid, rareflag, owners,
contract, discardValue, and localizedName), while definitionId is absent
entirely. Recorded but NOT applied — the path carrying it is live-proven and the
saving is payload only.

Method note added: CardsDLL is .text 0x180001000, .rdata 0x1801e5000, .data
0x18028a000. Confusing a live mapping offset with an image offset reads the wrong
section and returns false negatives — it made every atom lookup, controls
included, come back ABSENT until corrected. Validate scans against a known key.
This commit is contained in:
funman300
2026-08-21 21:28:13 +00:00
parent 59c249e76a
commit 404e859cb6
@@ -464,6 +464,33 @@ The lead worth following: find whether the owned cardtype-9 render path reaches
this resolver, and if so which field feeds the league id. If it does, league this resolver, and if so which field feeds the league id. If it does, league
logos need no `localizedName` at all and separate from the ball/misc gap. logos need no `localizedName` at all and separate from the ball/misc gap.
#### Where to look next, and where NOT to (2026-08-21)
The lead above was chased and stopped at a useful boundary. `FUN_180119bd0`
the cardtype-7 caption resolver this whole section rests on — has **zero
references anywhere in CardsDLL**: no `call`, no `jmp`, and its address is never
taken in `.text`, `.rdata` or `.data`. It is nonetheless a genuine function
(clean `mov rax,rsp` entry after `int3` padding).
A real, unreferenced function in a DLL is almost certainly an **export**, which
puts its caller in FIFA17.exe. That matches the shape of everything else here:
CardsDLL owns the card model and the database, and the EXE owns the UI that asks
for captions. `FUN_180098f20`'s only caller likewise iterates a small list
element, not a card record — a browse/catalog builder, not the owned-item path.
So the practical guidance is: **stop looking for the owned cardtype-9 caption
path inside CardsDLL.** It is not there. Closing this by static reading means
parsing CardsDLL's export table and following the callers in FIFA17.exe's 79 MB,
which is a much larger job than the launch probe in "The one probe still
outstanding" — one item, one family, and the answer is visible on screen.
Method note for whoever does dump memory here: CardsDLL's sections are
`.text` at image `0x180001000`, `.rdata` at `0x1801e5000`, `.data` at
`0x18028a000`. Confusing a LIVE mapping offset with an IMAGE offset silently
reads the wrong section and produces false negatives — every atom-name lookup
came back ABSENT until the region was corrected, including controls like
`resourceId`. Always validate a memory scan against a key known to be present.
--- ---
## 4. The card lifecycle ## 4. The card lifecycle
@@ -1008,6 +1035,21 @@ be misrouted onto another field. **Freeze risk: none** -- removing a key the par
skips strictly reduces executed code. Low value, zero cost, and it removes a field skips strictly reduces executed code. Low value, zero cost, and it removes a field
that three documents describe as if it did something. that three documents describe as if it did something.
**Fourth verification, 2026-08-21 (independent method).** Searched CardsDLL's
own `.rdata` in the running client for the literal key names. Every real atom is
present exactly once — `resourceId` `0x18022a3a8`, `cardsubtypeid` `0x180230520`,
`itemState` `0x180231490`, `assetId` `0x180230178`, `cardassetid` `0x180204200`,
`rareflag`, `untradeable`, `owners`, `contract`, `discardValue`, and notably
`localizedName` at `0x1802316d0` — while **`definitionId` is ABSENT entirely**.
The client has no string for it, so no arm can exist. That is a different method
from the three above (string table rather than key dictionary) and it agrees.
NOT applied all the same. The player path that carries `definitionId` is
live-proven in production, the saving is payload only, and this project's house
rule is that a flag defaults to the live-proven value. "Provably inert" is a good
reason to stop documenting it as meaningful; it is not on its own a reason to
change a working wire. Bundle it with the next change that needs a launch.
--- ---
## 7. Proposed corrections to existing documents ## 7. Proposed corrections to existing documents