« first day (4113 days earlier)      last day (897 days later) » 

2:16 PM
@DMGregory I actually implemented an archetype and it works great so far ^^ Iteration is blazing fast and well. Now i wanted to implement disabling/enabling components. It should be automatic, so i thought your second idea fits pretty good. But how would that look like in detail ?
Lets say thats our Archetype Archetype{ Transform[], Rotation[], Hit[]} and we wanna disable the Hit component of entity 0. You said it should be swapped to the inactive pile... how would that look like and whats that pile ? Could you give me one more example ? ^^ That would be great.
 
The swapping I described was for the case when you want to disable the whole entity.
If you want to disable a single component, I think the neatest method is to include an enabled/disabled flag on that component, check it, and skip it in your iteration loop.
Or you could consider removing the component (extracting the entity and adding it to another archetype without the excised component), and re-adding it if you later want to re-enable it. That gets trickier if the component has state you want to persist between cases.
Hmmm! Another thing you could try if you have only a few components that need this, is to add a marker component to indicate enabled states. So I have an archetype [Transform, Rotation, Hit] for inactive hits, and when I want to activate one I add a HitEnabled component, moving it to the archetype [Transform, Rotation, Hit, HitEnabled]
But coming back to your question about the piles, you'd keep an _activeCount on each archetype, in addition to _count, and maintain the invariant that the first _activeCount entries in the array are the active ones. Systems that care about active state should iterate over the first _activeCount items, not all _count living items.
When you want to deactivate an entity, you'll likely want to queue a request to do so at the end of the frame, so that entity indices don't move around in the middle of an ongoing operation. Then you swap the newly-deactivated entities' components with the last active entity's components in their respective arrays, and decrement _activeCount.
So the deactivated entity trades its index with an active one (possibly itself). Then you update any book-keeping that references entities so that they still point to the correct indices. To make this work, no other system should be allowed to hold onto an entity by index past the end of a frame, so it has to fetch the updated index next frame to always have the correct location.
Activating is the same thing in reverse.
 
@DMGregory Alright, thanks ^^ now i understand what you meant with pile :D i still wanna have that feature in an automatic way.
So i could either use an interface for each component like IActive which returns a bool to skip it in the query... or i could store some sort of entity information EntityInfo{ BitVector disabledComponents} and check that one to skip components in the iteration... or i could wrap all components in another struct which looks like this WrappedComponent<T>{ T component, bool disabled}. Which one of those ways is probably the smartest and most efficient one ? ^^
With the wrapped approach the archetypes would look like this Archetype{ WrappedComponent<Transform>[]...}
 
2:33 PM
I might call it a Toggleable<T> - it ends up working a bit like a nullable struct. But I still wouldn't apply it to every component type in an archetype - it should be something you request when it's needed and skip when it's not, like new Archetype(typeof(Transform), typeof(Toggleable<BoxCollider>)) for an entity that always has an active transform but has a collider that can turn on/off.
That way you only pay the cost (or have to type the extra toggleable.component) when you want it, and can skip it when it's not relevant.
Hmmm... you could even design your own ToggleableCollection<T> : IList, and have the archetype's components array store ILists that are either T[] or ToggleableCollection<T>s. That would let you give it an iteration method that automatically skips toggled-off items, rather than repeating that check in all systems that iterate the array. Might be more complexity than it's worth though.
(Note that even in that case, you'd still return the concrete types, not an interface, to avoid virtual call overhead)
 
Thats even a better idea :D So we only pay the price when we really need it. How would the queries work then ? Lets say we search for something like Transform, Rotation, Hit. This would exclude Toggleable<Hit>` i assume, right ? So we need to search explicit for Transform, Rotation, Toggleable<Hit> ? ^^
 
The system itself should know whether the update it does has an opt-out, and be able to select the component types it needs accordingly.
 
3:10 PM
Alright i guess thats actually the best way :D Just query for Player, Toggleable<Hit> iterating over them manually and check wether hit is enabled or not. Thanks ! ^^
 
 
3 hours later…
6:16 PM
A friend of mine posted on facebook during the weekend that he got out of the Gamedev industry because smaller companies only used Unity and Unreal, which did not offer him much possibilities for engine related work, and he's been burned out by bigger companies.
 
user92578
6:27 PM
@Tyyppi_77 "How do booleans work in Unity?"
 
6:47 PM
Voted to close as off-topic / general programming.
 
user92578
Nonono in Unity
 
😆
 

« first day (4113 days earlier)      last day (897 days later) »