Changelog
What's changed in each version. Newest first.
v1.10.0 — Match commentary now shows which team a goal or chance belongs to
- Every commentary line (goals, cards, injuries, substitutions) is now tagged with the team it belongs to and shown with that club's colour as a left-hand stripe plus the club name inline, on both the live match screen and the full match report — previously a line like "Elijah Nakamura splits the defense and Finn Johnson finishes it off!" gave no clue which side had scored.
- Old matches played before this change still display correctly — their commentary was saved without team information, so those lines simply show with no colour stripe instead of breaking.
v1.9.1 — Fixed: v1.9.0's free agent fix only helped brand new saves, not ones already running
- The previous fix only seeded free agents when a save is first created, so anyone already partway through a save (or between season boundaries, when the pool only refills once a year) still saw an empty Free Agents page — confirmed directly. Added a small weekly top-up instead: any save's free agent pool that drops below 8 players gets released a handful more (never goalkeepers, never from a club that's already thin), checked every single week regardless of when the save started or how long it's been running. Self-limiting either way, so it tops up when genuinely needed and leaves a healthy pool alone.
v1.9.0 — Fixed: no free agents or transfer-listed players at all in week 1
- Real bug fix: a brand new save started with a genuinely empty Transfer List and Free Agent pool — both only ever get populated by ongoing processes (AI clubs listing surplus players week to week, contracts expiring once a season), so week 1 had nothing to browse on either page. New saves now seed a modest, realistic starting pool of each (never touching goalkeepers, so no club starts a save short at the back). Also raised how often AI clubs list a player week to week for a healthier ongoing supply, not just a one-time fix for week 1.
- Added 'Hide players unlikely to join' to the Transfers browse list and the Transfer List page — filters out anyone who'd reject literally any fee your club could afford, instead of finding that out only after submitting (and waiting on) a doomed offer.
- Checked the underlying logic this relies on directly: a happy Premier-League-level star in their prime will not join a bottom-tier club for any fee that club could realistically raise — confirmed with real numbers (required fee ~£108M+ against a £15M budget, correctly rejected). An unhappy, transfer-listed, or veteran (34+) player is a genuinely easier sell and can move to a smaller club if that club can actually afford them — confirmed a mid-table club affording an unhappy 35-year-old star where the same club couldn't touch their prime-age, contented self — but even then, a truly small club's budget still won't stretch far enough, so it stays rare rather than becoming common.
v1.8.0 — Fixed unrealistic new-save squads: crazy position splits, and no home-nation bias
- Real bug fix: a freshly generated 16-player squad picked each player's position fully independently, which had enough natural variance to regularly produce things like 4 goalkeepers and barely any real defenders — confirmed directly as a repeatable problem, not one unlucky save. Every new squad now targets a realistic broad split (2 goalkeepers, 6 defenders, 5 midfielders, 3 forwards) every time, while still varying naturally which specific sub-position (e.g. centre-back vs full-back) within each.
- Real bug fix: nationality was drawn from the exact same global pool for every club in the game, regardless of which country's league it played in — an English League Two club had no more chance of fielding English players than a Bundesliga side did. Clubs now skew toward their own country's players, more heavily the lower the division (~90% British in League Two, ~55%+ in the Premier League and the other top flights) — confirmed directly with a 500-player sample at each level.
v1.7.2 — Key Attributes now shows 5 per player instead of 3
- Every 'Key Attributes' list (Squad, Free Agents, Transfer List, and Scouting reports) now shows 5 position-relevant attributes instead of 3 — e.g. a keeper adds Positioning and 1v1s, a centre-back adds Positioning and Strength, a striker adds Pace and Technique. Same one place (KEY_DISPLAY_ATTRS) drives all of them, so this applies everywhere the feature is shown, not just one page.
v1.7.1 — Fixed: intermittent 'Internal Server Error' from a database lock
- Real bug fix: pages could occasionally fail outright with a database-locked error — made noticeably more likely by v1.3.0's online-status tracking, which added a small database write to nearly every single page load. SQLite was running in its default mode, where any write briefly locks the whole database file and a second request arriving at the same moment fails immediately instead of just waiting. Switched to WAL mode (readers and a writer can proceed together) and gave writes a real timeout to wait out a brief lock instead of failing outright — confirmed directly this resolves it. The online-status write itself is now also wrapped so that even a genuine database hiccup there can never fail the actual page around it.
v1.7.0 — Pick your lineup right from the Squad page
- The Squad page now shows your current formation and style up top, and every player row gets a Slot dropdown — GK through every outfield slot in your formation, down to Sub 1-7, or Reserve. Picking one moves that player there immediately (bumping them out of wherever they were before, same as the Tactics page already does), so you can set your team without leaving the Squad view. Formation/style changes, captains, set-piece takers, and per-slot instructions still live on the Tactics page, linked right above the squad table.
v1.6.0 — Fixed: league position didn't actually decide European qualification (or promotion/relegation)
- Real bug fix, and a significant one: at the end of a season, the database's season boundary was being advanced to the NEW season before both promotion/relegation and European qualification were computed — both rely on reading the league table for the season that just finished, and with the boundary already moved, every match from that season fell outside the filter. The result was a standings table where everyone showed 0 points, silently falling back to whatever order clubs happened to be stored in — so final league position frequently had no real bearing on who got promoted/relegated or which European competition (if any) a club actually qualified for. Confirmed directly and fixed by computing both before the season boundary advances, not after.
- Season/week display fixed: the dashboard and Saves screen were showing a single ever-increasing week count (week 235, and climbing forever) instead of a real Season/Week pairing. Now shows Season X, Week Y, where Week resets to 1 at the start of each new season.
- Squad page's Attributes filter has 'Key Attributes' back as an option (the position-specific 3-attribute view) — and it's the default again.
- Fixed full-backs (DL/DR) showing Crossing as a 'key' attribute despite being pure defenders — swapped for Marking, alongside their existing Tackling and Pace. Wing-backs (WBL/WBR) keep Crossing, since delivering from the flank genuinely is their attacking role in a back-3/5 system.
- Free Agents and Transfer List pages now have a Position filter and a 'Show Key Attributes' checkbox, matching the filter pattern the Squad and main Transfers pages already use.
v1.5.0 — Fatigue is real now: it affects selection and performance, plus a Recent Matches list
- Added match fitness/fatigue, tracked per player (0 fresh - 100 exhausted): builds up from actually playing (more for a full start than coming off the bench, less for a player with high Natural Fitness), and recovers a bit every week whether they played or not. A tired player now plays below their normal level in a match (up to a 20% hit to pace/acceleration/agility/stamina specifically — fatigue is physical, not mental).
- Auto-filled lineup and bench slots (which is how every AI club, and any empty slot on your own team, actually gets picked) now weigh both fatigue and recent match form, not just raw attributes — a tired or out-of-form player rates lower for a starting slot than a similarly-able teammate who's fresh and in form. A manager's own explicit slot assignment is never second-guessed either way.
- Added a 'Tired' tag on the squad page for anyone at high fatigue, a Match Fitness % on the player page, and a real Recent Matches list there too (last 10 games: opponent, score, minutes, goals/assists, and that match's actual rating) — previously the player page only ever showed career averages, with nowhere to see individual match-by-match form.
v1.4.0 — Morale now actually affects matches, and AI clubs pick real tactics
- Morale used to be tracked for every player and drive transfer requests and contract odds, but a miserable squad played an actual match exactly as well as a delighted one — nothing in the match engine ever read it. It now scales a player's on-ball/decision attributes (not raw physicals like pace) up to 10% for a genuinely happy player, down to 15% for a miserable one, with a 'Content' player around the middle of the scale seeing no change either way.
- AI clubs now actually think about their own tactics instead of sitting frozen on the 4-4-2/Balanced default every club starts with, forever. Each AI club occasionally reviews its setup: formation is picked by whichever of the 5 shapes its actual squad fits best (reusing the same per-slot rating the auto-fill lineup already uses), and style leans attacking or defensive based on whether the squad's own attacking or defensive attributes are stronger, nudged further by the club's season ambition (title push = bolder, relegation fight = more cautious). Never touches a human-managed club.
v1.3.0 — See when your co-op partner is actually online
- The Saves screen now shows 🟢 '<name> online' next to a save when the other manager on it has actually been active in the app in the last couple of minutes, instead of no way to tell whether they're currently playing at all.
v1.2.2 — Fixed: Random Club only ever picked within whichever league was already selected
- Real bug fix: the 🎲 Random Club button only randomized among the clubs in the currently-selected league, not across the whole pyramid — so it looked like it was just shuffling within one division rather than genuinely picking from anywhere. It now picks a random league first, then a random club within it.
v1.2.1 — Fixed spacing on the new-save club picker, and rescaled reputation across the pyramid
- Fixed the Random Club button overlapping the ‘strongest to weakest’ hint text right above it on the new-save screen.
- Rescaled club reputation across the English pyramid so it actually reads as realistic top-to-bottom: the Championship's very best side now lands level with a Premier League mid-table club (50, same band as Brentford/Forest) instead of above it — it was previously stronger on paper than half the Premier League. League One and League Two rescaled the same way beneath it, each division's ceiling landing around the tier above's lower-mid table rather than overlapping upward into it.
v1.2.0 — Random club picker and reputation shown on the new-save club list
- Starting a new save now shows each club's reputation right in the club list, sorted strongest to weakest, instead of a plain alphabetical list with no sense of scale.
- Added a 🎲 Random Club button next to club selection (both for yourself and, in co-op, your partner) — picks a random club from whichever league is currently selected, for anyone who'd rather not pick by hand.
- Versioning switched to a strictly sequential vMAJOR.MINOR.PATCH counter — MINOR and PATCH are single digits 0-9 that roll over into the next segment up (so 1.9.9 becomes 2.0.0), but MAJOR itself isn't capped at 9 (9.9.9 becomes 10.0.0, not something else).
v1.1.0 — League Two's bottom clubs now actually get relegated, not just left in place
- Previously the bottom of League Two was a dead end — those clubs just stayed put every season, since there's no lower division modeled. Now they're relegated out of the Football League for real, replaced by a club drawn from a dormant non-league pool for your save (the strongest one available comes up first, same as a real promoted side) — generating a brand new one with a full squad if that pool's ever empty. Relegated clubs aren't deleted; they sit in the pool and can be promoted straight back up later.
- Your own club is never sent down this way, regardless of where you finish — there's no football modeled below League Two, so the board backs you for another season instead of leaving you with nothing to actually manage.
v1.0.0 — Real contracts, real transfer deals, a squad-page fix, and a genuine cup-name bug fixed
- Real bug fix: an FA Cup Final (or any Premier League club's cup fixture) could report itself under another league's cup name entirely — e.g. ‘Copa del Rey’ for an all-English final — in a save running more than one domestic league. A top-flight club's cup lookup was keying off its domestic_league field directly instead of the same division-based key every other part of the game already uses for this; lower-division clubs were never affected, which is why an earlier, related fix to this exact problem missed this specific case.
- New Contracts page (sidebar link, filter for Players or Staff): renew a player's deal with real added clauses — appearance fee, goal bonus, assist bonus, a clean sheet bonus for keepers/defenders, and a release clause (a fixed fee that guarantees a sale to any bidder, no negotiation). Bonuses are paid for real out of your transfer budget the moment they're actually earned in a match, not cosmetic numbers. Moved off the player page entirely, which now links here instead.
- Transfer offers can now include a makeweight player from your own squad (a real swap deal, not cash-only) and a buy-back clause offered to the selling club — a fixed fee and a window of seasons in which they can force a re-signing later. Both are weighed for real by AI sellers judging an offer, not just recorded. Active buy-back clauses you hold show on the Transfers page with a one-click trigger.
- Squad page now defaults to GK, then Defenders, then Midfielders, then Attackers (real shirt-number order) instead of an alphabetical read of the position code that used to put e.g. AM/C ahead of D/C — click the Pos header again to reverse it.
- The Transfers browse list can now be searched by position and by a specific attribute's range (pick an attribute, set a min/max), and its attribute display now matches the squad page's own Goalkeeping/Attacking/Defending/Physical/Mental filter instead of a fixed three-attribute summary.
v40 — Fixed: playing very defensively made you concede MORE goals, not fewer
- Real bug fix: a defending team's own tactical style never actually applied to any duel in the match engine — the variable holding it was computed every possession and then never read. Only the attacking side's style mattered. Practical effect: Very Defensive gave up meaningfully more of the ball (by design) for genuinely zero defensive benefit in return, making it actively worse than Balanced in every matchup tested, never a legitimate 'park the bus' option the way it should be. Now wired in on both sides of the ball, so a defensive setup actually makes you harder to break down, not just more passive.
- Also rebalanced how much a style shifts possession share (Very Defensive/Very Attacking were swinging it by a full 10 percentage points, stacking on top of the attack/defense duel-bias effect above and compounding into a near-unbeatable Very Attacking and a near-unplayable Very Defensive). Cut roughly in half — style still matters, but a low block can now realistically grind out a stalemate against a stronger side instead of just getting overrun regardless.
- Checked this wasn't hiding a formation-level version of the same problem (the classic old flaw where the strongest tactic fielded no wingers at all): it wasn't — every formation in the game includes width, wide positions are weighted at least as heavily as central ones in attacking involvement, and simulated testing confirms modern, wide-attacking shapes (4-3-3, 4-4-2) already outperform narrow ones (5-3-2), not the other way round.
v39 — AI clubs now scout visibly (WNT tag), plus a shortlist compare tool
- AI clubs now build their own scouting shortlist week to week, the same table the Scouting page uses — visible on your squad page as a 'WNT' tag next to any of your players an AI club is actively watching, a real early-warning sign before a bid shows up rather than one appearing out of nowhere. Yes — AI clubs do also scout and bid on players you haven't transfer-listed, this just makes that visible instead of invisible.
- AI transfer offers now prioritize a club's own scouted shortlist first (only needs a small edge to trigger a bid), then transfer-listed players league-wide, then a general upgrade hunt at their weakest position as before. A successful bid clears that player off the buyer's shortlist — interest became an actual move, not something still just being watched.
- Added Compare on the Shortlist page: tick 2-4 shortlisted players and see every attribute side by side, with the best value in each row highlighted.
v38 — Fixed: transfer-listing a player did nothing to get AI clubs to actually bid
- Real bug fix: AI clubs' transfer-hunting logic never looked at whether a player was transfer-listed at all — a listed player was evaluated exactly like anyone else in the league, so listing someone had no actual effect on whether AI clubs would bid. AI clubs now check every transfer-listed player first, against any position of need (not just their single weakest spot), need only a modest edge over the incumbent rather than a big upgrade, and bid somewhat below full value — a willing seller doesn't command full asking price.
- AI clubs also now attempt something in the transfer market a bit more often each week during a transfer window (up from a 12% to a 20% chance per club) — still most clubs sit still most weeks, but more real activity overall.
v37 — New Managers page, and your name shown instead of your login email
- The sidebar and header now show your manager name (once you've filled it in) instead of your login email.
- Added a Managers page (new sidebar link) with a career record for every human manager in the save: current club and formation, reputation, win-draw-loss and goals for/against at your current job, biggest win and biggest loss, trophies won, and your best-ever league finish. Trophies and season finishes are tracked from this release onward — there's no way to reconstruct what happened in a save before it existed.
- Changing clubs or taking an international job no longer starts your career record over — trophies and best league finish carry across every job you've held in a save.
v36 — Manager profile: your name, age, and nationality — as the manager, not a player
- New saves now ask for your first name, last name, age, and nationality when you create the save — this is you, the manager, not a generated player. Foundation for upcoming manager-identity features, nothing changes in-game yet.
- Already-running saves pick this up automatically: next time you open one, you'll get a one-time 'Complete Your Manager Profile' prompt before the dashboard loads. Answer once and it's done — carries over automatically if you later change clubs or take an international job.
v35 — Squad page: every column sortable, attributes default to Mental, contract/transfer moved to Details
- Every squad table column — Pos, Nat, Morale, Status, not just Name and Age — can now be sorted alphabetically or numerically. Every sortable header shows a small ↕ icon up front so it's clear before you click that it's sortable, not just after.
- Removed the old ‘Key Attributes’ column; the Attributes filter now defaults to Mental and always shows a full column per attribute in the chosen category (Goalkeeping/Attacking/Defending/Physical/Mental). Hover an abbreviated column header (e.g. DEC, WR, LDR) to see its full name.
- Contract renewal and the transfer-list toggle are no longer inline on the squad table — they've moved to the Contract and Transfer tabs on a player's Details page, which now also pre-fills a suggested weekly wage.
- Static assets (style.css) are now served with a cache-busting version tag, so a CSS change shows up immediately instead of possibly sitting behind a stale Cloudflare/browser cache after a deploy.
v34 — Squad page: sorting and a tidier filter bar
- Click any column header to sort — Name (A-Z), Age (youngest first), or any attribute column when a category filter is active (highest first). Click again to reverse the order.
- Tidied up the squad page: the Position/Attributes filters now sit in a proper toolbar with a Clear Filters link, and attribute/age values are right-aligned for easier scanning down a column.
v33 — Fixed players stuck on international duty, and a clearer label for it
- Fixed players still showing unavailable after the v32 timing fix: that fix stopped NEW call-ups from marking a player unavailable too early, but didn't retroactively release players already stuck by the old bug. This release does — automatically, the next time the server restarts, no action needed.
- The squad page and Loans page now show an orange ‘INT’ tag for players away on international duty, distinct from the cyan ‘Loan’ tag for a real club loan — previously both looked identical. Both now also show the week they're back.
v32 — Two real bugs fixed: reputation display, international call-ups
- Fixed club and manager reputation occasionally showing as a long decimal (e.g. ‘45.30000000000001’) wide enough to overflow the dashboard — three places that adjusted reputation by a fraction never rounded the result back to a whole number. Existing saves are cleaned up automatically on first load after this update.
- Fixed a real gameplay bug where international call-ups could mark a player unavailable (‘out on loan’ to their national team) many weeks or even a full season before the actual fixture, making it look like they’d never return. Call-ups now only take effect the week they actually happen.
v31 — Squad page filtering
- Added a Position filter to the squad page — show just your centre-backs, forwards, etc. Only lists positions someone in the squad actually plays.
- Added an Attributes filter to switch the squad table from the default Key Attributes column to a full breakdown of Goalkeeping, Attacking, Defending, Physical, or Mental attributes — one column per attribute, for comparing players side by side.
- Both filters work together and combine with the URL, so a filtered view can be bookmarked or shared.
v30 — Tactics pitch polish
- Player positions on the tactics pitch are now spaced out dynamically based on the formation in play, instead of every position having a fixed height regardless of formation — fixes tight clusters of players with large empty gaps between them.
- Stay Back / Balanced / Get Forward are now a clearer blue / neutral grey / orange-red on the pitch, replacing two shades of blue that were hard to tell apart.
- Added this changelog.
v29 — Cup name and cup bonus fixes
- Fixed the dashboard and cup page showing the wrong domestic cup's name for clubs outside the English pyramid (e.g. a League Two club's nav showing “Coupe de France”) — traced to a single shared field that only ever held one cup's name at a time, now resolved per club instead.
- Fixed the cup bracket page itself mixing fixtures from all 5 domestic cups together rather than showing just the viewer's own competition.
- Fixed a related gameplay bug: the board-confidence bonus for winning a domestic cup was only ever being awarded for the English pyramid's cup, never for the other 4 countries' cup winners.
v28 — Real login, PIN-protected saves, login alerts
- Replaced the old open username-only login with real email + password accounts, properly hashed — no more silent account creation on any typed-in name.
- Accounts are set up via a command-line script on the server (manage_users.py), not a public signup page.
- Every save now has its own PIN; all saves are visible to both accounts, opening a specific one requires its PIN.
- Added a drag-to-reposition tactics pitch — dragging a player forward or back on the pitch sets their existing Attacking Freedom setting, as an alternative to the dropdown.
- Added login tracking (visible in-app at /login_history) and optional email alerts on every login attempt, with repeated failures throttled so a guessed password doesn't flood the inbox.
v27 — Attribute system overhaul
- Training now grows a player's real 41 detailed attributes (the ones the match engine actually reads) rather than a separate summary score that the match engine never consulted — previously, training was cosmetic and had no effect on how a player actually performed in a match.
- Man-marking, corner takers, penalty takers, and wrong-footed wingers now genuinely affect match outcomes — each of these existed as a setting before but had no real effect on the simulation.
- Dirtiness and Versatility (cards, and playing out of position) wired into the match engine — 39 of the 41 detailed attributes are now actually used somewhere.
- The 5-number summary score is no longer shown anywhere in the interface — squad lists, scouting reports, and player pages all show the real detailed attributes instead.
- Goalkeeper and outfield trainable-attribute lists reviewed and corrected so every position can train what it's actually judged on in a match.
v26 — Unified world, manager careers
- Merged the separate pyramid and European-competition game modes into one shared world — every save now includes the full English pyramid plus La Liga, Bundesliga, Serie A and Ligue 1 together, with European competitions running automatically. No more choosing between them at creation.
- Added a reputation gate on job applications, so a manager can't apply for a job far above their proven career record.
- Added unsolicited approaches from bigger clubs for managers who are genuinely overperforming.
v25 and earlier — Original build through the CM01/02 redesign
- The bulk of the game as it exists today was built across many earlier versions: the core match engine, real clubs and players, scouting, tactics, transfer market, injuries and suspensions, live match viewing, domestic cups, the 4-division English pyramid, club finances and stadiums, international football (World Cup and continental championships), player morale and manager job security, backroom staff, loans, the Bosman rule, and mobile-friendly layouts.
- The full CM01/02-style visual redesign, match statistics tracking, the transfer list, and more realistic AI transfer behaviour all landed by v25.
- This entry is deliberately a single summary rather than broken out version by version — the detailed record for exactly what changed in each specific early version number doesn't exist, so itemizing them individually here would mean guessing rather than reporting.