Closed GRhin closed 4 years ago
The creator of http://statsmylord.com/ (@lawrencefoley, also on the Sourcehold Discord) may have more information on the structure.
Somewhere in there should be the "death" skull
Thats great, at this stage i think we have found everything he has, plus a bit more. I think we have even found the death time/date... One of the big things i want to find is the "score" the thing that defines the order of greatest lord... I think i know the adress by looking at this sheet, but havent had a chance to look yet.
This is a really cool project! Awesome to see someone working on something similar to my website. Looks like you have all the stats that I have on my website, but I would be more than happy to share my findings or code. It's a bit of a mess right now so I'd like to clean it up before putting it on a public repo, but I could share pieces of it if that would help.
As for the "score" value, I had looked for that a while myself. I'll let you know here if I find it before the rest of the group does.
Also, would it be ok if I used the memory addresses the group find in my website? @patel-nikhil
Edit: I've attached my config file. This is for versions 1.4 and 1.4.1 of the SHC. config.zip
@lawrencefoley I just opened your website - very nicely done!
My codebase is still in very early stages, and now that I know with help from @GRhin more information regarding offset between player stats, etc. I plan to revise make my logic more modular and efficient.
@GRhin has been helping me significantly with finding the memory values, and barring any objections from him, of course, I'm more than happy to let you use it on your website
@lawrencefoley thanks for the zip, will browse soon. I hadnt seen your project before void pointed it out, and I like the idea. I actually have a different application of the same idea on the backburner (much more complex, but what you have would be a part of it). If you are willing to share info when i get into it properly, add me on discord GRhin#9114 and ill explain the details of my application
Also, did you know about the weighted kills/deaths? They are much more informative when comparing players. I.e. 100 slaves lost is weighted to 100, but 100 E.archer gets weighted to 500, i have a list somewhere of the values of each unit, except for seige equipment and tunnelors which arent recorded. Ping my on discord if you want it.
And as another point, do you know how the stars in the after-game screen are calculated? a friend has been trying to work out a pattern to see how it decides to give 5 stars, or 2 or 11, and hasnt come up with anything.
@lawrencefoley I had a look at your config.json
, can you explain what the "ID" field represents?
Also, do you generate the .json file from a table? Or do you edit it manually? In my MemoryReader, I use a more compact table format: https://github.com/void4/PySHCLiveReader/blob/master/tables.py
@GRhin In your Google Doc, you have many "P1 Kills P1", "P1 Kills P2" etc. fields. Are these unit kills?
Good news, I have found today: -Players present in game (557-55E) -Time at which players died (5A4-5C0) -Gaia kills player x (5A4-5C0) -# of Lords killed by player x (7EA-7F1) -Weighted Buildings Destroyed (864-880)
Are the addresses the same if UCP is not installed? Edit: Have you found a way to make the game not fullscreen?
I think so, but cannot be 100% certain as I have not checked
On Tue, 18 Feb. 2020, 1:55 am void4, notifications@github.com wrote:
Are the addresses the same if UCP is not installed?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/patel-nikhil/SHCLiveStatReader/issues/4?email_source=notifications&email_token=ALGGWTVHA4ZRF4S2DKS5UVLRDKQNRA5CNFSM4KV6R2T2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEL6WHRI#issuecomment-587031493, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALGGWTTAKGIIFIVB2YLMLXLRDKQNRANCNFSM4KV6R2TQ .
@lawrencefoley thanks for the zip, will browse soon. I hadnt seen your project before void pointed it out, and I like the idea. I actually have a different application of the same idea on the backburner (much more complex, but what you have would be a part of it). If you are willing to share info when i get into it properly, add me on discord GRhin#9114 and ill explain the details of my application
Also, did you know about the weighted kills/deaths? They are much more informative when comparing players. I.e. 100 slaves lost is weighted to 100, but 100 E.archer gets weighted to 500, i have a list somewhere of the values of each unit, except for seige equipment and tunnelors which arent recorded. Ping my on discord if you want it.
And as another point, do you know how the stars in the after-game screen are calculated? a friend has been trying to work out a pattern to see how it decides to give 5 stars, or 2 or 11, and hasnt come up with anything.
@GRhin I'll DM you on Discord. I haven't found where the weighted kills are. I'd love to know though. :-)
@void4 Oh, the ID field doesn't mean anything. I generate that JSON file from a CheatEngine file so that ID just corresponds to the ID in the CheatEngine file I have. I prefer the JSON format because it's more structured, but I'd be open to working on a different format together.
Also, more of a general question: What version of the game are you guys using? I'm using the 1.4 and 1.4.1 version of the Steam game.
This is 1.41E, I use extreme when i stream for the extra unit limit, but without magic bar and outposts etc. And that's where i am displaying these stats (over the game for viewers) I'm guessing you should be able to use one of the values you already know, and find the rest with offsets. Ie. If you have total buildings destroyed, and we have weighted kills 32 bytes away from that, you can move 32 bytes away from your memory location to find it. Note that 32 was just a random number, not sure the actual offset
@GRhin In your Google Doc, you have many "P1 Kills P1", "P1 Kills P2" etc. fields. Are these unit kills?
Yes. It is how many units each player has killed from each enemy
@GRhin That makes sense. I used that same offset method when finding the values for different versions of the game.
For the "score" value that determines the greatest lord; Isn't this based on kills and gold? Wasn't sure if it is affected by other things in the game.
Nikhil is testing now to see what effects it. i can tell you that already he has found that gold and weighted buildings destroyed effects it. and resources dont effect it.
I've now added the greatest lord score calculation to my program. This is the greatest lord score for when the game has ended - greatest lord is calculated differently while the game is in progress.
The score is calculated based on the following factors:
The following is the calculation the game uses to calculate greatest lord score. Note A >> B is shift right, (also I believe, equal to integer division by 2), repeated B times
const long multiplier = 0x66666667;
long goldBonus = ((gold * multiplier) >> 32) / 4;
long score = goldBonus + weightedKills + weightedBuildings * 100;
score = score + (score * lordKills) / 4;
Int32 dateBonus = (endYear - startYear) * 12;
dateBonus -= startMonth;
dateBonus += endMonth;
if (dateBonus < 1)
{
dateBonus = 1;
}
Int32 bonusDivider = 200 + dateBonus;
score = score * 200;
score = score / bonusDivider;
return score;
Here is a Python function I wrote that calculates the score. Not the cleanest, but I chose to write it that way as that was how it was done in disassembly. Also, I chose to hard code start year and month in my Python function for convenience; in practice my program reads all the values as they are stored in game.
What is the multiplier? Looks like an address? Does the lordsKilled divisor change defendant on the number of players?
Multiplier is a fixed value in hexadecimal. The divide by 4s are actually shift arithmetic right (sar) 2 in the dissassembly -> also fixed The divider of 200 also appears to be fixed.
Calculation runs for each player and I didn't see any of those values changed in-between, so not dependent on other factors from what I saw
I'm pretty sure some of my test scenarios had different numbers of players, I'll go back and test again when I have time.
What is that fixed value?
The fixed value is the one I use in the function. So 0x66666667 is the multiplier for gold. ie. the dissassembly does: mov eax, 0x66666667 and then imul (multiply) ecx
By fixed value I mean to say it's not loaded from another memory address. It's part of the instruction.
But that is an address right? What is stored at that address? If it's an equation then it amounts to 0 as 0 x anything is 0, which wouldn't work. So it must be a pointer.
On Tue, 25 Feb. 2020, 1:06 pm Nikhil, notifications@github.com wrote:
The fixed values are the ones I use in the function. So 0x66666667 is the multiplier for gold. ie. the dissassembly does: mov eax, 0x66666667 and then imul (multiply) ecx
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/patel-nikhil/SHCLiveStatReader/issues/4?email_source=notifications&email_token=ALGGWTQ4H2H3X5BHHILEDMTRER4ITA5CNFSM4KV6R2T2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEM2IIYA#issuecomment-590644320, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALGGWTTLFXZVEW66UVKK2CTRER4ITANCNFSM4KV6R2TQ .
No, 0x66666667 is the number, as shown in the image, not the address of another number. 0x just means it's a hexadecimal number. And ecx register contains the total gold produced
That's a massive multiplier. Can you tell me what (multiplier >> 32) equates to? As that is the effective multiplier...
multiplier >> 32 is equivalent to multiplier / 2^32
Yea I meant the decimal result of that, all good will do soon when I have the opportunity
Comes out to 0.4
Then divided by 4, so its effectively Gold bonus = gold/10
Yea that seems to be it. I never thought to compute the decimal value, just followed the same logic and calculation, using the hex values to remove any room for error
I think we have found everything here that we are going to.... so will close ticket.
So, we have noticed that the after-game stats are all located around the same area, so to facilitate finding these stats. i have made a spreadsheet containing all adress locations around the area of the stats we have already found. and labeled the addresses we know (and bolded)
https://docs.google.com/spreadsheets/d/1Pg_LMhhTN82vhezguDuMJTtXuZGSOAAXtZyzpfY7SIw/edit?usp=sharing
Note that the odd-number player names are off by 2 bytes. There are some convenient gaps that could include pitch, total kills, score, or something similar. If you want to check out addresses, or know where some are, let me know and i can update it.