This week I've been working on the particle system I'll be using for Starlight Revolution. Particle systems are one of those high-impact areas of game development, where a lot of beauty can result from very simple initial conditions. That's not the case here, yet, but I'm hopeful that in the future things will look better.
As I mentioned in an earlier update, Starlight is designed to record replays, and play them back both forward and backwards. As a consequence of this, I need effects to work when played either way. My initial idea was to utilize openGL's transform feedback functionality to update particle positions incrementally, but after working out some implementations along those lines I've settled on another solution.
I'm handling particles entirely within the shader. As inputs, the shader is fed a number of particles, a couple of values defining the system, and a time. Future frames are independant of the prior ones, which will likely come in handy in the future. This is actually the simplest way to implement things, though it is not without drawbacks. Some effects might be difficult to do if they require complex movement, but I'm fairly confident I'll be able to use this to make things look good. As a side benefit, because shaders are accessible to modders, adding new particle effects to the game should be a fairly simple endeavour.
If you'd like to chat on this or other topics, feel free to message me on twitter @JeckDev or leave a comment below. You can also subscribe to the mailing list for occasional email updates on what I'm doing. If you'd like to see what kind of content you can expect, you can check it out the latest newsletter here.
Looking at time differently
Continuing on from what I mentioned in the prior development blog, I've finished working out most of the kinks in the way objects handle time. The most concise way of explaining what I've been working on is that, in Starlight Revolution, time is an explicit rather than an implicit aspect of the simulation. So, what does that mean?
We're used to treating time as something that happens step by step-- as a process. This is pretty much a must for games that have to worry about things like realistic physics and forces. The downside, however, is that there's no skipping ahead- if you want to know exactly where a ball is ten seconds in the future, you have to walk through all ten of those seconds, because each position is dependent upon the position before.
How we're doing it
With a game like Starlight, however, we can make certain assumptions that open the way for a different implementation; we don't necessarily care about the exact velocities involved in getting a unit from point A to point B. We only care about the events that happen along that path- starting out, arriving at the destination, possibly getting attacked halfway there. So instead of progressing through time millisecond by millisecond, we can work with larger chunks of time-- progressing event by event.
If we keep a record of past events, we get replays. Replays are awesome, and something I'm definitely planning to include in the game... but the area I'm most interested in right now is the opposite direction-- keeping a list of future events.
The closest real world equivalent is a calender or daily planner. In a planner, you schedule things to happen in the future; occasionally, plans change, so you schedule something else... but for the most part, you know what you're going to be doing in the near term future. Now that's interesting...
What we're doing with it
If you've got a list of events that will happen in the future, the AI can now have much stronger knowledge about the future. Now, rather than having to run through every step of the simulation, I can simply check out what events are scheduled around a given point in time to see what's going to happen next.
If you're picturing an omniscient AI that wins because it knows everything (like, say, where to send the Terminators), don't worry-- that's not actually the case here. For one, I'm planning to limit the knowledge fed to a specific AI based on stuff a human could reasonably predict given the same information. If the AI can't see your spaceship now, it's got no right to know that it'll be here in ten minutes.
A few caveats
Even if I wasn't limiting the information fed to the AI, however, it still wouldn't turn into a SkyNet level opponent. After all, the future state of the game can, and does, change-- often it changes rather rapidly-- so the information about the future I'll be feeding the AI is accurate as far as the game knows at that time, but is not an actual foretelling of the future. The accuracy is futher limited by exactly how much information I've put into the future; it doesn't make sense to plan things too far out, because every time the situation changes most of the future data has been invalidated.
Given these conditions, however, I'm reasonably confident that the result will be an AI able to make better decisions.
I think the biggest benefit will be the common sense stuff, the kind of thing a player immediately knows from looking at a situation, but an AI might not. If a player looks at a scene and sees a large group of hostile units moving towards a weak one, they immediately know that they should move that weak unit. An AI could know this in a variety of ways, but many of the more common ones are expensive... if it can just peek ahead at the situation ten seconds in the future, though...
That's the area I plan to be exploring in code next week. We'll see how it goes.
If you'd like to chat on this or other topics, feel free to message me on twitter @JeckDev or leave a comment below. You can also subscribe to the mailing list for monthly email updates on what I'm doing. If you'd like to see what kind of content you can expect, you can check it out the latest newsletter here.
Sometimes, development on Starlight Revolution can be less flashy than normal. The big projects this week have been support stuff, important but not glamorous.
The major one, and something I'm still working on right now, includes changes to the way that game objects handle time. One of the major issues I've been having is that the creation and destruction of game objects has been an atemporal action, meaning that once an object was destroyed so was all its information.
This was fine when I was recording replays for strictly linear playback, because after a spaceship explodes we don't really care what its health was five minutes ago. However, I've decided that I'd like to support rewinding and skipping around replays, and that means I /do/ care what the health was, because I might rewind the replay to that point.
The end result of all this has been that I've restructured how game objects store data entirely. It's been a lot of work, without much visual progress to show, but now that it's started to shape up I'm quite happy with the end result.
If you'd like to chat on this or other topics, feel free to message me on twitter @JeckDev or leave a comment below. You can also subscribe to the mailing list for monthly email updates on what I'm doing. The second newsletter will be going out at the end of the month, so sign up quick! If you'd like to see what kind of content you can expect, you can check it out the prior newsletter here.