2
\$\begingroup\$

Is there any way I can program (in Java or Python, but open to other solutions) some game logic based on events, timed and sent by player input, without dealing with it inside the game loop, by having a game state that has a number of scripts listening for events, and those scripts can themselves fire events that change the game states and by consequence the scripts listening for events? An example bellow

class BombScript {

    private GameObject bombReference;

    void bombDefused() {
        // change the script listening for events
        bombReference.destroy();
    }

    void bombExplode() {
        // launch some events, change the script listening for events
        stopListeningForEvent("bombDefused");
        bombReference.destroy();
        sendEvent("bombExplode", bombReference);
    }

    void bombPlanted() {
        // if somehow the server receives a defuse command
        onEvent("bombDefused").execute(bombDefused);

        // else, if 6 seconds pass without an "bombDefused" event
        onTimeout(6).execute(bombExplode); 
    }
}

I'm having trouble imagining a concrete implementation for that, specifically the timed based "if/else"

\$\endgroup\$
7
  • \$\begingroup\$ I believe it is possible to make an entire game without any game loop, though finding resources about this subject may prove quite difficult (game-loop based game being by far the most popular choice). \$\endgroup\$ Jun 22, 2015 at 18:05
  • 1
    \$\begingroup\$ The problem I see if you deal with it outside of the game loop, chances are they'll be treated at a bad moment: you might get data races, and it might be harder to debug. \$\endgroup\$
    – Vaillancourt
    Jun 22, 2015 at 18:07
  • \$\begingroup\$ Is that script for Unity? The solution you are looking for looks pretty much like the way Unity handles events. Although in Unity they are all handled in the main thread. \$\endgroup\$
    – zoran404
    Jun 22, 2015 at 18:24
  • 2
    \$\begingroup\$ Relevant: Event Queue Pattern \$\endgroup\$ Jun 22, 2015 at 18:32
  • 1
    \$\begingroup\$ If you are not using the physics engine it would be much better for performance if you don't use Unity (I'd use c# but java is good too. I think python is slower). But how you implement this depends on the specific problem you have. Best I can tell you is to follow the advice from @AlexandreDesbiens and queue the events and then call them from the main game loop. \$\endgroup\$
    – zoran404
    Jun 22, 2015 at 18:40

2 Answers 2

1
\$\begingroup\$

The way I've handled this in arc in the past - particularly for the JS version where you can't possibly avoid having to handle external events of various sorts - is to use a service that specifically acts as a proxy to the world outside the game loop. These services listen on the relevant event dispatcher(s) and stack up incoming events, which are popped off at the earliest opportunity by the controller class(es) (the main actors of the game loop in arc and can access any service) and handled thereby. You could handle one or more such events in a single game loop frame.

Using services neatly keeps this code away from your main game logic which - as you rightly indicate - shouldn't be polluted by external event loops.

One thing I will say about this is that if receiving game state from a server or peer, you will want those events to represent deltas, not absolute state since it becomes that much harder to update your local data model if you have to compare the last and current state objects (i.e. the events) just in order to determine what has changed... caused me some initial headaches.

This was tested in production for a client's real-time app, so I imagine it would work fine for you.

\$\endgroup\$
0
\$\begingroup\$

I'm not sure if you are asking about the implementation or the usage of an event based system, so I'll touch on both.

The implementation of event systems can be complex, and varies greatly depending on the language, but it is generally doable. The link above to the (excellent) Game Programming Patterns' article on the Event Queue is one hint to an implementation. The Observer (Delegate) pattern is also related; instead of binding to events passed by a mediator object, you bind directly to events fired by your objects.

After you have some building blocks, the game logic part is just that - logic. In your specific time-based example, here's what I'd do:

  1. Create a Timer class. It fires a single event: TimerExpired, when some given interval of time has elapsed after the timer is started.
  2. Create a Timer object in the BombScript class. In bombPlanted, initialize the timer with a time of 6 seconds and bind bombExplode to its TimerExpired event.
  3. In bombExplode, unbind from the bombDefused event (since that can't occur anymore) and explode the bomb. Additionally, reset the timer, but don't start it again.
  4. In bombDefused, unbind from the timer's TimerExpired event and reset the timer. Now, the timer won't fire.

I can see one big problem with dropping the game loop: things won't be able to happen without events firing. This is important for things like physics and AI, which must act independently of player input. Of course, you could just make a timer that fires every 60th of a second to update those systems - but that's basically just re-implementing the game loop. Barring those issues, I think it is possible (although, perhaps, difficult) to implement the server the way you are planning.

\$\endgroup\$
1
  • \$\begingroup\$ So do both: have a game loop that controls all the automatic stuff, but use an event system to respond to player input. \$\endgroup\$
    – jhocking
    Jul 22, 2015 at 21:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .