Skip to content
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

Thinker ThinkerIterations question #74

Open
constructigogo opened this issue Mar 13, 2023 · 3 comments
Open

Thinker ThinkerIterations question #74

constructigogo opened this issue Mar 13, 2023 · 3 comments

Comments

@constructigogo
Copy link

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

@constructigogo
Copy link
Author

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 ?

@zkat
Copy link
Owner

zkat commented Mar 13, 2023

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.

@rs017991
Copy link

rs017991 commented Dec 5, 2023

If I'm reading that Local doc correctly, one would need to

  1. Make ThinkerIterations derive Resource (which a consuming crate cannot do); and:
  2. Manually register BigBrain's thinker_system inside a closure (but wouldn't the original thinker_system added by BigBrainPlugin 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:

  1. 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)
  2. 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;
}

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants