My 20 year highschool reunion is coming up. This time its being organized in a Facebook group where all the members are from my former cohort. Its a strange mix of reminiscence and “Ew everyone looks so … old.” I looked for one of my former tormentors, hoping as the 80s convinced me, that I would find pictures of a balding, overweight Al Bundy sort, because those guys never wind up happy. Instead I find pictures of a blonde Adonis with a perfect body and a career in finance, vacation pictures of parasailing and rock climbing.

“Oh, there’s no way I’m going, now,” I tell my wife. She tries to convince me it’s not that bad. I’ve got a good life. Of course, I do. These are first world problems. “Don’t let that stuff bother you,” she says. But, we both know it will. It will because my self-perception, both then and now, was as a creator. A writer who might one day consider himself an author. A coder who might one day consider himself a game developer. Maybe, I think, if I had those credits under my belt, maybe it wouldn’t bother me. But it’s not just that I don’t have them, these artifacts of my creation. It’s this feeling that I never will have them and a general consensus from the industry that agrees.

If you take an article like, http://www.gamesindustry.biz/articles/2015-03-12-is-ageism-the-only-prejudice-the-industry-isnt-discussing, which discusses the industry’s ageism, and even specifically mentions late thirties as being the twilight of a career, then suddenly I’m not just shy a “by line” in the world of game dev, I’m on my way out! Heck, I’ve even embodied the cliché, “If you can’t, teach,” having just started teaching Introduction to Game Development to college students. Apparently, I’m giving up and leaving it to the next generation to fill in with their limitless time and present immortality. Perhaps they won’t repeat the mistakes of my youth. I shall live vicariously!

And yet… I mentioned being a writer as one of my other wishful avenues of creation. That’s my herald of hope for a creative future. Once I finally succumb to the ill-fated temperaments of my aging body, I will return once again to the art of the written word. It is in part this feeling that time is running out that has made me shirk my writing passion in an effort to use all my spare time, burning both ends of the candle, this website a testament, to get that video game credit. Once completed, then I can safely (because I’ll be old and my thoughts of video games long past) return to writing. Older, wiser, maybe a better grasp on grammar, I shall finally finish that book I started writing when I was sixteen.

Yes, for some reason writing a novel has an inverted expectation to the art of making of games. Somehow game making is only for the young, yet we refer to first books with a disdain “Well that was her freshman effort.” Young authors are greeted with skepticism; where the assumption on a first time author in her 40s or 50s is she might actually have something to say. Or, at least, that’s the perception that was passed to me early on and which I’ve carried, perhaps sparked by some smidgen of truth. It is hard to write about the nature of the world, or fate, or humanity if you’re only guessing at it, rather than having experienced loss, upheaval, regret, or enmity without the safety net of a home and parents to catch you. (Again, first world problems.)

As a younger man I rebelled against this notion that I could not write a novel at sixteen year old. I rebelled with the kind of passionate defiance only youthful ignorance can muster. I wrote my book about growing up without the hindsight of having done so. And now I’m paying (rather, delaying) the cost of that ignorance with editing for hindsight more than twenty years on. If only I’d spent that time trying to write a game instead of trying to invert the status quo. If only.

Let me arrive at my point. The video game as an art form is finally starting to mature, along with its audience, http://fortune.com/2015/06/15/video-game-industry-innovation. So should perhaps the expectation also mature.

Video games are not simply for the young.

It seems so obvious when put that way. Of course they aren’t. Many people in their 40s and 50s and older are playing games. I remember sitting on a plane next to a couple strangers. They were talking for a while, but the trip was long and the conversation fizzled. After a brief time, the woman next to me, around my age or older, pulled out her phone and turned on a game. She shrugged at the man next to her with a bit of an apologetic, “what are you going to do?” as she started to play. What she did, I think, was enjoy her flight.

Certainly young people can create good games. Young people generally have, because the industry has generally been young. But these young people have grown up and, many, also out, unfortunately. I want more than games created by this year’s 20 somethings destined to be cast off by next year’s. I want a game that speaks with the weight of experience. I want a game that ignores fads. That pushes with the inertia of seeing many fads come and go. I want a game that pulls inspiration from across the broad spectrum of experience that grew over the last fifty years games have existed, rather than the influence of games from last year. I want to hear voices of poignancy and elation, not just spectacle.

I want to play the Great American Video Game. I want to meet the J.D. Salinger, the Mark Twain, the Harper Lee of games. Maybe some of this is kindling in the crowdfund resurgence, but its a faint spark, and it is still so awfully dim. It must be stoked into a blaze to blind the eyes of those who see only the young.

This post is written selfishly. I want there to be an industry I can turn to when my obligations are met, when I’ve settled into retirement. I don’t want to have to give up making games because I’ve become too old. Maybe in this we’ll have an industry where my students can expect many years of a career, rather than 15-20 at most. Maybe we can change the perception that its okay to burn and churn the young because there is not an endless font of new talent. That experience can speak as loudly or louder in the creative process, if not also the technical one.

I’ve convinced myself, at least, that I should carry on regardless. *As it turns out, I have recently left my cozy, retirement-promising job for the games industry full-time. But that is a post for another time.*

As to the highschool reunion, I have no easy answer. This post was written toward defying expectations. Do I defy them by going or by not going? I’ll find out for certain when I decide.

*I didn’t go.*

Which leads me to the second thing: A new component available on the asset store.

We’ve created a new plugin that allows you to paint grass and detail meshes onto any surface, not just terrain. While it’d be easy to add a quad each through the regular editor, the overhead from draw calls would put the editor into a crawl. Instead, you can paint as much grass as you’d like at whatever density you’d like and it combines all those triangles into much larger container objects. These keep the draw calls down, allowing you to paint potentially millions of grass elements into a scene without killing performance.

Finally, we’ve started making progress on a new game, working title, “Runner”. You can find more information and track the progress of that here: http://www.indiedb.com/games/future-runner

]]>First, I’ll lay out the problem. Consider a sniper, “A” and a target, “B”. Sniper A is stationary and trying to track a target who is moving, for simplicity at some fixed speed in some arbitrary 3-dimensional direction. Sniper A wants to fire on B, but if he fires where he sees B, then by the time the bullet arrives, B may have moved out of the way. So the Sniper must aim at where B will be when the bullet get there.

Here’s a picture of the situation.

This would be very simple if B were moving directly toward A or directly away from A. Then we could either subtract or add that speed to our projectile speed and solve. But we must concern ourselves with the perpendicular speed as well. So where do we start?

In order to solve this, we must find a missing variable. We know all the variables except time, that is the time at which our projectile will hit the target if we aimed properly. Technically we don’t know where to aim, but if we knew the time, then because B is moving at a steady velocity we would just aim at B’s position plus the distance he travelled over that time, that looks like this

, where is B’s position and is B’s velocity.

So all we need to do is find the and plug it into that equation and that’s where we know B will be and thus where Sniper A should aim.

But how do we actually solve this? Well, let’s start with the naive approach: Lets just fire directly at B and solve for that . That’s pretty straight forward, we just need to find the distance from Sniper A to Target B and then divide by the speed of the projectile. That looks like this:

where and are A and B’s positions and is the speed of the projectile.

But the problem here is that we’ve missed the target by . Now we could take the approach that we find an initial this way, call it and then use that to compute a new and find a . That would look like this:

We can continue to iterate this recurrence relation this way, finding and so on. This is a pretty good way to solve a non-linear problem like this, if we don’t know of a closed form solution. We just keep iterating until, if we’re lucky, we get a converged value, a .

However, this may not converge. I’ll return to this because it’ll be there in any solution we find, but intuitively we can guess that it’s a case where our Target is moving as fast or faster than our Sniper’s projectile. Of course, this wouldn’t happen when we’re talking about humans and bullets, but we may not always be talking about that. Luckily with a recurrence relation like this, it’s easy to check if we’re converging, we simply watch the change in value between each and and make sure the number is getting smaller. If it grows or stays the same, we can’t solve the problem.

public float projectileSpeed; public float lastError = Mathf.Infinity; Vector3 CalculateLeadIterative (Vector3 previousPrediction) { Vector3 V = targetVelocity; Vector3 D = previousPrediction - sniper.position; float dt = D.magnitude / projectileSpeed; Vector3 pos = target.position + V * dt; float thisError = (pos - previousPrediction).magnitude; if (thisError >= lastError) { Debug.LogError ("No solution exists"); lastError = -1; // -1 is signaling its wrong, never should be negative } else { lastError = thisError; // outside code checks when this is close enough to 0. } return pos; }

Here’s an example player showing this code working.

Okay, so we have a solution but it’s not really efficient. If we could find a closed for solution, we could just plug the numbers in and get the answer back. Maybe that’s possible. Well let’s start with that recurrence relation we were using, but just get rid of the steps. There’s only one that we want, so let’s plug that in to both sides of the equation.

So, now we can’t easily find a solution for because its on both sides of the equation, so we have to do the hard work of seeing whether or not we can isolate it. I’m out of practice; there’s probably a shortcut I’m missing. In the end I’ll show the work in case there’s a mistake I’ve made along the way.

So first, I’ll move the out of the way.

Square both sides because it’s a vector magnitude over there and I want to get rid of that square root so I can pull it apart.

Because I don’t know a shortcut for this, I’m going to pull the vectors apart. But for now I’m just going to look at the x component because y and z will look exactly the same and we’ll just add them back in (again because we’re inside a vector magnitude).

Doing the work of the full squaring, we get this.

And then pulling together the like terms, we see we’re approaching a quadratic equation on , which is promising because solving a quadratic equation is straight forward.

That’s pretty close, but we can do one more simplification on those last three terms , that’s just a binomial. I remembered one shortcut. Yay!

Okay now, we need to pull in the other components, y and z. I’ll do this for each term, so it’s not too messy.

The first term after adding in the other components looks like . But we recognize that’s the square magnitude of , so really we have . This also works for the third term, which becomes .

The second term,

,

if we look closely, is a dot product between the vector and the vector , which becomes .

So putting it all back together we’ve got,

And then pulling the over, we finally have a quadratic equation.

Finally, we can compute a solution as follows, using

,

,

.

and plug them into

We’ll get two solutions for . One will be negative value of . We can see this as the point in the past where if the Target B, shot at the Sniper A then the projectile would have just now arrived. But what we care about is the future where Sniper A fires at Target B, so we just need to find larger than 0. And we’re able to write out the code.

public float projectileSpeed;

Vector3 CalculateLead () { Vector3 V = targetVelocity; Vector3 D = target.position - sniper.position; float A = V.sqrMagnitude - projectileSpeed * projectileSpeed; float B = 2 * Vector3.Dot (D, V); float C = D.sqrMagnitude; if (A >= 0) { Debug.LogError ("No solution exists"); return target.position; } else { float rt = Mathf.Sqrt (B*B - 4*A*C); float dt1 = (-B + rt) / (2 * A); float dt2 = (-B - rt) / (2 * A); float dt = (dt1 < 0 ? dt2 : dt1); return target.position + V * dt; } }

Here’s an example player showing this code working.

Before I conclude, I want to look at some of the properties that come out of the quadratic solution and how they relate to intuition about the problem.

Going back to the discussion of impossible cases we see that in . Seeing it in the bottom of the fraction, we know that if is zero this will blow up. That happens when Target B’s velocity is the same as the projectile speed. But looking under the square root we see that if B’s velocity is larger than projectile speed, we get imaginary results, which since we’re looking for a physical solution we want to avoid.

Finally, looking at the numerator of the quadratic solution

Lets make the following substitutions: will be . will be . And we’ll replace the dot product in with . And what we wind up with is,

Expanding under the square root we get,

And then simplifying,

Because, , we get,

Which is another binomial under the square root, giving,

Removing the square root,

Pulling out the and the extra minus sin, and put this back in with the denominator (which lets us get rid of the 2 all together).

Seeing this, our earlier intuitions about the problem pop right out. The term represents how fast Target B is moving either directly toward or directly away from Sniper A. The term represents how fast Target B is moving perpendicular to Sniper A. Pull the math all the way to its final conclusion we’re able to find the patterns that make sense with our original intuition.

I love me some math.

This update includes:

- A new horde mode that supports both single-player and co-op multiplayer
- Xbox360 controller support
- A high-score list

Look out for build 15 sometime around Dec 15th; we’ll be adding an entirely new game mode for single player and multiplayer! While we don’t want to give it away entirely, the engineer will become a lynch pin ship in these new modes.

Updates in this release include:

- Updates to the AI
- Fixes to the options menu
- Added messages to let you know when you score a kill or an assist
- You can now Activate the game on up to three machines (if you need more feel free to contact us about it)
- Improvements to the scoring system, including end-of-game awards
- and a few more surprises.

In addition to the game going on sale, we made the following changes:

- Tutorials
- Numerous bug fixes
- Several small gameplay enhancements
- Some interface improvements

Download the update and enjoy!

]]>There are *many* new changes in this update, including:

- New weapons
- New ships
- More special moves
- Three planes of action on which to fly
- New “king of the hill” game mode where you capture the center base and try to hold it
- … and more!