Suggested patterns for declaring and detecting event triggers?

Started by
2 comments, last by Roots 7 years, 9 months ago

Hi everyone. I've got a 2D RPG written in C++ and Lua with a custom game engine. I've been designing some more complicated environments in the game, and in the process I discovered a big technical limitation in the way we detect when important things happen that make us want to process a change. I'll call these triggers. When a condition is triggered, we want to fire off an event (that may in turn fire other events). My issues are not with the event system or processing, but rather checking when those triggers happen and firing the appropriate event.

How it works right now

It's pretty basic right now. Every map has an Update() function written in Lua. In the update function, we execute a series of conditional statements (the triggers) and if they are true, fire off the correct event. At this time, this is pretty much limited to checking if a sprite is located within a zone (we define zones simply as a section of the map). If it is, we fire the event. If there's something that we only want to occur once (say, a section of a cave collapses), then we register a string/value pair in a global event manager that keeps track of the fact that this event already happened.

Here's what it looks like in practice.


    if (GlobalEvents:DoesEventExist("passage_collapsed") == false) then
        if (zones["collapse"]:IsPlayerSpriteEntering() == true) then
            GlobalEvents:AddNewEvent("passage_collapsed", 1);
            EventManager:StartEvent(event_chains["passage_collapse"]);
        end
    end

Limitations

There are other things that I want to be able to trigger events in addition to just checking the position of objects on a map. For example, when the player presses the action button and was facing a certain interactable object. Or when the player collides into a locked door, to play sound. This one is particularly hard right now as collision dection and resolution is done completely in the backend of our map code and the results are not available to the map script at all. It seems kind of silly and inelegant to just have a big list of if statements listed in a function that we check on every update loop of the game.

I've been doing some reading on my own to see if I can get some ideas for a pattern or design that would work better in terms of flexibility. Right now I'm considering the Observer pattern. I'm hoping to hear some opinions on what sort of system you all may have tried to solve similar problems, or point me at what articles I should read or other designs I should consider. Thanks

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

Advertisement

Wouldn't simple event handlers in Lua suffice? They could be simple functions (per map probably) that are called if the backend raises an event:

function ButtonPushed( ButtonName )
  -- do something
end
 
function TriggerAreaEntered( AreaName )
  -- do something else
end

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Your issue is that you are using events as resources.

When you have a module named "EventManager" you arleady know that something is messed up.

Usually global or "manager" modules are bad anti-patterns.

The observer pattern is the classic way to implement a "subscriber-subscription" kind of relation and when implementating events that's what you want.

I'd enscapulate it into a a different module to use, and not "EventManager". Because this is not how you handle events.

Make sure to make it generic to reuse it.

I think that's a great suggestion, and I like how simple it is. However I'm wondering if it would be better to have it build a queue of events that occurred (button pushes, sprite movement, etc) when the map is doing its update operation. Then when the map script does it's own update, it looks at all of the events and their properties and decides if something needs to be done. That way we aren't making a function call from C++ into Lua on every single move/collision/whatever. Still thinking about it though.

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

This topic is closed to new replies.

Advertisement