How to prevent cheating in our (multiplayer) games?
I don't think you should do anything to stop cheating on single player games. Your users bought the game, they should be able to cheat if they want to, as long as they're not playing against others.
Here are a few things that I've done. These were mostly done for anti-cheat systems on tournament games, where money is at stake, and certain levels of intrusion on the user's system is considered acceptable. I would be careful about doing some of this stuff on casual games since if your game is not stable there is the potential for causing problems with their system.
1) Where possible, "Never Trust the Client" is your safest principle to adhere to. Perform all actions on the server, and only give the client as much knowledge as is necessary to render what he should be able to see on the screen at any given time. i.e. if a client doesn't know the position of a player that is hidden behind a wall, a wall hack won't do the user any good. For high-speed action games this can be extremely difficult - especially now that real-time shadows and such are the norm, where the user may need to be able to see a shadow even if the player's body is visible - but it should always be at the top of your options. Also extremely difficult to do on peer-to-peer games, but there are ways to limit knowledge between peers. Only when it becomes performance prohibitive, or outside of your time/money budget, should the following items be considered.
2) Open all other processes, and hook their WriteProcessMemory functions so that they can't write to the memory in your game's process. Done right this one step will block 90% of all cheats and cheat engines.
3) Do the same thing, hooking the various mouse and keyboard emulation functions. This will prevent a lot of aimbots and other types of automation bots.
4) Hook into the VirtualProtectEx/VirtualAllocEx/etc functions in your game's own process and monitor which modules are changing protection levels or allocating new memory chunks. You have to be crafty with this in order to prevent it from being too CPU intensive when your game does a lot of allocations, but it can be done.
5) Hook into the LoadLibrary functions and monitor any DLLs that are being loaded dynamically, to prevent DLL injection.
6) Use some lightweight polymorphic encoding on your game connections.
7) Use some anti-debugging techniques to prevent debuggers from attaching to your processes. Google anti-debugging and you should be able to find lots of stuff.
8) Use a custom proprietary PE packer to prevent useful disassembly of your game.
9) Hook into your OpenGL or Direct3D functions and methods that deal with transparency and alpha blending.
10) If using shaders, checksum your shaders and the shader constant values.
11) Use additional occlusion culling techniques on player characters to prevent them from being rendered at all when the line of sight to them is blocked by other geometry. It may or may not help with your performance also, but it will prevent many wallhacks.
You may find this paper on Cheat Proof Game Protocols interesting. They're all variations on the same idea: using hashes as a promise, and then reveal the meaning of the hashed promise once conditions on the behavior of other players are met. It's complicated, and it has performance impact, but some of the ideas may be useful, particularly to peer to peer games.
When the game is based on completely a server-client architechture, the job is almost done I think, but there is also wall hacks or something else.
If you cannot move most of the logics to run on the server-side, at least try to share as little state as realistically possible during each game play phase, in other words: keep each player's active game mode into account and only share information that's actually relevant at that time.
This will not only reduce the possibility to cheat, but also reduce the traffic caused by your protocol, i.e. it will improve the efficiency.
This is a technique that in itself has long been known and applied in the gaming/simulation industry to improve efficiency when rendering large 3D scenes.
There, "frustum culling" is used to determine which parts of a scene are actually visible, so that only the relevant parts are rendered.
Similarly, the same technique can be used to restrict multiplayer clients to only receive certain updates/information if they are actually relevant, e.g. if other clients are actually within a "range of relevance", so that other clients may retrieve corresponding updates.
Still, differentiate between relevance and "visibility": two players separated by a door may not actually "see" eachother, but depending on the surroundings, may very well hear eachother. So, differentiate between different types of "visibility": propagating audible state doesn't necessarily have to imply propagating the player's actual position in game coordinates. The same applies vice versa: only because you 'see' a player, you are not necessarily entitled to also hearing the client (e.g. imagine a scope on a rifle).
In other words, try to loosely couple the update packets that you support, so that they don't have mutual dependencies on one another, and can also be propagated/subscribed to independently.
Cheating can be largely controlled just by applying proper encapsulation and data hiding mechanisms, so that multiplayer clients do not generally share global state, but shared state is instead directly dependent on the player's active context (position, heading, orientation, speed etc).