Once saving exists, so does cheating. The two most common routes have the same shape: both engineer a situation where nobody else is present.
- Cheat Engine generally only works in single-player, so requiring two players shuts much of it out.
- Switching a slot in your own force to a Computer makes the player requirement look satisfied. A Computer never presses a key, so detecting a slot with no key input and disabling its save closes that door.
- Leaving the game running overnight to farm is caught by the same check.
Both are options in the generator; switching them on emits the code alongside the rest.
if(countPlayersPresent() < 2){
DisplayText("\x13\x19Saving needs at least two players in the game");
} else {
generateSaveCode();
}Detecting a Computer slot is not a separate setting - it falls out of the idle guard. A Computer never presses a key, so it trips the same idle check and that slot's saving is switched off.
The next step up is memory tampering, and the community's conclusion after a long time studying it runs against intuition.
An array declared once outside a function sits at a fixed address. Put a table of upgrade chances there and Cheat Engine finds and changes it immediately - that is the conclusion of someone who tried it. Reassigning inside the function each time blocks that attack, but doing it for every important array is not cheap.
Hiding the value does not work. Storing 50000 as 51234 and subtracting on read, or masking with XOR, all fall - said by the person who broke an XOR-protected test map in thirty minutes. Once the address is found the value changes, and nothing stops that.
So the direction changes: instead of hiding the value, notice that it changed.
The principle is simple: keep the real value A and a watcher B beside it, and act when the two disagree. What makes it work is that B's stored value changes every frame - a value that keeps changing cannot be found by searching, and what cannot be found cannot be adjusted along with A. The same shape works for currency: let the displayed minerals sit at 500 while the variable's stored value is a different number every frame, and someone searching for 500 never finds the variable.
And do not tell them in the game where it happened. Report it at their next login and they cannot tell what caught them; defeat them on the spot and they learn for free which thing is detected, and avoid only that next time.
Attach no DisplayText and no Comment to a protective trigger. An attacker pulls the map's whole string table and works backwards from the action that uses the text to find the trigger and neutralise it. Splitting the message into a separate trigger still leaves the hint: none at all is best.
And crash rather than Defeat - but find your own way to crash rather than using a published one. There are many ways to crash StarCraft, and a method in circulation is a method that is known.
"Block single player" is really two different questions, and a map wants both.
| 0x57F0B4 == 0 | Whether the game was launched as single player. Catches someone opening the map alone to work on it. |
|---|---|
| Counting players or buildings | A multiplayer game that has become solo. 0x57F0B4 is still 1 in that case. |
Doing only the first misses everyone else leaving; doing only the second misses the map being opened alone. People usually build the second first, so the cheap addition is the first.
It is worth stepping back here and deciding how far to go. What the people who have actually broken these schemes say comes down to four things.
- The tools edit several addresses at once, with different values. Keeping the number in two places is not safety in itself - it is safe only to the extent that the second one is hard to find.
- The process can be frozen, which is how "it changes every frame so it cannot be found" gets beaten.
- Do not respond with a Defeat action: it is one of the easiest things to find in memory, so it hands over the detector. Crash, or just set a flag and deal with it later.
- A fixed address is the real weakness. Allocate dynamically and reach the value through a pointer, so the address differs every game.
And there is a question of scope. Editing memory in a multiplayer game desyncs the person doing it - resources, the unit struct and the dat tables are all hashed. So the real exposure is a solo session that then produces a save code.
Guarding the money alone is locking the front door. Editing a weapon's damage or a unit's stats is easier than editing minerals and reaches the same ending. The answer to a solo session is not a better local guard - it is that the record is minted and checked somewhere the player does not control. Local measures are a cheap way to raise the bar and catch the careless; they are not what makes a leaderboard true.
