#archived-dots

1 messages Β· Page 139 of 1

mint iron
#

it seems that the prefix Native means that its allocated manually with malloc and needs to be manually disposed, and it has safety mechanisms. Unsafe is the same except without safety. Note that DynamicBuffer isn't prefixed with either, still uses malloc but doesn't need to be disposed by user.

loud matrix
#

Yeah I was going to ask why that sounds liek dynamic buffer

storm ravine
#

Because it's not fixed

#

if you overflow capacity

#

It will move to heap

#

and all memory management Unity doing automatically for you

loud matrix
#

ahh I see

storm ravine
#

Technically DynamicBuffer it's same as NativeArray

#

It's also NativeContainer with fixed size and simple pointer

#

Difference is

#

until you under initial capacity

#

you use chunk memory

#

Buffer has header

#

and when you read\write data it only use offsets in memory from header

north bay
#

Is it possible to step certain physic bodies in Unity Physics? I'm asking since i want to network the RayCast Car sample, or are there other ways to archieve rollback/prediction on physic bodies?

storm ravine
#

But after overflow internal capacity it allocates (malloc) Persistent memory

#

and using pointer to persistent memory instead of header with offset limited by internal capacity in chunk (yes it's also pointer, just different word). Implementation pretty simple

storm ravine
#

Is it possible to step certain physic bodies in Unity Physics? I'm asking since i want to network the RayCast Car sample, or are there other ways to archieve rollback/prediction on physic bodies?
@north bay Your networking is P2P or through server?

north bay
#

Using NetCode

#

So server authority

storm ravine
#

Well all physics calculated on server side guess?

north bay
#

People are going to control the vehicle so having an input delay of ping + interpolation delay isn't really acceptable

#

It seems like i have to remove it from the physics simulation and step it myself like they did with the character controller, but i thought there would be an easier way

storm ravine
#

Well it's how all network AAA games works, calc gameplay important physics fully on client not acceptable (acceptable for local things which not correlates with gameplay, like flags and trees affected by some things like bird etc), especially when it not fully deterministic πŸ™‚ For cars itself you should definitely calc it on server which will be "true" physic state, clients will have their local simulation but this simulation shouldn't be synchronized, this is just for hiding delay, server will send "true" simulation results πŸ™‚

north bay
#

Well yea, but when the server sends the true state it will be x ticks behind the currently client predicted state and therefor i need to repredict the simluation for those ticks -> step the simluation for that object. Maybe im missing something obvious

storm ravine
#

Yes and commonly for that using Dead Reckoning

#

And ususally this covers delay smooth and thus (usually) differences not noticable πŸ™‚

#

Write good networking is one of trickiest things, for latency sensitive games, in gameplay programming usually πŸ˜„

#

So many usually

opaque ledge
#

Does anyone have a helper methods for logging inside jobs ?

coarse turtle
#

Would the BurstDiscard attribute work on a proxy function to Debug.Log?

opaque ledge
#

Burst supports Debug.Log now

coarse turtle
#

Oh I guess its the inside jobs part πŸ€”

opaque ledge
#

but it is only callable on main thread, so it doesnt work with Schedule, ScheduleParallel

#

yeah

coarse turtle
#

Hmm you could try pushing the log statement into a parallel container with a timestamp

opaque ledge
#

weird thing is, it logs at first for a while then it gives error that i should call it from main thread

coarse turtle
#

and then flush that container later back on the main thread with the actual log statement to a file or console πŸ€”

mint iron
#

ive done it before, you can use shared static, write to some sort of stream/queue/whatever and then have it play back on main thread with some sort of hook.

coarse turtle
#

I also wonder if Visual Studio/Code's debugger works with the threads

#

I remember reading that rider had support sometime ago πŸ€”

storm ravine
#

Works inside jobs\parallel jobs with\without burst

opaque ledge
#

is that a love letter for me Eizen πŸ‘€

#

yay thanks, will check it

storm ravine
opaque ledge
#

@mint iron no need now i think πŸ˜„ (if your sentence was for me)

#

is there a need for Burst Discard now ? since it works with burst now

storm ravine
#

No need

#

Just not spent time for clearing that

opaque ledge
#

how can this work inside jobs exactly ?

#

you are just calling Debug.Log inside static methods

#

πŸ‘€

mint iron
#

yeah... thats confusing, if it BurstDiscards, then it not going to run in burst

zinc plinth
#

hemm in jobs from a system, am I sure that any entity struct that I get from a query will stay valid within the chain of jobs/dependencies from that system ?

this might be horibly worded sorry :x

opaque ledge
#

yeah they will stay valid as long as you dont do structral changes

#

log works thanks Eizen πŸ˜„

#

kinda weird, if we directly call it its an error but if we indirectly call it then it works πŸ€”

storm ravine
#

Well

#

problem in Burst usually is string concatenation

#

which not allowed

#

like "asdasd" + someVar

#

with string.Format("Some string {0}", index) right inside job it will work also

#

but will complain about Debug.Log

#

Because of how burst compiles things and Debug.Log works

#

Under hood Debug Log calls new Logger() and new DebugLogHandler() and here is come problem on which burst complains

#

Becuase of how burst compiles instances and call constructors

#

Like this:

#
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.```
opaque ledge
#

yea

storm ravine
#

Anyway it works? Then just s....t up and use that!

#

πŸ˜‚

#

Joke

#

hemm in jobs from a system, am I sure that any entity struct that I get from a query will stay valid within the chain of jobs/dependencies from that system ?

this might be horibly worded sorry :x
@zinc plinth well (why I always use that word) if you want schedule chain which in some job check\get some entity, stores it in some native container (for example) and you use that entity for something in other job in this chain yes?

zinc plinth
#

yep

#

before I had these ```
public NativeArray<GridMemberCoordinates> remainingGridMemberCoordinates;
public NativeArray<InventoryEmitter> remainingInventoryEmitter;
public NativeArray2D<GridMemberCoordinates> remainingNeighborsGridMemberCoordinates;
public NativeArray2D<RoadGroupGridElement> remainingNeighborRoadGroupsGridElements;

    public NativeArray<GridMemberCoordinates> activatedGridMemberCoordinates;
    public NativeArray<InventoryEmitter> activatedInventoryEmitter;
    public NativeArray2D<GridMemberCoordinates> activatedNeighborsGridMemberCoordinates;
    public NativeArray2D<RoadGroupGridElement> activatedNeighborRoadGroupsGridElements;``` but I saw that I needed an `Entity` to add a component to an entity so I added `        public NativeArray<Entity> remainingEntities;` and was afraid these structs could become invalid in some other system with the magic of the scheduler while this chain of jobs was still doing it's thing
storm ravine
#

Yes it will be stable always inside Jobs chain, because inside jobs chain structural changes not possible, they delayed by EntityCommandBuffers. (technically you can do structural changes directly inside job through ExclusiveEntityTransaction, which I described many times in many places, but this thing not for your case). If in a middle of chain you have system which completes jobs, doing structural changes - after that point validity of your entities not guaranteed

#

Also should mention ECB itself

zinc plinth
#

the structural change is the end of my job chain, so I'm all good

I'm using the EndSimulationCBS

storm ravine
#

if you have playbacks between your systems (which is structural change) - after that point validity of your entities not guaranteed. For example have multiple ECB systems which buffers used in chain

#

If you're doing all stuff with your entities before any playback it will be stable

zinc plinth
#

playback ?

storm ravine
#

But of course you should look at your dependency chain carefuly

#

because if systems use that array but not in same dependency chain it's again will be not guaranteed point

zinc plinth
#

I'm taking care of my deps πŸ˜ƒ

storm ravine
#

playback ?
@zinc plinth All entity command buffers playbacks - call Playback which....playback recorded commands chain (through burstable function pointers now btw)

zinc plinth
#

hooo that

didn't really know the sense for that word ^^'

storm ravine
#

You have tape

#

You record your voice commands in to that

#

then you press play button on your tape recorder and all your recorded voice commands playbacks

zinc plinth
#

I get it now ^^

#

thanks! :)

storm ravine
#

Huh need to go sleep, but there is still so many work (3 AM in Russia, Witching hour) 😦 You guys distracting me πŸ˜„

zinc plinth
#

^^

chilly halo
#

Hi guys.

I have a NativeMultiHashmap<Entity,int> and I need to do something in a Parallel Job with each entity and the sum of all INTs.
Those entities don't have anything in common and I cant use a query to loop through them.
Is there a known workaround or tip to do something like this?

zinc plinth
#

can't you get the key array from the multi hash map and use a IJobParralelFor ?

#

wait, do you mean the sum of all the ints, or just the ints relative to one key ? @chilly halo

opaque ledge
#

Just realized you cant put normal C# objects to entities thru AddComponentObject, i is sad

chilly halo
#

@zinc plinth The sum of all ints of each key.

And yes... I can do that but the thing is that the NMHM is being built in another job , and getting the array of unique keys must be done in the main thread, and I would prefer to dont do that.

zinc plinth
#

you can just get it in another job ThinkMan

#

which runs only once

storm ravine
#

Just realized you cant put normal C# objects to entities thru AddComponentObject, i is sad
@opaque ledge class (not struct) IComponentData

opaque ledge
#

ah true, why i didnt think of that

#

you know this reminds me, if we can just make class IComponentDatas and add that to Entities, why do we need AddComponentObject for ? πŸ€”

storm ravine
#

@zinc plinth The sum of all ints of each key.

And yes... I can do that but the thing is that the NMHM is being built in another job , and getting the array of unique keys must be done in the main thread, and I would prefer to dont do that.
@chilly halo Write native counter and sum concurrently

opaque ledge
#

(except TextMeshPro stuff, build fails if so)

#

Also werent you going to sleep, its 04:14 πŸ˜„

storm ravine
#

Fixing build

zinc plinth
#

well you still have to do that in a previous job @storm ravine

you'll end up with an NativeArray<int> sizes

mint iron
#

can't remember how to get the thread index in to Entities.ForEach, anyone?

zinc plinth
#

and I don't know how you could do that concurrently within one key

opaque ledge
#

[Unity.Collections.LowLevel.Unsafe.NativeSetThreadIndex]

#

i think

storm ravine
#

can't remember how to get the thread index in to Entities.ForEach, anyone?
@mint iron int nativeThreadIndex as one of lambda arguments

opaque ledge
#

ah in ForEach, nvm

storm ravine
#

and I don't know how you could do that concurrently within one key
@zinc plinth through written native counter

zinc plinth
#

yes, but how do you split an array of value from one key between parralel instance

#

from a NativeMultiHashMap

#

you only have Next

#

afaik thonk

#

you can parralel between keys, but not split the set of values of one key between multiple instances

mint iron
#
    public class LoggingTestSystem : SystemBase
    {
        protected override void OnUpdate()
        {
            Entities.ForEach((Entity entity, int nativeThreadIndex) =>
            {
                NativeDebugger.Log(nativeThreadIndex, FixedString.Format("The entity is {0}{1}", entity.Version, entity.Index));
                
            }).ScheduleParallel();
        }
    }
``` https://gist.github.com/jeffvella/ede829d9b6b8290009f083d6b7aa6604
Gist

Debug Logger that works in burst and any thread. GitHub Gist: instantly share code, notes, and snippets.

storm ravine
#

@zinc plinth IJobNativeMultiHashMapVisitKeyValue

zinc plinth
#

huuuuh

storm ravine
#

But it's just abstraction, under hood it's key per thread and it's what you need. Split one VALUE per thread will be bad, and reduce performance instead of give you gains

zinc plinth
#

ya

#

@chilly halo you got your answer πŸ˜€

storm ravine
#

With multi threading you always should process buckets of data, but not one value per thread in general

#

Only case where you set 1 per thread is some heavy algorythm and you just should run one calculation instance per thread

#

otherwise performance of parallelization will be opposite and can be slower that single thread

loud matrix
#

Quick guide and some additional notes on the new native debugging support for Burst. Available from package version 1.3.0-preview.4. Timestamps are below for convenience.

Timestamps:

[0:13] Quick guide to debugging
[1:29] Current Limitations
[1:33] Threaded Debuggin...

β–Ά Play video
opaque ledge
#

πŸ‘

zinc plinth
#

when you do ECB.AddComponent, what happens if the entity already has that component ? does it replace it or ? ThinkMan

opaque ledge
#

yes, it replaces it

zinc plinth
#

alright, thx!

safe lintel
#

remember the good old days when it would just error out πŸ˜€

storm ravine
#

It not replace but will ignore after first AddComponent

opaque ledge
#

it will replace it afaik

#

SetComponent gives error if it doesnt exist @safe lintel

storm ravine
#

AddComponent not replace any thing it's not the same as AddComponentData for ECB

opaque ledge
#

ah right, i assumed AddComponentData

storm ravine
#

Ah stop

#

I'm sleeping already

#

It's I missed

#

for ecb it's exactly AddComponent

#

AddComponentData it's for EM

safe lintel
#

yeah that made me go looking for a new addcomponentdata πŸ€”

opaque ledge
#

yeah i guess i am sleeping as well lol

storm ravine
#

For ecb AddComponent with instance yes latest override previous and now I'll go sleep

opaque ledge
#

I wonder if AddComponent causes a structral change if it already exists πŸ€”

storm ravine
#

No

#

It first execute AddComponentWithValidation

#

which check HasComponent

#

and after that it just set value

#

it only add on first AddComponent call

zinc plinth
#

what are the reasons a system could not show up in the entity debugger ? Thonkeng

storm ravine
#

not in one of root groups

zinc plinth
#

ahh nvm, it was because it wasn't ran and it hides it by default ^^'

coarse turtle
#

yea if the dependencies arent met on system initial run they're not registered to run so it doesn't appear in the entitydebugger πŸ€”

chilly halo
#

@chilly halo you got your answer πŸ˜€
@zinc plinth @storm ravine Sorry I was dining

So... I have my NativeMultiHashMap<Entity,int> and the idea is to end up with a parallel job able to do something with each entity in that NMHM and the sum of all int, so....

Run a IJobNativeMultiHashMapVisitKeyValue for the NMHM and build a NativeArray<Entity> and a NativeArray<int> with the same sizes , where the second NativeArray is the sum of each int[] inside a NMHM.

What I dont get is how to use IJobNativeMultiHashMapVisitKeyValue for that. IJobNativeMultiHashMapVisitKeyValue only has a ExecuteNext, no index and is executed N times as values has each key. How can I use it to build those arrays?

Sorry if the question is a bit obvious, I think I'm missing something big here.

chilly halo
#

In order to add some more context I will write the full story here... I case is happening an XY problem of some sorts .

I'm simulating fluids in a voxel world. I have a 3D Grid where I have an entity for each cell. In a given time I add some of those entities a new component [LiquidCompoenent].

The way I simulate that liquid is first fetch all entities with [LiquidCompoenent] but without the [SettledComponent] (that compoenent is added to entities with liquid that dont need to be updated) saving them in a NativeHashSet to use it later.
Then there is a second job that goes through those entities again but this time creates a new struct of data that has a cache of all relevant values for each valid NEIGHBOUR.
Then I go one more through every "simulated liquid voxel" to simulate the liquid movement using the struct of data created in the previous step. In this job I create two NMHM<Entity,int>, one with the differences of liquid generated (in and our flow) and one with a settled counter.

Then Lastly I should go through every entity in those NMHM and apply the sum of that numbers to their components.

craggy orbit
#

is it bad to use a cached monobehaviour in a system to change job parameters at runtime? like when the system is created, i get and save the monobehaviour as a property, then in the system's update i use public properties in the monobehaviour (exposed in the inspector) and pass them into the job?

#

i just feel like it'll be a lot quicker to test things rather than changing a single number, waiting to recompile, then seeing if the number even works

wide fiber
#

this component type is class IComponentData, not struct
@storm ravine wait what, a class deriving from IComponentData and not a struct? Native container inside IComponentData?

Can I use burst with a Class? Or are you making a query for the singleton, save the values that you want in local variables and then use them inside Entities.Foreach?

opaque ledge
#

Class is a managed type so you cant use burst with it, but you can make ForEach with class in your query but only with WithoutBurst().Run()

wide fiber
#

Yeah but to write cleaner code I want to use a singleton component instead of making some static variables inside the system, so @storm ravine talked about making the code cleaner

opaque ledge
#

Well, i dont know/remember that context so i just answered your question about if you can use burst with classes

wide fiber
#

How should I store a list inside a class deriving from IComponentData? With NativeList or with "normal" List? (I don't need burst, I need to query this component to read the data to use in other queries)

opaque ledge
#

You can do it with both

#

i mean, if you are going to somehow use that list in your other systems then make it NativeList, but if its self-contained then use List or Native

wide fiber
#

GenerateAuthoringComponent doesn't make NativeList inspectable :(

#

Should I dispose the native container inside the class deriving from IComponentData in the OnDestroy function of the system that writes to that component?

storm ravine
#

@storm ravine wait what, a class deriving from IComponentData and not a struct? Native container inside IComponentData?

Can I use burst with a Class? Or are you making a query for the singleton, save the values that you want in local variables and then use them inside Entities.Foreach?
@wide fiber yes class. You can’t work with that inside job/burst. Idea is query that singleton entity, get, for example NativeList, in local context of system OnUpdate and pass that list in to ForEach. No need fields on system for that, no need statics for that.

wide fiber
#

Ok, that means that I understood correctly

#

Should I dispose the native container inside the class deriving from IComponentData in the OnDestroy function of the system that writes to that component?
If the component doesn't exist and I query for that inside the OnDestroy() it gives me an error, should I use query.CalculateEntityCount to check if there is a singleton? (Or does a better way exist?)

I don't have this problem inside OnUpdate because I use RequireUpdate(query);

storm ravine
#

Should I dispose the native container inside the class deriving from IComponentData in the OnDestroy function of the system that writes to that component?
@wide fiber up to you. In my case as I mentioned above I have system which only destroy that containers in OnDestroy by querying that singleton entities

#

Yep, you need that check if your singleton may not exists

wide fiber
#

πŸ‘

storm ravine
#

@zinc plinth @storm ravine Sorry I was dining

So... I have my NativeMultiHashMap<Entity,int> and the idea is to end up with a parallel job able to do something with each entity in that NMHM and the sum of all int, so....

Run a IJobNativeMultiHashMapVisitKeyValue for the NMHM and build a NativeArray<Entity> and a NativeArray<int> with the same sizes , where the second NativeArray is the sum of each int[] inside a NMHM.

What I dont get is how to use IJobNativeMultiHashMapVisitKeyValue for that. IJobNativeMultiHashMapVisitKeyValue only has a ExecuteNext, no index and is executed N times as values has each key. How can I use it to build those arrays?

Sorry if the question is a bit obvious, I think I'm missing something big here.
@chilly halo now with you

#

You want TOTAL sum of ALL entities values in to one number yes?

#

Like you have 10 entities in map and every entity has 3 numbers - collected apple, orange, fish. And you want sum of all food from all entities? (Just as example)

zinc plinth
#

@storm ravine could you avoid the unnecessary pings please >.>

storm ravine
#

No. Suffer.

#

Sry, I just wok up πŸ™‚

wide fiber
#

Is there a way to get a random number inside a parallel job? (Foreach.ScheduleParallel())

mint iron
#

last i heard you have to create an array of randoms, one for each thread to avoid them producing the same value.

opaque ledge
#

i am using Shared Static for that, and put a Random in there and use that in my bursted jobs

stone osprey
#

One of my systems has a performance of about 0.20 ms ( Processes about 100 entities )... is this a good ratio ?

#

It calculates the position each frame

wide fiber
#
        {
            return math.acos(math.dot(v1, v2) / (math.length(v1) * math.length(v2)));
        }```

The problem with that function is that if the angle should be 180Β°, it gives me 0

#

It gives me always positive values

#

It's like:
if(angle >= 180f)
angle -= 180f;

stone osprey
#

Lets say im still using gameobjects for the visuals of my game... those gameobjects do have colliders... how could i code a system for listening to collisions between those gameobjects ?

storm ravine
#

Yes it's how it works, because dot product

The problem with that function is that if the angle should be 180Β°, it gives me 0
@wide fiber var a = new float2(0,1); var b = new float2(0,-1); Debug.Log(a.AngleDegrees(b)); where AngleDegrees is [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float AngleDegrees(this float2 v1, float2 v2) { return math.degrees(v1.Angle(v2)); }

wide fiber
#

Maybe it's 180.5 that gives me 0.5 instead of 180.5

storm ravine
#

Yes that expected. Angle is always <= 180 here

#

Ah stop it should be not 0.5

#

it should be 179.5

wide fiber
#

It gave me 0.0197.. when it was at the opposite (so around 180Β°)

#

Probably the problem is another, I will check other systems

storm ravine
#

Angle works as expected

#
            var b = new float2(0.01f,-1f);
            
            var c = new float2(0, 1f);
            var d = new float2(-0.01f, -1f);
            
            
            Debug.Log(a.AngleDegrees(b));
            Debug.Log(c.AngleDegrees(d));```
#

179 right side 179 left side

wide fiber
#

Yeah, it was a problem of execution order, sorry

#

Now I am doing another thing.

Basically now the projectiles that are shot from weapons are perfectly aligned with the weapon (I am setting the rotation to be equal to the weapon one) but I want to add an offset (based on the precision of the weapon)

How can I add an offset to the Z axis (in Euler) of a quaternion?

storm ravine
#

You want add scatter?

thorny halo
#

hello, is there a way to iterate over a NativeHashMap similar to how you can a dictionary. Just something like "foreach(var item in map.values)".

chilly halo
#

Like you have 10 entities in map and every entity has 3 numbers - collected apple, orange, fish. And you want sum of all food from all entities? (Just as example)
@storm ravine

Something like this...

NMHM a;
Entity e1;
Entity e2;
Entity e3;

a[e1] = [1,2,3,4,5]
a[e2] = [-1,1,-1,1]
a[e3] = [0,0,100,90,-50]

Inside the Job I need :

e1 -- 15
e2 -- 0
e3 -- 140

wide fiber
#

@storm ravine yes

chilly halo
#

good morning btw πŸ˜›

wide fiber
#

A random offset to the rotation of all the projectiles

storm ravine
#

@wide fiber multiply quaternions

#

math.mul(currentRotation, offsetRotation)

warped trail
#

@chilly halo there is IJobNativeMultiHashMapMergedSharedKeyIndices

chilly halo
#

@warped trail AFAIK that only works with <int,int>

warped trail
#

ohπŸ€”

thorny halo
#

does anyone know the difference between a multihashmap and a hashmap?πŸ€”

chilly halo
#

I tried with IJobNativeMultiHashMapVisitKeyValue but that executes one time for each VALUE, and I need the sum of all of them.
Just to clarify, I need to use the sum to modify a component but also to remove/add components depending on the final value.

#

does anyone know the difference between a multihashmap and a hashmap?πŸ€”
@thorny halo
HashMap= Dictionary <N,T>
MultiHashmap = Dictionary <N,T[]>

thorny halo
#

@chilly halo thanks

#

is there a way to iterate over NativeHashMap values in a job? I only see IJobNativeMultiHashMap interfaces.

storm ravine
#

@chilly halo there is IJobNativeMultiHashMapMergedSharedKeyIndices
@warped trail Deprecated. Only interface I mentioned above will continue exist (with mutable version)

coarse turtle
#

Looks like its updated with the latest entities version πŸ‘€

chilly halo
#

@storm ravine Good to know about that, before I start beating my brain out to see how to implement that Interface

#

I have enough try to find a way to sum all ints in a NMHM in a parallel job.

loud matrix
#

Is this possible or am i barking up the wrong tree?

public struct ItemBlobAsset
{
    public BlobArray<ItemBlobData> data;
    public ref ItemBlobData getById(string id)
    {
        for (int i = 0; i < data.Length; i++)
        {
            if (data[i].name.Equals(id))
            {
                 return ref data[i];
            }
        }
         return ref default(ItemBlobData);
    }
}

Looking for a way to grab items in a blob array by a FixedString ID, but I need to pass back a ref, and I need to have a catch for there not being a result

mint iron
#

mmm i dont think compiler will let you return a ref default, it will require a valid field or ptr source

loud matrix
#

Yeah this is my issue. I'm thinking of adding a "null" item as 0 when creating the database and returning the data[0] and checking for that

mint iron
#

yeah that might work!

#

i've used a workaround like this before

        public ref struct TryResult<T> where T : struct
        {
            public bool HasValue;
            internal void* Ptr;

            public ref T Value => ref UnsafeUtilityEx.AsRef<T>(Ptr);
        }
loud matrix
#

or i could be more verbose and have it look for the index, and then just sue that, but both would be mroe painful

#

I saw something similar when looking up the issue, though i wasn't sure if they would play well with Blobs

mint iron
#

blobs have been doing some unexpected things that's for sure.

loud matrix
#

Well they let me store meshes so they let me be lazy :p

mint iron
#

try this

     public struct ItemBlobAsset
     {
         public BlobArray<ItemBlobData> data;
         
         public unsafe TryResult<ItemBlobData> getById(string id)
         {
             for (int i = 0; i < data.Length; i++)
             {
                 if (data[i].name.Equals(id))
                 {
                     return new TryResult<ItemBlobData>
                     {
                         Ptr = (byte*)data.GetUnsafePtr() + i * UnsafeUtility.SizeOf<ItemBlobData>()
                     };
                 }
             }
             return default;
         }
     }

     public unsafe ref struct TryResult<T> where T : struct
     {
         public bool HasValue;
         internal void* Ptr;
         public ref T Value => ref UnsafeUtilityEx.AsRef<T>(Ptr);
     }
loud matrix
#

Would the Value and HasValue not also need to be set there?

#

And would it not be cleaner to just have a TryResult that contains only a ref to a ItemBlobData and a HasValue?

mint iron
#

mmm yeah you would want to set HasValue, so you can know not to call the exploding value

#

i dont think you can store a ref as a struct field, even in a ref struct, they only let u do that with Span<T>

loud matrix
#

Yeah i just gave that a try and it didn;t like it

#

Seems to work, though as per usual with me I cower at the use of "unsafe"

#

And for some reason it's having a hissy fit over this way of getting the name and casting it to string as opposed to when referencing the data index by its int id

mint iron
#

this data[i].name.Equals(id) ? or something else

loud matrix
#

nvm im being stupid

mint iron
#

there's also FixedString.Format("The entity is {0}{1}", entity.Version, entity.Index) if its useful for embedding strings in jobs, but only seems to work if its directly in the job root.

loud matrix
#

my issue was just with the search query string not the result, because jobs are a dick and strings are apparently the devil even when coming from outside the job

#

As for some reason a FixedString32 inside a blob referenced inside a job is fine to use ToString but a FixedString32 just inside the job can't use ToString

opaque ledge
#

ToString method returns string tho, which is a class hence managed

odd cipher
#

Hey, so I'm trying to make my noise generation code multithreaded but it for some reason generates some strange looking lines

bold sleet
#

im not sure if this is the right place to ask but, if i understand this right, if you use unity pro at all, and make a game using the Havok physics engine library, which you pay for (200 anual) and ship your game out as a standalone exe, and decide to cancel the license, the way Havok license reads is you must also remove all copies of your game featuring it too right?

opaque ledge
#

i think you should ask this question to DOTS/Physics forum, havoc people is there answering stuff

odd cipher
#

maxNoiseHeight is set to float.minValue and minNoiseHeight is set to float.maxValue

zinc plinth
#

hmm, do I need to dispose arrays from ArchetypeChunk.GetNativeArray myself or ?

odd cipher
#

im almost certain the problem is from me setting the minNoiseHeight and maxNoiseHeight in each execute

odd cipher
#

but not sure how to solve it

opaque ledge
#

i never did anything to do with noise but perhaps something about "x" variable ?

#

perhaps there is something weird going on with modulo and division

odd cipher
#

maybe, though the lines are only caused by the InverseLerp

opaque ledge
#

ah okay, something about lerping then

odd cipher
#

yeah, I think the minNoiseHeight and maxNoiseHeight variables are the problem but not sure

#

because the lerp did work without this job version

#

do those variables reset back to what they were after one Execute?

#

nvm it seems they dont

storm ravine
#

hmm, do I need to dispose arrays from ArchetypeChunk.GetNativeArray myself or ?
@zinc plinth no. Because this is direct reference to chunk memory, this is why you can change values in array and they immediately applied to chunk.

zinc plinth
#

hooo ok

odd cipher
#

cant figure this out at all

solar spire
#

@odd cipher you're setting the min and max inside of a job and not waiting on it, so it's updated over the course of the entire run of the job over the array. You would need to split it so you've recalculated the min-max over the entire texture before you start using them

#

because right now what you're seeing is how the job is executing

odd cipher
#

well im not using those variables afterwards, only changed in the job

solar spire
#

should you perhaps be having the min-max variables local to the function, and not the job?

odd cipher
#

well they are needed for the job, and only used in the job

#

not sure what youre suggesting

storm ravine
#

He mean

#

That one Execute sets value and other execute calls use that value

#

instead of initial float.Max\Min

#

And because it's parallel

#

every execute get random min\max which was set from one of other Executes

#

Simple example - you set initial value 0 and expect that it will be 0 for every execute, but it wouldn't.

#

Reason for that is how job collect data for executes. Under hood it just get IntPtr (through JobScheduleParameters from your job data void* pointer (which in turn get by simple AddressOf) ) to your initial struct which as result shared across all executes.

odd cipher
#

it shouldnt be reset though, the original code that worked didnt do that.

#

the new set value should be carried on to the next execute

solar spire
#

it all runs in parallel

#

the old version is not parallel

odd cipher
#

Yeah, I guess I'm just having a hard time wrapping my head around this

#

or how to fix it, I have a pretty poor understanding on how this noise generation works in the first place

#

I feel like it should work but it just doesnt

#

@storm ravine do you mean that the order of execution is random and therefore creating these weird lines?

storm ravine
#

Yes

#

Because all Execute runs in parallel

#

Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, output[index]); this part produces unexpected result because of random minNoiseHeight\maxNoiseHeight overwritten by other Executes

odd cipher
#

gotcha

storm ravine
#

Why you tying do that parallel? And not just main threaded\single threaded with burst. Which size of your map will be?

odd cipher
#

So, should I just do a IJobFor instead of IJobParallelFor?

storm ravine
#

Seems you trying noise generation implementation by Sebastian Lague. It runs on main thread fine (not the best but fine) Just use single bursted IJob \ Job.WithCode

#

IJobFor is same as IJobParallelFor but with two implementations of Schedule - all Execute runs sequentially on worker thread and ScheduleParallel - same as IJobParallelFor Schedule - batch size per thread

odd cipher
#

Yeah, a IJob works just fine

#

is there a way to do something like this but Burst compatible? System.Random prng = new System.Random(settings.seed);

storm ravine
#

Unity.Mathematics.Random

#

But remember - it's struct

odd cipher
#

Yeah, that works

#

6 milliseconds out of 26 is now gone with this new method, only took like 5 hours to figure out :p Thank you

storm ravine
#

It takes 20ms for you?

#

Which world size and noise octaves count?

stiff skiff
#

That sounds pretty heavy for perlin

storm ravine
#

Because of big octaves count and world size definitely

#

Well you can parallelize that.

stiff skiff
#

Is the link above the code you run in the jobs?

odd cipher
#

no I mean, 20 milliseconds for the noise and terrain generation with noise AND setting each pixel corresponding on what terrain

stiff skiff
#

Yeah that sounds very long

storm ravine
#

I interested in noise part only

odd cipher
#

well I dont know what the best way would be to time a multithreaded piece of code

storm ravine
#

Well for test

odd cipher
#

im currently using a System Stopwatch

storm ravine
#

return parallel schedulind

#

64 batch size

#

comment inverse part and if (noiseHeight > maxNoiseHeight) { maxNoiseHeight = noiseHeight; } else if (noiseHeight < minNoiseHeight) { minNoiseHeight = noiseHeight; }

stiff skiff
#

@odd cipher even for single threads, this quite high

odd cipher
#

noise generation time takes 0-1 millseconds

stiff skiff
#

float2 sample = new float2((x - worldSize.x / 2) / settings.scale * frequency + octaveOffsets[i].x, (y - worldSize.y / 2) / settings.scale * frequency + octaveOffsets[i].y); A lot of this is duplicated work every octave iteration

#

You are also iteration in columns, instead of rows,.

#

noiseHeight += perlinValue * amplitude; This can be replaced with an math.madd intrinsic

#
noiseMap[x,y] = noiseHeight;
noiseMap[x,y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x,y]);
storm ravine
#

Yeap rows first, for reducing false sharing

stiff skiff
#

This stores a value, only the read it again for a transformation.. and overwrite it?

storm ravine
#

He is doesn't need that inversion here tbh

odd cipher
#

I mean the whole thing takes 1 millisecond

storm ravine
#

It can be faster with suggestions above

stiff skiff
#

The code for updating min and max could likely be replaced with some nice simd select methods

#

The focus is to have as your octaves look be as few cycles as possible, and the writes afterwards to be sequentian

storm ravine
#

min\max can be dropped here completely πŸ™‚

stiff skiff
#
float2 point = new float2(x,y);
float2 sample = (point - worldSize / 2) / settings.scale * frequency + octaveOffsets[i]);
#

You might have to ensure that scale and frequency are also float2

#

Note that you can move worldSize / 2 outside of the octaves loop as well

#

Hell, the whole thing can move out, except for the * octaveOffsets[i])

#

You could probably rewrite the PerlinNoise function as well using the new mathematics package, in a much faster method

odd cipher
#

doesnt seem to work the same

stiff skiff
#

Ah sorry, I swapped a + for a *

odd cipher
#

ah yeah that fixed it

stiff skiff
#

Also this isn't a bursted job is it?

#

Since you're using an [,]

storm ravine
#

Hell, the whole thing can move out, except for the * octaveOffsets[i])
@stiff skiff not only. frequency not fixed

odd cipher
storm ravine
#

reorder for loops, rows first

odd cipher
#

is that faster?

storm ravine
#

(point - worldSize / 2) / settings.scale move out of octaves loop

#

is that faster?
@odd cipher yes, because of false sharing

#

when x loop first you going through array not linearly

#

And processor cache refill cache lines every time

#

when rows first you use cache lines effectively

stiff skiff
#

@storm ravine I think it works atm because they are using the [x,y] method of storing

#

This will break once you move to a single NativeArray<float>(Width * Height)

storm ravine
#

and not get new values every time but rarely, because they already in cache

#

@storm ravine I think it works atm because they are using the [x,y] method of storing
@stiff skiff you mean float2 implementation here which used in his array?

stiff skiff
#

@odd cipher Looks good, but do swap the x and y loops

#

I only just saw your burst job link πŸ˜‰ sorry bit behind

#

@odd cipher I wonder if it might be faster to move the checks for min and max noise outside of the loops

#

So instead of doing them for every pixel. You do a loop over the output array at the end and update the min and max. Should unroll the loop and SIMD it

storm ravine
#

Just remove them. They can be dropped here without any problem.

stiff skiff
#

Though I'm not sure how smart burst is at doing this

odd cipher
#

well I need some alternative to doing the same thing those two variables are doing

storm ravine
#

after dropping that he can easily parallelize that

#

unwrap XY loop and just calculate octaves part

odd cipher
#

ill have to continue tomorrow its 2:30 am and I have to get some sleep :p

stiff skiff
#

πŸ‘

opaque ledge
#

no sleep, only coding πŸ‘€

nimble reef
wide fiber
#

@nimble reef ? (I haven't understood the problem, do you want to make it show up in the inspector?)

nimble reef
#

No, I just want to set each entity's TileComponent's tileType to some value from that enum

#

Also, how would I find a specific entity once they've all been created? Like if I want to update one of them

nimble reef
#

I think maybe I'm misunderstanding what ECS can/cannot do. But that's what I'm trying to learn here. I'm basically trying to represent the grid in a 2d game via ECS, so I thought I'd make each tile in the grid an entity

opaque ledge
#

that is doable, you just get Entity reference somehow

#

but it all depends on how you struct your stuff

#

i am guessing each tile has 2 ints, x and y positions, you could put all the grid entities to a buffer, and select the grid entity you want from that buffer

#

i am not sure what to say about tile Type, you just simply set it, like
new TileComponent{tileType = yourEnum}

odd cipher
#

@stiff skiff how would you suggest getting rid of the min/max variables?

bold sleet
#

hey im looking at the docs and i dont understand, because it doesnt say, and the samples are confusing to me, but this isn't working at all:

#

entityManager = new EntityManager();

#

Entity _newEntity = entityManager.CreateEntity();

#

it throws a NullReferenceException error

opaque ledge
#

every world has their own Entity Manager, you have to access world's entity manager

#

World.DefaultInitializationWorldSomethingSomething.EntityManager

outer swift
#

How do I actually install DOTS in Unity 2020?

bold sleet
#

ok let me fix my code and i'll see if it works

outer swift
#

I can't see it in the list of packages, and the "show experimental packages" option is gone from the advanced settings in the package manager

#

I'm on the latest alpha, 2020.2.0a9

warped trail
#

show experimental packages escaped to Project Settings->PackageManager

outer swift
#

Ah, goodies. Thanks!

wide fiber
#

Any update on Physics Event handling? I want to receive the OnTrigger "event" without making an IJobIDontRememberTheName. But using SystemBase

opaque ledge
#

nah, we dont have those right now, maybe they will integrate to ForEach one day

#

i mean you can still call it in SystemBase, you just make the job thats all, instead of ForEAch

bold sleet
#

why isnt my Entity debugger seeing my entities

#

my list shows they are there, but the debugger doesnt see them

#

Entity _newEntity = entityManager.CreateEntity();

    managerEntityList.Add(_newEntity);
#

that works, but it doesnt see them in the Entity Debugger

#

oh nevermind i figured it out...

mystic mountain
#

Is there any good way for two systems to add entity references to a dynamicBuffer from created entities with commandBuffer?

opaque ledge
#

you have to create a workaround, since entity that is returned from commandBuffer isnt viable yet

#

my workaround is this, i put a RegisterComponent to new entity and put 'parent' entity in it, i have a system that queries for RegisterComponent and child adds itself to parent and then delete the RegisterComponent

gusty comet
#

Hi πŸ™‚ Quick question: I've created an entity that has been converted from a prefab (so it already has a physics body component on it), but I need to only update ONE aspect (linear velocity) of the component. If I use setComponentData, will the component be replaced? In other words, will I have to supply all the other configurations that I did on the prefab (gravity etc) just to set the linear velocity?

storm ravine
#

how would you suggest getting rid of the min/max variables?
@odd cipher I guess it’s question to me? πŸ™‚

#

Just remove them and inversion. Use amplitude for reducing β€œwhole black”

mystic mountain
#

@gusty comet Yes, the data of the component will be replaced with what you supply. So if you somehow was able to add angular velocity in your authoring it would be set to what you send in when you send in your linear velocty by SetComponent with PhysicsVelocity component.

gusty comet
#

@mystic mountain OK, thanks! πŸ™‚

#

@mystic mountain actually, I realized my mistake - I thought while I wrote the question that there was a 1-to-1 mapping between physics body and the component I needed to update, but since I only need to update the "PhysicsVelocity" component it's not that big of a deal πŸ™‚

odd cipher
#

@storm ravine So instead of InverseLerp I use amplitude somehow?

last jasper
#

Hey, I just came across something counter-intuitive. If I call localToWorld.Rotation, I would expect to get a quaternion that considers only the rotation of the object. Instead, localToWorld.Rotation also considers the Scale of the object. I would consider this a bug, but am I misunderstanding something here?

#

And for completeness:

    public class DebugRotationSystem : SystemBase
    {
        protected override void OnUpdate()
        {
            Entities.ForEach(
                (ref LocalToWorld localToWorld) =>
                {
                    Debug.Log(string.Format("localToWorld.Rotation={0}", localToWorld.Rotation));
                }).WithoutBurst().Schedule();
        }
    }
#

(Should probably add using Entities 0.9.1)

mystic mountain
#

@last jasper If I'm not really bad at my maths here. LocalToWorld.rotation is be the full rotation, scale is not part of it, from local space to world space. I.e. if you have it nested, it will be the full rotation to world space, equivilent to transform.rotation in the old system.

last jasper
#

yup, that's what I expected. Instead, localToWorld.Rotation is affected by the Scale. The two entities in the above example are not nested for simplicity, but still show this behaviour.

mystic mountain
#

Really can't tell from the images what you have done wrong.

last jasper
#

Me neither πŸ˜„

mystic mountain
#

You will need to show the full hierarchy or setup.

last jasper
#

Sure, I'll make a forum post

mystic mountain
#

If you simply do some wolfram alpha of your quaternions you'll see that your first rotation is something like 10-20 degrees

last jasper
#

yeah

#

that's exactly the point though, both have the same rotation

#

but localToWorld.Rotation returns a different quaternion for both of them

#

sorry for slow reply, I'm trying to add a bit more detail for the forum post πŸ™‚

#

You can see that Rotation is the same for both entities, neither has a parent, both are at the origin, but LocalToWorld.Rotation returns different quaternions. The only thing different between them is Scale

outer swift
#

What's the current best point of reference for pure DOTS design?

#

I've been looking at documentation and samples, and it's all a jumble.

#

I'm most interested in pure ECS, I can't say I like the idea of mixing GameObjects and Monobehaviours in, but if that's the intended workflow then I suppose I can hold my nose and cope.

#

What I really wonder about is really architecture. I'm sure I can get a few thousand cubes bouncing around on the screen, but that's not really going to help me understand how I'm supposed to handle stuff like input from multiple players, game sessions, asset pipelines and yada-yada

#

Am I asking a question with no real answer yet? Are batteries definitely not included?

amber flicker
#

What's the best point of reference for pure Monobehaviour design? πŸ˜… - you're right though, resources are thin on the ground. DOTS samples are partially supposed to be fulfilling this role but often criticized for their scope.

dawn badge
#

It's a tough one. I currently have a single mono behavior to handle loading the entities and storing an array of location data for all Systems to reference for collision

outer swift
#

The best point of reference for monobehaviour design is don't but I get your point

#

Yeah, ok, so I should expect to use Monobehaviours to orchestrate the ECS

#

My current preferred development practice is to just use a single Monobehaviour to send update signals and deltatime into my own stack, so the idea sounds just dandy to me

dawn badge
amber flicker
#

GameObject->Pure is the workflow that's here to stay, at least for the next n years. If you're interested in getting as pure as you can, Tiny is where it's at.

dawn badge
#

Main.cs is the only Monobehavior

outer swift
#

@dawn badge What do you use for collisions?

dawn badge
#

It's 2D so I just do a simple cast:

    private static bool isColliding(float aX, float aY, float bX, float bY) {
      var radius = 1f;

      var deltaX = aX - bX;
      var deltaY = aY - bY;

      return ((deltaX * deltaX) + (deltaY * deltaY)) <= (radius * radius);
    }
#

that's in my CollisionSystem

outer swift
#

ah, right

#

I got my own very simple SAT-based collision system written using the new maths lib that I was hoooooping to use

dawn badge
#

I expose the "grid" from Main via a static method

#

and meshes/materials..not sure it's great but it works

outer swift
#

Right, so you just load in materials and meshes and keep them in the Main, then whoever needs them looks them up from there?

dawn badge
#

yep exactly

#

currently using int codes so I can store in the struct for Components

outer swift
#

So before you start your big rendering foreach in each rendering system, you just fetch the mesh and material references from Main and ta-da?

#

Wait, so you have arrays with IDs aligned with the rendering components so you can slice into them?

dawn badge
#

Yea I just call Graphics.DrawMesh( after pulling the meshes with Ioe.Main.GetPlayerMesh() and Ioe.Main.GetPlayerMaterial()

#

exactly so while my Entities.ForEach filters I can still ForEach through my LocationData and update the correct Ids

outer swift
#

Can you actually call Graphics.DrawMesh from a big parallel foreach?

dawn badge
#

It's not parallel, Job Burst

#

well it's a weird one

outer swift
#

Ok, so it's a single-thread burst job

dawn badge
#

It's a raw compsystem but it runs after a burst job

#

so take your wins where you can πŸ˜›

outer swift
#

the job sets up everything, then the compsystem that depends on the job brrrrrrs through?

dawn badge
#

yep!

outer swift
#

Is that your general architecture? Jobs prep data for a compsystem that goes brrrrr?

#

And the dependencies decide order of execution?

dawn badge
#

[UpdateAfter(typeof(SomeScheduledSystem))]

outer swift
#

"beautiful"

dawn badge
#

The UpdateAfter is a life saver

#

you can really orchestrate to optimize where possible

outer swift
#

unity: c++ is bad we don't want users to deal with all that shit
also unity: haha we made c# into games-oriented erlang

dawn badge
#

haha well if you ever did erlang/elixir it's not terrible in comparisson. Similar to GenServers (mentally) just not purely sync which is nice

#

this is how I am learning C# and Unity and I am not having too hard a time

outer swift
#

I'm unfortunately from extremely imperative side of things

dawn badge
#

the docs need work though..like relying on intellisense and source definitions is pretty raw

mystic mountain
#

Is there any material on how using Adressables with DOTS yet?

outer swift
#

@dawn badge I noticed. Good to hear that it doesn't have to be tremendously complicated.

#

So thanks! That sorta allayed my fears a bit.

dawn badge
#

Isn't there a conversion script for that? I saw some people just telling Unity to convert to entity?

#

@outer swift yea it's doable! just be ready to yell at clouds πŸ˜‚

outer swift
#

my yellinator is set to cloud

#

Fortunately decided to clone an easy game for practice

dawn badge
#

Looks like a great candidate for ECS

storm ravine
#

Is there any material on how using Adressables with DOTS yet?
@mystic mountain not yet. Subscenes + addressables will be first step on unity near plan. Currently we use addressables with dots without problem. At app start loading all required stuff asynchronous, convert and store maps on entities (note: we use own persistent unique id for every resource, for excluding references to unity internal solutions and serialization which breaks from time to time)

gentle osprey
#

Is there a way to access the shared component of a random entity inside an IJobChunk?
I'm doing the CombatBees ECS project, and need to see if 'this' bees target resource is held by a bee on the other team, and I store teams in SharedComponents. Open to change the use of SharedComponents of anyone has any other ideas.

#

To rephrase, the problem is essentially: I have an entity, which targets another entity, I need to know the SharedComponent of the other entity.

storm ravine
#

Is there a way to access the shared component of a random entity inside an IJobChunk?
I'm doing the CombatBees ECS project, and need to see if 'this' bees target resource is held by a bee on the other team, and I store teams in SharedComponents. Open to change the use of SharedComponents of anyone has any other ideas.
@gentle osprey Not directly. You can only get SCD index, because itself they not stored in chunk, chunk only store index to unique SCD in global map

gentle osprey
#

The SCD index is the same for all entities with the same shared component though? So, in this case I would only need to see if the other entities SCD is different from "mine".

mystic mountain
#

@storm ravine So you wait with the whole conversion before you've loaded all stuff?

storm ravine
#

@mystic mountain well that content local and load fast in our case. And it loads at app start right in intro scene with copyrights etc. πŸ™‚

#

The SCD index is the same for all entities with the same shared component though? So, in this case I would only need to see if the other entities SCD is different from "mine".
@gentle osprey Yes

gentle osprey
#

But there's no easy ways to get access to the SCD index of a random entity? Like, there's no SharedComponentDataIndexFromEntity or similar?

mystic mountain
#

@storm ravine I see, what I want to do is load stuff based on map loaded and what other clients who joins map has chosen as visuals. πŸ€” I've not gotten my hands dirty with adressables yet, so not sure if I should just wait for their solution to show up.

storm ravine
#

Well addressables part itself async, thus wouldn't stall main thread and can be wrapped in to nice loading πŸ™‚

#

Conversion pretty fast, but you should convert batches, not one by one which inefficient. One of ways create hidden GO when every thing loaded, pass GO prefabs to that GO and using declare reference prefabs add them to conversion list and convert to entity in Convert, and store references to prefabs where you need. Or if don't need prefabs and just immediately instantiate content workflow will be similar, just without that utility GO.

#

But there's no easy ways to get access to the SCD index of a random entity? Like, there's no SharedComponentDataIndexFromEntity or similar?
@gentle osprey you can get SCD index on main thread by EntityManager and use that, or you can GetSharedComponentIndex from chunk to which entity belong

mint iron
#

a word of warning on that, runtime conversion is not going to be supported according to topher; the answer to all my issues was pretty much 'don't do it`. Conversions with IConvertGameObjectToEntity within a SubScene are fine, but hes talking about instantiating a go, and triggering a conversion at runtime.

For example i had an issue where i instantiate a GO at runtime, it converts and tries to create Entity prefabs based on referenced assets, but in the case of parent/child conversions, there's no guarantee that parents will have been converted before their children which for me broke everything. The process worked in earlier versions of Entities but it broke when they refactored to include assets other than GOs in conversion.

#

It seems that the intention now is to use Addressables to pull in an entire SubScene (a pre-converted blob of stuff that gets shoved right into the world).

mystic mountain
#

So I will need a subscene for each asset? πŸ€”

mint iron
#

no the subscene would contain all your entity prefabs, already converted.

storm ravine
#

Parent\child conversion works without problems, but you'll get result only on next frame, before that you only operate "hierarchy" through LinkedEntityGroup

mystic mountain
#

@mint iron Hmm right,.. but how would you go about; have a wide range of characters and only load the ones that are used? Would you chunk them into subsets and make subscenes of them?

storm ravine
#

For example after instantiation I want to get some things from child parts of complex prefabs, I use LinkedEntityGroup for that, because it's already here after GameObjectExportGroup run

mint iron
#

that's a good question; i haven't gotten that far yet; i gave up and went onto other things after being told it wasn't going to be supported.

storm ravine
#

Conversion system is how Convert to entity processed πŸ™‚ convert and inject just temporary dirty hack πŸ™‚

mint iron
#

i think hes referring to anything that's not pre-converted

storm ravine
#

He speak about hybrid workflow

mint iron
#

conversion system supposed to run at editor time only?

storm ravine
#

Why?

#

And I never heard about that intention from dots team

mint iron
#

thats what it seems like he was saying, that conversion system/world would eventually not even exist at runtime. you can of course make your own to do that same thing, but they dont want to support it, is what i took away.

storm ravine
#

Only about convert and inject part

#

I’ll ask Fabrice

#

He is working on that part of dots

mint iron
#

okay well then his response to me was irrelevent, i would have the same issue with convert+inject as with a conversion system, becuse its a flaw in the underlying systems.

storm ravine
#

For clarifying and excluding β€œguessing” πŸ™‚

mint iron
#

please, some clarity there would be great

storm ravine
#

Yep. Until that, just my thoughts:

#

Runtime conversion

#

I mean pure convert to entity should be anyway πŸ™‚ subscenes for everything not cover that.

#

Simple example is some procedural things

#

You definitely wouldn’t have all variations of things πŸ™‚

#

Yes you can predefine some parts and use subscenes

vagrant surge
#

@storm ravine do you use shared components or chunk components in your project?

storm ravine
#

But IMO convert some things at runtime (not hybrid GO’s) will be here long time πŸ™‚

#

@storm ravine do you use shared components or chunk components in your project?
@vagrant surge yes, SCD for filtering

#

Chunk component in todo list for some things πŸ™‚

#

But not yet, it will be on pre release and final optimisations

loud matrix
#

This is probably a dumb C# question rather than a Blob one but, any reason why I'd get the following error when trying to use BlobBuilderArrray as a variable in a custom delegate?
The type 'BlobBuilderArray<T>' may not be used as a type argument

loud matrix
#

Damn well that ideas downt he drain

#

As far as im aware there would not be a way to do this then

public class DatabaseBLobAssetConstructor<T> where T : struct, IDatabaseitem
{
    public BlobAssetReference<DatabaseBlobAsset<T>> reference;
    public DatabaseBLobAssetConstructor(List<T> rawData, AssetConversionAction<BlobBuilder, BlobBuilderArray<T>> dataConversion)
   {
        BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);

        ref DatabaseBlobAsset<T> itemBlobAsset = ref blobBuilder.ConstructRoot<DatabaseBlobAsset<T>>();
        BlobBuilderArray<T> data = blobBuilder.Allocate(ref itemBlobAsset.data, rawData.Count);

        dataConversion(ref blobBuilder, ref data);

        reference = blobBuilder.CreateBlobAssetReference<DatabaseBlobAsset<T>>(Allocator.Persistent);
        blobBuilder.Dispose();
    }
}
#

AssetConversionAction being my delegate

mint iron
#

where does dataConversion come from

#

what about this

public interface IDatabaseBuilder<T> where T : struct, IDatabaseitem
{
    void Build(ref BlobBuilder blobBuilder, ref BlobBuilderArray<T> builderArray);
}

public class DatabaseBLobAssetConstructor<TBuilder, TItem>
    where TBuilder : struct, IDatabaseBuilder<TItem>
    where TItem : struct, IDatabaseitem
{
    public BlobAssetReference<DatabaseBlobAsset<TItem>> reference;

    public DatabaseBLobAssetConstructor(TBuilder builder, List<TItem> rawData)
    {
        BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);

        ref DatabaseBlobAsset<TItem> itemBlobAsset = ref blobBuilder.ConstructRoot<DatabaseBlobAsset<TItem>>();
        BlobBuilderArray<TItem> data = blobBuilder.Allocate(ref itemBlobAsset.data, rawData.Count);

        builder.Build(ref blobBuilder, ref data);

        reference = blobBuilder.CreateBlobAssetReference<DatabaseBlobAsset<TItem>>(Allocator.Persistent);
        blobBuilder.Dispose();
    }
}
#

or

public class DatabaseBLobAssetConstructor<TItem> where TItem : struct, IDatabaseitem
{
    public BlobAssetReference<DatabaseBlobAsset<TItem>> reference;

    public void Build<TBuilder>(TBuilder builder, List<TItem> rawData) where TBuilder : struct, IDatabaseBuilder<TItem>
    {
        BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp);

        ref DatabaseBlobAsset<TItem> itemBlobAsset = ref blobBuilder.ConstructRoot<DatabaseBlobAsset<TItem>>();
        BlobBuilderArray<TItem> data = blobBuilder.Allocate(ref itemBlobAsset.data, rawData.Count);

        builder.Build(ref blobBuilder, ref data);

        reference = blobBuilder.CreateBlobAssetReference<DatabaseBlobAsset<TItem>>(Allocator.Persistent);
        blobBuilder.Dispose();
    }
}
loud matrix
#

Hummm that might indeed work, even looking at it is confusing me somewhat so I'd not have come up with doing it that way for sure.

tardy locust
#

The first one looks very...

#

"This thing is doing more things than one"

#

The second one looks more readable.

loud matrix
#

I'm using the second to be fair, i am having to rewrite a chunk as i have two types floating around being converted between in IDatabaseBuilder.Build

#

but it looks like it should work, and cut out a massive amount of copy and pasting

tardy locust
#

That would be the purpose of templating, yes

#

πŸ˜›

loud matrix
#

More than my fix i mean, which was to just use the rest of my templating but have a new Constructor class for each type i needed to convert

tardy locust
#

Well it could give you some customization if you needed it

#

But if you don't, then yea, waste of time

loud matrix
#

That's true, but i can always do both

#

for ones that just need a conversion script I can use this method and for anything more in-depth just do it the old way

tardy locust
#

"Always future proof your code, but never try to be too smart" is how I like to look at that πŸ˜›

loud matrix
#

Being smart is what we have xzjv for

tardy locust
#

outsourcing, working smart not hard

loud matrix
#

And if for some reason they're sleeping, which doesn't seem to ever happen, Eizenhorn exists πŸ˜›

tardy locust
#

But then you have to understand a level higher than your own

#

Could be harder

#

πŸ˜›

loud matrix
#

That is why I am currently resisting the urge to day drink while trying to wrap my head around this while expanding it.

tardy locust
#

There is that point though

#

Where the alcohol makes you the genius programmer

#

galaxy brain

loud matrix
#

I'm in that lovely grey area of having 24 years coding experience but very little high end C#

tardy locust
#

Huh. 24 years.
I'm 29 years old hah

#

I'm about 10 years behind

#

πŸ˜›

loud matrix
#

I was taught to code realllly young as my dad was a BT engineer and saw it being useful

tardy locust
#

How old are you though?

loud matrix
#

32

tardy locust
#

Ah okay.

naive parrot
#

whats BT?

loud matrix
#

British Telecom

naive parrot
#

i see

tardy locust
#

I guess starting at 8 is not so bad

loud matrix
#

In order to understand Blob assets fully and memory management in DOTs i think he needed to have started a few years earlier

tardy locust
#

Well

#

Understanding the fundamentals is fairly easy...a bunch of arrays of numbers

#

But the hard part

#

Is to understand how to use it to your advantage

#

For example using 1D arrays to store different kinds of data is completely legitimate. Something other languages are shunned for (like Lua and JavaScript)

#

Difference is you represent by numbers rather than objects πŸ˜›

#

Isn't a blob just an arbitrary container of data?

loud matrix
#

Pretty much yeah, just cotnainers for immutable data accessed via reference

#

And until someone corrects me I'll pretend I'm right

tardy locust
#

Lol

dawn badge
#

whatever works in your head

tardy locust
dawn badge
#

haha 100%

loud matrix
#

I personally find i program in eldrich runes. The issue is once the code is written no mortal man can decipher the madness within.

tardy locust
#

We have comments for that

dawn badge
#

directories and apt naming are good as well

tardy locust
#

"If it was made by a human, it means we can analyse and understand it"

  • Zelda, Breath of the Wild
#

πŸ˜›

dawn badge
#

all systems go in the systems dir
all components go in a components dir
all archetypes go in an archetype dir

trust me it helps

#

namespaces help too..

loud matrix
#

I started that way, then had to go with contextual folders

#

as grouping all movement components and systems together just made it so much easier to find

tardy locust
#

final project
_final project private
final project (1)
final project 2
Master Project
master project (2)

dawn badge
#

that is interesting

#

so domain related?

#
Player
  Systems
  Components
FirstLevelBoss
  Systems
  Components
#

What about shared systems/things?

#

In a shared dir?

loud matrix
#

More general than that for mine

Scripts
    Camera
        Debugsystem
        FollowSystem
        TargetEntity
        TagMainCamera
     Movement
         Dampingssytem
         PlayerCiontrolSystem
         Throttle
         Velocity
         VelocitySystem
dawn badge
#

ah gotcha

tardy locust
#

It's funny call it "Scripts".

#

I call it "Source"

loud matrix
#

so camera is camera only stuff, but movement is player and emery related

dawn badge
#

yea I guess it's just standard with Unity

tardy locust
#

Nah it's something people do

#

There is no standard πŸ˜›

dawn badge
#

oh..

#

that's kind of my problem right now

#

nothing is standardized

tardy locust
#

The only folder that has to be the way it is would be "Assets"

#

That's it

#

The rest of the folders in your "Assets" is free game

#

Editor is one other exception I think

#

Because the editor looks in that specifically for editor extensions

dawn badge
#

huh

tardy locust
#

Don't know if Resources is still necessary to use? It might be

#

Resources is another special folder that you can use with the Resources loading system in Unity

#

But it's not like you can't put other things in there too

#

It's typically a nice place to dump things that can be modded by players

dawn badge
#

Yea currently in my small project I have

Ioe (master) $ find Assets/Scripts -type f -name '*.cs' | grep -v .meta
Assets/Scripts/EntityBuilders/EnemyEntityBuilder.cs
Assets/Scripts/EntityBuilders/PlayerEntityBuilder.cs
Assets/Scripts/Archetypes/EnemyArchetype.cs
Assets/Scripts/Archetypes/PlayerArchetype.cs
Assets/Scripts/Components/EnemyComponent.cs
Assets/Scripts/Components/PlayerComponent.cs
Assets/Scripts/Main.cs
Assets/Scripts/Systems/EnemyMoveSystem.cs
Assets/Scripts/Systems/PlayerRenderingSystem.cs
Assets/Scripts/Systems/EnemyRenderingSystem.cs
Assets/Scripts/Systems/CollisionSystem.cs
Assets/Scripts/Systems/EnemyAnimationSystem.cs
Assets/Scripts/Systems/PlayerAnimationSystem.cs
Assets/Scripts/Systems/PlayerInputSystem.cs
tardy locust
#

You use cmd for git?

dawn badge
#

hopefully it is maintainable..

#

I am on Mac, but yea I use cmdline for as much as possible

tardy locust
#

I see.

#

I like to use GUI for git

mystic mountain
dawn badge
#

ahh well you have a Client and Server!

#

nice

#

Oh I use git a lot at work. So UI won't let me cherry pick from a specific branch into a release branch and rebase from a certain point in history

#

Didn't have a choice lol

tardy locust
#

I tend to find that all you need to do is have tight namespace organisation. Make sure your namespaces make sense and then make sure to use them properly. If something doesn't fit in a namespace you made, expand it and make sure to move everything in there that now fits it, rather than sorta fits another namespace you did.

#

@dawn badge Er

#

I do that in Gitkraken all the time

#

GUI based tool

dawn badge
#

Oh for real? Maybe it has gotten better since

#

I just have soo many scripts

tardy locust
#

And I can almost assure you that a lot of other GUIs also support what you just said

dawn badge
#

Reason I like ECS, less GUI more code/control haha

tardy locust
#

cherrypicking

#

Sure more control, I guess, but also make sure to support the design driven setup that Unity has. Ideally a programmer should make things that designers requests and then sit back and chill or fix bugs.

#

Help them to help themselves

dawn badge
#

Glad you like UIs. I can't use them very well for spatial things like Git

Oh I just do this on the side. Learning to make art, I already make music and code. This is what I am trying to do in my free time

tardy locust
#

Doesn't change what I said though

#

πŸ˜›

dawn badge
#

Sure but I will never work in a game studio lol

#

Anyways don't want to derail

tardy locust
#

"I can't use them very well for spatial things like Git"
Could you elaborate on what this means?

dawn badge
#

It means GUIs do things you don't 100% know all the time. If I am merging branches from separate remotes and rebasing I don't want to click the wrong button. If the mental model doesn't match the UI I get stuck. I have full control via CLI and can automate to my liking if need be.

tardy locust
#

hmkay

dawn badge
#

But yea anyways @mystic mountain your structure seems good

#

At the end of the day, if you are working on something alone and it makes sense go for it. If you are working on a team, document standards to explain the pattern(s)

loud matrix
#

I present to you why GIT should only ever be used in GUI form when working in a team

tardy locust
#

Yeah, that's a nice overview

loud matrix
#

That's not even the worse we'd had recently

#

When the language branches come in all hell breaks loose

dawn badge
#

If everything is a squash merge and master is protected nothing is complicated

#

but not every team can do 100% trunk based so I get it

tardy locust
#

Master is never safe πŸ‘€

#

Git can always screw something up

loud matrix
#

I always end up just working on Master for my own work, I bounce back and forth on ideas and systems too frequently to do it properly :p

dawn badge
#

yea for local work master mostly, then branch if I know it's sketchy haha

tardy locust
#

Git is "Quicksave" when working alone

#

Before you poke the dragon

dawn badge
#

but in teams master can only be merged into

loud matrix
#

That's what i use stashes for, but Unity seems to have a hissy fit when I stash sometimes and decided it needs to change my package versions.

tardy locust
#

In teams you should always have a git master who is the only one who can merge into master

#

Only stash while working in your GUI. As soon as you are done with it, pop

#

And go back in and work

dawn badge
#

ah stash and unity aren't friends? interesting

tardy locust
#

Meta files is Unity's downfall when it comes to Git

#

They can be messed up so easy

dawn badge
#

oh right..everything has to be generated

tardy locust
#

Yes

#

And some times Unity generates after a push

#

So you get new "changes" (which are non-changes)

#

And then you have to push meta files that Unity believes it changed

#

Even if you can compare to last push and see no changes

#

But Unity will damn keep on believing it did

dawn badge
#

it feels dirty to push meta files

tardy locust
#

Yea, but you gotta

dawn badge
#

but it is what it is I guess..

lusty otter
#

I don't have issue with meta files

tardy locust
#

gets nam-like flashbacks with git and meta files

lusty otter
#

Some scene and project setting stuffs do randomly add missing props though.

#

What are the meta file changes you are seeing?

tardy locust
#

Here is a scenario I've experienced a couple of times:

  • Do changes in scene. This affects meta files.
  • Save the scene and everything in it.
  • Go to Git client and commit/push
  • Go back into Unity.
  • Unity now claims to have made changes to other meta files (or the files you just pushed)
#

And so you have to save and push again

#

This is a very common issue

dawn badge
#

this is perfect use case for git commit --amend assuming you are not on master because it alters history if you have already pushed

#

but it sounds like a PITA

loud matrix
#

Problem is you don;t find out until you've done different work

tardy locust
#

I like pita

dawn badge
#

oh.. it does it "later"

tardy locust
#

Yes.

dawn badge
#

amazing πŸ˜‚

lusty otter
#

πŸ€”

#

Maybe it's just me but I don't have that issue doing exactly what you described.

tardy locust
#

Some times it happens

#

Some times it doesn't

#

It's very random

loud matrix
#

so your metas in git just get messed up into a knot of what commit they actually belong to. A good use case for Pure ECS though UnityChanExcited

tardy locust
#

And then you get the perpetual .meta commit

#

It's a type of commit where it keeps telling you that something went missing from a previous commit, so it deletes a meta file. Okay you think, I'll push that. No problem.

#

You push it, and it shows up again the next time someone makes a push.

dawn badge
#

gasps

#

that sounds unfortunate

tardy locust
#

It's so infuriating

dawn badge
#

why can there not be a single meta file?

#

or something

tardy locust
#

That would be like having a single code file

dawn badge
#

oh

#

or at least all meta files go into a meta dir

tardy locust
#

It would be better if meta files are not necessary at all

dawn badge
#

yes that too lol

loud matrix
#

I remember hearing this as a reason for people moving to GODOT a while back (Well that and pixel precision in 2D)

tardy locust
#

Most of the files in Unity are YAML based. They are text already .-.

#

Why use meta?

dawn badge
#

GoDot has much less "keeping track" files, but still has some. Wish it had native ECS but Vulkan is the focus for 4.0

#

I guess with ECS I don't get many meta changes

tardy locust
#

ECS is a paradigm

#

You can do ECS in godot

dawn badge
#

ehh managing the threads?

tardy locust
#

It is a paradigm, still

lusty otter
#

That's Job system, has nothing to do with ECS.

tardy locust
#

A programming paradigm

dawn badge
#

right but DOTS is nice because it handles a lot for you

loud matrix
#

Screw it, guys, I have a solution!

dawn badge
#

brust compiling, job systems, etc..

loud matrix
#

FLASH!

dawn badge
#

FLASH!?

tardy locust
#

Sure, so you wish that Godot had DOTS

dawn badge
#

yea exactly lol or something similar

loud matrix
#

Action Script 1, never had these issues back in the day!

tardy locust
#

Lol

loud matrix
#

Sure we didn't have version control, but who cares πŸ˜›

tardy locust
#

ActionScript 🀣

#

Let me go grab my floppy disc 3.5 grandpa

#

Then you can transfer the code to me

dawn badge
#

you should make a game in DOTS that lets you write actionscript flash games?

#

like roblox? but worse? haha

tardy locust
#

Why engage with torture?

#

That's illegal in most countries

loud matrix
#

pifft, 8" floppies were where its at

#

Now if you'll excuse me I need to find my 15 separate Ultima Underworld install floppies.

tardy locust
#

You need a floppy reader too

loud matrix
#

Got a USB one

tardy locust
#

That's cheating man

loud matrix
#

I've not had a PC case with bay slots in years

tardy locust
#

Yeah, adds to the challenge

loud matrix
#

I wonder, can i get a IDE to SATA2 converter

#

I think this may have been the most off topic this channel has ever managed to get

#

From my terrible programming, to folder structure, to unity meta issues to floppy disks

tardy locust
#

slow day at DOTS

dawn badge
#

yep

storm ravine
#

@mint iron Well, Joachim answered to me before Fabrice, great thanks to him for that (and whole DOTS team, they really kind and very responsive and helpful) πŸ™‚ He don't know if they will deprecate runtime conversion, which confirms what I heard, that only Convert and Inject will be deprecated definitely but not Convert To Entity. But of course general recommendation is use subscenes everywhere if that possible, because off size & memory cost at runtime (which expected of course, with runtime conversion you of course keep everything in memory all the time, where with subscenes you can simply unload things until you need that again). And relates to that we decided use convert to entity with our workflow with Addressables now πŸ™‚ But when they will add native support (and they will as they mentioned) we will compare, worth it for us - drop our solution or not πŸ™‚

dull copper
#

they do recommend to use subscenes but they still are the most broken part on the dots ecosystem πŸ˜„

mint iron
#

awesome, thank you for chasing that up.

dull copper
#

like, they work alone, but not that well with other dots packages

#

also hybrid setup is pain with subscenes as you can't just place cross scene refs even

#

in the future, definitely

#

I try them every now and them and after banging my head to the wall for some hours I always give up πŸ˜„

#

dots physics for one

#

but latest unity physics does work already better

#

in past the joints went all bonkers, then some other physics scripts (which I suppose were due to the way they were setup but at the same time, they were directly from ECS sample repo)

#

joints seemed to work on latest versions btw

#

but ultimately, going to subscenes makes non-hybrid rendering pain

#

and currently hybrid rendering v2 isn't faster on typical game scenes

#

(than old GO rendering)

#

yeah, I'm aware of the dark days ahead πŸ˜„

#

well, if you use it like it's supposed to be used, I guess it's not harder

#

but if you need the old renderer, you'd need to have some way to sync entities to GO transforms and subscenes make it pain

#

there are ways around it, but it's dirty

#

I basically just need the GO transform for the entities so can sync them efficiently on jobs

#

convert and destroy atm but inject would work too if the rendered GO would be on the same object

#

I'm basically using modified version of the old GameObjectEntity's transform syncing

#

I just set the transform to different GO, basically I have GO for dots conversion and separate GO for rendering and and animations etc, on conversion I assign the visual GO's transform to the entity that get's converted

#

it's a messy setup but it lets me get fully functional rendering and old animations

#

I guess, I've thought about the spawning too as it's going to happen anyway in some form

#

anyway, I did come up with solution for that in past but there were other dots subscene issues back then

#

I can look up the case where physics script broke on subscenes but worked fine on convert and destroy (on traditional scene)

#

I'm still so dots noob that I just try to avoid things that don't work my way πŸ˜„

#

and I totally understand that things I do are not usually things how Unity wants these things to be used

warped trail
#

im wondering if there will be some examples on how to properly use this new subscene stuff that was added with 0.10?πŸ€”

dull copper
#

if some day hybrid rendering is fully featured, I'll probably consider it again

#

I'm assuming all scenes on DOTS will eventually be dots subscenes, or using similar structure

#

I mean it would make sense, considering the serialization benefits

vagrant surge
#

like it was on unity tiny old version

dull copper
#

I don't think that will happen any time soon

vagrant surge
#

subscenes definitely will be awesome for the next gen consoles

#

couse they would be literally instant to load

dull copper
#

the direction Unity is going, you still author with conversion, even for dots subscene

#

I really don't like the conversion scheme at all

mint iron
#

for runtime conversion, should we in the future be making our own conversion systems? i assume the conversion world will be around at runtime and run just work the same as if it were in a subscene/editor.

dull copper
#

talking of dots editor, is there any chances we could dock the entity conversion preview to where ever we want without it only freezing to single entity's view?

#

like, you can do that now but it won't track the selected part anymore

#

I'd love to dedicate it some actual space on the Unity editor

safe lintel
#

while youre here @digital scarab πŸ™‚ i noticed when i updated to 0.10.0 inactive child gameobjects dont get added to a parent's child buffer after conversion, not sure if this is expected or not? the child entities did have the parent component pointing correctly to the parent entity though

storm ravine
#

in future there should never be a reason for runtime conversion, we need to figure out all the use cases and provide a solution for them
@digital scarab Yep it's definitely final target, that DOTS workflow should feel easy same as legacy workflow, and just give users "performance by default" πŸ™‚

dull copper
#

hopefully that perf by default on more than few cores πŸ˜„

#

yes, I was supposed to send the repro project for that

mint iron
#

for the record my main use case is around asset management and remotely configurable system settings. I want to be able to download my stuff with addressables on load from remote server; from that i can dynamically build game elements. They can't all be baked into a downloaded SubScene because not all of the assets are currently convertible (sounds, particle effects), so i've had to do things like storing the addressables Runtime key to be able to link everything.

dull copper
#

I still try to get it out to get more feedback on that

amber flicker
nimble reef
#

i am guessing each tile has 2 ints, x and y positions, you could put all the grid entities to a buffer, and select the grid entity you want from that buffer
@opaque ledge What kind of buffer? Like a NativeArray?

opaque ledge
#

there is a component type called DynamicBuffer, it gives you the ability to have a 'nativelist' as a component on your entity

nimble reef
#

Oh interesting! Thanks

amber flicker
#

Oh thanks @digital scarab - sorry to add to the list πŸ™‚ - yes, simple as add component object to an entity and then click on the entity in the inspector

#

Also... don't suppose you got a chance to sound out the ScheduleAuto / chunk threshold idea? No worries, just wondering.

nimble reef
opaque ledge
#

yes, you can make a buffer that holds Entity field, and then you can put this buffer to an entity and put your referenced entities into that buffer

nimble reef
#

I see. Thanks again

nimble reef
storm ravine
#

Because you have synch point after getting buffer. Synch point with structural changes which invalidates your buffer.

nimble reef
#

I'm not familiar with that term. What does Synch Point mean here?

storm ravine
#

Place where all jobs completes for making structural changes

#

Structural changes is thing when chunks data layout changes

#

Which mean there is shouldn't be any work on chunk memory for excluding race conditions and data corruption

nimble reef
#

Oh, so me going into a for loop invalidates stuff?

storm ravine
#

Why this invalidates native arrays? Because they points to chunk memory and after structural changes there is no guarantee it will point to the same thing

#

In your loop you have CreateEntity

#

Which trigger structural changes

nimble reef
#

Ahh I see

#

Makes sense

storm ravine
#

Every EM call which can change data layout (Add\Remove components, changing SetSharedComponentData value (because it changes entity chunk), Creating\Destroying entities, SwapComponents etc.)

loud matrix
#

There, database BS finally sorted. Now to stress test it and see how horrific an idea it is to do string based lookups on a blob database for every update UnityChanExcited

naive parrot
#

@storm ravine was wondering if your game uses any of the new SRPs or is it the Standard pipeline? would it be possible going forward to stick with old rendering pipeline and still adapt all of the new DOTS workflow and packages which as implied is sort of essential since subscene is entirely designed around 'pure' ecs workflow and requires hybrid renderer. am i mistaken.?
i have an ongoing project , 2yr into the development. slowly been moving performance critical aspects of it to DOTS land. often i am in more need of the ECS architectural advantage than performance benefit so am ok with hybrid nature of things with managed object sticking to entities here and there. on road ahead will this all be 'non ideal route'? some insights and suggestions would be nice..

tardy locust
#

It's likely that Unity will be completely DOTS/ECS based in the future under the hood and it won't matter much what you do on top.

#

But that's likely the really long term plan

storm ravine
#

We're on built in render pipeline, not using SRP, not using subscenes

naive parrot
#

so no Hybrid Renderer ?

storm ravine
#

We use HR + own renderer

#

We not using v2 version which only SRP compatible

naive parrot
#

what specifically have you added/changed to accomodate all your rendering needs , LOD and Culling aside..

storm ravine
#

gpu animation

naive parrot
#

i have read a bit on it since thats one of the major challenge trying to do all the 'core' stuff ECS way. dots animation package is apprently no go. i did take a look at a repo on Joacim's github as well , probably from nordeus demo ?

storm ravine
#

Own solution

#

but idea close to Joe and Nordeus

naive parrot
#

one very simple question since i haven't used HR first hand yet ,in own project , how do you go about updating material properties within ECS?

storm ravine
#

I only update them in my renderer, for HR I not update any thing, HR used for environment rendering, where I do stuff with my custom shaders, like triplanar mapping, shaking trees etc. which not using per instance properties but using global shader var's

naive parrot
#

i see. also , are you using light probes , reflection probes , lightmaps in your game. does it all work out of the box with HRV1 for supported shaders like Standard one for eg? or all of that stuff needs to be manually updated as some global params for shaders like standard renderer does..

storm ravine
#

If we'll require more properties, I just extend animation renderer or write new one

#

Not using, because everything is procedural generated at runtime

naive parrot
#

i see. that lends you lot of flexibility from ground up

storm ravine
#

Well you always can write your own renderer and shaders, and sample lightmap, probes etc by yourself

naive parrot
#

yea am all ok with that. just want to know if thats the route i need to take or existing solutions are already there.

#

i have realized ECS needs to be greatly complimented by design to warrant a full move to it. i would settle for core features like physics/rendering/navigation and interface with them via simple hybrid oriented APIs but apparently hybrid is forbidden fruit now.

loud matrix
#

Wellllll Fu-- (γƒŽΰ² η›Šΰ² )γƒŽε½‘β”»β”β”»

#

So after finally being able to stress test this database implementation. hooo boy does that take a hit on performance

#

1000 entities flying about referencing their data from a blob, 10fps. Just setting up a component and stuffing the data in on load without lookup, 60fps.

storm ravine
#

60fps for just 1000 entities? oO

#

vSync enabled? πŸ˜„

mint iron
#

no 10 fps for 1000

storm ravine
#

Yes but after that he speak about 60 for same entities without his db lookups

#

Or I misunderstood sentence? πŸ™‚

mint iron
#

ahh yes

#

no you got it, sorry, im just tired

storm ravine
#

Yep np

loud matrix
#

1000 entities both times, 10 with database lookups, 60 with direct data injection no entity creation

#

and i think my vsync may still be off

storm ravine
#

Your game GPU bound? Heavy graphic? Because 1000 entities in just 60 fps I can't imagine even with worst chunk layout where every entity in own chunk πŸ™‚

#

And in editor with all possible sefety checks on

#

Or if you run it on mobile πŸ™‚

naive parrot
#

performance by default intensifies

storm ravine
#

What your profiler tell you?

loud matrix
#

literaly rendering cubes and yeah its 61-62 with vsync off

storm ravine
#

Which part consuming performance?

#

Definitely not what you should expect with that count of cubesπŸ€”

loud matrix
#

about 1/2 scripts 1/2 others

#

but i really dont know how to read the profiler

#

20k tris on screen

storm ravine
#

Expand jobs

#

PlayerControl 10ms... need to see if it stuck on semaphore and waiting other job finish

naive parrot
#

are we just gonna ignore 25ms on editor?

storm ravine
#

they ignored

loud matrix
#

iiiiii forgot to switch from run to schedule when fixing something earlier =.=

storm ravine
#

πŸ™‚

#

And even with Run

#

if it bursted (even if not)

#

it should be faster

#

What consuming 10ms in your player control?

loud matrix
#

most of the logic currently in the game

storm ravine
#

All logic inside PlayerControlSystem ?

loud matrix
#

i don;t have much to show for myself after 6 weeks ok πŸ˜›

#

I have a cube that flys around

#

It's a very good cube, but he is somewhat lacking in gameplay

#

player control is my take in input and add onto velocity that's then taken into velocity system, and as i wasn't moving the velocity system didn't have much to do.

storm ravine
#

I mean - PlayerControlSystem takes 10ms in profiler

#

This simple logic you described can't take that much time

#

Show not timeline but hierarchy view

#

or send your profiler snapshot here

loud matrix
storm ravine
#

This is definitely something wrong in system OnUpdate

#

because this OnUpdate itself takes 11ms

#

Not waiting jobs etc, code in PlayerControlSystem OnUpdate takes 11ms 😲

naive parrot
loud matrix
#

Thats because its just using Run

storm ravine
#

No

naive parrot
#

is it Bursted code ?

loud matrix
#

withoutburst

storm ravine
#

This is because code inside doing something wrong if it that simple as you describes πŸ™‚

#

You told that it just input and velocity

naive parrot
#

clearly fundamental logic is computationally heavy

#

whatever is happening in that system

loud matrix
#

it's pretty much just taking the velocity components two float3's and adding to it with some clamps. shouldn;t be anything in there that bad, unless my pc has a bitcoin miner in the background i don't know about

storm ravine
#

Show OnUpdate here

#

what you describes can't take 11ms

#

even without burst, job etc.

naive parrot
#

why mixed Mathf/math use? just stick to one , preferrably the new math one. general observation.

storm ravine
#

Is there only one ActivePlayerShip?

loud matrix
#

Don't think there was a moveTowards in the new mathamatics library (when i was looking for it)

#

no currently all 1000 are

#

just so they all took in movement data for testing

storm ravine
#

Aaaaaah

#

Now it's clear

#

I have a cube that flys around
I tought you have only 1 cube here flying around as you told

naive parrot
#

you can do pos += dir*speed*deltaTime , simple move towards , maybe with clamp.

loud matrix
#

That would not take into account the rotation

naive parrot
#

can do same for rotation , calculate manually

loud matrix
#

@storm ravine So is 10ms not an insane time?

naive parrot
#

anyways dont think without jobs/burst you gonna gain anything out of maths

storm ravine
#

@storm ravine So is 10ms not an insane time?
@loud matrix in that case without burst - no

naive parrot
#

1000 of those math ops ,non burst , non jobs , seems ok..

storm ravine
#

Here is not 1000

loud matrix
#

I was a quick bit of code @naive parrot, not optimised yet, obviously :p

storm ravine
#

but 3000

#

because 3 ForEach

#

through same ships

#

1000 for every ForEach

loud matrix
#

I'm currently trying to make it run on schedule, but it is complaining that Ship is using IComponentData and thus not allowed

naive parrot
#

strip all those if/else use math.select/math.step and , enable burst and jobs. you have a winner.

loud matrix
#

I'll try to get the basic job running first

#

Just as soon as i remember basic ECS#

storm ravine
#

And merge that in to 1 ForEach, there is no need iterate same loop again and again

naive parrot
#

yeah

storm ravine
#

You increase your loop iteration x3 here as I mentioned above

#

and instead one loop through 1000 you iterating 3000...

#

just that merging will give you ~x3 (of course it depends on inner loop logic one loop heavy than another etc. but you can see what the problem here) boost in that exact case without changing other parts

loud matrix
#

why the hell is my ship a class....

storm ravine
#

Ah ant that too

#

class IComponentData slow

#

and should be used veeeeery rare

loud matrix
#

and can;t be run as a scheduled job

#

hence my current headscratching

storm ravine
#

It's of course I event not mention that thing πŸ™‚

loud matrix
#

ok so thats up to 170fps with just jobs

#

It was obvious to you, not to me πŸ˜›

storm ravine
#

Merge loop, use struct ICD and check again and you'll see big performance boost

#

Then use burst

#

one more BIG boost

#

then use off tread job

#

On moree BIG boost

#

and then optimize inner loops

loud matrix
#

I thought i had burst on

storm ravine
#

use simd friendly instructions, etc.

#

I speak only about your code posted above πŸ™‚

#

If you already removed .WithoutBurst() I don't know that πŸ™‚

loud matrix
#

yeah took it out with the run and converted to schedule

storm ravine
#

with minimal changes mentioned above it will give you more ms savings

loud matrix
#

A single foreach now and ... 0 performance boost, I've been lied to

storm ravine
#

Well because you now bursted and on worker thread

#

It's just not noticeable πŸ™‚

#

But you should see that at scale

#

just disable render mesh system (for exclude GPU bounds) and check how 3 loops work on 50k in comparison with 1 loop πŸ™‚ through jobs timeline, you'll see ms difference for that job

loud matrix
#

I assume when you say off thread job you mean one of the job worker threads?

storm ravine
#

Yes

#

by off thread i mean outside of main thread

#

Just shorter πŸ™‚

loud matrix
#

My poor render mesh system is taking up a whole 2.3ms

#

Ahh k, just wanted to make sure there wasn;t some other terminology I was unaware of πŸ™‚

storm ravine
#

My poor render mesh system is taking up a whole 2.3ms
@loud matrix your? I see only HR hereπŸ€”

loud matrix
#

Yeah that takes it from 170-190 up to 345

#

sorry that's what i meant

#

Not all of us are writing custom rendering engines

storm ravine
#

Yeah that takes it from 170-190 up to 345
@loud matrix 50k with 1 and 3 loops? πŸ™‚

loud matrix
#

1000 with 1 loop

#

gonna play with it now to see it at scale

#

Think i just crashed unity at 10k

#

ooh no it lives... 10fps

storm ravine
#

1 loop?

#

Burst and job?