Summary of recent findings for optimal play in FM24 & FM26

by GeorgeFloydOverdosed, Oct 31, 2025

GerardFM24 said: Interesting topic that I will keep following.
Is there also such research about staff and staffroles,
Like what are the most important roles and which attribute are the best.

EBFM has important findings about various staff. This video shows the impact of coach attributes, which I would surmise as somewhat impactful but probably a fair bit less important than you would think.

From memory he also found that you only need 1 physio to get the full benefit, and it doesn't matter if this 1 physio has '1' physiotherapy. Hopefully I'm recalling that correctly. I think the idea is that a physio's attributes only estimate length of injury better, they can't actually reduce injury rate/length aside from their presence as a staff member.

For newgen impact, staff are mostly irrelevant. The only effect is that HoYD will influence 1-2 players coming in each intake with their personality. This possibly extends to other 'youth coaches' who supposedly have half this effect.

IMO an aspect that is emerging as important is stuff to do with tactical & team selection, because these appear to significantly influence winning - even if it's just selecting between similar players you have in your squad. So tactical knowledge, judging player ability, motivating for whoever you set the relevant responsibility for. One thing this would mean in practice is getting an assistant manager who is a great manager, rather than great coach.

0

LightningFlik said: I want to share something of potential interest.

I've been disassembling the "fm.exe" application for FM 24, which means I've turned the machine code back in to something resembling C so that I can look at it. I'm doing this because I want to find where shortlists/search results are stored in RAM so I can read them in my scouting tool but I might have found something else.

There's a function beginning at memory address 0x0144b40180 (at least in my Windows, Steam copy of FM 24.4.2+2081827), which appears to be grouping together player attributes and scoring them. I'll share the approximated C code here (feel free to ask Chat GPT what it means) as well as what I think it's doing. If you do feed this in to an LLM to decipher, give it this file too. That will map the offset codes (e.g. 0x23d, Pace) to the player's actual attributes.

From what I can see, this code is reading player attributes in groups, multiplying them together and creating a score for each group. It then returns the highest scoring group and the group itself.

For example, starting on line 65 of the code snippet:

Spoiler sVar1 = (short)((uint)(*(char *)(param_1 + 0x239) * 0x6667 + 0xccce) >> 0x10);
  uVar8 = (sVar1 >> 1) - (sVar1 >> 0xf);
  if ((short)uVar8 < 2) {
    uVar8 = 1;
  }
  uVar6 = (uint)uVar8;
  if (0x13 < uVar6) {
    uVar6 = 0x14;
  }
  sVar1 = (short)((uint)(*(char *)(param_1 + 0x23d) * 0x6667 + 0xccce) >> 0x10);
  uVar8 = (sVar1 >> 1) - (sVar1 >> 0xf);
  if ((short)uVar8 < 2) {
    uVar8 = 1;
  }
  uVar11 = 0x14;
  if (uVar8 < 0x14) {
    uVar11 = (uint)uVar8;
  }
  if ((int)(short)uVar2 < (int)((uVar11 + uVar6) * 5)) {
    uVar2 = (short)(uVar11 + uVar6) * 5;
    *param_2 = uVar2;
    uVar3 = CONCAT71((int7)((ulonglong)uVar3 >> 8),9);
  }


- The lines beginning sVar1 = (short)((uint)(*(char *) read a different attribute from the Player entity (Acceleration and Pace in this example (0x239 and 0x23d)).
- The lines uVar8 = (sVar1 >> 1) - (sVar1 >> 0xf); divide the attribute by 2, rounding down.
- The next two if conditions ensure the number is between 1-20 inclusive.
- The final if condition sums uVar11 (which is Pace / 2) and uVar6 (which is Acceleration / 2) and then multiplies the value by 5. If that result is > uVar2 (which is the highest rating it has seen so far), then it sets that to be the highest rating (*param_2 = uVar2) and sets the return value of the function to be the category ID (9 in this case).

Now here's the exciting part: the attributes it groups together and how it scores them.

Group 1: Set pieces

((Corners + Free Kicks + Penalties + Long Throws) * 10) / 4

Group 2: Attacking technique

(Crossing + Finishing + Long Shots + Passing + Technique) * 2

Group 3: Attacking intelligence

((Anticipation + Vision + Decisions + Positioning) * 10) / 4

(Yes, positioning.)

Group 4: Leadership

((Bravery + Work Rate + Teamwork) * 10) / 3

Group 5: Defensive intelligence

((Tackling + Marking + Concentration + Positioning) * 10) / 4

Group 6: Technical control

(Flair + Dribbling + First Touch + Composure + Balance) * 2

Group 7: Aerial Ability

(Heading + Jumping Reach) * 5

Group 8: Physique

((Strength + Natural Fitness + Stamina + Agility) * 10) / 4

Group 9: Speed

(Acceleration + Pace) * 5

Now I'm not saying that the game uses the same aggregation/scaling in the match engine--the only place that I've found it make a difference is the coach report (see below; this is me hacking the return value from the function so it thinks groups 9, 8 and 3 are this player's best)--but it's worth bearing in mind. I'm going to keep this line of enquiry up and I'll report back anything I learn.




Although what you discovered isn't exactly the golden ticket we are looking for, it's nonetheless a significant insight for me.

Perhaps it's something obvious to a programmer, but as someone who doesn't know programming and couldn't make heads or tails of the code before, finding out what the attributes are called in the code gives me a solid foothold to work with.

I spent a while trying to find attribute combos in the code using this info. I came across a few intriguing ones, such as Reflexes interacting with CommandOfArea for some reason, but no clear formula I'm looking for. Strangely 'versatility' seems to interact with certain other attributes, but maybe I'm just misinterpreting what the code is about. Even without the formula, these attribute associations are perhaps useful clues for forming hypotheses to test about attributes.

Another thing I noticed is that there are references to four-letter names such as 'TrDp' (made-up example), after translating it into plain english with AI. If anyone else has a go at it, I know from previously trying to find the newgen mechanics in the code that these four-letter names are the shorthand they use for the actual mechanic. So a real example of this for instance is you can change the fitness heart icon back to fitness % by changing the mechanic it reads from 'PcOI' to 'PCRF' in the skin. If you go through the other game files, you can find a bunch of these four letter names, even ones that are meant to be hidden mechanics.

So I think I already found an example of say TrDp = anticipation + work rate, where if TrDp was what you were interested in finding out the formula for, you'd have your answer.

I reckon that the attribute combinations, and other things like newgen mechanics, are lurking in there waiting to be found.

0

GeorgeFloydOverdosed said: Although what you discovered isn't exactly the golden ticket we are looking for, it's nonetheless a significant insight for me.

Perhaps it's something obvious to a programmer, but as someone who doesn't know programming and couldn't make heads or tails of the code before, finding out what the attributes are called in the code gives me a solid foothold to work with.


I'm sorry to say that all the names in my post were given by me. There's nothing in the code I shared that names attributes or the groups they belong to (although you could infer them by reading the exact scout report detail they lead to).

The names in this post came straight from the qme_stat_relevant_attribute_data file in simatch.fmf though.

0

LightningFlik said: I'm sorry to say that all the names in my post were given by me. There's nothing in the code I shared that names attributes or the groups they belong to (although you could infer them by reading the exact scout report detail they lead to).
Hm.. isn't it the case though that 0x239 = acceleration?

Based on something my LLM said, it did occur to me that perhaps 0x239 just represents a generic offset (i.e. read ahead 0x239 amount starting at param1), but I saw interactions between attributes in lines of the code that made sense it was referring to specific attributes (i.e. I saw 0x244 (Aggression) with 0x240 (Dirtiness)).

I know your #defines list isn't the code itself, but you've nonetheless identified 0x239 effectively means acceleration, no?

0

Yes that's right. Everything in constants.h is right, that's from my app which scouts players in memory. I'm saying the names I gave to the attribute groups were made up by me.

Also I may have found the location in code where role/position suitability is calculated, but I can't get the code to fire in the course of the game, so testing it is proving difficult. It looks like that's what it's doing though.

0

LightningFlik said: Yes that's right. Everything in constants.h is right, that's from my app which scouts players in memory. I'm saying the names I gave to the attribute groups were made up by me.

Also I may have found the location in code where role/position suitability is calculated, but I can't get the code to fire in the course of the game, so testing it is proving difficult. It looks like that's what it's doing though.

So just to clarify, it is the case that 0x239 = acceleration, right?

What led you to 0x0144b40180 anyway?
I've been looking through instances of 0x239 for example for something interesting, but maybe there's a better way of going about it

Would be interested in seeing the suspected role location

0

GeorgeFloydOverdosed said: So just to clarify, it is the case that 0x239 = acceleration, right?

Correct. The game stores various objects in memory (Person, Player, Staff, Club, Team, Nation, Competition and so on) and 0x239 is the offset from the start of any given Player object where acceleration is stored. You can trust the offsets defined in my constants file.

GeorgeFloydOverdosed said: What led you to 0x0144b40180 anyway

I opened Cheat Engine, went to the memory address of a known player (which my scouting app told me) and added a "Tell me what read from this address" breakpoint on the player's acceleration. One of the instructions was the one I quoted in my code snippet here. I noticed the function actually hit a lot of offsets and learned it was combining and multiplying them in various ways.

GeorgeFloydOverdosed said: Would be interested in seeing the suspected role location

This is something you led me to last night, with this comment:

GeorgeFloydOverdosed said: I spent a while trying to find attribute combos in the code using this info. I came across a few intriguing ones, such as Reflexes interacting with CommandOfArea for some reason, but no clear formula I'm looking for.

I wondered what you were talking about so I searched the FM binary for "Command", "CommandOfArea" and "Command_of_Area".

"Command_Of_Area" is a hard-coded string at memory location 0x145c48e51 and it is used in only one location: 0x144380f6c. I can't copy and paste the whole thing but as soon as I saw it, I was intrigued.



It looks like it's taking a bunch of attribute names, feeding them in to a function and then getting a value back from them. Reading player attributes? Surely not, they're stored in a Player object in memory and accessed through offsets, not by string.

I looked at what called that function and got one hit: 0x14231dcd7.



It's a very boring looking function but then I noticed some strange looking memory addresses on lines 16, 33 and 50. I looked closer and realised they're not memory addresses, they're the words "posi", "attr" and "weig" represented as numbers (i.e. the character codes for each letter have been concatenated to make a 4 byte number). This intrigued me further.

I went back to the previous function (the one that read in attributes and did something with them) and noticed the bottom: the game reads in string references to player positions (e.g. DL, AMRL, SW) and it takes those plus the values read in above and feeds them in to another function.

Given all this, I'm convinced it is determining some sort of relationship between positions and attributes. Problem is, I can't find when the code is executed. I've put breakpoints all around it and they never fire. Is the code unreachable and unused? Does it fire when the game first loads, before I get a chance to attach Cheat Engine to it? (I can test this by launching the game with a debugger already attached, which I will do after work). Is it legacy code? (This wouldn't necessarily surprise me, I've found some legacy stuff already (around a mechanic called Match Boost in training modules that never seems to get used)).

1

Thank you for all these discoveries, small question that i have, do staff have any relevant role in player development, i tend to try and have the best staff there is, but with all you all discovered im not sure if it really matters or not. Assitant managers, scouts, phisios, all that, does it really matter? Thank you

0
Create an account or log in to leave a comment