Football Manager internals

How the game stores its data, what its files are, and what its numbers mean. Every app in this documentation links here instead of explaining the game again.

Compiled from the repos in /home/rob/code on 2026-10-14. Most facts come from reverse engineering, not from official documentation, so each one is marked.

How to read this page

Every fact is tagged with how sure we are and which repo found it:

"SI" means Sports Interactive, the studio that makes the game. "The FM22 source" is a read-only copy of SI's FM22 code kept at /home/rob/fm/sifiles/dev/fm2022/main. There is no source for any other version, so anything about FM24 or FM26 is deduced from files and from the game's program files.

Your values (used by the examples below)

Game versions

The game is released once a year and named after the year it starts in: FM24 starts in 2023/24 but is named for 2024, and FM26 is the 2026 edition. The repos cover FM18 to FM26, plus an experimental FM27. Files from different versions look similar but are not interchangeable.

Version numbers

Three different numbers are in use and they are easy to mix up.

NumberExampleMeaningSource
Build2620First two digits are the game year, then a major and minor number. 2620 = 26.2.0, 2430 = 24.3.0. It also names the folder of the data shipped with that build.fm-xml, fm-reader-data (Confirmed)
Database version ("DBV")3569 (FM24), 3729 / 3733 (FM26 editor files)A counter that goes up whenever the database layout changes. Editor files carry it as version.fm-xml (Confirmed for the meaning, values observed in sample files)
Save db_version3569 (FM24), 4000 (FM26)The same idea, read from inside a .fm save.fm-reader (Confirmed as observed)
The repos disagree. fm-xml gives FM26 editor files a database version of 3729 to 3733, while fm-reader reads 4000 from FM26 saves. fm-reader also notes that FM27 builds show 3750 and "FM26 and FM27 share 4000". We do not know why the two counters differ (Guess: the editor file and the save count different things). Always use the build number (svvs) to tell games apart, not the database version. FM22 is also given as 2962 to 3006 (fm-xml) and 3035 (fm-reader, a save), which is another unexplained gap.

What changes between versions

GameArchive versionCompressionNotes
FM18 to FM207zlibfm-reader, fm-re (Confirmed)
FM21 to FM238zstd (a newer, faster compressor)Each block has a length in front of it.
FM24 to FM268zstdPlain blocks. FM24 and FM26 have the same list of 77 database parts.
FM268zstdThe screens are built with Unity (a game toolkit); the match and database engine is still native code. About 4,000 fewer engine classes than FM24 (fm-re, Confirmed).
FM27--Experimental. Build 2700. Internal research only; the web and desktop readers reject it (fm-reader, Confirmed).

Platform differences: the Windows game program is heavily protected from FM17 on, so it cannot be inspected. The Mac builds of FM10 to FM19 contain readable function names and are the most useful reference (fm-re, Confirmed). FM26 is a Unity IL2CPP build, which exposes the names and values of every screen-level setting but not the engine's code (fm-re, Confirmed).

Working out which game a file is for

For editor files the best clue is the svvs field, the build the file was last saved in. The order of checks used by fm-xml (Confirmed as a method):

  1. svvs such as 2620: game is FM26.
  2. Otherwise orvs, the build the file was first made in.
  3. Otherwise verf, the versions the rules were checked against.
  4. Otherwise guess from the database version.

A file first made in FM24 and re-saved in FM26 has orvs=2430 and svvs=2620. It counts as FM26, because FM26 is the game that loads it.

grep -m3 -E 'id="(svvs|orvs|version)"' "{{FILE}}"

That only works on the XML form of the file. For a .fmf, unpack it first (see The FMF archive format).

File locations

Game data lives in two places: the install folder (read-only, ships with the game) and the user's documents folder (saves, editor files, tactics).

User folders

WhatWindows and Linux (Proton)Mac
SavesDocuments/Sports Interactive/Football Manager 2024/games/~/Library/Application Support/Sports Interactive/Football Manager 26/games/
Editor data (updates)Documents/Sports Interactive/Football Manager 2024/editor data/~/Library/Application Support/Sports Interactive/Football Manager 26/editor data/
Languages-.../Football Manager 26/languages/

The folder name changed style: FM24 and earlier use the full year ("Football Manager 2024"), the notes for FM26 use "Football Manager 26". Likely (the repos show both spellings and do not state the rule). Tactics also live in the user folder; see Tactics files.

Install folder and the data layers

The game ships its database as numbered layers (fm-reader, database-layering.md, Confirmed for the layout, Likely for loader behaviour in FM24+):

data/database/db/
  2600/            base release (26.0.0)
    2600_fm/       the .dat database files + 2600_fm.xml manifest
    dbc/           binary configuration (licensing, kits, names)
    edt/           .edt / .ddt directive files
    lnc/           .lnc language and name-change files
  2620/            update release (26.2.0)
    2620_fm/       full replacements of the .dat files
    dbc/ edt/ lnc/

An update layer replaces whole database files; it is not a patch. The base layer carries lang_db.dat (text such as names of competitions); update layers carry lang_update_db.dat instead. Folders ending _fm, _fmc, _fmm are different editions of the same build (Likely: full, classic and mobile; the repos do not spell this out).

Where this server keeps game files

PathWhat
/home/rob/code/fm-reader-data/games/Game installs FM10 to FM26, Windows and Mac. Read-only.
/home/rob/code/fm-reader-data/dat/Just the database files, per game and build. Large files use Git LFS.
/home/rob/code/fm-reader-data/saves/Example saves per version. A validation-json folder holds the game's own JSON export, used only to check our readers, never as an input.
/home/rob/fm/sifiles/dev/fm2022/mainThe FM22 source code (read-only).
/home/rob/fm/sifiles/mdb/118 old research databases, 2001 to FM2021. See Research databases.

Save games (.fm)

A save game is a file ending .fm. It is an FMF archive (a container, like a zip) holding several files. The important one is game_db.dat, the whole game world at the moment of saving: about 98 MB (FM18) to 154 MB (FM24) once unpacked (fm-reader, Confirmed).

How a save is read

  1. Open the FMF archive and read its directory.
  2. Decompress game_db.dat.
  3. Read its header to learn the database version.
  4. Walk the tables one after another (there is no index; each table follows the last) and decode each record.

Fresh and played saves both work, from FM18 to FM26. Everything is checked against the game's JSON export: player and staff ability, reputation, height, weight and all attributes match 100%, club names 99.4% across 26,268 clubs (fm-reader, Confirmed for FM24).

What is and is not in a save

Size and format by version

Versiongame_db.dat sizeArchiveCompression
FM1898.5 MB7zlib, one block
FM19107 MB7zlib, one block
FM20113 MB7zlib, one block
FM21116 MB8zstd, chunked
FM22130 MB8zstd, chunked
FM23137 MB8zstd, chunked
FM24154 MB8zstd, one block
FM26122 MB8zstd, one block

Source: fm-reader docs/formats/fm-save/README.md (Confirmed).

Example: list the parts of a save

python3 -I /home/rob/code/fm-re/scripts/fmf_dir.py "$HOME/Documents/Sports Interactive/Football Manager 20{{FM_YEAR}}/games/{{SAVE}}" --counts

The path template is only an example; use your own save location (see File locations).

Reading a running game

fm-reader can also read the game's live memory using a table of offsets per version (fm24.toml and similar). This is the only source for data that has not been saved yet. It is deliberately kept separate from the save and database readers: each reader reports its own gaps and never fills them from another source (fm-reader, Confirmed as project policy).

Editor and update files

The game's Pre-Game Editor lets people change the database before starting a career (move players, change clubs, rewrite competitions). The result is an editor file. Community data updates (for example sortitoutsi.net's yearly updates) are editor files. Three shapes exist and all hold the same content:

ExtensionWhat it is
.fmfAn archive holding a .dbc, a thumbnail and a small details file. This is what players download and install. See FMF format.
.dbcThe compact binary form of the changes ("database content").
.xmlThe same content as readable text. Lossless both ways.

Source: fm-xml docs/01 and 07, fmf-archiver docs/src/dbc.md (Confirmed).

What is inside an editor file

One outer record with two kinds of content (fm-xml, Confirmed):

Header fieldMeaning
svvsBuild the file was last saved in, e.g. 2620.
orvsBuild it was first created in. May be empty.
versionDatabase version. Only read it at the top level; rule groups inside have their own unrelated version fields.
verfBuilds the advanced rules were verified against.
XSvCSave counter: higher means a newer copy of the same file.
EdDt, EdBrLast save date and editor branch (a hint only).
description, authorShown in the game.

Field order differs between files, so tools must look fields up by name. The list of changes can appear anywhere, even after tens of thousands of lines of rules.

A database change

Each change names a table, a record, a property and a new value. The game applies them in list order and a later change to the same field wins. If the record is missing or the value is refused, the change fails silently (written to a log only), so a file alone cannot prove a change worked (fm-xml, Confirmed from FM22 source).

<record>
    <integer id="database_table_type" value="1"/>      table 1 = person
    <integer id="version" value="3729"/>
    <large   id="db_unique_id" value="421030296890625235"/>  person 98028755
    <unsigned id="property" value="1348695145"/>       'Pcti' = contracted club
    <record id="new_value">
        <large id="Ttea" value="1879"/>                  team 1879 = Trabzonspor
    </record>
</record>

That change moves Mohamed Salah to Trabzonspor (fm-xml sample). Special properties ADDR, COPY and DELE create, copy and delete records.

Table types

The table number in each change comes from SI's list of database tables. New types are only added at the end, so numbers stay stable (fm-xml, Confirmed from FM22 source; FM26 files use the same numbers for every type seen).

No.TableNo.Table
0Award18Derby
1Person (player, staff, official)19Region
2City21Stadium
3Club23Stage name
5Continent24Team
6Injury type25Competition
7Media source41Currency
8Language47Local region
9Nation12Award history row
These are the numbers in editor files. The numbering of the sub-files inside the installed .dat files is different and changes by version; see The database.

Property codes

A property is named by four letters stored as a number: 1348695145 is the letters P c t i. The first letter usually hints at the owner (P person, C club, S stadium, T team, lower-case c competition, N nation), but a code only has a meaning together with its table. Cnam is "Name" for both clubs and cities (fm-xml, Confirmed).

python3 -c "import sys;n=int(sys.argv[1]);print(n.to_bytes(4,'big').decode())" 1348695145

The FM22 source declares about 13,860 codes; a newer CSV export adds 45 codes FM22 lacks (fm-xml: data_update_fields.csv, 2,667 fields). Human-readable names come from those two sources.

Changing lists

Some properties are lists of rows (a club's league history, a person's second nationalities, kits). A change to these carries an operator (fm-xml docs/05, Confirmed from FM22 source):

lsopOperation
0Add a blank row
1Edit one field of a matching row
2Delete a matching row
3Clear the whole list

Which file wins

When several editor files change the same field, the one the game applies last wins. How the game orders them (fm-xml docs/10; confirmed from FM22 source and checked in FM26 in game, September 2026):

  1. It collects loose .xml then .dbc files from editor data (subfolders included), then from the shared editor data folder, then .fmf archives (top level of the folder only; each needs a _data/details.aom).
  2. It sorts them by file name without extension, ignoring case, comparing numbers as text (10 sorts before 2). For an .fmf the name that counts is the .dbc inside it, not the .fmf name. Renaming the archive changes nothing.
  3. Files with equal names keep the order they were found in.

To make a file load last, rename the .dbc inside it, not the archive. The skip thresholds for files with too few changes are only known for FM22 (Likely the same later).

Making a smaller copy

A modified copy of an editor file is made by dropping whole change records and copying everything else byte for byte, never by editing values (fm-xml docs/11). Example with fm-xml's command line:

fmx cut "{{FILE}}" --remove 3:Tcap,3:Tvcp -o "smaller.xml"

The pair 3:Tcap means table 3 (club), property Tcap.

The FMF archive format

FMF ("Football Manager File") is SI's own container, like a zip. It is used for editor updates, graphics packs, saves, tactics and the game's own database files. Sources: fmf-archiver docs/src/fmf.md, fm-tactic-reader research/fmf-spec.md (Confirmed from FM22 source and 1,500+ real files), fm-re (Confirmed).

Layout

offset 0   9-byte header   format 2, byte order 1 (little-endian), magic "fmf." (or "afe." if encrypted), version 7 or 8
offset 9   17-byte prologue: where the directory is, where file data starts, compression type
offset 26  file data, one block per file
...        second header (always "fmf.") then the directory, compressed with zstd (v8) or zip (v7)

What an editor archive contains

My Update.fmf
  Title.dbc            the changes (the part you want)
  data update.jpg      thumbnail
  _data/details.aom    title, description, tags, owner (add-on metadata)

A saved game contains game_db.dat among others.

The DBC inner format

8-byte header: format 3, little-endian, magic "cbd.", version 6
1 byte: encrypted flag (then a key block if set)
compressed stream (zstd):
    summary record  (change count, versions, author, description)
    rules record    (everything except the changes)
    change count
    one record per change

Every value is typed (null, int, bool, colour, date, list, string and so on) and has a four-letter name. The XML form is a straight text rendering. Reading is supported for format 2 version 5, FM18's version 9998 and format 3 version 6; version 9999 is not supported (fmf-archiver, Confirmed). Writing always produces version 6. A comps.dbc file is a DBC header followed by an embedded FMF archive of about 1,158 smaller rule files (fm-reader, Confirmed).

Packing and unpacking

The tool is fmf_archiver (fmf-archiver repo). Its release build on this server is /home/rob/code/fmf-archiver/target/release/fmf_archiver.

Your values
# Unpack an .fmf; each .dbc inside is turned into .xml
/home/rob/code/fmf-archiver/target/release/fmf_archiver unpack "{{FILE}}" "{{OUT}}"

# Convert one .dbc to .xml
/home/rob/code/fmf-archiver/target/release/fmf_archiver unpack changes.dbc "{{OUT}}"

# Pack a folder (or one XML file) into a mod
/home/rob/code/fmf-archiver/target/release/fmf_archiver pack -i ./my_mod -o my_mod.fmf -t "{{TITLE}}" -a "{{AUTHOR}}"

Tips (fm-xml, Confirmed): the tool reads a config.json from the folder you run it in, so run it in an empty folder. An 8 MB .fmf can become a 397 MB XML file, and the whole XML is built in memory. The XML it writes is byte-for-byte what sortitoutsi publishes next to their .fmf files.

Encryption

The only encryption in these formats is AES-128 in counter mode, and it protects nothing from us: the key and the starting value are stored in plain sight in front of each encrypted file (fmf-archiver fmf.md, fm-xml docs/07, fm-tactic-reader fmf-spec.md; Confirmed).

Decryption is done server-side in fm-tactic-reader on purpose: that app keeps all format knowledge on the server and sends only opaque data to the browser. See that app's page.

The database

The installed game keeps its starting world in several .dat files per build (fm-reader-data README; fm-re fm-dat-archive.md; Confirmed):

FileHolds
server_db.datThe main tables: clubs, competitions, nations, stadiums, cities and many smaller lists.
people_db.datPeople: names, personality, the 69 playing attributes, 52 staff attributes, contracts.
basic_people_db.datA compact summary per person: ability, wage, value, reputation, nation, club and the id used for linking.
client_db.datData the game's screens need.
lang_db.dat / lang_update_db.datText and names (base layer / update layer).
pl_hist_*, non_pl_hist_*Playing and non-playing career history.
summary.datSummary information.

Each is an FMF archive with a directory at the end naming every sub-file (table_<type>, name_table_0, ...). That lets a reader find a table by name instead of guessing its position. Works for FM18 to FM26; all 587 sub-files across eight versions decompress to the size the directory says (fm-re, Confirmed).

python3 -I /home/rob/code/fm-re/scripts/fmf_dir.py /home/rob/code/fm-reader-data/dat/fm{{FM_YEAR}}/{{BUILD}}/{{BUILD}}_fm/server_db.dat --counts

How the table list changed

ChangeFirst version
elections sub-file (FM18 and FM19 only)gone from FM20
Newgen parameter tables (table_65 to table_70)FM20
Old-save copies of competition and stage-name tablesFM21
Table 40 (starting international friendly) droppedFM23
table_10 added, before table_9; table_1 dropped; table_71 to table_73 addedFM24

FM24 and FM26 have an identical list of 77 sub-files. Source: fm-re.

Nation versus national team

From FM24, table_10 is Nation (251 records) and table_9 is the national-team container (one per nation in FM24; men's and women's in FM26, so 502). Before FM24 table_9 was the nation. Confirmed by the FM26 enum names (fm-re) and the internal class names, and agrees with fm-reader's own "FM24 split" notes.

Table families

fm-reader exports 143 tables as CSV or MySQL; the generated catalogue is /home/rob/code/fm-reader/DAT_SCHEMA.md. thefmdb and fm-xml read the MySQL copies, one database per game release, named like fm26_update, fm26_release, fm24_release, fm23_release, fm22_release (fm-xml docs/08). Notes:

Research databases (mdb)

Before the modern files, SI's research tooling used Microsoft Access databases. There are 118 of them (38 MB to 2.1 GB, from Championship Manager 3 in 2001 to FM2021) with 22,875 tables. mdb-reader exports them to CSV with mdbtools version 0.7.1 (chosen over 1.0.0 so new output matches the 12,675 CSVs already on disk; the difference is float formatting). Run scripts/run_all.sh 8, which skips tables that already exist, and check scripts/audit.sh for coverage. The CSV tree is in /home/rob/fm/sifiles/csvs/. Source: mdb-reader (Confirmed).

IDs

Every record in the database (person, club, stadium...) has numeric ids. Rules that hold across all the repos:

Unique id and random id

Each record has two 32-bit numbers (fm-xml docs/03, Confirmed from FM22 source):

When a reference is written as a single 64-bit number the two are packed:

packed    = (random_id * 4294967296) + unique_id
unique_id = packed & 0xFFFFFFFF
random_id = packed >> 32

For shipped records packed = uid x 4294967297 ("fermat form", because 4294967297 is 232+1). Always decode with bit operations, never division, because division only works when both halves are equal. Three forms appear in real files, sometimes together: fermat, short (random half 0) and editor-random.

Your values
python3 -c "p={{PACKED}};print('uid',p&0xFFFFFFFF,'random',p>>32)"

That prints uid 98028755 random 98028755 for the default: Mohamed Salah.

When two ids mean the same record

  1. If the random halves are non-zero and equal: same record.
  2. Otherwise, if the uids are equal and either random half is 0: same record.
  3. Otherwise different.

This matters for references to records created in an editor. Uids from 2,000,000,000 upwards are editor-created in the files seen (Likely). A reference can carry both a packed id and a plain DBID uid.

Ids are only unique within a table

uid 680 is a club (Manchester United), a stadium (Old Trafford) and a city (Mobile, Alabama) at once. Anything that stores an id must also store the table type (fm-xml, Confirmed).

Club versus team

A club is the organisation. A team is one side: first team, reserves, youth, or a national team. A person's contract points at a team, not a club (fm-xml, Confirmed in the FM26 reference data).

So team 1879 is club 1879, Trabzonspor. Search for a club should also match its teams.

Reference keys in editor files

KeyPoints atKeyPoints at
PerspersonNnatnation
CcluclubTteateam
citycitycompcompetition
stadstadiumcontcontinent

Other id facts

Attributes

Attributes are the numbers that describe a person. Players have 69 stored values in a fixed order; 15 of them are position ratings, leaving 54 true attributes. Staff have 52 non-playing attributes (fm-reader people-and-attributes.md, Confirmed).

Scale

Your values
python3 -c "r={{RAW}};print(max(1,min(20,(r+2)//5)))"

The 69 slots in order

SlotsMeaning
0 to 14Position ratings: goalkeeper, sweeper (unused), defender left/central/right, defensive midfielder, midfielders left/central/right, attacking midfielders left/central/right, striker, wing-backs left/right. A score of 20 means natural.
15 to 25Crossing, dribbling, finishing, heading, long shots, marking, off the ball, passing, penalty taking, tackling, vision
26 to 31, 34, 36, 46 to 48Goalkeeper: handling, aerial reach, command of area, communication, kicking, throwing, one on ones, reflexes, eccentricity, rushing out, tendency to punch
32 to 33, 35, 37 to 45Anticipation, decisions, positioning, first touch, technique, left foot, right foot, flair, corners, teamwork, work rate, long throws
49 to 68Acceleration, free kicks, strength, stamina, pace, jumping, leadership, dirtiness, balance, bravery, consistency, aggression, agility, important matches, injury proneness, versatility, natural fitness, determination, composure, concentration

The full slot-by-slot enum is in /home/rob/code/fm-reader/docs/formats/dat/people-and-attributes.md section 4.5.

Position of the block moves. In people_db.dat the 69 attributes start a fixed distance after the current-ability number, and that distance depends on the version: 18 bytes (FM18), 19 (FM19 to FM22), 23 (FM23 and FM24), 24 (FM26). Using the wrong one shifts or garbles every attribute (fm-reader, Confirmed). Names, in the same record, are written after the playing data.

Current and potential ability

Current ability (CA) and potential ability (PA) are a single 0 to 200 number each, hidden from players in the game. A negative PA or CA from -1 to -10 is not a value but a range the editor uses for "unknown" (fm-reader, Confirmed):

CodeRangeCodeRange
-10 to 20-690 to 120
-210 to 40-7110 to 140
-330 to 60-8130 to 160
-450 to 80-9150 to 180
-570 to 100-10170 to 200

The base database also holds a second family of codes (-15, -25 ... -95) that fm-reader passes through raw; their meaning is not documented (Guess: scaled ranges). Reputation, height, weight and the personality (eight small numbers) also sit in the person record.

Numbers the game does not store

thefmdb's six-axis summary (pace, physical, technical, mental, defending, shooting) is an average computed by the app from the stored attributes, not a game value. Its exact grouping is on the thefmdb page.

Positions and roles

Positions

FM26 tactic files store each player slot as a position mask: a base bit plus an optional side marker (fm-tactic-reader research/fm26/positions.md, Confirmed from 28 controlled test files).

BitPositionBitPosition
0GK8MR
2DR9ML
3DL10MC (CM)
4DC11AMR
5WBR12AML
6WBL13AMC
7DM14STC (ST)

Adding 0x100000 to a mask marks the left half (for example DCL = 0x00100010) and 0x200000 the right half (DCR = 0x00200010). That is how a two-centre-back line is told apart. Names such as DMC and CM are aliases of DM and MC.

Roles and duties

A role (such as Poacher or Ball-Playing Centre-Back) is a bit number in a 64-bit field; the duty (Defend, Support, Attack) is another bit in the same field. Roles are separate in possession and out of possession. Both were checked two ways and agree: from 187 controlled test tactics (fm-tactic-reader) and from FM26's own program metadata (fm-re fm26-il2cpp.md). All 40 in-possession and 39 out-of-possession roles match, with 0 conflicts (Confirmed).

DutyBit
Defend21
Support22
Attack23
Defend (Stopper)25
Defend (Covering)26
Float34

Examples of role bits (in possession): 0 Goalkeeper, 1 Centre-Back, 2 Full-Back, 3 Wing-Back, 4 Defensive Midfielder, 5 Central Midfielder, 7 Winger, 9 Attacking Midfielder, 19 Poacher, 27 Inside Forward, 40 False Nine. The full table is /home/rob/code/fm-tactic-reader/research/fm26/roles.md.

Use the bit, never the name. The game's internal names are often old ones for a renamed role: bit 14 is called "Libero" but is the Advanced Centre-Back, 18 "TargetMan" is Target Forward, 32 "Trequartista" is Free Role, 41 "ShadowStriker" is Second Striker (fm-re, Confirmed).

Ten in-possession bits exist in the game's list but in no test file (20, 28, 30, 33, 36, 37, 39, 42, 47, 50: Complete Forward, Anchor Man, Regista, Mezzala and others). They were roles of FM24. Probably FM26 retired them (Guess; fm-re). Out-of-possession bit 24 does not exist at all.

Player instructions

Each player instruction is a numbered bit. All 31 bits seen in test files match the game's own enum (fm-re). Five exist in the game's list but in no sample (5 Cross Often, 6 Cross Less Often, 20 Be More Expressive, 21 Be More Disciplined, 28 Switch Position), probably FM24 leftovers (Guess). There are 15 setting groups (attacking width ... marking target).

Tactics files

A tactic is saved as a .tac file, or inside an .fmf archive when shared. A shared tactic is just an archive that happens to contain a .tac (fm-tactic-reader, Confirmed).

FM24 layout

Fully deterministic from byte 0 (validated on 423 files, 13,775 role slots; fm-tactic-reader research/tac-spec.md):

  1. 8-byte header: format 3, little-endian, magic cat., version 34.
  2. Body: tactics version (58), match version, name, description, author, password.
  3. Team instructions: fluidity, mentality, three 32-bit instruction words, goalkeeper distribution target, style name.
  4. Exactly 11 player slots: position mask, role and duty, enabled flag, player-instruction slots (24 bytes each), exclusions.
  5. A tail that is kept unchanged.

Mentality (1 to 7): Very Defensive, Defensive, Cautious, Balanced, Positive, Attacking, Very Attacking. Fluidity (0 to 4): Very Rigid ... Very Fluid. The game derives fluidity from duties, so keep what is stored.

FM26 layout

Schema version 66 (FM24 is 58). Verified on 839 shared tactics, all reading to the end of file (fm-tactic-reader). Each player has separate in-possession and out-of-possession records. The 72 controlled team-instruction files define a table of numbered bits (for example bit 1 to 4 are passing directness from "much more direct" to "much shorter"). Preset tactics also set six bits (25, 33, 34, 60, 74, 75) whose meaning is not known.

Not resolved: the FM26 program metadata does not list team-instruction bits, so those are known only from test files (fm-re). Two-phase edits to out-of-possession positions propagate to a family of duty bits, which is why edits must follow the stored rules, not only change one bit.

Rules a tactic editor must follow

Nation rules

Each nation has a set of rules that describe how its competitions run and when its season starts: league structure, cup draws, transfer windows, qualification slots, registration limits and start dates. They are authored as XML and compiled into comps.dbc; the running game reads the compiled form, never the loose XML (fm-reader docs/formats/comps/README.md, Confirmed from FM22 source). The database itself does not contain authored rules.

loose XML  ->  editor / compiler  ->  comps.dbc  ->  rule objects in the game

Where they are

Parts of a nation file

PartWhat it controls
start_date_rulesChoices in the career start-date dropdown. See Start dates.
generated_start_date_rulesDates generated by the editor's "Test Rules"; not what the game uses (see Start dates).
season_windowsSeason-start dates per division range.
Competition records (file_type="comp")One per competition; a direct-child start_year controls whether it is active.
preseason_preparation_days, late_preseason_preparation_daysDays before the season start for early and late preseason (typically 28 and 14).

The nation-editor app edits these files in the browser. It labels property numbers by decoding the four-letter codes, and its tree edits are not checked against the schema as you type; run the saved file through the validator in the start-dates project (validate.mjs).

Do not write the date inside generated_start_date_rules yourself. The editor computes it from the rules and it cannot be derived from the XML (start-dates, Confirmed).

Shifting rules a year forward

start-dates documents the recipe used to move older rule files to a new start year (Confirmed in file structure, in-game results noted per nation):

  1. Set base_year_offset to 3 for FM24 files or 1 for FM26 files in every start-date rule.
  2. Insert early and late preseason rules before each start-of-season rule, cloning the competition block.
  3. Set the direct-child start_year of each competition record. Leave deeper nested ones (history) alone.

Start dates

When a new career begins, the game offers start options such as "Start of season", "Early preseason", "Late preseason". How it picks the actual date is documented in /home/rob/code/start-dates/docs/start-date-methods.md, re-verified 2026-08-26 against FM22 source, FM24 and FM26 files and recorded in-game results for Denmark and Portugal.

How a date is resolved

  1. Use the rule's own date if valid.
  2. If invalid and the rule is preseason or training camp, find the matching season rule and subtract the preparation days.
  3. If still invalid, use the nation's season-window fallback.
  4. If adjustment is requested and the date was not imported, subtract three days for season and competition types (one day for first game), then move back to Monday.
  5. Finally move back to Monday and zero the time.

When several invalid rules fall to the same fallback, their small adjustments can land on the same Monday, which collapses the dropdown into fewer options (Confirmed, FM22 source).

Things that surprise people

Earlier start years

fm-re shows FM26 can start in 1995: a patched database was built and a headless start on 3 July 1995 runs, using England's nation rules repacked for build 26.9.0. Real birth dates for people and other nations' rules files are still to do (Confirmed for England only; fm-re docs/start-year-1995/).

The match engine

Football Manager plays a match as a series of tiny time slices. Facts below come from the FM22 source and from two projects that use it.

Basics (FM22 source)

Running the real engine here

me-harness builds FM22's engine, and has FM24 and FM26 running headless from the Mac builds. It plays a match in about 2 to 3.5 seconds, about 10 matches a second on 64 workers, and is exactly repeatable. Typical output is 2.55 goals a match across 1,000 seeds (me-harness, Confirmed). A worker takes JSON lines:

Your values
echo '{"id":1,"pkm":"{{PKM}}","seed":{{SEED}},"edits":{"synthetic":true,"neutral":true,"freeze":true,"tactics":[{"tac":"{{TAC}}"}]}}' | /home/rob/code/me-harness-claude/scripts/me-worker.sh --workers 1

"Synthetic" makes every player identical; "neutral" removes home advantage and weather; "freeze" stops AI substitutions. Results include goals, expected goals, shots, possession and a checksum.

What has been learned about tactics

FM26 positional engine

FM26 projects each player's pitch area using a temporary match simulation. fm-re recovered the cross-phase positional warning table (118 rows) and part of the grid scoring, but the full role-by-role table is still missing. Do not substitute FM22 weights for FM26 (fm-re, Likely/in progress).

Updates

Two different things are called updates.

Official updates

SI ships a new build as an extra database layer (for example 2620 on top of 2600). The layer has full replacements of the .dat files, so the newest layer is the whole current world (fm-reader, Confirmed). The MySQL database fm26_update comes from the 26.2.0 layer; fm26_release comes from the base layer. Use the update database first and fall back to release (fm-xml).

Community data updates

Groups such as sortitoutsi.net publish editor files (.fmf plus the equivalent .xml) that change players, contracts, clubs and competitions. They are split by topic: Player Attributes, Contracts, New People, England, and so on. Sizes vary enormously: a Player Attributes file has 1.57 million changes (397 MB as XML). Typical uses of the changes: release then re-sign contracts, create and delete people (ADDR/DELE), rewrite club league histories. Load order matters when several are installed (see Which file wins).

Glossary

afe.
Magic text at the start of an encrypted FMF archive. A normal one starts fmf..
AOM
Add-on metadata: the small _data/details.aom file inside an .fmf with title, description, tags and owner.
Attribute
A rated skill of a person, 1 to 20 on screen. See Attributes.
Build
A numbered release such as 2620 (26.2.0).
CA / PA
Current ability and potential ability, hidden 0 to 200 numbers.
.dat
A database file shipped with the game; an FMF archive of tables.
.dbc
"Database content": binary form of editor changes or configuration. Header magic cbd..
DBV
Database version, a counter for the database layout.
Editor / Pre-Game Editor / PGE
SI's tool for changing the database before a career. Makes editor files.
Fermat form
A packed id where both halves equal the uid: uid x 4294967297.
FMF
SI's archive format (like zip). See The FMF archive format.
FourCC
Four letters stored as one number, used to name properties and file types.
IL2CPP
Unity's way of turning C# into native code; FM26's screens are built this way.
Layer
One release folder of the shipped database (2600, 2620 ...). Later layers replace earlier files.
.lnc / .edt / .ddt
Language and name-change files / directive files that the game applies on top of the database.
Nation rules
The competition and calendar rules for one country. See Nation rules.
PI / TI
Player instruction / team instruction, stored as numbered bits in a tactic.
Sample
The word used in these repos for test data; "fixture" is reserved for football matches.
svvs / orvs / verf
Header fields giving the build last saved in, first created in, and verified against.
.tac
A tactic file, magic cat..
Team
One side of a club (or a national side). Distinct from the club.
uid / random id
A record's id within its table, and its disambiguator. See IDs.
zstd
A fast compression method used from archive version 8.

Open questions

Changelog