All posts

Games

Game development

Stories

Happiness

Personal

Music

TV

Film

TOM FRANCIS
REGRETS THIS ALREADY

Hello! I'm Tom. I designed a game called Gunpoint, about rewiring things and punching people, and now I'm working on a new one called Heat Signature, about sneaking aboard randomly generated spaceships. Here's some more info on all the games I've worked on, here's the podcast I do, here are the videos I make on YouTube, here are some of the articles I wrote for PC Gamer, and here are two short stories I wrote for the Machine of Death collections.

Theme

By me. Uses Adaptive Images by Matt Wilcox.

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

Teaching Heat Signature’s Ship Generator To Think In Sectors

What Works And Why: Multiple Routes In Deus Ex

Natural Numbers In Game Design

Naming Drugs Honestly In Big Pharma

Writing vs Programming

Let Me Show You How To Make A Game

New Heat Signature Video: Galaxies, Suction And Wrench-Throwing

What Works And Why: Nonlinear Storytelling In Her Story

My Idea For An ‘Unconventional Weapon’ Game

From Gunpoint To Heat Signature: A Narrative Journey

The Cost Of Simplifying Conversations In Videogames

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

Heat Signature Needs An Artist And A Composer

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

Gunpoint Patch: New Engine, Steam Workshop, And More

Distance: A Visual Short Story For The Space Cowboy Game Jam

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

Heat Signature: A Game About Sneaking Aboard Randomly Generated Spaceships

The Grappling Hook Game, Dev Log 6: The Accomplice

A Story Of Heroism In Alien Swarm

One Desperate Battle In FTL

To Hell And Back In Spelunky

Games Vs Story 2

Gunpoint Development Breakdown

Five Things I Learned About Game Criticism In Nine Years At PC Gamer

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

The Magical Logic Of Dark Messiah’s Boot

Arguing On The Internet

Shopstorm, A Spelunky Story

Why Are Stealth Games Cool?

E3’s Violence Overload, Versus Gaming’s Usual Violence Overload

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

How I Would Have Ended 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!

Francis Joseph Serina: What Engine are you using? If this were Unity, I'd such the reticule to be a child of the gun (or aiming mechanism). Is there only 1 gun? Or can you control multiple guns like when you hijack a ship and have the turrets follow the mouse/reticule?

James Vokes: As I'm understanding it you're using the oReticule.visible variable to decide whether "auto aim" is active. Why do you turn it off each step always? Why not do something like once "auto aim" is active a "dead zone" is created around the object being aimed at. While the cursor is in the dead zone the "auto aiming" remains active. You might have to dynamically adjust the size of the dead zone so it's not too sticky when there are multiple objects near each other.

Tom Armitage: Loose thoughts - but they might be more useful than specific approaches:

- it feels like separating out the visibility of the reticule object, and whether auto-aim should be engaged, might help you here. Ie: you need to work out what object the player is auto-aiming at, and separately, you need to work out whether to show the thing.

- given that, feels like you need a separate ReticuleManager unattached to a visible object. Basically: anything that can turn the reticule on sends a message to this, such as "I am enemy #248 and I should be auto-aimed at". That probably gets stored on something like a list, if you want to have many reticules, or just a single field if you want one. (Or: might be worth having a list, so you can re-prioritise later, though I think priority order might just be last on first off). Anyhow, then, when it comes to aiming, you ask the ReticuleManager "which object should I point at" - and separately, when it comes to rendering, you ask the reticule manager "entirely separately, which object do I draw the reticule on?"

And then, at the end of your loop, you need something to tidy up - ie, rather than setting reticuleVisible=false immediately, you clear up after yourself at the end of a game loop.

Is this making sense? It might not be what other people do, but what it feels like is you need something abstract to handle all the possible auto-aims and reticules, that you can message and later ask for canonical answers. That'd also help separate out render and logic.

Jason Wroe: In Unity and C# what I would use would be callbacks. In C# u could create a call back handler on your reticle object and in your other bits of code the call back functions would be called once reticle is visible. I know you use game maker maybe this will help. @jayone74 http://gmc.yoyogames... ...pic=589410

Nounverber: It's unlikely that I'm a more experienced programmer but what I would do is probably let character always aim at the abstract target which may be on the mouse cursor but may also be somewhere else. Basically you always aim at the small reticle, whether its visible or not. No "aim at the mouse cursor except when xyz".

dwm: So, I think the problem you're running into is that you're commingling the reticule rendering and logic states. You're using the same boolean value — oReticule.visible — to determine both whether:

* The reticule should be shown (i.e. you've locked onto a target)
* The reticule needs to (re-)paint itself to the screen.

Instead, if you separated these values to something like:

* oReticule.visible
* oReticule.painted

… then you can use .visible as you currently are for the player aiming logic, and use .painted to keep track of whether the object needs to repaint itself.

Does that make sense, or have I misunderstood?

Duncan Wintle: Add a flag to your oReticule object called willDeactivate.

When oReticule.visble is set to true. set oReticule.willDeactivate to false.

When oReticule.visble would be set to true instead check oReticule.willDeactivate.
If oReticule.willDeactivate is false set oReticule.willDeactivate to true
else set oReticule.visble to false.

some sudo code:
setVisble(value)
if value:
oReticule.visible = true
oReticule.willDeactivate = false
else:
if oReticule.willDeactivate:
oReticule.visble = false
else:
oReticule.willDeactivate = true

This will make visible false after one loop in which nothing has called it but will stay visible until that happens

Nerd: Now I'm not anywhere near as experienced as you are.

But could you potentially make a separate script that turns the reticle on, and while it's on, everytime you call "IsReticleOn()" it checks for a certain condition, in your case: "Mouse no longer on enemy", before returning the value?

Kinda similar to James Vokes' suggestion, actually

Or alternatively, make the reticule ALWAYS drawn, but when it's not autoaimed, make it's position off-screen, yet still in the same direction as the mouse. Pretty easy vector math, no?

Duncan Wintle: someone compressed my white spacing :(

setVisble(value)
{
if value
{
oReticule.visible = true
oReticule.willDeactivate = false
}
else:
{
if oReticule.willDeactivate:
{
oReticule.visble = false
}
else:
{
oReticule.willDeactivate = true
}
}
}

Frans Kasper: Maybe just treat the visible state as an integer, e.g. set myVisible=2 whenever you want the reticule to appear. Then, where you currently set visible=false, instead subtract 1 from myVisible and set visible=false when it hits zero. That way your visibiliry state will carry over 2 frames, technically leaving the player auto-aiming for one frame too long but that might not be a big problem.

Mike: If you're happy with your current architecture and just want to fix the ordering problem - then perhaps you could store the frame number that the reticule was turned on, and change the code that turns it off to only do that if the current frame is greater than the stored frame. That way it will prevent the reticule from turning itself off immediately on the same frame, and your other code will get a chance to see that it's on and update accordingly before it does turn itself off the frame after.

Csirke: Wow, you got a lot of responses very fast! There might be some bikeshedding going on here :)

Anyway, I think what Duncan Wintle and Frans Kasper are saying is the simple solution you can easily use. But I don't like it.

I think your problem is that you have both the "Several bits of code that can each turn the reticule on", and the "None of these bits of code know what order they will execute in, on a given step" requirements. I'm guessing this means that if several bits of code want to turn the reticule on in the same step, it will be set to the place where the last bit of code wanted it to go. So even if you solve this problem now, you might run into a problem later, where every step those code paths run in different order, and your reticule will jump around between two places. And you make it a bit hard to set up any priority between the targeting.

So I think long term what would be best would be to have one function which can decide whether to turn the reticle on and where to target it, and this function would run once each step. Of course this probably requires a larger rewrite of your code, so I understand if you don't do it. But maybe later, when you are introducing some new "state" into the game, you could try doing it in a way where setting the state only happens in one place, generally that makes working with it less complicated.

Matthew Smith: I think the problem is you want it to appear whenever but only stick around for one frame from when it appears. However you now have a problem that the time it should disappear is arbitrary.

I think the cleanest solution is to let it stick around for one frame on from a designated point. Ideally this point occurs just after when it gets turned on, but at least this solution will never fail if it happens to be some time before this point. Then both the draw and the auto aim can happen if the reticle is on, and while they may last for one frame more than is ideal, they will never last for longer than that, and they will always be on for at least one frame.

Matthew Smith: In terms of how you achieve this you need amIOn and stayOn. When you turn the reticle on both amIOn and stayOn need to be true. Then at this designated point if (stayOn)
{
stayOn = false;
}
else
{
amIOn = false;
}

TomF: When all you have is OOP, everything looks like an object. But it isn't. Time to go back to imperative. Let me try to explain (I hate writing English about Code, it's even harder than writing Code about English).

So you have all this functionality distributed around these "objects". But they aren't actual independent entities - you're actually just doing a single action (aim a gun) and a single blob of logic. So splitting things around the objects is hurting you, and you're having to add a bunch of book-keeping - stuff that doesn't make decisions, it just tried to keep all the objects in sync.

I would move all the actual thinking logic into a single place. Doesn't matter where, but probably PlayerMovementControls(). It will do:

1. Find enemy to point at.
2. Point player at enemy.
3. Tell gun to aim itself that way.
4. Tell reticule to draw itself there.

All the other objects just do what this logic tells them. The information flows one way - from the decision-maker to the children. There's no back-and-forth or multiple chunks of state. In this case the player object makes the choice, and then the gun and reticle do what they're told. This will keep things so much simpler, modifiable and debuggable.

TomF: Oh - what Csirke said :-)

Thomas H: However, the implemented solution only solves the problem if the execution order doee not change between frames.

Example:
initially OnSignal=OnState=false
# Frame 1
Listener A checks OnState: false
Something sets OnSignal = true
OnState = OnSignal = true
OnSignal = false
# Frame 2
OnState = OnSignal = false
OnSignal = false
Listener A checks OnState: false

If Game Maker does not guarantee that an order is kept you might want to think about implementing something more robust.

Gunpoint problem?

Don't post them here, I'm a useless idiot! E-mail tech support with as much detail about your system and the problem as possible, and they can actually do something.

Question?

There's a page about the games I've worked on, what I use to make them, and what platforms they're coming to.

Formatting

URLs get turned into links automatically. You can use <i>HTML</i> but not [b]forum[/b] code.

Comment