-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AbstractGroup
s
#15
Comments
Hi, Awesome that you're enjoying the package! So What usecase are you thinking of? |
i see, thanks for the explanation. i'm considering making a trigger resolution system that process entities representing triggered abilities. still brainstorming idea, so this is pretty rough. i've come up with two ways to go about it: first is to have a triggered ability by represented by an entity which has a parametric component type the second way is to have two components, respectively containing the trigger type (e.g. like an empty |
Interesting, is it similar to what I'm doing here to have some sort of "modal" system for tui's? Is it a specific entity has a specific ability triggered, or more that an ability is "active" influence the whole board or world let's say. EDIT: From the point of using groups for this, I don't think that's going to help you here, it really is just another "bookkeeping" tool |
yeah, i think it's somewhat similar. this part is pretty cool; i came up with something kind of similar struct TriggerAware{T<:System} <: System
system::T
end
Overseer.requested_components(s::TriggerAware{T}) where {T} = (TriggerComponent, requested_components(s.system)...)
function Overseer.update(s::TriggerAware{T}, m::AbstractLedger) where {T}
update(s.system, m)
while !isempty(@entities_in(m[TriggerComponent]))
update(TriggerSystem(), m)
end
end as someone trying out ECS for the first time, i was under the impression that having a system calling another system is a big "no no". good to see it's not that bad, ha. in my case an ability is owned by an entity and is triggered by an event. for example, at the beginning of a turn, a cat deals 7 damage to a random enemy, or something to that effect. |
Well, technically it kind of is and you should have either one system for each possible event or one system with if-else for each possibility. If you want something more flexible I'm not sure you can do it any other way. The reason I was designing it like this is that it would potentially allow users to more easily specify tui modes etc. I'm not set on it yet. In your case, I'm not sure there is much benefit to do this over just having one system for each event that loops over entities with the components linked to that event. I'd probably actually recommend doing that, what is the reason for not going that way? In a game usually you can update everything each turn, or each render loop. |
i'm not sure, but my thinking is, a triggered ability (could be triggered by a variety of things, "a friend in front attacks" or "an enemy was hurt") can have arbitrary effects, which may trigger another ability. and those nested triggered abilities need to be resolved in the update loop they are generated in. so triggered abilities are like a global queue that's emptied before each system call. i think having my |
Oh I see what you mean. Yea it's kind of trying to solve the problem reactively, which is not at the moment exactly well-supported indeed. What you're suggesting and what I've kind of done in tuiseer is getting close to that. Now still, I'd suggest to also just try having a set of systems that would "trigger" an ability by putting the right component, which then would be seen during the next update loop by the next system that takes it and puts the components signalling triggered abilities that it takes care of there. |
yeah, i thought about putting everything in messaging components and update them in future loops, but now in each loop (for example, |
Well, that is sort of the beauty of ECS to some degree, you have “no control” but that also means you don’t need to have control. I mean, a system will just be doing nothing unless it finds the right combo of components to then do something with. If these are one time things, using for example @safe_entities_in together with pop! Makes sure that next time it doesn’t iterate again over the same things. You can be even more explicit/fast by just having an early exit isempty return construct checking the component(s) the system acts on. |
interesting, that makes sense. will try to code for both versions and run some bench. thanks for your thoughts! |
This is basically what I do in Gamoji. Sometimes it requires fiddling with the order of stages a bit. But generally I've found it to be fine and fairly transparent. I'm generally very concrete with my systems, I tend not to want a lot of abstraction other than what the ECS itself provides. I wouldn't try to do standard reactive programming (ie, wiring causes and effects together) with an ECS. In fact I feel that doesn't work that well anyway for games because effects from one system can be fairly global and in general can propagate for multiple time ticks. I believe this is a feature of ECS though: it encourages you to think of systems as the "physics of the game world" - ie, generally the laws by which the game operates. Generally, thinking this way leads to
|
yeah, that's the dream for sure. along the same line i think ECS has difficulty when these laws of the game world cannot easily be captured cleanly in a regular system: system execution order, stage/mode transition (which is more for performance's sake than anything else, i think). system only interact through components, but the way they do is substantively determined by these meta-laws. spitballing here: to abstract away system interaction through execution order, ideally a game's behavior should be execution order agnostic; perhaps every system in a loop can operate on the same old state, produce |
I have found that indeed mostly this is actually the case (the execution order agnosticity). The reason for a given execution order is just because then certain things happen without delay, waiting for the next loop. In the real world the loop is continuous and every “system” and result happens instantaneously and so the problem of execution order of systems doesn’t at all matter. I’d say, at least in most of the things I’ve coded up, it doesn’t matter when which system runs, just that then certain effects take one frame more to appear. EDIT: “results are instantaneous in physics” well this is a lie, but you understand what I mean 😅 |
Yes that could work in the context of a particular game and systems. I don't think any mechanism is really general because game rules are some weird mixture of
Systems with arbitrary high level logic do sometimes interact with each other a little weirdly. I feel like... that's a fact of life? And some case by case fixes just need to be made in those situations. But also that ECS allows such code to be relatively well factored regardless of the occasional difficulty. For the "actual physics", the right and fully consistent thing to do is to treat all coupled systems as one big set of differential equations. But IIUC people tend to separate such systems into tightly coupled updates (which go into individual systems and are integrated together with a purpose built solver), and loosely coupled updates (which go into separate systems and only communicate at the game's tick rate) |
@c42f Do you often run into the situation where the exact order of the system execution matters for the actual behavior, or mostly of how fast results take effects (i.e. this tick or next tick)?
Do you have an example of this in Gameoji? |
I have had trouble with ordering in the past but I can't remember the exact detail. The game previously triggered updates only when keyboard events occurred so in that case it does matter more. I've since moved to time-based updates though so it might not be such a problem now. My memory is a bit hazy to be honest! I haven't looked at the code for quite some time now. |
Oh I see, yes then it for sure would matter.
…On Fri, Aug 12, 2022, 21:16 c42f ***@***.***> wrote:
I have had trouble with ordering in the past but I can't remember the
exact detail. The game previously triggered updates only when keyboard
events occurred so in that case it does matter more. I've since moved to
time-based updates though so it might not be such a problem now. My memory
is a bit hazy to be honest! I haven't looked at the code for quite some
time now.
—
Reply to this email directly, view it on GitHub
<#15 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AFCD32OYMDIBSN662DNDBGTVY2WLJANCNFSM554P6SWA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
hi!
i've been enjoying
Overseer.jl
a lot for writing an auto-battler. thanks for the good work.could you explain a little how to use
AbstractGroup
? i think i might have a use case that would be made easier with it, but having looked at the source code, i'm still not totally sure what's going on and what it's meant to do. thanks a bunch.The text was updated successfully, but these errors were encountered: