Scene Graph Feedback Thread

The definition for GetCreativeObjectsWithTag<native><public>(Tag:tag)<transacts>:[]creative_object_interface being a global function is actually a bug and is going to have to be fixed at some point in the future. Global functions in Verse are defined as being “truly global”, as in, they are looking at all instances of Verse running everywhere at once. So by Verse’s definition GetCreativeObjectsWithTag would actually have to be returning every creative object in every running island, which obviously wouldn’t be feasible. The entity version is scoped such that you are only looking at entities related to InEntity which is much more logical.

1 Like

There is no guaranteed order currently. The system is likely consistent in the way it initializes and ticks things but it doesn’t yet make guarantees that that order will be stable release-to-release.

1 Like

Perhaps tie it to the session then? After all, one would like to query for specific entities or devices within a server, no matter how global scope is defined.

Individual servers are also not a concept that can or ever will be exposed to Verse. The Verse language is being designed to scale to the ideas of a future metaverse, where we have an always-on, persistent 3d world that spans any number of servers or server clusters. While this doesn’t exist today the plan is that in the future we would be able to have interconnected experiences, where code/data/objects from multiple creators can all interact together seamlessly. Verse is designed with those ideas in mind, which is why there is no implicit running context exposed to the APIs, as any context we locked into at the language/API design now would have to be broken to achieve these goals in the future.

1 Like

Thanks for calling this out @Cleverlike_Studios. We’ve logged this and will be taking a look. Definitely something we want to sort out.

1 Like

This is good to know. It looks like the editor will auto re-inject the component when there’s also something like a mesh_compnent, but with purely own components the transform_component can be fully removed in the editor. :tada: Great little trick.

[QUESTION] Since the mesh representation via the scene graph might be somewhat different then actor based mesh components, I was wondering. Why is there not “mobility” setting for the entity? (static, stationary, movable) This setting does affect certain aspects of the engine as far as I know (shadows, light, HLOD builder, etc.).

Just for my sanity check. This means that in the future there will be a replacement available where we can properly configure and predict the streaming behaviour and not rely on the current FN relevancy? I guess the “fn relevancy system” is fn specific, but not a general streaming solution.

  • A follow up question. Is there a ruff approximation you can provide on how entities currently affect fn memory calculation?
  • Is the mesh data always loaded into memory even when the mesh is not being relevant for rendering, or will it free up that memory during that phase?
  • Do two entities with the same mesh and material equal x2 memory usage?

No information yet on memory characteristics. The system hasn’t been optimized and there are a lot of inefficiencies in the implementation that we will be addressing.

In terms of two entities = 2x the memory it isn’t quite that. Just like with devices the underlying resources you’re referencing are only loaded once, so the first usage of something brings the memory up the most since those resources are also loaded. After that there is a flat per-instance cost which for now you can assume would go up linearly with each instance used. This won’t always be the case in the system but in its unoptimized form that’s roughly what’s happening.

1 Like

Slightly off-topic: Could possibly shortly answer if there is a difference between such a flat per instance cost compared to an ISM? What would ISM do better than the mentioned flat instance optimization? Is the flat instance optimization more CPU bound than the ISM which is GPU optimized?

Scene graph is here and I’m excited! Thanks for the hard work and I can’t wait to see each new update.

The biggest feedback would be that I wish there were more examples of Verse in the documentation. With all the known issues, I’m not sure if I’m doing something wrong or its just a bug
For example:

  • Adding an entity to another entity: does a parent constraint component get created automatically? Is it meant to attach and follow the transforms?
  • Initializing a component and adding it to an entity: When you initialize a component it requires an Entity does that mean it is already added? or do I define the entity and then AddComponent afterward?
  • Relative Transform/World Transform: When an entity is attached to each other, if I set transform on the child, is it relative or world?
1 Like

Hey @TomJank. Examples definitely seem like a good idea. I’ll pass along the request to the documentation team.

In terms of the questions you posted:

Adding an entity to another entity: does a parent constraint component get created automatically? Is it meant to attach and follow the transforms?

When creating entities from Verse nothing is automatically done for the programmer. The entity that you add will be blank, not even containing a transform_component. This felt like the cleanest setup since there are so many different use cases for entities, that forcing one specific archetype of components all the time would often not be the correct choice for what you might be doing. On the editor side the tools do automatically inject a few components because we can generally tell in those workflows what the users intention was, such as dragging something into the world likely needing a transform.

Initializing a component and adding it to an entity: When you initialize a component it requires an Entity does that mean it is already added? or do I define the entity and then AddComponent afterward?

You’ll have to do both. Right now you need to provide the backpointer from component to entity since Verse needs to know there is a valid parent pointer. Calling ParentEntity.AddEntities(...) after will then set up the relationship of parent->child and will start moving the components through their lifetime functions.

# NOTE: Must cast each item to `component` right now to work around a Verse bug when building the array

# Example 1: Creating components on individual lines
NewEntity := entity{}
TransformComp := transform_component{ Entity := NewEntity }
ParentComp := parent_constraint_component{ Entity := NewEntity }
NewEntity.AddComponents of array:
    component(TransformComp)
    component(ParentComp)

# Example 2: Adding and creating components together
NewEntity := entity{}
NewEntity.AddComponents of array:
    component(transform_component{ Entity := NewEntity })
    component(parent_constraint_component{ Entity := NewEntity })

Also, in the future when Verse’s lenient evaluation semantics all come online you’ll no longer need to manually set the back pointer to Entity; Verse will be able to determine that itself based on unification with the AddComponents call.

Relative Transform/World Transform: When an entity is attached to each other, if I set transform on the child, is it relative or world?

transform_component.SetTransfrom is always setting the world transform. However, if there is also a relative transform through the parent_constraint_component (not yet exposed to users but that is coming) then the relative transform will be updated automatically to match the new positioning.

3 Likes

Thanks for the response! This is extremely helpful!

In regards to adding an entity to another in verse, what if the entity already exists in the space? In order for it to “attach,” I would assume you need to make parent constraint for the child because nothing comes for free when doing it in verse?

also the adding and creating together does not seem to be working with the complier

1 Like

In regards to adding an entity to another in verse, what if the entity already exists in the space? In order for it to “attach,” I would assume you need to make parent constraint for the child because nothing comes for free when doing it in verse?

The first thing to remember is that entity parenting (the AddEntity or AddComponents) on its own only controls the lifetime of the entities. If the parent entity is destroyed, all child entities will also be destroyed with it. When it comes to other relationships, such as transforms moving together between parent and child entities, this is controlled through another means, which in this example is the parent_constraint_component.

You have the option of making it so that child entities automatically update their position when the parent updates its position by adding a parent_constraint_component. However, if you wanted the child entities to not care about the parent transform and just be positioned with a world position, then you could choose not to add a parent_constraint_component. A good example of this might be if you had a prefab that had a few NPCs inside it (in the future when that’s a thing). You likely want the NPCs to be able to wander the world independent of the parent position. The added benefit of not having the parent_constraint here is that less processing needs to be done to re-calculate positions, saving some CPU time during each frame update. We’ll also be adding other types of transform constraints in the future, such as positioning an entity from a socket, another entity, or physics constraints like building a rope bridge.

also the adding and creating together does not seem to be working with the complier

That’s my bad. There is a Verse compiler bug that has been fixed but isn’t out in this release. I’ve updated my original post with the correct code that works around the bug so anyone else reading it won’t hit the compile error.

2 Likes

Request for the upcoming feature:

Another request which would enable a ton of cool applications:

@Incredulous_Hulk during the live stream you’ve said that there are technical reasons for not permitting modifications of actors that are promoted into a SG prefab via the bridge_component. (Here’s this clip.)

Why is there such a hard restriction?

The problem I see with that is when I bridge a fortnite device at point of time A and later on the same device gets new additional settings added to it, I will not able to go to my prefabs and set that new settings. I will be forced to delete all existing prefabs with that device and redo everything from scratch. For the majority of use cases this might be easy as I imagine many people will only have a few prefabs for certain fortnite devices. However I’m already in a situation where I want to create 100+ permutations of a certain device with all it’s settings. The device of my interest also sometimes gets new settings exposed, which will lead to the problem I just mentioned. I will have to delete all prefab permutations and recreate everything again.

Regular SG native prefabs can be easily overriden, but prefabs with bridges fortnite devices can’t. This is going to be very painful UX for some of us.

If the prefab editor does not permit such functionality, here’s an alternative proposal:

  • let us place the prefab into the scene
  • let us update the bridged actor
  • provide a button on the prefab entity to update / save the values back into the prefab
  • profit :tada:

While I’m not able to articulate all of the reasons behind this current limitation, as there are quite a few things to sort out, I can provide some insight into some of the bigger limitations we’re working through.

  1. Actors use the UE delta serialization system. To bring the scene graph to life we created a new override serialization system which replaces delta serialization. The override serialization is how we can allow all the layers of overrides between prefabs in prefabs (in prefabs…). Moving actors, which are the underlying tech of devices, over to override serialization is a huge change that couldn’t be done in any short time frame.
  2. The prefab editor uses a lot of different editor tech from the level editor. One such change is that the outliner and details panel between the two are not the same and don’t yet support the same functionality, of which displaying actors and their components is a big piece. We’re working to bring these to parity but its going to take quite a while until that is ready.

That said we’ll be continuing to look at interoperability opportunities and how we can smooth out some of the roughest edges to help teams move to the scene graph more fluidly.

2 Likes

[request] I would like to be able to register devices in the Shene Graph and have them dynamically generated from the Verse (e.g., call a player reference from the Verse so that when a button is pressed, the player reference spawns at the player’s location).

That’s on their near future release todo. It should be possible via the upcoming bridge_component. You will be able to create prefabs with any fortnite derived actors. This will include fortnite devices. Last but not least there will be a way to obtain the reference to the devices on such bridged entity component.

Suggestion for the Scene Graph icons.

  • The override inside icon is confusing. Its meaning is clear, but the icon is strange.
  • Keep the icons consistent and minimal, hence remove the + from the unique override.

The “override inside” is simple because it just shows that not all values are overridden, hence the circle is not fully filled. override insidepartial override

“Unique override” is not really an override, it’s a component that has been added to the pre-placed entity. Therefore it represents a “new” state, which why a green circle would make sense. It can even be further extended:

  • green circle outline: new with partial overrides
  • full green circle: new with all values overridden

image

  • gray circle outline: no override on the component or value
  • blue circle outline: partial override on the existing component or value with more sub-values
  • blue filled circle: all values are overridden, the existing component is fully overridden with all its values
  • green circle outline: newly added component (not part of a prefab) with partial overrides
  • green filled circle: newly added component (not part of a prefab) with all its values being fully overridden

Note: Overrides on new components are still blue. Only the new component is marked green.

1 Like