fifa17-recon: repair_club keeps dead cards unless asked, plus the 2026-08-05 plan

Deleting cards from someone's club is their call, not the tool's. The nine
unrepairable blanks are now KEPT unless --delete-dead is passed. A blank card is ugly,
not harmful, and the 175 stale cards were never the deletion candidates anyway: they
are real players wearing old invented numbers and they get repaired in place.

Also records the build round's synthesis as docs/plan-2026-08-05-families.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUT92pz6RWKih9dSr8ZpxW
This commit is contained in:
funman300
2026-08-05 10:16:13 -07:00
parent 21b2263e30
commit 22ba361578
3 changed files with 17587 additions and 7 deletions
+17 -7
View File
@@ -13,8 +13,10 @@ Two different faults, two different remedies:
DEAD the playerid does not exist in the roster at all. The client misses on it
and stamps its generic card (rating 50, teamid 1933, nation 14, blank
name). These are the blanks on screen and there is nothing to repair, so
they are REMOVED.
name). There is nothing to repair, because there is no player to repair it
to. They are LEFT ALONE unless --delete-dead is passed: removing cards from
someone's club is their call, not the tool's, and a blank card is ugly
rather than harmful.
RUN THIS WITH utas_server STOPPED. The server holds the profile in memory and
rewrites it on its own schedule, so an edit made underneath a running server gets
@@ -24,8 +26,9 @@ cards were removed and reappeared a few hours later.
Squad safety: a card referenced by a saved squad is never removed. Repair is safe
for squad members because the item id does not change.
repair_club.py dry run (default)
repair_club.py --fire write, after taking a timestamped backup
repair_club.py dry run (default)
repair_club.py --fire repair stale cards, keep dead ones
repair_club.py --fire --delete-dead also remove the unrepairable blanks
"""
import argparse
import json
@@ -43,6 +46,8 @@ POOL = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "data", "p
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--fire", action="store_true")
ap.add_argument("--delete-dead", action="store_true",
help="also remove cards whose playerid is not a real player")
a = ap.parse_args()
truth = {p["id"]: p for p in json.load(open(POOL))}
@@ -88,13 +93,18 @@ def main():
continue
repaired.append((it, changes, t))
keep_dead = [d for d in dead if d.get("id") in squad_ids]
drop_dead = [d for d in dead if d.get("id") not in squad_ids]
if a.delete_dead:
keep_dead = [d for d in dead if d.get("id") in squad_ids]
drop_dead = [d for d in dead if d.get("id") not in squad_ids]
else:
keep_dead, drop_dead = dead, []
print("club %d: %d already correct, %d to repair, %d dead to remove"
% (len(items), untouched, len(repaired), len(drop_dead)))
if keep_dead:
print(" %d dead card(s) KEPT because a squad references them" % len(keep_dead))
why = ("a squad references them" if a.delete_dead
else "--delete-dead was not passed")
print(" %d dead card(s) KEPT (%s)" % (len(keep_dead), why))
for it, ch, _ in repaired[:8]:
print(" repair id=%-11s asset=%-7s %s" % (it.get("id"), it.get("assetId"),
"; ".join(ch)[:80]))