This is generally done by reverse engineering the game to find out where in running memory these variables live within the program. There are two ways to modify those variables.
An attacker can patch the executable or DLL itself if there is no integrity protections on it. Basically the actual bytes of the program are modified to be/do something different. As long as the program does not check to ensure no data has been changed this is a very viable option.
This can be mitigated by performing some type of checksum over the entire executable. A cryptographicly strong hash would do. You wouldn't want to use something like CRC32 because with enough changes to the binary an attacker could make the checksums match.
You could also sign your program. Before executing the program it verifies the signature of the program. If this fails then the program doesn't execute.
In Memory Patch
This technique is generally a bit more annoying. While the program is running an attacker either injects code into it, or finds where it's living in RAM and patches the program there. Code injection is much harder to do, but the memory patching is almost the same as regular patching. The attacker has to perform this every time that the program is run though since RAM will get cleared. This is much harder to mitigate since you're program is already running.
There are techniques you can use to prevent reverse engineering in general. During portions of the program you want to protect you can detect the presence of a debugger. Reverse engineers will almost certainly need to use a debugger to figure out exactly what pirtions of memory effect what the program does during execution. Manipulating memory in a debugger to see how the program is affected.
You can also use code obfuscation to make the disassembly or decompiling of your code much harder.
Here is a fun link in that general direction.