Squad planner findings: 4 season runs of 27 position slots in the "humans" section
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start by reading the existing humans section reader and the save parsing entry points; the issue does not name their files. Use the documented run layout and controlled observations to decide whether and how to expose planner records in the parsed output. Done means the four runs and their 27 slots can be read without losing empty slot indices, with player IDs resolved safely; run 4 semantics and several slot mappings remain open.
Written by the indexing model from the issue text.
Description
What this is
Format findings for FM27's in-game squad planner (the per-position depth columns on the squad screen), collected from my own career saves by controlled in-game experiments and the planner UI - no decompilation, no third-party parsers. Inside fmsave, planner data is the one part of the humans section there is no reader for, so here is what my tooling observed, in case it is useful for a reader.
Checked on FM27 builds 27.0.0+2486695 and 27.0.0+2493426, macOS, single-player career. I can email a controlled save privately if useful.
Location and framing
Per human manager, the humans section holds four planner runs. Each run:
03 1b run header (constant across observed saves)
[ n u8 ][ id u32 x n ] 27 slot records, back to back, empties included
1b terminator
A record is [count u8][item_id u32 x count], item order = depth order (first item = top choice). An empty slot is a lone 00 byte: a record with count 0. This is not padding - emptying a slot in the planner UI kept the run at 27 records and wrote a 00 exactly at the emptied index, so slot indices stay stable.
The four runs are season sections
The planner UI shows three season sections (current / next / next-next). Controlled edits (game paused, only the planner screen changed, saves otherwise byte-comparable) mapped them:
- run 1 = current season, the user's assignments (changed by every edit in the current-season view),
- run 2 = next season: removing one player from the next-season view changed exactly one slot of run 2 (an 8-item list became
00) and nothing else, - run 3 = the season after: clearing every position of that view emptied seven run-3 slots,
- run 4 = all 27 slots
00in every save observed; semantics unknown.
Future-season runs are seeded by the game with auto depth lists (they include loaned-in and youth players), so they are not empty by default, and clearing the view does not remove the seeded lists - only the user-placed entries.
The 27 slots are a position grid
Enumerated from the keeper upward, right to left within each zone. Labels below are backed by the controlled experiments (GK, ST) and by planner position views whose depth-card lists match slot records exactly in depth order; the planner's position dropdown enumerates the current tactic's positions bottom-up, left to right, matching the save.
| slots | zone |
|---|---|
| 1 | GK |
| 2 | ? (always empty in observed saves) |
| 3-7 | DR, DC x3 (right/center/left center-backs unsplit), DL |
| 8-12 | DM: central trio 9-11; flank cells 8/12 held backup full-backs |
| 13-17 | MC: central trio 14-16; flank cells 13/17 |
| 18-22 | AMR (18), AMC trio (19-21), AML (22) |
| 23-27 | ST trio 24-26 (25 = the drag target of the UI), 23/27 always empty |
Item ids
item_id = person compact id + 1. A person record in game_db starts with [compact u32][uid u32][uid u32] where the uid pair is equal, so an item resolves to a person by scanning for [compact][uid][uid] and requiring the uid to exist in the players table.
Two traps, both hit in practice:
- reverse lookup (find the uid pair, read 4 bytes back for the compact id) is not reliable: the same uid pair also appears in non-record positions;
- the same compact id can prefix more than one person (observed: one compact matched a staff record and a player record) - disambiguate by requiring a player uid.
Open questions
- slot 2, 23, 27 (always empty; 23/27 are presumably the wide-forward flank cells),
- which exact cell of an identical trio the tactic's position maps to,
- run 4's semantics,
- what
03in the header encodes (1b= 27 may be the run length).
Happy to share the experiment protocol, screenshots or a save privately.
- Dominant language
- Python
- Stars
- 28
- Forks
- 8
- Avg merge
- 42m
- Merged PRs (30d)
- 33
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rhiever/fmsave
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
training_man: 27.0.1+2494687 writes a non-zero block trailer, training/mentoring readers fail closedOpen
Difficulty 4/5 1-2 days Newbie friendliness 49/100
rhiever/fmsave#82 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 43/100
rhiever/fmsave#75 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 52/100
rhiever/fmsave#68 · 6 comments ·
Maintainers usually reply within 1 day
Similar issues
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gke-labs/kube-agents#5671 ·
Maintainers usually reply within 1 day
-
docs(auth): Method B step 4 should tell users to tick "Use this client for an AI-powered agent"Opendocumentation next-release v0.9.6
Difficulty 1/5 Under an hour Newbie friendliness 88/100
khuisman/mcp-gee-sweet#1446 ·
Maintainers usually reply within 1 day
-
model:sonnet runtime:claude security size:S
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
FootprintAI/Containarium#3671 ·
Maintainers usually reply within 1 day
-
HolidayBase: reassigning `language` does not re-initialize translations or re-populate holidaysPossibly taken @shikhabhadoria claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
vacanza/holidays#4116 · 1 comment ·
Maintainers usually reply within 1 day
-
bug CLI exec
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day