Goal Machine: build progress

Status page last updated 2026-10-28 · master 341c8a3b · this page built 2026-10-29 13:41 UTC

Complete86.8%
Done108
In progress34
Not started2
Areas / items8 / 144

Complete counts a done item as 1, an item in progress as ½ and a not-started item as 0, averaged.

Being worked on now

Updated 2026-10-29 13:41 UTC

Match engineThe defensive block at its real size is committed and in its full engine test suite. Next: marking, and getting men ahead of the ball.
Transfers and moneyListed players: the transfer-cap fix, wage demands that fall when nobody bids, and a visible reason why no club can afford him. Final checks.
World and peopleAI managers: boards in small, flat leagues expecting arbitrary places (ties broken by list order), then new managers judged against a target their predecessor left. Two fixes approved.
Interface and CzechTest reliability: finding which test leaves state behind for a flaky match test.

The tree

Match engine — SimV274% · 16 done, 18 in progress, 0 not started
Agent-based engineDone
Continuous per-player decisions, body collision, physical contests. 2026-10-21 (the lateral mirror, GM_V2MIRRORY): a side's sheet turns through 180° with the end it attacks, so its left-back plays on its own left in both halves, across from the other side's right-back. Before it, the side attacking toward x = 0 played every half upside down: a left-sided wide man's nearest opposing defender was the other LEFT back 56.6% of seconds, and is the right-back 55.8% now (512 runs, FLANK MEETINGS, SimV2LateralMirrorTest). The depth follows the end too: the throw-in's ranking and the wall's pick key had read the first half's depth in the second. 2026-09-27 (stage 5 batch 5, V2Contact): every body's wish bends round a body he does not mean to meet — the carrier and the men sent to him, and two men going for one loose ball, meet on purpose — and a contact takes the two men's approach out of their velocities: body contact 7.4% → 1.7% of body-ticks, a runner in contact on 1.5% of his run against 11.2%, the approach after a contact zero, the one-two and third-man rows unmoved (GM_V2CONTACT 27, SimV2ContactTest). 2026-09-27 (stage 5 batch 4): the engager arrives at the carrier's body instead of inside it. The only engine — the rule-based one was deleted. Its three decision cadences are audited (2026-08-15): team decisions at 4 Hz (or on a change of possession), steering at 10 Hz, physics at 20 Hz — and a team decision read faster than it is taken can be read on a premise the world has already falsified. A12 priced one member of that class at a fifth of a goal a match; all twelve team-scope decisions have now been walked with a verdict each and the result is that eleven are clean: markOf reads zero violations over 23 million looks because every one of its falsifiers is a possession trigger that re-solves within 50 ms, backfillOf is zero on all four of its exclusion falsifiers, the offside trap’s 7.5% is already guarded at the read, and the engager’s 0.67% is deliberate hysteresis that was measured and kept. The one defect was the deep block’s goalmouth station (GM_V2BOXFRESH): its entire gate is a fact about the BALL, which moves seven metres in the quarter-second between elections, so 63.4 looks a match — 22.5 of them a hard setDesired(urgent) with no man to mark — sent a defender to defend a goalmouth play had already left. Fixed by one shared predicate read by the election and by every read site. Its bill is a reading rather than a claim in both directions: goals 2.92 → 2.81 (~0.7 SE) and OPEN_CARRY 53.6% → 60.1% with its count 178 → 196 (~1.3 SE), with offsides slipping 4.01 → 3.83, just under its band. The census is a permanent STALENESS block of runSim v2, so the walk is a number to check rather than twelve call sites to re-read.
In the code: engine/…/match/v2/; engine-log The staleness audit
Engine seamsDone
LiveMatch (watched) and MatchSimulator.runToEnd (instant) are engine-neutral; a future engine arrives the same way.
In the code: docs/architecture.md
Injuries in playDone
One model in :model read by both engines and by training. 2.01 injuries/player-season against a real ~2.0.
In the code: docs/injury-model.md
Injury prevention: the fitness coach and the programmeDone
2026-10-19 (the owner's request of 2026-10-17): on soft-tissue injuries only, in all three paths (training, QuickSim's non-contact share, SimV2's background check): the fitness coach a little (±~10%, pivoted on the world's mean) and an extended prevention programme (structured warm-ups and Nordic work, ×0.85 on muscle injuries, ×0.97 on development, the elite figure from the literature). The manager sets it on the Training page; AI clubs with medical facilities 7+ run it. The medical screen shows the squad's muscle-injury risk and its three causes. InjuryPreventionTest; runSim injuries 2: 1.90 → 1.87 a playable player-season, 44 of 354 clubs on the extended programme.
In the code: docs/injury-model.md
Concussion protocolDone
SHIPPED 2026-08-19 (THE MOMENTS member 2, GM_INJCONCUSSION, and the arm lives in :model with the other injury arms because three paths can hurt a footballer). Concussion already existed as a kind; everything the laws say happens AROUND it did not. The match half: the injury KIND is drawn downstream in :model hours of simulated time after the whistle, so SimV2 has to decide at the treatment that a contact injury was a blow to the head — a HASH of (match seed, tick, man) rather than a draw, so the arm costs the RNG stream nothing, at a share derived from InjuryKind's own contact column (2.0% of contact injuries) so the two statements about how often one happens cannot drift apart. He is then removed permanently whatever the severity roll said (if in doubt, sit them out) and replaced by a substitute charged to neither side's allowance, capped at two per side, with the opposing side granted an additional substitution in reply; MatchEventLite.injuryHead carries the decision out so the world books a concussion rather than an ankle. The return-to-play half is :model's and therefore reaches a QuickSim fixture and a training week too: a concussion may not be shortened below its own six-day minimum by any medical department (medicalDurationFactor bottoms out at 0.65, so a strong one was returning a concussed man in three days), and a man who was treated and FINISHED the match may not be booked one at all (drawKindPlayedOn excluded only kinds longer than the played-on ceiling, and six days is well inside it). MEASURED on runSim injuries 3: 185 concussions, shortest lay-off 6 days against a minimum of 6, mean 8.5, and none under it. The match half fires about once in 130 matches — 2% of contact injuries — so it is measured on its own scaled arm: GM_INJCONCUSSION=8 over 160 full matches gives 4 head injuries, 100% of them permanently removed, 100% replaced by a free concussion substitute (none with an empty bench), and 4 additional substitutions granted to the other side. SimV2MomentsTest is its eval and runSim v2full its census. It did not need squad registration (roadmap 19), because both allowances are per-match quantities.
In the code: football-catalogue §8; docs/injury-model.md
OffsideDone
2026-10-23 (the realism batch, GM_V2LINEREAD): the passer reads a team-mate's margin to the line with an error, and the runner holds off the line as it stood a beat ago, so the ball in behind finds an offside man (0.04% → 1.18% of through balls) and offsides read 2.29 → 3.34 a match, still under a real 4-6. 2026-10-24 (GM_V2HELDFLAG): a held flag that meets another stoppage is given, so an offside attack no longer keeps the corner or free kick it won after the offence (~9% of held flags kept one; offsides +0.14 a match). The receiver is checked. Fixing it fixed the league's goal shortfall.
In the code: roadmap 15f, 15f-bis; engine-log The realism batch
Set-piece designerIn progress
Still missing: screen and short-then-cross templates, wide free kicks, free placement.
Stage 1 (2026-10-22): a routine per corner flag and five corner jobs named by slot, on Tactics → Design corners, with the AI choosing routines too and a per-corner log read back on the screen (worked share beside the drill, first contact and second ball against the league). Measured on 117 staged corners an arm: the routine moves first contact (flick 57.3% against AUTO 42.7%), a named target moves it down against the engine's own pick (30.8% against 76.1%), the second ball does not move. Missing: screen and short-then-cross templates, wide free kicks, free placement.
In the code: engine-log, the set-piece designer stage 1; SimV2CornerPlayTest
Set-piece routine engineIn progress
Still missing: the named taker's walk has not been re-read on a regulation (controller) match since the landing (the staged fix is SimV2CornerTakerWalkTest), and nothing prices the far-post arrival as a chance.
Every routine in catalogue §6 is built. Missing: the named taker's walk has not been re-read on a regulation (controller) match since the landing (the staged fix is SimV2CornerTakerWalkTest), and nothing prices the far-post arrival as a chance.
In the code: engine-log, corner member costs (2026-10-06); TASKS, the taker's walk
Chance qualityIn progress
Supply is in band since the 2026-10 landing (one-on-ones 0.54 / 0.70 a match). Still out: saves 4.83 / 5.10, conversion 11.8% / 13.5%, one-on-one conversion 28% / 30%, blocks and woodwork. OPEN_CARRY's share is reported, not graded (release plan C10).
In the code: engine-log, the 2026-10 calibration landing; AGENTS.md, where the league stands
The calibration passDone
The one deliberate pass (2026-09-02): nine constants, five pinned 512-run cycles, worst-deviation-first. Closed: goals 2.06 → 2.79, conversion 10%, saves 6.17, reds 0.28, cards per foul 0.158 (the honest denominator), miscontrols 77.5 → 54.5, penalty frame 6-7% → 4.25% (bench-guarded), illness 0.86 → 0.81, and the 0-0 rate IN BAND on the standard world (8.1% on v2dist 768). Every row still out of band carries a diagnosed cause and a measured non-lever in the residual table — engine-log § THE CALIBRATION PASS, which is the closing statement.
Release calibration (stage 5)In progress
2026-10-10, the landing. The candidate's mechanics and nine calibrated dials are default. Eight calibrated dials were refused because two of them switched a mechanic off: a front commit base of zero leaves the challenge decision on its floor, and urgent approach 0.9 brakes every urgent runner from seven metres out. Of the owner's must-pass core, shots, fouls and cards are in band on both worlds and goals on 20250717 (2.97 / 3.58). On target (7.95 / 8.85), saves (4.83 / 5.10), conversion, passes (913 / 965), tackles (66), take-ons (67.5) and distance (9.82 / 9.78 km) are open. 2026-09-27, batch 5. GM_V2CONTACT 27: every body steers round a body, the contact absorbs the approach, and the challenge's win pivot is re-derived on that physics, giving back the parent's yield and take-on completion on both worlds; the foul's clean moment inherited the same defect and its re-derivation breaks the take-on guard, so it waits with its arm. Penalties (C11), reds (D8) and cards per foul (D9) enter their bands on both worlds; take-ons (52.2 / 52.4) leave theirs, because commitments per arrival rose 16.9% → 24.1% — a defender pressed against a man reads as set — and nothing that priced the pinned population can give that back. Tackles 63.7 / 65.6, fouls 24.6 / 25.3, goals 1.79 / 2.20. 2026-09-27, batch 4. GM_V2CONTACT 2: the engager arrives at the carrier's body instead of inside it. Fouls (D5) now pass on both worlds (25.7 / 25.4); tackles fall 50.8 → 43.0 and take-ons stay in band; reds and cards per foul fall just under their bands on the standard world. Distance does not move: the collision was 0.6% of it. The contact that absorbs the approach is built and off, waiting on body avoidance for every body and the yield it re-prices. 2026-09-26, batch 3. GM_V2CHALLENGE 11: the challenge volume was looks, not commit probability. Cards per foul (D9) enters its band on both worlds; fouls pass on world 42 (29.7) and miss by 0.26 on 20250717; take-ons, their completion, yellows, reds, blocks, one-on-one supply and the one-touch share stay in band. Goals (1.89 / 2.24), shots, on target, saves, tackles, committed challenges, fouls per commitment, passes, offsides and distance stay out. The passes row's arms still cost 0.092 tackles a pass. 2026-09-26, batch 2. Bit 64 of GM_V2SHIELD (default 125): no ordinary shield beside a shot. Graded on both worlds for the first time: one-on-one supply (C7) passes; goals pass on 20250717 (2.44) and not on 42 (2.36); blocks, one-touch share, yellows, reds, take-ons and take-on completion pass; shots, on target, saves, conversion, passes, completion, tackles, fouls, offsides and distance stay out. The career rig no longer lets the board sack the measured club's manager. 2026-09-25. The acceptance matrix is frozen: 46 rows on two worlds, each with instrument, denominator, band and source, several marked for the owner to confirm. Batch 1 corrected supply and opportunity before probability (bits 16 and 32 of GM_V2SHIELD). Take-ons enter their band on the harness; goals (1.53), shots, on target, saves, one-on-one supply and conversion, tackles, fouls, offsides, passes and distance remain outside theirs, and the held-out harness world has not been run.
In the code: docs/engine-release-plan.md § Stage 5 acceptance matrix; engine-log Stage 5 batch 1
Restarts (throw-ins)In progress
Throw-ins 38.8 / 35.75 against 40-45: little play in the outer five metres (TASKS A2). Corners are back in band at 10.05 / 10.19 since the 2026-10 landing.
In the code: engine-log 2026-08-22 and the 2026-10 landing; TASKS A2
Balls in the airIn progress
2026-10-23 (the realism batch): a man the ball drops within two strides of goes up for it (the step, GM_V2AERIALSTEP 1.2 → 2.5): the contested share of contacts at heading height 21% → 28% against a real ~25-35%, headed goals 0.45 a match, corners 4.9% → 7.8% of goals. The aerial row reads 16.79 against 20-25: it is a count, the share is the behaviour.
In the code: roadmap 39; engine-log 2026-08-11, 2026-08-12 and the 2026-10 landing
Aerial ability, read consistentlyDone
One aerial expression since 2026-08-23, and the wall stands and jumps since 2026-08-24 (SimV2CorrectnessTest, SimV2RoutineTest; readings 189.23 → 189.93 cm, and 2.15 m against 1.70 m).
In the code: engine-log, THE ONE AERIAL EXPRESSION and THE WALL JUMPS
Home advantageDone
The engine has a modelled home advantage since 2026-08-13 (Lane E, V2Venue) and the row it was built for did not move. Three pieces, one chain: crowdVoice (how loud this ground is right now — gate size against a floor, how alive the game is, how late it is), a REFEREE drawn per fixture from the match seed with a strictness and an ear for the crowd, and his lean on seven marginal calls plus the fourth official's board. Measured paired at 512 runs: fouls away-to-home 1.12 → 1.16 (real ~1.10), cards 1.10 → 1.19 (real ~1.25), added time +26 s with the home side a goal down against −17 s with them a goal up over 40 full matches. At league scale it is worth nothing one season can see — 30.79% home wins against 31.15% on the pre-change tree, while the five QuickSim neighbours nothing could reach moved by up to 5.2 points. And the arithmetic that explains why is the lane's real output: away wins are already on their band (30.5% against a real ~30%), so the 13-point home shortfall and the 12-point draw excess are the SAME points. This engine does not lose too many home games, it draws the ones it should win — see the Draw rate row. Travel is measured and deliberately not built: the median away trip in the division the full engine plays is 130 km. Since 2026-10-22 the official is named (Officials): a panel per played division, one referee for every club of it (a top flight's men do not do third-tier matches), each keeping his strictness and crowd ear for good; the match preview names him, says his strictness in words until he has five matches and in numbers with its basis after, and the report names him with the fouls he gave (OfficialsTest). Only matches played in full go on a record, so a referee of a division played on paper always reads in words: nobody sees those matches. Since 2026-10-24 a played league's page lists its referees (Referees chip): most matches first, each told by the same words-or-numbers switch as the preview (Officials.recordBasis), with last season's figure. Ground familiarity: not modelled, by decision (~0.1 goals in football, below resolution; dimensions have no tactic to use them; roadmap 15). The outcome gap lives on the Draw rate row.
In the code: engine-log Lane E; football-catalogue §8
Refereeing as a personDone
Every match in the world used to be refereed identically — something the rule-based engine had and SimV2 lost. V2Venue.refereeStrictness gives each fixture an official ±18% off the average one, SYMMETRICALLY (he gives more to both sides, so it is not home advantage in disguise), hashed off the match seed so he costs no RNG draw and the same fixture gets the same man on a replay. Measured over 400 fixtures: mean 0.992 spanning 0.823–1.179, with GM_V2REFEREE=0 collapsing every one to exactly 1.0. It adds variance between matches without moving the league — the DISCIPLINE total is 20.60 → 20.68 at 512 runs, which is the correct signature. One of the four golden-digest fixtures drew a referee with an ear of 0.006 and is byte-identical under the whole mechanic, which is what "a referee is a person" means.
In the code: engine-completeness § officiating
Draw rateIn progress
2026-10-10: one fresh season per world on the landed engine, 276 fixtures each: draws 38.0% / 33.3% against 23–30%, home wins 29.7% / 33.7% against 40–48%, away wins 32.2% / 33.0%, goals 2.74 / 2.71 a fixture inside 2.4–3.0. Single seasons, so shape only. 36.95% against a real ~26% at the post-calibration pinned leaguecheck (2026-09-02), from 42.75% — six points bought purely by the goal rate coming home (2.38 at league scale), with away wins back ON band at 30.08%. The remaining excess (~11 points) IS the home shortfall (~11 points) — one deviation, not two, fifth consecutive reading of that sentence, and it survived a +0.45-goal movement untouched. roadmap 15; engine-log Lane E, THE CALIBRATION PASS
Decoy runsDone
Shipped on: 30.1 runs a match and 88% take the marker, with GM_V2DECOY=0 as the paired arm. A side managing the clock suppresses them; the shape-composition and backfill work removed the blocker that originally parked the mechanic.
In the code: engine-log 2026-08-05; roadmap 14c, 40
Combination and coordinated movementIn progress
2026-10-10. Since the landing a trapped carrier keeps his choice for its interval (GM_V2SHIELD 893). One-twos read 29.5 runs a match with 6.33 returned against 39.0 and 8.14 before, the same 21% of runs; third-man runs read 10.66 with 2.38 found (512 trials, 20250717). 2026-09-25. The nearby election now admits an already-close man just ahead and retains incumbency only while close. Final-third supply improves 0.3902 → 0.4054 at 512 paired trials, t = 3.06; the selected man stands 0.365 m closer. The previous reader and planted-pocket approaches remain refused. One-twos, third-man combinations (OffBallRun.THIRD_MAN, 13.54 runs to 4.33 found at 512 runs), overlaps, underlaps, runs in behind and decoys all exist. The blindside run shipped 2026-08-13 (A8, GM_V2BLINDSIDE) and closes tactics §9's honest limit 5: a man breaks into the channel beside a defender who has stepped out of his own back line and cannot hold both him and the ball in view — 23.7 a match at 512 runs, off a man genuinely 7.97 m out of his line with his body turned away (facing dot −0.68), 13% of them found by a pass. Its finding is worth more than its size: the run is not the mechanic, being LOST is — the second half is a marker who has lost a man that way losing his 0.55 s of anticipation, and without it the runner's room is flat at every age of the run (3.81 → 3.92 m) against 3.73 → 4.21 m with it. Half a metre, and nothing measurable in any harness row. Short support in the final third shipped 2026-08-15 (A12, GM_V2SHORTSUP) and it is the first thing in this engine that sends a man TOWARD the ball rather than past it: with the carrier in the attacking third and under pressure, up to two men behind the ball are elected to show for him and stationed six metres from it, under a body-count guard on the recovery race. Measured paired at 512 runs and graded on SUPPLY, never on completion — team-mates inside six metres of a final-third carrier 0.22 → 0.30, with a clean lane 0.08 → 0.11, and the elected man's realised distance from the ball 12.25 m → 10.46 m. It did not bunch the attack (same-line pairs 1.76 → 1.75) and it did not cost the rest defence a body (cover at the turnover 2.94 → 2.97, breakers nobody covers 0.23 → 0.23), because the man sent was already goal-side of the ball and stays there. Its finding is worth as much as its size: two placements were built and rejected first, because no PREFERENCE in this engine can produce a six-metre support position — the principle ring reaches eleven metres from a target that never converges on the ball, and seekSpace alone shoves a support spot four to six metres back out. What was missing was an instruction. It cost +0.15 goals (2.77 → 2.92, about one standard error) and OPEN_CARRY fell 63.7% → 53.6% of goals with its absolute COUNT falling too, 202 → 178 — the first change in nine to move that count; penalties, offsides and corners all came into band with it. A quarter-second of stale 4 Hz election was worth a fifth of a goal a match: the election refuses anybody on an off-ball run and a run starts between elections, so the pull has to refuse him again at the point of use — adding that guard took goals 3.12 → 2.92 on its own. OFF-BALL SHAPE shipped 2026-08-17 — four errands, and all four MOVE A MAN (V2Elections.kt; GM_V2POCKET, GM_V2RECOVER, GM_V2BIGPITCH, GM_V2SCREEN). It was scheduled third in the queue because it was the one most likely to fail: A14 and THE CHANNEL had both built a mechanic of this shape, measured it paired at 512 runs and reverted it (0.12 m and 0.004 m of realised movement). What beat that ceiling is that every member is a hard assignment or clamp on exactly one axis, read last, leaving every other layer its say. Dropping into the pocket — the band between their two lines, computed from the four deepest opponents against the next three — is a DEPTH clamp: the elected man stands 4.84 → 4.31 m beyond the band, t = 7.05. The recovery is a SPEED and not a station, because every man caught up the pitch went home at a flat maxSpeed * 0.7 with an empty net the only exception in the engine; the quota is the size of the break (raceUnanswered), so one man comes back for a one-man break and nobody for a covered one — 14.14 → 12.58 m off his own station, t = 4.83. Making the pitch big is the one that overturns a rejection on the seam that rejection named: every width dial in the engine is a multiplier on offset-from-centre and the widest lane available is 6.2 m, so it is a HARD LATERAL ASSIGNMENT instead — 13.82 → 12.33 m from his own touchline, t = 8.79, channels occupied 4.09 → 4.18 of five, moving carry goals 214 → 196 (−18, 0.89 SE). Screening a lane puts a spare defender ON the ball the delaying engager only shades toward: 8.17 → 6.02 m off the lane, t = 23.46, and it discharges the catalogue's standing warning that closing lanes inside the block might push carrying UP — on its own arm on the shipped tree it moves carrying DOWN (223 → 196, −27, ~1.3 SE) and is the batch's largest single-member mover on that row. Batch bill as one paired reading: goals 3.22 → 2.83 (~2.6 SE, the largest single step the goals chain has taken), OPEN_CARRY's count 203 → 196 — about 0.35 SE, nothing — on a total of 360 → 314, so the share reads 56.4% → 62.4% and every point of that is the denominator. Four band memberships gained (offsides 4.08, throw-ins 40.97, reds 0.22, cards home/away 1.27) and one lost (blocks 4.84). Distance 11.21 → 11.33 is a cost with no owner — no single-member arm reproduces more than 0.06 km of it. The batch shipped a defect that the gate caught and every figure here is the SECOND measurement: the touchline election was eligible to pick an INVERTED_FULL_BACK, whose whole identity is coming inside, and a hard lateral assignment read last beats a role anchor — the role eval collapsed to t = 1.38 from 4.24. Excluding any role whose v2RoleAnchorShift width is negative fixed it, and the re-measurement moved every aggregate while the metres bars moved by hundredths (the touchline 1.50 → 1.49 m), which is A11's rule for the sixth time. The withdrawn first-form claim — the largest movement OPEN_CARRY has ever had — is recorded in the log rather than quietly dropped. Two of the cycle's own claims were refuted by its own attribution arms: the distance rise is not the recovery's bill and the carry movement is not the screen's. Still missing: a chosen rest-defence structure, and checking to feet outside the final third or as a receiver's own decision. Spatial overload RECOGNITION shipped as phase 5c — see Body counting.
In the code: football-catalogue §§2, 7; tactics.md phase 5; engine-log A8, A12
Receiver-aware passing and deliveryIn progress
Still missing: the struck ball (lead, pace, foot) does not read pressure on the receiver, and the short game's completion curve is flat (74.3% against 77-83%).
Target and ball are fitted to the receiver (5b), and disguise, dummy and back-heel shipped with DECEPTION (2026-08-17). Missing: the struck ball (lead, pace, foot) does not read pressure on the receiver, and the short game's completion curve is flat (74.3% against 77-83%).
In the code: engine-log 2026-08-15 and DECEPTION
Body counting and rest defenceDone
Phase 5c (2026-08-09) put a body count in the match for the first time — countBodies fills each side's men ahead of and behind the ball on the team-decision cycle, localSpare gives the man on the ball his local numbers — and the BEHAVIOUR half shipped on 2026-08-15 as A11, after being measured and rejected twice. Both rejections died on the same reading: the side in possession looked short in 2% of in-possession cycles. That was the cover count's fault — behindBall only asks whether a man is goal-side of the ball, so the far-side full-back forty metres from the play counted — and countRecoveryRace (2026-08-11) replaced it by racing every man to his own goal against the first breaker at the speed he can actually run: 2.96 cover against 7.5 by geometry, short in 19% of cycles against 2%. A11 then added the price the count could not give. raceDeadline is the earliest clock at which the deficiency is worst, so a man's distance from his own goal minus deadline × his own top speed is how many metres short he is — and the cheapest candidate is 2.18 m short, under five metres 89% of the time, out of 3.42 candidates a cycle. So the ask is two metres of one man rather than a recall of the attack. electRestDefence holds up to two NAMED men (never everybody: the first rejection was a principle term that moved every off-ball station and cost five unrelated evals their resolution) inside that distance, as a depth clamp read last in decideAttacker so the width instruction, the channel hold, the space nudge and the principle ring all keep their say. The second half is the hole Lane D's step-out carry shipped with open on the record: assignBackfills covered a station only while the OPPOSITION had the ball, so nothing covered the space a centre-half left when he drove out with it. Measured paired at 512 runs (GM_V2REST): breakers nobody covers 0.24 → 0.20, cover at the turnover 2.94 → 2.98, short by the race 19% → 18%, the elected man stands 2.37 → 1.26 m beyond his own recovery line over 1.36 M looks, and the driver's vacated station goes 0% → 84% covered on 745.85 looks a match. The aggregate bill is +0.23 goals (about 1.5 standard errors, a reading), with one band membership changing — corners 10.92 → 9.82, 0.18 under the low edge — and offsides going the other way, 3.83 → 4.05 and further inside its band. The election also had to learn to refuse a man AHEAD of the ball. A side's rest defence is by definition the men behind it; the first cut left that gate out on the argument that the cheapest man is never a striker, which is true with ten outfielders to choose from and false with two — a scenario staging a carrier and one forward duly elected the forward and clamped him off the last line. An election that runs out of candidates does not fail safe, it elects the wrong man. Two findings from 5c are still REFUTED and kept in the open: playing against ten men does not improve your local numbers at all, and losing a man barely worsens your own. Still not here: overload instructions, attack-commitment dials, LIBERO.
In the code: tactics.md §5 5c; engine-log 2026-08-15 A11
Pressure-side defendingDone
2026-10-25, who covers: the press's cover is elected for his own point (GM_V2COVERPOINT) rather than as the second man to the ball; not from a man holding an attacker in behind; cover-time within a metre of his point 22% → 38% at 512 paired on both worlds, arrivals and committed challenges down, passes −10 a match, goals unresolved; the whole engine suite green on it. Phase 5a (2026-08-09): Steering — SHOW_OUTSIDE (the pre-5a engine), SHOW_INSIDE, WEAKER_FOOT — read by steerShade in both engage branches, so which way a carrier is shown is a decision rather than a hard-coded side. Graded on where he WENT: 10% of looks infield shown outside against 42% shown inside, at a measured cost of 23.0% of conceded final-third entries through the centre against 36.7%. Show-onto-foot per NAMED opponent followed the same day (SHOW_OUTSIDE / SHOW_INSIDE / SHOW_WEAKER_FOOT resolving in steeringOn, beating the team dial for the man they name and nobody else), and 3g gave the delaying engager the lane screen. GM_V2STEER=0 is the exact arm. The ENGAGER'S APPROACH is a measured rejection twice over now, and the second attempt says why (2026-08-16). Leading the carrier — running at where he will be rather than at where he is — works, and it exposes that the station he is led to was never a jockeying position: the goal-side chase aims 1.06 m from the carrier, i.e. standing on him, and it survived only because a tail chase never got there. Lead alone takes the realised standoff 2.70 → 2.53 m and the share inside two metres 22% → 50%, with tackles 31 → 55 and take-ons 66 → 197; lead plus a real 1.8 m close-down station makes the station reachable (ask-to-stand 1.64 → 1.15 m) and moves the graded row 2.70 → 2.95 m, the wrong way. 2.69 m is what a pursuit curve leaves behind, not a number anybody chose. What shipped is the ENGAGER APPROACH census, which is the row any third attempt is graded on — and that attempt has to change what a defender DOES on arrival, priced against commitsToChallenge's third-of-a-second cadence.
In the code: engine-log 2026-08-09; football-catalogue §4
The surface and the airIn progress
BATCH 5, 2026-08-25. Weather.slipChance had been declared since the engine was written, was read by the rule-based engine until that engine was deleted, and was never read by SimV2 at all — so nobody slipped, which is the single most visible thing bad weather does to a football match, and BALANCE had exactly one read in the whole engine. Both halves ship: the wet surface and the PLOUGHED one, which can take a man's feet away in dry weather. Sized off the census rather than a feeling — 34,045 player-seconds a match at pace, 0.4% of them planting and turning — and it is graded PER LOOK, because on a dry day at a good ground sweepSlips returns before its first draw and the population is empty by construction. Temperature and humidity ship too, derived from the venue's latitude and the fixture's month, so a June trip south costs a body about 22% more than an April match in the north and an international summer tournament is physically a different game. ALTITUDE is the named residue: no venue in this world carries one, and a field the generator never fills is worse than no field — it needs data before it needs code.
In the code: MatchLoad.kt; V2Physics.kt; engine-log 2026-08-25 THE BODY
Defending as a physical actIn progress
2026-10-10, the landing. Committed challenges 191 / 189 a match against 55–75, tackles 66.0 / 65.7 and take-ons 67.5 / 67.3 (512 trials a world). A calibration that reached 62.7 by setting the front commit base and patience to zero was refused: it left the decision on its 0.05 floor, so TACKLE_HARD, EASE_OFF and stays on his feet did nothing. Fouls per commitment 13.7% / 13.6% against 22–30%. 2026-09-27, stage 5 batch 5. The contact that absorbs two bodies' approach ships with every body steering round a body (GM_V2CONTACT 27): a defender pressed against a man is SET now (closing into him 2.14 → 0.03 m/s at a committed challenge in contact), so in contact he commits on 40% of his looks against 22%; the win pivot, priced on the pinned population, is re-derived and gives back the parent's yield (40% won per commitment; 43% in contact, 36% free). He fouls on 12% of commitments against 16%: the foul's clean moment inherited the same defect and its re-derivation breaks the take-on guard. Still Partial: commitments per arrival 24% against A16's 18%, committed challenges 179 against 55–75, tackles 64 — the moment's floor cannot reach it and the presser going round the carrier costs the duel. 2026-09-27, stage 5 batch 4. The man going to the ball arrives at the carrier's body plus a gap he chooses (GM_V2CONTACT 2) — tight to a man with his back to him, a jockey's distance from one facing him — instead of steering at a point inside him: against the man on 16% of his chase cycles against 22%, 78 fewer arrivals into standing reach, tackles 50.8 → 43.0, fouls 30.3 → 25.7, the yield of what he goes in on unchanged. Still Partial: the contact that absorbs two bodies' approach is built and off, because every body steers in a straight line and the challenge yield was priced on the pinned population; tackles and committed challenges stay above their bands. 2026-09-26, stage 5 batch 3. A defender does not take a standing look through the carrier's body, or while still arriving at a man who is not running (GM_V2CHALLENGE bits 1 and 2): looks per arrival 0.92 → 0.70, balls won per front commitment 35.3% → 38.8%, fouls 36.9 → 30.3, tackles 55.4 → 50.8. The professional foul is asked at a look he declines (bit 8): 0.54 → 1.56 a match. Still Partial: tackles and committed challenges stay above their bands, won at set moments, and two thirds of the zero-moment looks were a defender pinned against the carrier with his velocity uncorrected by the collision, a physics residue named for its own batch. 2026-09-25, stage 5 batch 1. A defender behind a shielding man's body waits for the ball instead of taking a look through him every third of a second: looks per arrival 1.19 → 0.92, balls won per commitment 31.9% → 35.8%, fouls 46.0 → 36.6, tackles 63.1 → 57.6. Both stay above their bands. A new row for a gap that had none, and the shipped half is what makes the rest legible. A cross can be blocked (A3, 2026-08-10) — the whole body-block sweep sat inside if (ball.flight.isShot) and a cross is not a shot, so every wide entry in this game was settled in the air and tackling, timing and bravery had nothing to bite on against a delivery. Measured paired at 512 against GM_V2CROSSBLOCK=0, which is the pre-A3 engine bit-for-bit: 2,092 of 6,603 crosses blocked (31%) against 0, corners 8.89 → 9.76. Blocking a SHOT, intercepting in the lane, the loose-ball race and jockeying at arm's length are all real. THE SLIDE TACKLE SHIPPED 2026-08-16 (A9, GM_V2SLIDE) and the challenge is three acts now rather than one function with a flag. A slide is reach bought with commitment: standing foot reach ends at 1.6 m and a man along the ground gets to 3.1 m, gated on him sprinting AT the ball with the gap NOT closing, and priced with lungeCd = 34 set before any outcome branch — 1.7 s on the grass whether he wins it or not, against the 8 ticks a beaten standing tackler needs. It carries its own foul term, its own SLIDE cause and its own card profile, including the challenge from behind at pace that is football's only ordinary straight red. Measured paired at 512 runs: 10.02 a match against a real ~4–10, 45% making contact, 23% winning the ball, 5% carded, 17.03 s a match of a defender lying down. The row it was AIMED at is not its grade — tackles 30.32 → 31.45, a ninth of a 5-tackle deficit — and two rows went out of band with it, both recorded for the final calibration pass: reds 0.11 → 0.33 (only 0.026 of that is a straight red from a slide; the rest is second yellows) and cards away/home 1.19 → 1.39. The RATE was the mechanic: the first cut had the geometry alone and fired 175 times a match, because "somebody is chasing the ball" is most of a football match. Still absent: the sliding BLOCK of a cross or shot. The clearance off the goal line shipped 2026-08-18 and the man who is kept there for it shipped 2026-08-21 (GM_V2LINECLEAR, GM_V2POSTMAN): the act is 0.11 a match on 57% of its pictures, and one defender now stands on the near post at every corner, 0.06 m from it when the ball is struck. AND THE CHALLENGE'S RATE IS NOW MEASURED AND WRONG (A16, 2026-08-16), which is the half this row is partial on: a defender inside standing reach commits on 62% of every 0.3 s window and gets 0.30 windows per arrival, so the engine plays 168 committed challenges a match against football's ~55–75 and only 19% of them become a TACKLE event where football's convert nearly all. The visible rows are in band on that product, not on the act. Turning the dial down is a measured rejection (GM_V2TACKLEAGG=0.5: take-ons 61.49 → 41.27 into band, tackles 31.2 → 20.8 further out), so the target was a challenge that HITS something more often — sized at ×0.73 on the rate bought with ×1.4–1.5 on its yield, and BUILT the same day (see below). CHALLENGE CADENCE in runSim v2 is the instrument. AND THE THIRD ACT IS THE WORST OF THEM (A17, 2026-08-16): the poke from behind runs 46.29 a match against a derived ~8–15 — a defender tight behind a carrier commits on 26% of every half-second window and gets 0.34 of them per shadow, over 306.96 s a match of shadow, which is MORE than the 202.93 s anybody spends inside standing reach. It wins the ball 2.7% of the time and concedes a free kick 15% of the time, and it is absent from the take-ons row by construction, so its only visible output is 6.95 of the league's 23.13 fouls. That is the same arithmetic as the tackles row one row up: the fouls row is in band because a 2.7x challenge rate is multiplied by a 13.8% per-challenge foul rate against football's ~21–32%. TRAILING CADENCE is the instrument, and the ×0.26 it wanted had to ride with A16's yield rise — which is exactly what happened. AND THE CHALLENGE IS TIMED NOW (A16 + A17, THE CHALLENGE batch, 2026-08-16), which is the half this row was partial on. challengeMoment asks the question a coach shouts and neither challenge decision asked: is there a ball to take, and is his own body under him — ballExposure (which side of the carrier's body the ball is on, from this defender's point of view) MULTIPLIED by whether he is set (his own closing speed on the man). Multiplied rather than summed, and that was measured: as a weighted sum, a defender being run at by a dribbler and one who had matched a carrier side-on scored the identical 0.55. It is read TWICE — once to decide, once in attemptTackle to price whether he gets the ball or the man — and the poke from behind gets the same permission. MEASURED paired at 512 runs: committed challenges 168.20 → 109.76 a match against football's ~55–75; a front challenge makes contact 49% → 67%, wins the ball 29% → 36%, and is a foul 13.8% → 20.9% of the time against a real ~22–30%. The poke 46.29 → 16.09. The grading row is one subtraction's SIGN: the old engine went in at a moment WORSE than the average it was offered (0.23 against 0.21), because danger and cover pushed it into geometrically poor challenges and nothing pushed back; it reads 0.22 offered against 0.24 taken now. And the batch rule is measured for the first time in this repo: A16 alone puts the fouls row at 28.74 and A17 alone at 18.33, against a control of 23.13 and a real ~22 — one out high, one out low. Together, 22.94. What is still open is the LEVEL, and it is why this row stays Partial: 109.76 committed challenges is still 1.5–2x football's, the yield came in at ×1.23 against a sized ×1.36–1.52 because selection is worth only 0.02–0.03 of the moment, and tackles fell 31.20 → 28.41 against a real ~35. The gate then caught an ACCOUNTING defect the batch had made load-bearing, and it is fixed in the same commit: a take-on the DEFENDER FOULED was booked as one the dribbler FAILED, so takeOnsCompleted / takeOnsAttempted read one minus the defender's win rate plus his foul rate — the same shape as the first-time pass booked as a failed pass. A provider's take-on asks whether he beat the man or LOST THE BALL and a fouled one did neither. Corrected: 61.49 att/50% → 54.27/57% on the pre-batch engine and 45.87/33% → 36.19/42% on the shipped one, with the fouled ones printed beside the row. The football is untouched — one line of the 512-run output moved on each arm and the golden digest passes on unchanged literals. It also changes what the batch achieved there: take-ons went THROUGH the 40–50 band (4.3 over, then 3.8 under) rather than into it, and the extra cut is the foul rate rather than the timing gate. AND THE CLEARANCE OFF THE LINE EXISTS AS OF 2026-08-18 (THE FINISH member 4, GM_V2LINECLEAR), which is one of the two things this row has been naming as absent since it was written. It is the THIRD act built as reach bought with commitment after A9's slide and A17's poke: the band between the block sweep's 1.05 m and a 2.4 m lunge, on a ball that is GOING IN inside the last 3.5 m with the keeper beaten, paid for with 0.8 s on the grass. It has its own feed event (GOAL_LINE_CLEARANCE, deliberately not SHOT_BLOCKED), the clearance is booked to the man, and the shooter's attempt is marked ON TARGET because by definition it was going in. MEASURED at 512 paired: 0.11 a match against a real ~0.2–0.3, on 57% of the 0.19 pictures a match, 66% of them put behind for a corner — and the blocks row is UNTOUCHED BY CONSTRUCTION (4.84 → 4.81), because a man inside the block radius is still a block and its own eval asserts it. What is still missing is the DELIBERATE half: v2DefensiveBoxStations's deepest station is 5.5 m off the line, so nobody stands on the post at a corner — that is staging, and it is now a member of SET-PIECE REMNANT. And the picture had to be found rather than reused: goalBoundLooseBall projects height with gravity and no floor, so a ball ROLLING into an empty net is not "goalbound" until it is 1.4 m from the line, which is a TASKS.md line of its own. AND THE SLIDING BLOCK SHIPPED 2026-08-22 (A15, GM_V2SLIDEBLOCK), which is the last thing this row was still naming as absent. It is a different code path from A9's — updateBall, where the blocks and deflections live — and its geometry is the goal-line clearance's moved out from the line rather than the slide tackle's: measured against the ball's own LINE and not this tick's segment, ONE LOOK PER FLIGHT, in the band between the standing sweep's 1.05 m and a body's length at 2.55 m, with a 0.70 m ceiling because a slide covers the ground and a ball over him goes over him. The commit and the connection are two separate numbers and the second is the point: a man who goes down and misses is lying there while the ball runs on. MEASURED at 512 paired: 0.81 a match from 12.27 pictures a match — 10% went to ground, 65% of those got in the way, 70% of them on a shot — 2.12 s a match on the grass and 0.43 a match of a man going down and missing it, with the stretch 0.51 offered against 0.45 taken. Graded on the act and never on the blocks row — though that row is worth reading for what it says about SUBSTITUTION: 4.93 → 5.50, so 0.57 of the 0.81 slides are blocks that would not otherwise have happened and the other quarter are balls a standing block would have taken later in the same flight. AND THE CHALLENGE'S NUMBERS MOVED AGAIN ON 2026-08-17, from the ATTACKING side (THE TOUCH): once a carried ball is a real ball rather than a point glued 0.7 m in front of its carrier, there is something there to take. The ball spends the same 203 seconds a match inside a presser's standing reach and the commit rate per window is unchanged at 42% — nothing about any defender's willingness moved and commitsToChallenge's constant was not turned — but arrivals last longer and present 35% more matured windows, because directReachTicks wants three CONSECUTIVE cycles and a rolling ball flickers across the 1.6 m boundary far less than a glued one, so front challenges go 82.44 → 110.63, the moment offered/taken 0.22/0.24 → 0.24/0.28, tackles 28.41 → 39.19 and fouls 22.94 → 27.48, both out of band. And A17's poke had to be RE-DERIVED or it would have died: a shadow needs the defender inside 2.05 m of the BALL as well as 1.55 m of the body, and 2.05 is 1.35 m of body plus the 0.7 m a carried ball was glued in front of its carrier — a constant derived from the constant this batch deleted. Left alone it read 16.09 pokes a match → 2.38, and the two scenario evals that stage one reported the scene never staged a trailing challenge at all. V2_TRAILING_BALL_TOUCH is the same arithmetic done again (2.5, reading 21.24) and it rides GM_V2TOUCH's own gate, because ungated it widens the control arm too. A constant derived from another constant inherits its death. The slide moves the same way, 11.23 → 5.07, and stays in its band.
In the code: football-catalogue §4; engine-completeness § defending; engine-log 2026-08-16
Fouls and contact away from the ballDone
Nobody could be fouled in this engine unless he had the ball, and that was true for its whole life: both handleFoul call sites required the victim to be the ball carrier. So a shirt-pull on a runner, a block on a near-post run, a forearm in an aerial duel, a charge through a man's back, persistent infringement and dissent were not rare — they were impossible by construction. BATCH 3 (2026-08-24, V2Offence.kt) gives handleFoul a third call site that asks nothing about who has the ball, and six members hang off it. The instrument came first and decided every constant: 2,777 off-ball engagements a match (two opponents' bodies in contact, neither owning the ball, the ball more than 5 m away), 55.5% of them a marker and the man he picked up, 10.2% inside a penalty area — so every rate is per ENGAGEMENT and two orders below what the offence feels like. Measured paired at 512 runs: the hold 0.38 and the block 0.85 a match, the shoulder charge 671.54 a match costing the man who loses it 0.36 m/s of 5.09 (the first time a body in this engine changed another body's velocity rather than only its position) with 0.62 of them a foul, the open-play aerial offence 0.57 a match on 3.1% of the 18.18 two-man duels a match against a real ~4-5%, a lost aerial duel committing a body 18.19 times a match for 0.24 s, and dissent 0.34 a match — the first card in the game with no foul in it at all. Batch bill −0.23 goals (1.5 SE) and OPEN_CARRY's count 214 → 193. The aerial member shipped with a DEFECT and a scenario test caught it in the gate — it charged the climb against the man who WON the ball on the majority of aerial contests — so every number of that member here is a re-measurement and the first published set is superseded. The cost is written down rather than tuned away: fouls 27.18 → 29.52 against a real ~22, a row already out of band, which belongs to the single calibration pass. THE OFFICIATING RESIDUE (2026-09-01) closed most of what was left: the SPOILER's push in the back ships (GM_V2SPOILPUSH — 0.55 a match of 13.38 spoils, free kick to the ATTACKING side, its draw taken before the spoil gate so the scenario pairing survives) and advantage is now played on an off-ball foul whose side is breaking through its CARRIER (GM_V2ADVOFFBALL, 0.18 of 0.32 eligible a match). Still left: no airborne STATE on a player (physicality, not officiating; only a commitment window on the man who loses a duel). The foul on the KEEPER shipped 2026-08-29 (GM_V2CLAIMPRESS).
The laws the official appliesIn progress
Still missing: a penalty awarded on review, a card upgrade or violent conduct, and offside for interfering as an act.
Since the 2026-10 landing: the dropped ball's recipient, Law 3's replacement keeper and Law 10's shoot-out; rebound offside on staged cases (SimV2LawPathTest); an abandoned match shown in English and Czech (visual review only). Missing: a penalty awarded on review, a card upgrade or violent conduct, and offside for interfering as an act.
In the code: engine-log, THE LAWS and THE LAST SEVEN; engine-release-plan.md, the law table
Taking a ball down — the first touch on a ball that arrivesIn progress
2026-09-20: the pace a ball arrived with is now a term of what his first CARRY touch is asked (V2Touch.touchAsk), behind the miscontrol roll: 16-17 heavy first touches a match, 4.3% of them (128 runs). A ball more than eight centimetres off the grass could not be miscontrolled at all — on any touch, by any player, in any match this engine had ever played. miscontrolsGroundBall opened with ball.z > 0.08 and the settle beside it read the HORIZONTAL arrival speed and never ball.z or ball.vz, so the dropping ball out of the sky was strictly the easiest ball in the game and firstTouch and technique were never tested by the balls that test them. Nobody put that line there on purpose: how hard was that to take down had no chapter, which is why V2Reception.kt is the ninth (2026-08-31, THE LAST SEVEN member 1, GM_V2AWKWARD). The census came first and sized it: 23.9% of 1,159 receptions a match arrive off the deck (0.08-0.3 m 4.9%, 0.3-0.75 9.1%, 0.75-1.3 5.1%, above 1.3 4.6%), 14.7% of them dropping, and that one line refused 14.8% of the function's looks. v2AwkwardArrival prices the HEIGHT — worst from the knee to the chest, the ball that sits up on him, easier again above it where he has a technique — and the DROP, which scales what the height set; the failed touch and the settle both read it. Measured paired at 512 runs: 31.38 miscontrols a match on a ball off the deck, 12.6% of the 248.26 such receptions, against a control arm in which the number is zero by construction. The cost is written down rather than tuned away and its CAUSE is the useful part: miscontrols 40.84 → 75.90 against football's ~20-30 unsuccessful touches, and cutting the mechanic's own constant by 30% moved its rate 13.7% → 13.0% — because the member removes an EXEMPTION rather than adding a term, and the pre-existing pace and pressure terms are most of what those balls now face. Partial, and the missing half is named: the touch has no DIRECTION yet (a man cannot take it away from a defender or into his stride), the chest and the thigh are not distinguished, and nothing yet lets a first touch be deliberately heavy.
In the code: engine/…/match/v2/V2Reception.kt; engine-completeness, “Controlling a ball that is bouncing or dropping”; engine-log THE LAST SEVEN
Carrying the ballIn progress
Still missing: every carrier runs at 72% of his top speed whatever his dribbling (V2Decisions.kt), and a skill move only happens inside a defender's tackle.
Touch, shield and knock-past built and tested (SimV2CarrierContestTest). Missing: every carrier runs at 72% of his top speed whatever his dribbling (V2Decisions.kt), and a skill move only happens inside a defender's tackle.
In the code: engine-log, THE TOUCH and the 2026-10 landing
Finishing vocabularyIn progress
Still missing: one-on-one conversion 28% / 30% against 35-45% (2026-10 landing), penalties hitting the frame, and pressure in the shoot-out.
Every strike in the catalogue is built (SimV2FinishTest). Missing: one-on-one conversion 28% / 30% against 35-45% (2026-10 landing), penalties hitting the frame, and pressure in the shoot-out.
In the code: engine-log, THE FINISH and BATCH 6
Goalkeeper sweeping and build-upIn progress
Still missing: which centre-half comes short is nobody's decision; the race in behind is still lost (8-9 of about 400); +0.19 goals from the line unexplained.
Build-up, the goal-kick shape and the resting line built and tested (SimV2KeeperLineTest, SimV2KeeperOutletTest). Missing: which centre-half comes short is nobody's decision; the race in behind is still lost (8-9 of about 400); +0.19 goals from the line unexplained.
In the code: engine-log, THE KEEPER'S LINE
Fatigue over ninety minutesIn progress
Still missing: the extra-time collapse (the tank reads 0.89 at the whistle), and time above 5.5 m/s is 12% against 3.5-4.5% (TASKS: the urgent approach).
Legs, sprint debt, cramp, travel and the hand-over are built (SimV2LegRestClockTest, SimV2SettleTest). Missing: the extra-time collapse (the tank reads 0.89 at the whistle), and time above 5.5 m/s is 12% against 3.5-4.5% (TASKS: the urgent approach).
In the code: engine-log, THE LEGS and sprint recovery (2026-10-06)
The goalkeeper's hands — the shape of a save and the releaseDone
A new row for a limb of a position that was one number wide. Shipped 2026-08-24 (Lane F batch 2, THE KEEPER'S HANDS), four rows of nine, each measured paired at 512 runs against its own arm. He can FIST a shot (GM_V2PUNCHSHOT) — punchDelivery had exactly one call site and it was inside the aerial contest, so a fierce drive was caught, parried or spread and never punched; the picture is hit hard, above his set hands, and already a ball the catch draw said he was not holding, and it reads 0.69 a match, 10.9% of the saves he faces, going twice as far and behind for a corner at 30% of the parry's rate. He can DROP one (GM_V2HOWLER): concentration is read in the goalkeeper for the first time, on the ball the catch draw had already given him, at the order football books an error. throwing stopped being decorative (GM_V2KEEPERTHROW) — it was a GATE on the choice and appeared nowhere in the execution, so a keeper with throwing 18 threw exactly as accurately and exactly as far as one with 3; it is in the weighting blend now and the range is 26 + throwing × 16 metres, pivoted at the average so the mean release is unchanged and the SPREAD opens. And the throw is two throws (GM_V2ROLLOUT): he rolls it out 5.9 times a match over 12.2 m and slings it 3.9 times over 24.0 m, where those were one event with one flight profile. THE KEEPER BATCH closed the five named residues on 2026-08-29 and this row is DONE. The ball from his hands is a keeper's kick (GM_V2PUNT: the PUNT hangs ~2.95 s at 40 m against the old hoof's 2.09, the DROP-KICK to a named man is flatter and faster, and kicking decides the range, 44–80 m pivoted at the parent's flat 62); a claim with a BODY ON HIM asks whether he comes at all (bravery), whether he is FOULED by the climber (a free kick to his side — the last residue of "only the team without the ball can foul"), and whether he holds it through the contact, with a failure under contact a DROP at his feet (GM_V2CLAIMPRESS); the flat cross he is not favourite for is ATTACKED, gathered or palmed clear (GM_V2LOWCROSS); his hold reads the clock-management state and Law 12.2's six-second offence exists and is vanishingly rare, as in football (GM_V2SIXSEC, a runSim v2full row); and the spread save and the punched ball carry their own feed verbs (SPREAD_SAVE/PUNCHED_CLEAR, football byte-identical). Census before mechanics, every population real, no member refuted; the paired 512 table is in docs/engine-log.md, THE KEEPER BATCH.
The goalkeeper at a man's feet — the smotherDone
Counted for the first time on 2026-09-20 (release plan stage 3a): both documents had it done on a symbol the deleted engine owned. The act existed as the ground claim, which never required a loose ball: 7.6 at-feet episodes a match, the ball winnable in 26%, claimed at feet about once a match. What did not exist was a FAILURE — every claim was certain and clean. With a man arriving it is now a hold contest: 76% held, 0.24 spills a match with the keeper down and the ball live in the box, the collision still the breakaway penalty. Staged: the heavy touch he wins, the protected one he cannot, the collision, the spill, the rebound (SimV2CarrierContestTest). And the trailing poke is asked at the look: 19.9 → 6.45 a match, trailing fouls 3.3 → 1.05, fouls 29.8 → 27.1.
In the code: engine/…/match/v2/V2AtFeet.kt, V2CarrierCensus.kt; engine-log Release plan stage 3a
Restart vocabulary and lawsIn progress
Still missing: the dropped ball's release audit (catalogue §6), and tests of their own for the quick restart and the game-state kick-off. Throw-in volume is Restarts (throw-ins).
Every restart in the laws exists; the deliberate ball out of play and the dropped ball are tested (SimV2LastActionsTest, SimV2Rules2025Test). Missing: the dropped ball's release audit (catalogue §6), and tests of their own for the quick restart and the game-state kick-off. Throw-in volume is Restarts (throw-ins).
In the code: football-catalogue §6; engine-log
Tactics and instructions89% · 23 done, 4 in progress, 1 not started
Per-player instructionsDone
Including the screen. Overlap, underlap and deception shipped with it. The 2b batch added tackle harder / ease off, mark tighter, hold it up, stay wider / sit narrower and come deep — each on a number the engine already computed, measured per man (SimV2PlayerInstructionTest), and issued by AI managers at the extremes of their philosophies.
In the code: roadmap 20a, 15h, 15i; tactics.md §5 2b
Advanced player instructionsDone
2026-09-25. A far-post station now elects an available attacker and rechecks his other jobs. Its isolated pair moves the furthest body 3.261 → 3.858 m past the middle, t = 3.10. The aim bite stays 1.35; the new mechanic moves a man. The measured 24-instruction core, plus the four families 5a and 5b unblocked, all shipped 2026-08-09 and all measured. Show onto foot per NAMED opponent — three OppositionInstructions resolving in steeringOn, which beat the team-wide dial for the man they name and change nothing for anybody else. The crossing plan — where from, what kind, aimed where; paired per trial on the ball actually struck, 15.42 m from the byline against 10.49 (t = 5.5), 30.7% drilled against 6.3% (t = 8.7), aimed +1.45 m past the middle against −1.31 (t = 7.4). Pass to feet or into space — one scale on the lead 5b built, 0.459 s against 0.220 (t = 79.7). The wide-target service — a WIDE_TARGET_FORWARD role and a long ball that finally reads who it is going to. AI managers select every one of them. The crossing SOURCE dial failed its own reading twice before it worked, which is the entry worth reading in the log. Still not here: move into channels — and it is no longer blocked on plumbing but on a MEASUREMENT, since the additive lateral term built for it on 2026-08-16 moves a forward's station and not the forward (t = −0.02).
In the code: tactics.md phases 2b, 5; engine-log
AI tactical vocabularyDone
Every AI club's roles and a small instruction set now follow its manager's philosophy (pure function, no RNG). Before 2026-08-04 every outfield role in the world was a formation default and no AI club had ever set a player instruction. Measured: ManagerGenTacticTest invariants + leaguecheck recorded either side. AND EVERY ARM OF EVERY SHIPPED INSTRUCTION IS NOW ISSUED BY SOMEBODY (2026-08-26): AttackFocus.CENTRE had been selectable, documented and played by NOBODY — 0 looks over 512 harness matches — because tacticFor issued only FLANKS and BALANCED, so one arm of a measured team instruction could never be exercised. attackFocusFor gives it to the purist at pragmatism < 0.28, which is boxEntryFor's own threshold rather than a second number, and the census goes 0 → 242,463 looks, standing 10.89 m off the spine with 1.51 men wide against a BALANCED side's 11.79 m / 2.06. That is the a selectable option nothing selects is unmeasured code rule caught by an instrument rather than by a 3.2-goal surprise. Its arm exposed a trap worth carrying: written as a leading withholds("focus") → BALANCED the control ALSO withheld BATCH 7's FLANKS, so a single-field token reproduced all's own documented failure — the census caught it and the whole seven-arm run was discarded. runSim rolecensus confirms every one of the twenty-four roles is fielded by somebody.
In the code: tactics.md §5 1a
Role fit bitesDone
The engine reads Ability.roleFit: a badly-fitted man attempts his role's signature actions less (regression toward the generic baseline; naturals unchanged at 1.0). Decision-level eval; GM_V2ROLEFIT is the control arm. And since 2026-08-26 it also PICKS the side (BATCH 7, GM_XIROLE): LineupPicker ranks candidates on the role fit of the role the manager put in the slot, so naming TARGET_FORWARD starts the aerial striker. Measured over 510 league clubs — 2.81 of the eleven shirts change hands for +1.04 of role fit out of 100, and a PLAYMAKER slot now holds a genuine one (the harness's craft split of playmakers goes 4,833/2,954 to 7,237/781).
In the code: tactics.md §5 1b
The instruction surfaceDone
Every field of Tactic now reaches the pitch, and three that did not exist do too (BATCH 7, 2026-08-26). AttackFocus was the one field of thirty-five read only on the ball and now moves a STATION — a FLANKS side's ten outfielders stand 12.94 → 13.63 m off the spine while a BALANCED side's are unmoved. Work ball into box / shoot on sight (18 m+ looks taken 2.0% → 5.9% and 2.0% → 0.9%), focus play through a named man (his share of his side's on-ball decisions 0.74x → 0.90x of a fair share) and get it in the mixer (balls into the area per final-third decision 2.7% → 4.1%) are new fields with a screen and an AI path. And TEMPO is a beat rather than an option mix: a man releases it 1.92 → 2.01 s under SLOW and 1.65 → 1.50 s under FAST, with a playmaker setting his own. Bill −0.42 goals, nearly all of it long shots that do not go in — conversion 11% → 9% is a calibration line.
In the code: engine-log.md 2026-08-26
Opposition instructionsDone
Orders about a NAMED opponent, keyed by his slot: mark tight / stand off, close down more/less, tackle hard / ease off, man-mark — each on a decision the engine already makes. The AI briefs the opponent's hub per its manager's philosophy; the user sets them in the in-match sheet; the stats panel reports the cost (named men's freedom vs the rest). Seven decision-level tests. Show-onto-foot shipped 2026-08-09 — the one order 2a held back, and it was held back for the right reason: nothing steered a carrier by pressure side until 5a. SHOW_OUTSIDE / SHOW_INSIDE / SHOW_WEAKER_FOOT resolve in steeringOn and beat the team-wide dial for the man they name, measured on the shade itself (the named carrier's flips sign; an unnamed opponent's is bit-identical to the control's). The AI briefing now names a wide man as well as the hub — an inverted winger is shown onto his weaker foot, a touchline winger inside.
In the code: tactics.md §5 2a; engine-log 2026-08-09
The last line — somebody between the ball and the goalIn progress
Still missing: the onset census (57% with nobody goal-side) not re-read since 2026-08-30, and no test for the errand. Conversion is Finishing vocabulary's.
The goal-side shape and the last-line errand are built (SimV2ScenarioTest), and one-on-one supply is in band since the 2026-10 landing. Missing: the onset census (57% with nobody goal-side) not re-read since 2026-08-30, and no test for the errand. Conversion is Finishing vocabulary's.
In the code: engine-log, THE GOAL-SIDE SHAPE
Defending a receiver in the zone: the block's real size and the man in my zoneNot started Active: Match engine
Designed 2026-10-26, awaiting the owner (docs/marking-model.md). At the strike of a pass the defending outfield block is 44 x 45 m against a real 29.5 x 36.8 m (DFL, n 2,477), the receiver is unmarked on 45% and marked from ~14 m on 43%, and his nearest defender is goal-side 57% against 74%. It is the structural cause of the challenge excess and probably of the running row.
Picking a man up: the marking hand-overDone
Shipped 2026-09-18 (release plan stage 2, GM_V2HANDOVER). A zonal or mixed side sends a spare man for an ordinary threat only from inside his zone's reach (12 / 16 m) and leaves the rest to the shape; a runner inside 30 m of goal, on a run or with a ball on its way is picked up from anywhere, and man-marking sides and TRACK jobs still follow anywhere. Measured at 512 paired: ordinary pick-ups 19.6 m → 12.2 m, every dangerous runner picked up in both arms from the same 14 m, the fresh marker's share of the sprinting 17.2% → 13.9%, distance 10.86 → 10.35 km, goals +0.30 ± 0.23 on the batch (3.22, out of band, written down). A STEP or COVER job weighs the pick only inside the zone's reach — the engine gate found the stopper being sent 24 m for runners, and that was fixed in the mechanic. SimV2SettleTest fails if it is deleted. The swap rung was measured and refused; offsides fell 3.38 → 2.46 and that is written down, not tuned.
Out-of-possession jobsDone
The FM26 axis for one enum: PRESS (a striker's press starts +73% — the forwards-last engager ranking inverted), TRACK (his mark survives the release range), HOLD (the screener's chases halved, his own zone intact), OUTLET (defends 9 m higher and takes 20.5% of first balls after regains vs 15.4% on auto — the out-ball term exists because positioning alone measurably backfired). Phase 4e (2026-08-09) added the centre-half PAIR, STEP and COVER, which is one job in two halves rather than two independent ones: the stopper stands 2.5 m in front of the line and the spare man 2.5 m behind it, the stopper wins the marking sweep for the most dangerous forward and gets 1.15 m tighter to him while the spare declines those men and sits 1.55 m off, and the stopper is the only ball-driven absence the cover layer accepts — coverable by his named partner and nobody else. Graded on the space he leaves behind: 11.22 m to the nearest team-mate against 12.99 m on auto, while he is off his station 13% MORE often. That reading carries a third arm (the step with no partner, 12.15 m), because the lifted anchor closes 0.84 m of it on its own and a two-arm reading would have credited the partner with all of it. Per-man evals; AI managers assign at philosophy extremes (124 of 1,234 generated clubs field the pair); GM_V2DEFJOB is the control arm, proven bit-identical off.
In the code: tactics.md §5 3a, 4e
Transition policyDone
Separate decisions after losing and winning the ball: counter-press / balanced / regroup, and counter / balanced / hold shape. COUNTER sends 39.9% of shots inside eight seconds against 26.2% for HOLD_SHAPE; COUNTER_PRESS holds mean team x at 51.0 m after loss against REGROUP's 48.1 m. AI managers select every extreme; GM_V2TRANSITION is the golden-proven control arm.
In the code: tactics.md §5 3b
Focus play left / rightDone
The most common real team instruction: a sided focus is FLANKS committed to one wing — every ball-moving option is weighted by its destination's side, and the AI targets the opponent's weaker defensive wing against a deep block. Measured: final-third entries by flank move 46/34/20% ↔ 17/32/51% between LEFT and RIGHT arms (SimV2TacticalEvalStyleTest); GM_V2FOCUSSIDE is the control arm, proven bit-identical off.
In the code: tactics.md §5 2c
Phase-specific defensive widthDone
Attacking and defensive width are separate saved choices, with the latter on the out-of-possession tactics panel. On the same XI, WIDE vs NARROW moved realised possession spread 11.34 → 12.70 m and defending spread 11.00 → 11.60 m. AI managers select every extreme from pressing philosophy; GM_V2DEFWIDTH restores the old one-width engine exactly.
In the code: tactics.md §5 3c
Two-phase possession shapeDone
possessionShape mirrors defShape, with phase-only 3-2-5 / 2-3-5 shapes and an explicit saved player-to-slot permutation for each phase. The tactics screen edits both mappings; AI managers select both build-up shapes without another RNG draw. On the same 4-3-3 XI, 3-2-5 put five men above 62 m against three in the base shape, then all ten returned to exactly the same defensive stations. GM_V2POSSHAPE=0 restores the old engine exactly.
In the code: tactics.md §5 3d; engine-log 2026-08-06
Tactical visualiserDone
The two-phase board on the tactics screen: both sets of stations on one pitch, an arrow for each man's journey between phases, the static count behind the ball, and no-width / uncovered-channel / no-outlet warnings. Tactic.board() re-derives the engine's own static shape terms and SimV2BoardTest asserts it against the live baseShapeTarget to 5 cm in both phases — which caught the mentality push being applied in possession only. The Duty checkpoint is settled: Duty stays, being a gain on movement rather than a station.
In the code: tactics.md §4, §5 3e; engine-log 2026-08-08
Corner structureDone
Who stays back at our corners (cornerStayBack, 1–3 highest-defDuty men, AUTO by mentality) and zonal/man/hybrid responsibilities at theirs (cornerDefence, AUTO follows marking), both on the tactics screen and selected by AI philosophy. Measured: stay-back men held at the kick near halfway, marks occupied (majority touch-tight at delivery), and corner-conceded → counter shots instrumented. GM_V2CORNERSTRUCT=0 restores the all-ten-up, pure-zonal engine exactly. The third man held out of the box shipped 2026-08-21 (GM_V2POSTMAN): after the counter outlet and the short-corner presser, one defender stands ON the near post through the flight — the row this page carried as still does not exist for a year of cycles — elected by one sum in metres, the ground he has to cover against five metres of running to spare a good header of a ball, and measured at 0.06 m from the post when the ball is struck.
In the code: tactics.md §5 3f; engine-log 2026-08-07
Role vocabularyIn progress
Still missing: Shadow Striker, Libero and Channel Forward (blockers in tactics.md §5 phase 5); the inside wing-back is graded on position only.
24 roles, all fielded and measured (the SimV2*RoleIdentityTest family). Missing: Shadow Striker, Libero and Channel Forward (blockers in tactics.md §5 phase 5); the inside wing-back is graded on position only.
In the code: tactics.md §5 phase 4; engine-log
Formation vocabularyDone
Thirteen line-up formations plus the phase-only 3-2-5 / 2-3-5 shapes. Phase 4d (2026-08-08) closed the agreed common set by adding 3-4-2-1, the narrow-diamond 4-1-2-1-2 and 4-2-2-2 one at a time; each carries a line-up entry, default roles playable where they stand, a structural AI-selection path and a phase remap into and out of every other shape, all asserted in ManagerGenTacticTest. ManagerGen's classifier stays structural (never the display name) and the phase-only shapes still cannot enter a team sheet. The ten older shapes are now recorded slot by slot, so a stray edit to a balanced formation fails the build. DRAWING YOUR OWN shape is a separate row — see Constrained formation editor.
In the code: tactics.md §5 3d, 4c
Preferred-move vocabularyDone
TWENTY-EIGHT traits are implemented and §11 of the catalogue has NO OPEN ROW LEFT. Winds up opponents came BACK to that list and SHIPPED on 2026-09-01 as Trait.WINDS_UP_OPPONENTS — it had been re-homed to engine-completeness in 2026-08-26 on the correct argument that a trait is one more multiplier on machinery that already exists and there was no provocation machinery to multiply, so row 618 built the machinery first. A TRAIT and not an attribute threshold, deliberately: winding an opponent up is a specific characteristic a scout would list, not a by-product of tackling hard. 296 of 9,628 generated footballers, 3.1%. The rest of this row is 2026-08-26 (THE VOCABULARY BATCH) — every one of the thirteen candidates it carried is now either shipped or refused with the number or the named term that refused it, which is the state §1–§9 reached on 2026-08-24. Four shipped, each graded on an EVAL where the habit is granted to every eligible man in a copied XI, because a preferred move reaches only the footballers generation gave it to and a pooled harness row is diluted 9.4× by the holder share. Comes deep (orderDepth, taking the STRONGER of habit and PlayerInstruction.COME_DEEP, never the sum): 0.00734 ± 0.00227 of the pitch, t = 3.23 over 64 trials — 0.77 m realised of the 2.5 m asked for, so 31% arrives, which is the standing a depth preference only partly arrives rule measured on the axis where it arrives at all. Tries the spectacular is ONE taste read by THREE improvised acts — the back-heeled pass, the overhead kick and the back-heeled finish, written in two chapters eight days apart — and unblocks the lean optionBackHeel was written to take in 2026-08-17: 1.00 against 0.406 back-heels a trial, t = 4.01. Its other two acts are STRUCTURALLY INVISIBLE on the harness and that is counted rather than assumed (32% of 0.78 pictures against 32% of 0.80, and 3% against 3%): with seven holders across sixteen XIs, only a handful of ~400 overhead pictures a season fall to a man with the habit. Looks for the overlap is the FIRST per-player term maybeStartFlankRun has ever had — it read two attributes and a running duty, so he is the one who overlaps was unsayable about any footballer: 4.44 against 3.50 flank runs a trial, t = 3.08. Stays on his feet is EASE_OFF at player scope, stronger-of and never their product, at all four commit decisions the order already reaches, graded PER LOOK: the share of matured challenge windows committed to falls 0.419 → 0.327, t = 4.26. Nine refused, and the test is whether a per-player HABIT would change the act's rate rather than whether the act exists: stops play deliberately is commitsTacticalFoul, already carrying DIVES_INTO_TACKLES ×1.2 and in band at 1.43 a match; argues with officials is checkDissent/dissentTemper, already keyed on professionalism and TEMPERAMENTAL ×1.5 and sized to its real rate at 0.29 cautions of 29.40 looks a match; two duplicate shipped traits (LONG_RANGE_SHOOTER, ARRIVES_LATE), one is a composition of two, one is already the taker election, one has no per-side counter to grade on, and moves into channels stays REFUTED at t = −0.02. Winds up opponents is RE-HOMED rather than refused: there is no provocation mechanic and no per-player composure channel anywhere in the engine, so it is a missing DISTINCTION and belongs to engine-completeness. The batch bill is −0.15 goals (1.0 SE) and ALL of it is carry goals — OPEN_CARRY 205 → 189 on a total 326 → 310, so non-carry goals are 121 in both arms exactly.
In the code: football-catalogue §11; engine-log 2026-08-26
In-match management surfaceDone
Bookings visible; the subs sheet stages a batched double-change (one stoppage, `MatchRunnerEngineTest`) and swaps two men's positions for free; the opponent's live formation + mentality sit on the scoreboard and its tactic changes reach the feed — the AI scouting the user is no longer one-way. Mid-match changes refresh every surviving player's role, duty, defensive job and individual instructions. Phase 4f (2026-08-09) closed the last gap: the sheet reached 6 of 21 team dials while the engine read all 21 live every tick, so a manager could raise the press at half time and could not go narrow, drop into a back five, spring the offside trap or start wasting time. All twenty-one are now driven from one TeamDials list, grouped in the pre-match screen's own panels and order — and TeamDialsTest reads the Tactic schema as source text and fails the build when a dial is added to it and not classified, which is the part that keeps this row honest. Per-player editing stays in its dedicated sheets. Score/minute rule cards, 2026-10-19: up to three cards on the tactic (“down by one from 75': push for a goal”) play the AI's own four game-state responses for his side, watched or instant, and come off when the score passes; with none, the panel shows what his assistant does in an instant match, read from the engine's table; each card's start and stop is in the feed (SimV2ManagerTest).
In the code: tactics.md §5 phase 0, 4f
Team principles layerDone
The layer under every modern tactic; expression vs discipline shipped.
In the code: roadmap 14a, 14b
Tactic expressivenessIn progress
Still missing: that re-run, and a re-grade of the nine tactics since 2026-08-06.
Eleven of the twelve primitives shipped (re-audited 2026-08-06). P6, a whole side pressing on a trigger, is built behind an off arm (GM_V2PRESSSPRING, V2PressTrigger) and measured inert, because the parent already over-presses (committed challenges ~3x real); re-run after the challenge calibration. Missing: that re-run, and a re-grade of the nine tactics since 2026-08-06.
In the code: tactics.md Part II; engine-log, P6 (2026-10-21)
Deception and flairDone
Disguise, four named moves, the back-heel, the dummy and the reverse pass, with readings (engine-log DECEPTION 2026-08-17, THE LAST ACTIONS 2026-08-19) and the back-heel's test (SimV2PreferredMoveTest). Disguise, the moves and the dummy are guarded only by the golden digest.
In the code: engine-log, DECEPTION and THE LAST ACTIONS; football-catalogue
Pressing heightDone
The engagement line gates cover, second challenger and followers, and an eval asserts a high press wins the ball higher. The one engager who always goes now DELAYS beyond the line rather than chasing (3g): he is stationed 2.6 m off the carrier in the lane to the central option, stops sprinting at a man who is standing still, and goes in on 23% of his looks against 52% chasing — measured paired at 512 runs, where it also wins the ball higher (36.1% up the pitch against 35.3%) rather than deeper as designed. Two low blocks still produce football, which is the guard the mechanic exists behind. Honest limit: his realised distance to the ball barely moves (2.99 m against 2.90 m) and the reason turned out NOT to be what everyone assumed — engager stability was built on 2026-08-09 and rejected, because doubling the mean engagement spell to 4.26 s moved the standoff 3.00 → 3.10 m, the wrong way. He is in transit whoever he is — and "how he closes the last few metres" was built in two forms on 2026-08-16 and REJECTED in both: leading the carrier moves the standoff 2.70 → 2.53 m and quadruples the take-ons, and leading him to a real close-down station moves it 2.70 → 2.95 m, the wrong way. The standoff is the residual of a pursuit curve rather than a station anybody chose; see Pressure-side defending. Phase 5a (2026-08-09) added the SIDE: Steering — down the line (the old engine), inside, or onto the weaker foot — read by steerShade in both engage branches, so "force him onto his left" is expressible. Graded on where the carrier went rather than on where the defender stood: 10% of looks infield when shown outside against 42% shown inside, and 16% on the weaker-foot arm, which sits between them by construction. It is a tilt and the eval asserts it stays one — even shown inside the average carrier still drifts wide, and a version that decided his direction would be a defender carrying the ball for the opposition. Not here: a press INTENSITY axis separate from height. The 5c "regression" here was REFUTED on 2026-08-09 and the guards are restored. A high press was recorded as having lost most of its territory to phase 5c's body count; re-measured per trial at 48 paired trials the body count moves field tilt by 0.06 ± 2.04 (t = 0.03), recovery by −0.0015 ± 0.0091 and final-third regains by 0.21 ± 0.67 — nothing. The original reading ran on twelve trials, where field tilt's standard error is 2.8. The press dial's own effect is healthy and now barred in standard errors: tilt +6.33 ± 1.48 (t = 4.28), recovery +0.041 ± 0.007 (t = 5.53), regains +2.06 ± 0.48 (t = 4.32).
In the code: tactics.md §1, §5 3g, 5a
User-facing set piecesIn progress
Takers and swing shipped (2d): the tactics screen names a taker per situation — left/right corner, direct FK, penalty, long throw — plus in-/out-swinger, the named slot takes ≥95% in matches, and the swing is the taker's foot. Still missing: designing or assigning a ROUTINE — the designer itself. That is a UI track and not engine behaviour, which is why football-catalogue.md §6 reclassified its row to ⎕ on 2026-08-19: nothing in the engine is waiting on it. Rehearsing the routines the engine has shipped 2026-10-19: see Rehearsed shapes and routines.
In the code: tactics.md §5 2d; roadmap 27
Rehearsed shapes and routinesDone
2026-10-19. A squad holds three shapes fully drilled; a fourth takes the excess familiarity off every shape in proportion on Mondays, and a letter says what it cost (shape familiarity used to grow without ever falling, so every shape could be fluent for nothing). The three corner routines the engine chooses between (near-post flick, back post, short corner) are drilled under the Set Pieces focus for the routines the manager ticks, at his set-piece coach's pace pivoted on the world's mean; two fully drilled, a third costs both, and the engine weights each where it already chooses. User-side only: an undrilled side plays exactly as before (golden digest). Shown on the Tactics screen's Rehearsed panel, and a rule card that changes shape says how drilled the shape is. RehearsalTest, SimV2RehearsalTest; runSim setpieces 200 only=5: undrilled reproduces the pivot row exactly (29.8% routines), both designed routines drilled 48.5%, the back post alone 12.6% → 17.6% of corners; the short corner's drill is not resolved by that instrument (a both-sides counter). Capacity growing with the staff is on the calibration list.
In the code: tactics.md, Rehearsed shapes and routines
Constrained formation editorDone
The two-phase board made writable (2026-10-20): each phase's dots drag inside their position-family bands, 6 m apart, a slot's position following its dot across its own line, the three warnings as advice; the engine stands the side where the board draws it (SimV2BoardTest). The AI keeps named shapes, and a match played instantly plays the named shape, which the board says.
In the code: tactics.md §5 phase 5
Team talksDone
The AI match-engine slice shipped 2026-09-03. Rare half-time and touchline stances are generated from the score, momentum, confidence and frustration; each reaches Psyche through a bounded, personality-sensitive term, while repeated touchline messages fade and carry a cost. The 160-match controller census found 85 half-time talks over 320 manager-sides and 302 touchline messages. The user's talks shipped 2026-10-17 (dressing room slice 6): a pre-match talk on the preview and a post-match word on the report, offered only when something is at stake (a derby, four without a win, a man the story is about, a heavy defeat, a red card), said to the room or to one man, landing on each man's morale through his personality and on the friends of a man spoken to, every response shown with its number (`TalksTest`); and the half-time talk in a watched match, which now stands at the break: four stances through the AI's bounded term, the assistant's word when he says nothing, what it did shown (`SimV2ManagerTest`). The touchline, 2026-10-18: in a watched match the user may shout one of the same four words, once an eighteen-minute gap and at the AI's growing repeat cost, with the assistant's advice and the next minute he may speak on the match screen; when he says nothing his assistant gives the AI's touchline words, as the fixture played instantly does; and every touchline word, from either bench, is now in the match feed with who said it (it never was, not even the AI's). SimV2ManagerTest, EventTextTest.
In the code: roadmap 21; engine-log 2026-09-03; dressing-room.md slice 6
World, career and competitions93% · 19 done, 3 in progress, 0 not started
Multi-country worldDone
Country-scoped pyramids, light leagues, twenty football nations.
In the code: docs/world-model.md
International footballDone
National teams, World Cup / continental cycle, three career modes.
In the code: docs/world-model.md
Country coefficientDone
European places are earned by a rolling UEFA-style coefficient, not assigned. 2026-10-15: the draw read every league on reputation, because it ran after next season's fixtures had replaced the table (84 entrants in three seasons from outside their places); the finishing order is now one value read by the bonus, the letter and the draw, and runSim seasoncheck 3 reads clean on both worlds. A domestic cup winner has its own place in the second competition, passed down the table when it is already in (22 of 22 drawn, against 17 or 18).
In the code: runSim europe N
Talent modelDone
CountryProfile splits youth population, culture, coaching and wealth.
In the code: docs/world-model.md
Relative age effectDone
Birth-quarter selection bias, per nation and per academy.
In the code: runSim rae
Affiliate clubsDone
2026-10-19: a parent holds as many affiliates by agreement as its level and money allow (three at reputation 70, two at 55, one at 40, one fewer on a ladder rung), pays each 0.5% of its income a year, sends its prospects on loan there first, follows them with the better of the two clubs' coaches and has first refusal on their men (the manager is asked by letter and the sale waits three days); a group's members and a club the manager owns abroad are affiliates by ownership, outside the count; at a director-led club it is the director's call, asked through the requests. The transfer desk lists them; a club's page says whose it is or offers it (Affiliates, AffiliatesTest). Read: a loanee at an affiliate plays 0.60 of its minutes against 0.53 for every loanee, and grows +0.147 a season against +0.123 (ambitions 3, second season), the money flat (club-economy §25).
In the code: club-economy §25
Feeder teamsDone
Generated B and youth sides with player movement between squads. 2026-10-16: the club runs the manager's B and youth contracts by default (renewals, the summer top-up, matchday cover, one letter a season), and a switch on the feeder side's page hands them to him; on runSim seat 2 the B side holds 18-21 men over two seasons, where it fell to 7. SeatFixesTest.
In the code: roadmap 10b
Youth intake as decisionsIn progress
Still missing: any visible effect of a better director — runSim youthdev reads it inside one standard error.
2026-10. The academy director says what is coming a month before (his forecast, and a poor director flatters it); a youngster is signed on a wage that depends on him, the club and the length the manager chooses, one to five years; a trial keeps him sixty days longer for a sharper read at the risk of another club signing him; the youth squad holds 26; and the academy director the club hired now coaches its feeder sides, which he never did. A full intake offers existing youth players for release with a confirmation and quoted parent-funded pay-off. Terms show the June deadline. Missing: any visible effect of a better director — runSim youthdev reads it inside one standard error.
In the code: YouthSystem; YouthDecisionsTest; docs/staff-hiring.md §6
Academy regionsDone
2026-10-19. One to three countries an academy recruits from besides its own city (by youth facility), chosen on the academy screen. A region takes a share of the boys an intake already draws from abroad, never a home boy and never a better one: three shares where a scout or the academy director knows the country, one where nobody does, against two for the rest of the world, so one known region brings 60% of the boys from abroad. AI clubs keep regions drawn from their own foreign draw, shown to a manager who inherits them. The screen says who knows each region and its share; the intake letter and the boy's card say where he came from. AcademyRegionsTest; runSim youthdev 3: no home boy replaced, 55-77% of the boys from abroad through one or two known regions, potential equal within a club, each nation's supply unchanged within noise. Not modelled: FIFA's rule on the international transfer of minors.
In the code: docs/world-and-people.md, first-set slots; AcademyRegions
AI managersDone Active: World and people
Every club has a person with a philosophy; they are judged on a season and some are sacked. In-match they manage the real game state: a side that loses a man re-forms with the vacancy up front instead of defending around a hole, and in a two-legged tie the AI chases or protects the aggregate, not the night's scoreline (SimV2TenMenAndSecondLegTest). Seen, 2026-10-19 (world-and-people slice 6): a manager card on every other club's page and the opponent's on the match preview: the man, his four philosophy numbers, his last seasons and his trophies, which are now written (AiManagerTrophyTest, runSim managers 3). Personalities, batch 1 (2026-10-19): every AI manager holds one or two derived traits; market shark, cautious in big games, develops youth and loyal to his men act, each one line in an existing decision (the cautious man's own game-state thresholds as rule cards), shown on the card with this season's evidence (ManagerTraitsTest). Batch 2 (2026-10-20): the other four. A man who holds grudges remembers hurt twice as long and, under −15, will not sell or lend to you (his reply and the club's relations panel say so); a tinkerer changes his shape when his board is uneasy and his side plays the new one stiffly for six weeks; a man who talks the game up writes to you before a derby or title battle, with two answers that cost on two standings; a pragmatist under pressure keeps his shape and plays a notch deeper. One test each. 2026-10-21: a man appointed mid-season is judged on his own league matches, nothing until six of them (AiManagers.HONEYMOON_MATCHES, ManagerHoneymoonTest), and his card says from when; against GM_HONEYMOON=0 in econ 8 the nine top flights sack 0.60 a club a season against 0.86, and a club's second sacking inside ninety days falls 466 → 25 (docs/club-economy.md §30). A club could re-appoint the man it had just sacked; fixed.
In the code: roadmap 10b; tactics.md §5 0e
Player aimsDone
Aims shipped (roadmap 10c). Friends, mentors and a player's trust or grudge toward the manager are built (Mentoring and social groups; TrustTest). 2026-10-21: a rivalry for one shirt that lasts, built from who starts and ended by it, with one named receipt (“X started ahead of him”), the shirt letter as its voice, and both men's panels showing it since its date; brothers bond and are named (RivalsTest, EventsTest; runSim dressingroom seasons=2: 36 and 60 rivalries a season in the division, about five points of morale on the man left out). No squad has brothers yet. 2026-10-22, read: loanees no longer drift below average on minutes (0.53 / 0.63 / 0.47 a season against 0.41 / 0.30 / 0.31); a winter loan reads low because its share counts the borrower's whole season, and development reads the same input. A loanee gains 0.14-0.17 less ability over three seasons than a matched man not loaned (SE ~0.09), a third of it the lower tier and a club he outclasses (roadmap 10c). 2026-10-22, built: a man's minutes count from the day he arrived, for development and for his share alike (Arrivals, ArrivalsTest): one who plays every game since a January move reads 0.97, not 0.52-0.58. 2026-10-24: his page says why he wants away and that he is getting there, under Transfer status: one reason with its numbers (“short of football, 31% of the club's league matches since he came, where his promised role expects 68%”), restless exactly when the Monday's request chance is above zero, never the score (WhyAway; WhyAwayTest, WhyAwayLineTest).
In the code: roadmap 10c; dressing-room.md; world-and-people.md, Standings
Club identityDone
2026-10-14. A club is a contender, an academy club, a selling club, a modest club or an established club, derived each summer from its league and standing, reputation, academy and academy director, who runs it, and whether it has been selling (ClubIdentities, no draw). Its board judges the manager on the table and on what the club is for: academy minutes, net sales and a side younger than its league, squad cost under the line; a contender's table counts more. AI managers are judged the same way, and a selling club no longer refuses a bid for a starter for having money. Shown on the club panel, the club page, the board screen with the season's progress against each expectation, the season's letters and a job offer. ClubIdentityTest; runSim identity 3: 24 contenders, 3-6 academy clubs, 156-178 selling clubs; a selling club's sales met by half after the first season; no AI manager at a selling club sacked in three. Not built: style, which the game cannot yet measure; the academy club is rare.
In the code: docs/club-recruitment.md § What a club is for; roadmap 11
Club philosophyDone
2026-10-17. Every club has two philosophy slots, each holding one of four policies: Our own first, Buy low, sell high, Win now, Live within our means (ClubPhilosophies, no draw). Each gives one modifier on a decision that exists (the picked side favours a man the club trained over an equal one; the seller's floor; the board's reserve; the trust its money levers read), adds its aims to the board's season review beside the identity's, and moves the fans' season-ticket renewal. An AI club holds its identity's policy under the same rules. A change costs board confidence (−8 and a trust debit away from what the club is, −4 toward it, free in a manager's first 60 days) and a slot changes once a year. A change is a receipt on the board's standing. Shown on the Board screen in words, with the price and the next day it can change, and on the board's levers in Finances. ClubPhilosophyTest. Measured on 0a47f625 against the same tree without them, read before the in-the-red stop (final form 48e0422d), which can only shrink the effect: econ 3 moves the board's median reserve 10.0 weeks to 8.0-9.6 in the big first divisions on opening day and nothing else beyond one world's noise; runSim identity 3's POLICY rows show every policy held and judged, and refused a first form whose stricter terms reached the four clubs in five that hold them by default (modest clubs under the line 27 of 159 against 105). 2026-10-19: Our own first's training half, one of the club's focus slots kept for a man it trained, the Training page saying so (FocusSlots.keepsOneForItsOwn, FocusSlotsTest). 2026-10-23: a third slot, the manager's, opens when his board's trust reaches its top band (Keys) and closes, its policy dropped, if trust falls back below, with a letter either way; the philosophy panel says how many points it is away or what keeps it (ClubPhilosophyTest).
In the code: docs/club-recruitment.md § What a club stands for
The minute of the matchIn progress
Measured for the first time on 2026-09-01 (row 563, V2Rhythm.kt, runSim v2full's THE RHYTHM block) and the engine is FLAT. Goals by fifteen-minute band read 18.2 / 17.6 / 15.8 / 14.9 / 15.3 / 18.3 per cent over 887 goals, closing:opening 1.00, against football's ~9–11 / 12–14 / 15–17 / 15–17 / 17–19 / 22–25 and its rise of 2.2–2.5× — so the engine's richest goal band is the one football's is poorest in, and shots (0.84) and offsides (0.74) lean backwards while cards, which climb steeply in a real match, read 1.02. The reason as arithmetic: exactly ONE performance read in this engine moves with the clock, and it is energy — worth 1.04% of every attribute and 2.86% of top speed across a whole match. There is no opening ramp of any kind. ONE HALF SHIPPED: a LEVEL side now risks 22% more in the closing fifteen minutes (GM_V2LATEOPEN), which was a missing branch rather than a new system — situational's three existing game-state arms all need a scoreline, so at 0-0 in the eighty-eighth minute the engine played exactly as it did in the fifth. Graded per LOOK: 330 risky looks a match, with its effect on the distribution below this instrument's resolution (~2,000 regulation matches an arm would be needed). THE OTHER HALF IS A MEASURED REJECTION (GM_V2WARMUP, defaulted off): a warm-up ramp moves the opening band's goals the WRONG way (combined t ≈ 2.0) while being inert on the errors row it acts through (t = 0.43 on 50,700), because max(rust, cold) returns 25% of the term it was sized at — every generated footballer already carries a rust of 0.178 mean. A cold side gives the ball away in its own half, and that is a chance against it. Anything built here must be RHYTHM and not FATIGUE: 73.5% of player-seconds sit above a 0.90 tank and 0.0% within 0.45 of the floor, so nobody in this engine gets tired enough for a fatigue-shaped member to have a population.
In the code: engine/…/match/v2/V2Rhythm.kt; engine-completeness 563; engine-log THE RHYTHM AND THE TEMPER
Provocation, and a footballer's composure as something another player can moveDone
SHIPPED 2026-09-01 (row 618, V2Temper.kt, GM_V2TEMPER) after being LEFT OPEN ON PURPOSE by the batch before it — the design was the open part, not the build. Until now composure was read at forty call sites in twelve files and every one was the static ag.a.composure, an attribute a man carried onto the pitch and off it again unchanged; the only mutable mental state in the engine was arrayOf(Psyche(), Psyche()), one per SIDE, so no footballer could act on another footballer's head at all. Agent.rattle is the engine's first mutable PER-PLAYER mental quantity — moved by an off-ball engagement with a man carrying the new WINDS_UP_OPPONENTS habit, by being fouled and by a caution, scaled by his own professionalism and temperament (dissentTemper's expression, reused rather than re-invented), and decayed on a ninety-second half-life. It reaches FOUR of the forty reads and that number IS the design: thirty-eight go through Agent.sk, so one derived read could have reached them all — and that would have rebuilt the exact fake match sharpness had just been criticised for, a flat multiplier of the same kind as condition, giving a man who is slightly worse at everything rather than one who has lost his head. The four are a decision or a mistake apiece: the heavier first touch, the hoof instead of playing out, the ball put behind for a corner, and the lunge in his own box. Nothing about his shooting, his penalties or his goalkeeping moves, and teamNerve is excluded on purpose because it would feed back into the mood. The census decided the shape in both directions: the feud is SATURATED (2,752.9 off-ball engagements a match on 71.5 distinct pairs, 34.9% of them a pair's twelfth meeting or later, the heaviest pair meeting 51.9 times), so a feed on the CONTACT would rattle every marker on the pitch — which is why it is gated on a rare habit instead. What was PARTIAL is built. A temper carries between matches as a grudge between two named men (2026-10-24: the next meeting starts him a little wound up and the other man's wind-ups land harder; both men's panels, the match preview and the feed; Grudges, SimV2GrudgeTest, GrudgesTest). And since 2026-10-26 a wound-up man DOES something to the man who wound him up (V2Provocation, GM_V2TEMPER bit 4): he goes for him (his commit share on that man's looks 32% → 52%), goes in late (fouls per challenge when hot 12% → 17%), lashes out at him — violent conduct, a straight red, three matches and Law 12's restart, 0.017-0.020 a match expected against a real 0.01-0.02 — and is the one who argues. The feed says “X loses his head and lashes out at Y” and the suspension letter names the cause (SimV2ProvocationTest, SuspensionCauseTest; engine-log, provocation's acts). Its bill: fouls +1 a match on both worlds.
In the code: engine/…/match/v2/V2Temper.kt, V2Provocation.kt; engine-completeness 618; engine-log THE RHYTHM AND THE TEMPER
Assists and the scorer's recordIn progress
Still missing: the rest of the gap to a real ~70% is play, not the record: goals off a ball won from an opponent and carried in without a pass.
An assist is the final touch, as the providers define it: a completed pass, or since 2026-10-20 a team-mate's touch, knock-down, clearance or unsaved shot that reached the scorer (SimV2ResultAccountingTest; 51% → 61% of 377 goals assisted, runSim v2 '' 900 512). Missing: the rest of the gap to a real ~70% is play, not the record: goals off a ball won from an opponent and carried in without a pass.
In the code: engine-log, THE FINAL TOUCH (2026-10-20)
The match as a storyDone
Six mood feeds and the BIG_CHANCE_MISS / KEY_PASS / BUILD_UP events since 2026-08-26, and touchline words in the feed since 2026-10-18 (EventTextTest). 2026-10-23: a man's head in the feed: nervous on the ball, three chances gone and the rattled man, four lines a match at most, two a man, ten minutes apart (SimV2RhythmAndTemperTest; runSim v2full 40: 3.68 lines a match). 2026-10-25: the rating graded against one reference, WhoScored per Ball, Huynh & Varley 2025 (mean 6.62, SD 0.67): it read 6.41 / 0.56, so the average man sat 0.2 under every reader anchored at 6.6; rescaled onto 6.64 / 0.67, and no threshold moved (SimV2RatingScaleTest; leaguecheck 1 RATINGS). 2026-10-26: the top bends above 8.5 (tens 35 → 4 a season) and a save is worth the chance its on-target shot had of going in (keepers man of the match 1 → 19 of 276), the mean and spread still in band (engine-log, the rating's shape). And a rating says why: tapping it in the post-match table opens its parts in the shown units, from the rating's own expression (ratingWithParts), adding to the number on screen, the bend above 8.5 as a part of its own (SimV2RatingScaleTest, RatingWhyLineTest). 2026-10-27: a man who cannot carry on is told going off (“cannot carry on and goes off”), no longer “is injured” a second time (EventTextTest).
In the code: engine-log 2026-08-26; dressing-room.md
Touches and the player stat lineDone
The most basic stat any provider reports, absent from this engine until 2026-08-26. Agent.touches counts every foot-to-ball contact and ownedTicks the time in possession — a pure accumulator, deliberately distinct from carryTicks, which is engine state read by three decisions and reset every spell. Both reach PlayerMatchStats, along with take-ons attempted and completed and progressive carry metres, which had been counted on Agent and stopped there. It was built to settle a claim and it settled it: the roles audit's finding substantially STANDS. Split by ability, the stronger five of each outfield ten by the engine's own playmaker reading take 1.15x the touches of the weaker five — a world-class playmaker really does see barely more of the ball than the man beside him. Split by POSITION the engine grades ~3x, so the counter separates people perfectly well when there is something to separate. Read the ratios and not the levels: this engine's touch counts each carry contact where a provider aggregates a dribble.
In the code: engine-log 2026-08-26; completeness 687
The pitch and the groundDone
Every ground in the world was 105×68 m until 2026-08-26. A club's dimensions are now derived from its capacity and its id — DERIVED and never rolled, so no save's RNG stream moves. The cost was not the dimension, it was the centre line: the middle of the goal was the literal 34.0 in 199 places across seventeen chapters, and a pitch that varies in width with those left alone is a pitch whose goals are not in the middle of it. The golden digest passing on untouched literals is what proves the substitution behaviour-neutral. The distribution is the member, and its first form was wrong and was measured to be wrong: a continuous jitter made almost every club slightly small, shifted the league's mean pitch 3.1% and cost +0.23 goals a match — a mean shift wearing a variance member's clothes. Football's shape is a spike at regulation with a tail, so 70% of grounds are exactly 105×68 now and the member reads −0.01 goals on its own arm. The axis that matters is LENGTH, not area: length is worth ~2.7x width per metre, and two grounds of equal area but different shape differ by 0.28 goals.
In the code: engine-log 2026-08-26; completeness 690
Psychology and morale depthDone
The dressing room, talks, standings, crises and trust are built and measured; an AI club replaces a captain who has turned and, since 2026-10-20, answers its crises with the effects his answers have (DressingRoomCaptainTest, CrisesTest; dressingroom seasons=6 against GM_AIANSWERS=0), and a deposed captain minds. Since 2026-10-20 a man who has lost his head reaches the match feed, once a spell: frustration, or nerves protecting a late lead (V2Story.tellTemper; SimV2RhythmAndTemperTest; runSim v2full 60: 5.03 lines a match from 3.00 men; the golden digest unmoved).
In the code: dressing-room.md; world-and-people.md, Standings
Standings: the board, the room and the fans, with reasonsDone
2026-10-18, slice 1: every change to the board's confidence and to a man's morale at his club records its cause (BoardSystem.move, MoraleSystem.adjust), and Home shows the board and the room as numbers with their four-week change and three largest reasons; the Board screen lists all of them, the room opens man by man, and a profile says why he feels what he does (StandingsTest). Behaviour-neutral. Slice 2: the fans' mood, a sum of fading reasons for each club of his division (the table against what the club expects, results and derbies, a favourite sold, season-ticket prices, an academy club's own boys), read by the gate and the summer's renewals in place of the table, and monthly by his board; a Fans tile on Home and the stands on the ground page (FansTest). Slice 3: the event catalogue, letters as data with stored choices and follow-ups, rolled on hashes: the winning run, the controversy, the friend you sold, a promise falling due, two men for one shirt; what each answer did is shown under its letter (EventsTest). Slice 4: crises: the board, the room and the stands, each two Mondays under its threshold, open one with three choices that cost different meters, a midpoint word and six weeks, ending in a lasting reason or a consequence the game already has; the division's AI clubs have them too and, since 2026-10-20, answer by a rule their news states (the answer whose cost lands on their healthiest other meter) with the same effects as his, their boards' moves carrying reasons (CrisesTest; dressingroom seasons=6 against GM_AIANSWERS=0: the AI's rooms through 9 of 33 against 3 of 37). Slice 5: what each of his men thinks of him, in words with its reason (promises kept and broken, a refusal, his debut, the armband, a friend sold), read by his renewal ask and his unrest (TrustTest). The five slices are built; what is left is in docs/world-and-people.md.
In the code: world-and-people.md, standings
Mission goals / curated startsDone
2026-10-14. Beside the free choice, six curated starts on the new-career screen, each a situation with a goal and a deadline: the great escape, the fallen giant, back from the brink, sell to survive, the academy project and the owner's project. The club is found on the world by what it is (CuratedStarts.find, no draw) and the career is built on that world, so the card names the career's club; the three that need a state on day one set it through Club.book and the ladder's own Monday. The goal is one the board already judges, read once a season at the season's close: met or missed is a letter and a line on the board screen. CuratedStartsTest: every start found on the default world and world 42, each start's day one, the judgement. Not built: a start on any world but the default one, and any reward beyond the letter.
In the code: docs/world-model.md § Curated starts; roadmap 12
Transfers, contracts and recruitment93% · 12 done, 2 in progress, 0 not started
Contract negotiationDone
Permanent moves show scouting estimates and a word-only appeal estimate. Character reasons require report-level knowledge; unknown character is stated. User signings check the player's actual appeal deterministically; a hard block ends talks. June deadlines, actual renewal extensions, bonuses, renewal clauses, release prices, current ownership and manual feeder actions bind. May/June signings start next season; the dialog shows the end date. Free agents can enter talks. Release prevents a return to the same club for a year. Release quotes and books a pay-off. ContractYearTest, TransferMoneyTermsTest, DealPlumbingTest, ContractDecisionsTest, MoveAppealViewsTest. Loan terms remain in the loan lane.
In the code: docs/club-economy.md §7
Who signs the playersDone
Three recruitment structures — manager, sporting director, owner — and the marquee signing with a playing obligation. 2026-10, the relationship: the board's trust in the manager is one function with three bands (watched, trusted, given the keys) shown with its terms on the board screen; he can ASK a director or owner for a position, a named player or a sale and gets an answer with a reason; a signing over his head comes with why and he may welcome it or object, the objection settled two months later; trusted managers are asked first and may block one director's signing a season, with the keys every one; an owner's marquee is always put to him first and can be steered, at a price. Checked on the landed tree, 2026-10-13: both halves this row was waiting for are in. An AI club carries the marquee's playing obligation too (ClubControl.aiObligation; read on team sheets, 142 of 142 matches started, so it sacks nobody), and the three bands set the board's reserve, credit, sign-off and squad-cost line in the pot (Pot, PotTest). Not built, and refused: steering an owner to a named player.
In the code: docs/club-recruitment.md; BoardRelationsTest, BoardTrustTest
Scouting as beliefDone
A club is wrong about a player, with three systematic biases, and the AI market orders and prices on that belief. 2026-10: the recommendations read the lens and the squad's need instead of the truth, the director ranks on belief, a report keeps what was believed so a signing can be shown to have been misjudged, and knowledge has geography. The offer dialog shows and pre-fills the scouting estimate; incoming bids price through the buyer's lens. ContractDecisionsTest.
In the code: docs/scouting-model.md; runSim scout
Scouting departmentDone
Built 2026-10. Scouts are assigned to a country or one competition, an age band and a position group; an assignment costs money every week (its own ledger line), raises what the club knows about the players it covers and files reports; knowledge nobody maintains fades to a floor set by geography. A report says what the club believes he is good and bad at, where he would play, whom he would replace, what he would cost and how sure the scout is — and two months after a signing the club says whether the report was right. The shortlist reports a listing, a transfer request, a final contract year, a price move and a move elsewhere. 2026-10-16: scouts are people. Each is a member of staff with a judging-ability and a judging-potential rating, the countries he knows and a wage on the staff curve, hired and let go on the staff market screen up to the size the facility funds; an assignment or a watch is one scout's, a good judge and a man who knows the country raise the club's knowledge faster (runSim scout row 11: 0.53 to 0.78 known, belief error 0.23 to 0.10, from the worst to the best scout), his report is read through his own two ratings and names him, and the bill is his wage on the staff line plus his travel. AI clubs send their scouts at each window where their needs are and their money reaches (row 12: 24.5% of their foreign signings come from a scouted country, against 2.4% under the old hash). 2026-10-16: a rival's interest. The market records which clubs are after a man and how far they have gone (asking, bid in, bid accepted) where AI clubs act, keeps it 90 days and drops it when he moves; the manager hears it through his scouts (a public bid, or a club or player in his country or one his scouts are in), on the target panel, the shortlist and its news, and in the bid dialog (runSim seat 2 at Everton: of his 120 candidates mid-window another club was after 9 and he knew of 7). Not built: scouts are not poached and an AI club's scouts do not age; a man with several clubs after him does not ask more.
In the code: docs/scouting-model.md § Scouts who are people, § A rival's interest; ScoutingDepartmentTest, ScoutsArePeopleTest, RivalInterestTest
Squad planningDone
The planner half is built (2026-10): depth by position group, best first, with age, contract end and who is leaving; cover by position; and each group's need now and a year from now. It is ONE definition of need (SquadPlanner.needs) read by the planner, by the scouting department's suggestions and by every AI club's shopping, which now counts a man in his last contract year as a body it is about to lose. 2026-10-14: the club's B and youth players are shown in each group as cover under the senior men, marked as feeder, best first (the need still counts the senior squad: it is the one every AI club shops by, and the screen says so); and every leaving first choice — out of contract, past the planner's age, or here on loan — is given a successor from the senior, B or youth squads, with how far short of him he is, or, when nobody is within a point and a half (SquadPlanner.WITHIN_REACH), the player search opened on that group with the club's first-team standard as the bar. SquadPlannerSuccessionTest. 2026-10-16: the manager can pin a successor of his own (the pin on the row; Club.successors): the planner shows his man over its own, says when its own would be closer, and takes the place back when his man has gone. January and April expiry warnings include feeders and owned loans, human feeder renewals stay manual, and squad lists mark the final year. Matchday cover promotes existing feeder players; missing cover is explained and fewer than seven fit players blocks kick-off. ContractDecisionsTest.
In the code: docs/scouting-model.md; SquadPlanner
Fee amortisation and PSRDone
Football accounting: profit on disposal, an academy player as pure profit.
In the code: runSim psr
Instalments and sell-onDone
Dated debts settle through both ledgers and survive save/load and resale. Sellers discount deferred fees and price a young player's next-sale share; clauses pay once on the next fee and lapse on a free move. AI deals create both. Dated amounts and retained shares are shown before acceptance; the seller can counter all up front. Obligations and public clauses remain shown. Feeder fees, instalments, sell-on and player costs belong to the parent treasury. TransferMoneyTermsTest, ReviewedBidsTest.
In the code: docs/club-economy.md §7.7
LoansDone
2026-10-26, a club that needs a man asks to borrow one: short of bodies, a first choice out for four weeks, or a better man it cannot afford, a club asks a club above it for a man that club does not pick (the manager's by his own eleven and minutes), and the manager gets a letter saying which need it was and what the man would play, never two in a week and not again from a club he refused in that window (LoanRequests, LoanRequestsTest). Read, pyramid 8 paired at two seeds: about 1,100 such loans in eight seasons, the men playing 0.83 of their borrower's matches; loans into a big-five top flight 0.43 / 0.41 a club-season against 0.22 / 0.18, still a seventh of CIES's 3.09; loanrequests 3: 5, 5, 0 letters a season at Manchester City, 5, 1, 0 and 5, 3, 0 at mid-table Czech and Championship clubs (club-economy §33). 2026-10-20, one read of a man's minutes: a move judges a man's minutes as the loan wish does (last season's in pre-season), so a man who sat on the bench takes his parent's affiliate in July: loans out on the window's first Wednesday 53 → 103, summer 2027's to affiliates 0 → 11, the transfer market within a few per cent (PlayerAgency.knownShare, club-economy §27). 2026-10-20, pre-season loans: a man still at the club he played for last season is read on last season's share until four rounds are played, so the summer loan market works through the window instead of on one Wednesday (and a summer like 2027's is no longer empty: 0 → 82 loans); his page says why he wants a loan (PlayerAims.loanShare, PreseasonLoansTest, club-economy §26). User and AI loans keep fees, wage shares, end dates and roles. Fit league opportunities measure delivered minutes; owners receive reports, can recall in a later window with an unused-fee refund, and both clubs remember broken commitments. Purchase quotes use the world price curve; agreed borrower wages remain fixed; incoming quotes can be countered, and an AI borrower accepts a compulsory purchase only at a fee it would bid outright and a role its squad can deliver (LoanBorrowerTest). Options use normal transfer accounting and player agreement; obligations survive recall and complete automatically. LoanTermsTest, LoanLifecycleTest and LoanReviewTest. Registration remains a later lane.
In the code: LoanSystem Weekly wages and forecasts use parent treasuries, dated returns and compulsory purchases.
The transfer window as one placeIn progress Active: Transfers and money
Still missing: the board's line refuses 27% of Czech January passes.
The desk, the target panel, one frame for every deal dialog, the means and the star frames are built (ClubMeansTest, StarScaleTest, SignableSearchTest), and January's wage curve is read (club-economy §19.4: Czechia's January share 16%, band 13-23%). 2026-10-20, the Club frame's top: four and a half stars is the best first choice of a man's group in the country's top division (a top-flight club's own), three still starts for us, and the step keeps its 0.75 floor at a club whose starters are that best; so a second-division club's affordable page reads four stars in Club where it read five. League answers where a man stands in our own division, so men past its best still read five there; each frame's caption says both ends of its scale (StarScaleTest). 2026-10-22: a deal between two AI clubs takes days: the fee, then the player's terms two to four days later, then his medical (an injured man fails it), each a stage the market and the papers see, and a later bid can still take him; a man on his shortlist or in his scouts' reports is a desk item and a letter at each stage (TransferStages, TransferStagesTest; econ 8 against GM_AIDEALSTAGES=0: 5,487 staged, 3.4% collapsed at the terms and 1.8% at the medical, and 13% fewer moves at home, written down in docs/club-economy.md §31). Missing: the board's line refuses 27% of Czech January passes.
In the code: ui-outstanding.md; club-economy.md §19
Competition for a signatureDone
Offers persist to a shared decision date. Valuations use this world's price curve. Sellers compare present value and retained shares; players choose accepted clubs by appeal and wages. The manager sees plausible rival interest, improves his terms or compares incoming bids, and can miss the deadline. An immediate club reply lets the manager offer player terms; a late new rival grants one visible answer day once, within the window. AI offers reserve fee, wage and positional need; board approaches join the same auction and announce only an actual arrival. TransferInterestTest, BidReviewTest, MarketDayTest. Part-exchange remains unsupported; PartExchangeSaveTest covers removal of its unused offer field.
In the code: roadmap 8; TransferInterest
Deadline dayDone
Country calendars come from the database, with July–August and January defaults. The buyer’s country governs registration. The final three days lower unwanted sellers’ floors and raise bids for unfilled needs; decisions can come today. Existing human auctions reject unseen last-day arrivals when no reply day remains. One public digest covers the day’s business and refreshes after later manager actions. Closed panels explain free agents and agreed loan purchases. TransferWindowTest.
In the code: roadmap 10; TransferDates; TransferDeadline
Where clubs buyIn progress Active: Transfers and money
The depth rule and the abroad bar are measured (scout 3, goingrate 8), and the summer top-up prefers a man from home (TopUpAtHomeTest). Open with the owner: whether a released squad player finding a club abroad is wrong; the home preference changed little (World talent balance).
In the code: club-economy.md §4.9, §10.9
Agents, fees, work permitsDone
Work permits are built (2026-10-11, Lane G). One rule a country, as data; the bundled table asks one of the British associations only. A points test on caps and the nation's standing, the league he is leaving, the fee against the buyer's own squad, and age; refused before any money moves at the bid, the completed transfer, the free signing and the loan, and shown with its parts in the offer dialogs. PermitTest. Agents' fees (2026-10-14): the club that signs a player pays his agent 4–8% of what the contract pays him over its term (a stable function of the player, no draw), on a transfer, a free signing and a renewal's added years, the manager's club and an AI club through the same paths; every deal is asked with the fee, and the deal dialogs name it. AgentsTest, TransferMoneyTermsTest. econ 8: 1.7–3.1% of a big top flight's earned income against the Premier League's ~6.5% (a small transfer market), no club over its line for it on day one; a bid in flight holds the fee. Not built: agents as people the manager deals with, agents touting players, an agent's say in whether a player moves, fees on loans and academy contracts, and agents' fees in the squad-cost ratio.
In the code: roadmap 24; docs/club-economy.md §13.4, §17
Squad registrationDone
2026-10-11, Lane G, first piece. The rule is data on the competition (RegistrationRules: places, places reserved for home-grown players and for the club's own, a limit on players from outside the country or its union, an age that needs no place, the loan rule), with a recognisable default for each playable country. Where a player was trained is a fact about him, counted each 30 June from fifteen to twenty-one, and assumed without a random draw for the players already in the world. RegistrationTest. Every club in a league with a rule names a list (Club.registered): AI clubs the best valid one, re-named through their window and fixed at its close; a league side is picked only from it, with a counted dispensation for a side that cannot make up eleven or has no fit goalkeeper. Measured, runSim registration 3: no AI club names an invalid list in three seasons; squad size binds nobody (a senior squad is about twenty), the foreign limit does (Spain leaves 67 men off twenty lists on the first deadline). RegistrationListTest. The manager builds his own on the Squad list screen: quotas counted on his draft, every man with what he counts as, a list that breaks a rule cannot be registered, and an unanswered deadline registers a valid one and writes to say whom it left out. The planner shows the quotas beside depth, the offer dialogs say what a signing does to the list before the bid, and the team sheet shows a man without a place as it shows a suspension. AI clubs shop by the rule (RecruitmentRules): no bid for a foreigner at the foreign limit or for a man with no place to take, half a point more for a home-grown man where reserved places are empty, and loans in and from one lender are the league's to set. Measured over three deadlines: no AI club names an invalid list, and sides made up a team with an unregistered man 15 times in three seasons then and not once on the joint baseline of 2026-10-13, which is a zero to look at before it is believed. 2026-10-14, the continental list: a club in Europe names a second list, UEFA's List A (25, eight home-grown, four of them its own) with List B as the exemption (under 21 and two seasons at the club), fixed at the same deadline and changed in winter; the manager builds it on the same page with a chip per list, and a European side is picked from it with the counted dispensation. runSim registration 3: no AI club names an invalid continental list in three seasons, and a European side leaves 0 to 0.25 men off. ContinentalListTest. 2026-10-16, UEFA's winter cap: the list a club holds at its summer deadline is the season's, and in the winter it may add at most three names to it (RegistrationRules.winterChanges, data on the competition; taking names off is free, and a league's list is not capped); the AI's best list, the manager's own and the place a signing would take all read it, and the list page counts the new names against three. ContinentalListTest. Not gaps: the domestic cups keep no list, which is the rule in most countries; and Spain's first deadline leaving a dozen or two off its lists is the generated world having been built before the rule, a fact of the first season and not a missing mechanic.
In the code: roadmap 19; docs/club-economy.md §13, §13.8
Squad, development and staff83% · 8 done, 4 in progress, 0 not started
39 attributesDone
Full schema plus special moves, with generation and engine reads measured separately.
In the code: Attr, CapGroup
Training loadDone
Intensity as a decision beside TeamFocus, with a per-player override. Three of the four design claims it was built from were refuted by the instrument.
In the code: docs/load-management.md
Match sharpnessDone
It is a different thing from condition as of 2026-08-31 (THE LAST SEVEN member 5, GM_V2SHARPNESS), and the story of this row is a DENOMINATOR measured wrong twice. Until now V2Agent.sk multiplied every attribute by 0.88 + sharpness × 0.12 and nothing else read it — a multiplier of the same KIND as condition's, doing the same thing to the same twenty-two men — so a man three months out was slightly worse at everything rather than a selection decision. BATCH 5 measured a freshly GENERATED world (0.826 mean, 0.0% under 0.70) and closed the row; THE LAST SEVEN's first census measured 5.31 M playable PLAYER-DAYS of a played career (0.821 mean, 23.6% under 0.70) and reopened it. Both are the wrong population, in opposite directions — a generated world is the one state in which sharpness has never moved, and a player-day count is dominated by men who are NOT playing, because losing 0.02 a matchday is what creates the low tail. The honest denominator is an APPEARANCE, and over 296,140 of them a man walks out at 0.944 mean, 81.1% at 0.90 or better, 5.4% under 0.70 and 1.4% under 0.45 — about one and a half men a match, which is what a real squad looks like. What shipped is a change of SHAPE at roughly constant size: the flat blend is halved and the freed half redeployed onto RHYTHM, which is what match sharpness is about and condition is not — his first touch on an arriving ball, how long it takes him to settle it, and the timing of his jump. Nothing physical reads it. The half that MOVES sharpness was already right and is untouched: minutes played, a matchday missed, the injury return, the pre-season reset.
In the code: V2Agent.kt v2Rustiness; engine-completeness line 562; engine-log THE LAST SEVEN
What a match costs a bodyDone
BATCH 5, 2026-08-25. The engine computed a per-second fatigue drain for every man from his speed, his side's pressing height and tempo, his own stamina and natural fitness, the weather and the pitch — and MatchDaySim threw all of it away and charged rng(0.32, 0.45) × minutes/90, so stamina bought nothing outside the ninety minutes and natural fitness bought nothing inside them and squad rotation was a question with no inputs. It is charged now, by all three paths that take a match out of a footballer — a SimV2 fixture, a QuickSim fixture and an international — which is why the arm lives in :model beside the injury arms and not in V2Tuning. The MEAN is deliberately unchanged at 0.385, because Development.OVERPLAY_FRESH, the injury model's chronic load and illnessSusceptibility are all sized off it; what changes is the SPREAD, measured at 0.251 exertion per ninety minutes with a range of 0.105 to 0.517, i.e. 0.42× to 2.06×. The interval is a share of the deficit now, scaled by natural fitness: the census found energy at half-time was 0.88 and the flat 0.12 put it back to 0.99, so the break was a full reset and nothing across ninety minutes could accumulate. Two rows were REFUTED by the same census rather than built — repeated-sprint decline and cramp — because nobody in this engine gets tired: a match costs 0.25 of a 1.0 tank, a man finishes on 0.89, and 0.0% of player-seconds come within 0.45 of the floor. Their blocker is the speed distribution (24% of player-time above 5.5 m/s against a real ~3.5%) and it is a calibration line, not a mechanic. And the career-scale reading is the best result it produced: the chronic-load median held (0.057 → 0.058, which is the pivot doing its job) while the tails spread (p99 0.240 → 0.395) — and that turns Development.overplayFactor from a mechanic almost nobody reached into a live one, since its hinge sits at 0.30 and fewer than one player in a hundred used to get there. Its cost is illness 0.79 → 0.86 a player-season, recorded as a calibration line rather than dialled out.
In the code: MatchLoad.kt; engine-log 2026-08-25 THE BODY
Staff hiringDone
Wages, contracts, compensation, pay-offs, a derived shortlist, board-appointed posts, and AI clubs poaching each other. 2026-10: a contract that runs out is a decision — the man asks for what he is now worth (more after a good season, or if a bigger club would take him), the manager renews or lets him go within three weeks, every other club decides on the price, and a man who leaves is on the market for two seasons. A man who leaves is signed by the club that wanted him or goes onto the market, and does not come back to the club that let him go for less than he asked. World staff quality drifts +0.76 in eight seasons against +0.82 with every contract renewing: lapsing does not explain the drift (an earlier reading that said it did rested on two defects in the rule).
In the code: docs/staff-hiring.md §3, §6; StaffMarketTest
Relegation wage reductionDone
A contract carries a percentage cut that applies if the club is relegated, set from how much less the division below earns (45% in the Czech second division), and shown with the player's contract. A club that goes down from a top flight is over its board's squad-cost line on arrival about half as often and for five months of the next twelve where it was all twelve. 2026-10-13: the manager's own renewals carry the term and his contract dialog shows it, a division that relegates only through a play-off has one, and the cut moves a man's mood category. 2026-10-14: the calibration pass sized the convention on a relegated club's own income fall (35–40% in the top flights) and refused it: a club that came down was then over its board's line all year in five of six countries; back on the 50% cap it reads 1–7 months (club-economy §15.4). 2026-10-14: the manager negotiates it. In the contract and renewal dialogs he sets the cut, none up to the cap, and the player prices it into his wage at the club's danger of going down; AI clubs keep the convention (RelegationClauseTest: two cuts, two asks; the rollover takes the negotiated cut). Not built: a promotion wage rise as its mirror.
In the code: docs/club-economy.md §4.7.16, §10.11; runSim pyramid 8
World talent balanceIn progress
Still missing: the intake arrives at 8.7 and gains 0.2 a year, so men of 17+ fall from 1,168 to 930; how much a small league keeps under the market curve. Promoted clubs are A promoted club that can stay up.
The mechanical exits are fixed and read (talentflow 8; club-economy §4.7, §22-23). Missing: the intake arrives at 8.7 and gains 0.2 a year, so men of 17+ fall from 1,168 to 930; how much a small league keeps under the market curve. Promoted clubs are A promoted club that can stay up.
In the code: club-economy.md §4.7, §22-23; player-development.md
A promoted club that can stay upIn progress
Still missing: their recruitment signs men about two points under the new league; a league-standard bar was measured worse and reverted. 2026-10-24: the census says why: when a promoted club goes after a man at its new standard the SELLER refuses 58% of the time, the player 5%. Senior loans from above landed (SeniorLoans: a club lends a man it does not pick, keeping cover): promoted clubs borrow 53-70 men in their first summers against 12-18 and close the gap, but straight back down reads 57 / 49 of 105 against 59 / 49 without, still about 50% against football's 38-43%; the lender's points and injury cover do not suffer. Loans into a big-five top flight read 0.23 a club-season against CIES's 3.09. 2026-10-25: where the row lives: pyramid plays on QuickSim, whose strength-to-result curve is half the full engine's on the same squads (7.7 against 16-18 points a season per ability point), so its tables are compressed at the top (champion 70 against football's 88); written down as a calibration line, not turned. 2026-10-26: with loan requests (a club that needs a man asks to borrow one), straight back down reads 45 / 43 of 105 against 52 / 44, inside the noise.
Read 2026-10-14 (pyramid 8): promoted top-flight clubs go straight back down 7-12 times in 21, football's band. Missing: their recruitment signs men about two points under the new league; a league-standard bar was measured worse and reverted. 2026-10-24: the census says why: when a promoted club goes after a man at its new standard the SELLER refuses 58% of the time, the player 5%. Senior loans from above landed (SeniorLoans: a club lends a man it does not pick, keeping cover): promoted clubs borrow 53-70 men in their first summers against 12-18 and close the gap, but straight back down reads 57 / 49 of 105 against 59 / 49 without, still about 50% against football's 38-43%; the lender's points and injury cover do not suffer. Loans into a big-five top flight read 0.23 a club-season against CIES's 3.09. 2026-10-25: where the row lives: pyramid plays on QuickSim, whose strength-to-result curve is half the full engine's on the same squads (7.7 against 16-18 points a season per ability point), so its tables are compressed at the top (champion 70 against football's 88); written down as a calibration line, not turned. 2026-10-26: with loan requests (a club that needs a man asks to borrow one), straight back down reads 45 / 43 of 105 against 52 / 44, inside the noise.
In the code: club-economy.md §4.15, §14.9, §32, §33
Player developmentIn progress
Still missing: stage 3's reinvention prompt, stage 4's development plan and breakthroughs, stage 5 for AI clubs; the §9 baseline is from 2026-08-03.
Stages 1-2 shipped and measured: ceiling vectors, and exposure reshaping them (player-development.md §13, §16; runSim dev 5; DevelopmentModelTest). 2026-10-28: the playing-time input counts the club games he was fit for, not every game since he came, so a man back from injury is no longer read as left out (DevFitShareTest; runSim dev 5: the world's young men gain +0.76 against +0.68 in five seasons, peak25 +0.11, written down for the calibration pass; §21). Missing: stage 3's reinvention prompt, stage 4's development plan and breakthroughs, stage 5 for AI clubs; the §9 baseline is from 2026-08-03.
In the code: player-development.md §6, §9, §13, §16
Expanded trainingIn progress
2026-10-15, the rest instruction: the manager rests one man from training for a few days (REST intensity through the existing load arithmetic, his own programme resuming after) or from his club's next matches or one competition (left out of an auto-picked side, the cover takes the shirt; his own team sheet is warned, never overridden), from the Medical Centre row and the player's page, and a rested man is badged where an injured one is. RestTest. A per-player intensity and an individual focus already existed. 2026-10-18, the season plan: no weekly grid; four rows (pre-season, the season, a busy run of three matches in eight days, the run-in), each one focus and one intensity, filled by default (pre-season fitness at a high load, a busy run recovery at a light one) and switching by itself on each club's own fixtures; the manager changes a row with one choice on the Tactics page, where the row in force is marked, and the assistant says in one letter when a new part of the season starts. AI clubs follow the same plan with their manager's own methods as the season (TrainingPlan, TrainingPlanTest). Read against master: injuries per playable player-season 1.93 → 1.90, unavailable 7.7 → 7.4% (inside the band), the world's development unmoved (runSim dev 5: mean ability within 0.04 a season). 2026-10-18, focus slots: a club gives individual focus to two men plus one for every five points of its first-team coaches' quality; the Training page shows the slots held, the assistant's men for a free one with their reasons and one tap to apply, and beside each focus what it has moved since it was set ("+0.4 in 9 wk"); one letter a month while a slot is free. AI clubs fill theirs from the same suggestions (FocusSlots, FocusSlotsTest). Read: the world develops slightly more (clubbed mean +0.07 in five seasons, the young cohort realising 32% of its headroom against 27%), written down for the calibration pass. 2026-10-20, the AI rests: an AI club in a played league rests a fit man from training for three days on a Monday when the medical screen would call him at risk and his load has spiked past what his body is used to, the one cause a rest can take away (Rest.aiWeekly, AiRestTest). Read, runSim injuries 2 against GM_AIREST=0: 2.58 rests a playable player-season; injuries 1.86 against 1.88 a player-season (about 1.3 SE), unavailable 7.5% against 7.5%: a few days off training moves little, because most of a man's risk is match exposure and who he is. The first form, on the risk band alone, rested 6.28 times a player-season for no change and was refused.
In the code: roadmap 31, 30
Coaching allocationDone
2026-10-19, coaches by unit: a goalkeeping coach, a fitness coach and one to three outfield unit coaches (defence, midfield, attack; the training ground carries one, two from level 5, three from 8) through the staff market; a senior trains with his unit's coach in the assistant's place and the coach's speciality leans what his position needs, the fitness coach leans physical growth; the Training page lists each coach, his quality and wage and the posts the ground does not carry yet (StaffPost.open, UnitCoachesTest). Read: development unmoved (dev 5), staff wages up to 7.5% of the players' and squad-cost breaches 43 → 50 over eight seasons, written down for the calibration pass. Before it: coaches could be hired, kept or let go, but not assigned to a group or a discipline. (Scouts are people with their own assignments since 2026-10-16: the “Scouting department” row.) What changed under this row in 2026-10: the academy director a club hires now coaches its B and youth sides (he coached nobody there before), and runSim youthdev reads the effect inside one standard error — a teenager in a feeder squad gains a third of an ability point in three seasons, which is the thing allocation would have to move.
In the code: roadmap 29; docs/staff-hiring.md §6, §7
Mentoring and social groupsDone
Decided 2026-10-16 and built in slices 1-4: bonds that grow from the squad, the same room at every club of the division, natural mentoring with one lever, the captain who keeps a grievance in the room and, since 2026-10-20, a captain who minds losing the armband (DressingRoomTest, DressingRoomMentoringTest, DressingRoomCaptainTest). 2026-10-21: the room's camps, named by the one thing that binds each (the compatriots, a unit, the academy boys, the old guard, a temperament), with their men, who leads them and their mood, on the room's dialog and a man's dressing-room panel; a reading that decides nothing, and never the majority (CampsTest; runSim dressingroom: one to four camps a club on the first day in both the Czech second division and the Premier League, about half the men in none, none over half a squad). 2026-10-23: what mentoring did is on both men's panels, in words and months (“more professional twice so far, the next in about 4 months”), and when nobody looks after a young man, why, from the pairing's own predicate (DressingRoom.mentorship; DressingRoomMentoringTest: the countdown lands on the Monday it names, MentorshipLineTest).
In the code: dressing-room.md, Built
Club, finance and the board96% · 21 done, 2 in progress, 0 not started
Two-price ticketingDone
Season vs matchday split with a real elasticity curve that peaks at the revenue-optimal price and falls past it. Corrected support raises season-eight median fill in ≥54.5k grounds from 41.38% to 65.29% on econ 8; the price curve is unchanged.
In the code: runSim econ, gatecheck
Wage billDone
Squad and backroom on one balance sheet. The backroom is 8.1% of the bill at the top of the game against a real ~8%.
In the code: docs/staff-hiring.md
Board confidenceDone
Monthly review, season review and the sack. Predictions and position targets follow league size and exchange places; no-drop leagues require a respectable finish and rank bands are monotone. The season review judges actual post-playoff survival from the played division’s snapshot. The picker shows the same range. BoardEconomyTest covers the rules. Since 2026-10-18 every change records why, listed on the Board screen (Standings).
In the code: BoardSystem
The manager's own moneyDone
2026-10-17 (slice 12, docs/world-and-people.md): every club pays its manager on the staff line, the AI's too, about 2% of what it can count on; the user signs a contract when he takes a job, is paid out to a year when sacked and nothing when he resigns, and earns a quarter's wage for a trophy. His account sits outside every ledger: a lifestyle he sets, an investment strategy on a market drawn from the world's seed each month, the share invested, and his net worth recorded monthly and drawn on the career page. ManagerPayTest. 2026-10-18 (slice 13): what it is for, buying a club (the row below). 2026-10-21: an AI manager signs the user's contract too: two seasons at appointment, re-priced only when it runs out, paid what is left of it to a year when sacked, and kept by a board that cannot pay him off; his card shows the wage, the year it runs to and what his club would owe today, and the chronicle what a sacking in his division cost (ManagerPayTest, TakeJobTest; econ 8 against GM_MGRCONTRACTS=0: sackings 2,909 against 2,953 in eight seasons, compensation 1,772m against 1,084m, five boards kept a man they could not pay off; docs/club-economy.md §29). 2026-10-22: a federation pays the manager of its national team, beside his club or alone: the club curve read off the median club of the country's own highest league and the job's standing, to the June of the next finals, renewed each cycle, on his account as its own line and shown beside his club wage (ManagerPay.signNational, NationalWageTest; runSim intl FEDERATION-WAGES: England €3.2m a year, Germany €3.0m, the Czech job €624k, a top-10 nation's median €2.3m). 2026-10-23: a nation whose football is played on paper is priced by where it sits in the world ranking, interpolated between the played nations either side of it, and no longer by its light league: in the opening season ranked 11-30 a median €982k (€111k before; Morocco €104k → €1.59m), 61st and below €208k (€62k), each nation its own figure.
In the code: ManagerPay, ManagerFinancesPanel
Club ownersDone
Owners, takeovers, elections and 50+1 built and measured (OwnershipTest; runSim owners 3); the manager as owner and the groups have rows of their own. Since 2026-10-20 the members of a club in his division vote on the fans' standing, three quarters of their mood, with the board's confidence the rest, and his election letter says both and which way they lean (Ownership.membersMood, OwnershipTest; runSim owners 3 club=GER:1:mid against GM_FANSVOTE=0: 11 elections in his division, 1.7 challenger wins expected against 3.3, the fans' standing being calmer than a board's). Elsewhere the board's confidence stands for the members, as there is no fans' standing kept. Since 2026-10-20 what an owner gives follows his means (OwnerMeans: the ask 8-33% of a year's income, a takeover 4-42%, the marquee ceiling; MoneyAsksTest covers all four bands; runSim owners 3 against the flat rule: modest owners 10m against 79m over three seasons, very rich ones 310m against 196m, the top flights' spread of budgets unmoved; econ 8: the competitions' squad-cost breaches 52 against 35, half of them very rich owners' clubs after a marquee signing, the other half hair-width breaches that come with any change to the world, §28). The ask's offer says his share and his means.
In the code: world-and-people.md §6
Clubs remember each otherDone
Club-to-club reasons price fees, and a manager who holds grudges refuses you under −15 (ClubRelationsTest, ManagerTraitsTest; dealcheck 3). Since 2026-10-20 two more: a deal he hijacked (he signed a man that club had agreed a fee for, −10) and an instalment paid late (a payer past its board's credit pays one 28 days late, once, −6 to the payee's view, and his letter says so); ClubRelationsTest. Read, econ 3 against GM_LATEPAY=0: 176 instalments fell due over three seasons and none had a payer past its credit (a club past it is barred from buying), so the late rule is correct and rarely reached; administrations 0 in both arms. Since 2026-10-21 first refusal from the opinion: a club at +4 toward his (one kept loan) offers him a listed man first, with the reason and a three-day hold no other club may bid through, and a lapse line (FirstRefusalsTest); read 0, 0, 1 offers a season for an AI-run second-division club, the bottleneck being a listed man good enough while his window is open, not the threshold.
In the code: world-and-people.md §1, §2
The manager buys a clubDone
Purchase, consortium, the home and abroad rules, Article 5, the owner-manager's keys and an owned club abroad as an affiliate are built and tested (ManagerOwnershipTest, OwnerManagerKeysTest, AffiliatesTest). The blind trust (2026-10-21, BlindTrust): a stake abroad placed while he manages another club keeps its value and loses every say in it; the two clubs may not trade, Article 5 skips it, he may instruct the trustee to sell (28 days), and it ends only at the rollover after he stops managing elsewhere; when Article 5 moves one of his clubs down, a letter says a trust would have kept both in (BlindTrustTest).
In the code: world-and-people.md §6, decision 12
Multi-club groupsDone
Three seeded groups, cheap trades inside, Article 5 (MultiClubGroupsTest; runSim owners 3); the parent lends to its members first through the affiliates. Since 2026-10-22 a group buys in takeovers (one in five it could make: no club in that country, room under its means, a price its parent's year of income covers) and its members lend among themselves first (MultiClubGroupsTest); owners 3: groups 5/6, 6/6, 5/6 by season three, group buys 1, 1, 0, loans inside groups 4, 3, 3 a season, Article 5 moving 2, 5, 4 clubs.
In the code: world-and-people.md §6; club-economy.md §25
The manager's familyDone
2026-10-18 (slice 17, docs/world-and-people.md decision 16): he is 40 when the career opens, with none to three children; a child of 24 to 34 may have children of his own. About one in six plays football and one in eight goes into management, decided at birth from the world's seed. A son who plays arrives at 16 beside his father's club's intake, made by the academy's own function on a stream and an id of his own, so the world is identical outside him; a letter, and "The manager's son" on his profile. Each child at home adds a tenth to the lifestyle's bill. Shown on the career page. ManagerFamilyTest; runSim family N. 2026-10-21 (Succession): the succession. When the career ends, a child or grandchild who went into management and is 28 or more may carry it on, offered on the Game Over screen: a club the family owns passes whole (and he may take charge of it as owner-manager), half the rest of the net worth as an inheritance, a fifth of the reputation, the board's and the players' opinions at half their size, the chronicle; the parent's record is kept on the career page (SuccessionTest). A career has an heir by season 15 in 4% of 200 seeds, by 20 in 7%, by 30 in 18%. Former players' and staff's sons: the row below.
In the code: ManagerFamily, FamilyPanel
The men the game remembersIn progress
Still missing: the position lean (considered, not built: docs/world-and-people.md § 7).
2026-10-18 (slice 15, docs/world-and-people.md decision 14): a player who retires from a played club with 120 league matches for one club, or a season under the manager, and staff after five seasons in one post, are kept with the club they served longest and its city, their record there, and what they think of the manager (seasons under him, his strongest receipts as they left), as Reasons. A former player who takes a coaching job keeps it: his staff card says where he played and what he thinks of you, and that view shades his wage ask to your club, or keeps him away. Forgotten at 60 unless working. ArchiveTest; runSim savesize N: 34 / 94 / 192 men by seasons 5 / 6 / 7, 0.05 MB. 2026-10-19 (slice 18): a world opens with each played club's own former players and staff, retired before the career (more at a bigger, older club), positions and best attributes in the country's style, and at about one club in three the academy director or assistant is one of them from day one. 2026-10-21: an AI club that would generate a new manager appoints a remembered former player instead, his own club first (a homecoming, the world's headline in a played league or the manager's country), on the same draws, so the world is otherwise unchanged; a rival manager's card says where he played, or “Played N matches for your club”. ArchiveManagerTest; runSim owners 3: 11 of 1,093 appointments in three seasons, every one the pool could not fill, 4 of them homecomings. 2026-10-21: at a members' club, one election in two, a former player of the club stands for president; the election letter says so, and if he wins the owner panel shows where he played and what he thinks of you. ArchivePresidentTest; runSim owners 3: a former player stood in 9 of 25 elections in three seasons and won 3. Missing: the position lean (considered, not built: docs/world-and-people.md § 7).
In the code: Archive, FormerPlayerLine, ManagerCard, OwnerPanel
World events: television deals, rules, crises and boomsIn progress
Still missing: the Czech pyramid's sizes.
2026-10-19 (slices 9 and 10, docs/world-and-people.md § 5): one shape for what the world changes on its own, drawn from the world's seed a season ahead, announced (news, chronicle, a letter in his country, the Finances page) and applied at the rollover. Television deals every three seasons a country (median +6%, −25% to +60%); the Premier League's betting-shirt ban as the first rule; a crisis (×0.85) or a boom (×1.10) for two seasons on new sponsor deals and the gate, and a 12% overdraft in a crisis. WorldEventsTest; econ 8 paired on the arm: 23 deals in seven seasons, broadcast −12% to +82% a top flight by 2032. 2026-10-21: a top flight's squad-cost rule tightens, drawn from the seed a season ahead (one chance in twelve a country-season, five or ten points, not under 60%), told as news, a letter in his country and on the World events panel with both figures, and applied at its season; the board plans to it from the day it is told (WorldEventsTest; econ 8: five rules in seven seasons, and in the season each bites 5 breaches in the touched top flights against 3 without, all of it Slovakia's ten-point step). 2026-10-25: an owner's money reads the era (Ownership.era): the ask and a takeover's gift ×0.85 in a recession and ×1.10 in a boom, the debt cleared in full, and the ask names the term (MoneyAsksTest). 2026-10-26: a league changes its size, from the database (format 4) or by its own vote about once in twelve seasons, through a transition season's extra promotion or relegation places (LeagueSize, LeagueSizeTest); the Czech pyramid is refused and never votes. 2026-10-26: every played top flight may draw a front-of-shirt betting ban (about one season in fifteen, once per country), and a ban binds the league: a running betting shirt ends in its first season, a promoted club's on arrival (BettingBanTest). Missing: the Czech pyramid's sizes.
In the code: WorldEvents, WorldEventsPanel
Records, the chronicle and the hall of fameDone
2026-10-19 (slice 14, docs/world-and-people.md § 7): every club of a played league keeps its biggest win and defeat, record crowd, record fees paid and received, most goals in a season and its ten best by appearances and goals, opened with the world from its former players and kept at full time, at a signing and at the rollover. The career page tells the career by season (60 lines a season of his, 20 of the world's) and lists his players; the club page shows its records and legends read through the archive. RecordBookTest: a record win replaces the club's record and is a line of his career. runSim savesize 6: records 0.75 MB, flat after a season; the chronicle 0.01 MB. 2026-10-20: records by kind of competition (league, cup, continental, kept from the career's start), a legend's trophies in his seasons and whether the club made him, and the academy's best wherever they play now (RecordBookTest). Since 2026-10-25 every club cup, domestic and continental, has its all-time ten by appearances and goals too (the same appearance rule as the league's, counted per competition on the season, RecordBook.cupSeason), so nothing on this row is missing. Since 2026-10-23 every league and club cup, domestic and continental, has a roll of honour on its page (Winners): the champion and runner-up with the points, or the final with its score and shoot-out, the winning manager, and the most titles with shared ranks, opened from the database's last winner (Honours, RecordBookTest); since 2026-10-24 the national-team tournaments too, on the International screen (the winning nation, the finalist, the score and the national manager, an edition a line by the finals' year; a finished tournament stays listed between editions). Since 2026-10-23 each played league has its own all-time ten by appearances and by goals, folded at the rollover from each man's archived season and counted from the career's first season, on the league table's All-time toggle (RecordBookTest). Before 2026-10-25 these goals lists, the club's all-time goals list and its most league goals in a season counted every competition's goals (SeasonStats.goals); since then they read the league's alone (leagueGoals), so an older capture's figures can be higher. 2026-10-20: crises are in the chronicle: one at his club when it opens and how it ends (through it, or the board's warning, the captain giving up the armband, a voice asking to leave, the fans marching), and a rival of his division who sacks its manager in or soon after its board's crisis is the world's headline (Crises, CrisesTest).
In the code: RecordBook, Chronicle, HallOfFame, LegacyPanels
Former players' and staff's sonsDone
2026-10-19 (slice 18, docs/world-and-people.md decision 16): each remembered man has none to two sons; a former player's son plays one time in five, a staff man's one in fifteen. A son who plays comes through at 16 beside his father's club's intake, never one of its boys: the academy's own function on a stream and an id of his own, so the intake and the world are untouched outside him; an AI club signs him if it has room, the manager's club gets a letter. He leans toward his father's best attributes in the ceiling's shape, never its height. "Son of …" on his profile. ArchiveSonsTest; runSim youthdev 3: 8, 6 and 6 sons a season (Spain, England, France and Italy most), under one new boy in a hundred, and the feeder sides' development unchanged within a standard error. Not here: the catchment rule for a father whose club's academy is elsewhere, and a parent on the club's staff named with the post.
In the code: Archive.sonsAtIntake, familyLine
AI clubs that buy to get betterDone
An AI club buys to be better and sells to stay inside its means (2026-10-12 to 16, lanes S and M). It looks for a man it believes better than the weakest of its first choices, lists the surplus man that makes (an upgrade is a trade; nobody is bought into a squad of twenty-five), asks every purchase of its pot and its board's squad-cost line whole, pays what a seller's key man costs when it has money to spare and does not sell its own starters when it does; free agents are looked at for every position group each pass, and a club invented for a nation with no league signs only its own nation's free men. Over its line it lists men for sale, a listed man is not held at the wall of his own level, and a listed man nobody buys is let go by mutual consent at half the wages owed when its pot can pay and the year stays under its competition's limit (Ambition.kt, FinanceSystem.letsGo, LetGoTest). Measured: the richest and poorest quarter of a big top flight 1.15 → 2.14 points of best eleven apart over eight seasons and of a small league 0.69 → 1.30 (joint baseline, 2026-10-13); a club handed two years of its income spends 130m on fees in three seasons and its best eleven rises (potcheck); econ 8, 2026-10-16: 432 men let go in eight seasons, the clubs over a line at each close down in every season, administrations 7 → 1, the competitions' breaches unchanged. Limits, not missing halves: a club whose every wage is far over its income and whose contracts run for years (the stress case in potcheck: every wage ×1.6, every contract to 2030) stays over its line, since one man's pay-off is more than its cash or would breach its competition's rule, and a pay-off is not spread, by decision; the refusals of a listed man still turn on the buying club's level, which is his own; the upgrade shop takes its neediest group first.
In the code: Ambition.kt; club-economy §4.10, §5.9, §14, §21; runSim moneybuys, potcheck
Budgets that bindDone
Still missing: the rule's second and third sanctions (a registration embargo, exclusion from Europe) and limits for lower divisions; the owner's promise is a league finish only (no cup round, no Europe);
As of 2026-10-13 they bind, and the row is done. There are no budgets: there is one pot, what the club can commit over twelve months under its board's reserve, credit and squad-cost line, and every way of committing money asks it, for the manager and an AI club alike (ClubMeans.canPay; PotBindsTest, ClubMeansTest). Below the line is a ladder (LadderTest, the Insolvency row). The manager can ask the board for more against a promise with a date, and a broken one costs trust (MoneyAsksTest); a large signing needs the board's yes, answered in the deal's own dialog (BoardSignOffTest). Joint baseline, eight seasons: 46 to 51 of 336 played clubs over a line, where 148 were before anything bound; 54 of the 86 over a line two seasons before are back under. What is left is not this row's: the competition's sanctions are under Financial regulation, and the owner's promise is a league finish only. The slices as they landed: 2026-10-11, Lane M slice 3a: at that slice the pot was computed and shown and bound nothing. What the club can commit over twelve months (cash, plus income it can count on, minus what is committed, minus the board's reserve, plus its credit), the squad-cost gauge with the board's line and the league's, the four levers and why they are where they are, commitments and a month-by-month projection are on the Finances screen. Measured before it binds, econ 8: on day one 334 of 336 playable clubs are inside their pot but 144 are over the board's squad-cost line; after one season 82 are past their credit. M3c, same day: a rung is read off the tightest day of the year ahead; a club opens on its reserve plus its own first-season dip; a value is 4.8 years of the going wage at every ability (amortisation over wages in England 61% → 23% at season eight); squad cost divides by income plus average profit on sales. Clubs over the league's 70% at season eight 248 → 127 of 336. M3b-AI, 2026-10-12: AI clubs live under it. An AI club pays a fee out of its pot and a wage only under its board's squad-cost line; over a line it cannot buy and sells one man a month. Clubs past their credit after one season 56 → 9, at season eight 53 → 18; a club put over its line by hand is back under within two seasons. M4, 2026-10-12: the pot binds the manager on every path he commits money through (a bid, a contract, a renewal's rise, a loan, a coach, a stand, a scout, an academy boy); every deal dialog says what the deal commits, what is left, and squad cost before and after; the four stored budget fields are gone. The three independent reads' fixes are in (forty-one findings). M6, 2026-10-13: asking the board for more. Four asks on the Finances screen, each with its terms in front of the manager before he agrees — part of the reserve released until a date, an advance on next season's television money repaid at source with interest, the owner's money against a league finish (a gift if he makes it, a debt off his credit if he does not), and the board's yes to one large commitment. The board answers by how far it trusts him and by what is already outstanding, and a refusal says what would change it. MoneyAsksTest, PotBindsTest, ThirdReadTest. M7, 2026-10-13: the competition's squad-cost rule. A played top division holds its clubs to 70%; a club over it as the year closes is counted in breach and fined a tenth of the overspend, the manager's and an AI club alike (SquadCostRuleTest). The board's yes to a large signing is answered in the deal's own dialog and can be refused for the wage structure, the age and the term, or the price (BoardSignOffTest). Missing: the rule's second and third sanctions (a registration embargo, exclusion from Europe) and limits for lower divisions; the owner's promise is a league finish only (no cup round, no Europe);
In the code: docs/club-economy.md §4.6, §11
Where the money goesDone
Finance, matchday and prize bookings, season closure, accounts panel and country/tier instrument. Stadium and facility queues are independent for user and AI clubs; desktop and phone purchase flows are verified. Transfers and staff compensation book through the ledger. Feeder weekly bills and receipts belong to the parent treasury; AI scouting is charged in every career. Season projection includes recurring ledger movements and dated instalments. Transfer counts observe exact agreed fees. See docs/club-economy.md §9.12–9.13.
In the code: Ledger.kt
Sponsorship and local costsDone
Still missing: Czech lower-division commercial income reads 60-75% of income.
2026-10-19, four deal slots: the shirt, the kit partner and the sleeve divide what the one deal was, each on its own term and letter, and the stadium's name is new money sold only by choice; a betting shirt (not in England's top flight from 2026-27) and a relegation clause pay more, and the supporters hold a sold name and a betting shirt against the club while they run; the Finances page lists the deals (SponsorSystem, SponsorshipTest). Read on econ 8, both seeds: the first season's sponsorship unchanged, 1.5-4% more in the next three from clubs short of money (club-economy §24). 2026-10-11, Lane M slice 1. The commercial deal is a contract with a term: priced on the club's supporters and its league's television audience the day it is signed, renegotiated when it ends, with three offers for the manager (four years for less, two at the figure, one with a bonus for a finish). Upkeep, a facility level and a seat are priced in the league's own money. Measured, econ 8: sponsorship falls from 75% to 26% of an English top-flight club's income; a Czech third-tier club's upkeep from 113% of income to 16%; playable clubs in distress after eight seasons 43 → 3. Missing: Czech lower-division commercial income reads 60-75% of income.
In the code: docs/club-economy.md §4.8, §11
Wages and fees that follow the moneyDone
A wage curve per league, per club and dynamic, as the owner asked (2026-10-16). One world curve for ability, re-read each summer from what the clubs that employ it can pay; each league prices ability at its own money (the world's curve times the league's scale) and each club at its own scale inside its league (0.8–1.25), both re-read at every window, so promotion, relegation, TV deals and European runs move them; a man is asked at the market of the club asking him and not far below his present wage; a fee is the world's price (WagePrices.CLUB_MARKET, GoingRateTest). A bid is judged on the wage the man will ask, so the pot cannot accept a bid and then refuse him (BidWageTest). A new world opens every club three points under its board's line (0 of 336 over it on day one). Measured on one tree, econ 8, against the one world price: administrations in eight seasons 14 → 1 (the Czech second division 8 → 0, its eleven held); the richest quarter of a division pays a smaller share of its income than the poorest, by less (Czech second division 32 → 40% against 62%); every playable top flight 53–57% of income in wages in the first season; no renewal asks a rise its club cannot pay; Czechia's January share of its bids 16%, inside football's 13–23%, and Brno's listed men draw January bids from the manager's seat. A winter hold was built and refused on its reading (club-economy §19.4). For the calibration pass, not a missing half: wages over income in the big five drift to 42–50% by season eight against football's 50–70% (amortisation under a line that may not pass 70%, §15.3); the AI's bid check writes a fee off in one season, a margin the economy is calibrated on (§19.3); more Czech players leave for richer leagues (162 → 196 in eight seasons), which is the owner's, under World talent balance.
In the code: docs/club-economy.md §4.8, §15, §19
InsolvencyDone
2026-10-12, Lane M slice 5: one ladder for the manager's club and an AI club alike. Below zero a club pays interest every week (8% a year). Past the credit its board allows it is embargoed — nobody signed, no wage raised — and the board names a sale; after fourteen days the named man is listed at a price a buyer cannot be refused at; after eight weeks it is administration: nine points off, no credit until the season ends, an administrator's sale, and what is still owed written off when the season closes. The board reads its squad-cost line when each window has shut and a manager over it loses standing. A club that came down a division is told the line moved with it and is given that season. An AI club over a line still lists one man a month until it is back under. LadderTest; econ's ladder and why-over-the-board's-line lines. 2026-10-13: the administrator ends the dearest contracts with no severance (down to a side of fourteen) and mothballs facility levels until the year ahead no longer ends in the red, and only then is the debt written off; the club raises no wage and builds nothing until it has closed a season under its line. The manager may run any facility a level lower himself, on the Finances screen. LadderTest; econ's administrators line. 2026-10-14, the owner's choice: administration is judged by blame for the manager — forgiven if he inherited the trouble, an ultimatum to the close of next season if he caused it (shown on the Board screen), the sack for a second on his watch (AdministrationBlameTest). Not built: a wage run that cannot be paid as a second route into administration; the points deduction is not marked in the table beyond the points.
In the code: docs/club-economy.md §11
Club economies outside the Czech pyramidDone
City populations reach fans and youth in every playable country; major clubs draw support beyond their city; LIGHT operating income covers AI wages, upkeep and scouting; generated background clubs no longer open in distress (700/700 → 0/700); career and picker budgets preserve league wealth; European, promotion and cup-round bonuses use competition money terms; AI investment raises facilities without every club reaching the cap; generated grounds follow reputation and support follows capacity. The payroll that fell now holds (joint baseline of 2026-10-16, econ 8 on both seeds): a top-flight club's weekly bill over eight seasons moves −3% to +20% in eight of nine countries (England +3% and +11%, where it fell 564k → 327k on 2026-10-11), and every top flight pays 51–56% of its income in wages in the first season. The one that still falls is Czechia's (−12%, −14%), with its mean ability 9.70 → 8.94: talent, not money. Deviations left for the calibration pass are in club-economy §0.3 (matchday share 5–7% against 15–20%, a rich club's cash 120–156% of a year's income at season eight, net fees to other leagues).
In the code: docs/club-economy.md §0.3, §4.2, §4.5
Manager-controlled investmentDone
Corrected 2026-10-10: upgrades are already the manager's own purchase, not a request. What is missing is the tension roadmap 32 asks for — nothing competes with the spend because no budget binds — AI clubs now buy one affordable project a year by stature and manager preference. Checked on the landed tree, 2026-10-13: the tension exists. A stand, a facility level, a coach and a scout sent abroad are asked the same question as a transfer (ClubMeans.canPay, through FinanceSystem.canBuild), out of the one pot, so building competes with buying; PotBindsTest refuses a stand and a scout the pot does not hold. Asking the board for more is under Budgets that bind.
In the code: roadmap 32; docs/club-economy.md D9
Financial regulation (FFP)Done
A competition enforces a squad-cost rule in the played top divisions: wages, what the club paid players' agents and the year's write-off of fees over a season's income, read as the year closes, the manager's club and an AI club alike (SquadCostRule). 2026-10-14, the sanctions escalate with the breaches inside three seasons: every breach is fined a tenth of the overspend; a second also costs six points in the season that opens; a third costs the points and bars the club from registering anybody until its next window shuts, through the embargo's own gate. A league declares its own figure: UEFA's 70% in every played top division, England 85% (the Premier League's planned ratio); lower divisions none. The manager is told once a season when his club is over the limit with a breach on its record, and the Board screen carries the record and what the next breach would cost. SquadCostRuleTest, one test per sanction. econ 8: 27 breaches in eight seasons, 9 repeats, 9 point deductions, 3 registration restrictions (24 breaches and 9 repeats with a fine alone). 2026-10-16: the joint baseline counted 213 breaches in eight seasons (185 on world 42) with 95 point deductions, because a trusted board's line was the competition's own 70% and did not count the agents' fees the rule counts. The board's line now sits at least three points under the competition's limit (Pot.RULE_MARGIN; England's 85% and a league with no rule keep the band's line), and both sides count wages, the write-off and agents' fees, a deal's own agent's fee included (SquadCostRuleTest): 42 breaches (29), 19 point deductions (10), the clubs over their board's line on its old sum halved; with agents' fees counted more clubs read over the board's line at 30 June, on renewals' fees paid unasked (club-economy §20). Not built: exclusion from continental competition; a limit below a top division (England's salary-cost protocol is not this ratio). PSR accounting is still kept on every club. Each points deduction is shown with its reason under the league table, on the club's page and on the board screen (Deductions, club-economy §23).
In the code: roadmap 25; docs/club-economy.md §11.6, §16, §20
Press and mediaDone
No press conferences, by decision. Home carries one fading story line with a rare question (StoryTest), and a rival manager who talks the game up writes before a derby (ManagerTraitsTest). The News page: other clubs' stories, two a week nearest the manager first (StoriesTest; record signings 0, 2, 3, 6 of 21-36 stories a season once a club opens with a record fee, RecordBookTest), and the rumour mill — a club's real interest printed by invented outlets as its next step and answered by the market, with each paper's record, a line on the player page, a desk item and capped letters (RumoursTest). Since an AI deal takes days (2026-10-22), the reporter prints 13 rumours in 420 days and is right 12 times, the broadsheet 24 and right 39% of those answered, against 1 and none (runSim rumours 420).
In the code: dressing-room.md, slice 5; world-and-people.md §2, §8
Interface and platform88% · 7 done, 0 in progress, 1 not started
Design systemDone
Material 3 chrome, Football Manager density. Theme.kt and Design.kt are the whole contract.
In the code: docs/ui-design.md
Desktop, Android, web buildsDone
All four targets compile and run. Web serves the development bundle only (wasm-opt breaks the production bundle on Kotlin 2.1.x) and has no emoji/glyph font coverage, so icons must be vector. Saves (2026-10-20): desktop writes zstd and Android gzip, streamed and off the UI thread, read by their magic bytes; a season-end save (32 MB of JSON, ~7 MB on disk) loads in a 128 MB heap in ~0.5 s (runSim savemem load), where the old String path ran out of memory at 320 MB. The web still writes an uncompressed String to IndexedDB on the main thread. The plan for when the web resumes: the browser's own CompressionStream('gzip') (native, no bundle cost, ~5x on a save) and a binary IndexedDB record instead of a String; the loader already picks the codec from the magic bytes.
In the code: AGENTS.md
Saving and loading a careerDone
2026-10-20. A season-end save (32 MB of JSON, ~7 MB on disk) loads in a 128 MB heap in ~0.5 s, where the old String path ran out of memory at 320 MB (runSim savemem load). Never held as a String on desktop or Android; zstd on desktop, gzip on Android, read by magic bytes; written off the UI thread behind a “Saving…” chip (0.4-0.8 s at a season's end). A save that does not load says so and its slot is not written over until deleted (SaveStreamTest, AppStateTest). The web still writes an uncompressed String on its main thread; its plan is in the builds row.
In the code: SaveManager.kt, FileSaveStorage.kt, SaveArrays.kt; docs/player-development.md
Live match viewerDone
Watched matches, heat maps, shot maps, live line-up.
In the code: LiveMatch
Global and power searchDone
Across players, clubs, staff and competitions.
In the code: GlobalSearchScreen
LocalisationDone
English and Czech: keys, letters, competitions, countries and national sides read in the player's language, and Czech speaks to the manager as vy (LocalisationTest, including czechAddressesTheManagerAsVy; NationalNamesTest, ComposeHealthTest). 2026-10-28: every displayed decimal goes through one decimal(x, lang), a comma in Czech (“6,8”, “€1,2M”), and a decimal :core writes is typed (Inbox.decimal) (DecimalTest, ComposeHealthTest.everyDecimalGoesThroughDecimal).
In the code: ui-outstanding.md; ui-design.md, rule 12
Analysis hubDone
2026-10-20. Analysis (Competitions in the sidebar, More on a phone) reads the manager's division at three levels, each on what a fixture keeps: a match — both sides' chances against goals (xG, shots, on target, xG per shot, possession, field tilt, final-third entries), the stored shot map and the xG through the match, the goal minutes, every man's shots, xG, xA, key passes and touches, and the match report for heat maps, average positions and the pass network; the season — goals and xG for and against, xG by match, where the shots come from (the club's shots and those against it, and a zone table with the league's share and xG per shot beside the club's), match by match, and who takes and creates the chances; two teams of the division per match on the same rows, opening on the next opponent. A full-engine result keeps every shot (MatchResult.shots: minute, side, man, metres from the goal aimed at, xG, outcome) and, for the manager's own matches, completed passes by pair (passLinks); a result played on paper says so in words. The shots sum to the team's xG and shot count (SimV2ShotRecordTest); the golden digest did not move; runSim savesize: 2.7 KB of shots a full-engine match (23.5 shots) and 5.4 KB of pass network, so ~0.6 MB of shots a season of a 16-club division and 0.16 MB of his networks, cleared with the fixtures at the rollover. The opposition report (2026-10-20): on the match preview and the Compare tab, a side's shots for and against per match by depth and by its own flank, beside the league's, with the basis said in words (“from 3 matches”) and one sentence when an area stands 1.5 standard deviations out across the clubs, silence otherwise (OppositionDataTest). Not built: per-pass arrows (the network is aggregated by pair on purpose).
In the code: AnalysisScreen.kt, ShotPanels.kt, AnalysisData.kt, V2Story.shotRecord; roadmap 28
Web match performanceNot started
Parked (2026-08-05) until the desktop game is content-complete. A serial matchday in a browser is ~103 s; the Web Worker pool is built and the workers individually verified, but the Kotlin driver hangs undiagnosed, so it shipped off.
In the code: TASKS.md, engine-log
Data and modding83% · 2 done, 1 in progress, 0 not started
Engine tuning surfaceDone
Sixteen balance scales a .gmdb.json can set. A scale that cannot be shown to change a match fails the build.
In the code: docs/modding-tuning.md
Database importDone
Clubs, competitions, players and staff from an open database.
In the code: GameDatabase
Real player dataIn progress
Still missing: the attribute stage (model-rated, anchored), and no real squads in the shipped database.
Rosters fetched from Wikipedia squad templates (scripts/rosters.py; Premier League 561 players, Czech first division 498) and imported into a world (PlayerImport, PlayerImportTest). Missing: the attribute stage (model-rated, anchored), and no real squads in the shipped database.
In the code: player-data-pipeline.md

Recently landed