All posts

Games

Game development

Stories

Happiness

Personal

Music

TV

Film

TOM FRANCIS
REGRETS THIS ALREADY

Hello! I'm Tom. I'm a game designer, writer, and programmer on Gunpoint, Heat Signature, and Tactical Breach Wizards. Here's some more info on all the games I've worked on, here are the videos I make on YouTube, and here are two short stories I wrote for the Machine of Death collections.

Theme

By me. Uses Adaptive Images by Matt Wilcox.

Tom’s Timer 5

The Bone Queen And The Frost Bishop: Playtesting Scavenger Chess In Plasticine

Gridcannon: A Single Player Game With Regular Playing Cards

Dad And The Egg Controller

A Leftfield Solution To An XCOM Disaster

Rewarding Creative Play Styles In Hitman

Postcards From Far Cry Primal

Solving XCOM’s Snowball Problem

Kill Zone And Bladestorm

An Idea For More Flexible Indie Game Awards

What Works And Why: Multiple Routes In Deus Ex

Naming Drugs Honestly In Big Pharma

Writing vs Programming

Let Me Show You How To Make A Game

What Works And Why: Nonlinear Storytelling In Her Story

What Works And Why: Invisible Inc

Our Super Game Jam Episode Is Out

What Works And Why: Sauron’s Army

Showing Heat Signature At Fantastic Arcade And EGX

What I’m Working On And What I’ve Done

The Formula For An Episode Of Murder, She Wrote

Improving Heat Signature’s Randomly Generated Ships, Inside And Out

Raising An Army Of Flying Dogs In The Magic Circle

Floating Point Is Out! And Free! On Steam! Watch A Trailer!

Drawing With Gravity In Floating Point

What’s Your Fault?

The Randomised Tactical Elegance Of Hoplite

Here I Am Being Interviewed By Steve Gaynor For Tone Control

A Story Of Heroism In Alien Swarm

One Desperate Battle In FTL

To Hell And Back In Spelunky

Gunpoint Development Breakdown

My Short Story For The Second Machine Of Death Collection

Not Being An Asshole In An Argument

Playing Skyrim With Nothing But Illusion

How Mainstream Games Butchered Themselves, And Why It’s My Fault

A Short Script For An Animated 60s Heist Movie

Arguing On The Internet

Shopstorm, A Spelunky Story

Why Are Stealth Games Cool?

The Suspicious Developments manifesto

GDC Talk: How To Explain Your Game To An Asshole

Listening To Your Sound Effects For Gunpoint

Understanding Your Brain

What Makes Games Good

A Story Of Plane Seats And Class

Deckard: Blade Runner, Moron

Avoiding Suspicion At The US Embassy

An Idea For A Better Open World Game

A Different Way To Level Up

A Different Idea For Ending BioShock

My Script For A Team Fortress 2 Short About The Spy

Team Fortress 2 Unlockable Weapon Ideas

Don’t Make Me Play Football Manager

EVE’s Assassins And The Kill That Shocked A Galaxy

My Galactic Civilizations 2 War Diary

I Played Through Episode Two Holding A Goddamn Gnome

My Short Story For The Machine Of Death Collection

Blood Money And Sex

A Woman’s Life In Search Queries

First Night, Second Life

SWAT 4: The Movie Script

Help Me Structure Some Code Better In Heat Signature

Update: Solved! See bottom of post for details.

Hello, more experienced programmers than me! I could use your advice. There’s a code-pattern I’ve been using for a while and I’ve just discovered a problem with it, but I can’t see a great alternative either. I will explain by example:

What I’m doing

Right now I’m trying to add a little auto-aim when you’re pointing a gun at people. If you’re holding a gun and the cursor is near an enemy, I want a little reticule to appear on the enemy, the player to point their gun at them, and if you fire, obviously, fire in that direction.

How I’m doing it

The reticule needs to be an object – that’s the only way to specify a particular depth (z-layer) for it to be drawn at). I called it oReticule.

The code that looks for enemies to aim at is in the PlayerItemControls() script – that handles anything specific to what you’re holding in your hands, and this is a feature of guns and possibly some other item types, but not others. I tell it: if there’s an enemy near the cursor, place oReticule on it and make oReticule.visible = true.

The code that decides which way the player should face is called PlayerMovementControls(). Normally, in this ‘moving around freely’ state, the player always faces the mouse cursor. For auto-aim, I’ve added an exception to say: if oReticule.visible = true, look at that instead of exactly at the mouse. The difference is slight but important: guns fire in the direction they’re facing, so you really do need to look exactly at the reticule.

Lastly, when oReticule has drawn itself, it sets oReticule.visible = false so that it won’t be drawn again unless the auto-aim code tells it to. I don’t want to have to add lines to all other player states telling the reticule to be off, I want it to be always off unless this one specific bit of code activates it.

What the problem is

Currently, the player movement code executes earlier in the step than the player item controls. So:

  1. PlayerMovementControls() checks oReticule.visible, finds that it’s false, and continues pointing straight at the cursor.
  2. THEN PlayerItemControls() finds an enemy to point at, and puts the reticule there and sets oReticule.visible = true.
  3. oReticule finds that visible = true, draws itself, and then sets oReticule.visible = false.
  4. PlayerMovementControls() checks oReticule.visible, finds that it’s false – etc.

So the player doesn’t look at the reticule, and never will – it’s checking before the item controls has a chance to turn it on, and after the reticule has turned itself off.

Obviously I can fix this by just moving ItemControls to execute before the MovementControls, but those are separate behaviours, and I don’t want them to be order-dependent. It’s perfectly possible that I might later have the same problem the other way around, and it’s almost certain I will forget that they have this hidden order-dependency.

I also often want a similar relationship where those two scripts would be on different objects entirely, and in that case the order in which their step events execute is unknown. (It can be known, but it depends on something about how you organise your objects in GM that I change regularly, so I can’t depend on it).

What I’ve tried

What I’ve done for now is to take the ‘visible = false’ bit out of the oReticule’s draw event and put it at the start of ItemControls. Now the player does look at the reticule as desired, but there are still two problems:

  1. If we leave this state at a time when the reticule is on, this code won’t execute again, so the reticule will never get turned off. I do have an OnExitState bit I could add a line to, but this feels messy. It’s also possible for the player to get destroyed unexpectedly, and since the reticule is a separate object it would continue to exist and be visible.
  2. It’s perfectly possible that I might want something else to also turn on the reticule.
So what I want is
  • Several bits of code that can each turn the reticule on
  • Several other bits of code that need to know whether the reticule is currently on
  • If none of the bits of code that turn the reticule on execute, the reticule should be off
  • None of these bits of code know what order they will execute in, on a given step
  • It’s fine if the listening bits of code respond on the next step instead of this one
Context

This in Game Maker Studio 1.4, which uses its own language GML. It doesn’t have delegates or coroutines or structs, that I know of. All functions are public and can be called from anywhere.

Any thoughts?

Update: Solved!

Thanks everyone! Lots of very different ideas, many of them involving big concepts I didn’t know about. As usual, finding out all the different ways other people tackle this problem clarifies where the issue is, and I found I could boil it down into something pretty simple and lo-fi: I just need two variables instead of one.

The two types of code I identified above are ones that can set the variable and ones that listen for it. If these two operate on the same variable, order will always be a problem. So instead we’ll call the ones that can set it Signallers, and the ones that listen for it Listeners. And we replace the single variable with:

OnSignal: anyone can set this, but it is never read by anything other than the object.
OnState: only the object can set this, and anything can read it.

So Signallers all set OnSignal, and Listeners all listen for OnState. Then in the object’s code, we say:

OnState = OnSignal
OnSignal = false

Anything that listens for OnState – including this object’s draw code – will trigger once for every step when OnSignal was triggered by anything (it may be the next step). And will stop triggering if nothing set it since last step.

Tested it: it works, is only 2 lines, and most importantly, doesn’t involve adding code where there wasn’t already code for this.

Thanks again for the ideas!