1
\$\begingroup\$

A while ago I implemented a simple event-condition-action system for my game trying to emulate the Warcaft 3 trigger system (in a small scale, of course):

ignore the red circles

So far, it works fine, but there is something I have not been able to implement yet. It is the specific events or conditioned events (I don't know if there is a proper name for them). Following the example of the picture, a set of actions are performed if that event is triggered and matches the condition specified PLUS another condition within the event.

Every time I have worked with event systems, events (understanding them as event types) are non-mutable strings, ints, enums or any type of unique ids that allow subscription/mapping/etc. so someone else is notified. The way the system of the picture works clashes with what I know, as the event type can be "edited". What I mean is that, from my point of view, it seems there are two type of events in the example: "A unit dies" and "A unit owned by player 12 dies". But I'm almost sure it's not how it works.

Do systems like this one keep the same "constant event structure" as I conceive it and have an inner condition layer checking for that specific event? Do they work in a completely different way that I'm unaware? How, then?

\$\endgroup\$
  • \$\begingroup\$ Sorry, I didn't know that. I've just deleted the one in SO. Thanks for telling. \$\endgroup\$ – Miguel Garde Mar 21 '16 at 11:36
3
\$\begingroup\$

The event "A unit owned by player 12 dies" implies the "A unit dies" event. So there is no reason to have two different events.

You should only need a single "Unit death" event, but have that event include all the relevant information like which unit exactly got killed and what killed it.

You can then have the event receivers inspect that information about the event to decide whether or not to act on it:

HandleUnitDeathEvent(UnitDeathEvent event) {
    if (event.killedUnit == this.target) {
         if (event.killer == this) {
             say("Wohooo!");
         } else {
             say ("Hey, " + event.killer.name + "! Stop killstealing!");
         }
    }
    if (event.killedUnit == this) {
         say("Dammit, not again!");
    } 
    if (event.killedUnit.type == "Kobold") {
         say("I like seeing kobolds getting killed.");
    }
}

Or you could have your event dispatcher system implement the filtering to only forward those events which are relevant to a specific receiver.

\$\endgroup\$
  • \$\begingroup\$ I don't really like the idea of the receivers dealing with that internally because I want their behaviours to be editable. I do like, however, what you mentioned of the dispatcher filtering the events. But where and how should I evaluate whether the specific event has been triggered?. For example, if I had these rules: "A Unit dies" -> Narrator.say("Another soul vanished") "A unit of type Kobold dies" -> Player.say("God, how I hate Kobolds") I assume both actions (narrator's and player's) should subscribe to the "unit dies" event. But how will the dispatcher know when to notify the player? \$\endgroup\$ – Miguel Garde Mar 21 '16 at 13:12
  • \$\begingroup\$ @MiguelGarde When an object subscribes to the dispatcher, it could also provide a callback function which is used to filter which events are relevant. You could also have an parameter to the subscribe-method which tells the dispatcher the scope (all events of this type, only those which happen in distance x around me, only those which mention me directly, etc.). \$\endgroup\$ – Philipp Mar 21 '16 at 13:25
  • 1
    \$\begingroup\$ @MiguelGarde When you are planning to create a visual editor like the Warcraft 3 one, consider if it is really worth the effort. When you look at it you will notice that it is basically just a visual representation of some nested if ... else .... statements you could just as well program. The reason Blizzard did that effort is that they want to spare the end-users from having to learn a programming language. When this event system is just for internal use and your team is not that large, then doing it with code (maybe with an external scripting language) might be the better decision. \$\endgroup\$ – Philipp Mar 21 '16 at 15:02
  • \$\begingroup\$ The main reason I'm trying to achieve this with an editor is just for personal knowledge. Having a better understanding of how "the big ones"' approach works in order to have a basis for when I have to face a similar problem. \$\endgroup\$ – Miguel Garde Mar 21 '16 at 15:55
  • \$\begingroup\$ What you mentioned about the scope seems very clever. I will make the event filtering going in that direction. Thanks! \$\endgroup\$ – Miguel Garde Mar 21 '16 at 15:59

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.