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

[FEATURE MODIFICATION] Prefab system compatible with atelier-assets #1894

Open
kabergstrom opened this issue Aug 20, 2019 · 0 comments

Comments

@kabergstrom
Copy link

commented Aug 20, 2019

Feature

Atelier-assets is almost at feature parity now. I think prefabs is the only missing existing feature, and naturally it has a bunch of other new shiny features that are not available in the current asset system.

I would like to introduce a design for a new prefab system that is inspired by Unity's latest iteration of prefabs. My idea is to implement this as an experimental feature in Amethyst that uses atelier-assets while keeping the existing prefab system as it is, perhaps the current one in the future.

Change/Design

Overview

From a user perspective, a prefab is a container of entities that can be instantiated in the ECS world. Translating this into the asset system, a prefab is an asset that references a set of other assets that each define an entity with its set of components.

The file format would look something like this, inspired by randomPoison's dynamic-prefab but extended.

Prefab(
    // Prefab AssetUuid
    id: "5fd8256d-db36-4fe2-8211-c7b3446e1927"
    objects: [
        // Inline definition of an entity and its components
        Entity(
             // Entity AssetUuid
             id: "62b3dbd1-56a8-469e-a262-41a66321da8b"
             // Component data and types
             components: [
                 {
                     // Component AssetTypeId
                     type: "d4b83227-d3f8-47f5-b026-db615fb41d31",
                     data: {
                         "translation": [0.0, 0.0, 5.0],
                         "scale": [ 2.0, 2.0, 2.0]
                     },
                 },
             ]
         ),
       // Embed the contents of another prefab in this prefab and override certain values
       PrefabReference(
             prefab_id: "14dec17f-ae14-40a3-8e44-e487fc423287",
             component_overrides: [
                 {
                      entity_id: "030389e7-7ded-4d1a-aca3-d6912b19116c",
                      // Override values of a component in an entity of the referenced prefab
                      overrides: [
                          {
                              component_type: "d4b83227-d3f8-47f5-b026-db615fb41d31",
                              path: "translation",
                              value: [1.0, 2.0, 3.0],
                          },
                          {
                              component_type: "3720f211-dc1b-413f-973a-6ffcd9f91598"
                              path: "parent",
                              value: "62b3dbd1-56a8-469e-a262-41a66321da8b",
                          },
                      ],
                 },
             ],
       )
    ]
)

Authoring a prefab

Ideally we create a tool for creating prefabs since it's really annoying to deal with UUIDs, overrides etc in the file. I don't expect anyone to author these files by hand.
I saw that Awpteamoose had a pretty cool Inspector-like tool in its nascent stages.

I think taking inspiration from Unity's UX will be good here.

"Cooking" a prefab

Resolving all these references, value overrides etc can get pretty expensive and complicated at runtime. To simplify loading and instantiation code, we should "cook" the prefab down to a simple collection of entities + components without overrides by copying all referenced entities into the prefab, apply all overrides etc. This can happen in the atelier-daemon in the build stage so that the runtime code can be kept simple.

Loading & instantiating a prefab

Loading a cooked prefab should be pretty simple as it becomes a single asset with a format that can be optimized for loading & instantiating. Handwaving a bit here, should dive deeper into how this format should look later.

Implementing overrides

Overrides is the key to making prefabs powerful, but is also the most complicated part in the system. There are two parts to making this work.

Value paths

We need to be able to address a field within a Component and serialize/deserialize only a set of fields. Rukai's treeflection already sort of does this. It uses Strings a bit more than I'd like, but maybe it can work out.

Value equality/diff

When authoring a prefab, we will most likely need to figure out which values of an instance of a prefab differ from the prefab template to be able to extract a set of override path/value pairs. We may be able to fork/modify treeflection for this, I am not sure yet. amethyst-inspector also does some proc macro magic to be able to affect values for fields, so we may be able to use that as inspiration too. Would love some help with this.

Reason

I want to implement a more powerful and easy-to-use prefab system that integrates well with the new asset system. This will make Amethyst scene authoring and management much nicer and enable some really cool tooling.

Impact

I think this can be implemented without impacting existing code, making it a backwards compatible change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.