execute_file() and GM:S

Posted by link2x101 on June 1, 2014, 5:21 p.m.

That is, why it doesn't exist, shouldn't exist, and how it can exist.

I've spent today thinking about how Studio is lacking the execute_file() and execute_string() commands.

And there's a fair number of reasons why this is so.

    [#]Piracy concerns. It's extremely easy to create your own GML runner. Sure, it makes Game Maker a significantly harder language to use, but it's still possible. This runner can then bypass all of the free-version limitations (provided someone with a paid copy compiled the executable.) The only real features lost are things like the loading bar, icon, and game-info. [#]Safety concerns. Look, I shouldn't have to tell you that letting your code run someone else's code without any safeguard can be a problem. Keyloggers, viruses, various kinds of bots, and any other malicious software can be transmitted this way. (Not to mention older versions of Game Maker weren't so safe with the filesystem access thing. Hello, system32.) [#]Rare usage. The most common usage case for these commands that I've ever seen is level editors and readers, which can easily be done in .INI format (depending on the game, though this lacks security) or a custom format (which is really not hard to do). Games using this style of saving/loading for maps are particularly at risk of the above safety concerns. I could easily write in some code among the instance_create()s to execute a .DLL saved along with the 'map', or even have the .DLL itself embedded into the map file, creating the actual .DLL file before executing it.

Now, these commands could easily be used to allow modding to a game. That is, you could let people hook in to core gameplay components and change how it's played, or change the music, or add multiplayer. All sorts of things, but I can't say I've ever seen anyone do such a thing with a Game Maker game. (And now it's a bit late for using this method).

However, you can still add such a feature to your game if you wanted. It's just a bit harder.

Now, instead of having free reign over a Game Maker game from an outside script, you have to specifically write in (effectively whitelisting) a parser.

Using file reading functions and more-strict Game Maker code (raise your hand if you don't always use semicolons) it can then be made possible to execute outside code.

That's right, you can still use an instance_create() level system, you just have to work a bit harder on making them load.

It's a pain, but this is a far safer way to go about things, as you probably won't be whitelisting dangerous commands, nor opening a hole for .DLL hooks or keyloggers.
TL;DR: execute_string() and execute_file() are gone because they are lazy and dangerous. You can still execute strings and files if you take the time to do it properly.

Comments

sirxemic 9 years, 10 months ago

Pretty sure they also abandoned them because they are slow as fuck and difficult to implement when the code is no longer interpreted but actually compiled.

Pirate-rob 9 years, 10 months ago

I thought execute_strings and files were removed do to the fact that GM:S doesn't translate at runtime any more, the same reasoning for checking if variables exist also being removed.

Btw I agree with you :P

link2x101 9 years, 10 months ago

sirxemic + Pirate-rob: You would both be correct. I had forgotten about this fact as I wrote the blog. :(

Pirate-rob 9 years, 10 months ago

You make a valid point though :S

Powerful Kyurem 9 years, 10 months ago

I don't think that's right to remove them. Sure, you can make pirated copies, but you could just as easily email the installed files to people, or anything like that. It's hardly protection. You lose the ability to do a lot of stuff. I've seen games use it as a feature. Not just a cheat system, but the ability to support entire game mods. Sure, you could make a level editor, but not only is that hard, but it defeats the point. You could change the very game mechanics. Besides, execute_string is used for much more than cheat systems. It's used for simple checks in levels, and things that would otherwise become redundant. I've actually come very close to creating a multiplayer once, if not for one line of code that was unchangeable. I can see preventing execute string from altering external files as that is dangerous or allowing it to grab external files to run, but it has a lot of in-game uses that the devs themselves. So, they should put it back in.

I apologize for the long reply. I'm just very strong about this.

link2x101 9 years, 10 months ago

Powerful Kyurem:

You know, I can't say I've ever seen it used for a cheat system, even though it makes sense. (Then again, I always build my own console system anyway.) Still, that would be falling prey to the "letting potentially-unwanted code run" issue.

As far as piracy, a compromised, single executable would be far smaller than the entire IDE (even with the bloat that is Game Maker itself). Not to mention if being a single file. It isn't something I've seen, but I know for a fact that it's possible and that's something YoYo has(/had) to worry about.

Sirxemic and Pirate-rob both bring up another point (the most important reason from YoYo's perspective): The shift from interpreted (GM8.1 and older) to compiled (Studio) gave up these features for speed and reduced size. If they wanted to add these two functions, they'd need to add several megabytes to the total size and add some kind of hooks for interpretation, which would slow down the game overall. Given the fact that they are fairly rare (and that someone in dire need of them can in-fact add them back in), it's more logical for the average user to just not bother keeping them.

It's still very possible to create your own execute_string() and execute_file() functions, though you'd be giving up a fair bit of speed depending on how you manage them. Cheat code and developer systems can also easily be done without these functions. All of the string functions combined with switches can be very powerful.

Powerful Kyurem 9 years, 10 months ago

That's why I said to remove the external file stuff for that function. That way, you couldn't create your own ide in any practical manner, or create a virus.

Powerful Kyurem 9 years, 10 months ago

Weird blank post above. hmm. must have been a whisper.

Anyway, I've seen a few games involving cheat systems. I plan on adding one into all of mine, eventually. It's annoying that some games won't port cause of this, though.

Pirate-rob 9 years, 10 months ago

If they don't port, just remove the commands :P

Yaru 9 years, 10 months ago

All the blog post points are valid. Writing your own parser gives you more control, and it also makes your scripts more portable (you can write a parser accepting the same language in C# or Unity or whatever and reuse your eigencode scripts there).

Using execute_file() basically lets anyone disguise a virus as your game. Probably not the best way to get more people to play it…