#archived-dots

1 messages Β· Page 11 of 1

rotund token
#

from my experience, the bigger the job the better overall performance

sharp stump
#

error CS0104: 'TreeView' is an ambiguous reference between 'Unity.Editor.Bridge.TreeView' and 'UnityEngine.UIElements.TreeView'

#

whatntha heck?

#

I just installed entities and this error is here.

rotund token
#

what version of unity

#

and entities

sharp stump
#

2022.1.0f1 and entities 0.51.1-preview.21

rotund token
#

you need to stick to 2021.3 for 0.51

rustic rain
#

did they give any ETA yet?

sharp stump
#

So I moved to 2021.3 and now there are several of these : error CS0117: 'JobsUtility' does not contain a definition for 'GetSystemIdMappings' πŸ˜„

rustic rain
#

21.3.4f is minimum

robust scaffold
viral sonnet
#

is l1 cache and stack speed somewhat comparable?

rustic rain
rustic rain
#

hmmmm

#

any idea why prefabs spawned during runtime and rendered through SpriteRenderer

#

don't render in scene view?

viral sonnet
#

while the game is running?

rustic rain
#

yeah

viral sonnet
#

hm, no idea

#

maybe scaled differently? too big, too small?

rustic rain
#

no

#

normal size

dreamy glade
#

Any way to manipulate a rendermesh while in a .scheduleparallel() for each loop? (In hopes to be burst compatible) If not, I would love to understand why something like that isn’t possible. Thanks. (:

rustic rain
#

oh wait

#

RenderMesh

#

it's managed component (all shared are)

#

burst does not support managed data

robust scaffold
#

Like the HR's render mesh? It contains a Material and Mesh property. Both classes. So no burst.

rustic rain
#

since they are stored in managed list

robust scaffold
rustic rain
#

well yeah, kind of

robust scaffold
#

Strange set of errors I've been getting lately. It's an editor error and I dont think it affects the actual play

rustic rain
#

oh

#

you have a process of UnityEditor

#

somewhere

#

which wasn't closed

#

just force close all processes of Unity

#

it'll get fixed

robust scaffold
#

Thats so odd

rustic rain
#

kill them all ^,...,^

robust scaffold
#

10,000 simultaneous box collisions: 2.5ms total. Half of that is the single threaded BVH builder.

#

Circle colliders about 0.2ms faster per thread.

viral sonnet
robust scaffold
rustic rain
#

just gotta split managed shared and unmanaged

#

so if they won't implement it, that would really mean they lack workforce

viral sonnet
robust scaffold
rustic rain
#

it's all meaningless if they won't be able to implement unmanaged share comps πŸ˜…

robust scaffold
#

Does anyone have any experience with mem-move?

#

Is this logic right for inserting a value at index inside an array?

#

Where vertices is a large stackalloc array

rotund token
#

seems fine

robust scaffold
# rotund token seems fine

Missing a pointer. I think this is now right. Im worried about off by 1 errors though. Edge.Index starts at 0.

robust scaffold
#

I think it works but wow, finding penetration depth is extremely expensive. For 10,000 entities overlapping with only 2 other identical box entities, it costs 3ms per thread. That's the same as the total amount of time to generate the BVH, find overlapping entities, and determine if they're colliding.

#

Im gonna see if Unity physics has any better idea. Or the interwebs, than this brute force method

viral sonnet
#

arrowx has started another exquisite thread. been a long time

robust scaffold
#

I mean, that is what I'm doing with these collision checks but getting usable per instance data out of it is extremely expensive.

#

Arowx has been haunting the forums for so long, his user ID is in the tens of thousands whereas the usual member is in the mid millions.

viral sonnet
#

to double check. the loop is unrolled and vectorized, right?

robust scaffold
#

For that, in order to get vectorization, you want to memcpy then conduct the multiplication on a float*, not a float3

#

Unrolling for burst is most recognized for single scalar operations.

viral sonnet
#

mh i see. then why are there 2 fors?

#

and 2nd question, is unrolling important here?

#

i was under the impression burst + mathematics output the best assembly for such a simple use case

robust scaffold
#

the second jump is the actual for loop.

#

For this, you might get it unrolled if you use a float4 array. float3 results in unaligned vectorized operations (not aligned to 16 byte wide or float4 width)

#

This is unrolled operation. Notice how the original math is operating on a single scalar float to allow burst the best chance to recognize and unroll

#

Also how there's 4 identical operations just shifting pointers after another. That's the most obvious sign of unrolling

viral sonnet
#

yeah, right! and unrolling is nice for scalar values but not so much for values that can already be packed, right?

#

with float4, less instructions

robust scaffold
#

try making multiplier a float4

viral sonnet
#

only change is a vmovups instead of vbroadcastss

robust scaffold
#

Huh, guess not then.

viral sonnet
#

i don't think there's any point in unrolling here. it won't work faster when 4 instructions are behind each other. the loop essentially does this anyway - just trying to figure out when to focus on unrolling

robust scaffold
viral sonnet
#

true dat

robust scaffold
#

Actually, it's 128 bytes at once. 4 bytes in 1 float, 4 floats in a packed single, modern chips have 2 packed singles in a single vectorized operation. And 4 operations means 128. Unrolling means entire cache line operations at once.

viral sonnet
#

so why is this not unrolled then! i see no reason

robust scaffold
#

Burst not that intelligent? No clue.

robust scaffold
#

for (var i = 0; i < 64; i++)

viral sonnet
#

wait no, something weird was happening with burst. this is the assembly

#

ah fuck. the assembly is lagging behind. above is for float, not float4

#

i think i queued 2 changes on accident haha

robust scaffold
viral sonnet
#

can't get float4 to unroll

robust scaffold
#

Guess not, huh

viral sonnet
#

and float unroll with length

robust scaffold
robust scaffold
viral sonnet
#

i'm pissed that we haven't found unity earlier. we were still writing our own c++ engine around 2009 and failed hard

rotund token
#

Still 5 digits πŸ˜‹

viral sonnet
robust scaffold
viral sonnet
#

instruction size exceeded with float4 or what's going on here that the unroll is not happening?

#

wait that can't be. i've seen 512 sets

#

around that time unity was really unknown. i mean i was in gamedev.net pretty much daily and haven't heard anything about it.

rotund token
#

I went from failing at ogre3d to unity

#

Not sure why

viral sonnet
#

how did you find it tertle? yep, we also dabbled in ogre3d

rotund token
#

I think probably because it had c#

#

I started in 2.0

#

A month or so before 3.0 came out

#

I think my forum account is a year or so younger than I actually started working with it

viral sonnet
#

i still remember this 13 year old kid from the ogre3d forums who was a shader wizard and wrote some pretty good SSAO shaders

robust scaffold
#

Imagine the legions of free labor just going wasted out there. Playing video games and having fun when instead they could be leveraged to pump out hlsl.

dreamy glade
#

Anyone know of a way to convert a dynamic buffer (containing 1 float3 in each element) to a native array of float3's?

#

Or to ask another question, is there a way to make a dynamic buffer hold float3's rather than a dynamicBufferElement? Hopefully that'll at least better explain what I'm try to accomplish. Thanks.

rotund token
#

Do you need a copy? Or directly point to same memory

#

Reinterpret<float3>()

#

Then AsArray() to change it to a native array

#

Note it'll point to same memory so changes in native array with affect buffer

#

Clone the array if this is not desired

#

But yeah Reinterpret is what you're looking for

#

Exists on both buffer and native arrays

robust scaffold
#

I need someone who knows C# to tell me if this works:

#

I am fixing a ref return property of a interface

#

Will this work?

#

It does work, that is wild.

#

I am generically obtaining the pointer to a float property.

#

This is cursed c#.

#

It works in burst as well. Generics is a pathway to many abilities some consider to be unnatural...

viral sonnet
#

i think i need some context why you are amazed by this because i have seen you doing this a bunch of times. what i see is that you are juggling a pointer several times and I don't really get why you are not just using the pointer

#

the variable I don't see is X and what it is

robust scaffold
#

Two implementations of IPolyShape.

viral sonnet
#

so in the get, why not UnsafeUtility.AsRef<float> ?

#

and you don't need to pin. it won't leave memory

robust scaffold
#

As for why generic method, I'm trying to make one method for both a box and a polygon. Box is just a polygon with 4 points and special math.

robust scaffold
viral sonnet
#

UnsafeUtility.AddressOf might also work. you can typecast the void* to float*

robust scaffold
#

That simplifies the box ref at least

viral sonnet
#

yep a bit cleaner. the UnsafeUtility methods are really cool

#

i'm interested if the assembly is actually any different with AddressOf vs pinning

robust scaffold
#

No clue, I am nowhere near ready to check assembly right now. Slowly crunching through this tutorial

viral sonnet
#

the AddressOf code is pretty much the same. they also just return &var. the interesting bit is that it won't compile if you write it like that instead of using the method

robust scaffold
#

I think this also works to obtain the index of the maximum value in a float4:

viral sonnet
#

i don't get it haha that shit is wild

robust scaffold
#

This returns the vertex that defines the support point in a specific direction.

#

And this is what bitmask does. Turns a bool4 into 4 bits.

viral sonnet
#

funky thanks πŸ˜„

robust scaffold
#

This is why I want the generic float pointers, so i can get everything into neat float4 operations.

#

I think this is right. The repo I'm scraping this physics engine from is in standard unoptimized scalar math.

rustic rain
timber ivy
#

if i run a custom conversion system on an object will components like SceneSectionComponent still get used?

rotund token
#

do you mean just implementing a GameObjectConversionSystem?

#

because all that's doing is adding into the pipeline

#

every other conversion system still runs on it

timber ivy
timber ivy
#

Thank you

rustic rain
#

conversion is just like other ECS systems

#

the only difference

#

they only update once when there are game objects to convert

#

they even follow same achitecture with update groups

rustic rain
#

smth super weird going on

#
            _query = state.GetEntityQuery(new EntityQueryDesc
            {
                None = new[] { ComponentType.ReadOnly<InteractionSound>() },
                All = new[] { ComponentType.ReadOnly<SoundInstance>() },
                Options = EntityQueryOptions.IncludeDisabled
            });

I have this

#
            _query = state.GetEntityQuery(new EntityQueryDesc
            {
                None = new[] { ComponentType.ReadOnly<SoundInstance>() },
                All = new[] { ComponentType.ReadOnly<SoundSource>() },
                Options = EntityQueryOptions.IncludeDisabled
            });

And I have this

#

oh, f

#

nvm

rotund token
#

am i insane thinking about updating BuildPhysicsWorld on frames that don't tick fixed update

rustic rain
rotund token
#

I don't want to tick the simulation

#

Just update the world to have new entities and remove destroyed entities

#

if the fps of my world is > the fixed rate fps

#

then when new entities are created and I do queries outside of FixedUpdate then there is a (good) chance they won't exist in the world

#

(same thing if you destroy, might still have destroyed entities in the world)

#

this is not something i've really had an issue before

#

until i moved to a complete change filter setup

#

so i'm only ever going to query once on the first frame of a change and if the entity doesn't exist in the world everything breaks 😐

#

i moved logic into the fixedupdate but it just causes more issues

#

since not all the logic can move in there

#

so instead i'm just thinking, what if fixed simulation system group doesn't update this frame, just manually update BuildPhysicsWorld

rustic rain
rotund token
#

yes

#

but if my fps is higher than the fixed update

#

my update loop will run multiple times before fixed update ticks

rustic rain
#

ah

#

glitches

#

yes

#

how about using FixedStep ECB?

rotund token
#

considered it

#

but you can't create entities from Update in fixed step ecb

#

without leaking

rustic rain
#

or if you really want to try normal update, why not just do it?

rotund token
#

if your update loop is 4x fixed update then you leak 4 frame tempjob thing you've probably seen

rustic rain
#

all you gotta do is just change update groud

rotund token
#

?

rustic rain
#

Foreach system that updates in FixedStep, remove from update list and add to update list of simulation group

#

no?

rotund token
#

i don't want to update physics in Update

#

if you want physics to update in Update you can just access FixedStepSimulationGroup and set RateManager to null

#

and it'll just work like normal

rustic rain
#

ah,

viral sonnet
#

tertle, wouldn't it be easier to move the systems in question to fixedstep?

rustic rain
#

I figured, that another solution: personal ECB

#

if it's only entity instantiation

#

then can be done in a very simple manner

#

so instead of creating command buffer

#

you simply access list/array or whatever

#

or stream

viral sonnet
#

i figured the problem isn't just about ecb. the physics world is only built in fixed steps so in between, entities that are added/destroyed are either still able to be raycast or not

rustic rain
#

that has no non-persistent allocations

dreamy glade
robust scaffold
robust scaffold
safe lintel
#

@rotund token btw what were the hybrid renderer changes in 1.0 for unique meshes(saw you mention this in a forum thread)?

robust scaffold
#

Honestly, after setting up now 2 custom render passes for sprites and lighting, the BRG seems extremely unwieldy when you can do the exact same thing with a ComputeShader and DrawProceduralIndirect. Far less unity keywords, strange custom formatted input buffers, and opaque defines.

#

The only major advantage of using the BRG is the ability to setup and dispatch draw commands in a job. Or at least schedule the commands in one and then unity does whatever they do in the engine black box.

#

For a practical example, in my sprite renderer system, I must call complete dependency on the system following execution of a setup job to release any safety handles on NativeArrays of GPU data I'm putting together in the CPU. Potentially, I might be able to delay this to just before the rendering system kicks off but that means two separate systems to do the work of one temporary solution. The lighting rendering system however I am looking into that completion system. Maybe one that forms a generic completion and upload to GPU.

safe lintel
#

hm is that test scene in the post of 24k implying that each mesh/material is unique, so 24k unique types or just there are a handful few different types?

robust scaffold
#

Unless Unity has reinvented a new graphics driver along with this pipeline, there is no way that is possible with the current driver API.

#

I see 4 individual GO meshes and 2 separate materials. That's reasonable. Each GO may have unique per instance data but that's fairly standard for instanced drawing, or drawing in general.

safe lintel
#

yeah, being able to create commands directly from a job sounds nice, I was using drawmeshinstancedindirect with a 1 frame delay so I didnt need to use .Complete

robust scaffold
#

1 frame delay causes stuttering in movement when combined with a physics engine (this was back when I was using Unity's default Box2D, maybe different when I implement my own). The cost of rendering is comparatively insignificant so i havent invested a lot of effort in making it run optimally.

safe lintel
#

ah thats true, my particles were just dumb transforms

rotund token
#

your fps drops below 60 (or whatever your fixed update tick is)

#

and you are in a death spiral

#

there's no point for these systems to be in fixed update, they don't affect the physics simulation

#

they just want to use the spatial map for querying

#

so what would be the harm in updating the spatial map every frame?

#

then you could just use it in Update with always up to date data

#

i still haven't thought of a downside of doing this - except it didn't work as expected first time i tried ^_^'

robust scaffold
rotund token
#

yes but if it's any more than 1

#

it still causes issues

rotund token
#

i thought it was in the batch render group api stuff kornflaks posted

viral sonnet
#

does it make any sense that buildphysicsworld can run twice?

rotund token
#

yeah i thought about that - just removing it entirely from fixed update

#

but i realized it does because you could destroy an entity on collision

#

after the step stage

#

or create new entities

viral sonnet
#

so if you don't use that it should be good

rotund token
#

yes

#

wait no

viral sonnet
#

create/destroy at that stage ... hm I don't like that

rotund token
#

you could move in the bvh

#

and your bounds would change

robust scaffold
viral sonnet
#

oh right. ..

#

i find the physic death spiral design so dumb

rotund token
#

this is basically what i'm testing

    [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    public struct FixedStepUpdatedSystem : ISystem
    {
        private EntityQuery query;

        /// <inheritdoc/>
        void ISystem.OnCreate(ref SystemState state)
        {
            this.query = state.GetEntityQuery(ComponentType.ReadWrite<PhysicsUpdated>());
        }

        /// <inheritdoc/>
        [BurstCompile]
        void ISystem.OnUpdate(ref SystemState state)
        {
            this.query.SetSingleton(new PhysicsUpdated { Value = true });
        }

        /// <inheritdoc/>
        void ISystem.OnDestroy(ref SystemState state)
        {
        }
    }```
#
    [UpdateInGroup(typeof(SimulationSystemGroup), OrderFirst = true)]
    public partial class BuildPhysicsUpdateSystem : SystemBase
    {
        private BuildPhysicsWorld buildPhysicsWorld;

        /// <inheritdoc/>
        protected override void OnCreate()
        {
            // TODO remove just testing
            var fix = this.World.GetExistingSystem<FixedStepSimulationSystemGroup>();
            fix.Timestep = 1 / 30f;
            // TODO end

            this.buildPhysicsWorld = this.World.GetExistingSystem<BuildPhysicsWorld>();
            this.EntityManager.CreateEntity(typeof(PhysicsUpdated));
        }

        /// <inheritdoc/>
        protected override void OnStartRunning()
        {
            this.RegisterPhysicsRuntimeSystemReadWrite();
        }

        /// <inheritdoc/>
        protected override void OnUpdate()
        {
            if (this.GetSingleton<PhysicsUpdated >().Value)
            {
                this.SetSingleton(new PhysicsUpdated { Value = false });
                return;
            }

            this.buildPhysicsWorld.Update();
        }
    }```
viral sonnet
#

if you have fps issues. don't make it worse. there's no reason to step more than once

robust scaffold
#

So complicated. So nice having full control over physics. Kinda. My collision detection is fucked...

robust scaffold
viral sonnet
#

yep, which makes no sense

#

i mean, in which case does this profit? some kind of fast forward simulation? i can step manually for that

#

in realtime, i see no reason

robust scaffold
#

For multiplayer rollback

viral sonnet
#

manually stepped

robust scaffold
#

And if there's a desync, a frame where fixed step updates more than once to catch up automatically is nice.

rotund token
#

you really want it to tick the same rate on client/servers

robust scaffold
#

Manual stepping can be done. Just turn off PhysicsWorld update then do it yourself.

viral sonnet
#

catch up is indeed nice for multiplayer. yet those physics systems are not really built for multiplayer. their design of multiple steps in a frame goes way back before that

dreamy glade
#

Is there a proper way to 'sleep' or more specifically, wait for the end of a frame to continue a function inside of a foreach loop within a system? Similar to how coroutines have WaitForEndOfFrame. Thanks.

robust scaffold
viral sonnet
#

a component system group is probably the best fit for this. There's also EntityManager.CompleteAllJobs(); and some other methods to force a sync point

rotund token
#

yeah that's my post

#

not the post where the info was from

safe lintel
#

oh right misunderstood what you said before

viral sonnet
#

that's for unmanaged sharedcomps, right?

#

i wonder what's taking them so long for this. seems like such a minor change on the surface

#

or does this just tie in the core of the render system and I'm overlooking something?

robust scaffold
#

Simple enough, I would imagine.

viral sonnet
#

yeah i dunno. must be reasons but i was honestly expecting this in 0.5

robust scaffold
#

Might be tied up in somehow allowing for shared components to be added during conversion / bake.

rotund token
#

minor change πŸ˜…

robust scaffold
viral sonnet
robust scaffold
#

Another code blurb. Calculate the normal vector formed by a linestrip point set:

#

Fully vectorized. The only section that dips into scalar math is the inverse length calculation.

#

Actually no it doesnt. rsqrt has a vectorized version:

rotund token
viral sonnet
#

then the question just changes, why wasn't it in 0.50 πŸ™‚

viral sonnet
#

is there any resource which elements already exist in ui toolkit? i need a list that can be reordered

robust scaffold
viral sonnet
#

yeah

robust scaffold
#

But there is no by default drag and reorder list in UI elements. It's pretty bare as intended.

viral sonnet
#

cool thanks! i googled and got to the 2019 doc. was a little sparse. should have figured lol

robust scaffold
viral sonnet
#

i can go from there. thanks

robust scaffold
#

I havent played around with UIE since 2019. But it has clearly evolved to become fully mature since then (unlike dots *cough*). Still no per element custom shader/material though. Wonder what's taking them so long.

#

I probably know why though. It's a single indirect draw call for all UI elements which is fantastic for performance but you can only have 1 shader per draw call. They'll need to develop their own UIShader that's compatible with their universal UI shader to allow it.

robust scaffold
#

10,000 circles. Each colliding with 19 other circles. Performance acceptable.

#

I've gotta say, unity's BVH really is fantastic. 10,000 entities each matching AABBs with each other. In that screenshot, 19 times.

robust scaffold
#

I've been seeing in some of the source there are comments mentioning jump tables for burst. Anyone know how to activate it?

rotund token
#

use when i think

#

article from 2019 though

#

tldr: instead of

        {
            case 10: outVal = 20; break;
            case 20: outVal = 40; break;
            case 30: outVal = 50; break;
            case 40: outVal = 60; break;
            default: outVal = 100; break;
        }```

```        switch (InVal)
        {
            case int _ when InVal == 10: outVal = 20; break;
            case int _ when InVal == 20: outVal = 40; break;
            case int _ when InVal == 30: outVal = 50; break;
            case int _ when InVal == 40: outVal = 60; break;
            default: outVal = 100; break;
        }```
robust scaffold
#

interesting, okay I'm gonna see if I can use this

viral sonnet
#

wait what. i read, and i think it was even in the docs that you only need to implement every case. that is a pretty roundabout way. shit. i need to rewrite switches ...

#

maybe they have improved it? i have never checked the assembly

#

I'm not getting a definitive answer if jump tables are actually better for todays cpu.

robust scaffold
viral sonnet
#

yeah, i just don't get why we have to use when

robust scaffold
#

Produces a jump table, I think

#

This produces the exact same result

viral sonnet
#

huh, so they do have fixed it

#

any ideas for a better coding style with this? basically i want to define stats to enable/disable them

viral sonnet
#

is there anything better than a bunch of if/endif

robust scaffold
#

You want to be able to toggle the existence of these chance modifiers per file? Where each file is its own spell?

viral sonnet
#

i have programmed a bunch of stats. it's for the asset. the incremental game i'm making uses not even half the stats i've defined and i wanted to make a stats editor anyway. what this editor should be able to is to enable/disable stats via checkbox and set the data type

robust scaffold
viral sonnet
#

i feared that. no i don't think so lol

robust scaffold
#

I dont think you can actually modify compiler defines from the editor without code generation anyways.

viral sonnet
#

that stats.cs is very simple. but yes, i'll use code gen for it. just not for everything

robust scaffold
#

Unless you want to go file by file and change #define for each one.

viral sonnet
#

setting directives is actually quite simple in unity. how would codegen even help me here? the solutions i've are all cumbersome af

#

that said, i have 0 experience with these new codegens

#

but i don't want to rely on some template or smth

robust scaffold
#

Oh, are these universal for all spells? Then a universal directive probably works. If these are per spell like some have a hitchance and some dont, then you'll need code gen.

viral sonnet
#

oh no, this is totally generic on that level

#

no individual spells involved

robust scaffold
#

Codegen is eh, It works in Unity but you need to open an actual C# NET project and then compile that project and add it as a DLL plugin to work.

viral sonnet
#

fk that

#

πŸ˜„

robust scaffold
viral sonnet
#

hm, i'd like some bitmask directive. i don't want to have 30+ smth directives in unity. that would be annoying

robust scaffold
#

I have a bitmask going. Burst compiles this into a jump table.

#

But this is fully dynamic, object against object collision call jump table.

viral sonnet
#

not really a bitmask smth like #if STATS_STRING[...] contains CRIT. i have to google a bit what's possible here

robust scaffold
viral sonnet
#

yep, sadly it's the most basic thing ever. how this never evolved is beyond me

robust scaffold
#

Code gen

#

Preprocessor directives are very inflexible. Code generation is the next frontier.

viral sonnet
#

ah yeah, the overengineered output of thousand of devs that is able to write text files

#

i'm a bit snarky because i've never seen one straight forward codegen example where i thought, yep, that's intuitive and really nice.

#

everything i've seen is, wtf is this. WHY

#

it makes textfiles and copy/replaces strings

robust scaffold
#

It's very flexible in copy pasting strings. You can use the entire library of C# logic to copy paste strings conditionally

#

Hrm, I dont know if this is just me but always label your method properties as either in or ref. If it isnt inlined, this will remove the burst move operations

#

Or just aggressively inline everything

rotund token
viral sonnet
#

it's an enterprise solution that can do a lot. i'm just looking for something in between. :/

robust scaffold
#

From my observations right now, the method call doesnt need the in but the method property list does.

#

Burst does constant fold / delete branches if statements if the conditional is constant.

#

I dont know how that will work with an editor setting the value though. But if you just have a const int value mask and a if/switch statement, it works identically to preprocessor defines

rotund token
viral sonnet
#

so i'm better of codegening some const bool hitEnabled?

rotund token
#

oh i recorded that in potato format

#

if you squint you can read it

#

just + the list, auto generates the asset, sets the id and off you go

viral sonnet
#

how does your code for calculating crit is handling this then?

rotund token
#

i dont have an example on hand since i'm in a different project

#

but the key is just an index to my stats buffer

#

i just assign it to the system via config

#
int critChanceIndex;
NativeArray<Stat> statBuffer;

var damage = statBuffer[baseDamageIndex].Value + math.select(0, 1, rand.Next() < statBuffer[critChanceIndex]```
#

something like that i guess if i was to write it in notepad right now

#

i guess it's a bit different depending on your objectives

#

my system is meant to be usable in any project with any number of stats

#

a designer should not have to change code to add stats is my objective

robust scaffold
#

Not the best for vectorization though

rotund token
#

it's never going to vectorize well

robust scaffold
#

That indirect to the statbuffer will prevent any vectorization of calculation of damage

rotund token
#

but it doesn't need to

#

you might have 100s of damage instance

#

but they'll only calculate damage usually once

#

and only 1 or 2 entities per chunk

robust scaffold
rotund token
#

chunk capacity of 640 atm~

robust scaffold
#

Ah, okay.

rotund token
#

but only 1-2 need to update their damage

robust scaffold
#

My chunk capacity's at 42 right now

#

It aint good let me tell ya

rotund token
#

is that just physics components?

robust scaffold
#

It's everything

rotund token
#

oh not so bad then

#

i mean, chunks at work are lucky if they're 6 ^_^'

robust scaffold
rotund token
#

trying to avoid it in my own project

#

so painful though using multiple per entities

#

i should just go back to everything -_-

robust scaffold
#

Im thinking about moving the poly to a unsafe list but polyreal is directly vectorized in collision code. It's only hardcode max 8 points as well.

#

The issue of course is that there's no way to convert a unsafe list. Maybe a dynamic buffer....

#

But dynamic buffer is 16B, I only need 8 as these lists are NaN terminated.

#

Ah I remember why I dont use dynamic buffers. I strongly dislike the API

#

The main problem with Dynamic Buffers is that BufferTypeHandle is so much shorter than ComponentTypeHandle so in my vertical spacing formatting, it just generates so much empty space.

viral sonnet
robust scaffold
#

Just look at this. Everything's nice and organized accessing pointers from handles. Then you get the BufferAccessor blurb.

rotund token
#

well i guess, is your stat system generic?

viral sonnet
#

oh and your index in the statBuffer has to exist. the question is, why do stats exist that are not used

rotund token
#

and it was fine memory wise up to a lot of stats

#

and much faster if i don't have to check

#

and solves so many calculations

#

i can write direct to index

#

without adding/removing/findingelement

#

the only thing it costs is the single job calculating the final value

#

which is annoying as it's slowest part

#

but i'm happy to live with that for convenience everywhere else in my project

viral sonnet
#

i'm not concerned about the stat system itself but the systems that are using it. lots of bloat. like i said in the beginning. i would only use half of them in my project. a have thousands of monsters with stats that are not used then. not good.

robust scaffold
viral sonnet
#

so, this?

#

otherwise i'm not getting what you want to tell me πŸ˜„ either way, i think my best options are now compiler directives or using constants and check if burst removes the code paths. (it probably will)

rotund token
#

oh i think i was slightly off from what you're trying to do

#

you just want to remove some stats from your damage calc etc

#

because your game won't ever use those stats?

viral sonnet
#

yep

rotund token
#

precompiler grossness πŸ˜„

#

i really wish ides would process precompiler paths optionally

#

so easy to break things

viral sonnet
#

yeah i wanted to avoid that πŸ˜‚

rotund token
#

or if there is, please let me know

robust scaffold
#

Code gen is that way...

viral sonnet
#

i hate directives in my code

robust scaffold
#

IDEs have full support for code gen functions

rotund token
#

it's still a huge pain to go through and test every config

#

to make sure you haven't broken something at some point in the past

#

because it requires recompiling not as simple as a basic unit test

viral sonnet
#

i'd need to codegen the whole method and parts of my jobs

#

i don't quite see the gain of it

robust scaffold
#

Do you really need to make this a conditional?

viral sonnet
#

yes πŸ˜„

robust scaffold
#

You're gonna need those directives everywhere then.

viral sonnet
#

haha this is too ugly. i'll give constants a try

#

or better yet, i'll sleep over it and think about codegen. might be a nice learning experience

#

i've encapsulated this well enough that my brain shouldn't explode from it

robust scaffold
#

So many dot products. So so many dot products. Dot products apparently are key to rendering and physics.

#

I've got to say, pokemon progress bars is an amazing plugin

robust scaffold
#

What a man has to do to reinterpret a fixed buffer.

#

Another vectorized snippit. Counting the number of elements in an array that is NaN terminated:

#

Vectorized.

#

Originally this horrific comparison table:

#

It's so good, now the normal calculation has been unrolled:

robust scaffold
#

Also, dont forget to plaster AssumeRange on int counters passed to functions if you know it's at least 1. Removes 1 early jump to return but when horizontal space in the burst inspector is rationed by the number of jumps, reducing one from the rainbow is valuable.

#

You can also stick it on functions that return ints.

robust scaffold
#

tzcnt is so useful holy shit. I've placed it everywhere now.

timber ivy
#

is there an attribute for a system to run in fixedupdate?

rotund token
#

You just add it to the fixed update system group

#

This isn't the same fixed update as physx though

timber ivy
#

is it just an attribute or something?

timber ivy
#

Ah yep I guess its just this

viral sonnet
# robust scaffold

seems it's not important here to get an accurate count, right? a bitmask of 0100 would return 2, right?

#

because in that case, would a math select work too?

#

for an accurate count you'd need a left shift before hand. just thinking out loud

#

and what about 1011? the count would be 0

robust scaffold
robust scaffold
viral sonnet
robust scaffold
#

Tzcnt will then return: 4 + 0. But the count should be 5.

viral sonnet
#

you sure this works? i'm just testing the output for just float4. no nan return 32 for example

robust scaffold
#

Since bitmask does flip, it returns: 0000 1110.

viral sonnet
robust scaffold
# viral sonnet

Oh, bitmask returns an int. Not just a bit4. If there is no NaN in the float4, there needs to be a final math.min(tzcnt, 4)

#

There will be no situation in which there is a value past the first NaN. So something like (1, NaN, NaN, 1) will not be possible.

viral sonnet
#

ah i see. ok this clears things up

robust scaffold
#

0, 1, 2, 3, 4, NaN, NaN, 7, 8 will throw an error. Not from any of the math functions but a custom verification check at conversion

#

hopefully the min check doesnt break the vectorization

#

ugh, adds 2 extra commands

#

Doesnt break unrolling though which I'm happy with

viral sonnet
#

pretty cool that tzcnt is hardware level

robust scaffold
#

Yea, there's even a vectorized componentwise version. But in this case it's not used

#

Like... you could...

#

Here's an alternative that reduces the number of scalar operations to a minimum. Max number of elements in the list is 32 though.

#

Wow, this performance is amazing. 7ms for 200,000 collisions simultaneously (box - box). Each box (10k) is colliding with 19 other boxes.

#

For comparison, this is what happens when 200k circle collisions (4ms):

#

And this is the actual most complex interaction, 200,000 polygon - polygon collisions (12ms)

rustic rain
#

bruh, sir

#

can't you make it compatible with Unity Transforms? xD

#

you are teasing me so hard with those results

robust scaffold
#

So this can use 3D transforms. Just you'll be wasting a lot of the chunk capacity for empty float values

rustic rain
#

the reason behind 3D transforms

#

is because it's compatible

#

with everything

#

you don't have to reimplement lighting, renderer and etc

#

besides

#

it's also compatible with 3D

#

kek

#

which is also required is certain applications

#

unless you want to implement patches for that

robust scaffold
#

I mean, you can replace all my 2D transforms with 3D and it'll work perfectly fine: This is the only interaction between my 2D O2W and the actual physics components.

robust scaffold
north bay
#

I took a look at my games performance using superluminal, 80% of my execution time is spent on releasing semaphores? Am I reading this correctly?

balmy thistle
north bay
#

Mostly job system stuff

#

Yea it's using DOTS Netcode buut it seems like all the semaphores are just coming from scheduling and completing dependencies

#

This is only the main thread execution time by the way

robust scaffold
north bay
#

I sampled without fps lock or vsync, running at 125fps and it's barely GPU bottle-necked

robust scaffold
north bay
#

Yea but those ReleaseSemaphore calls are not sync points, it's just notifying the job system about work (I think)
If I would have sync points I would expect the main thread to spend time idling on WaitForSingleObject...

viral sonnet
#

its waiting for jobs. look at the inclusive time. it's nit actually doing anything

#

here's a profile of my project

#

Semaphore_Release is very small

#

the unity profiler timeline will give you much better clues what's going on

robust scaffold
#

Wild, actual statistics. I just read the burst output and hope.

north bay
viral sonnet
#

sorry, meant exclusive time

#

i find the function list not that useful

#

call stack is much better. the time is spent somewhere. otherwise there's still some vsync or smth going on

rustic rain
#

Profiling threaded code without timeline is a waste if time imo

#

Some things are literally x16 times bigger than they actually are

north bay
# viral sonnet call stack is much better. the time is spent somewhere. otherwise there's still ...

I guess the callgraph or looking at the timeline would be useful if I would have some sync points to look at or other spikes, but the execution time is pretty well spread across my ~460 systems
Per frame it's spending 12.5ms on ReleaseSemaphore kernel calls
I'm only looking at the main thread time, I have very very little time in which the main thread is actually blocked by a worker

But apparently this got better in 2022.2 (?) https://twitter.com/s4schoener/status/1550477564266815493?s=20&t=AohVWX2IlOp5xY8BxdiiOg

Probably the most significant change from my POV is that 2022.2 ships with a new job system. The old one was stretched far beyond its intended use and I have frequently seen customer projects spend ~25% (!) of main thread time just on job overhead (kernel calls on main thread).

robust scaffold
#

A close second favorite of mine is the removal of DisposeSentinel from NativeArray. That thing is finally fully unmanaged

north bay
#

No clue, I also haven't tried it out yet 🀷
But apparently even the jobs debugger got faster

robust scaffold
#

Holy shit, NativeArrays in IComponentData in 2022.

north bay
#

You can also now schedule IJob from burst without using that weird IJobBurstSchedulable thingy

robust scaffold
rustic rain
robust scaffold
rustic rain
#

Well, how else would it work?

robust scaffold
#

NA is just a pointer and an int for length at bare minimum. There's a bunch of safety for read write and race conditions.

rustic rain
#

Hmm

#

Pretty sure it's unsafe list like that

#

Meanwhile native collections actually allocated in struct

robust scaffold
#

No, NC are definitely not fixed buffers. That's the FixedListXBytes.

rustic rain
#

Not fixed

#

Hmmm

#

I'm confused

robust scaffold
#

Allocated inside a struct is fixed. Pointers to the heap is what NCs are.

rustic rain
#

Then what is even a difference between unsafe and native list?

robust scaffold
#

If you never resize an UnsafeList, it's an NA. If you do, it's a NL.

#

Lists just have that little bonus where it also has an int for count and a second int for capacity. NAs just have 1 int for length.

rustic rain
#

Then I am really confused why you can't have arrays of arrays

#

And forced to use unsafe lists

robust scaffold
#

You can do NA<UnsafeList> as well

#

Just not nested NAs because NAs also have that race condition safety system and nesting NAs prevents the safety system from working.

rustic rain
#

Why not native of native?

robust scaffold
#

Native has safety. Unsafe does not.

rotund token
viral sonnet
#

the dispose sentinel in NA is managed.

robust scaffold
rotund token
#

Wait yeah stopping nested native containers

#

Not stopping icomponent containers

viral sonnet
#

yeah, just adding to the NA in icomp discussion

robust scaffold
#

I wonder, use a custom rewindable allocator, set a bunch of ICD with NAs out into the wild. At cleanup, all you need to do is just rewind the original allocator and boom, doesnt even need a ISSCD

rotund token
#

Nested containers still not allowed in jobs

#

Yeah that's what I thought

robust scaffold
#

Literally nothing changed with Unity 2D Physics (not DOTS) in 2022.2 beyond 1 fix. Wow, they fired everyone.

#

Wait no, it's foldered under regular physics

#

N/A (internal): Added: AtomicSafetyHandle.SetExclusiveWeak and AtomicSafetyHandle.GetExclusiveWeak.
Huh, anyone know exclusive weak safety means?

rotund token
#

Without reading at all, could be related or replacing secondary handles

rotund token
#

That seems pretty well received, not that I've used it

robust scaffold
#

Core: Improved Job Debugger performance to avoid redundant work. Most users should feel comfortable to leave the Job Debugger enabled at all times.
Core: Improved the Job System to better scale as core counts increase and reduced the cost of scheduling jobs and combining dependencies.

#

Core: Changed so that IJob, IJobFor, and IJobParallelFor schedule sites can be burst compiled.

#

I leave the Job Debugger on at all times. Havent noticed any cost of it personally

rotund token
#

Oh boy

#

Try physics with it on v off

#

Like double the performance

robust scaffold
#

Inferior unity physics (so much redirection. It's a fucking enterprise java program)

rotund token
#

In our project at work (without physics) load times to from 15 to 45s

#

From our terrain gen

#

With it on

robust scaffold
#

This entire section's equivalent in unity dots physics is about 4 separate methods

#

Located in 3 separate files

#

I dont get it, why build a literal maze of methods and function calls when a nice and linear execute pathway works?

#

Is code reuse really that valuable? At which point does reusing the same line of code for multiple other methods become a problem rather than a solution.

#

But I dont think that's the issue with the jobs debugger though. Just multiple jobs start building up overhead with the debugger

rotund token
#

if you ever go into enterprise you're going to be extremely depressed πŸ˜„

robust scaffold
rotund token
#

unfortunately everything changes as soon as 1 other person has to work on the code as well

#

some dev gets a ticket for a bug, goes in and fixes it, doesn't realize you have duplicate code elsewhere in project that also need to updated. now you have 1 bug fixed, but multi new bugs

robust scaffold
#

This is why one coder is better. The source of the bugs is the same person who will be forced to fix it.

rotund token
#

until that guy leaves the company

#

now no one knows how the code works

viral sonnet
robust scaffold
#

And one thing I've gotta say is really nice working solo. Pushing straight to master. No need for PRs, no need for review, no need to compartmentalize changes. I can work on physics one moment, polish up some part of lighting, go make a new debug visualizer. And force push to master instantly at the end of the day.

rotund token
#

haha

#

i do branches / pull requests on my own libraries

robust scaffold
#

disgusting

rotund token
#

not frequently, maybe once a month

#

but just a good excuse to have a quick look over stuff

#

i would say there has never been a time i haven't spotted something broken

#

none of the libraries in my project are pointing to master, i just work on all of them at the same time in various branch/states

#

i have integration testing on my gitlab

#

automatically runs tests + makes builds

#

catches issues nice and early

#

i absolutely hate doing a bunch of development

#

only to make a build and everything is broken

#

and having to spend a day (often days) debugging it

robust scaffold
#

I do need to build test though.... ehhhhhhhh

#

wait, the bot didnt delete my comment

#

ehhhhhhhhhhhhhhhhhhhhhhhhhhhh

#

Nice

viral sonnet
#

so for my problem yesterday. i'll use a mix of const bools for definitions and code gen

#

the const bools are nicest for my actual runtime code. burst will just rip them out when false

#

the stat enum and config struct will be code gen'd

#

i figured i need some form of definition so the source generator can actually analyze something

#

it probably will get a bit more complex once i introduce different data types but i have to start somewhere and this is a good excuse to learn some source generator

timber ivy
#
        var worldPos = world.EntityManager.GetComponentData<LocalToWorld>(e);

        var newPos = new LocalToWorld() { Value = worldPos.Value };
        newPos.Value = float4x4.Translate(new float3(position.x, 0, position.y));
        newPos.Value = float4x4.RotateY(rotation);
        world.EntityManager.SetComponentData(e, newPos);

is this really the correct way to write an entities position and rotation?

robust scaffold
timber ivy
robust scaffold
#

Unity's transform systems converts the 3 (or less) components into the unified L2W.

robust scaffold
#

Translation ICD, Rotation ICD, and ScaleICD. Not the L2W ICD.

timber ivy
#

Oh ok i got you

robust scaffold
#

Unity ships by default 4 component datas.

timber ivy
#

Will an entity being rendered with hybrid renderer get a translation component automatically or do I have to add it?

robust scaffold
#

I replaced the first list with my custom 2D second list but otherwise they're analogous.

robust scaffold
#

Well, Nonuniformscale isnt if your scale is 1, 1, 1. But the other 3 will always be added.

#

Check Unity.Transforms.Hybrid\TransformConversion for the conversion logic.

timber ivy
#

Alright cool beans thank you.

#

Ill give it a look now actually thanks.

gusty comet
#

@gusty comet stop ghost pinning me in random channels

#

You already did that twice

timber ivy
#

How do you handle scriptable objects with dots? You cant reference it in a component since they aren't blittable, am I best off just making a component that takes a pointer to the scriptable objects address?

rotund token
#

you convert your scriptableobject data to unmanaged data in setup or just don't use them

#

or just write the values to variables in the job

timber ivy
#

The values of the scriptables aren't blittable either I am using things like animation curves. Its a shame unity didn't expose any of the low level methods cause looking at the sourece of animation curve its just a pointer already anyways.

rotund token
#

someone wrote a much faster version of animation curves for dots like 2-3 years ago

timber ivy
#

oh really ima look on github now

robust scaffold
#

@viral sonnet Also, just added systemstate extensions to the EntityExposed CDFE versions:

[BurstCompatible]
public static UnsafeCDFE<T> GetUnsafeCDFE<T>(this SystemState state, bool isReadOnly = false)
    where T : struct, IComponentData
{
    return state.EntityManager.GetUnsafeCDFE<T>(isReadOnly);
}```
#

Nice and colorful

timber ivy
rotund token
#

but more than 1 person could have done it

viral sonnet
rotund token
#

you haven't told the dependency management that the system depends on this component

#

if your system version is doing the same thing using EntityManager, again unsafe

viral sonnet
#

wait does isystem register differently?

rotund token
#

what's your normal system version doing?

viral sonnet
#

the same as unity

rotund token
#
            return EntityManager.GetComponentDataFromEntity<T>(isReadOnly);```
is what unity does
#

it calls AddReaderWriter

#

before calling entity manager

#

the code above is not calling AddReaderWriter so it's never adding the dependency to the system

viral sonnet
#

he calls an extension method. it's in there

timber ivy
#

Are blob arrays performant if they are preallocated upfront?

viral sonnet
#

but i see i have commented this out. haha yeah might want to add that again

#

thanks for checking

rotund token
viral sonnet
#

yeah it's probably the reason i have commented this out

rotund token
#

since you're writing your own unsafe version, if you want to make this fast

viral sonnet
#

i can add it to the systemstate extension though as i have the state there

rotund token
#

just create it in OnCreate, cache it

#

and add an Update method like TypeHandles have

#

(this will exist in 1.0)

viral sonnet
#

yeah good idea

#

i'm mostly stress testing under heavy load but on no load the systembase onUpdate could be a lot smaller with not setting these up every frame

#

man this is fun, getting the stat system to support 8/16/32/64 bit datatypes

robust scaffold
#

I've so far not been caching any of the handles since my jobs far outstrip the system update times (per systems range in 0.1 ms, per jobs in the 2-3 ms).

viral sonnet
#

so simple data types aren't working to use as a generic T. are there any good solutions for it to not write several jobs with just different data types? there's Single, Double structs. should I use these?

rotund token
#

can't you just store it all in a 64bit type?

#

and reinterpret depending on what you need

robust scaffold
#

Reinterpreting is magical.

timber ivy
#

Does dspgraph work with entities 0.51?

rotund token
#

i don't believe so

timber ivy
#

so no options for sound atm?

viral sonnet
#

i think that would actually be for the best. i just have to be able to mix them all and that is a lot easier when seperated

viral sonnet
#

ReinterpretLoad will be helpful

robust scaffold
viral sonnet
#

what i find complicated right now is how to access the values with its correct data type without too much overhead

viral sonnet
#

the values would be stored in a byte buffer

robust scaffold
#

Will these values be constant across a chunk or unique per entity?

viral sonnet
#

actually something cool for codegen. writing offset myself is tedious

#

they are stats, so unique per entity. every entity has the same amount of stats though

robust scaffold
viral sonnet
#

just concerned about performance πŸ™‚ i think i'm getting somewhere though.

robust scaffold
viral sonnet
#

yep, that's my concern. right now it's just a nice vectorized job running on floats

timber ivy
#

Anything wrong with doing this? so I can have arrays inside of components?

 public unsafe struct BlitableArray<T> : IDisposable where T : unmanaged
    {
        public void Dispose()
        {
            Marshal.FreeHGlobal((IntPtr)arrayPointer);
        }

        private readonly T* arrayPointer;
        private readonly int length;

        public int Length => length;

        public BlitableArray(int length)
        {
            this.length = length;
            arrayPointer = (T*)Marshal.AllocHGlobal(Marshal.SizeOf<T>() * length);
        }


        public T this[int key]
        {
            get => GetValue(key);
            set => SetValue(key, ref value);
        }

        private void SetValue(int key, ref T value)
        {
            arrayPointer[key] = value;
        }

        private T GetValue(int key)
        {
            return arrayPointer[key];
        }
    }
robust scaffold
timber ivy
robust scaffold
#

None of the NativeXs do. UnsafeXs do not have the managed safety components of NativeX containers so they can be used inside a ICD. But you need to dispose of them manually somehow.

timber ivy
#

When I was looking at possible solutions all I seen mentioned was DynamicBuffer and I didn't want to use that in this scenario

timber ivy
robust scaffold
timber ivy
#

I think ima keep using mine then cause as far as I am aware unsafe list doesn't include the leak detection already anyways, and I really only need an array anyways.

robust scaffold
#

This is what a dynamic buffer is. A pointer to an array in heap, an int for count of elements, and an int for capacity.

#

I recommend not reinventing the wheel when not needed. A Dynamic buffer is just a native array component.

timber ivy
#

can I put a dynamic buffer inside of a component or do I have to attach it to an entity?

robust scaffold
#

Dynamic Buffer is a component. IBufferElementData for the T.

timber ivy
#

you can put it a component as well apparently

#
    public struct VehicleComponent : IComponentData
    {
        DynamicBuffer<float> gearRatios;
    }

this compiles anyways

#

any problem doing that?

robust scaffold
#

Yes because that's not what a dynamic buffer is.

timber ivy
#

I know its not what it is

#

but will it work?

#

because I can't have two dynamic buffers of type float on an entity

robust scaffold
#

No. Because the pointer is invalidated on structural change

#

Thats why you make wrapper structs.

timber ivy
#

but the arrays aren't the same lengths

robust scaffold
#

What?

timber ivy
# robust scaffold What?
 public struct VehicleComponent : IComponentData
    {
        DynamicBuffer<VehicleDataWrapper> gearRatios;
    }

    public struct VehicleDataWrapper : IComponentData
    {
        public float gearRatio;
        public float gripRatio;
    }

you're proposing this right?

viral sonnet
#

what are you doing πŸ˜„ read the docs

#

KF linked it

timber ivy
#

Im trying to have two dynamic buffers of type float

viral sonnet
#

then make 2 structs with a float and implement IBufferElementData

robust scaffold
timber ivy
#

oh

#

ok makes perfect sense now

robust scaffold
#

And then reinterpret the DB.Reinterpret<float>() to get the base values.

timber ivy
#

sorry for the confusion xd

robust scaffold
#

If you dont want the buffer from flooding the chunk, set the InternalBufferCapacity to 0 to force it onto the heap (basically a NativeList at that point)

timber ivy
#

Is there any negative side effects to this?

robust scaffold
#

It takes far longer to obtain the data inside the DB since the CPU needs to access Allocator.Persistant (where DBs larger than IBC are located).

#

And writing also takes a while since it needs to travel all the way over to the heap.

#

But Entity is a Int2 and Manifold is an Int10 so storing it inside the chunk would basically cut chunk capacity from the current low 50s to 20.

timber ivy
#

Ok so if I understand this right. Entities of the same type might be located in seperate chunks of memory. if the dynamic buffer is also inside this chunk of memory then it will cause my chunks to contain less entities and queries will take longer due to this?

robust scaffold
#

If you want to do fast iteration across multiple DB on multiple Entities, you want the DB to be located inside the chunk so you're not waiting on the read-write back and forth to the distant Persistent. But that comes at the cost of less entities inside the chunk since the DBs are now taking up space. And if you surpass the DB's ICB, then that inside chunk space is wasted and the DB will instead point to a persistent allocation.

timber ivy
rotund token
#

you mean like, all entities of an archetype in a single chunk?

timber ivy
#

yeah

robust scaffold
#

Chunks are fixed size and you gotta work with what Unity hardcodes as the limit.

viral sonnet
#

basically adding/removing works faster in chunks. that principle is used a lot in advanced data types that use several small blocks of memory and not one huge one. for example, NativeList uses one huge block and resizing when you have 10k elements in it gets exponentially expensive

robust scaffold
#

Since you have 1 pointer and 1 length, everything from the pointer head to the pointer at length must be valid and in that list.

#

What I really wish is the ability to shove everything into one chunk if I know the entities themselves will never structurally change but the values will.

#

They said they were looking into the possibility for user defined chunk sizes but that was... a long time ago

timber ivy
#

So since ISharedComponentData forces entities to the same chunk would that not be an ideal way to force entities into the same chunk?

robust scaffold
viral sonnet
#

entities of the same archetype are in the same chunks. SCD is like a groupBy method

timber ivy
robust scaffold
timber ivy
#

ah alright

robust scaffold
#

If you have a mega-entity with size 16KB, that means one chunk can only contain 1 entity. Even if multiple of these megaentities share the same ISCD, that will do nothing to change the number of entities per chunk.

#

What will change if you have an entity of 8KB (so 2 entities per chunk) and a different ISCD per entity, you will force every chunk to now contain one 8KB entity. But the chunk remains a total of 16KB.

timber ivy
#

I am going to have awful chunk utilization I feel like. Each vehicle has a dynamic buffer of floats that relates to gear ratios with a size of 5-8, torque for any given rpm with a size of 256, and a slip curve with a size of 256.

robust scaffold
timber ivy
#

The AnimationCurve?

robust scaffold
#

An literal mathematic curve. Ax^2 + Bx + C

rotund token
#

i think you're being way too influenced by this channel when you're reasonably new to entities πŸ˜…

#

we have like 6 entities per chunk at work. our server still runs really fast

#

performance issues are still all tied to main thread job scheduling etc

robust scaffold
#

First google result. 7 floats.

timber ivy
robust scaffold
#

Looks empirical but good enough. You wont get any simulation running off of that equation past the feds but if this is for a game, it's sufficient.

timber ivy
#

So this procedurally generates the torque curve basically interestting

robust scaffold
#

Also note, I'm a guy coding my own physics engine because I dont like the existance of a z float in unity's DOTS so my advice is probably not the best.

viral sonnet
rotund token
#

you say that

#

but the only difference between these 2 is increased chunk capacity

#

50% faster by tripling chunk capacity

#

(fuck linked entity group)

robust scaffold
rotund token
#

you should see the 100M version πŸ˜„

robust scaffold
#

My poor comp dies at 10k...

rotund token
#

i think it was 13GB of just linked entity list

robust scaffold
#

It's slowly creeping higher

viral sonnet
# rotund token

you should profile that. i would bet most is spent on GetNativeArray

rotund token
robust scaffold
viral sonnet
#

and can't be said enough. LinkedEntityGroup should be burned at the stake

#

btw. i found GetPtr more light than GetNativeArray. with such a testcase it might be worth exploring the difference

#

aaand, caching accessors for threads. can we make this a thing?

viral sonnet
#

GetComponentDataPtrRO and friends

#

the safety overhead also kicks in even with checks off, there's some left

robust scaffold
viral sonnet
#

no, the handles

robust scaffold
#

Oh, that would be nice. Got a copy?

viral sonnet
#

it's built in

robust scaffold
#

Oh my god im stupid

#

Look at all these

viral sonnet
#

good thing we talk πŸ˜…

#

the nice thing about getting RO directly is that version doesn't get bumped on write handles

robust scaffold
viral sonnet
#

yes

robust scaffold
#

You could just do that with the old unsafeReadOnlyPtr as well

viral sonnet
#

wdym, it's built into GetNativeArray

robust scaffold
#

wait, seriously? Oh my god

#

explains so much about why my version checks break so easily

viral sonnet
#

ChunkDataUtility.GetComponentDataRW does it and that is used in GetNativeArray based on if the handle is read or write

robust scaffold
rotund token
#

why does this all look so familiar πŸ˜„

viral sonnet
#

i dunno we must be doing the same things πŸ˜„

rotund token
#

// This should (=S) be thread safe int writes are atomic in c#

#

even write the same comments πŸ™ƒ

viral sonnet
#

i'll add a ❀️ tertle

#

not being able to write extension methods for pointers makes me a sad panda

viral sonnet
#

Method(this float* array, ...) doesn't work

rotund token
#

you don't write them for pointers

#

you write them for the underlying type

#

and then just use pointers on them

robust scaffold
viral sonnet
#

makes no sense to me tbh. i can write a normal method just fine with a float* parameter. so why no extension

#

afaik it's just a wrapper anyway

rotund token
#

it works fine

#

you're just writing it wrong

#
        public static void Method(this float array) {

        }
    }```
#

you probably want to do something like


            var ptr = (float*)UnsafeUtility.AddressOf(ref array);
        }```
robust scaffold
#

the issue with that is now every float will have this extension method...

rotund token
#

well yeah

#

but that's what he's asking for πŸ˜„

#

personally i'm a fan of container structs

#

and i have a default Ptr<T>

#

with implict conversion for this

#

that i can write extensions on

#
    public readonly unsafe struct Ptr : IEquatable<Ptr>
    {
        public readonly void* Value;

        public static readonly Ptr Zero;

        public Ptr(void* value)
        {
            this.Value = value;
        }

        public static implicit operator void*(Ptr ptr)
        {
            return ptr.Value;
        }

        public static implicit operator Ptr(void* ptr)
        {
            return new Ptr(ptr);
        }

        public bool Equals(Ptr other)
        {
            return this.Value == other.Value;
        }

        public override int GetHashCode()
        {
            return unchecked((int)(long)this.Value);
        }
    }```
#

oh that's the non generic one

#

but yeah i find this one useful as well

#

for storing in containers

#
        where T : unmanaged
    {
        public readonly T* Value;
        
        public Ptr(T* value)
        {
            this.Value = value;
        }

        public bool IsCreated => this.Value != null;

        public static implicit operator T*(Ptr<T> node)
        {
            return node.Value;
        }

        public static implicit operator Ptr<T>(T* ptr)
        {
            return new Ptr<T>(ptr);
        }

        /// <inheritdoc/>
        public bool Equals(Ptr<T> other)
        {
            return this.Value == other.Value;
        }

        /// <inheritdoc/>
        public override int GetHashCode()
        {
            return unchecked((int)(long)this.Value);
        }
    }```
#

then you can just write extension methods on Ptr<T>

#

anyway back to original point

#

what he wants to do is totally possible

#

extension methods on floats

viral sonnet
#
        {
            var tmp = array.ReinterpretLoad<double>(Health_Index);
            tmp = value;
        }``` any better suggestions to write a double to a byte array?
robust scaffold
#

Hrm, does anyone know how blob assets creation during conversion works? I know you have to do something with BlobAssetComputationContext in order to register between a converted entity and blob asset but how does incremental generation and update of a single blob asset work?

rotund token
rotund token
viral sonnet
#

i might just get the ptr. reinterpret has some overhead

rotund token
viral sonnet
#

it's what i'm doing tertle. just using load because it has an offset

rotund token
#

i've seen burst basically strip it to nothing

rotund token
#

with just blob builder

robust scaffold
rotund token
#

so using computation context can help with that

#

but the actual blob asset store can do it as well

robust scaffold
#

Right, the docs are pretty sparse on that.

rotund token
#

conversionSystem.BlobAssetStore.AddUniqueBlobAsset()

#
        /// Adds a blob asset where the key that makes it unique is based on the BlobAsset contents itself. If the contents of the generated blob asset is the same as a previously inserted blob asset,
        /// then the passed blobAsset will be disposed and the reference to the blob asset will be replaced with the previously added blob asset
        /// </summary>
        /// <param name="blobAsset">The blob asset that will be inserted or replaced</param>
        /// <typeparam name="T"></typeparam>
        /// <returns>Returns true if the blob asset was added, returns false if the blob asset was disposed and replaced with the previous blob.</returns>
        unsafe public bool AddUniqueBlobAsset<T>(ref BlobAssetReference<T> blobAsset) where T : struct
        {
            Hash128 key = default;
            ulong hash = blobAsset.m_data.Header->Hash;
            UnsafeUtility.MemCpy(&key, &blobAsset.m_data.Header->Hash, sizeof(ulong));
            key.Value.w = ComputeTypeHash(typeof(T));

            if (m_BlobAssets.TryGetValue(key, out var previousBlob))
            {
                blobAsset.Dispose();
                blobAsset = BlobAssetReference<T>.Create(previousBlob);
                return false;
            }

            m_BlobAssets.Add(key, blobAsset.m_data);
            return true;
        }```
viral sonnet
rotund token
#

if it already exists in the store, it will delete it and re-use the existing one

#

if you can hash it yourself you can speed up conversion

rotund token
#
                (uint)this.sockets.GetHashCode(),
                (uint)this.type.GetHashCode(),
                0,
                0);

            if (conversionSystem.BlobAssetStore.TryGet<Piece.Asset>(hash, out var piece))
            {
                return piece;
            }

// ...

            piece = blobBuilder.CreateBlobAssetReference<Piece.Asset>(Allocator.Persistent);
            conversionSystem.BlobAssetStore.TryAdd(hash, piece);
rotund token
robust scaffold
#

Ah, okay. Hrm

#

This is literal pain.

rotund token
#

yeah it is painful

robust scaffold
#

Oh wait, that code blurb is unity's

rotund token
#

yes

robust scaffold
#

I see it, yea. Blob asset building is terrible. My god.

#

So in what situation would you use a computational context? This seems to handle unique filtering by itself

rotund token
#

i think it's for performance

robust scaffold
#

Oh, okay. hrm

rotund token
#

i will admit i am not super familiar with blobs

#

i think you can use jobs to pre-compute all hashes with BlobAssetComputationContext and things like that

#

instead of running it all single thread

#

at least that's what i've seen physics doing

viral sonnet
#
    {
        private NativeArray<byte> _array;
        private readonly byte* _ptr;

        private const int Health_Index = 1;

        public StatsWrapper(ref NativeArray<byte> array)
        {
            _array = array;
            _ptr = (byte*) array.GetUnsafeReadOnlyPtr();
        }
        
        public void SetStat_Health(double value)
        {
            ref var tmp = ref UnsafeUtility.ArrayElementAsRef<double>(_ptr, Health_Index);
            tmp = value;
        }
    }``` this might be a bit better
#

i dunno, allocates a struct though :/

#

eh, don't like it either. static methods it is

viral sonnet
#
                        tmpMultiplicativeStatsWithValues[ii] = 1;``` i have to convert this very simple loop to work for a byte array that has double at first, then all floats and then all shorts. ```var bytePtr = (byte*) tmpMultiplicativeStats.GetUnsafePtr();
var doublePtr = bytePtr;
var floatPtr =  bytePtr + StatsConfig.STATS_64BIT_AMOUNT * UnsafeUtility.SizeOf<double>();
var shortPtr = floatPtr+ StatsConfig.STATS_32BIT_AMOUNT * UnsafeUtility.SizeOf<float>();
                    
double* doubleValue = stackalloc double[1];
doubleValue[0] = 1.0;
float* floatValue = stackalloc float[1];
floatValue[0] = 1.0f;
short* shortValue = stackalloc short[1];
shortValue[0] = 1;
                    
UnsafeUtility.MemCpyReplicate(doublePtr, doubleValue, UnsafeUtility.SizeOf<double>(), StatsConfig.STATS_64BIT_AMOUNT);
UnsafeUtility.MemCpyReplicate(floatPtr, floatValue, UnsafeUtility.SizeOf<float>(), StatsConfig.STATS_32BIT_AMOUNT);
UnsafeUtility.MemCpyReplicate(shortPtr, shortValue, UnsafeUtility.SizeOf<short>(), StatsConfig.STATS_16BIT_AMOUNT);``` any input?
#

i migh have overcomplicated this πŸ˜„

robust scaffold
robust scaffold
rotund token
#

at this point, would it just not be better to keep everything in double

#

for your sanity

#

but also, weirdly enough, peformance

robust scaffold
#

You can use the sizeof() against unmanaged types in unsafe C#

viral sonnet
#

wdym, to have everything in doubles with no other data types?

rotund token
#

yeah

#

if you're going to have to do all this weird extra math to support different types

#

why not just only support the double

viral sonnet
#

this only happens once per thread. everything that goes beyond that though. i think i can kiss my beautiful vectorization goodbye

rotund token
#

personally after our last discussion i ended up adding the option for high precisions because you were right, i guess some weirdos want higher values

viral sonnet
#

well, not really when i'm smart about but it's gonna be a pain

rotund token
#
    [StructLayout(LayoutKind.Explicit)]
    public struct StatValueUnion
    {
        [FieldOffset(0)]
        public int Whole;

        [FieldOffset(0)]
        public float Fraction;
    }
#else
    [StructLayout(LayoutKind.Explicit)]
    public struct StatValueUnion
    {
        [FieldOffset(0)]
        public short Whole;

        [FieldOffset(0)]
        public half Fraction;
    }
#endif```
#

so they can optionally unlock it

#

only place in my code that actually needs this #if though

#

which is kind of nice

viral sonnet
#

oh i don't really mind if it's a pain to code tbh. regarding perf, i can access them via const index so it should be really the same

#

and it's gonna be nice when it's done so i think it's worth the effort πŸ™‚

#
float floatOne = 1.0f;
short shortOne = 1;
var bytePtr = (byte*) tmpMultiplicativeStats.GetUnsafePtr();
var doublePtr = bytePtr;
var floatPtr =  bytePtr + StatsConfig.STATS_64BIT_AMOUNT * sizeof(double);
var shortPtr = floatPtr + StatsConfig.STATS_32BIT_AMOUNT * sizeof(float);
                    
UnsafeUtility.MemCpyReplicate(doublePtr, &doubleOne, sizeof(double), StatsConfig.STATS_64BIT_AMOUNT);
UnsafeUtility.MemCpyReplicate(floatPtr, &floatOne, sizeof(float), StatsConfig.STATS_32BIT_AMOUNT);
UnsafeUtility.MemCpyReplicate(shortPtr, &shortOne, sizeof(short), StatsConfig.STATS_16BIT_AMOUNT);``` a bit nicer, thanks @robust scaffold
robust scaffold
#

@rotund token There's this superior option to build single value blob references. Without having to go through the pain of a blob builder

#

That is what I expect blob asset building should be like. Smooth, painless, and efficient.

#

I wonder, can you have generic components?

#

Hrm, yes you can. A bit cumbersome but it works.

timber ivy
#

im trying to mess around with unity physics rigidbody if I want to do something similar to AddRelativeForce do I just do it on the linear velocity property of PhysicsVelocity component?

robust scaffold
#

The blob asset still uses the same amount of memory, the type doesnt change.

rotund token
#

i mean in the chunk

robust scaffold
#

No. The type of the blob asset reference is the same as the blob asset reference created from the BlobBuilder

rotund token
#

i just mean, using blob in general in a component

#

over storing the box in a component

robust scaffold
#

A box component is 8 floats on every single component. A blob asset is 1 int pointer.

rotund token
#

blobs are a long

#
        internal long m_Align8Union;```
#
    internal unsafe struct BlobAssetReferenceData : IEquatable<BlobAssetReferenceData>```
#

but yes the box is still 16 so that's fine

#

i missdid the maths

robust scaffold
#

Right, size 8, not size 4. Still, that means 2 ints. Still 6 less int sized fields.

rotund token
#

oh are those ints?

robust scaffold
#

int sized, 4 bytes

rotund token
#

half sounded like half, but i guess its half size

#

as it says πŸ˜„

robust scaffold
#

yea, half the tile size. I dont use half floats.

rotund token
#

all good

robust scaffold
#

The tile's position is at the center of the box. Then half size for the 4 points.

#

I think this works?

#

I havent used blobs but I am allergic to ref.

timber ivy
#

there isn't a way to enable/disable specific components is there? Just entire entities?

robust scaffold
timber ivy
#

rip

rustic rain
#

Like DisableRendering

#

Transform uses write group filters

timber ivy
#

Disabling the entire system isn't an option for me unfortunately

#

I need to just be able to exclude an entity from a system temporarily guess i will just remove/readd the component

rustic rain
#

What system are you talking about?

#

Your or unity's?

timber ivy
#

uh whatever system handles gravity for the entities converted with the physicsbody attached

rustic rain
rustic rain
#

Let's you turn bodies into kinematics or disable velocity

timber ivy
#

So in the editor when you attach the physics authoring component you can make it static or dynamic but there doesn't appear to be a way to do this at runtime.

rotund token
timber ivy
rustic rain
#

And set it's settings

rotund token
#

PhysicsMassOverride is good for short term behaviour

#

but it does cause your statics to exist in dynamic world for updating

#

for long term changes just add/remove PhysicsVelocity

robust scaffold
#

I have clawed back 64 bytes per entity. My physics systems are completely broken but I can fix that slowly.

#

AABB could be a half4... Hrm

rotund token
#

huge

robust scaffold
#

63 usages. Ughhhh. Maybe doesnt need to be converted to half4.

timber ivy
#

why would I be getting an error message stating that there is no translation component on an entity for using SetComponentData but I can see with my eyes in the entity hierarchy that it is there.

rustic rain
#

add a check for it

#

EntityManager.HasComponent()

#

and make sure it is indeed has it

timber ivy
#

I should have it. if its rendering it has it

#

but ill add a check

rotund token
#

just localtoworld

#

static entities don't have translation

timber ivy
#

Yeah hascomponent fails but i can see the translation component on it in entity heiarchy so idk whats going on x)

rotund token
#

it means when the code runs

#

it doesn't have Translation

#

but when you look at it in hierarchy it does ^_^

rustic rain
#

or maybe it's different entity

timber ivy
#

Is it possible the conversion system isn't finished or does that happen at edit time?

rotund token
#

No

timber ivy
#

ok i found the issue, the entity is a subscene section entity and is still being loaded when the request for translation is made

rustic rain
#

@rotund token does it work like this?

#

I highly doubt entities can be loaded with half of their components

rotund token
#

yeah...

#

that's not how it works

#

but i feel like he's talking about the actual subscenesection entity

#

not the entities in the subscene?

#

but basically the subscene gets loaded from disk then when done the whole thing is just copied into your world all at once

timber ivy
# rotund token but i feel like he's talking about the actual subscenesection entity

I am talking about the actual subscene entity, I am using subscene sections to stream prefabs in and out of memory. each prefab gets its own section in a subscene, so when I need the prefab i just instantiate a copy of it, but if the subscene section isn't loaded the conversion process hasn't happened(im guessing this is how it works? not 100% sure on this part)

rotund token
#

conversion happens outside of play mode

#

its baked before you even enter the game

#

there is no runtime component

#

it's saved as a giant chunk of binary data

#

that is saved to disk