LightningFlik
A few experiments.

1. Tweaking Knap's FM 24 EF 424 IF HP V2 tactic one setting at a time.

Every single thing you can change makes this tactic worse, except disabling "Roll it out" and "Distribute quickly", which don't really change anything.

(Whether you can improve this tactic by changing groups of settings at a time remains unclear, but I've no plans to check that right now; it's plenty strong enough).

2. Does CA make a difference?

Baseline Aston Villa team:  300 runs: home 265 / draw 28 / away 7, avg 3.68-1.34
Current Ability set to 200: 300 runs: home 262 / draw 26 / away 12, avg 3.63-1.35
Current Ability set to 1:  300 runs: home 264 / draw 23 / away 13, avg 3.56-1.27

Basically no difference. (I had a theory for a while that it did, but it shows what I know).

3. Does age make a difference?

Baseline:      300 runs: home 265 / draw 28 / away 7, avg 3.68-1.34
Set ages to 15: 300 runs: home 270 / draw 22 / away 8, avg 3.72-1.34
Set ages to 37: 300 runs: home 257 / draw 25 / away 18, avg 3.54-1.33

A very minor bonus for a younger team and a slight penalty for older teams. Note that I haven't changed any attributes here. I've not even changed the players' dates of birth, just the single "Age" property (in years) attached to each player in the fixture object.

4. Does height?

Baseline:            300 runs: home 265 / draw 28 / away 7, avg 3.68-1.34
Set heights to 150cm: 300 runs: home 266 / draw 24 / away 10, avg 3.60-1.23
Set heights to 210cm: 300 runs: home 275 / draw 13 / away 12, avg 3.74-1.

A slight improvement for tall boys. Honestly though, I'm prepared to call variations from the age and height experiments within the margin of error. I might check whether the code reads these values later but, for now, I'm saying neither matter for performance.
Pretty sure these relationships have no effect in matches by the way.



I've found the data that represents them in memory: it tracks games and minutes played together (plus two other values I've not deciphered yet). But I can't see these in the fixture data, meaning they don't factor in to on-field performance.
I need to make a list of all the experiments I want to run with this.

- I can finally learn whether height makes a difference in game or whether it only influences the ceiling of your jumping reach (I've heard conflicting anecdotal evidence on this)
- Put a goalkeeper in a middling team with a non-overpowered tactic and test _every_ attribute on him to see what happens to his xGA vs goals conceded. (Testing every combination of every attribute isn't possible because of the eventual heat death of the universe but I've estimated it would take one machine ~26 hours to test every attribute 1-20).
- Test whether there's a rock-paper-scissors effect with tactics or whether some are universally strong.
- Test how powerful match plans are (right now I can't find match plan settings in the exported fixture blob so it's unclear to me how these instructions are fed in to the match engine).
- Test assistant manager attributes on his ability to manage a match.
- Best tactics/tweaks for underdogs, mid-table and strong teams etc.
- Does CA/PA affect a player's on-pitch performance independent of his attributes?
- How much does positional familiarity affect on-pitch performance?
- What's the best corner/free-kick tactic?
- Does footedness matter?
  - If single-footed players can both play on the same wing, does one do better than the other?
  - What's the penalty for playing players on their non-preferred CM/CB side? What's the bonus for playing them in the preferred one?
- Find where player bonds are stored in the fixture data and look at the impact on results for maximising these.
- What's the performance penalty for players who have low tactical familiarity?
  - Test all different aspects of tactical familiarity
- What is the performance impact of low(er) morale, sharpness, fatigue, and condition?
- what attributes matter and to what extent (a pipe dream but I live in hope)
- what impact does Match Focus (e.g. "Focus on Attacking Corners for the upcoming match";) actually have?
- Does venue matter?
- Does competition importance matter?
- Do relative team reputations matter?
- Does weather matter?
- Do referees have attributes or are they just a name and a face on top of a random number generator?
  - Also, the game generates a random number for referees before you advance to a match; what impact does this have? Do they catch more or less based on it? Are they more liberal with cards/penalties?
- Does squad harmony/manager support factor in to results or is this more like a baseline for players' happiness that they return to when no other factors are at play?
- What does training happiness actually mean?

And on and on and on.

Some of these can be tested experimentally and some I can probably gleam from the code itself now I know where the match engine is located.

EDIT: actually here's one I'm quite excited about. I had an idea way back when in this thread about comparing entire players rather than comparing players one attribute at a time.

Take a normal team and replace all strikers with Haaland clones. Nobody else is capable of playing striker. Simulate 300 games against a normal opponent. Then swap your clones out with Mbappe, Kane, Lewandowski and so on. If you really want to find who the best striker is (if you're still interested in weighting attributes) then you can find out.

It might be easier to hone in on important attributes (or, combinations thereof) if you're testing them in chunks.

EDIT 2: come to think of it, nobody ever needs to wonder "which of these players is best? which should I buy?" ever again. The simulator is right here. I might need to think about the UX to make the JSON blob easier to edit, or you could give a screenshot to an LLM and tell them to modify the file for you.
GeorgeFloydOverdosed said: The anticipation result is more reassuring. Here we see that -5 anticipation does make a big difference as expected. I don't know why there is a discrepancy between this and LightingFlik's attribute results posted earlier.

Good question. I ran my experiment using on tiniest database, EPL only, managing default Aston Villa, using Knap's 424 tactic, playing a friendly at the earliest opportunity against Bristol City. (The exact lineup I used probably doesn't matter, but suffice to say I let the assistant pick everything.)

You could recreate those conditions if you wanted to double check my result.

If you match my result then the discrepancy might come from a quirk of your meta-players' attributes. If you don't match my result then I can re-run my experiment later. Maybe I had incorrectly mapped the anticipation attribute in my test or maybe I was still simulating games incorrectly (for a time the player's manager would make no subs).

Also you could pastebin me your fixture JSON and I could re-run my experiment on that and see if I get the same result as you.
It'd be interesting to see what statistics leadership and dirtiness affect in game that produce different results. Presumably you concede more fouls/cards with higher dirtiness but what is leadership doing in game?
I've looked in to this. I'll write it up properly tomorrow because I'm either too sleepy to understand what I'm seeing or the match engine does _not_ work like I thought.

It looks like some attributes are stored mid-match as values 0 to [attribute value + 1] and the match focus you pick (set pieces, phase-of-play) refresh these values and pick the higher of them?

Other than that, the Match Focus module trains nothing but gives a bit of Team Cohesion and Tactical Familiarity. It's the mid-match bonuses that are the real boon though.
Yeah it supports Steam only right now. Reason is that the DLL calls about 40 functions in-game and they're all referred to by relative memory location. I don't know what kind of launcher or DRM Epic has but I assumed it would interfere with at least one of them.

Fortunately, I had anticipated this. Run this command on this latest app and send me the output:
Right, have at it: v1.0.0. Let me know how you get on and I'll try to iron out any bugs as they're reported. After a few days, I'll shout louder about this but you can be my guinea pigs for now.
The effects of training modules are stored in the game's external FMF files and can be read in a hex editor (I know because I modified the Team Bonding module to have the same impact as Match Practice, except it improves fitness, injury proneness, fatigue and all the other negative effects it's supposed to come with; and you can have as many as you want in a week).

I can have a look at what that specific one does when I get home.

(That said, the file probably says something like "tactical familiarity +3", and what that actually does is harder to track down.)
I almost released this last night but then I thought "I'll add one more feature first". If you ask for it, the app now exports all team and player stats, averaged across the games you ran. So you can play 200 games with a certain tactical/attribute tweak and look what it does to xGA or crosses attempted or headers won etc. across all players.

Then I looked at the output and noticed the human-controlled team never makes substitutions even in the event of red cards or injuries...

So I've got that to fix first.

I mention this because those kinds of stats should mean you don't have to guess how a certain change got you to fewer goals scored/conceded; the statistics ought to tell you.
This should be extremely conducive to experiments via LLM, if you're inclined. To test, I pointed free Copilot at the repo locally and told it to test what happens to the results if each attribute across the entire team is lowered by 5. I know it basically replicates what many other tactic testing experiment has already done but this only took two hours once it started. You could tell an LLM to get a lot more creative with it and it takes no effort on your part once it's begun.

Results
I've got the test harness working now. I'll be releasing the tool maybe this evening or tomorrow, once I've removed all the hacky debug stuff)



It works by exporting out of RAM the entire NEXT_FIXTURE object and then passing that as an argument in to the FM's GAME_MATCH__Run function (which it does via an injected DLL). And that works and you can run it multiple times with the same inputs but only changing the seed and it works great.

One thing I noticed about repeated edits of players and dumps of the next-fixture blob are that the game generates role ratings for each player across all 22 roles, except it uses the lower value of either itself or the player's adjusted CA (CA but modified slightly by Important Matches, Consistency, Determination  and Natural fitness (which are all worth about 0.2 CA per point). I saw Ollie Watkins' CA go from 144 to 149 (his real value is 146)).

These roles are calculated using the attributes the game highlights for you on player screens, so Pace only appears in something like four of them, not almost all like you'd actually expect.

Changing these derived values makes no impact on results; changing raw attributes does. I suspect these role ratings are used for AI player selection (because I drastically altered some and the players slipped out of the opponent's starting XI).

There's another value that changes whenever you modify your attributes and regenerate a fixture and I'm calling that the Leadership Value. It's a number from 1 to 4,406 and its weighted by these attributes: Leadership 184.92+-127.02, Teamwork 1.20+-0.68, Work Rate 1.05+-0.69, Consistency 0.60+-0.35, Important Matches 0.55+-0.33. I couldn't tell you what it does though. It looks like how you'd rate a captain's ability but I've not seen where it's used.

Also, positional familiarity has a cliff. At 12 and above, it contributes about 1-2 points to the role ratings described above (which, again, make no difference to actual performance). At 11 and below it collapses:

John McGinn's trquartista rating goes from 113 at familiarity 12 to 47 at 11 and 44 at 10. Below 10 he gets dropped out of the starting XI altogether.

Consistency, Determination, Important Matches and Natural Fitness only make a difference between 5 an 14. They shift the ratings by about 2-3 points at the extremes.

I've not tested yet the impact of these things on actual performance, just expected performance so far.
I can see a call to QueryPerformanceCounter which is the way of getting the length of time since the computer was last rebooted, so not system time exactly but something like that.

If you want to test it...

1. save before a fixture
2. attach your favourite debugger to FM 24 (Cheat Engine works well enough for this)
3. attach a hardware breakpoint to 0x143AB8350. (It may also look like fm.exe+0x3AB8350).
4. Proceed to the match (instant or the full thing, it's your call).
5. After you click "Go to match"/"Continue" on the following screen, the breakpoint will trigger and the game will hang.
6. Look at the value of the current registers. RDX is the one you're after.
7. Change the value of RDX + 8 to your chosen seed. For me, RDX always seems to be 0x0807F920 (but maybe it's different for you). My seed are the four bytes at 0x0807F928.
8. Play the game. If you're playing the full thing and not simming, ensure you do the exact same thing every time you test it (e.g. don't say/do anything to anybody).
9. Repeat this and you'll get the same results every time.

This would, for example, let you look at the impact of team talks, or shouts, or subs.

I set my seed to 42 and used the Instant Result button three times (reloading the save after each match). My 3-0 games were identical every time.

I then set my seed to 42 and played the full match, skipping all interactions. I won 2-1 both times. It's a surprise to me that the results were different; I've been told they use the same match engine but I guess the instant result implies a level of behind-the-scenes interaction with players/the match that fully neglecting them for 90 minutes misses.

Anyway, I repeated this again but this time I gave a team-talk before kick off. I lost 1-2 this time. EDIT: giving the exact same team talk on the same seed leads to the same outcome, so that is testable.

Also I'm very close on the test harness. And I will will be sharing it, unlike that other guy.

EDIT: something else to note, the match takes 3 seconds to simulate for me. My method is to call the in-game function (rather than exporting it and calling within my app) so there's nothing I can do about speeding it up. It seems like games just take 3 seconds at a minimum to complete.

GeorgeFloydOverdosed said: Are you saying that the match result is partially determined by the system time?

I've wondered if this is the case, from seeing Paradox do it with their saves
The Reddit post I highlighted a few days ago (the one where the guy got the game's match engine running independently of the game) has inspired me to get serious about disassembling the logic for FM 24. So far I've managed to find where the game's seed is supplied to the match engine, which means you can set a breakpoint before going to the match, set the seed to a fixed value (right now it comes from your machine's current date/time) and then get the same result every time.

I can share this if people think there's a use-case for it, but I'm going to be cracking on with my digging regardless.

EDIT: previously I said this only works for instant matches; it doesn't. It works for the full thing also.
It's not feature complete yet but here's a beta version of my FM 24 scouting tool for Windows: https://github.com/PhilipArmstead/Yet-another-Scouting-Tool/releases/tag/v24.0.139-beta

A config file will be created after you run it; see here for a primer on how to configure the weights (but I think it will be straightforward). The app hot reloads after modifying the config so it should make it easy to tweak scales and such.

This was built with speed and convenience in mind so there's no absurd wait time when starting the app. Just run it, load a save and get cracking. (Once you see the number of players cached in the bottom left corner, it's fully primed. Blink and you'll miss it).
GeorgeFloydOverdosed said: Interesting that the coach rating decreased with lower current rep. Wouldn't have thought that.

I've always suspected that the coach report is vibes-based, really. It makes sense to me that their current reputation (and possibly even form) influences it, as well as the relative strength of the league and team-mates. I don't for one minute think the game is telling me that a 4.5 star player is unquestionably better than a 4 star player.

GeorgeFloydOverdosed said: Club rep and manager rep doesn't matter, would have expected somewhat otherwise.

This surprised me too. Anecdotally I am convinced that my manager's reputation is factored in when talking to players one-on-one (my manager is always bullied in conversations with players when starting from the bottom; after a few seasons though I can reliably threaten to sell any player I want to keep them in line).

I'm going to do more investigation on this tonight; I think maybe the function I was looking at last night was actually determining how long the player wants his contract to be. It returns a number 1, 2 or 3 and I thought it was grading your bargaining position, but now I think it's how long the player wants.

I should be spending time finishing my scouting tool but it would actually be incredibly useful reverse engineering the mechanisms behind this so I can search the entire database for players who are interested in joining.
johnconnerson said: Have you (or anyone else) done research into how wage demand is calculated? I'm curious if there is a way to estimate how much a player "should" make (based on age, CA, reputation, or whatever else affects it). This would be helpful for quickly understanding whether or not I can afford a player/if a player is undervalued by the market.

I'm intrigued enough by the question to look.

Here's a very quick test. There are three metrics for reputation in the game:

- Home
- Current
- World

Other websites can probably explain (or guess) what they do but I'm just here to see if they affect contract negotiations. (How could they not?) I'll play with the values (and use my unchanged player as a baseline) and record them below.

| Home rep | Current rep | World rep | Salary demand
| 3,115        | 4,372      | 1,1911    | Important player, £53k p/a
| 10,000      | 4,372      | 1,1911    | Important player, £55k p/a (plus small bonus increases)
| 0                | 4,372      | 1,1911    | Same as baseline
| 3,115        | 10,000    | 1,1911    | Wants to talk but thinks I can't afford him (1)
| 3,115        | 0              | 1,1911    | Important player, £36k p/a (also his bonus demands have halved and the coach's estimation of his ability has decreased)
| 3,115        | 4,372      | 10,1000  | Important player, £86k p/a (plus large bonus increases)
| 3,115        | 4,372      | 0            | Important player, £51.5k p/a (plus small bonus decreases)

(1) This was true even after I adjusted my budget sliders and tried again and after I adjusted the club's reputation to be 10,000

N.b. after changing reputations I advance a few in-game hours so the system registers it

Other notes
1. I saw no change after setting my wage budget as low as it would go (£428k p/a) and as high as it would go (£1.2m p/a) even for the 10,000 world rep experiment. (But if someone on Reddit said it did then I'm not going to dispute that.)
2. World reputation is the only thing that changed the player's reputation on his Personal Information page. It was 5 grey stars ("Minimal";) at 0 and 5 gold stars ("Exceptional";) at 10,000.
3. It makes sense that Current Reputation would have such a big impact on demands + your star rating if it's meant to be the sense of how hot you are as a player.
4. I also tested the baseline player when the club had a reputation of 0 and 10,000.

0: Important player, £58k p/a
2,920 (baseline): Important player, £53k p/a
3,115 (player's home rep): Important player, £54k p/a
10,000: Important player, £64k p/a

5. I also tried setting the CA/PA of the player to various values:

| CA  | PA  | Demands
| 67  | 120 | £53k p/a (baseline)
| 67  | 200 | Unchanged
| 67  | 67  | Unchanged
| 120 | 120 | Not willing to discuss!
| 1  | 200 | Unchanged

6. I changed the manager's Home, Current and World reputations to 10,000 and it made no difference (although it made people like me more).

Here's a dump of screenshots showing (most) of the above. I know a lot of this might not be new information but it's a start.

Baseline


CA 120/120


Club rep 0


Club rep 10,000


Player current rep 0


Player current rep 10,000


Player home rep 0


Player home rep 10,000


Player world rep 10,000


EDIT: From reading the game's code I can tell you that the reputation of the league you're going to be playing in next season is a factor (or the current league, if next season's isn't decided yet).
It's a minimal impact though, seemingly. If I tell Isaac that we're going to the Premier League next season instead of League Two, he asks for a tiny bit more money and his coach summary rating drops an entire star.



From the looks of the code, it seems like a few things are summed (reputations) and then scored (given a grade?) That is, I don't think changes are linear; I think you get bucketed in to discrete grades, which represent how strong your bargaining position is. After enough reputation points gained/lost, you might find yourself in the next bucket.

This has taken _far_ longer than I anticipated and I'm knackered so I might look at the actual calculations tomorrow (no promises though).

EDIT again: I can't help myself.

If you have a "Front End" Sugar Daddy, the player's demands increase. (+15 to the score it keeps track of).
GeorgeFloydOverdosed said: How did you get it to display the phrases as single lines like that? Maybe its cause I didn't let it fully finish processing I guess.
Maybe Analysis -> One Shot -> ASCII Strings?

I know I did that at the start. Then I use Window -> Defined Strings to search.
I just can't find where that code above is executed. I've decided to search for "weig" in hopes that I can find somewhere else in the code where that logic is performed. In doing so, I've found the nuttiest string references in the binary. What the actual hell is in this game?





EDIT: one more. I actually googled the strings in this one and found a medical website with the exact same strings. I'd love to talk to one of the people who worked on this game and ask exactly what directory they've accidentally included in their build pipeline on this project.

Medical website