#archived-dots

1 messages ยท Page 12 of 1

rotund token
#

it is then async loaded when you open a subscene

#

so yes, it can take multiple frames to load

timber ivy
rotund token
#

when you call load subscene

#

it gives you an async handle

#

you need to wait till that is done before doing anything

timber ivy
#

yeah im in the process of doing that now but issue mentioned it didn't work like that so I just wanted to clarify before I continued

rotund token
#

alternatively you shouldn't even do this at all

#

you should just be doing this with jobs/queries

#

when the entity exists

#

the job will run

#

if not

#

it won't run

timber ivy
#

Ah I guess I could make a spawnvehiclesystem that handles this you're right

#

thank you for the suggestion

rustic rain
#

or are they loaded only on last frame of loading?

#

as in, all at the same time?

rotund token
#

They are all loaded at once

rustic rain
#

I wonder if you can load subscene from build in editor

#

not as authoring, but as just entities

timber ivy
#

So one of my auto converted entities has children entities, is there a way to take the root entity and copy it and it will copy all children as well? cause EntityManager.Instantiate just copies the root entity.

rotund token
#

Hmm I thought it should work

#

With linked entity

#

But tbh I avoid hierarchies so I'm not that familiar with it

timber ivy
#

Its not a linked entity according to the inspector

#

there aren't any linked entity components being added when its converted

rustic rain
#

is created during normal conversion for all children in Transform hierarchy

#

during instantiation of prefab

#

all entities that belong to that group are copied

timber ivy
#

ill read into it

#

but in this case I was able to solve my problem with a mesh combine tool xd

robust scaffold
#

Imagine: IBlobComponent...

robust scaffold
#

Well, a blob ref is just a pointer... Reinterpret as a BlobType** ugh. Disgusting. But it works.

#

Burst does not like generic double pointers sadly.

viral sonnet
#

why would you ever do that?

robust scaffold
viral sonnet
#

reinterpret as blobassetreference<T> is the next best thing

#

using a pointer pointer for blobs

robust scaffold
viral sonnet
#

hehe, i see. you can also get the ptr to the blob and save just the ptr. double ptr is performance hell

robust scaffold
#

Shape<Circle>** comes from a ICD containing a single BAR of a Shape<Circle>.

robust scaffold
viral sonnet
#

yeah funky setup

robust scaffold
#

But it works

viral sonnet
#

in that case all good

robust scaffold
#

Burst throws an error if it's a generic double pointer sadly

viral sonnet
#

i didn't mean it like that. just haven't seen nativearrays with it

robust scaffold
#

A NativeArray<BlobAssetReference<BlobType>> => BlobType**.

#

The redirection of the second pointer breaks vectorization sadly. It is random access.

#

What it does is reduce memory usage and increase chunk capacity. I've shaved off nearly 88 bytes (22 floats) from every entity.

viral sonnet
#

you moved those bytes to the blob?

robust scaffold
viral sonnet
#

yeah blobs are great for that

robust scaffold
#

Hrm. No difference in performance though. The actual chunk iteration jobs are sub 0.1ms and singlethreaded.

viral sonnet
#

oh nice, my blobs are taking quite the hit. but they are muuuch more than just 22 floats. i'd have to check how much size they take

#

hm, seems i need internal access to find that out

#

around 350-500 bytes ๐Ÿ˜…

robust scaffold
viral sonnet
#

good lord, not per entity ๐Ÿ˜„ it's my spell definition database

#

and yeah, it's a shit ton of data

viral sonnet
#

anyone remember this? unity said the want to make some cap on chunk capacity or smth

rotund token
#

yes

viral sonnet
#

and still going with 16k chunks? how does this work then when the capacity would be very high? empty chunk space?

rotund token
#

it's 128
and imo it's actually somewhat of a problem

#

i'm hoping that it's only for archetypes with enable bits... but i feel like this won't be the case

robust scaffold
viral sonnet
#

i remembered the mention about this while looking at my capacities and I'm just not getting it - why? enabled bits might be the best answer. yeah, i also hope this is just for enabled bits archetypes. i'd hate the idea of such an arbitrary cap

rotund token
#

128 entities per chunk

robust scaffold
#

Wait, what? Why

rotund token
#

One related change we did make for 1.0 is putting an artificial cap of 128 entities per chunk, to simplify and optimize the enabled-bits processing code (128 bits = one 16-byte SIMD register). Previously you could have a chunk capacity as high as 2048 under pathological conditions, but in practice almost every archetype we've seen is already comfortably below the new capacity limit, so we don't expect this to result in too many additional chunks.

rotund token
robust scaffold
#

I guess... I can see the reasoning

safe lintel
#

dont suppose anyone encountered a physics bug when you destroy physics colliders+joints entities, the physics system does like 10x more work(!) and theres an immediate death spiral?

robust scaffold
safe lintel
#

yeah just destroy entity via entitymanager.destroy. theres a minor step of removing some system state component but I dont understand this at all

robust scaffold
#

Possibly if the destroyed entity's AABB somehow persists but 0'ed out. That'll cause the midpoint split to end up in a neverending loop.

safe lintel
#

it definitely feels like something like that is happening

#

I swear there are less physics entities in the below profiler than the top ๐Ÿฅฒ

#

maybe the only wrinkle is that Im relying on LinkedEntityGroup to destroy the ragdoll rather than doing it manually? I dont ever recall getting this before in previous ragdoll experiments but now that Im thinking about it, Im not sure if I ever actually destoyed entity ragdolls before

robust scaffold
#

My hypothesis is that when you destroy an entity with a LEG, the target entity is destroyed but the linked children persist until the next frame, or end of frame.

#

During that time, physics attempts to reconstruct a joint but one of the entities are invalid. And it moves forward with the invalid data, resulting in a broken while loop (maybe)

safe lintel
#

yeah it doesnt last forever but its a good few seconds of terrible performance after the fact before it settles down. definitely gonna need to do some experiments. Im a bit worried it seems the havok guys havent really been active in a while if this is really a bug and not some dumb implementation thing on my part

robust scaffold
#

Join me in making it crystal clear who to blame when the physics engine explodes. Roll your own engine.

safe lintel
#

this is specifically why I didnt write my own engine ๐Ÿ˜Ÿ

#

my code already explodes enough when using off the shelf parts!

robust scaffold
#

Ha, I think I broke live conversion personally. Thankfully pressing the clear cache is simple enough

viral sonnet
#

this is getting nerdy AF ๐Ÿ˜„

robust scaffold
#

You can halve the width of that function by using direct pointer access

#

You can probably make that generic...

viral sonnet
#

open for input. i looked at generics and datatypes yesterday. wasn't that great, so, wdym?

robust scaffold
#

Just looks like repeated code. Replace the <short>, <half>, <float>, etc with a <T> and you can just copy paste the method name instead of the code.

#

But for this short of actual code, it's on the edge of worth generifying

viral sonnet
#

T doesn't work for simple data types

#

and yeah, i'm changing the unsafeUtility methods. figured as I'm using byte ptr and byte index it doesn't work anyway

robust scaffold
#

ref *(float*)((byte*)statChangeValuePtr[statChangeByteIndex]) I guess that isnt much better...

viral sonnet
#

changed it to this

robust scaffold
#

Adding to a pointer changes the target of the pointer, you still need to pull the actual data out

#

*((short*)Ptr + Index) (dont need the parenthesis around the second.

rotund token
#

(original was better)

viral sonnet
#

oh right, *(short*) should work

robust scaffold
viral sonnet
#

yeah, i liked the verbose nature of it but the index gets multiplied by the size of the data type so sadly not an option

robust scaffold
rotund token
#

if another c# dev jumps in, or just enzi in 6 months time what version is going to make sense faster to them

viral sonnet
rotund token
#

because i'm already just looking at it and thinking, wtf you doing mate

viral sonnet
#

i looked at some unsafeUtility method but couldn't find one which is not using a sizeof multiplier

#

and i'll probably inline method this because you are right. this gets hard to figure out and any slight change will make it explode ๐Ÿ˜„

robust scaffold
#

I just make everything either a float or int. Easier for everyone that way. Value type switches are just more headaches than it's worth unless you generify everything

viral sonnet
#

eh, most programming task are too easy anyway. need some challenge ๐Ÿคฃ

#

and i'm certainly not mad enough to write my own physics engine

#

that's for sure!

robust scaffold
viral sonnet
#

(i've already done that in flash AS3 ๐Ÿ˜ฉ )

robust scaffold
#

Pointer madness.

viral sonnet
#

yeah physics and simd go well together

#

having pointers makes c# fun again

robust scaffold
#

Having to write unsafe everywhere is not fun

viral sonnet
#

make the top class/struct unsafe. done ๐Ÿ˜„

robust scaffold
#

So big.

viral sonnet
#

this whole thing turned out to be quite the nice case for codegen. i have to create so many index lookups. doing that by hand. ooff

#

yep, that's a big one ๐Ÿ˜„

errant hawk
rotund token
#

probably 90%

robust scaffold
#

And the 10% will make you very confused.

errant hawk
#

Trying to get an idea of the workflow, starting point, etc of dots. I already know how to use burst/jobs quite well so that is not an issue

robust scaffold
robust scaffold
rotund token
#

+1

#

only tutorial i've seen i like

#

(though just read the manual)

robust scaffold
#

It touches basically all aspects of DOTS ecosystem currently. From the basic entity all the way to UI and VR integration.

errant hawk
rotund token
#

my strong advice is don't port an existing project to entities

#

if you want performance on an existing project, just stick with jobs + burst

errant hawk
rotund token
#

oh if you're writing from scratch then sure ok go ahead

viral sonnet
#

hm, does it make any difference if I add 2 short or 2 half values as long as they are 16 bit? i'm not sure if i can generalize this on bit level or if i should stick to data types

robust scaffold
viral sonnet
#

that's what i thought. hm, well okay then ๐Ÿ™‚

robust scaffold
#

You must re-expand the halfs to floats before operating any math on it. Floats have 2 components, the exponent and mantissa, and can not be added like an int.

#

Unless you want to implement half arithmetic. It's just like floats but halve the bitshifts.

viral sonnet
#

i was expecting var statChangeHalfValue = *(half*) changeValuePtr; ref var tmpHalfValue = ref *(half*) valuePtr; tmpHalfValue += statChangeHalfValue; to fail as I can't find the + operator for it

robust scaffold
#

There's an implicit cast to float.

viral sonnet
#

ok then

robust scaffold
#

Check. Implicit casting is sneaky.

robust scaffold
#

God, I forgot how amazing swizzling is.

#

It's been too long since I had to hammer out any shaders but burst is keeping me sharp

errant hawk
#

quick question regarding the dots workflow: is it better than prior to 0.51? I am not a fan of all the boilerplate or custom tools that need to be made first just to do something simple in earlier versions

rotund token
#

depends how fast you want your code to be

robust scaffold
#

It's easier to use with far less boilerplate if you use the code-generation version but you're not gonna see the maximum burst performance using them

rotund token
#

you can still get great performance boosts from burst and easy multi threading from jobs

#

and will be potentially a lot faster than gamoebjects

#

but yeah, you won't get max performance without writing it yourself

robust scaffold
#

Rendering honestly is the largest bottleneck. Using the code gen Entities.ForEach or IJobEntity will give you objectively far better performance on a larger scale than GOs.

#

You just wont get performance to support thousands to tens of thousands simultaneously

errant hawk
rotund token
#

writing the jobs yourself with IJobEntityBatch

#

that's what all the code gen turns into

errant hawk
#

oh, so just native Jobs/Burst

robust scaffold
#

Basically

errant hawk
#

Im kind of bothered that IConvertGameObjectToEntity exists. DOTS workflow should not incorporate the concept of GameObjects

#

The only link between the two should be the ability to share data, ie; cache value from GameObject, queue job, await computation, apply results (just like normal jobs currently not using entites)

#

and really the only use as of right now that GOs serve in a DOTS-based project is for UI/ease of use/setup. If unity can cut down on that reliance, DOTS will be much better overall

robust scaffold
#

They're not evil. I've grown to like them quite a lot as an authoring tool despite going completely DOTS with no GOs during play.

robust scaffold
#

This single monobehavior is 24 different components when authored.

#

Dont think of GO's as good or bad. They're just a well fleshed out inspector tool in DOTS.

errant hawk
robust scaffold
#

These GOs wont exist during gameplay. They only exist inside the editor. You ship the entities found in the DOTS Hierarchy.

rotund token
#

So if they invented EntityObjects and they existed in scene and could be prefabs and used the exact same inspector that'd be fine?!

#

Why spend years re-inventing the wheel

errant hawk
#

For entites/GameObjects that exist in the scene, Im fine with them technically being GameObjects, but presented to the user they should come with obvious entity restrictions and not this hacky ConvertToEntity script that gets added when the checkbox is selected.

rotund token
#

^

robust scaffold
#

Subscenes are DOTS's prefab and authoring tool all in one. You can nest subscenes. You can edit subscenes. You can selectively activate (load) or deactivate them.

errant hawk
#

DOTS honestly should have it's own editor

rotund token
#

you need to watch the 1.0 talk

robust scaffold
#

Watch that. I've gone from a subscene hater to holy shit I cant live without them

errant hawk
rotund token
#

part of their gdc 2022 playlist

robust scaffold
rotund token
#

but yeah it's weird it's unlisted

robust scaffold
#

It singlehandedly re-kindled my hope in DOTS. Being a salty old vet in these coding trenches.

errant hawk
errant hawk
robust scaffold
#

If they somehow can extend that to scheduled jobs, that will be fantastic but the foreach IAspect on the mainthread is still nice to see.

rustic rain
#

Conversion workflow with gos is great

#

Subscenes make it so no gos make it to the build

errant hawk
#

Im liking the light humor and the way examples are presented to solving issues. My favorite so far is the ability to manipulate entites and have the changes reflect it edit mode as well (dirty.) I also like that there is now less abstraction between authoring mode, and runtime mode

errant hawk
#

cool, watched it all and Im liking what Im seeing so far

robust scaffold
rustic rain
#

Months away?

#

They gave any tips about eta?

robust scaffold
#

Im being optimistic for the new guy

#

probably years

rustic rain
#

Ah yes

#

That's more like it

robust scaffold
#

(although 2022 LTS is their goal according to the very small blurb at the end of the 2022.2 beta features list)

#

Got physics working. Only discrete collisions though.

rustic rain
#

Can't wait for jornal

robust scaffold
rustic rain
#

Ability to track structural changes history

robust scaffold
#

Is that not already in entities? I havent used it before

rustic rain
#

I wasn't able to find anything about using it

robust scaffold
#

Only through an attached debugger currently though

rotund token
#

yeah you can see a lot of info through debugger now

#

its great

#

look at entity field, can look it up in every world

#

all it's components etc

#

was such a great addition

rustic rain
#

bruh

#

I barely have systembase to attach breakpoint xD

#

hmmm

#

Does Rider support journal?

timber ivy
#

So I have an entity that I am converting from a gameobject. It has one of unities physic authoring scripts. Physics Shape attached. Later after it is converted to an entity and spawned with entitymanager I add a PhysicsVelocity component to it. The moment I do the entities Translation and LW all get NaN as the values. What am I missing?

rustic rain
#

then create it manually in code

rotund token
timber ivy
#

oh good idea

#

thank you

rustic rain
rotund token
#

a good way to see how to use it is turn on break points on exception

rustic rain
#

I can't find that journal anywhere in debug options

timber ivy
#

hmm so I am not missing any components. This problem appears to be from copying an entity. If I do not copy the entity and just create a new one the problem doesn't persist. Maybe the colliders are being reused and its causing this not sure, but I know how to fix it now at least.

rotund token
#

Maybe the colliders are being reused and its causing this not sure, but I know how to fix it now at least.
collider is definitely re-used

#

if you want to make something that's static -> dynamic

#

convert it as a dynamic

#

and remove the component

#

it needs to setup a bunch of other stuff

errant hawk
#

likely this year imo

rustic rain
#

if you'll have invalid rotation

#

you'll certainly have NaN errors

timber ivy
#

Yes they are just 0

rotund token
rustic rain
rotund token
#

journaling records are automatically attached to the stack of any exception

rustic rain
timber ivy
#

its 0 0 0 1

rustic rain
#

what about translation?

#

try to ensure they are all 0

rotund token
timber ivy
#

They are

rustic rain
#

and I had no idea about exceptions

timber ivy
#

Its cause the colliders being copied so the rigiddbody doesn't know how to behave

rotund token
#

but any exception you have from entities should attach journaling info

#

(turn journaling off and compare)

rotund token
#

you can inspect entities in normal break points

rustic rain
#

oh

rotund token
#

that's not really journaling info, but just another very useful feature

rustic rain
#

well, no

#

I need journal

timber ivy
rustic rain
# rotund token

I have this weird exception triggered on entity from subscene (I assume) which is not meant to be destroyed at all
How can I breakpoint this code with journal?

rotund token
#

you can see it should be debugging the journal info out for you already

rustic rain
#

well, I don't see it

rotund token
#

in your log?

#

what type of info are you looking for?

rustic rain
#

what destroyed this entity

#

ok, I figured it out without journal

#

xD

rotund token
#

mine literally shows this info in the exception

ArgumentException: The entity does not exist. Entity (190:1) was previously destroyed by Beyond.Environment.Corruption.CorruptionSystem.

#

or if done via ECB

ArgumentException: The entity does not exist. Entity (190:1) was previously destroyed by Unity.Entities.BeginPresentationEntityCommandBufferSystem. This command was requested from Beyond.Environment.Corruption.CorruptionSystem.

#

this is from journaling

rustic rain
#

yeah and in my case it said ConvertToEntitySystem

#

which did not really help

timber ivy
#

Does the new input system work in jobs?

rotund token
#

just have an input system

#

that writes your input to a component

rustic rain
#

yeah, I created generic components for each action

#

Started<>
Performed<>
Canceled<>

#

and everytime action is pressed - there's singleton component

#

with it

rustic rain
#

bruuuuh

#

how can I solve this problem?

#

I have trigger events

#

which sometimes need to be disabled only for query

#

which is basically based on write group

#
        private struct JumpInteractionJob : ITriggerEventsJob
        {
            public EntityCommandBuffer buffer;
            [NativeDisableUnsafePtrRestriction] public EntityQuery kek;

            public void Execute(TriggerEvent triggerEvent)
            {
                if (kek.Matches(triggerEvent.EntityA) && kek.Matches(triggerEvent.EntityB))
                {
                    Interact(triggerEvent.EntityA);
                    Interact(triggerEvent.EntityB);
                }
            }

            private void Interact(in Entity e) { buffer.AddComponent<InteractedTag>(e); }
        }

Current implementation doesn't work

#

because EntityQuery methods aren't allowed in jobs

viral sonnet
#

cast entityquery to entity array and build a hashset

rustic rain
#

hmm

#

I wonder if I can do opposite

#

get all filtered entities

#

so this way I will have very small hashset

errant hawk
#

Im getting memory leaks with a super simple test SystemBase that modifies a cube GameObject in a subscene

#

It seems it has something to do with subscenes

#

there's a second memory leak error that points to AsyncLoadSceneOperation.cs

#

nvm, I forgot the subscene had the ConvertToEntity enabled... ๐Ÿ˜… weird how that checkbox exists in the first place.

errant hawk
rustic rain
#

in subscene - yes

#

everything inside subscene gets converted

errant hawk
#

yeah it doesnt make much sense to convert the subscene itself

rustic rain
#

oooh, you literally converted subscene

#

kek

errant hawk
#

internally the subscene is a GameObject, so that's why it's showing up in the first place (and also why it can actually convert a subscene, but not without errors)

rustic rain
#

they use some kind of hooks

#

to inject subscenes into world

#

they are not meant to be converted through normal interface

errant hawk
#

is EntityManager usable inside of a burstified job? or at least a normal job? The docs claim you cant, but source code says otherwise

whole gyro
rustic rain
#

works out fine, since it's literally same thing as

#

normal calls

#

from new input system

#

the only thing that bothers me is that it can be codegened

#

into a very nice wrapper

#

which generates all components manually, creates system that registers for all callbacks

#

and etc

whole gyro
#

Yeah, I guess I'm wondering if its worth splitting input into one component per action like that. I use a single big component for all my input right now. I can definitely see the benefits of the more granular approach, but wasn't sure if it was overkill.

whole gyro
rustic rain
#

yeah

#

you have list of actions

#

you generate tags for buttons

#

special components for values

#

so for example if you want to generate that for moving mouse, which gives Vector2 value

#

you simply make such component

#

literally same as OOP new input system

#

and fully burstable

#

potentially

#

it can be even improved more

#

by creating single system to handle all of them

whole gyro
#

yeah sounds like a nice setup. Wonder if unity will provide a better way to work with input in dots

#

Do you mean a single system for populating the tags and components, also codegened?

rustic rain
#

I already have single system

#

which is hand written atm

#

and looks horrible to manage

#

it simply resets archetype of input entity

whole gyro
#

yeah same for me, but all editing the same component instead of one per input event

rustic rain
#

so all input components are gone

#

meanwhile adding components to that entity is done by new input system callbacks

whole gyro
rustic rain
#

yeah

#

I haven't really dug into how new input system works outside of that

#

so potentially can be made even faster

whole gyro
#

yeah that's what I'm using too. Thought it has been around for a while so making sure I didn't miss some new thing there

robust scaffold
#

I'm still using the old input system. I have that control system wired from years back in my first unity project and it works even today

rustic rain
#

old input system is not that cool with custom bindings to centralized actions

robust scaffold
#

WASD, the only bindings you ever need

rustic rain
#

or uses gamepad

robust scaffold
viral sonnet
#

there's really nothing more that i hate more and that's html and css. say hello to ui toolkit

robust scaffold
viral sonnet
#

i can't even make this dropdown and textfield in 2 columns and i made the froggy flex tutorial a few times. ...ugh

#

webdev hacks are everywhere

#

flex is at least better thand oldschool css. doesn't help when theui builder is just weird

#

(I'm fat fingering on mobile again.)

#

i'm sure if i get around it, it'll be great. much better than the old way of building editor ui

#

anyone has experience in ui toolkit for editor ui? there's some controls but i don't know how to style them. everything's greyed out

#

like the textfield. can't make the label smaller

viral sonnet
#

yeah

#

found some thread. maybe that will help me

robust scaffold
#

I only played with it to render text and such, not actually build a UI

rustic rain
viral sonnet
#

yep, custom selector .my-text-field > .unity-base-field__label - this UI builder is very unintuitive. i had to find out now that min-width of this label is set to 150px. doesn't really show me. shame, hope this gets better. it also says when hovering over some class. double click to create selector but nothing is happening. you have to type it in ๐Ÿ˜„

eager pawn
#

is it still RenderMesh we use to draw 2d sprites?

rustic rain
#

nah, 2d is drawn through hybrid go

eager pawn
#

and ig this would be able to fix my problem with mesh and material being a managed type cuz hybrid go is non-burstable anyway

rustic rain
errant hawk
#

Best way to get a specific entity? Such as the local player that is in the same chunk of NPCs/other players.

#

or should the local player(s) be tagged to separate it

solemn hollow
#
var packedEnablerCounts = enablerCounts.Reinterpret<int4>();
                    for (int j = 0; j < enablerCounts.Length; j++)
                    {
                        bool valid = packedEnablerCounts[j] > new int4(0,0,0,0);
                    }```

how could i do something like this? 
i want that bool4 to be turned into a bool "valid" that is true if all evaluations of the bool4 are true.
solemn hollow
solemn hollow
errant hawk
viral sonnet
#

this starts to look like something

#

tutorials are all over the place for ui toolkit. some make it harder than it actually is

errant hawk
#

Entities.ForEach doesn't have an ability to await it like .Complete() for jobs, so parsing data is not possible.

solemn hollow
solemn hollow
errant hawk
solemn hollow
#

else there is no reason to await since its synchronous with .Run

errant hawk
solemn hollow
#
             {
                 
             })
            .Schedule(Dependency);```
#

Where Dependency is the Systems Dependency jobhandle.

rotund token
#

^ if you don't pass in a handle it's handled for you via code gen

#

Is you pass in a handle it'll return a handle and you can manage it yourself

errant hawk
solemn hollow
#

yep

#
var packedEnablerCounts = enablerCounts.AsNativeArray().Reinterpret<int4>();
                    for (int j = 0; j < enablerCounts.Length; j++)
                    {
                        var isValid = math.all(packedEnablerCounts[j] > new int4(0, 0, 0, 0));
                        var didChange = possibilities[j].valid != isValid;
                        
                        possibilities[j] = new Possibility
                        {
                            valid = isValid
                        };

                        if (didChange)
                        {
                            //do some expensive stuff
                        }
                    }```
#

how should i go about getting rid of that branch at the bottom to make that loop SIMD compatible?

#

write to a didChangeArray and do an extra loop over that outside of this faster loop?

errant hawk
safe lintel
#

ok my physics performance woes were due to an extra PhysicsStep(didnt realize had two). two will annihilate performance in certain scenarios(but not all apparently)

solemn hollow
solemn hollow
safe lintel
#

imo it should error having more than one PhysicsStep to protect dummies like me, but it only manifested under certain obscure circumstances, enabling a ragdoll one way but not another. ๐Ÿคทโ€โ™‚๏ธ

viral sonnet
# solemn hollow how should i go about getting rid of that branch at the bottom to make that loop...

you can only really make the top vectorized. the bottom would require another loop. something that could work, would be to use left shift (math.compress) and tzcnt to count the number that can be skipped. having said that, i don't think this will be worth it much if this runs every frame anyway. just let it branch. the expensive part will probably still be scalar so you can make only ns improvements with the intro

#

@robust scaffold might have some better ideas

solemn hollow
#

its not a performance bottleneck atm. i just thought the datalayout fits perfectly here to try to learn some easy SIMD. gotta start somewhere

#

i do have some other places where SIMD should actually do alot for performance but those im not touching right now ๐Ÿ˜„

viral sonnet
#

try it, i also think skipping is a nice way to utilize some simd

solemn hollow
#

first time i hear about skipping. so give me some time to google it ๐Ÿ˜„

robust scaffold
#

Early returns and code skips are great but it really depends on what you're trying to do.

solemn hollow
#

i need to message neighborcells of this cell running the code about changes to the possibility array. Changes to possibilities can only occur if in all 4 directions (the int4) the enabler count is positive.

robust scaffold
solemn hollow
#

yes AND if possibilities[j].valid was also false before.

robust scaffold
solemn hollow
#

no. its something like Get the neighbor cell from Grid and a struct containing the changed PossibilityIndex ( j ) to a dynamic buffer

robust scaffold
#

This looks like a simple bit check

#

Instead of an if (int4 > int4.zero), try instead just a byte and then toggle on bit flags.

#

Not everything needs to be SIMD with SOA format.

#

The code blurb I just posted above calculates the maximum distance out of 4 points simultaneously using SIMD. That's a easy situation to SIMD. If you're just using a flag check, you dont need a math.all()

#

Use a byte and save chunk memory.

solemn hollow
errant hawk
viral sonnet
#

that's expecting loop unrolling and something very different. automatic loop unrolling will never work with scalar branches

robust scaffold
robust scaffold
errant hawk
robust scaffold
solemn hollow
#

that depends on the TileRuleset of the WaveFunctionCollapse. id practically expect not more than 10k

robust scaffold
robust scaffold
solemn hollow
#

its not good for my heart thats true

errant hawk
robust scaffold
robust scaffold
robust scaffold
#

Let me tell you, I took a shot at doing this by hand for a sweep and clear algo on a tree and, while it worked, manual vectorization means having to manually support all instruction sets.

#

That article describes manual vectorization for Neon, which is AMD chips. The code wont work on Intel for example. You'll need to write out the intel intrinsics as well. And if you want to support mobile, those as well.

errant hawk
robust scaffold
solemn hollow
robust scaffold
#

The lowest entropy probably cant be done in SIMD unless you're gonna use SIMD first to obtain lowest neighboring entropy and write back to the source array and a second pass that operates on 4 tiles at once to calculate the resulting tile.

solemn hollow
robust scaffold
solemn hollow
#

but you are not wrong in that the entropy can be done in parallel. there is actually only one really good article i found on WFC that explains the overlapping model combined with the performance improvements. the other articles simplify quite alot. if you are curious : https://www.gridbugs.org/wave-function-collapse/

robust scaffold
#

Hrm yea. Seems right.

solemn hollow
#

im still intruiged about the math.compress and tzcnt @viral sonnet mentioned

#

what does the compress do with an int4?

robust scaffold
#

Compress is left pack.

#

Tzcnt is the standard count low zeros

solemn hollow
#

so it packs every int4 that is 0 to the right of the array?

robust scaffold
#

This is my usage of compress to obtain overlapping AABBs when querying a BVH tree for broadphase physics.

#

The first compress uses a bool mask of 4 possible leaves containing entities and left packs a compIdx and compDat (name of an arrays of ints) of the two halves of an entity struct.

solemn hollow
#

ah so the bool4 defines which ones are packed left i see

robust scaffold
#

Yep

#

it's just a really fancy shuffle.

solemn hollow
#

and that enables me to avoid branching because i can just sort everything i want to skip to the end?

robust scaffold
#

Yes. But make sure this is appropriate for the math and logic you want to use.

#

I'm left packing / sorting in order to obtain all possible overlaps from a quadtree like node array that I then pass into a narrowphase system.

#

It might be more efficient, depending on your math, to just integrate the mathematics into this system and skip the use of compress

#

you have the bool4 mask. You can just zero out portions that are not masked.

solemn hollow
#

in the comments it says its useful for building intersections. atm i am using hashsets to build intersections between dynamic buffers in my AI. is there a much more efficient way with compress?

#

ah nvm. they would need to be in the same order right?

robust scaffold
solemn hollow
#

i learned a lot again. thank you! ill head off to bed for now and ponder over how i will never get to use all those fancy tools ๐Ÿ˜„

devout prairie
#

is there any difference between doing:
RequireForUpdate(GetEntityQuery(ComponentType.ReadOnly<MyComponent>()));
and:

        {
            All = new ComponentType[] { typeof(MyComponent) }
        }));
robust scaffold
#

wait

#

All = new ComponentType[] { typeof(MyComponent) } translates to RequireForUpdate(GetEntityQuery(typeof(MyComponent)));

#

All does not imply readonly

#

you must also ComponentType.ReadOnly<MyComponent>() inside the all array

#

typeof is read write

devout prairie
#

right yeah

#

i was wondering why do the longer version really

robust scaffold
devout prairie
#

unless you need Any or none ofc

#

yeah

robust scaffold
#

I rarely use the inline ones since I have so many any queries.

devout prairie
#

right yeah

robust scaffold
#

Although I hate to say it but I think my physics is hot garbage, damn. Well that was a great learning session. I'm gonna go back to old monobehaviors.

#

It works, kinda, it's more efficient than unity's by miles due to SIMD and burst everywhere but it just doesnt have the same stability as box2d and I really dont know how

devout prairie
#

ahh that's painful

#

no ideas of why you are having stability problems?

robust scaffold
#

or else it just penetrates into objects and bounces off violently

#

ugh, it works fine enough. and it's deterministic because it's all in burst (or at least as deterministic as DOTS physics is)

#

onto other things, i spent enough weeks on this already

devout prairie
#

i guess you could always go back to it with a fresh approach at a later point

robust scaffold
#

Box2D is open source, just way beyond my current ability to replicate in SIMD though

#

why did unity stop 2d dots. I mean, I know why, money, but i am very sad

devout prairie
#

yeah i do wonder if they'll pick that up later, it seems a no brainer to leverage dots in that area

errant hawk
#

is the order of entities in a chunk deterministic? If it's not, is there any way I can define the order? I need the entity index to be consistent on both the server and client because I do not want to make the operation an O(n^2)

robust scaffold
#

Even without burst. Integer math is deterministic. The second you add floats into it, not anymore.

errant hawk
robust scaffold
errant hawk
robust scaffold
#

Memory layout is not an issue though. It's 16kb of linearly allocated memory blocks per chunk.

rotund token
robust scaffold
#

if there is no structural changes, that section of code will be valid.

errant hawk
rotund token
#

chunks is entities

#

but your client might not be the same as your server

#

you can have different entities on each

#

and the time things spawn might differ due to network conditions

#

but if you create things in the same order in different sessions on the server

#

the chunk layout will be identical

errant hawk
#

alright thanks

viral sonnet
# robust scaffold Although I hate to say it but I think my physics is hot garbage, damn. Well that...

aw damn! but yeah, i know what you're talking about. as mentioned i wrote a physics engine in AS3 because we needed a very specific web demo and concave colliding. most was straight forward but then stability issues hit and i spent weeks full of tweaking on it. that's honestly where writing a physics engine stops being fun. so yeah, if you have a fallback model, go for that, for the sake of productivity. but revisit it some time later. i think it's worth it what you started.

robust scaffold
#

I'm keeping my BVH though. Pinnacle of my coding right now.

viral sonnet
#

that shit takes a lot of patience and time to get right

#

box2d is the default for unity 2d physics?

robust scaffold
#

Yea

viral sonnet
#

and dots physics is not an option?

robust scaffold
#

3d locked Z axis has terrible top down stability

viral sonnet
#

anyone knows how i can trigger source generatos before i google? ๐Ÿ˜… i actually need the source gen to read a json file

robust scaffold
viral sonnet
#

in case the json doesn't work out i need to go in a roundabout way :/

robust scaffold
#

It should work... should

viral sonnet
#

hm, if not, i can just write the code file myself from a template. it's not that complicated, just a bunch of indices that are a pain to write

viral sonnet
#

yep, no need for ISourceGenerator

timber ivy
#

are you able to read values from a referene type stored in ISharedComponentData in a parallel job?

rotund token
#

not in a burst job

#

but technically yes

#

i wrote a SharedComponentDataFromIndex<T> that let's you do this

timber ivy
#

hmm, I found like 5 different ways to deal "use" animation curves in dots. All of them are way too memory heavy. So I thought about using ISharedComponentData since most of the entities will be sharing this data

rotund token
#

why are they anymore heavy than a shared component?

#

if the animation curve is shared between multiple assets

#

just use a blob to store it

timber ivy
#

interesting ok, that will make sure the memory isn't duplicated ig? ima go read up on this

#

if I make a blob asset then pass it to components doesn't it just make a copy of the it since its a valuetype?

#

nvm this is what blobassetreference is ig

timber ivy
#

is it possible to create an authoring component for blobassetreference?

#

i tried but ig it doesnt' work cause the pointers shift when you enter play mode idk?

safe lintel
#

if you're feeling mildly adventurous @timber ivy you can just copypaste the Animation.Curve blobasset from the Unity.Animation package, it should have conversion in there as well

timber ivy
#

I thought about doing the same from unity.timeline.dots

#

they have animation curves in there too

#

that are dots compatible

safe lintel
#

Itโ€™s most likely the same one. Wonder whatโ€™s going on with that package

rustic rain
#

Blob assets are saved in subscenes

#

And references are remapped correctly by Unity

#

During loading

timber ivy
#

Ok yeah it works if you do it in one of the conversion systems

#

but if you try to do it from an editor script it doesn't seem to work

rustic rain
#

Ahem

#

Subscenes conversion is done in editor only

timber ivy
#

I litterally copied my code from a custom editor window to a GameObjectConversionSystem and the blob reference worked

#

wasn't working in my custom editor window

rustic rain
#

I don't really understand what you're doing

timber ivy
#

oh i see what the problem was. Its is because blobassetreference isn't serializable

rustic rain
#

We'll, not really

#

It is serializable, just like entity

#

But

#

It requires remapping

#

Because otherwise during load it's invalid

#

They use some kind of memory offset approach for blobs that makes it possible

hollow jolt
#

how do i convert Matrix4x4 to float4x4 ?

vertices[i] = vertexMatrix.MultiplyPoint3x4(v);
normals[i] = vertexMatrix.MultiplyVector(n);

where v and n are Vector3

rotund token
#
                float4x4 f = m;```
rustic rain
#

(float4x4)yourmatrix;

rotund token
#

it has an implicit cast

hollow jolt
#

tried math.mul but there is nothing for float4x4 and float3

timber ivy
#

will entities foreach work on gameobjects and monobehaviors?

rustic rain
timber ivy
#

Entities with monobehaviors?

rustic rain
#

yeah, you can add managed objects

timber ivy
#

oh so I can attach a camera to an entity for example?

rustic rain
#

yeah, that's pretty much how camera conversion works

timber ivy
#

so how do you do this?

rustic rain
#

if you want to go with this approach, I suggest you to make conversion system

#

dstManager.AddComponentObject(entity, object);

timber ivy
#

oh awesome thanks!

rustic rain
#

keep in mind, it'll keep actual game object around

timber ivy
#

and the downsides are ofc can only be ran without burst and on the main thread

#

any other?

hollow jolt
#

no overloads

rustic rain
#

what does error say?

rustic rain
# timber ivy any other?

it's slow, it's managed, it might not work very well if companion link system doesn't catch up

#

for built in types

#

like SpriteRenderer

#

it automatically creates gameobject clone

#

with same spriterenderer settings

#

for other monobehaviours

timber ivy
#

"wont catch up" Hmm does this mean I will have trouble making a camera smoothly follow an entity then?

rustic rain
#

I'm not sure if it will work the same every time

rustic rain
hollow jolt
#

i can however do the following , so i could cast vec3 to flaot4 , any ideas which one is the correct way ( would the matrix be the 1st or the 2nd argument ) ?

rustic rain
hollow jolt
#

the first line is what im trying to replicate

#

or rather im trying to figure out how to write it using Unity.Mathematics

hollow jolt
#

yep

#

hence the float4

#

any ideas which one is the correct way ( would the matrix be the 1st or the 2nd argument ) ?

rustic rain
#

look at example

#

A*B=C

hollow jolt
#

so if u put float4 on the LHS the result would also have a single row

rustic rain
#

well, you can literally see the return type

#

of your math.mul

#

after you assigned parameters

hollow jolt
#

both return float4 lol

#

so im guessing the vector is on the LHS

#

var result = math.mul( ( float4 ) vec3 , (float4x4) matrix ).xyz ;

#

gonna try something like that

#

i wonder would it be worth it

#

is Matrix4x4 is burst compatible ?

#

well this is the closest i got
from :

vertices[i] = vertexMatrix.MultiplyPoint3x4(v);
normals[i] = vertexMatrix.MultiplyVector(n).normalized;

to :

vertices[i] = math.mul( ( float4x4 ) vertexMatrix, new float4( v, 0 ) ).xyz;
normals[i] = math.normalize( math.mul( new float4( n, 0 ), ( float4x4 ) vertexMatrix ).xyz );
#

for the vert , the input is M4x4 x Vec , for the norm the input Vec x M4x4

#

however the math . mul doesn't not preserve position

timber ivy
rustic rain
#

companion link

#

system

timber ivy
#

alright cool thank you!

rustic rain
#

hmmm, anyone remembers how to make command buffer for ISystem?

#

that can be played back multiple times

#

ah, nvm

#
        /// <summary>
        /// The <see cref="EntityCommandBuffer"/> can be played back more than once.
        /// </summary>
        /// <remarks>Even though the EntityCommandBuffer can be played back more than once, no commands can be added after the first playback.</remarks>
        MultiPlayback
rotund token
#

i've never really found a good use for it

rustic rain
#

delayed component adding

#

but I was able to resolve it with other tools

#

like system groups and ordering

#

but tbh

#

I could use ECB in many other systems

#

which are for no reason managed rn

#

after all you can schedule jobs in ISystem

#

btw, I figured an interseting option

timber ivy
# rustic rain yes, it's built in

This isn't happening for me.

i attached a CameraComponentAuthoring script to the main camera in the scene. The authoring component is just autogenerated from this

[GenerateAuthoringComponent]
public struct CameraComponent : IComponentData
{
    public float smoothTime;
    public Entity observable;
    public float3 offset;
    public Vector3 velocity;
}

when the entity is created it looks like the pic below. However when I update the values of the translation component the cameras gameobject doesn't follow

rustic rain
#

I want to make helper method to get ref of actual ComponentData

#

so instead of doing double em call for GetComponentData and then SetComponentData

#

I could just do GetComponentDataReference

#

with ref value as return

rustic rain
timber ivy
rustic rain
#

I think you need special compiler declaration

errant hawk
#

Im trying to get a subscene's entities in a SystemBase but having trouble finding info on how to do that. Thoughts?

rustic rain
timber ivy
rustic rain
#

add this to Player options

timber ivy
#

awesome thank you!

rotund token
#

btw doing it on main camera causes, oddities

#

which is why it's disabled

rustic rain
timber ivy
errant hawk
rustic rain
#

ahem

#

what kind of chunk

#

for what

rustic rain
#

and see how it works first

#

maybe you won't need any special treatment at all

rotund token
#

but i think srp needs one

#

it still works btw on main camera

#

you might just get oddities in editor

#

like camera starting in wrong position when entering the game

#

as far as i'm aware these are editor only issues

#

and if you aren't lerping camera you probably won't notice anyway

errant hawk
# rustic rain what kind of chunk

EntityManager.GetChunk(Entity) doesn't specify any other parameters other-than Entity so idk what you mean by "what kind of chunk"

rustic rain
#

why do you need it?

rotund token
#

just query for the subscene?

errant hawk
#

trying to get info from a specific entity

#

specifically for UI purposes

#

but using GOs

rustic rain
#

well, that's not really supported so you'd need hacky ways to make it work

#

if it's UI related

#

why not just store data in GO

#

this way you can get reference to it with Object.FindObjectOfType<>()

errant hawk
#

you're telling me I can write to an entity, but I cannot read for it to be used elsewhere?

rustic rain
#

when you store entity in subscene

#

that means you store it in large chunk of serialized data which is not loaded during world creation

#

so in order to get data from subscene in System you either will have to do it on every frame

#

or in OnStartRunning

#

which will require you to implement some algorithm to ensure it only loads it once (assuming it's important)

#

so that's why it's all hacky

#

and rather be done differently

rotund token
#

that didn't sound like their problem

rotund token
rustic rain
#

trying to get info from a specific entity
I assume he just stored settings for smth in here

#

query sounds like an overkill for that kind of purpose

#

allthough, completely ok

#

if it's some kind of true ECS UI interface

errant hawk
#

these are networked entites so storing the context of their UI on a GO isn't really ideal. Would rather just read the entity and copy the data to the UI

rustic rain
#

well then

#

RequireSingletonForUpdate<YourEntityComp>();

#

and then in OnStartRunning
GetSingleton<YourEntityComp>();

#

and do all your work in on start running

#

but that would be called every single time there's such entity added to world when it didn't exist previously

rotund token
#

correct me if i'm wrong, but the problem sounded like extevious wants to get a specific entity and write it's data to the UI

#

not query a UI entity

rustic rain
#

var ptr = access->EntityComponentStore->GetComponentDataRawRW(entity, typeIndex);
Hmm

#

can I somehow cast ptr to ref T?

#
        public static unsafe ref T GetComponentReference<T>(this EntityManager em, in Entity entity)
            where T : struct, IComponentData
        {
            var access = em.GetCheckedEntityDataAccess();
            var typeIndex = TypeManager.GetTypeIndex<T>();

            access->EntityComponentStore->AssertEntityHasComponent(entity, typeIndex);
            access->EntityComponentStore->AssertNotZeroSizedComponent(typeIndex);
            if (!access->IsInExclusiveTransaction)
                access->DependencyManager->CompleteWriteDependency(typeIndex);

            var ptr = access->EntityComponentStore->GetComponentDataRawRW(entity, typeIndex);
           
        }
#
        [BurstCompatible(GenericTypeArguments = new[] { typeof(BurstCompatibleComponentData) })]
        public static unsafe ref T GetComponentReference<T>(this EntityManager em, in Entity entity)
            where T : unmanaged, IComponentData
        {
            var access = em.GetCheckedEntityDataAccess();
            var typeIndex = TypeManager.GetTypeIndex<T>();

            access->EntityComponentStore->AssertEntityHasComponent(entity, typeIndex);
            access->EntityComponentStore->AssertNotZeroSizedComponent(typeIndex);
            if (!access->IsInExclusiveTransaction)
                access->DependencyManager->CompleteWriteDependency(typeIndex);

            var ptr = access->EntityComponentStore->GetComponentDataRawRW(entity, typeIndex);
            var structure = (T*)ptr;
            return ref *structure;
        }

hmmm

#

let's see if it'll work

#

oh well

#

it's not even crashing

#

๐Ÿ˜…

errant hawk
rustic rain
#

yeah, that's really interesting thing

#

just gotta remember

#

that structural changes invalidate it

solemn hollow
#

oof how to debug without burst when burst is actually required to get any kind of performance? if i disable burst i need to wait minutes until i run into the error i wanna debug lol. with burst its seconds...

rustic rain
#

NativeDebugger in VS

#

haven't ever used it though

solemn hollow
#

hmm any idea if its possible in rider?

rustic rain
#

not that I know of

rotund token
#

I can hook riders native debugger up to native code run by unity but not burst

#

For some reason

rustic rain
#

how do you hook VS?

solemn hollow
#

:/

rustic rain
#

I can't even attach VS to Unity

#

hmm

#

hmmm

timber ivy
#

Quaternion.LookRotation

is there something similar to this in the math/collections library?

timber ivy
timber ivy
#

Do I have to do something speicial to set the rotation of a rigidbody in unity.physics? in vanilla physics it just works

#

in unity physics with dots they are fighting each other

rustic rain
#

rigidbody?

#

there are no rigidbodies in dots

rotund token
#

They call them different things like physics body and rigidtransform

#

But it's the same thing

rustic rain
#

btw

#

is it possible to get triggerevents list

#

manually from physics world?

robust scaffold
#

Wait. Since I uninstalled entities, I can move to 2022.2... IM FREE

rustic rain
#

๐Ÿค”

#

uninstalled entities?

#

herecy

robust scaffold
#

Yea. Went back to trusty pile of NA.

pastel field
#

Do you guys separate Data, Authoring & System in separate files ?
I would have thought this was a good practice, but my code base is growing and I'm starting to find it annoying. I hesitate to put everything in one file.

robust scaffold
#

I'm handing out raw pointers to everything and I want them to still be valid if I structural change

robust scaffold
rustic rain
#

usually I keep mechanics together

pastel field
rustic rain
#

unless it's some very general components

#

that are used by multiple mechanics

robust scaffold
#

My components are often a dozen lines or less but I have a lot of them. My authoring is quite large but one off and conglomerates (all the components for entities get added in one authoring system). My systems one per job

pastel field
robust scaffold
#

I mean, you structure your project however you like. There is no set rules for this

rustic rain
#

"Just drop everything in /Scripts folder and it's fine"

robust scaffold
rustic rain
#

it's fine

pastel field
#

Speaking of assembly def, Is there a faster way to add dependencies? It's a bit messy at the moment.

robust scaffold
robust scaffold
#

Keep your dependencies low and use the least amount of packages as possible and it's less amount of pain

pastel field
#

Especially since sometimes the addiction is not very explicit, I've been known to look for a long time for what the addiction was. The experience could be more "automated".

robust scaffold
#

That's just regular implicit assembly definition (using the scripts folder)

pastel field
#

I would like to, but it's Unity that makes it difficult with its duplicates (Unity.Physics,Unity.Physics.Editor, Unity.Physics.Hybrid, Havok.Physics, Havok.Physics.Editor, Havok.Physics.Hybrid,...)

rustic rain
#

really don't understand why Rider doesn't do

pastel field
robust scaffold
#

Or you can just buy that asset.

#

Ugh. Migrating to 2022 is gonna be pain

#

Or 2023... choices. FREEDOM in versions...

rustic rain
#

one thing Rider does tho

#

is lets you easily add references through code

#

but still

#

so annoying it doesn't add reference automatically

pastel field
#

true

rustic rain
#

must be heaven for you ๐Ÿ˜…

pastel field
#

The official editor could be better at this

robust scaffold
robust scaffold
rustic rain
#

wha

#

hybrid?

#

herecy

robust scaffold
#

I chopped my entire project back down to my custom lighting engine. Archived my physics. Deleted my Sprite renderer

robust scaffold
#

No entities

rustic rain
#

oh god

robust scaffold
#

Freedom tastes amazing

rustic rain
#

I feel like I'm in cage when using GOs

robust scaffold
#

What's stopping you from just rolling a mountain of native arrays?

#

Component data replaced with direct pointers to the NA element. Although resizing means invalidating all the pointers and reissuing them to all the GOs which is very painful

rustic rain
#

no poggie woggie memory layout

robust scaffold
rustic rain
#

yeah...

#

not much help here

#

for CPU cache

#

besides

#

Unity entities worked with pointers a lot too

#

just under a safe hood

#

and tons of checks for you

robust scaffold
#

If you iterate in sequence, the cpu knows how to properly manage the cache

#

You dont need to divide up arrays in 128 sized chunks to get performance. In fact, that reduces performance

rustic rain
#

and how would it work

#

with fragmentation

robust scaffold
#

Fragmentation?

rustic rain
#

well yeah

#

if for example

#

there are 50 blue entities and 50 red entities

#

and they are all

#

go through 0-1-0-1

#

kind of thing in your array

#

and you only need one color

robust scaffold
#

You can have multiple native arrays

rustic rain
#

so how that would handle multiple archetypes

robust scaffold
#

1 per entity archetype and then string them together. Or use multiple sequential or parallel jobs

rustic rain
#

so array for each archetype

#

aaand how would that work

#

if you need multiple data from 2 different arrays

#

CPU cache will be lost with it

robust scaffold
#

Yes. Or you can merge archetype similar components like one array for all colors and the two separate arrays for different components

robust scaffold
# rustic rain CPU cache will be lost with it

The CPU cache doesnt need to be handheld. It's quite intelligent in knowing what information is required so long as you include it. What helps performance is following along its assumptions. That the next data to be iterated on is the best element when incrementing the pointer.

rustic rain
#

yeah, not really

#

the fastest cache is very small

#

if you load 1 large memory chunk and then the other

#

first one you load will be unloaded to less faster cache layer

robust scaffold
#

Yes. Extremely small. 64 bytes. That's 1 struct.

rustic rain
#

so each time you grab your component data

#

for one iteration per entity

#

you basically reload cache

robust scaffold
#

My entities? A pile of NAs is just that. Arrays of ints or structs of ints. It's the best cache friendly format

rustic rain
#

if you only work with it

#

and only it

robust scaffold
#

You can not get any better than NA<int>

rustic rain
#

but if you work multiple data at the same time

#

where you need data from several arrays

#

you end losing cache value with every call

#

to different array

robust scaffold
#

What, is the cache reloading every time two arrays are called? What do you think is happening when two native arrays are added together and written into a third? The classic example of vectorization is pointed to as good cache utilization because its linear access. Despite multiple arrays

rustic rain
#

it is realoding when you need to access 2 parts of memory

#

and even your arrays will be multiple parts of memory, because cache can't load it all at once

#

so it all be chunked for it anyway

robust scaffold
#

It can load from two sections of memory simultaneously. Divide up the cache into 2 parts for data from two sections of memory. It's not one continuous block

rustic rain
#

yeah and then you end up loading memory x N times per array used

robust scaffold
#

It can load from parts of an array as well. Load 64 elements from one, 64 elements from a second, and 64 elements from a third and so on

#

What do you think a chunk is? It's a 16KB section of memory with multiple NAs

rustic rain
#

what I'm saying is that in case of chunks - it loads chunk and boom. YOu can access any data from entitiy - all already loaded in CPU cache

#

meanwhile in your case

#

for each component

#

it'll have to access dfiferent parts of memory

#

and what if some of it's memory will be in RAM and not L3 or smth?

#

yeah, it's good when you want to just iterate over 1 array only

robust scaffold
#

So? It's just one initial access to declare that these memory locations will be required for the execution of this job

rustic rain
#

but when it comes to multiple, it seems slower

rustic rain
robust scaffold
#

And plus, what is there to be intelligent about? It knows it has it's set cache size. It knows which arrays are required

rustic rain
#

it's still less fast though

robust scaffold
#

It's a simple division operation to calculate the amount of elements it can load into the cache at once from every array

rustic rain
#

in case of chunks you load 1 chunk per lots of entities

#

let's say per 32

#

so per every 32 entities it'll load slow memory 1 time

#

and in case of multiple arrays, it'll have to access slow memory x N component type times

robust scaffold
#

Not all 32 entities will be able to fit though. That cache is shared between all compute applications using whatever memory they want as eell

rustic rain
#

in best case scenario for not less than 32

robust scaffold
#

In a completely isolated cpu running only your program, yes chunks can be read in sequence and fit in perfectly. But when other applications are also running, nothing will be in sequence

rustic rain
#

chunks usually contain even more

#

I mean, sometimes it's literally 139 xD

robust scaffold
#

I'm just saying, this entire discussion can be concluded with a simple performance test. Generate a random number from one value and write that into an output.

rustic rain
#

but it's not about reading chunks in sequence

#

it's about reading contents of chunk

robust scaffold
#

One would assume reading and writing from one array is better than doing so from a set of linked arrays

#

That's what a chunk is. A linked array set

rustic rain
robust scaffold
#

Okay. Have 10 arrays of size 10,000 vs 10 structs containing 10 arrays of size 100

#

In fact, I dont need to do that, ArowX has that benchmark on the forums

rustic rain
#

as long as chunk size is ~ size of chunk in entities

robust scaffold
#

Have the arrays be of 4x4 TRS matrices and read and write to a corresponding float3 position value.

rustic rain
#

no no sir, I specifically mean what I mentioned above

#

this is what I think is worst case scenario for multiple array approach

robust scaffold
#

I'm standing by ArowX's benchmark post as my proof that a size 10,000 NA performs better than an equivalent chunk implementation

rustic rain
#

1 array? or multiple arrays?

robust scaffold
#

Just have 10 position values multiplied against a 4x4 TRS then

viral sonnet
#

you have to ask yourself, is it practical?

#

isolated tests can be made faster. doesn't mean they are worth anything in practice. like how often do you use a float3 alone? if a single value is important why use float3. if you add/multiply/etc... a bunch of float3s they are as fast

#

to add something to the discussion. chunks will be slower as they are not linear in memory. but when i say slower. it'll be marginal. like extremely small. a quite good test is reading nativelist/array against nativestream. nativestream also uses small blocks of memory (4k)

robust scaffold
#

The smaller the block, the higher the cost vs linearly arrayed elements. Which is why chunk size should be maximized

viral sonnet
#

totally with you, the chunk size of 16k is not good. with their enabled comp feature they seem to be doubling down though

rustic rain
viral sonnet
#

entities that are rarely added/destroyed and are big should have at least 32/64k

rustic rain
#

I'll do test

#

here's array approach

#

where ```cs
private static float4 DoWork(float a0, float2 a1, float3 a2, int a3, int2 a4, int3 a5, float4 a6, int4 a7,
float4 a8, int4 a9)
{
var kek = a0 * a1;
var lul = a2 * a3;
kek /= a4;
lul /= a5;

        var adds = a6 + a7;
        var subs = a8 - a9;

        adds = new float4(adds.x * kek.x, adds.y * lul.x, adds.z * kek.y, adds.w * lul.y) / lul.z;
        adds *= subs;
        return adds;
    }
viral sonnet
#

do yourself the favor and write a performancetest

#

will save a lot of time

rustic rain
#

now gotta do the same with Entities

viral sonnet
#
    "name": "Tests",
    "rootNamespace": "",
    "references": [
        "UnityEngine.TestRunner",
        "UnityEditor.TestRunner",
        "Unity.Burst",
        "Unity.Jobs",
        "Unity.Jobs.Editor",
        "Unity.Collections",
        "Unity.Collections.BurstCompatibilityGen",
        "Unity.Entities",
        "Unity.Entities.Tests",
        "Unity.Entities.Editor",
        "Unity.Entities.Editor.Tests",
        "Unity.PerformanceTesting",
        "Unity.PerformanceTesting.Editor",
        "Unity.Entities.Hybrid",
        "Unity.Transforms",
        "Unity.Mathematics"
    ],
    "includePlatforms": [
        "Editor"
    ],
    "excludePlatforms": [],
    "allowUnsafeCode": true,
    "overrideReferences": true,
    "precompiledReferences": [
        "nunit.framework.dll"
    ],
    "autoReferenced": false,
    "defineConstraints": [
        "UNITY_INCLUDE_TESTS"
    ],
    "versionDefines": [],
    "noEngineReferences": false
}``` here's an asmdef for it
#

the annoying part of performancetests is setting them up. asmdef, boilerplate code. once done. excellent. saves so much time and timings are accurate.

#

i'll post a class to test ecs also. courtesy of some forum member with an anime avatar whose name i can't remember

rustic rain
#

let's see

#

oh wait, forgot to assign values to entities

#

also ReadOnly attributes

robust scaffold
#

More prep for 1.0

viral sonnet
#

posted 2 mins ago. nice!

robust scaffold
#

gotta continuously refresh the forum page

viral sonnet
#

F5 dat sheet

#

prepare for disappointment with your post ๐Ÿ˜„

robust scaffold
#

Hahahahahaha. I am 99% sure it's gonna be a no.

#

If it's a yes. I'm uninstalling 2023.1 and going back to entities.

rustic rain
#

what are these errors?

robust scaffold
#

use ref?

rustic rain
#
        public partial struct TestJob : IJobEntity
        {
            public void Execute(ref ResultComp result, in FloatComp a0, in Float2Comp a1, in Float3Comp a2,
                in IntComp a3, in Int2Comp a4,
                in Int3Comp a5, in Float4Comp a6, in Int4Comp a7, in OtherFloat4Comp a8, in OtherInt4Comp a9
            )
            {
                result.value = Test.DoWork(a0.value,
                    a1.value,
                    a2.value,
                    a3.value,
                    a4.value,
                    a5.value,
                    a6.value,
                    a7.value,
                    a8.value,
                    a9.value);
            }
        }
#

I mean

#

why?

robust scaffold
#

IJobEntity

rustic rain
#

I want RO access

robust scaffold
#

cursed

#

IJobEntityBatch

rustic rain
#

ok let's go

#

huh

#

maybe, I should test in build

robust scaffold
#

the length of them

#

not the actual number of arrays

rustic rain
#

10k not enough?

robust scaffold
#

100k. You're measuring in the nanoseconds

rustic rain
#

all right

#

I also need separate project for this

#

so I can actually test it in build

#

ok, here's editor

#

here's build

#

welp

#

array wins by 2

#

@robust scaffold what would be fair IJobFor settings for that kind of array?

#

I want to test parallel too

#

job.Schedule(sampleSize, 16).Complete();

#

array batchSize

#

sampleSize = 10 mil

#

Editor

#

I'll play a bit with values

#

smaller sampleSize yields same result

#

huh

#

I mean

#

batchSize

#

for parallel in arrays

#

let's leave it at 16 then

#

interesting

#

pretty much same result

#

I'd say

#

chunks win, because in real life you won't have such nice synthetic 10 mil array xD

rustic rain
#

yeah, but if you'd need to have a query over multiple archetypes

#

you'll run into a same problem, why chunks lose here

#

they do way more job, than just iterating over 1 large array

#

combining multiple arrays

#

per archetype

#

and etc

#

I have a feeling, if pure array equals to perfomance with chunks, that means chunks compensate somehow

#

for such losses

robust scaffold
#

Chunks compensate with flexability. If you know beforehand the archetype of the entities you're creating and the way you will be using them, hardcoding the array is faster

#

Not faster in coding time, but faster in performance

rustic rain
#

ofc hardcoding it is faster

#

but then you will have a very hard time creating mechanics along that hardcoded stuff

#

I'v been there, kek

#

this project... this is my 5th full redo

#

from scratch

#

kind of how I learn ECS, kek

#

everytime I recreate it better than it used to be

#
  1. dots ecs, 2. full OOP, 3 another dots attempt, 4 managed dots ecs attempt (works ok btw), 5 current fully unmanaged attempt
#

so far only 2, 4 and 5 worked out

pliant pike
#

I've done that I have tons of projects where I've started with dots and got better over time