How To Enable The Load Remover
Right click livesplit > Edit Splits > Activate
Congrats! You're done!
If you want you can click into the settings to optionally have the timer wait until the first loading screen to start. This way when starting your run you can start it after creating your character and it'll pause until the load finishes.
The rest of this guide is for nerds in the discord server to update the load remover when it breaks.
Unknown Game Hash popup? Load Remover not working?
If you're getting this popup from the load remover then join the discord server and ask someone to update the load remover script files. They will come to this page and read the stuff below. In the meantime consider down patching to a supported version, like 400313.
Nerd shit - STOP READING HERE
THIS SECTION IS FOR GIGA-NERDS ONLY, this is almost definitely not for you! If you want to use the load remover, stop reading here. This section is for nerds in the community who want to add support for new remnant 2 versions to the load remover scripts.
Every update that's released will need some work to support it in the load remover. Open the load remover file in notepad, and you'll see some stuff at the top that looks like this:
state("Remnant2-Win64-Shipping", "STEAM-397429") {
bool isPlaying : 0x07D6C788, 0x470, 0x170;
}
state("Remnant2-Win64-Shipping", "STEAM-382873") {
bool isPlaying : 0x07C25590, 0x158, 0x210, 0xB0, 0x1A1;
}
This is a list of entries for each supported version of the game. When a new version of the game comes out we have to create a new entry that looks like this, and fill in the required details:
state("Remnant2-Win64-Shipping", "STEAM-XXXXXX") {
bool isPlaying : YYYYYYYYYY, ZZZ;
}
XXXXXX is the game version number, it's very easy to find. It appears in the top left of the main menu when opening the game.
YYYYYYYYYY, ZZZ is the path to the "Is Playing" flag in the memory of the program, finding what to put here will be the only complicated part of the process. In summary we'll do the following steps:
- Install/prepare cheat engine
- Restart the game
- Load a character, and be next to a loading zone
- Attach cheat engine
- Find the code that handles loading
- Set a breakpoint
- Find some candidate pointers
- Save a pointer map
- Repeat steps 2-8
- Use the two pointer maps to find a reliable path
- Test the path
Once you get it down you should be able to do this all in about half an hour. You don't have to understand what is going on in each step, just follow the instructions and you'll have a working load remover :)
Install/prep cheat engine
Cheat Engine is a tool that is often used for hacking games (which is why it's called Cheat Engine). We won't be using it to hack, but it does a lot of other stuff that we need to find this pointer path.
- Download cheat engine, and run it.
- In the top click "Edit" / "Settings"
- On the left side of the settings window choose "Debugger Options", and on the right select "Use VEH Debugger"
If you skip this setting, then the game will likely crash in future steps.
Finding the pointer path
In Remnant 2, load into a character, and stand by a loading zone.
In Cheat Engine, click the little computer icon in the top left, and attach to the remnant 2 process:
In the middle left of the cheat engine window, click the "Memory View" button:
In the Memory View window, click "Search" and "Find assembly code"
The scan window has three fields we need to fill in:
- In the "From" field, copy paste this: Remnant2-Win64-Shipping.exe
- In the "To" field, copy paste this: Remnant2-Win64-Shipping.exe+fffffff
- In the big code area, copy paste this:
mov [rbx-08],r12
dec [rbp+00000170]
sub r14,30
sub edi,01
Click the scan button. It may take several minutes to finish the scan.
When it's done (1) double click the line in scan window to select it in the memory viewer window, (2) verify the blue line in the memory viewer has the "Bytes" "4C 89 63 F8". If it says something else then something went wrong, either retry the above steps or ask for help.
Click the line just below that one, with bytes "FF 8D 70010000". Press "F5" to set a breakpoint on this new line. When it asks to attach the debugger press "yes" to continue.
Back in Remnant 2, press E to go through the loading zone. The game should immediately freeze, do not worry it has not crashed or anything like that. It's waiting for us to click some buttons in cheat engine. The game will freeze maybe 5 or 6 times, and we're trying to find the first freeze that happens in the loading screen. In cheat engine memory viewer click the "Run" button in the top left, with the green arrow icon:
The game should instantly freeze again. If you are in the loading screen then move on to the next step, otherwise keep pressing this button once at a time, and checking the game.
Once you have the game frozen on the load screen copy down the "RBP" value on the right. Copy paste this value into notepad or something like that so you don't lose it. The 0s are always zeroes, never the letter O.
Press Run and take note of the next value from RBP as well. Do this a few times, there may be up to 5 or 6 values and we're not sure which one is correct until we do a little bit of testing. When you've got your values press F5 again to clear the breakpoint, and the run button to unfreeze your game. You should be able to turn around and go through the load zone without freezing.
Open up windows calculator, and put it in "Programmer Mode"
In the top area of the calculator click "Hex", and type in the RBP value you wrote down earlier.
Add "170" to that value:
In the normal cheat engine window, in the middle right, (1) click "Add Address Manually", (2) enter the address we just calculated, (3) set the type to byte, and (4) click OK.
For each of the RBP addresses you wrote down a few steps ago, repeat these "add 170" and "add address manually" steps.
Make sure your game is running normally again. If there is only a single row with the value "1", then congrats, you have found the right address! Keep that line, and remove the others.
Double click the description of your line that you are keeping and name it "first value" so can remember which test it came from.
Right click the line, and choose "Generate pointermap". Save it anywhere you want, called "firstpointermap". This may take a few minutes.
Once saved you are done with the first iteration, and now it's time to do it all again :)
Keep cheat engine OPEN, but close and restart your game. Don't just exit to menu, fully close the game and reopen it. Repeat all of the steps starting from there again. When you attach cheat engine again it will ask if you want to keep the old addresses, make sure to say yes. At the end you should have two values that look like this:
Now right click your second value and choose "Pointer scan for this address"
You need to change a lot of settings in the scan options window:
- Click "Use saved pointermap" checkbox in the top left, and choose the SECOND pointer map, the one you made most recently. The box beneath that should already have your "second value" address.
- Click "Compare results with ..." checkbox. Choose the first pointermap file, and enter the address of your first value next to it.
- Click "Pointers must end with ..." checkbox near the bottom, and enter "170".
Then click OK, choose any file name like "scanresults". This may take a few minutes to run.
Click "Offset 3" at the top to find the shortest paths. Expand the left "Base Address" column so you can see the full offsets. These are potential pointer paths that we can use in the load remover, but like before most of them are false positives and we'll need to do some testing to verify which ones are good.
To check which ones are actually usable we will close Remnant 2 completely, open it again, and get stand in front of the loading zone again. Cheat engine needs to be attached again, so use the little computer button in the top left for that just like before.
Once attached, double click a few of the top results from your pointer scan to bring them into the cheat engine address pane:
You want to go back and forth through the loading zone a few times, checking the value column. When you're in the loading screen they should have value "0", and when you're out of the loading zone they should have "1". For me all three looked fine, but if you have none that work you might need to look at some of the longer pointer paths in the scanner or unfortunately you might need to try again from the start.
But, if you found a pointer path that is giving you the values you expected, then you'll be ready to update the load remover. In the pointer scan window take the value after the "+" in the "Base Address" column, and the values from the offset columns. For example this row that I'm using:
You take the values mentioned above, with "0x" before them, with commas separating, ending with a semicolon:
state("Remnant2-Win64-Shipping", "STEAM-400313") {
bool isPlaying : 0x07D8F558, 0x470, 0x170;
}
Finally, we need to add an entry to the version lookup list. Take the hash value from the livesplit popup, the version number from the main menu of the game, and put them in the list like this:
vars.hashToVersion = new Dictionary<string, string> {
// == Steam ==
{"72FAF81E831F7120D3B0E7A66A6947D1", "400313"},
{"76197FF9D374E59E32BF6E5004D2DA89", "397429"},
{"B128B471801EA627591095DBB8BFA362", "382873"}
};
Copy and paste the top line (right below the "== Steam ==" line), replace the long value on the left with the hash and the short value on the right. Save the file, restart your game, and it should work :)
Start the timer and test some different load zones to verify it's working as expected. Verify that load zones work, but also teleporting from the crystal should pause the timer. The labyrinth bridges technically "load" some stuff, but they should not pause the timer, so make sure to run through there.