Skip to content

Script Systems & Components #244

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

Open
6 of 8 tasks
Tracked by #150
makspll opened this issue Feb 1, 2025 · 3 comments
Open
6 of 8 tasks
Tracked by #150

Script Systems & Components #244

makspll opened this issue Feb 1, 2025 · 3 comments
Labels
enhancement New feature or request

Comments

@makspll
Copy link
Owner

makspll commented Feb 1, 2025

The idea of using scripts as systems, i.e. having a script declare functions which act like systems, with specific dependencies on the world, and scheduling them in such a way that they can access the world safely

  • Dynamic world access system

  • Handler resources should have interior mutability at bms_core level, so systems can run in parallel if they access different scripts

  • Reflecting schedules and systems, querying the ordering

  • Dynamically injecting systems into bevy schedule safely

  • Injected systems to specify access ahead of time, and dynamic systems are parallelizable against other systems

  • Multi threading scripts not necessary

  • Command - Deferred versions of the WorldGuard bindings (i.e. insert_component_deferred + better warnings if aliasing is broken, geared towards script authors who might not know rust)

  • Allow specifying read/write access in script builder as an optional argument as well as for queries

@makspll
Copy link
Owner Author

makspll commented Feb 26, 2025

The linked PR, will allow us to create world guards compatibile with the schedule at the point of insertion, while it doesn't get us all the way there, it does solve the first part necessary in achieving script systems, I.e.:

  • syncing the accesses map with the bevy schedule

In theory, now even without a dynamic script insertion mechanism, you could have a number or "sync" points predefined by the author which could bootstrap script systems into specific parts of bevy.

The big limitation though is that if you insert a script at any point of the bevy schedule which accesses ANYTHING in the world, your script won't be able to get global access, I.e. it will have to schedule component insertions like a normal system

@makspll
Copy link
Owner Author

makspll commented Feb 28, 2025

Dynamically adding event handlers is now possible through: #335, including ordering constraints against rust systems

@makspll
Copy link
Owner Author

makspll commented Mar 11, 2025

This is very close with #361 working as expected

makspll added a commit that referenced this issue Mar 12, 2025
…rs & Schedule debugging utilities (#361)

# Summary
Major step towards #244 

- Adds a `bevy_system_reflection` crate to organize all the things that
would be nice to upstream to bevy eventually and aren't really core
logic
- Moves `ReflectSchedule` etc into that crate
- Adds a few more things to the reflected sets, schedules and systems
- Adds `DynamicSystemParam` enum which we use to store config for script
systems
- Adds `ScriptSystem` which can be converted into a system using the
`IntoSystem` trait via `ScriptSystemBuilder`
- The custom script system allows us to use default_system_sets
predictably for script systems, which previously all lived under the
same `SystemTypeSet` which didn't let us do ordering between them
- Adds utilities for script writers for printing dot graphs of system
schedules
- Splits `WorldGuard::new`  into `new_exclusive` and `new_non_exclusive`

# Example
this allows you to parameterize systems like:
```lua
    world.add_system(
        post_update_schedule,
        system_builder("my_parameterised_system", script_id)
            :resource(ResourceTypeA)
            :query(world.query():component(ComponentA):component(ComponentB))
            :resource(ResourceTypeB)
    )
```

and then have the callback run with those parameters passed in:
```lua
function my_parameterised_system(resourceA,query,resourceB)
    print("my_parameterised_system")
    runs[#runs + 1] = "my_non_exclusive_system"

    assert(resourceA ~= nil, "Expected to get resource but got nil")
    assert(query ~= nil, "Expected to get query but got nil")
    assert(resourceB ~= nil, "Expected to get resource but got nil")

    assert(#resourceA.bytes == 6, "Expected 6 bytes, got: " .. #resourceA.bytes)
    assert(resourceB.string == "Initial Value", "Expected 'Initial Value', got: " .. resourceB.string)
    assert(#query == 2, "Expected 3 results, got: " .. #query)
    for i,result in pairs(query) do
        components = result:components()
        assert(#components == 2, "Expected 2 components, got " .. #components)
        local componentA = components[1]
        local componentB = components[2]
        assert(componentA._1 == "Default", "Expected 'Default', got: " .. componentA._1)
        assert(componentB._1 == "Default", "Expected 'Default', got: " .. componentA._1)
    end
end
```

The system will setup a specially sandboxed world guard for the system
which only allows access to those set components and resources, this
combined with the archetype component access setup in the new system
type, allows us to parallelize against any other bevy system where there
are no overlaps in access!.

One can also create exclusive systems via `:exclusive` allowing a normal
uninhibiting world guard

Tests
    - [x] ordering between script systems
    - [x] exclusive & non exclusive systems 
    - [x] check these run in parallel as expected
    - [x] test scripts can only access resources and queries as expected
@makspll makspll moved this from Planned to In progress in BMS Roadmap Mar 16, 2025
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
Status: In progress
Development

No branches or pull requests

1 participant