#archived-dots
1 messages ยท Page 33 of 1
but i think it'd be an easy assumption to make as it's how it's worked so long
i've seen a few people ask aboutt the addjobhandle stuff
This works btw, thanks. I had to restart the editor though for it to refresh properly
hold up
if I use
SystemAPI.QueryBuilder
in OnUpdate
will it cache it in OnCreate instead?
Unity should mention whether method can run in OnUpdate ngl ๐
all systemapi methods can
from memory
/// Gives a fluent API for constructing EntityQueries similar to the EntityQueryBuilder. This API statically constructs the query as part of the system, and creates the query in the system's OnCreate.
/// Calling this method should allow for construction of EntityQueries with almost no run-time performance overhead."
/// </summary>
public static SystemAPIQueryBuilder QueryBuilder()```
just to confirm
Indeed, SystemAPI.QueryBuilder does caching in OnCreate you can always check sourcegen, when in doubt :3
Dude, I need this for type handles
I have already politely asked Dani for this ๐
will actually make things so much compact
Hehe :3
i feel somepoint soon, i'm going to be complaining that ISystem includes OnCreate/OnDestroy by default
as most of mine will be empty
and i'd prefer them to be like OnStart/OnStop running optional interface
Hopefully default implemented interfaces will fix that part!
for now, that's the best I could implement for short code
private ShipMovementJob _job;
protected override void OnCreate()
{
_job.ltws = GetComponentLookup<LocalToWorld>(true);
_job.entityTypeHandle = GetEntityTypeHandle();
_job.translationHandle = GetComponentTypeHandle<Translation>();
_job.rotationTypeHandle = GetComponentTypeHandle<Rotation>();
_job.gtpTypeHandle = GetComponentTypeHandle<GetToPoint>();
_job.shipHandle = GetComponentTypeHandle<ShipComp>(true);
_job.actionHandle = GetBufferTypeHandle<QueuedAction>();
}
protected override void OnUpdate()
{
var buffer = SystemAPI.GetSingleton<EndTickSimulationCommandBuffer.Singleton>()
.CreateCommandBuffer(World.Unmanaged);
_job.buffer = buffer.AsParallelWriter();
_job.ltws.Update(this);
_job.entityTypeHandle.Update(this);
_job.translationHandle.Update(this);
_job.rotationTypeHandle.Update(this);
_job.gtpTypeHandle.Update(this);
_job.shipHandle.Update(this);
_job.actionHandle.Update(this);
Dependency = _job.ScheduleParallel(SystemAPI.QueryBuilder()
.WithAllRW<QueuedAction>()
.WithAllRW<Translation>()
.WithAllRW<Rotation>()
.WithAllRW<GetToPoint>()
.WithAll<ShipComp>()
.Build(),
Dependency);
}
_job.ltws = GetComponentLookup<LocalToWorld>(true);
you could turn that into systemapi
but it's only saving 1 line
~~actually does it save any ~~
what method?
oh yeah it does
It'd save the update call
oh
SystemAPI.GetComponentLookup<LocalToWorld>
aspects will not help?
I'm still not sure if I should store my queries in the system or use QueryBuilder when scheduling the job
Well, it has no perf diff, so purely a design choice (only slightly on iteration time)
Yeah I know, I was talking design wise
i don't really wnat to do requireforupdate(query) in update
so that's the 1 thing that causes me on occasion to do it in oncreate
i can work around a lot of these though by simply using the attribute
I'm just was so busy with fixing project's conversion, selection system and all that stuff
I just now managed to get to converting all my IJobEntityWithBatch and systems xD
Couldn't you use the attribute? Or do you only want a specific query to match
Ah, I missed it
do aspects support type handles?
Aspects create typehandles :3
readonly partial struct SomeAspect : IAspect {
readonly RefRW<MyComponent> myComponentReference;
}
will make a SomeAspect.TypeHandle that is used in OnCreate and Updated at call site (that's what IJobEntity, Query, and even Entities.ForEach use)
And then you only get a single typehandle for the entire aspect instead of multiple?
Indeed
Alright, that's how I thought they worked, but I haven't used them yet
I still don't get how to get type handle
Tho, It's not a supported API to use any of the functionality we create as backing for Aspects (aka stuff like SomeAspect.TypeHandle and SomeAspect.EntityLookup is not something we will promise not to change, so be careful!), tho we do want to publically expose something in the future!
Indeed that's how to do it!. But again, it's one of the usecases we won't promise not to change in the future.
Try seeing the system code that is generated from doing:
OnUpdate(){
new myIJobEntityThatUsesSomeAspect().Schedule();
}
from a very quick look since i haven't looked at aspects yet, if you're doing things manually it seems to generate nice little structs for you
var aspectHandle = new ColliderAspect.TypeHandle(ref state, true);
// on update
aspectHandle.Update(ref state);
// in job
var resolved aspectHandle.Resolve(chunk);
for(var i = 0; i < chunk.length; i++)
var aspect = resolved[i];
oh, just like that?
But again, just like using InternalCompilerInterface is a not supported to use, this is danger, we might change it without warrant so is MyAspect.TypeHandle, MyAspect.ResolvedChunk and MyAspect.EntityLookup.
Not like that sentence stops people from using it, same goes for internal functions apperantly ugh... ๐
all people read is "... supported to use ..."
are buffers supported in aspects?
Here's your answer:
i was actually shocked how few extensions i wrote broke in 1.0 that relied on internal access
so yeah, buffers work
hm
why buffers are not defined
as RO or RW?
buffer type handles do require it
Indeed, they simply didn't get as much care as IComponentData 
What do they default to? RW?
so, they are just RW?
Yup
I'm guessing this is the same case for the Query API
Indeed, those are the two cases!
I'm guessing Aspects require compilation to get TypeHandle generated?
sadly my project has tons of errors rn xD
Haha they indeed do ๐
"Project has compile errors so won't code generate. Project needs code generation to not have compile errors" ๐
yeah, I'm afraid to get into one of those cycles
i think it's generally not an issue
About the system entity chunk fragmentation chat earlier, I wanted to add my 2 cents:
Maybe they will change the way system data is stored in the future. Why else would they: 1) make the system entity internal and give us specific overloads to access system data. 2) make queries discard systems by default. So I'd say lets just enjoy using system entities for now and hope unity fixes the chunk fragmentation issue for us later.
Luckily generators run before compilation so that indeed is not an issue :3
Ok I am somewhat confused. I seem to have borked something during install of entities and entities graphics somehow? I did a fresh install of the beta of 2022.2 and get lots of errors for the collections dependency?
And given the amount and type it seems like its literally not registering a package but the collections package was installed as a dependency, and no errors during install at all
have you restarted the editor since install?
not yet gonna try that now
try it, usually fixes such errors
given it misses keyword, I was wondering if its not linking properly
ok restarting boils it down to one error now.
Library\PackageCache\com.unity.2d.animation@9.0.0\Runtime\TransformAccessJob.cs(165,62): error CS1955: Non-invocable member 'NativeHashMap<int, TransformAccessJob.TransformData>.Count' cannot be used like a method.
that's a problem i have with my code generation. didn't really had the time to find solutions around it. i think having the source generator in pre-compiled dlls help
hmm, seems weird, maybe try restarting again lol idk
Tried several times now with no luck
that said it would be nice if unity respected asmdefs and compiles them even when the main source can't be
@gusty comet are you in an asmdef and missing the reference?
I have no clue what asmdef even is so I assume no
hehe, ok, then no asmdef ๐
Fresh unity install out of the box, clean new project, just added the two packages as per install instruction
api level on .net standard 2.1?
I have changed literally nothing.
What entities version are you using?
The one it fetched when I queried for com.unity.entities and com.unity.entities.graphics
So I'm guessing 1.0?
I don't think you can use entities@1.0.0-exp.8 with unity.2d.animation@9.0
The error you are getting is from the changed NativeHashMap API
I don't think the 2d package has been version matched to the entities 1.0 release
good catch, that seems most likely
Can I revert to an older version of unity.2d.animation
The package isn't released yet...
They promised 2d support for what... 2 years now?
maybe it would work to downgrade collections package?
Yes, and it's still not finished
The newest collections version is a dependency for entities 1.0, so I doubt that will work
oh ok
Where?
Yeah I am wondering the same thing
I don't think that was ever promised
Unless they mean project tiny or something
ever since the unity tiny release
they said that full 2d support will follow shortly
and 2 years is by no definition shortly.
where?
What's a good way to check if entity exists and is enabled from within IJobEntity?
you can downgrade to entities 0.51. if the package manager is not able to, edit the manifest.json in the packages folder
The entity that is currently being iterated as part of the Execute method?
No. Another one.
I specifically wanted to test baking which afair is not a thing in 0.51
the one part of execute has a component that has a Target of type Entity
just need to check if that target is alive each frame while target is set.
then use 1.0 and render with GOs and sprites
jason, you'd so that with a componentlookup
I mean how when the default installed 2d package breaks it?
Let me recommend that you request 2d support via the DOTS Product Roadmap - https://unity.com/roadmap/unity-platform/dots . That isn't a promise that it will be implemented in the future, but folks will see it.
It seems the Exists method was removed from component lookup for some reason though...
entityTypeHandle should check existance
oh wait
no, I mixed it up
lol
I will do that, thanks for the link.
kek
Wait until 1.0 is out of experimental, I assume the breaking code in the 2d package is fixed by then
HasComponent also works
But that would require the Target to have that component, otherwise there would be no difference between "alive" and "doesn't have component"
oh sorry, didn't catch that then - was just on mobile ๐
I guess you could check Translation if you aren't stripping them @drowsy pagoda
Simulate would probably also work
it would still work, HasComponent has Exists as first method call
Well yeah, but if it could be one of 5 archetypes with no overlapping components you'd have to check them all
So ideally something that is always on an entity
HasComponent and Exists have always been the same thing
I feel like there should be an explicit way to check for existence, simply from a semantic point to make what is happening clearer
why check for existance though
there is
if you have entity you most probably want some component on it
In case the entity was destroyed
not really, but HasComponent always called Exists. in 0.51 Exists was a standalone public method
so checking component should be the way I guess?
EntityStorageInfoLookup
they did the same thing
EntityStorageInfoLookup has
/// Reports whether the specified <see cref="Entity"/> instance still refers to a valid entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns>True if the entity exists and is valid, and returns false if
/// the Entity instance refers to an entity that has been destroyed.</returns>
public bool Exists(Entity entity)```
yeah, that works
[0.12.0] - 2020-05-27
Added BufferFromEntity.HasComponent(), with the same meaning as the existing .Exists() call (which is now 'deprecated).
Deprecated ComponentDataFromEntity.Exists(); Use .HasComponent() instead.
Exist had been deprecated for over 2 years
{
int index = entity.Index;
ValidateEntity(entity);
var versionMatches = m_VersionByEntity[index] == entity.Version;
var hasChunk = m_EntityInChunkByEntity[index].Chunk != null;
return versionMatches && hasChunk;
}``` it's a very seperate call though?
{
if (!Exists(entity))
return false;
var archetype = m_ArchetypeByEntity[entity.Index];
if (Hint.Unlikely(archetype != cache.Archetype))
cache.Update(archetype, type);
return cache.IndexInArchetype != -1;
}``` i don't know what you mean tertle
you're comparing component lookup vs entitystorage
i'm saying exists/hascomponent on componentfromentity were the same
^
it was literally just renamed from Exists to HasComponent in 0.12
the HasComponent is from ComponentLookup which calls Exists
yes?
^
which all funnel to EntityComponentStore
if you have an entity that only has a translation component and you call hascomponent on it for rotation
it will return false
if you call exists on it
it will return true
they have different usages
@drowsy pagoda so to answer the question use EntityStorageInfoLookup
and that is burst job safe right?
i haven't said anything different ๐ point is Exists is not accessible anymore on ComponentLookup. Should it even be there? Debatable. Unity removed it probably because of the overlap of EntityStorageInfoLookup
you're missing my point there
the old Exists on ComponentLookup was exactly the same as HasComponent
it didn't check if an entity exists (well it did but it also)
it checked if a component exists
it was simply renamed to HasComponent to clear up this confusion
i posted the code above. that's 2 very different things. nothing changed from 0.51 to 1.0
I think it's correct that it's been removed from ComponentLookup
It didn't make a lot of sense before
and i actually don't get it because one complaint i had is that HasComponent does an Exists check which is overhead when you in fact do know that the entity exists
unfortunately the SystemAPI doesn't work in IJobEntity for me.
you don't use it in IJobEntity
you use it in the system and pass it to IJobEntity
new myJob
{
StorageInfo = SystemAPI.GetComponentLookup(),
}.Schudule()
don't you mean Schedule
now HasComponent have been merged which i find quite annoying -.-
Oh it was renamed toSchudule
btw
careful there, I certainly do make mistakes
you saw nothing
hasn't there been anything about ability to move entity to existing one?
I really would love a feature to Instantiate entity into existing Index/Version
entities old god edition new myJob { StorageInfo = SystemAPI.GetComponentLookup(), }.sch'thulu()
new myLord
{
WorkshipInfo = SystemAPI.GetComponentLookup<Prayer>(),
}.sch'thulu()
๐คฃ
this just gets better and better ๐
that's weird, i did that and it's still giving me that failed generator error.
code
I am constructing the job from a SystemBase@OnUpdate, and inside OnUpdate there is a call to a private method that does that construction.
Have you tried making a sacrifice? ๐คฃ
I think that's not allowed with systemAPI, I could be wrong though
I think you might be right.
I'm gonna try changing private method to static. see if that does anything.
That won't work
it's easier if you post code
It needs the world to get the storage info
SystemAPI must be called from within a system
EntityManager.GetStorageInfo()
use that
No I can't because that's for a specific entity that I must know about
Actually, wrong one
I need this for a parallel job
I stripped code from that private method and placed it directly inside OnUpdate. Still same error!
Try CheckedStateRef.GetEntityStorageInfoLookup()
got it now, works in private method too. Basically you can't use SystemAPI inside a constructor. You have to use it only where you assign a variable directly. Then pass that var into the job construction.
Well yes, it has to be inside a system
yeah i would not really recommend using job constructors
Especially since it's just more code to write
code hating gang
less code = gud
soo...
I really need a feature
to instantiate entity into another
basically, so all systems can get reference to entity in OnCreate
but since it's loaded through SubScene
whatever is loaded will be assigned only after subscene loaded
Why do you need it in on create
because there's no other way (simple way) to get entity reference in ISystem
Read it from a component
unless you do if(entity= null) in OnUpdate
That you bake
IStartRunning?
which I hate
no.
besides
OnStartRunning is practically OnUpdate
for a lot of such cases, so
Not if you have requirements
a lot less so now that everything is alwaysupdate
by default now onstartrunning is much more like oncreate ๐
anyways, I still need this functionality
Why not put it on a baked component? Sounds infinitely easier
it's not /that/ hard to implement yourself
archetype.getcomponents
and dynamictypehandle
yeah, already looking into Instantiate
So you want to manually set index and version to get a reference to an entity?
no
I want to create singleton
with specific tag
and then once subScene is loaded
this singleton will change it's archetype and comp data to be clone of loaded entity
How will you keep the system from running before that is done?
systems depend on singleton which is created only after everything crucial like this is loaded
Why not just get that singleton then once everything has loaded
this is to avoid getting singletonEntity during OnUpdate
because that would require very complex callback for ISystems
Since your system is waiting you can use OnStartRunning to cache the entity
Once the subscene has loaded
easy with SystemBase
yeah i still don't get your hate with this but whatever it's doable!
we do something like this at work, we strip an existing entity back to no components then add a bunch of new components onto it to change it's archetype
superhard with ISystem
(this is done to have creatures morph into something new and allowing things that are already targeting them to keep targeting them)
yeah, in my case it's morphing entity, kek
Doesn't the entity reference stay the same even if you change the archetype?
yes
this is the whole point why I need it
thats the point, it stays the same things still target it
but we completely change what it is
give it a new prefab effectively
I'm guessing the reason for this is make it fast (instead of just a bunch of add / remove components)
it's unknown what components need to be removed/added
the larva becomes a butterfly kind of thing
for example here's one of use cases:
- some systems (mostly input related) rely on entity selection (just a square basically)
- I get or create singleton of that selection entity in OnCreate
- once it's actually loaded, I attach all data to that singleton
Profit
i mean, i disagree with the reasoning behind what issues wants to use it for but it's his architecture so he can set it up how he wants and it is totally doable and useful so it would be kind of nice to have a built in way to easily do this
for now I construct entity manually through code
but it broke after update
that's why I want to depend on conversion with SubScene instead
to get perfect graphics of selection I want
hmm
so there's Dynamic type handle for shared?
dynamictypehandle can be used for any component
even shared?
you dont need it for shared
there's a shared version instead ๐
DynamicSharedComponentTypeHandle
oh i missunderstood
basically what you need to do from top of my head
A.SetArchetype() from B components
Add some kind of filter component to either A/B to differentiate them chunks
Execute a job, get handles to A/B
Just iterate every component and memcpy using dynamic handles from B to A
no need for filter, I already know source and target entity
oh i guess you could just compare entities in the chunk
just remember to use dynamic handles you need to iterate the chunk
yeah, pretty much
not do a lookup on entity
wow sometimes DOTS drives me crazy I've suddenly got a whole system that's stopped running it was fine before and now suddenly its like "nah I'm fed up not running anymore" 
yeah, EntityManager.GetChunk() makes it pretty simple
what's funny is that it's potentially burst compatible
side note: if you want to get real low and dirty, you can do this without dynamic type handles
you just have to get really into the entity component store
would rather let dth resolve it for me
I think I've got a bug I don't understand this warning Ignoring invalid [UpdateAfter] attribute on PlayerDamageSystem targeting TurretAttackSystem.
at least that would be persistent between updates
they are both literally in the same group ๐
are they in the same world though
I only have one world I hope
Is there a way to run some specific code not if it's running as part of a test?
like a compile guard or something
elaborate?
basically ignore a piece of code if it's running as part of a test
what's the condition
compilation define
Is there one for unity tests?
no idea
it's an odd request because your tests are meant to be testing your runtime code!
i'm not sure [conditional] will work as it'd require a recompile
Yeah, it's an editor test that's instantiating a client system, and that system enables an input system, which I don't think is allowed in the editor
I think it might be Aline that's just breaking my whole project
odd
I keep getting a nativearray error not disposed from Aline when I'm just randomly compiling
Are you using it in editor code?
nope I don't think so
is it possible for a entities.foreach to be running but your just not getting any debug.logs from it? ๐
Its just bemusing I can see the system is running, the entities.foreach does not even though the entities exist for it
neh mind, sorry, its always me doing something stupid using a return instead of a break before the job 
Happens to the best of us
GetSingleton can't be a managed type?
and there doesn't seem to be a managed version
best is just
EntityManager.GetComponentObject<T>(GetSingletonEntity<T>())
and maybe write an extension method for it
Yeah I was just confused since everything else seems to be there
I still don't know if I should be running my tests as editor or play mode tests
play mode takes forever 
they serve different purposes
running nice, isolated editor tests for code coverage can help a lot on refactors and changes
but a set of intergration tests via play mode tests can provide better actual bug catching when things comes together
Why can't you run integration tests as an editor test?
Couldn't you just tick them manually? You want the test to abort after a certain amount of time anyways
tick what manually?
worlds
Yeah there's some stuff that's a bit trickier but I feel like ECS especially is easier to run integrations as editor tests
Do playmode tests do a domain reload between each test?
This sounds incredible useful. I currently need to do lots of entity swapping and it is quite annoying and error prone to update everything that references the old entity. It would be amazing if there was a way to change an entity's archetype in place. Even better if it could keep its old data (like translation and rotation) but only if the component exists on the new archeype. And any new components would just use the defaults from the prefab.
Hi all! I'm developing my new dots project using unity 2021.3.11f. I've got a trouble. Every first time entering the game after I recompile my code, the Unity gets no response forever until I shutdown it externally. After re-launch the unity, it can run successfully. But once I change my code and recompile, the next time when I enter the game, it gets stuck again. This is very annoying. I've checked the EditorLog, there is nothing helpful, every log seems normal. Anybody can help? Thanks!
Bit off topic but curious why if you were starting a new project you would target 0.51 and 2021.3 instead of 1.0 and 2022.2?
as for your issue, i'd suggest hooking up a debugger when it's stuck and force breaking to see what code it's looping in
yes it is
omg. Thanks!
Can I use my own BakingSystem to instantiate some prefabs before any other SystemBase initializes?
baking isn't during runtime. It happens in the editor before the game starts.
ah right....
But yes, you can set up prefabs in baking
If you want the prefabs to be there before OnCreate runs you probably need to do manual bootstrapping
Yeah, I am doing some manual bootstrapping, but running into a bunch of race conditions lol. Trying to synchronize it proper.
What race conditions are you running into?
I'd assume you just need to set up the scene loading systems first, tick them a few times to load your scenes, then instantiate everything else
Yeah, it's simple stuff, just wanted to funnel it all into one place so in case I need to bootstrap more stuff, I'd just drop it in that basket instead.
How do you handle resetting the world state between playmode tests? Just dispose of the world manually and then rebuild it before the next test runs?
this whole entity swapping thing would be somewhat easier when ecb createEntity would return valid entity ids
Would that even be possible?
i think the problem is with parallel creates
i don't do anything. each test runs separate play sessions
Doesn't that make it take ages to run all tests?
Also how do you even do that from a playmode test? I thought controlling the editor playmode state is only possible from within an editor test
the 3 tests i wrote at work take about 5 min to run
1 being load game, enter, save quit, load save
the 2 other are loading and faking things like player not spawning for a while etc
I'm kind of trying to figure out how I want to set it up. Either domain reload between playmode tests, don't domain reload between playmode tests and dispose and rebuild ECS state, or run it all in editor tests
I don't have a lot of gameobject logic
why do you need domain reloads
can you not enter play mode, exit play mode, enter play mode
without your game blowing up
Doesn't re-entering playing do a domain reload?
Really? I always get one when hitting play
since most people turn off domain reload
it's highly recommend tot urn off domain reload with entities
it significantly speeds up your iteration time
it's recommended by unity
I think that depends on how often you change code vs how often you enter play mode
Maybe for entities, but not for "normal" unity
i'm not talking about normal unity, we're in the dots channel
normal people use a lot of statics
I know, I wasn't sure if you were talking about dots exclusive when you said "most people"
fair
Anyways, can you just change the playmode state in a playmode test? What does that do if you run the playmode test standalone?
I don't really plan to, but I'm guessing that's editor only functionality
too time consuming to make a build to run tests
we have QA for that ๐
i suspect from what i understand
it'd work the same way though as editor
It'd restart the player?
it doesn't really leave play mode it kind of just resets it (maybe let me test)
Huh
so play mode tests runs it's own scene
then loads your scene into it
(this caused some issues with world startup time for me originally, i had to tweak some stuff)
here let me just run our tests quickly
i havent done this in like a year
(we run all these tests on dedicated machines anytime someone puts a pull request up)
(no one actually runs them themselves unless they fail)
yeah it never left playmode
In the editor?
yes
How are you resetting the ECS state then?
And it resets between each test?
// We want any error/exception to cause us to stop the test straight away
// Otherwise we could get in a situation where the test never ends
Application.logMessageReceived += (condition, trace, type) => {
if (type == LogType.Error || type == LogType.Exception) {
_fail = true;
}
};
yield return WaitForInit();
yield return RunTests(true);
}```
this is my test
WaitForInit waits for an event from
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
that's in our actual game
and RunTests just calls
StartGame
Save&Quit
LoadGame
Save&Quit
So all tests in RunTests are ran on the same ECS world state?
no
If I have two test files, and one loads the scene, loads my client and server world, and then another test without setup in a second file runs, the world is still there
I know with editor tests you can change the current editor play state (even if I can't for the life of me find the documentation for it right now, I saw it earlier...)
^
StartGame creates world
Save&Quit destroys world
it's just normal app cycle
Alright, then it makes more sense. I thought from the way you described it you were entering and exiting playmode in the tests and resetting world state that way (which would probably still be pretty fast with no domain reload on playmode entering)
(i did think it entered/exited play mode, but yeah only after testing it runs it in one go)
I guess both approaches would work. Yours is faster I'm guessing, the other approach is more robust against dangling static state (which shouldn't be there in the first place)
I'm still not sure how I should be handling unity scene references when moving system state to singletons
I guess caching them with stuff like Object.FindXXX variants would work, but I'm not sure if that's the best way
And alternative would be to have a single monobehaviour with the references and fetch that, but I'm not a huge fan of that either
I'm still not sure how I should be handling unity scene references when moving system state to singletons
what scene references? like subscenes?
If I just need something that's part of the unity scene
e.g. a UIDocument component for setting the root visual element or something
or the camera
oh
yeah the only thing in my scene is UIDocument
and i just do a FindObjectOfType in the root of the 1 system that cares about it
could probably register it as a singleton or something
but i've encapsulated it's to only 1 system
Alright. It's not a huge deal, it's mainly some leftover debugging stuff that uses the old ui system to display some textures
oh and my directional light just because its covenient when i open subscenes to have light
No Camera? 
nope
its converted
exists in a subscene
with all my cinemachine virtual cameras / brains etc
I thought it may have been a mainly aural experience
to explain the lack of a camera
Do you need to use the graphics package to convert a camera?
Or how does the baking system handle that
How is the graphics package btw? I haven't looked at it at all
yeah it sin graphics package
HYBRID_ENTITIES_CAMERA_CONVERSION
you need to define that though
apart from having it installed haven't looked
Hi all, after upgrading to Unity 2022.2.0 and using Entities 1.0, I get this compile error of Havok Physics:
Is there any compatible Havok package available for Entities 1.0?
no
I don't think it has been updated yet
Havok Physics for Unity to land directly with the pre-release: we made some adjustments to the pricing of Havok Physics for Unity that required a few changes. We chose to land all of it properly directly with the pre-release and skip the beta phase. More details on pricing here.
OK, I'll switch back to Unity Physics. It's fine
In Unity 2022 I often got this frustrating Hold on
Seems it will never end
Loading Entity Scene failed because the entity header file couldn't be resolved. This might be caused by a failed import of the entity scene. Please take a look at the SubScene MonoBehaviour that references this scene or at the asset import worker log xxx
๐ Subscene still not really stable yet
Yeah that happens sometimes
oh yeah that's still definitely a problem that needs fixing
yep, 1.0 needs a lot more clear entities cache than 0.51
Still not working after reboot unity... Can anybody help?
try clear your subscenes
apart from that really not sure
what is the mesh you are selecting
I have this weird issue again where my burst code throws an exception and non-burst doesn't, so annoying...
No idea why it pops up randomly
It's also ignoring all my breakpoints for some reason which really doesn't help...
removing everything and re-adding it does seems to fix the subscene issue, very annoying tho
make a build and crash in that
oddly easier to debug
Clear entity cache
Sometimes requires also to restart editor
Thx, I'll try
use typemanager
Can't find the method to get size
GetTypeInfo() first
ah, forgot about that one
@rotund token any idea what's next?
public static void InstantiateInto(this EntityManager em, Entity source, Entity target)
{
var sourceChunk = em.GetChunk(source);
var targetArchetype = sourceChunk.Archetype;
em.SetArchetype(target, targetArchetype);
var targetChunk = em.GetChunk(target);
var targetTypes = targetArchetype.GetComponentTypes();
foreach (var targetType in targetTypes)
{
if (targetType.IsZeroSized) continue;
var typeInfo = TypeManager.GetTypeInfo(targetType.TypeIndex);
var dynamicTypeHandle = em.GetDynamicComponentTypeHandle(targetType);
var componentData =
sourceChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeInfo.SizeInChunk);
}
}
Dynamic data array is readonly
Literally just get the target chunk and do a memcopy
You just need to figure out if index 0 or 1 is target or source by checking entity
One think i dont understand based on the documentation and the dots source code...
A archetype chunk is 16 kb right ? Does one chunk only store 16kb of one single component : [Health, Health, Health...] or does it basically store all the archetypes components but limited to 16 kb : [Entity, Entity, Entity], [Health, Health, Health], [Transform, Transform, Transform] ?
And when we query for Entity, Health for example, is then a new chunk being created ? If the purpose of a chunk is to fill the L1 cache, than it would make more sense to load only a 16 kb chunk of only Entity, Health therefore the chunk with Transform would waste L1 cache since transform isnt needed in the query... or how is this handled ?
but what if it's not 2 sized chunk
You told me when I asked yesterday you knew what was source vs target
I do
but how do I get memory pointer
to component data of specific entity in chunk?
for selected component type
Use entity type handle
To figure out indices of each entity
Then just read at the address + index * size of component
chunks are defragmented, right?
If I understand correctly, it will only pull the data u query instead of all the entire 16kb chunk goes into cache line
A chunk is layed out all component x, then all component y, then all component z etc
So does entities actually copy my queried data into a new chunk basically ?
Yes, guaranteed to be sequential
Queries don't make any changes
It just returns a pointer to start of each component
Alright, thanks ^^
so
I got my targetEntity index
do I still have to iterate over component types
or maybe I can simply copy over whole memory chunk
they're probably in same chunk
you dont need to iterate
you just access it directly
are components layed out per entity or per type in chunk?
as in, can I memcpy archetype chunk size based of index or?
literally just replied
it's just going to be
byte* componentPtr;
UnsafeUtility.MemCpy(componentPtr + destinationIndex * sizeOfComponent, componentPtr + sourceIndex * sizeOfComponent, sizeOfComponent)
something like that
where sourcePtr just = (byte*)componentData.GetUnsafePtr;
how do I get componentData though?
var componentData = sourceChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeInfo.SizeInChunk);
is that it?
it's readonly
which made me questioned
allthough
judging by source it's fine
it's created from existing memory based of bointer
what do you mean it's readonly
modifier
Btw what happens if an entity has theoretical so many components or so big ones that it does not fit into one chunk ?
you will crash
So there is actually a component (size) limit ? Unity does not handle such cases and increases the chunk size for example internally ?
chunk size is fixed
Well kinda interesting... i think such cases will never occur but however.
i've put more than 16kb on a single entity accidently
it's not hard with a buffer
though it has to be kind of intentional
(was trying to fully fill a chunk)
you won't crash in editor i should say, it will just error telling you
Hmmm... i could probably also crash it some day.
There tons of items in my game, recipes and other inventory/player related stuff.
When i attach that data to the player itself it could actually happen that it will blow up those 16kb at some point.
^^^^^
right
foreach (var targetType in targetTypes)
{
if (targetType.IsZeroSized) continue;
var typeInfo = TypeManager.GetTypeInfo(targetType.TypeIndex);
var typeSize = typeInfo.SizeInChunk;
var dynamicTypeHandle = em.GetDynamicComponentTypeHandle(targetType);
var sourceData =
sourceChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeSize);
var targetData =
targetChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeSize);
var sourcePtr = (byte*)sourceData.GetUnsafePtr();
var targetPtr = (byte*)targetData.GetUnsafePtr();
UnsafeUtility.MemCpy(targetPtr + targetEntityIndex * typeSize,
sourcePtr + sourceEntityIndex * typeSize,
typeSize);
}
so that should be it
this might not be related to dots, but i think dots is causing it
this method is being called by OnCreate by a system
right
is it possible that its being called so early that tilemap hasn't been initialized yet?
default behaviour of entities is to initialize world before scene has loaded
you can override this behaviour easy enough
oh okay cool was about to hack around this
add
UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD
to your defines
this is the default bootstrap
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Initialize()
{
DefaultWorldInitialization.Initialize("Default World", false);
GameObjectSceneUtility.AddGameObjectSceneReferences();
}
}```
(will be disabled with that define)
just copy/paste it and change BeforeSceneLoad to AfterSceneLoad
damn, how can I test this feature quick? ๐
I don't have anything setup for it
oh I know
yeah
OK actually before you do this
i forgot there's kind of a side effect
your subscenes won't auto load
i've disabled this behaviour long ago so i forget about this
the world needs to be created before MonoBehaviour.OnEnable runs for subscenes to be auto loaded
just use OnStartRunning?
thats one way
or create an entity with a tag
thats like
"create my shit"
and capture it on all the systems
would prefer not to do that
so gonna test OnStartRunning first
or...
or i just calculate world coordinates
without using tilemap
personally I just use this system
stops simulation/presentation updating
until the subscenes i need have loaded
(and now handles if you open/close them at runtime when it nukes your entities for a few frames)
just a universal, yep I need these subscenes before I can start playing
nice gotta create my own impl of something like this eventually
thanks for the example
i'm not certain how you do that if your shared components are managed
wait a second
hmmm
I feel like
there's an easier way to achieve it
๐ค
well
managed components do work
var em = state.EntityManager;
var e = em.CreateEntity(typeof(Translation));
var kek = em.CreateEntity(typeof(LocalToWorld), typeof(Transform));
em.SetName(e, "TestTargetEntity");
em.SetName(kek, "TestSourceEntity");
em.SetComponentData(kek, new LocalToWorld { Value = float4x4.identity });
em.SetComponentObject(kek, typeof(Transform), new GameObject().transform);
em.InstantiateInto(kek, e);
I tested it this way
gotta try it bursted
im not seeing a managed component?
Transform
same code I sent, nothing else
no burst though
wouldn't they be pointing to different things ๐ค
i didn't even expect managed components to be accessible this way
wonder if they're just stored as a collection of pointers in a chunk
i never really thought about how they were stored
so you just memcpy the pointer
makes sense
what i don't understand is how they'd pin this
oh yeah
at least, that's what I would do
yep that's totally what happens
it's same as scd
now you mention it i do recall seeing this implementation
whats the main culprit for something like this to happen?
tried to move things to OnStartRunning
and for some reason its not creating any entities
and its doubling up on the gameobject scene entity for some reason
protected override void OnStartRunning()
{
Debug.Log("OnStartRunning PlayerResourceSystem");
this.playerAddGoldQuery = EntityManager.CreateEntityQuery(typeof(PlayerAddGoldComponent));
this.playerAddLivesQuery = EntityManager.CreateEntityQuery(typeof(PlayerAddLivesComponent));
var entity = EntityManager.CreateEntity();
EntityManager.AddComponentData(entity, new PlayerAddGoldComponent() { Value = StartingGold });
}
pretty much all its doing
but burst compiled method will run regardless if it's burst compatible
I need log message to know
if it's bursted or not
you use burst discard for this
IsNotBursted(ref isNotBursted);
[BurstDiscard]
private void IsNotBursted(ref bool isNotBursted)
{
isNotBursted = true;
}```
something like that
ah, forgot about that trick
does terrain work with entities yet, or still not?
ah, thank you person who reacted!
[BurstCompile]
public static class TestKek
{
[BurstCompile]
public static void BreakStuff(ref EntityManager em, ref Entity a, ref Entity b)
{
em.InstantiateInto(a, b);
BurstCheck();
}
bruh, why direct call not getting bursted?
bruh
now it bursted
after 4 recompiles
well
managed comps copied over fine
with burst
nvm
I'd dumb
I started test before burst compiled
๐
and no, shared comps didn't copy
@rotund token kill me cs private void Start() { var defaultInjectionWorld = World.DefaultGameObjectInjectionWorld; defaultInjectionWorld.GetExistingSystem<GridSystem>().Initialize(); defaultInjectionWorld.GetExistingSystem<PlayerResourceSystem>().Initialize();
how i hacked around it
removed OnCreate/OnRunning from all systems
and just made a mb call them
(made it a method on the system)
probably find ive asked this before (sorry if i have....), but is there any builtin way to convert a regular array to a native array fast? Either that or get mesh vertices as a nativearray to begin with (basically just tryna convert mesh data to be in pointer arrays using those fast bursted job parallel for loop thingies)
There is UnsafeUtility.PinGCArrayAndGetDataAddress() and UnsafeUtility.ReleaseGCObject() if you want to use a normal array's pointer in a job
ooh thank you!
so in here, they explain there are two ways to deal with MeshData, the old way, based on copying arrays of data, and the new way built with dots and jobs in mind
it's a little bit of messing around with to get it sorted in your head but that should get you most of the way there
ok fascinating, dots may make things faster but wow it always makes what is usually 3 lines of code suddely become 10, if not more lol
yes, for mesh manipulation it's very worth it
dont really think im manipulating a mesh, just tryna convert the data to be in pointer arrays lol
Check this for inspiration: https://github.com/Per-Morten/UnityUtilities/blob/main/ViewAsNativeArrayExtensions.cs
unfortunately it appears that overwrites the pointer to a new location
@rotund token so, I found this
foreach (var targetType in targetTypes)
{
if (!targetType.IsSharedComponent) continue;
var handle = em.GetDynamicSharedComponentTypeHandle(targetType);
var sharedComponentIndex = sourceChunk.GetSharedComponentIndex(handle);
var access = em.GetCheckedEntityDataAccess();
var store = access->EntityComponentStore;
store->SetSharedComponentDataIndex(target, targetType, sharedComponentIndex);
}
What do you mean?
all pointers point to a location, and it appears that changes the location
Why do you think so?
wait nevermind, i misread it, sorry lol
yep, tons of errors
It's just pinning the managed array (not changing location) and building a nativearray from that
then you can dispose it to release the managed array again
oh ok fascinating
๐ฅ
looks like I did it
Entity instantiation into existing entity
burst compiled
btw Issue, wouldn't EntityManager.SwapComponents() also work? just swap the components with an empty entity?
oh, nvm, they must have same components
How is this even possible? Assert.IsNotNull(instance); // runs this line fine Assert.IsFalse(instance == null); // Throws here
ok i managed to get this working (i think?), but how would i do it for triangles? ```cs
VertsLooping VertJob = new VertsLooping();
VertJob.RWVerts = RWVertices;
using (var dataArray = Mesh.AcquireReadOnlyMeshData(TriMesh))
{
var data = dataArray[0];
var Verts = new NativeArray<Vector3>(TriMesh.vertexCount, Allocator.TempJob);
data.GetVertices(Verts);
VertJob.Verts = Verts;
}
JobHandle VertHandle = VertJob.Schedule(TriMesh.vertices.Length, BatchSize);
there aint any GetTriangles function it appears....
well you assert two opposite things
I do?
oh, hm
instance is a gameobject, only possibility is if they did something weird in equals overload i guess
I have more of a architectural question. How would you guys make a dots based mechanic where you can have many different modifiers on projectiles. Think how the binding of isaac works. A item can add fire damage to your shot and another can add splitting on impact and a third adds bouncyness. Would I have to make a component and a system for each modifier or how can I aproach this ?
Data.getindices/getindexdata to get your triangles
thanks a ton!
Anyone here got samples on how to use new input system with dots directly from input actions?
Probably bit flag the damage modifiers and remap enabled bits to indices so that a system can apply the damage logic upon projectile collision (off the top of my head)
It really depends on the kind of modifier what is best. If its just a damage type modifier, all that is required is basically an enum alongside the damage. For the projectiles I would probably have one system that handles the movement and collision detection, maybe the same system reads some metadata about the projectiles and handles bouncing and spawning of more projectiles if the splitting modifier.
@spice vale " reads some metadata about the projectiles and handles bouncing and spawning of more projectiles if the splitting modifier." But what is this metadata exactly ? A component ? Wont this result in a bunch of if(HasSplitOnImpact) if(HasBounce) etc etc ?
Yes, or you could make the projectile movement system spawn different events when it collides based on the modifiers and let separate systems react to those. But Imo why would you have a separate system for bounce? to me that seems like it should go in the movement system, its just a redirection of the velocity.
I'm not opposed to having the bounce be done in the same system, but how do I "notify this system" that I have picked up the bouncy bullets power up
Add a component to all bullet entities and then what? Do a if check in the system ?
yes why not?
I dont know why not.... I'm not experienced in dots at all. It's why Im asking
seems somehow redundant to be checking on possible thousands of bullets each time if we have a power up picked up or not
when you add the bouncy component to some projectiles, these projectiles will end up in a separate chunk, so in your movement system you can just check what kind of chunk you are processing atm and do the conditional on chunk level rather than per entity.
by using an IJobChunk
interesting. I was planing on having the bullets be pooled, so picking up a modifier will work on "non-active bullets" and when the active ones return to the pool they will get the new modifiers
if the bullets are entities you don't gain anything from pooling
you dont ? I know there is no garbage when you create entities but surely there must be some cost ?
I haven't done any performance testing but to my knowledge it is very cheap to create entities, and pooling is not advised for
do you have a link to resources going into why pooling is not advised ?
thanks
@rotund token ok, it works. Shared comps and managed comps. While burst compatible.
Nicely done
Btw hat happens if i delete an entity in the first archetype chunk ?
Will the next entity land up in that spot ? Or will that spot stay "unused" for ever ?
the last entity will take its spot
Yeah but... the last entity from all chunks ? Or the last entity from the chunk i deleted it from ?
from the chunk it was deleted from
Yeah but in this case the chunk has a unused spot ? Is that going to be unused for ever ? Im not sure if my question was well defined enough...
But each archetype has a list of chunks. Lets say our archetype has 5 of them, all of them are full...
Now we remove an entity from the first chunk. Is now the last entity from the fifth chunk moved into the first chunk and takes its place ?
Assuming the five chunks has an entity capacity of 100 each, when we delete the first entity of the first chunk, the entity that is last in the first chunk (index 99) will be moved to to the first spot (index 0)
Note that this index in the chunk is not the same as the index inside the entity struct
the last entity in that chunk will take deleted entity's spot
Yeah but than we have a gap in the first chunk since there now 99 used entities in there when there can actually fit 100 into...
And my question is, will this gap fill up when we add more entities ? Or will that chunk have one unused spot forever ?
that's how it avoids fragmentation
it will fill up
when you add entity to archetype, it fills all existing chunks before creating new
Ah finally, thanks... i just began to believe that at some point we could have like 5 chunks with only 5 used entities in it while the other 95 are still unused... that would be kinda bad
Chunks of same archetype are not guaranteed to be next to each other
you could
but that would be the result of removing entities
and you'd need to create enough for 5 chunks first
potentially
at some point in the future, we'll have chunk GC
๐คฃ
I mean... wouldnt it be smart to move the last entity from the last chunk into the removed spot ?
Would take the same amount of processing power and would instantly fill up the void being left over... so we will never have holes in our chunks... once the last chunk is empty, it could be disposed
actually, maybe thats how they do it, now I became unsure.
that's exactly what it does, but only inside chunk
are you sure about it? doing like genar said seems better
"but only inside chunk"
just not among whole archetype, only among chunk
Probably a communication problem exists here
what if you remove the last entity in a chunk ?
it's empty kek
so it's wasted space
yes
so why not move the last entity from the same archytype from the last non full chunk to that spot
^
if I understood genar correctly
Thanks, thats better explained
idk
Therefore, we would never have any gaps at all, wuuuu party
that's the task for unity
then again finding the last not fully filled chunk might be troublesome
do chunks have a isFull property ?
Not really... with that mechanic you would exactly know that the last chunk is always the one with space in it
I bet they have an array somewhere, so its a direct operation... not that complicated to get the last chunk then
here's the question
why it's probably not that simple
when you remove entity
it's only checking current chunk
I'm still very unsure how to design my bullet mechanic. What I want is basically what The Binding of Isaac does. Pick up a item -> Change bullet behaviour
so if you remove frist entity in chunk. You need to fill that slot
and you also suggest to fill that chunk from all other chunks?
based on which one is not filled?
sounds hella expensive
Not from all the other chunks, from the last one. That shouldnt be much more expensive. And the gap avoidance comes also in handy since it increases the cache friendliness
( You can stuff more of that current chunk into the l1 cache )
again how do we know this isnt what unity does under the hood?
No idea, its all blank speculation but pretty funny
source is right there
it's all C#
with comments
kek
can you like not kek on every other line? If reading the code is so simple go read it, comeback and end the discussion
checking right now, looks like they move the last entities in the same chunk
would love to know why they decided on this.
// Move component data from the end to where we deleted components
var startIndex = chunk->Count - patchCount;
ChunkDataUtility.Copy(chunk, startIndex, chunk, indexInChunk, patchCount);
ChunkDataUtility.CloneEnabledBits(chunk, startIndex, chunk, indexInChunk, patchCount);
var clearStartIndex = chunk->Count - batchCount;
ChunkDataUtility.ClearPaddingBits(chunk, clearStartIndex, batchCount);
I'd say
the reason behind it that if you do structural change on other chunk
it'll do order version and change filter version change
causing systems that rely on it run again on all entities in chunk
But you don't need to tick version of you just move them no?
but data is same
they are regardless
Guys, again a very noob question. I'm reading https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/DOTS_Guide/cheatsheet/jobs.md#ijob I thought that a system operates in parallels on the components of entities that match a query. Why would I schedule a IJobChunk from a System ?
no you need a job, system does nothing in itself
all systems run on main thread, in very precise order
To run code in parallel you need to schedule a job, yes
public void OnUpdate(ref SystemState state)
{
var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI);
+ // WithAll adds a constraint to the query, specifying that every entity should have such component.
+ foreach (var transform in SystemAPI.Query<TransformAspect>().WithAll<Turret>())
{
transform.RotateWorld(rotation);
}
}```
So this will run for each Turrent
on the main thread
so if I want to multithread my system
I would schedule a IJobEntity or IJobChunk from that system
it's very simple to implement, codegen based job
yeah
fun fact, none of actual code you wrote in OnUpdate is really executed xD
only codegen based on it will
I dont understand this
you mean that it gets compiled down by the burst compiller etc
not really, it gets codegened with .net code generators
they get codegened into other methods
smth like this
and they are actually what gets called
I..see
You can also just look at what was generated after the compiler ran in your IDE
I think that makes it a bit clearer
So.... what ECS gives me in terms of perf over lets say a Job with transform access is that entities are neatly stores and order in memory
ECS architectures is way easier to handle in large projects
what is it called?
right
data layout is only 1 part of entities. the data layout makes it easy to multi thread. the biggest performance gain is from burst.
I heard Raid Shadow legends chose ECS exactly for a reason, so that they keep project easy to mantain over time
I'm really starting to miss being able to select objects in the scene view while running, I have an errant cube sitting in the middle of scene no clue where its came from 
That works fine on my end
I'm on 0.51, does it work in 1.0 alpha then
yeah
is it difficult and a lot of trouble to upgrade
yeah
I'm still upgrading
xD
Lost quite a lot of functionality, took at lot to restore
still haven't gotten all of it back
yeah I think I'll stick with 0.51 for now
it seems like its better to just start a whole new project with 1.0
although I could just create a new project in 1.0 and then transfer scripts over one by one ๐ค
Are you keeping a list? Anything you can share?
not really, also it's not really your fault
it's because I heavily relied on RenderMesh
and since it's gone... welp
xD
Thanks, just like to help people know what they're getting into before they start an upgrade attempt
I do need help though, because I just can't understand the idea behind RenderMeshArray and MaterialMeshInfo
var mesh = rma.GetMesh(mmi);
for example this is 100% of all times is null
so I temporarily rely on this var mesh = rma.Meshes[mmi.Mesh - 2];
Which also doesn't work all the time
What is the intended way to signal another system in a high performance way now that state should exist on components? a NativeStream?
Native stream can only be written to once, I'd use a list or a custom collection instead if you want to be able to write from more than one other system
You need to re-create it after writing to it once? 
after you end the for each index you can't open that index again
Not even if I close it?
close?
There's a function to signal that reading has ended
.EndForEachIndex()
That one
But a single thread can share the reader right?
I mean you can read in parallel too
I just need something to signal to another system that something has happened, but I'd rather not create entities for this
I guess an alternative would be to compile a function pointer and store that in the component
do you need a list? why not just set a system's singleton
It's a method atm called by another system that takes arguments, and it can be called multiple times per frame
so if you don't need to write to this in parallel i'd go with a nativelist on a component on the system's entity
Sure, that'd be possible, but then anything that can grab that list could also clear it for example
Yeah that's unavoidable i guess
I'll try the function pointer route and see how I like it
Nevermind, the function uses managed types ๐
list it is
I guess the "classical" way of avoiding this issue is making the native list private in the component and adding methods to it, but the DOTS crusaders would probably object to that
I was going to suggest that, but realized that the system would not be able to clear the list then
Sure, if the component is inside the system, then it has access to the fields
Oh
Alternative would be to put it outside the system and make it internal
but internal is quite broad
Yeah, that's why I'm putting it in the system ๐
well if that works that's excellent
I also like the namespacing more that way
e.g. MySystemName.State
instead of MySystemNameState
It's the same thing the ECB systems do, e.g. EndSimulationCommandBufferSystem.Singleton
State can be public inside the system
and if you want to hide something inside state, that needs to be private, hiding it from both the system and anything else.
You're right, my bad, I was thinking the other way around
e.g. accessing private state on the system inside the component inside the system
I'd have said yes, NativeStream is the way to go. Only thing is NativeStreams feel quite awkward in a Singleton NativeContainer. Still, nothing wrong with it. it'll outperform a simple NativeList unless the list is persistent
How do you work with them though? You need to recreate them each frame?
yes
Write everything, then read?
yeah
so with e.g. WorldUpdateAllocator or something