Open marklundin opened 1 month ago
An additional note is to ensure that the order of component systems and their update execution is deterministic and consistent between runs and through the development while using various number of systems.
And how that would work is no ESM?
I think the order of execution is something the engine would specify which would be independent of the order in which they're added.
UMD build would just inline those imports, which means you lose the benefit of tree-shaking, but engine only users can just handle this in their own build tool.
I like this.
3. In both cases neither can be tree-shaken, as they're instantiated by the App
Three-shaking works in the engine only project at the moment. The AppBase does not import any components, and so the components the user does not provide when the AppBase is created can be tree-shaken.
Modifies the
addComponent()
to become async.
This feels like it would be pretty inconvenient to use, for both the users and as well the engine developers, where a lot of functionality would need to be made async to support this?
I'm not convinced by the dynamic import (though its a really cool idea) but I like the idea of the auto system instanciation
An alternative solution is to extend parameters addComponent
accepts to allow Component Classes too ie addComponent(CameraComponent)
. Then introduce a static system = CameraComponentSystem
in the component which is used to instantiate and register the system.
class MySystem {}
class MyComponent { static system = MySystem }
entity.addComponent(MyComponent)
The string syntax addComponent('camera')
would still be supported, so this is a non-breaking change. Strictly speaking this is a tight coupling between Component and System, but this already exist in the component lookup in the entity anyway.
An alternative solution is to extend parameters
addComponent
accepts to allow Component Classes too ieaddComponent(CameraComponent)
. Then introduce astatic system = CameraComponentSystem
in the component which is used to instantiate and register the system.class MySystem {} class MyComponent { static system = MySystem } entity.addComponent(MyComponent)
The string syntax
addComponent('camera')
would still be supported, so this is a non-breaking change. Strictly speaking this is a tight coupling between Component and System, but this already exist in the component lookup in the entity anyway.
That would require an additional import when using ESM?
The string syntax
addComponent('camera')
would still be supported
if the old way is still supported (and has to be for loading the scene from json), than this won't help with tree-shaking? What's the advantage then.
Editor project can be tree-shaken as we won't need to include the static list of every component systems in the start up script. Also for engine only it will simplify the boilerplate
Editor project can be tree-shaken as we won't need to include the static list of every component systems in the start up script. Also for engine only it will simplify the boilerplate
How you will ensure that the right component systems are in the engine, and avoid extra network file requests?
Editor projects are bundled, so unused modules can be excluded from the build.
but components can be added by string from scripts. Also the scene format has their names, and creates them by the string. How can you detect what is not used.
In order to do that for Editor there are few complexities:
The save from tree-shaking will be neglectable, complexity is huge, and if developers really need to save their tiny KBs, they can compile engine themselves excluding unnecessary component systems. Another branching in API with achieving same thing but a different way, leading to reduced learning curve long-term.
The original plan we had (and I don't see a better solution at the moment) is that somewhere in project settings, we'd have a list of components with checkboxes. By default all are ticked. User can untick some they don't need and the bundler will not import those components to tree-shake them. In a way equivalent to engine only project where we list those. Manual, but simple. Most people don't need to touch it, because as you said, the saving are minimal for majority of projects.
Before you can add a component to an entity, you currently need to register the component system with the app.
This has a couple of friction points:
An optimal solution would;
Proposal
Update the
addComponent()
method to resolve to a lazily loaded component system:Benefits of this approach
addComponent('camera')
systems
array.Cons
Modifies the
addComponent()
to become async. Strictly speaking this is a breaking change as it requiresawait addComponent()
which means a semantic major version bump.Other options
An alternative non breaking change would be to use statically imported components which are not async