I'm considering developing a space opera game, having already done some game design. Technically, though, I'm coming from a business applications background. Hence I don't really know how I should handle time and duration.

Let's state the matter clearly: what if something is bound to happen in 5 hours and on which other events depend.

For example the arrival of some space ship in some system where some defense systems are present, hence a fight would start.

The aim is to do some web application, so with multiple nodes for better scalability and the like. Hence a single loop on one node wouldn't do it. Should there be a master node or are they some better known solution?

Furthermore, the loop in itself doesn't resolve this duration issue: between firing of the event on its ends, many loops happen. Does it mean every loop should check such "waiting" actions?

Should I use some kind of scheduler (like Quartz in my java land) to trigger the corresponding event when due (I plan to use events for communication)? Something else?

  • \$\begingroup\$ By space opera You mean this? \$\endgroup\$ – user712092 Jul 11 '11 at 11:07
  • \$\begingroup\$ In which language or game kit are You planing to make it? \$\endgroup\$ – user712092 Jul 11 '11 at 11:19
  • \$\begingroup\$ hum, by space opera I just mean a game with planets/ships and the like. Nothing about some old RPG. For the language, it's Scala on the server side. \$\endgroup\$ – space borg Jul 29 '11 at 21:58

Most games centre around a 'game step' loop. Things happen in discrete pacels of time.

It is straightforward to have a queue of future events and to consume those events for each game step.

More about game time-steps on the gafferongames blog.

| improve this answer | |
  • \$\begingroup\$ I also read the document <a href="gafferongames.com/2010/01/24/… every programmer needs to know about game networking</a>. Very nice, but really FPS oriented => I edit my original post \$\endgroup\$ – space borg Jan 31 '11 at 22:29
  • \$\begingroup\$ @borg I just add working link \$\endgroup\$ – user712092 Jul 11 '11 at 11:21

Just record your game time, add it to a variable, once the variable gets to a certain amount, fire your event.

| improve this answer | |
  • \$\begingroup\$ quite unclear :$ Mind to elaborate a bit more? How do you do the "once the variable gets to a certain amount" part? \$\endgroup\$ – space borg Jan 31 '11 at 22:33
  • 2
    \$\begingroup\$ if( currentTotalTime > timeWhenSomethingHappens ) { /* do something */ } \$\endgroup\$ – Tetrad Feb 1 '11 at 0:02
  • 2
    \$\begingroup\$ @borg: This is assuming you have a main game loop. \$\endgroup\$ – Richard Marskell - Drackir Feb 1 '11 at 4:43

What you need is a priority queue with the time of event as priority. If you create an event that will happen in 5 hours, you add it to the priority queue; it will probably be inserted somewhere in the back as in 5 hours has a low priority. Your main event-loop will constantly work on your priority queue and will check if the priority of first even is now. If so, it will trigger the event. After 5 hours, your event will become the event with the highest priority in the queue and will be the first element. This will make the event-loop trigger the event. If the ship has exploded in the mean-time, you need to make sure that the event is removed from the queue... ;)

| improve this answer | |
  • \$\begingroup\$ Better than removing it from the queue is having the event check if the ship has exploded. (This means you avoid race/synchronization issues with removing and executing at the same time etc). \$\endgroup\$ – Tim B Apr 18 '16 at 11:26

What kind of web application is it?

Is it one that runs all the time, as a continuous process? If so, simply do this with a standard game loop:

while app_still_running:
    check queue of pending events
    while the next pending event is due now:
        execute event
    sleep(some reasonable duration)

You may need to run this in a background thread if the rest of your app is event-driven: if so, be sure to put a lock around the whole event so that everything stays consistent.

Or, is the web app one that only runs when you visit a page? (eg. like a PHP app?) If so, you can have an entry at the top of each page which checks if events are due, and if so, process them at that point before rendering the rest of the page. It's basically the same thing, except done just-in-time instead of periodically.

Either way, the idea is to push events onto a queue and read them off in order. If you just have one process, this can be a queue data structure. If you have multiple processes, it's probably best to have them in a database and use a sorted query to collect them. (Though be careful to ensure multiple processes can't both read the same events.)

There is probably no reason why a single loop on one node isn't good enough for your purposes. You can designate one node as the master for performing all this. Or you can store pending events in the database and just have the various nodes grabbing a handful of events via a transaction. On the whole though your scalability problems will not be at the business logic end.

As far as consistency across nodes is concerned, where one node is processing an event but another is displaying or editing data relevant to that event, that's an issue for database transactions and the like. If you cache anything, you are pretty much throwing away consistency, so you have to make decisions over what can be cached, and what cannot. That starts to get outside the scope of this particular problem however.

| improve this answer | |
  • \$\begingroup\$ I was about to wrote the same solution. :) +1 \$\endgroup\$ – user712092 Jul 11 '11 at 11:19
  • \$\begingroup\$ I'm not settled yet for the framework. Anyway, server side always running for sure (Scala land) + event driven as well for sure (using #eventsourced). Funny in the end how your suggestion matches Rich Hickey Datomic :) Sounds good ;) \$\endgroup\$ – space borg Jun 12 '13 at 20:15

You usually have some kind of "main loop" in your game that runs continuosly.

Depending on wether your game is multithreaded or not, this "main loop" looks different.

In a single threaded environment, your main loop usually looks like this

time = current time
while game is running
    deltaTime = (current time) - time
    // custom logic
    // e.g. updating the AI etc.
    // or polling input
    // or polling sockets when networking is involved
    render current state to screen
    sleep some reasonable amount

You would typically advance your simulation using the time delta. This allows your user to speed up or slow down the game as well (just multiply the delta with a time factor, e.g. 2, and the game runs twice as fast [but especially when physics are involved, might lose precision]).

You can simply add a priority-queue sorted by the (game) time an event should be done, and then check the top elements of the queue. If the time for the event is reached, execute it, otherwise sop iterating over the queue (if it is sorted by time, no other event can come).

In a multi-threaded system this gets a bit harder, but you typically enqueue things in the main thread then.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.