January 2nd, 2013
Category: development, Quadrilateral Cowboy

QC Dev 001: Ghost Cursor

In Quadrilateral Cowboy, the player can place items in the world.

placer_ghost

The player moves around a “ghost cursor” of the item. When the cursor is in a desired position, left-clicking makes the item appear at that spot.

This went through some iteration, and will almost certainly be further tweaked as development continues. Let’s take a look at how it works right now.

Tracelines And You

But first, some terminology: traceline.

In the picture below, I want to figure out what the player is looking at. So, I use a traceline. The traceline would start at the player’s eyeballs, and then shoot forward a very far distance.

placer_traceline

The traceline then spits out a bunch of information. One of these pieces of information is collision: what did the traceline collide with. In this example, the traceline hit the wall, signified by the red circle.

placer_tracelinehit

I examine what the traceline collided with, and now I know what the player is looking at: the wall.

Tracelines can do more stuff, but we’ll leave it at that for now.

Bare Necessities

I like to start with the most stupidly easy & simple implementation and then work from there. In this case, the most SE&S implementation is to make the ghost cursor appear X units in front of the player’s eyeballs:

placer_occam

This has some issues:

  • The item would spawn in & drop down to the ground, forcing the player to make a dubious guess where it’ll land.
  • It relies on a lot on trusting players to have good depth perception, which first-person games are notoriously awful at (hence why platformers are great in 2D but suffer in 3D).

On The Ground

To address those issues, the next iteration had the ghost cursor snap to ground surfaces. This was done by having two tracelines:

  • Traceline 1: start from player eyeballs, shoot forward X units.
  • Traceline 2: start from Traceline 1’s end position, shoot downward X units.

placer_ground

There. Now we have a nifty ghost cursor that snaps to floors, tables, shelves, vanities, curios, whatever old-timey furniture you can throw at it:

placer_ghost2

Done, right? Not quite.

Against the Wall

This is where things break down. If the ghost cursor is positioned near a wall, it’s fine. But once you push it closer to the wall, the ghost cursor ends up lodged into the world:

placer_collide

That’s no good. Halfway into a wall is a highly inappropriate place for any self-respecting ghost cursor. To illustrate, Traceline 1 is hitting the wall, then Traceline 2 is tracing down to the ground, resulting in this awkwardness:

placer_hitwall

Now, we can rely on the player to not place stuff so close to the wall. They’ll learn and get used to it, right?

Yes, they will learn your quirks. But if making your game lean is a goal, then stuff like this is definitely fat. Players have a finite amount of time and energy for you. Everything that goes into the project has to answer one question: is it respecting the player’s goodwill or squandering it?

Wash Rinse Repeat

The problem: the ghost cursor is lodged into the wall. Therefore, the most straight-forward solution would be to move the ghost cursor away from the wall. Let’s start there.

We add an additional check. If the ghost cursor is stuck in geometry, we:

  1. Step 1: Modify Traceline 1 by shortening it by X units.
  2. Step 2: Do the Traceline 2 downward trace. If the ghost cursor is stuck in geometry, stop everything and return to Step 1.

Once the ghost cursor is no longer stuck in geometry, then we know it has found a suitable place. Done!

placer_pullback

That’s where the system is right now. As levels are completed, more gotchas and edge cases appear as the ghost cursor has to contend with increasingly bizarre world geometry.

Et al

There’s something exciting about creating a system and then putting it through its paces. While artistic creativity plays a large part of game development, it also tickles that pleasure center of creating a finely-tuned clockwork machine, brimming with a billion moving parts working in concert with one another.

Then one day your baby is released out into the wild and you hope those billion moving parts don’t violently implode on themselves.

It reminds me of a program I saw on PBS about an off-road racing competition. The catch was: the cars had no drivers, nor were they remote controlled. Robot cars, folks. There was something so exciting and satisfying about seeing these machines have to be ready for whatever one-in-a-million edge case might happen, and gracefully handle it when that edge case inevitably happens ten times in a row.

7 Comments

  1. Cpt EverosCpt Everos  
    January 3rd, 2013
    REPLY))

  2. I love these updates, and I always check on this news section of your site. Keep it up!

    As for this particular update, it is interesting to see how devs come up to solutions to problems like this. Seems like yours will definitely do well.

    Looking forward a ton to this game.

    1F

  3. Avocado876Avocado876  
    January 4th, 2013
    REPLY))

  4. Glad you’re writing in this regularly, both the game reviews and the dev-blog-type stuff. I’m not a game programmer, but I’m a programmer. Curious as to why the Q2 engine you use doesn’t handle this sort of thing without additional coding (and/or that there’s not a third-party lib somewhere that’d handle this). Or perhaps there is a lib but you decided you wanted to roll it yourself, either as an educational exercise (I do that sometimes; I wrote a text-based database once — ZERO reason to have done that other than just as a challenge and to do a type of coding I don’t usually do), or because you’re wary of libs because they can become out of date for lack of support?

    Anyway: hope you keep posting here! Love your games, man; they’re fantastic .

    2F

    [...] wizardry, and intuitive puzzles harnessing a mobile “deck” computer for solving. In a blog entry posted today, Chung began a series of in-depth looks at the code keeping Cowboy’s code [...]

    3F

  5. BrendonBrendon  
    January 4th, 2013
    REPLY))

  6. @Avocado876 –

    QC uses the Doom 3 engine. Doom 3 doesn’t have any sort of functionality like this, so I had to roll my own.

    I’m very open to using libraries. I prefer making games, not tech, and libraries address that directly. I’m not aware of any general game libraries that do what I’m looking for.

    4F

  7. Avocado876Avocado876  
    January 5th, 2013
    REPLY))

  8. Got it — well, please keep up the excellent work (and the posts too); genuinely looking forward to QC (and secondarily, looking forward to whatever excellent music you choose to go with it — on of my favorite parts of your games).

    5F

    [...] January 9th, 2013 Category: development, Quadrilateral Cowboy « QC Dev 001: Ghost Cursor [...]

    6F

    [...] reading is the Blendo Games devblog on their upcoming Quadrilateral Cowboy. The specific post is mildly technical, but the quote in question is quite an artistic [...]

    7F