Attack, series of delayed events. Would like some input

I’m making lightweight objects that represent weapons being fired by an “attacker”, targeting a “destructible”. It’s for a game. The setup is fairly simple.



Just a short description of the system: Gunfire, and all kinds of attacks basically is wrapped in an “attack” object. The weapons themselves are just a bunch of data and has no functionality. Each class has a different set of attacks and abilities etc. If I choose to fire against a target, I do it by performing an action (an attack).



The attack object contains some data, a reference to the weapon that was used and what the target is, among other things. It has an update method, as several steps needs to be performed over a period of time. Currently, all active attack-actions are stored in a list, and the attacker is responsible for updating it. Gonna use a separate manager later.



So basically…



If I perform the attack (by pressing a key for example), this normally happens:


  1. The object is created. The preAttack stuff is carried out (like if there’s a charge up time requried), and it’s put in a list for updates every frame.


  2. When the pre-attack phase is done, or if there’s no preAttack, it’ll step forward to executing the actual attack. It might trigger a muzzle flare, recoil, and perhaps some other effects. Create rockets and stuff. Also during each step there are of course the appropriate checks, make sure that the target is still alive, that the ability is ready and all that.


  3. The attack hits the target. It could be timed, or triggered by a collision with a projectile or w/e (tho I only used timed effects so far). It can also be repeated continously or a number of times if it’s an auto attack or a DoT effect, for example.



    The attack is fully resolved at this time (hit/miss is calculated, damage is done, checks are done to see that the target is still alive and a valid target etc.).


  4. There is a postAttack method, in case something extra has to happen after the attack is finished.



    When the final step is done, or if it failsat any of the earlier stages, the attack is flagged as “done” and is removed from the active list and thrown away.





    Just curious if anyone has done something similar and had some insights they’d like to share. Or if someone would like to discuss something regarding their own system. Nuts and bolts stuff.. I developed this system from experiences with old MUDs and stuff, so it’s not that fresh… but it works.

Sounds like very specific code in the objects, did you think about using an ES for this?

I have something similar for a game I’m working on. It’s not ES at all though.



There are 2 characters standing in front of each other.

We initiate a dice roll (dice handled with bullet), and if the roll is a success we play a list of “events”.



An Event has a target (one of the 2 characters) can be an animation, an effect (usually particle emitters) or what ever (even damage score popping on the target is handled like that).

each event handles its own run() methods that makes it execute.

Events are chained by an event manager.

for Chaining i use a “momentum” that is the moment when the next event should start.

for example let’s say you have a “slashing” animation for a character and a “getHit” animation on another. You can’t play the whole slashing anim then play the “getHit” or it won’t feel natural. The getHit has to start when the weapon hit the target. That’s the momentum.

I put the momentum in userData of the model or of the effect (usually a node containing particles) so i just have to read this when scheduling events in the event manager.

This system is flexible enough to do w/e you want and give good results.

Also it’s very targeted to my own needs for this game, and I guess this kind of system is really game specific.

@nehon

Ok we’re doing basically the same thing. Events are like runnables etc., and there’s a manager. Thanks.



I don’t quite get what a momentum is tho, but I’m guessing its something similar. My “attack objects” are simple FSMs, you could say. They are objects created when an attack is made. The flow is coded into these objects, and they in turn contain an array of events (one for each state), tho they can be null. The attack event continues to be updated and run until reaching the end state.



There’s one machine class for auto attacks, one for simple fire and forget attack, one for dots etc. As I mentioned, the attack objects are handled by the attacker now, but that’s of course going to change, and there’ll be a manager much like the event manager to handle attacks. I’m thinking about making the manager handle the flow by linking each incoming attack object to a flow/logic controller, making attack objects nothing more then containers for events. In fact I’m gonna do that right now.



It’s a typical hierarchical oo system btw, mine as well.

Tried to make a sketch.



http://jamtlandoutdoors.se/images/dist2/Attack.png



In the top is what it would look if the events just followed one after the other, like in a successful regular fire and forget attack. Each event does it combat stuff, and also may trigger stuff like particle effects etc., and send those to the regular event manager.



The bottom is the auto attack flow control. If the check succeeds (target is valid etc.) it’ll just keep attacking regularly until the cycle is broken (maybe changing targets, or the current target dies, or the attacker dies etc.).



EDIT: The attack “sub events” all happen in the attack object atm. tho, which I guess is wrong. An attack sub-event is basically just a bunch of regular effects + some damage/combat calculations. Maybe encapsulate all of that into regular events to be run in the regular event manager, alongside everything else. Calculating damage isn’t that different from doing a particle effect I guess, or playing a sound. It’s just a way to keep the event manager less cluttered, as many events are prevented from ever reaching it due to the checks done directly in the attack object.

Replace “event” with “component” and “manager” with “system” and its an ES :wink: Anyway how do you plan to thread this? Event systems normally execute on the event dispatch thread, or are you going to use queues as the “every x sec” suggests?"

Talking about the Design of such an EventSystem, I my self have to design such EventSystem once for Cinematic and AdvanceParticle, and also felt in to mistake those “EntitySystem” and “EventSystem”. Are those things different, well, not really but just make your self clear because…

First, Entity system some how a “data-driven” one, but maybe in this discussion it’s NOT…



In some games, a system like this is not light weight at all because It should carry and oporate the whole game! It have to answer the whole “who-what-when-how” question its controlled “entities” want to know?

WHO do WHAT? - The system has to know which entity have to do what action, HOW its should do it, and WHEN to call it to start or finish.

In your case, it may be simpler because it just for the attack actions but let make it clear how much information the EventSystem have to answer its asker, every frame or every cycle!



Why we have to answer those question, let’s me explain my self a little bit, arcording to how the system answer its asker, we can devide them into:

Type1: Answer all:

=> In this kind of system, you have a full-ledged EntitySystem, in which, the entities depend on so call “System” to manage and oporate them. Two (or more) sub types:

A: call their execute() or update(). <= Just like our JME3 Spatial Controls

B: just look a several entities of interests and take their data int System.execute()



Type2 to typeN: Not answer all, the entities have to ask some “things” outside of the system to know 1-3 other answer they want to know.



Let take one example. A system just answer question WHO and WHEN: Maybe it’s @androlo system.

Various AttackActions (which are in form of Events) are sent to a EventManager (Queued “System”).

  • Two types of Start behaviors: Triggered (when a logic conditions sattified) and Timed ( every n frame …).
  • The system also in charge of updating its Actions every frame or cycle.

    So the 2 question above WHO and WHEN have been answered! And the Action itseft know how to act in every frame in update(). Call-back functions of the Action let the system know its progress once they are started.

    Other scenario is the Action has “quite” a fix route. So the system also take care of driving it:



    Action{

    start()…

    update()

    reachPoint()

    hit()

    miss()

    finish()…

    }

    That’s the HOW question!

    In my game RPG and RTS one, I start by learning the Effect system of WarCralf in which also has a “Fixed” route! Then I ask my self should scale it to EntitySystem architect or not. In the end, I decided not to use EntitySystem and just use a simplier one like @androlo system. It’s a note (a political one) that :



    If you want your entities to be more intelligent, more flexible… they also have to be less controlled by the system, and have to know more informations outside of the system.



    Then it cannot be lightweight!

OK thanks all for all the input. And the clarifications.



@normen

I have not worked with the threading yet, at all. There are no separate update loops for the event manager etc., events are just added and executed, and updated every frame if there is need to update. Events are basically just a way to organize the code at this point, and to prepare it for a more sophisticated system later (maybe even network based one).



@atomix

Thank you, I like this What When etc. Makes it a bit more clear.


In the end, I decided not to use EntitySystem and just use a simplier one


That's good to hear. Then at least someone has made an "informed decision" not to use an entity-based system.
@atomix said:
In my game RPG and RTS one, I start by learning the Effect system of WarCralf in which also has a "Fixed" route! Then I ask my self should scale it to EntitySystem architect or not. In the end, I decided not to use EntitySystem and just use a simplier one like @androlo system. It's a note (a political one) that :


It's probably good that you decided not to use an entity system. Based on your description, you didn't really understand the point of them and have attributed qualities to them that are not part of an entity system... so probably best avoided.
1 Like

I think I have stitched this together a bit better now. A combat manager now handles all combat instead of the combatants. Also, instead of making “combat logic controls” i made a general “chained event logic control”. It is basically an abstract FSM class with generic state-types that can be used for all chained events, combat-related or not. The combat logic controls are just specialized versions of these. They use the combat event manager instead of the regular one, and does damage calculations etc. on top of the normal stuff.



A trivial example of a chained event could be a 3 step process, firing off three related events in succession. Fuse burning - firework shooting - firework exploding, for example. The FSM just changes states from maybe 0 to 1 to 2 at times x, y and z. There’s a standard N step control for simple stuff like that.



Just to clarify - an event in this game is something that happens :o. It can be a particle effect, an animation, an attack. Pretty much anything that changes the “game state” in one way or another. I’m not sure what the correct definition is, but that’s how I think of them. Regular movement and stuff isn’t necessarily events in the system tho, like the vehicle doesn’t fire off a bunch of events every time you steer it etc. It’s just stuff I consider “big” enough to warrant their own objects. That may have to change later i suppose…