I’ve gone back to working on the infiltration-themed platformer I’m making, Gunpoint. I’d planned to take two days out of the winter break to binge on it, but after a few interruptions I’ve decided four half-days might be more doable, and less exhausting.
The plan is to rapidly impliment the last few features it needs before the main mechanic can make sense, without slowing down to fine tune their operation or tweak the look. So far I’ve got security doors and light switches working, and I’ve almost got the AI interacting with them correctly: only guards can pass through security doors, and they’ll turn on lights if they find them off. Next it’s the main mechanic, then a few last fundamentals that may end up being important.
It’s fun to be making fast progress again. It was a huge mistake to bother putting elevators in before the rest of the basics were working, and the ridiculous time that took added to the ridiculous time AI took is the main reason I ground to a halt on the whole thing.
I now have a game that is ugly, broken and crude in every way except the lifts, which are the most magnificently smooth, reliable and satisfying vertical transportation in the history of interactive entertainment. And I’m about one month behind where I would have been if I’d stuck to stairs. It started to feel hard.
It isn’t, really, but a few things do trip me up repeatedly. I want to make a note of them here on the offchance it gets any of it through my skull, so the rest of this post will make no sense to anyone who doesn’t use Game Maker (the tool I’m making the game with).
Things I Wish I Wouldn’t Constantly Forget
- When you store an instance in a variable – remembering which wall I’ve just collided with, for example – don’t. Store its .id property. Sometimes, even though what you want to reference is a property of that thing, you have to pretend it’s a property of that thing’s id, even though that makes no sense. Otherwise, you get shit like light switches that toggle their own existence on and off instead of changing the light level.
- The Create event is a handy place to put any code that should be executed when the object is created. DON’T EVER FUCKING USE IT FOR THAT. Why? Because the objects in the game at start up are created in an arbitrary, unreadable, undeterminable and randomly changing order.
You have no idea what code has already been done and what hasn’t when any given Create event is executed. So when one tiny change to something suddenly breaks everything in your entire game, including a bunch of stuff it had absolutely nothing to do with, it’s because the Creation order has changed arbitrarily.
Only ever use Create to set initial variables, then use Alarm events to trigger actual code. That way you can set those alarms to go off in the order you specify.
- Often you want one object to ‘trigger’ an event for another object. The reason the method you just tried isn’t working is that it’s getting re-triggered repeatedly sixty times a second all the time that the conditions are fulfilled, usually reversing the effect and/or delaying alarm events indefinitely.
The best way I’ve found to do triggers like this is to have it set an Activate property on the target object. The target object checks this Activate property every step, and the moment it’s ‘true’, it sets it to false, does its work, then tells the trigger object not to bother it again until it needs to.
- Relatedly, attach code to the object it affects, rather than the object that executes it. A button shouldn’t open a door, even if that’s the only thing it’s ever going to do. It should just say “Open!” to the door, and the door itself should contain the code for how to do that. That way, if you ever need other objects to open the door, they can just say “Open!” too and it won’t cause any conflicts or require any repeated code.
Pretty goddamn fascinating, I think you’ll agree. The truth is that most of the problems you encounter creating a game aren’t as frustrating as playing the average shooter. You don’t expect to succeed. You’re wrestling a ridiculous tangle of logical statements into something that functions as a comprehensible world, which is an insane and extraordinary thing to do – even when the results are drab, glitchy and artless. In other words, I’m enjoying it again.
By the end of this sprint I plan to at least be able to show you a video of it in action, and possibly send out a new prototype version to testers. If you’d like to try it when the next version’s ready for testing, and haven’t already mailed me about it, mention Gunpoint in a mail to firstname.lastname@example.org.