donadigo / gbxtools

Various scripts that I use for TrackMania replay analysis
GNU General Public License v3.0
58 stars 11 forks source link

Question about reconstructing a run from a decoded replay #2

Closed ad71 closed 3 years ago

ad71 commented 3 years ago

Hi, Since the physics engine in these games are deterministic, I was wondering if it is possible to extract inputs from a replay and inject them as virtual keystrokes / pad movements and get the exact same run. Has this already been verified? Or would it be affected by hardware / ADC etc?

PentaHelix commented 3 years ago

As I have gathered from twitter, this has already been done, and (exactly?) the same run can be reproduced I was curious as well if test have been done where

  1. inputs are read from a replay,
  2. those inputs are then used to replicate the run
  3. the resulting replay is run through the algorithm again to see if the inputs read from the second replay are the same as in the first / where they differ
ad71 commented 3 years ago

Yes, that would be really interesting to see Thanks for the clarification

pixeltris commented 3 years ago

I'd imagine injecting input at an OS level would result in inconsistencies (given that the polling rate is 10ms). For this to consistently work I think you'd need to forcefully simulate the exact input at the exact time by modifying the input handler code in the game itself. I assume this is something that has already been achieved in their TAS project https://donadigo.github.io/tmtas

ad71 commented 3 years ago

This is super cool, thanks for the link

pixeltris commented 3 years ago

FYI this post confirms the above and gives a rough overview of the hooks used to replay input https://donadigo.github.io/tmx1#2-internals-of-trackmania-input-handling

The official install of TMNF actually includes function symbols in the root directory under the name TmForever.map. This file includes the address and full name of every function in the game (in msvc++ mangled form, these can be demangled via UnDecorateSymbolName, or loaded into IDA with ida-pro-loadmap).

To be specific this is found at https://www.trackmaniaforever.com/ with the full download url being https://nadeo-download.cdn.ubi.com/trackmaniaforever/tmnationsforever_setup.exe with a SHA1 of 23388798D5C90AD4A233B4CD7E9FCAFD69756978.

Symbolic information is pretty significant for creating a similar tool as it greatly reduces time spent reverse engineering. In this case, as it's a map and not a pdb, some time would still need to be spent on figuring out relevant function locals, and class/struct members.

It would probably be a pretty fun project given the amount of info already available in the map. If that file has been around since at least 2011 (based on its timestamp) then I'm honestly shocked by the lack of native open source mods to TMNF... well I can't find much of anything on github at least!

donadigo commented 3 years ago

The report discusses this in section 3.2 and 3.3. Yes, the tool we use for replicating replays has been in development for ~3 years now, and it is capable of much more than just injecting all the right keystrokes at the right time. This is irrelevant to the report though.

pixeltris commented 3 years ago

Awesome, that's quite a lot of dev time! It is a little unfortunate that it sounds unlikely to ever see the light of day in the open source realm.

pixeltris commented 3 years ago

So I decided to have a go at this and got results I'm happy enough with. I decided to hook CTrackManiaControlPlayerInput::UpdateVehicleStateFromInputs for injecting inputs. And I loaded the GBX manually rather than getting the info from memory (though I fetch the GBX file path from memory). I didn't implement respawns, or insert the input events to the event store.

It's actually fairly simplistic to do and there are surprisingly few steps you need to take.

You can find the crux of the code here. There's a lot more code in that repo than necessary for just input replaying. I was going to do other modding stuff, but I've lost interest honestly! Still a pretty neat game to mod / reverse engineer. Hopefully some parts of it are useful to someone.