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

Add System Priority Option to decide Order of Execution #11

Open
EriKWDev opened this issue Aug 13, 2021 · 5 comments
Open

Add System Priority Option to decide Order of Execution #11

EriKWDev opened this issue Aug 13, 2021 · 5 comments
Labels
enhancement New feature or request

Comments

@EriKWDev
Copy link

From the docs it says

Systems are added to the output of commitSystems in the order defineSystem is encountered.

It woul be nice if I instead could add something like a priority or order integer as an option upon creating the system. For example:

import polymorph

registerComponents defaultCompOpts:
  type
    Comp1 = object
    Comp2 = object


makeSystem "mySystem3", [Comp1, Comp2], EcsSysOptions(order: 9999):
  all:
    echo "s3: Comp1: ", item.comp1

makeSystem "mySystem1", EcsSysOptions(order: -1):
  all:
    echo "s1: Comp1: ", item.comp1

makeSystem "mySystem2", [Comp1, Comp2], EcsSysOptions(order: 10):
  all:
    echo "s2: Comp1: ", item.comp1

makeEcs()

commitSystems("run") # <- would sort systems on their order/priority upon generating their bodies

run() # <- Would execute systems in order System1, System2, System3 even though they were defined in a different order

I can see some problems though with this approach such as "What to do when a system isn't given an explicit priority?". I do not have a good answer to that. I suppose systems should be primarily sorted by the priority, and if none is given simply when they were defined like how they are now, though I do not know what that would look like in implementation.

This feature would help me if I define systems in different files and don't want to have to create a template each time and make sure the templates are put in place in the correct order.

I was working on my own macro ECS system when I discovered polymorph and you guys have much better performance than what I had managed xP So congrats and thanks for the module! I will switch to using it for my game :)

@rlipsc
Copy link
Owner

rlipsc commented Aug 16, 2021

Hi @EriKWDev, thanks for your suggestion!

I can see this fitting in quite well with the current control flow options.

I suppose systems should be primarily sorted by the priority, and if none is given simply when they were defined like how they are now

Yes, that makes sense. Systems would be ordered by the order/priority value, then definition order. If order is not explicitly set (i.e., the value in EcsSysOptions is zero), system definition order would prevail and backwards compatibility is maintained.

This feature would help me if I define systems in different files and don't want to have to create a template each time and make sure the templates are put in place in the correct order.

I don't know if this helps you in the mean time, but you can defineGroup to explicitly set the order manually for a subset of systems. These systems are removed from the output of commitSystems so you can pull out sets of systems to run before/after the main committed ones.

Another approach is to import modules with defineSystem without defining the system body, and import some or all of the body definitions separately. You can then use makeSystemBody and commitSystems piecemeal to output sets of systems as procedures. This still maintains the definition order, but as commitSystems skips systems without a body, you can impose your own order this way. This is detailed more in the system execution order section of the docs.

performance

Thanks! Performance is one of the stand out features of the ECS pattern in general and it's nice to hear that Polymorph is doing well there!

There are also a number of features and improvements in the pipeline (ahem) for speeding things up further as well, so things should only be getting faster!

@EriKWDev
Copy link
Author

Thank you for taking the time to respond.

I will experiment with defineSystem and come back with results. I imagine though that , since I want to separate systems into different files, the import order would still have to be correct then for the defineSystem-calls to come in the right order..?

Maybe I should just use templates like the documentation proposes.. xP

@rlipsc
Copy link
Owner

rlipsc commented Aug 19, 2021

Yes, the import order would matter for defining systems if you're not using templates as the order is set when they're first seen.

It might be easier to use defineGroup. For example, something like this:

# Module1

makeSystem "sys1", [A]: discard
makeSystem "sys2", [A, B, C]: discard
makeSystem "sys3", [A, B]: discard

# Group previously defined, ungrouped systems in the order they're defined.
# Here this would be sys1, sys2, sys3.
defineGroup "module1"
# Module2

makeSystem "sys5", [B]: discard
makeSystem "sys4", [B, C]: discard
makeSystem "sys6", [A, B, C]: discard

# Specify order for this group.
defineGroup "module2a", ["sys4", "sys5", "sys6"]

# ... define more systems

# Group the next set of systems in this module as they're seen.
defineGroup "module2b"
# Module3 (creating the ECS)

import componentdefs, module1, module2
export componentdefs

makeEcs()

commitGroup "module1", "module1"
commitGroup "module2a", "module2a"
commitGroup "module2b", "module2b"
commitSystems "runUngrouped"  # If any.
# Main module

import module3

# Execute module groups.
while true:
  module2b()
  module1()
  runUngrouped()
  module2a()

Hopefully this helps!

@EriKWDev
Copy link
Author

Yes, after some testing the groups are really useful and the most versatile. It's very nice because now I can run game logic systems on a quick loop with fixed timestep and have rendering in a separate group which can run on a variable rate.

I still think the order^ option could be useful for simpler setups.

@rlipsc
Copy link
Owner

rlipsc commented Aug 19, 2021

Excellent, good to hear! I will definitely keep in mind the ordering/priority for a future release.

@rlipsc rlipsc added the enhancement New feature or request label Mar 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants