Guide:Entity swap tutorial
|Game(s)||Sly 2: Band of Thieves|
Sly 3: Honor Among Thieves
|Time to complete||20-30 mins|
Introduction[edit | edit source]
Entity Swap is a name given to a high-potential memory editing trick in Sly 2 and Sly 3 where you can replace any loaded entity with another entity. You can also modify their spawn limit, or even completely stop them from spawning.
Short explanation[edit | edit source]
Sly 2 and Sly 3 have a bunch of strings in memory that all start with FK$X and end with the name of an entity. The game uses these FK$X strings to find and load entities from the disc. Each FK$X string is accompanied by other data about the entity (such as it's ID, the number of them in the world, etc).
During the loading screens, these FK$X entries are populated in memory on a per-level basis. That’s why most entity swaps that are applied on boot will crash (or won’t work at all)-- you have to apply them when the level is loading (or after it has fully loaded). "If" conditional statements in PNACH files makes these mods possible by allowing us to time the patch execution at the point just after the maps have loaded.
Long explanation[edit | edit source]
Not being able to apply the entity swaps on boot used to be a problem for PNACH mods, until we learned that you can conditionally apply patches using “if” conditions we call "E codes".
This is a pretty rough visual explanation of how the conditions work, so I’ll explain it further. Almost every entity swap-related PNACH requires these 2 highlighted lines; it first needs to check whether you’re loading into the right map, and then checks when your game isn’t loading anymore. E0 means 16-bit multiple skip:
In the green section, it checks how many lines of code it will execute below itself. The last 2 bytes are reserved for your mod. Let’s say you need to check that the Map ID is 20, you would write 0014 at the end. Remember that everything in PNACH is in hexadecimal (if it helps, the Windows calculator has a built-in DEC to HEX converter if you switch it to Programmer mode).
The loading address will always check for “3”, so you can easily copy that line into your mods, just make sure to count the number of instructions below it first.
The pink address at the end is where it’s checking the value from. The address order is super confusing at first but believe it or not, it is not a weird design decision by the emu developers, it’s actually how the raw cheat codes have always worked on a real console.
The potential[edit | edit source]
All this means (IN THEORY...) every possible swap you can imagine is possible, which would allow us to create A LOT of unique mod patches for the games. For example:
- Replacing patrolling guards with harder enemies (they keep their original pathfinding!)
- Modifying enemies' attacks (weapons, projectiles, etc.)
- Eventually map modifications like custom trampolines, triggers... even custom clue bottle locations????
Example of a finished mod that swaps the bear with Jean Bison:
Entity Swap Tutorial[edit | edit source]
Disclaimer[edit | edit source]
This guide will not teach you the basics of Cheat Engine or other programming concepts like memory maps and data structures. It is recommended to study them by yourself before wondering why nothing works (but screenshots will be provided to help you follow along).
Prerequisites[edit | edit source]
- PCSX2 (1.6.0 or LOWER)
- Cheat Engine (7.0 or higher recommended)
- Gou's Sly Trilogy Trainer or save file with 100% completion
Scanning for the target entity[edit | edit source]
First and foremost, we need to find the target entity that we will replace with something else. In this tutorial I will replace Sly’s music box gadget with a moose guard in Sly 2 Episode 6. This will be much easier when you know exactly what to look for. I recommend checking the Address Sheet for a work-in-progress list of FK$X entities in all the different episodes.
The music box in the game's memory is called FK$Xmusic_box. In this GIF, I search for the music box, left-click on it and press CTRL+B to view it in the Memory Viewer. Then I press the scroll bar’s up-arrow twice to show exactly what we need. Here I’ve visualised what all the values mean:
Blue is the entity’s spawning rule (-0x1C from the string)
Red is the entity’s pointer address (-0x18 from the string)
Green is its spawn limit (-0x14 from the string)
Keep in mind, the memory viewer will only show the values in this exact position when you View Memory on the string starting from the letter F and scroll up exactly twice. To do this, you can click the letter F in the Memory Viewer and press CTRL+G, which will make it start from there. Otherwise this visualization won’t help you and the values are all over the place.
For this swap, we are only going to need the entity, so left click on the first red number like in the visualization above, then right click and select "Add this address to the list". A window will pop up; you should give it a description so you remember what it is later (in this case I will simply call it "Music Box"), then change its type to 4 Bytes. That way it will get the full entity array that I highlighted in red. Click OK and close the Memory Viewer. Your address list should look something like this:
Scanning for the new entity[edit | edit source]
Now that we know what to replace, we can choose literally anything to replace it with, as long as it’s loaded in the same map. Again, to know for sure what you’re looking for, please check the Address Sheet (again, list is not finished yet).
The flashlight guards in episodes 6 and 7 are called
FK$Xnpc_moose_guard. So I repeat the entire process; scan for that string, CTRL+B, scroll up twice, left click the first byte of the entity and add to the list as 4 Bytes. (remember to name your addresses) Now your list should look like this:
Performing the magic[edit | edit source]
Before we replace anything, we do a crucial step to avoid crashing. Right click both addresses and show them as hexadecimal. Like so:
Now for the final step; copy the guard’s value and paste it into the music box’s value. If all done correctly, you should now be able to throw guard(s) out of Sly’s hand instead of the usual music boxes.
Creating a mod patch (PNACH)[edit | edit source]
As explained in the short explanation, every single swap is not possible yet. There is still a chance that your mod isn't crazy enough for the game to handle and you’ve successfully created an entity swap mod.
For this mod, we need the code to check the Map ID, and the loading state before swapping the music box with a guard. Here’s how we do it:
I already explained how the E codes work, but I will quickly explain this image. First, memory addresses that you find in Cheat Engine always start with 0x20 or 0x21 because the base address of the emulated PS2 memory is 0x20000000. This means that in the pnach we can use the first digit for something else because because the emulator already knows to take the rest of it and add 0x20000000 to get the real address. For E codes, that digit tells the emulator which kind of conditional it is: 0 means "equal", 1 means "not equal", 2 means "less than" and 3 means "greater than".
For this mod, we need it to check that these values are equal, so we change the 2 into a 0 in the pink addresses.
The first line tells the emulator that this line is checking for a condition. Then it says execute the following two patch lines if the condition is met. Then it checks from this address that the Map ID is 20 (0x1B in HEX).
The second line also tells the emulator that this line is checking for a condition. Then it says execute the following one patch lines if the condition is met. Then it checks if your game is not in a loading screen (2 means loading, 3 means not).
The third patch line, which makes the swap between music box and moose guard, is only executed if both of the conditions are met.
Conclusion[edit | edit source]
I hope the tutorial helped you learn some stuff about memory editing and PNACHs. If you have any confusion or need help, you can always ask people at the Sly Modding server for help!! We’ve created a #sly-entity-swap channel for everything related to this trick.
Attribution[edit | edit source]
NiV and Frogg originally found this trick/wrote about it in the modding server. zami expanded on it, making the method a lot easier and writing a tutorial in a google doc. This guide was originally adapted from that doc.