I'm just wondering how other games handle the problem of ensuring scripts are identical across clients in a multiplayer game. If one client modifies one of their scripts before joining the game, it could allow them to run different logic that could in some way give them an advantage or allow them to cheat. Obviously, you would use an authoritative server model to prevent most cheating, but there could still be client side cheats by modifying the client side scripts. For example, you could display the positions of enemy players on the screen using a modified client script by reading the positions received from the server for those players.

I'm guessing the most common way to solve this problem would be to simply compare scripts between the client and the server. More specifically, you could compare perhaps a hash value of the script's content and then load the script and run it from memory rather than from file. This would prevent the user from modifying a script while the game is running as it would already be loaded in memory. However, I'm not sure if this is a good solution (or the only solution). There are two things that concern me.

Firstly the hash value would need to be transmitted, which means it could be intercepted and tampered with to ensure it will always "match" regardless of the content of the script it was generated from. Perhaps this could be solved by encrypting the hash before the server sends it and then decrypting it on the client. However, this requires the decryption algorithm to be included in the client, which could be compromised somehow. Worst yet, the client could be compromised to always "match" or to always send the expected hash.

Secondly, hash values and such could be tampered with directly in memory using a memory editor attached to the running executable. Obviously this sort of stuff is not for the casual cheater, but a dedicated cheater will find ways to do this and more often than not broadcast such methods on the Internet with step-by-step instructions so that every kid is doing it before too long.

So I'm just wondering what other methods might be available or am I stuck with the above solutions and just have to deal with the problem as it comes up. Stopping cheaters is an on-going battle for developers and often results in game patches to plug holes found. I just want to put a bit of thought into this first to help minimize problems later.

You can’t stop people from modifying their clients, but no one is really going to be willing to go that far, realistically, unless you are a major corporation making a major AAA game.

Even then, trust me, hackers have better ways to get the information they need. You are definitely absolutely 100% over-thinking script security.

Real-life example, when I made my auto-aims for various FPS games, all I needed was data on player positions, velocities, etc.

Option #1: Spend weeks figuring out how to crack the script-verification process and write a hook to allow it to let me use my own modified server-sided script to gain access to this information, plus making the actual script.

Option #2: Spend 1 hour searching the RAM for this information, maybe 1 more hour trailing the data down to a base pointer, and make my auto-aim quickly by just using ReadProcessMemory() in a language I know well (more efficient than learning a new scripting language).

Seriously, what are they going to do with modified server scripts that they can’t do just by hacking with an external program and accessing the data they need directly? MHSeven has a built-in language which would handle all the attaching to the process for you and allow you to make any cheats you want right there.

As for cheating via just scripts, the player needs the same scripts as the server and this can be checked via checksum.

For example, you could display the positions of enemy players on the screen using a modified client script by reading the positions received from the server for those players.

Then don’t give scripts access to player positions? This is a solved problem since at least 15 years ago.

Player’s client scripts don’t need to match those of the server. That would be stupid. What would be the point of client-side mods, configurations, HUD’s, etc.?
You don’t need any fancy loading-from-memory or verification on the client-side scripts. If they can cheat via scripts, you’ve made an error in your scripting language or API itself (such as exposing a function to get player positions).

Obviously this sort of stuff is not for the casual cheater, but a dedicated cheater will find ways

Yeah, you can hash your data as you load it and send the hashes off to the server to defeat casual file editing, but there's no way to stop a clever adversary from editing their client.
If you're a big AAA game where this is an issue, the solution is to outsource this fight to VAC, PunkBuster, etc... It's a never ending battle (like writing anti-virus software) so you need a dedicated team who are experts in trying to detect game cheats...

By all means, but some basic systems in place to stop casual cheaters, but don't get carried away trying to solve the cheating problem completely, because it's unsolvable
The other thing you can do is put some other simple detection measures in place. E.g. if the client was in control of movement for some reason (ideally the server should be!) then you can have the server check the distance moved by each client per second. If the max is 100 units per second, but one client is consistently moving at 10000, you can flag their account as a cheater
Most companies seem to not ban cheaters right away, but instead they keep track of them for a few weeks, making sure they're cheating, and then they ban hundreds of cheaters all at once. That tactic is designed to create uncertainty I guess, because cheaters never know if they're actually going undetected or not. Just because their cheat seems to be working now, doesn't mean their account won't get a ban tomorrow...
If you're going to go down that path though, you need to be absolutely sure that your detection routines never create false-positives, where you'd end up banning an innocent player!

Then don’t give scripts access to player positions? This is a solved problem since at least 15 years ago.

15 years ago it was fine to write the whole game in C++. These days we have AAA games being written entirely in Lua. The scripts are the game.

Starsiege: Tribes is the showcase for everything I said.It is over 15 years old and and all of the gameplay was written in script. Exactly how games using Lua are today.Auto-aim was impossible via script because even though the server-side scripts had that information the client side did not.

That is what I mean by a solved problem for at least 15 years, and today there is no excuse for that kind of silly mistake (giving client-side scripts information that can be exploited).

Thank you for your replies. Let me address some of the points that have been brought up.

You can’t stop people from modifying their clients, but no one is really going to be willing to go that far, realistically, unless you are a major corporation making a major AAA game.

Indie games suffer from this too, if they don't have reasonable mechanics in place to stop casual tinkers.

Seriously, what are they going to do with modified server scripts that they can’t do just by hacking with an external program and accessing the data they need directly?

Not sure if you meant to type "server scripts," but I am actually referring to client-side scripts. By all means the game will be moddable both on the server side and client side. I'm just looking for a reasonable way to ensure the scripts on both sides match up.

As for cheating via just scripts, the player needs the same scripts as the server and this can be checked via checksum.

Yes, this is exactly what my post is all about. Exploring the merits of different options for ensuring the client and server have the same scripts.

Then don’t give scripts access to player positions?

As Hodgman pointed out, most if not all of the game logic is written in script (both on the server and client sides). The client scripts need access to that sort of data to render other players in the correct position and to also provide corrections to the local player when their movements get too out of sync with the server.

Player’s client scripts don’t need to match those of the server. That would be stupid. What would be the point of client-side mods, configurations, HUD’s, etc.?
You don’t need any fancy loading-from-memory or verification on the client-side scripts. If they can cheat via scripts, you’ve made an error in your scripting language or API itself (such as exposing a function to get player positions).

Sorry, I think you might be missing the points of my post. Modding is my main goal with scripting. I want people to create mods, however I need to ensure that both the client and server are running the same mods (i.e. the same scripts) otherwise the game will look different on the client than the server as they will be running different logic.

Yeah, you can hash your data as you load it and send the hashes off to the server to defeat casual file editing, but there's no way to stop a clever adversary from editing their client.
If you're a big AAA game where this is an issue, the solution is to outsource this fight to VAC, PunkBuster, etc... It's a never ending battle (like writing anti-virus software) so you need a dedicated team who are experts in trying to detect game cheats...

Thanks Hodgman, you have pretty much confirmed my exact thoughts. I know it is a never ending battle, and I do intend on using a dedicated service like VAC or PunkBuster. I was just thinking that maybe others have found ways to handle this situation that help to minimize the problem and make it easier to deal with when it happens.

If it's possible for your game, you can try and design the game rules such that cheating isn't as possible.

e.g. in an FPS, the client needs to know about players who are around the next corner. (Say network latency is 100ms, you can move the camera to a place that sees around the corner in under 100ms, so the server has to make sure you know about the enemies hiding there in advance, otherwise they'd be invisible for several frames if the server only told you about them after you were in a position to see them)

This means that people can write cheats where they render "invisible" players, AKA, the wall-hack...

If the game was designed instead where everyone had a gadget that could see through walls, then there's no point in writing a wall-hack cheat!

Similarly with RTS games -- people write "map-hacks" that let them see units hidden by fog of war (Ideally their clients wouldn't know about them, but the lock-step peer-to-peer network architecture means that clients basically have to have this knowledge). If you cant solve it with engineering (e.g. making the server hold this knowledge so clients can hack it), then you can solve it with game-play by not using "fog of war" in the game and instead having all units visible at all times

This obviously doesn't work at all times, but it's a good idea to keep your engineering limitations in mind and to keep potential cheats in mind when you're designing the game. Maybe you'll occasionally come up with multiple gameplay options which are all fun, but some expose more potential cheats than others.