big-brain
big-brain copied to clipboard
Thinker `ThinkerIterations` question
As I understand it, a thinker will run based on some ThinkerIterations
values, and will guarantee that the thinker run at least every 10ms, or when it cycles back on the frame count if time is not elapsed.
Is it possible to set this value somewhere ? as the current value is just the Default for ThinkerIterations
impl Default for ThinkerIterations {
fn default() -> Self {
Self::new(Duration::from_millis(10))
}
}
Also would this be applicable to Actions
as well, to avoid the ::Executing
on all entities every frame
I think I understood that the wrong way,
It seems like ThinkerIterations
is giving a frame budget of 10ms, in which case the thinkers not processed yet will be the next frame
Question still apply, is it possible to change that value ?
You can provide a ThinkerIterations
instance through the Local
API, as described here: https://docs.rs/bevy/latest/bevy/prelude/struct.Local.html, since ThinkerIterations
is public.
If I'm reading that Local
doc correctly, one would need to
- Make
ThinkerIterations
deriveResource
(which a consuming crate cannot do); and: - Manually register BigBrain's
thinker_system
inside a closure (but wouldn't the originalthinker_system
added byBigBrainPlugin
still be there and run as well?)
I could easily be missing something; either way an example on how to configure the value would help.
To take the original concern one step further though: I'm actually coming at this from a place of wanting to disable the feature entirely(for enhanced determinism), but after thinking about it some more, perhaps having any one global value might not be the way to go. I'm considering two primary categories of Thinkers:
- Important ones tied to game mechanics that ought to be more deterministic (ex: AI opponents' decision-making affects game difficulty; not something you want tied to system performance or time dilation)
- Non-important ones that add variety/flair (ex: NPCs with varying idle emotes/behaviours. If we can only manage to process 10% of those each frame, then sure, no real consequence there).
At first glance, it seems like the implementation would be pretty trivial to allow individual thinkers to opt in/out, indicating whether they can afford to be skipped: This line could be replaced with something like:
iterations_since_time_check += 1; //(initialised to `0` before the loop)
if ! thinker.is_important_or_whatever {
if already_skipping_flair { continue }; //(initialised to `false` before the loop)
if iterations_since_time_check % 500 == 0 {
iterations_since_time_check = 0;
if start.elapsed() > iterations.max_duration {
already_skipping_flair = true;
continue;
}
}
iterations.index += 1;
}
- (the existing maintenance at the end of the loop would be removed in lieu of the above)
- (the final
iterations.index = 0
would only be performedif !already_skipping_flair
)
What do you think?