#archived-dots

1 messages ยท Page 49 of 1

blissful bobcat
#

it makes sense

viral sonnet
#
{
    var healthStateMask = chunk.GetEnabledMask(ref HealthState_ReadHandle);

    for (int i = 0; i < chunk.Count; i++)
    {
        if (!healthStateMask[i])
            continue;
        
        Method(in chunk, unfilteredChunkIndex);
    }
}``` 
found the code which trashes my project. from 2.5ms to 20-27ms!! now if i just call Method (the previous Execute method, everything's fine) wtf is up with this? i expect some overhead but not utter destruction
#

whelp i'm a dummy ๐Ÿ˜„ created a double for loop. good lord what a mistake... well i'm leaving it there for everyone to laugh ๐Ÿ˜„

#

for so many calls performance is quite good lol

blissful bobcat
#

@rustic rain @viral sonnet It really makes much more sense to just open the folder as a unity project browsing from unity hub, idk why i didn't thought that before. Ooh and making the changes to URP really made it, just coming back to thank you both, it really helped. And maybe if someone in the future has the same questions they can rely to my confirmations here it worked. Thank you very much again.

rustic rain
blissful bobcat
viral sonnet
solemn hollow
#

how is the transition to transforms v2 atm? will it break everything?

viral sonnet
#

no it went pretty smooth

solemn hollow
#

and would the new physics still work with transforms 1.0?

viral sonnet
#

yes, if you set ENABLE_TRANSFORM_V1 manually

rustic rain
#

didn't new physics transisitoned to v2?

viral sonnet
#

yeah, as new default

solemn hollow
#

what would be the TLDR of what Transforms 2 changes?

rustic rain
#

it's all-in-one component now

viral sonnet
#

Translation/Rotation are gone and replaced with LocalTransform

rustic rain
#

similiar to GO basically

viral sonnet
#

if you don't do anything with scale, that's pretty much it

rustic rain
#

nu scale is still unsupported?

solemn hollow
#

and it is still updating changes to the "LocalToWorld" only at the end of the frame in one system or does that work differently now

rustic rain
#

it's similiar system group

#

with a lot of systems

#

no idea what's inside

#

neither it should be concern anyway

solemn hollow
#

i think what i am asking is when the WorldTransform is updated.

#

is it updated automatically when i write to localtransform right away or do i have to wait till the end of the frame?

#

just skimming through the docs and trying to figure out how much will break for me ^^

viral sonnet
#

it's updated in the transform system at some point

#

so not updated automatically when LT changes

#

i'm still confused how to optimize this beast. like, on a root entity there's no need for WorldTransform

#

my previous method was to just use LocalToWorld but that wasn't working out with the physics package

#

anyway, LOTS of data now. LocalTransform, WorldTransform, LocalToWorld.

solemn hollow
#

im pretty sure they are aware of the problem of useless Unity IComponentData atm

viral sonnet
#

a regression is if you relied on change filtering just for rotation as it's all packed now into one comp

rotund token
solemn hollow
#

as i understood it its the whole selling point of aspects right?

rotund token
#

But this has stopped any sliver of hope if updating work project

solemn hollow
#

oh reminds me you wrote something about changing your perspective on aspects. you didnt explain further. what happend

rotund token
#

1651 uses of translation

rotund token
#

I just try to avoid many to many

#

The many write 1 read is very useful for this

solemn hollow
rotund token
#

I'm pretty sure most people would use transform aspect as many read many write

#

Too much of a universal concept to avoid

viral sonnet
#

many writes, many reads is such a problematic concept in every regard

#

pretty much everything that relies on order

solemn hollow
#

ah then i understood you the wrong way. i thought you are talking about access to the components inside the aspect.
I havent worked with Transform aspect but as i understood it i write to Pos,Rot,Scale and i should only read from WorldTransform

solemn hollow
viral sonnet
#

yeah and even if it gets stable. working within such architecture is like entering a minefield

solemn hollow
#

what i found helping me a lot is trying to get everything of a bigger module inside its own update group. its not always possible though when interacting with transform etc

viral sonnet
#

has anyone programmed in python? they declare variable names like source_transform instead of sourceTransform - i'm on the verge of changing my style ๐Ÿ˜„

rotund token
#

Some web languages style like that

#

I hate it

viral sonnet
#

typing underscore or what do you hate about it? ๐Ÿ˜„

rotund token
#

I hate underscores

#

Also extra characters for no reason

viral sonnet
#

well, best replacement for a space character

#

but yeah, underscore isn't really on a key that's easily reachable

rotund token
#

Best replacement is nothing

#

c uses snake case doesn't it

viral sonnet
#

i started to use this style for handles a long time ago

rotund token
#

I guess the information is useful for unsafe containers...

viral sonnet
#

yeah, i made mistakes with read/write states when binding the job and got annoyed. so i put the info in the variable itself. the first part is always the struct itself which i copy/paste

#

needed the underscore to seperate the information

viral sonnet
#

so i'm using the CamelSnake_Case for my handles. lol

misty wedge
#

It seems like default interface methods break burst compilation

winter depot
#

I have done some searching but haven't been able to find anything. Is there a way to set IEnableableComponent to disabled by default on creation or when added, or do we need to manually set them for each component?

misty wedge
# rotund token I hate it

I also hate it. It's especially annoying when writing python web servers since serialized variable names then need to be aliased to proper JSON camelCase names if you don't want your request data to look ugly

misty wedge
winter depot
#

Runtime

misty wedge
#

I assume if you instantiate an entity that has the component set to disabled, it will also be disabled on the newly instantiated entity

winter depot
#

That's a good point, I think that should work. Thanks

viral sonnet
#

then the state is already baked into the prefab

winter depot
#

I am not a baker, just a weak developer lol, everything comes from a database and gets generated at runtime, but when I create the prefabs from that I data can disable there so it works as intended, thanks again!

viral sonnet
#

runtime generation? you still on 0.51?

winter depot
#

No, 1

viral sonnet
#

is your generation so complicated? some kind of prefab template can work quite well. pure runtime generation trashes archetype variations

winter depot
#

I think its pretty solid, I have 4 items in my scene. Camera, Event, UI, then my single GO that starts everything once it finishes html request. I use a few archetypes that are pretty concrete and don't add/remove much so I think its ok. I still need to break apart some things and nest anything that will get add/remove, but I haven't noticed any issues so far. I moved away from game objects when I first started ECS so I don't want to go backwards with the baking system.

misty wedge
#

Gameobjects never hurt anyone

winter depot
#

Yeah, I just don't see a point. I moved all data when .5 came out so I could make balance changes or add new units/ manipulate game on the fly. Data oriented just makes more sense to me being generated at runtime. Maybe a mistake but once I committed it was too much to backtrack

misty wedge
#

The reason unity uses subscenes is because it's insanely fast. Loading a scene is just a memcpy, that's why they are authored ahead of time

#

(vs creating everything at runtime which is most likely slower)

viral sonnet
#

there's the content management system now which should be dots addressables. hooked up this will be much nicer for web updates

#

i think your system will work well enough though.

misty wedge
#

Yep, I think it also depends on the project to a degree

#

I have like 5 prefabs, and that's only because netcode requires it

winter depot
#

I get what you mean, but so far I have not experienced an issue. Since I really only touch the initial data at launch of the game it takes less than .25s to load. After that there is zero load times, as everything in my game is entity driven its been instant. I still need to do some mobile testing but I am happy so far

misty wedge
#

My point was for a traditional AAA game, that loading time at runtime will be very long. A big draw of ECS is that it enables very large scale simulations and worlds

#

Subscenes make that loading as fast as possible

#

But for indie projects it most likely doesn't matter, unless you have requirements similar to those

#

Just go with whatever works

rotund token
#

Aspect.Lookup doesn't seem to have a Has method? hmm

misty wedge
#

For optional components?

rotund token
#

no just for the whole thing

#

if i have an entity, how do i know if it has a transform

misty wedge
#

Use a component lookup for a transform?

rotund token
#

that what aspect.lookup is!

#

it holds all the component lookups

misty wedge
#

Is this an aspect that is different from an IAspect? ๐Ÿ˜…

viral sonnet
#

damn, 13ms more in my stress test with TransformV2 -.-

rotund token
#

just think TransformAspect.Lookup as example

misty wedge
#

I don't think I've ever used the .Lookup type, what's it for?

#

I just read the data from the aspect when querying

rotund token
misty wedge
#

Ah, I see

rotund token
#

it has
Lookup(ref global::Unity.Entities.SystemState state, bool isReadOnly)
void Update(ref global::Unity.Entities.SystemState state)
TransformAspect this[global::Unity.Entities.Entity entity]

viral sonnet
#

why not use the lookups generated?

rotund token
remote crater
#

It was requested a video of nothing but warp drive cuts, and its very fun to watch, people have said I'm funnier than Saturday Night Live and movies: https://www.youtube.com/watch?v=96cIYun83FE Enjoy.

Yes, these are actual 1:1 size stars of 1400000000m big or 80x as big!
Star Trek TNG, And all games since just use like particle effects... Impressive, but this warp effect I invented and many said could not be done has been done. ENJOY!

www.starfightergeneral.com

We run a guild. Opportunity: I can teach you how to make games for free better...

โ–ถ Play video
rotund token
#

but i have to write this for every aspect

misty wedge
rotund token
#

(and they're internal so other users can't do it)

misty wedge
#

How do you create the lookup?

rotund token
#

wait no they're private

#

i can't even access them

rotund token
#

Lookups are meant to have a Has method angry face

misty wedge
#

Do you get an exception if it doesn't have it?

#

Or is that an allowed operation

rotund token
#

its just like doing
ComponentLookup<Transform> t;
t[entity] // crash if it doesn't exist

viral sonnet
#

seems you lookup the whole aspect and then check for null pointers which can be returned from GetRefRWOptional

#

but yeah, that's not really the point of a lookup for a single comp

misty wedge
#

That can't be the intended user friendly way ๐Ÿ˜…

viral sonnet
#

agreed, certainly needs a Has method

misty wedge
#

Weird that it's missing

rotund token
#

i don't understand how no one has run into this before

misty wedge
#

I assumed you could check the RefRW / RefRO for the IsValid field, but that won't work if it won't even let you get the aspect

rotund token
#

updating library to v2 and took me 15min to have an issue

#

i'm hoping i'm missing something

misty wedge
#

I've only used a single aspect and only read and write to it in an IJE

rotund token
#

trying to convert all libraries to transforms v2

#

and it's tedious

#

hoping this is the last major refactor

misty wedge
#

Never

#

refactors 4 lyfe

#

Any netcode experts here? I'm running into an issue I don't understand

rotund token
#

i am not anymore

#

haven't touched it in 1.0

misty wedge
#

Pretty sure this isn't something new

rotund token
#

ok try me

misty wedge
#

So I have a dynamic buffer that I am sending over the network, and the updates for it are run in a prediction system

rotund token
#

ah the classic schnoozlereference

misty wedge
#

๐Ÿ˜ฆ

#

It's just a guid!

rotund token
#

(side note, reference seems like bad naming, should be like schnoozleid or something since reference is kind of means something anyway continue)

frosty siren
#

Anyone knows how to manually initialise world in 0.51 with convertion systems and stuff? Because it seems that just adding ConvertToEntitySystem to world in 0.17 works, but in 0.51.1 it doesn't. I don't want to switch instantly to 1.0

misty wedge
rotund token
#

it holds a guid which matches a scriptable object
i can't access that scriptable object without an extra method/lookup right?

#

anyway side tracked its not important, your project

misty wedge
#

The scriptable objects are converted to blobs, and a struct container matches the SchnozzleReference to that blob for that scriptable object

#

ok, back to the topic

#

From my understanding of how the tick updates work, if the client sends a command at tick 100, and then updates that dynamic buffer, it should only be overwritten if new data is received by the server that was originally created on the server at tick 100, right?

#

And would then re-predict to the current time

coarse turtle
rotund token
misty wedge
#

Yes, both the client and server write to this buffer as part of the prediction loop

#

Since the client is trying to predict the contents of the buffer in this case

misty wedge
#

Is this correct, or am I misunderstanding something?

rotund token
#

sounds about right

misty wedge
#

Ok, so then here is the issue:

#

This is the client sending a command on tick 793. That data is then processed by the client and server in the prediction loop

#

This is the buffer on the frame where the command was executed on the client:

#

However, due to latency the command has not reached the server, but that should be fine since the client hasn't received buffer information for the tick he is currently at. But for some reason on the next client frame, the buffer is empty:

frosty siren
misty wedge
#

Then, once the server receives the command, it is populated back to the client:

#

(blue is the server)

rotund token
#

because the buffer is empty on the server so it's sent you that

misty wedge
#

But it's not empty on tick 793

rotund token
#

it's not being populated on server until it receives your command sends you back its own data

misty wedge
#

The client is ahead of the server

viral sonnet
#

how's the client issuing the ability?

rotund token
#

yes but data from server is 3 frames behind (it looks like)

#

so for those 3 frames your data is being overridden no?

misty wedge
#

As an IInputCommandComponent (basically a command data)

misty wedge
#

The data the server sends is always old

#

So the client re-predicts the state on the server from the old snapshot data

viral sonnet
#

if it's in the command queue the buffer will be readded over and over again

coarse turtle
misty wedge
#

I would assume on prediction, the client gets the "old" data, and then re-adds it

viral sonnet
#

and the command queue is correct?

rotund token
misty wedge
#

But the prediction loop would reach the command that has the executed ability in it

#

and should re-add it

viral sonnet
#

correct

misty wedge
#

it always predicts back to the "present"

misty wedge
#

But it uses the IInputCommandComponent from netcode 1.0, which should make this automatically correct

#

I can check the auto-generated buffer though and see if I find anything

viral sonnet
#

there are some pitfalls with command queueing

#

it can happen that the prediction overwrites it

rotund token
#

i'm unsure why abilitystate is even a ghost component - why is it not driven from the command

viral sonnet
#

pretty common mistake from what i've read and had myself

misty wedge
rotund token
#

i don't think this is true at all

#

if i send a start ability command at tick X all clients/server should be able to predict forward from this themselves

misty wedge
#

How do you roll back without the old state though?

coarse turtle
#

Anyone knows how to manually initialise

viral sonnet
#

i think tertles point is that they should always be calculated from the commands. which means the buffer would be empty everytime a new prediction starts

misty wedge
#

But the ability can run over hundreds of frames, prediction doesn't go back that far

viral sonnet
#

if the data isn't too much i'd just keep it as it is though

rotund token
#

if it's a been a while but i think prediction rolls back from ghost snapshots, not from data you arbitrarily set on client

viral sonnet
#

you could split the data then. it seems the are getting in the way kinda. persistent data and input data that is

misty wedge
#

So it is in that snapshot

rotund token
#

how are you sending this buffer though?

misty wedge
#

as a ghost component

rotund token
#

you haven't posted your command

#

wait - dont ghost components only get sent 1 way from server to client

misty wedge
#

They do

#

The command sent from the client so server is the IInputCommandComponent I mentioned earlier

#

This is read back in the prediction loop, which starts the ability

rotund token
#

yep ok

misty wedge
#

I think I may have found the issue though, let me check real quick

rotund token
#

but anyway i still dont see why/how this buffer needs to be synchronized

misty wedge
#

So that the client gets sent the old snapshot data to then forward predict

rotund token
#

but you can predict this just from the command

misty wedge
#

No necessarily

#

Say the ability runs over 2 seconds, and the client position is slightly out of sync. The client entity is hit by a stun on the server, but not on the client, interrupting the ability. It then needs to send the ability state snapshot so the client can re-predict the correct state

rotund token
#

but client will also get the stun

#

and can interrupt it

misty wedge
#

Sure, if you send everything else that can influence this buffer, you don't need to send it

#

I don't know if that's what I'll do. For now this is much easier since it assures they can't go out of sync

#

The issue was a really silly thing btw. Thanks for the talk though, it helped me find it.

#

Rubber ducky method always works

rotund token
#

anyway this is mostly just from our game syncs way too much data

#

and we have network issues

#

and i'm always basically trying to find savings >_>

#

what was the issue just out if interest

misty wedge
#

I have this component on the thing triggering the ability:

#

And it was missing the ghost component fields, meaning the client wasn't re-executing the ability on prediction

#

The counter is what you mentioned yesterday @rotund token , as a workaround for events in a command buffer

#

I hope to get rid of it again though and just use InputEvent if I can figure out what the issue is there

misty wedge
#

I've not done any sort of network optimization yet though

viral sonnet
misty wedge
#

Yes

rotund token
#
    {
        public static bool Has(ref this TransformAspect.Lookup transformAspectLookup, Entity entity)
        {
            Check.Assume(UnsafeUtility.SizeOf<TransformAspect.Lookup>() == UnsafeUtility.SizeOf<TransformAspectLookup>());
            ref var ta = ref UnsafeUtility.As<TransformAspect.Lookup, TransformAspectLookup>(ref transformAspectLookup);
            return ta.LocalTransformComponentLookup.HasComponent(entity);
        }

        public static bool TryGetAspect(ref this TransformAspect.Lookup transformAspectLookup, Entity entity, out TransformAspect transformAspect)
        {
            if (!Has(ref transformAspectLookup, entity))
            {
                transformAspect = default;
                return false;
            }

            transformAspect = transformAspectLookup[entity];
            return true;
        }

        private struct TransformAspectLookup
        {
            public byte IsReadOnly;

            public ComponentLookup<LocalTransform> LocalTransformComponentLookup;
            public ComponentLookup<WorldTransform> WorldTransformComponentLookup;
            public ComponentLookup<ParentTransform> ParentTransformComponentLookup;
        }
    }```
i really dislike that i need this
and i dislike it more than i'd have to implement it for every aspect
viral sonnet
#

this was my fix back then. (counters are also fine) ```if (inputBuffer.GetDataAtTick(serverTick, out var input) && input.Tick != serverTick)
{
// new frame, new input
input = default(PlayerCommandData);
}

    input.Tick = serverTick;

    input.jump |= jump;
    input.angle = angle;
    input.autoAttack |= autoAttack;
    input.moveDirection = moveDirection;
    input.placeablePosition = inputPlaceablePosition;

    inputBuffer.AddCommandData(input);```
misty wedge
#

Ideally I'd like to use the InputEvent struct, since that automatically addresses the issue

viral sonnet
#

ah that must be new ^^

misty wedge
#

It basically just auto generates a counter for you

viral sonnet
#

ah cool, was wondering how they would handle this. as i said, pretty common problem back then

#

i'd rather change the codegen tertle

#

there's no point in writing this ๐Ÿ˜„

misty wedge
#

Missing the Has method seems really weird. I initially thought they hadn't even put in a lookup for aspects yet since I didn't see it in the aspects documentation

rotund token
#

you know how annoying that would be for my 15 separate projects i have to maintain

viral sonnet
#

give dani a friendly ping ๐Ÿ™‚

rotund token
#

systemapi QueryBuilder also really needs an aspect option

viral sonnet
#

are aspects uaed internally? seems odd they never needed a has to an optional comp

misty wedge
#

If the component is optional on the aspect itself, and you already have the aspect, you can just check there directly. Maybe they just rarely used the aspect lookup functionality? ๐Ÿคทโ€โ™€๏ธ

rotund token
#

because one of the nice things about aspects is they can completely change the required types without me caring

#

they could redo the transform system again completely and as long as all i'm using is the transform aspect it no longer matters

misty wedge
#

Yep, I was just trying to rationalize why this could have not been an issue for unity internally

rotund token
#

i'm not going to speculate, i believe it's probably in some task tracker as a todo

misty wedge
#

Hopefully

viral sonnet
#

unity uses like 2 aspects in physics. none has optional comps

#

i'm not sure how this should work. WorldTransform is optional. when you access via get, you get a RefRO value. i see no safety then

#

oh nvm, public unsafe bool IsValid => _Data != null;

rotund token
#

a has lookup only needs to check the non-optional components

viral sonnet
#

yeah, back to the same conclusion

rotund token
#

but yes the safety is built into the generation of the ref components

viral sonnet
#

so all it really needs is the generated ComponentLookups to be public

rotund token
#

i don't think so

#

i think those should be hidden from users

#

i just think it needs to generate a has method and check component lookups for us that aren't optional

viral sonnet
#

wouldn't work when the optional tag changes and the Has method is gone then

rotund token
#

what do you mean?

#

if the signature changes the code gen would update the Has method

viral sonnet
#

i don't see the point of hiding the lookups. they are core to entities

rotund token
#

because that's the beauty of aspects

#

you don't care about the underlying data

#

you can change and refactor it completely

#

as long as the aspect methods itself don't change then it doesn't matter

viral sonnet
#

but you do know with wanting to know if a certain comp is available

rotund token
#

i dont care what component exists

#

i just want to know if the aspect is valid on a certain entity

misty wedge
#

It's like designing and interface, exposed functionality doesn't care about the internal state

#

(from the outside)

viral sonnet
#

huh? lookup does exactly that

rotund token
#

?

misty wedge
#

He wants to know if an entity fulfills the requirements to be called a specific aspect

#

So that certain functionality can be executed on them

#

If that makes sense

viral sonnet
#

hm, i dunno. there's nothing specific when optional is involved

rotund token
#

i just want a handy method

rotund token
misty wedge
rotund token
#

optional is completely irrelevant to this discussion

misty wedge
#

The caller only cares that the method can be executed on the entity

#

(regardless of what components the aspect actually has)

#

That's why exposing the lookups is probably a bad idea, because it makes refactoring it much harder (if you were to use the exposed lookups a lot)

viral sonnet
#

ok i think i get it ๐Ÿ˜„

#

sorry, bit dense today ๐Ÿ˜„

rotund token
#
var entity = state.EntityManager.CreateEntity();

// ArgumentException: A component with type:Unity.Transforms.LocalTransform has not been added to the entity.
// as far as i can tell I have no way in checking this would be an error
var aspect = transforms[entity];

// I just want these (which I have now implemented but only for TransformAspect) - please code gen them for me!
if (transforms.Has(entity))
{
}

if (transforms.TryGetAspect(entity, out var aspect2))
{
}```
stone osprey
#

How would you implement "actions" in an ECS ? Whats your typical approach ?
Like player and mobs are entities... all nice and makes totally sense.

But how do we deal with actions ? Like "Build that building over there, move there, place it and increase its health till its full"... or "Damage that entity in an interval, cancel when out of range or when its dead or some other condition was met".

I find this pretty hard to implement as components since they are getting pretty complex, however it does also not make sense to have that as its own entity.

rotund token
#

it does also not make sense to have that as its own entity
unity dots shooter implemented abilities/actions as their own entity

stone osprey
rotund token
#

i'm not saying it's the best approach or how I'd do it (i would consider it though considering my success with effects as a standalone entity)

#

i'm just pointing out unity thought it made sense when they were doing something similar so it must be worth investigating

#

we do abilities states as entities at work though

#

an ability/action system is pretty complex if you want it to be extremely flexible

#

but it definitely pays off in the long run if you can make something very generic

misty wedge
#

I'm trying with a graph system that uses blobs, we'll see if I have to change it to entities at the end...

#

The major pain is node state

stone osprey
#

Alright thanks, im gonna look at that ^^

Since a flexible "action system" with components only is real pain... for example i currently have like 8 components to handle the building process...
Like some components doing range checking, placing it once the space was reached, some increasing the health of the building to "build it", some doing other stuff... only to make it flexible. Its a real pain actually xD

mystic mountain
rotund token
#
    private NativeArray<PhysicsCollider> physicsColliders;
    private int entityIndex;

    public bool OnChunkBegin(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    {
        this.hits = new UniqueHitsCollector<DistanceHit>(0);
        this.physicsColliders = chunk.GetNativeArray(ref this.PhysicsColliderHandle);
        this.entityIndex = -1;
        return true;
    }

    private void Execute(Entity entity, ref Cluster cluster, in TransformAspect transform)
    {
        this.entityIndex++;

        if (!cluster.IsNotInitialized)
        {
            return;
        }

        cluster = Cluster.Initialize;

        if (this.physicsColliders.Length == 0)
        {
            return;
        }

        ref var collider = ref this.physicsColliders[this.entityIndex].Value.Value;```
OnChunkBegin is as good as I expected. I can do chunk based any checks now in IJobEntity without a lookup
misty wedge
#

Yep, it's really cool

#

Even better if the version bumping is fixed

misty wedge
rotund token
#

we are more like, ability start -> create entity

#

server/client simulate this independently

#

with their animations etc

#

server just has timings that it waits for which should match client

#

you should not use this project as a good practice though

#

our networking is jank as

misty wedge
#

Yeah but say you have a sequencer node that needs to remember what index it is currently "running"

rotund token
#

we just have stages

#

windup, execution(s) etc

#

windup is just a delay on server, on client it would play say a swinging motion of a pickaxe

#

execution would actually mine the node on server, on client it tries to predict this

misty wedge
#

I see

#

I'm using a graph based system, and am still not sure if I should design it so each node is truly an instance when an ability is running, or if the state of the ability is just a single thing stored on the entity. The latter would mean I can only remember the state of the currently running node (without trickery)

rotund token
#

again do not copy anything from work ๐Ÿ˜„

misty wedge
#

That's the scratchpad bit I posted yesterday

rotund token
#

if i was writing this myself

#

and i intend to sometime next year

#

i would use a graph (re-using tech i did for my AI)

#

i would try to make nodes stateless though

#

(again what my ai does)

misty wedge
#

Don't you think that's a limitation on design? I'm still unsure

rotund token
#

i don't think so

#

i can store state on the entity

#

it just won't be stored in the graph

misty wedge
#

How would you store per-node state though?

rotund token
#

again i haven't really thought about this much yet

#

but first thought is most nodes need similar data

#

for example, when it entered node (to determine how long it needs to stay in node etc)

#

so this can be mostly stored in a single component

#

and just relate to current node

misty wedge
#

That's what I currently do

#

This is the context that is passed to the node

#

Where this is the state

#

But the scratchpad can only "remember" the state of the currently running node. I'm unsure if that's going to be an issue in the future

#

The other concern with this I have is that I would like to make it possible to design abilities in game at some point. This approach with blobs makes that more difficult I think

#

An entity based approach where each node is an entity would make it trivial to sync to clients and modify by clients

#

I guess alternatively you could use entities to store "custom" abilities and when changes are detected you could rebuild the blob asset for that single ability at runtime

rotund token
#

is ability state a buffer because you can be in more than 1 ability at once or something?

misty wedge
#

Yeah

rotund token
#

makes sense

misty wedge
#

This is my parallel node code

#

It basically just starts each connected port as its own ability

#

Sequencer nodes are actually pretty difficult to implement with this system, since they need to remember their own state. Alternatively you would need to write the sequencer stack somewhere, but I'm trying to avoid using pointers to make future serialization easier

#

(then again sequencer nodes don't actually do anything besides make graphs more easy to organize)

#

Some things you can cheat, such as repeat nodes by just creating more nodes during blob creation

#

I think the approach that would give the most flexibility, is have each node be it's own entity, and when an ability starts, the nodes are copied and all hold their own state. This would probably be much slower, but would make it much easier to implement custom abilities and node state

#

Alternatively create a single entity per ability with a dynamicbuffer on it that stores all nodes with their respective state, and use a type punned union to store the different data layouts

#

Maybe I'll try that and see how it goes

uncut rover
#

Does the profiler no longer show (Burst) on bursted jobs in the timeline ?

rotund token
#

it shows as green doesn't it

uncut rover
rotund token
#

then it's not burst compiled ^_^'

#

(if you're on 1.0, 2022 anyway)

stone osprey
#

Would events in total also be their own entities ? I also struggled with that part... For example collision events, each entity has a collider... when entity A collides with entity B i wanna execute some logic.

My current solution is that each entity gets a Collisions component with a list in it basically to track collisions, theres also a "CollisionsEntered" and "CollisionsLeft" component which are getting attached once a collision lefts or enters.

This way im currently reacting on collisions... however this is not really "clean" in my opinion, since events are not really "data" which should be stored in an entity.

rotund token
#

but not for ISystem it doesn't seem

#

but they do appear in green

uncut rover
misty wedge
#

Is there a way to serialize a blob to bytes? Since the fields like blob ptrs etc are just int offsets inside the struct...

rotund token
#

well since subscenes do this, yes

misty wedge
#

Since if that is possible, I can just serialize the blob onto a ghost component dynamic buffer to share it to clients if it's a custom ability

rotund token
#

oh yeah you're doing runtime creation hmm

#

i would look at just using a blobassetstore per custom ability

#

or serializing / deserializing that

#

its only 3 hashmaps + a list

misty wedge
#

Like building components to synchronize the contents of it?

rotund token
#

actually i guess each ability just starts as 1 blobassetreference?

#

what you want to serialize then is probably the BlobBuilder

misty wedge
#

It's a NativeHashMap<SchnozzleReference<AbilitySettings>, BlobAssetReference<AbilitySettingsBlob>>

rotund token
#

if you just serialize the
blob builders
NativeList<BlobAllocation> m_allocations;
NativeList<OffsetPtrPatch> m_patches;

#

you could /easily/ regenerate a new blobbuilder on the client

#

and create the same blobasset references from it

misty wedge
#

Doesn't it use a bunch of pointers internally though?

rotund token
#

yes you'd need to serialize out each one

misty wedge
#

:[

#

That's probably easiest though, since I could just serialize the scriptable object that contains the settings for the ability as JSON on the client, send it to the server, it creates the blob and syncs it on an entity

#

The scriptable object is probably easier to expand on during runtime than the blob format

#

I've never looked at blobbuilder and blobassetstore internally, so I'll take a look. Thanks for the pointers (hehe)

#

Ok the layout is actually a lot simpler than I thought

#

That seems doable

#

Can you not serialize a blob asset store at runtime?

#

I've barely used them

rotund token
misty wedge
#

Kind of annoying that the blobbuilder values are private

rotund token
#

yeah i think you should stick with blobassetstore

#

since thats how subscenes must handle it

#

you should just check what they do

misty wedge
#

I'm not sure how to handle this, calculate the memory address offset in relation to the memory address of the constructed root?

rotund token
#

the offsets would be the same

#

isn't that the point

misty wedge
#

In the final blob yes, but not in the builder

#

It stores the memory address in the struct

rotund token
#

hmm honestly i dont know how subscenes save this

misty wedge
#

I wish I could just reuse their code

rotund token
#

i've found digging through the source since their baking changes much harder to figure out

#

it just seems to magically do a step

#

then dispose stuff ^_^'

misty wedge
#

Couldn't I just memcpy the entire memory block of the stored blob data? Since I know the total size of the blob, and the entire blob is linearly stored in memory, couldn't I just copy that entire region into a byte array?

#

Then put that on a dynamic buffer, synchronize it to clients, allocate the required amount of memory, and copy it there?

rotund token
#

is the entire blob asset store stored like that though

#

having a quick look it doesn't seem like it

#

the blobbuilder is

misty wedge
#

Really? I thought the blob is just a single block of allocated memory and all "reference types" (blob array and blob ptr) just store an offset for that memory block

#

There could be some unused space but that wouldn't matter

#

Actually, now I'm confused

#

Wait no, that's fine, right? It's taking the memory address of the offset field, and adding the offset field (an integer)

#

So the offset is relative locally to the memory block, not relative to the memory of the host machine

#

It's the same for blobptr

#

So I don't see why I couldn't just memcpy the entire thing...

#

Time to try it out!

rotund token
#

which is setup from the builder

#

blobassetstore just seems to be like a collection of pointers. there doesn't seem to be any remapping to ensure they're all together.

#

which makes sense, i can just create a blobassetreference with any old pointer and add it to the store

misty wedge
#

Yeah, each one pointing to a memory block for a specific blob

#

I'll check the offsets, but it wouldn't make sense for them not to be together for a single blob

rotund token
#

the offsets are in the builder

#

not the store

misty wedge
#

No, I mean the actual data allocated

#

e.g. BlobPtr

#

stores an int

rotund token
#

yes but that's created for a blobbuilder

#

so that will be packed together with other things from that blobbuilder

misty wedge
#

But It lives in the struct

#

This is the actual data that the blob asset reference points to

rotund token
#

yes

misty wedge
#

BlobPtr only holds an int field as an offset for the memory location of the allocated data the reference points to

rotund token
#

im not sure what this has to do with what i'm saying though

misty wedge
#

Maybe we are talking about different things?

#

๐Ÿ˜…

#

I'll try out my idea and see what happens

rotund token
#

when you call blobbuilder.CreateBlobAssetReference

#

it creates a giant chunk of memory the size of everything you added to that blob

#

and stores it under the blobassetreference

misty wedge
#

Yes, so can't I just copy that entire memory block?

rotund token
#

yes you can totally do that

misty wedge
#

That's what I meant ๐Ÿ‘

rotund token
#

but you'll need to patch the pointers

#

on deserializing

misty wedge
#

Really?

#

If the blobptr just points to "5 memory jumps below me" that would still be valid in the copied block

rotund token
#

once you call CreateBlobAssetReference

#

there is no offsets anymore

#

oh wait

#

thats not true

#

no i think you're right

misty wedge
#

The offset is stored in the blobptr

#

How else would it know where the memory is

#

Same for blobarray

rotund token
#

yeah i think that'd be fine

misty wedge
#

Thinking about this also made me finally understand why blobs need to always be passed by reference

#

I never understood why it didn't copy the entire struct, but with this "pointer" layout it makes sense

rotund token
#

just watch out for this gotcha

        {
            get { return ((BlobAssetHeader*) m_Ptr) - 1; }
        }```
#

the header is stored at -1

misty wedge
#

Yeah that's really weird

#

I guess they want to the pointer to start at the data

rotund token
#

so you need to serialize
from: ptr - sizeof(BlobAssetHeader)
length: header.length + sizeof(BlobAssetHeader)

#

actually you might not need the header

#

at all

#

just serialize
header.length
ptr -> ptr + header.Length

#

much easier to reconstruct

#

Create(void* ptr, int length)

#

and it'll setup the header for you

misty wedge
#

are there any issues with setting the internal values of a native array?

#

Or is there some fancy method to create a native array from a pointer

#

NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray seems to do the trick

#

Anyways, time to sleep now ๐Ÿ˜ด thanks for the help ๐Ÿ™‚

mortal knot
#

unity rigidbody can not be used in burst jobs, right? i need the dots ecs for that?

rustic rain
#

with tiny utility exceptions

rotund token
#

hmmmmmmmmmmmm finally dived into my actual test game

#

and baking feels like it falls apart from large scenes

#

it takes me over a minute to open my test subscene

#

it's not even that large

#

(there's a bit more than you can see due to lods hiding small ground details)

#

closing subscene just as bad, this is feeling shocking atm

rustic rain
#

I hate baking ๐Ÿฅฒ

rotund token
#
Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at <44569b2d1c974b5eb5e85c3450cfe46d>:0)
Unity.Collections.NativeArray`1[T].CheckElementWriteAccess (System.Int32 index) (at <44569b2d1c974b5eb5e85c3450cfe46d>:0)
Unity.Collections.NativeArray`1[T].set_Item (System.Int32 index, T value) (at <44569b2d1c974b5eb5e85c3450cfe46d>:0)
Unity.Entities.Editor.HierarchyNodes+FilterSubSceneNodes.Execute () (at Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities.Editor/Hierarchy/Model/HierarchyNodes.cs:626)
Unity.Jobs.IJobExtensions+JobStruct`1[T].Execute (T& data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at <44569b2d1c974b5eb5e85c3450cfe46d>:0)
Unity.Jobs.LowLevel.Unsafe.JobsUtility:Schedule_Injected(JobScheduleParameters&, JobHandle&)
Unity.Jobs.LowLevel.Unsafe.JobsUtility:Schedule(JobScheduleParameters&)
Unity.Jobs.IJobExtensions:Run(FilterSubSceneNodes)```
#
Unity.Entities.Editor.HierarchyNodes:Refresh(Immutable, World, SubSceneNodeMapping) (at Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities.Editor/Hierarchy/Model/HierarchyNodes.cs:353)
Unity.Entities.Editor.Hierarchy:Update(Boolean) (at Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities.Editor/Hierarchy/Model/Hierarchy.cs:550)
Unity.Entities.Editor.HierarchyWindow:OnUpdate() (at Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities.Editor/Hierarchy/HierarchyWindow.cs:350)
Unity.Entities.Editor.DOTSEditorWindow:Update() (at Library/PackageCache/com.unity.entities@1.0.0-pre.15/Unity.Entities.Editor/Common/DOTSEditorWindow.cs:196)```
#

also i seem to have completely broken the entities hierarchy window

#

i do not think it likes cinemachine's hidden children gameobjects ๐Ÿ˜…

#

if i recall baker doesn't like HideFlags

rotund token
#

either physics or renderer seems to take forever

#

though i've just realized burst has been off so let's give it 1 more shot

#

kind of forgot that could make a big difference these days

#

oh yeah that makes a huge difference, like 10seconds now

#

well except now i'm just being spammed by exception from the logging platform in burst

#

sigh this has not been my night

proud jackal
#

Those trees look familiar ๐Ÿ˜†

rotund token
proud jackal
#

Gotcha, good thing I just bought that asset then.. Those are the trees ๐Ÿ˜† - Did you also like me have a fun time changing the shaders to be DOTS_INSTANCING? ๐Ÿ˜†

rotund token
#

I replicated the shaders in Shader graph

#

So I can easily switch between hdrp and urp

#

And I wanted an excuse to learn it a bit

proud jackal
#

Well, that would do it too ๐Ÿ˜† - I decided to just change #pragma target 3.0 to #pragma target 4.5 and then add #pragma multi_compile _ DOTS_INSTANCING_ON.. As that too is often all you need to fix up an Amplify shader ๐Ÿ˜›

rotund token
#

I do like the visuals of the pack and it's detailed enough to test things like my nav mesh

#

Been a great test scene

proud jackal
#

Agreed - loving it for the same reason :3

rotund token
#

Oh the one annoyance was converting the terrain - need some dots support!

solemn hollow
#

I am still having problems with how to structure my project / package.
Simple example:
I have an AI package that needs to do some filtering based on UnitFaction. Sure i could give the user that component and tell him to write to it but then i force him to duplicate data from his own Faction component into the "UnitFaction" component of my package. Id need a way to alias those components so that my AI could be setup to directly read from the package users "Faction".

This is not a problem for static data like a UnitFaction but imagine my AI reading Health from Units to reason about them. I dont want to needlessly copy that every frame.

Atm i do this with codegen but i wonder if i am missing some simple solution here.

rotund token
#

I did this with generics

#

Was a huge pain do not recommend

solemn hollow
#

its what i do :S

rotund token
#

Code gen would be less effort

solemn hollow
#

we already talked about it about a year ago or so.
i am slowly migrating everything to codegen from generics right now

rotund token
#

Whole thing is a lot less effort you aren't trying to distribute it

#

And handle every possible case, sigh!

#

Could you just not make unit faction flexible enough that it doesn't matter if they have to use that

#

If you're using someone's library there has to be some expectation of using the components from it

#

I don't just install unity physics and create my own standalone collider and sync them together!

#

And by flexible I mean using like an int over an enum nothing crazy

#

Hmm it is an interesting problem

solemn hollow
rotund token
solemn hollow
#

oh i dabbled with those at the very beginning but hit some roadblocks. dont know if they got expanded?

rotund token
#

I'm not sure they're missing anything

#

Just randomly thinking about something I hadn't considered

solemn hollow
#

when i used them there was no dynamic buffer allowed i think

rotund token
#

But you could totally have a job and system that works on a component that doesn't exist

rotund token
#

Imagine if you simply had an attribute to put in a field

#

On create you can reflect get the component type and the field offset

#

And pass that to your job that was written separately well before this component ever exists

#

You know it's not that different to how my save system works

#

This is a fascinating idea

#

Wonder what I could use it for

#

Anyway I really got to sleep like 2 hours past when I was meant to

#

But now I'm just going to be lying here thinking about this

#

This is an amazingly fascinating solution, I just don't have a problem for it to solve

solemn hollow
rotund token
#

I'll write up a proof of concept tomorrow if I find time

solemn hollow
#

@rotund token oh and i just remembered another issue with all of this. what if i want to read from components defined in some other package. like i wanna read the Physics Velocity and want to let the AI do some fancy dodge. Now as a package user I dont have ownership over any component. So my way of creating the reference by discovering an Interface on a component and using codegen to reference it would not work.

oblique cosmos
#

Quick question: I have a ComponentLookup<LocalToWorldTransform> for a job and feed the entities in question through a job execute. Long story short, I can read them just fine but when I try to write to them absolutely nothing happens (not even errors). It's marked with [NativeDisableContainerSafetyRestriction] but notably not [ReadOnly], sooooo... judging by the documentation I should be able to do this, no? Where am I messing up here?

viral sonnet
#

do you get the struct and then write back?

#

i don't know abou LocalToWorldTransform? you sure this is right? it's possible your value gets overwritten

#

[NativeDisableParallelForRestriction] is enough

oblique cosmos
oblique cosmos
viral sonnet
#

with the new TransformV2 system, LocalTransform is what you want probably

#

you can use GetRef from the ComponentLookup. it's what you should be using as there's no struct copy involved, so a bit faster

oblique cosmos
#

Hm. Visual Studio is not happy with LocalTransform, it doesn't appear to be informed about its existence?!

#
        var test = Transforms.GetRefRW(entity, false);
        test.ValueRW.Value.RotateY(5);
#

Surely that can't be right? (because it doesn't appear to do anything either)

#

Hm.
test.ValueRW.Value = test.ValueRW.Value.RotateY(5);
That appears to work. Confusing. Wasn't it the entire point here to get a reference? And if so... shouldn't the rotate just work? My poor reference-trained brain can't handle this lol

#

Oh. Nevermind, I'm a dumbdumb.

oblique cosmos
viral sonnet
oblique cosmos
viral sonnet
#

are you using physics and/or netcode? then v2 is only available in 1.0pre15

#

so either you are on v1 or the namespace is missing to get LocalTransform

#

the quickest way is to check is, if the Translation struct exists. if it does -> v1

#

GetRefRW is used like this ref var test = ref Transforms.GetRefRW(entity, false).ValueRW; test.Value.RotateY(5); get the ref to ValueRW and then it can be modified any way you want

oblique cosmos
#

I think I did import physics in this project at one point, which broke all my aspect usage, so upon finding out that that's not a thing, I threw it out again. Perhaps that messed something up? VS can't find Translation either, so... idk?!

oblique cosmos
viral sonnet
#

are you using the Unity.Transforms namespace?

oblique cosmos
#

Yup

#

Also using TransformAspects, which are new, too, no?

viral sonnet
#

yeah, new for 1.0

oblique cosmos
#

Hm. So.. the way I understood this is that you get the new transform stuff if you are on ECS 1.0 but it breaks when using physics or netcode, no?

viral sonnet
#

hm, inspect the TransformAspect. it should be obvious which path is used then

#

it's either LocalTransform/... or Translation/...

#

before entities 1.0pre15 physics and netcode fored ENABLE_TRANSFORM_V1

#

i don't think you have set this but you can take a look in the player settings if that scripting define is there

oblique cosmos
#

I'm not entirely clear on what you mean by "inspect the TransformAspect"?

viral sonnet
#

in VS, right click -> go to definition

oblique cosmos
#

Wait, am I just on an older version or something? I'm on 1.0.0-exp.12 and the package manager doesn't give me anything new. Is there a new repo out there or something I'm not aware of?

viral sonnet
#

newest

oblique cosmos
#

Oh.

#

Hm.

viral sonnet
#

edit in manifest.json: "com.unity.entities": "1.0.0-pre.15", - sometimes it doesn't show up in package manager

#

same version for physics too

oblique cosmos
#

Wait, does that mean physics works just fine now?

viral sonnet
#

wdym? it runs fine, yeah, but as i said it forces transformV1 system in your version. so Translation/Rotation is used

oblique cosmos
#

No, I mean if I use both of the new versions, pre.15, does it work with the new system then?

viral sonnet
#

yes

oblique cosmos
#

Huh. Cool. That's rather good timing. Now I just gotta figure out how to actually get them because I'm a bit slow, you see...

#

I assume that's not right, is it? :<

rustic rain
#

find physics here

viral sonnet
#

looks good to me

rustic rain
#

and make it 15

viral sonnet
#

same version for entities.graphics

rustic rain
#

it's pre.15 too?

oblique cosmos
#

And then just restart Unity or how does that work? Still needs to import the stuff somehow, no?

viral sonnet
#

save the json and switch back to unity

#

yes, graphics is on pre.15 too

#

i don't use it in my current project.

Burst Occlusion Culling occlusion browser tool
was added, seems cool

oblique cosmos
#

Is it supposed to show up in the package manager? Cause that's still saying exp12

rustic rain
#

ctrl+r

#

should reload

oblique cosmos
#

Reloading does nothing, pretty sure I'm doing something wrong here ๐Ÿค”

viral sonnet
#

you did edit projectFolder\Packages\manifest.json right?

oblique cosmos
#

Yup

#

That's what it looks like now, plus some more blabla

viral sonnet
#

hm, it should reload and do it's thing then

#

otherwise restart unity ๐Ÿ™‚

#

works 100% for me though. never had to actually restart

oblique cosmos
#

Just restarted, still nothing ๐Ÿค”

viral sonnet
#

it's com.unity.physics

oblique cosmos
#

Crap, right. Still, presumably it should've found the rest, no? Hm. Let's see

viral sonnet
#

could have ended up in a parsing error

oblique cosmos
#

Nope, no change :|

proud jackal
solemn hollow
# oblique cosmos Nope, no change :|

i can only speak to transforms v1 but writing to localtoworld before the system that writes from transform/rotation/scale to localtoworld will just be overwritten. You either need to make sure you dont have any transform/rot/scale component on the entity or you need to apply your own localToWorld transform after the "TRSToLocalToWorldSystem"

#

or you can just do what you are supposed to do and write to transform ๐Ÿ™‚

oblique cosmos
solemn hollow
#

you are supposed to write to Translation / Rotation /Scale and unity figures out what the LocalToWorld matrix will be from there

#

that happens in "TRSToLocalToWorldSystem"

#

but as i said i can only talk about transform v1.

#

same basic principals should apply though

oblique cosmos
#

Well, apparently that's where I'm at right now anyway (or am I? I'm getting increasingly confused lol), if you followed the rest of the conversation. But how do I even do that? I'm not entirely sure I follow here :o

oblique cosmos
rotund token
rotund token
safe lintel
#

is 2022.2.0f1 good to use? find it a bit odd that forum and hub still show b16 as the last release for 2022.2

rotund token
#

But I've had no new issues in it

safe lintel
#

i recently had my urp renderfeatures break, seems like a switch was flipped and some old api just doesnt work any more and the new api doesnt render transparency ๐Ÿฅฒ so was wondering if anything else was coming up buggy or just my code

rotund token
#

My urp fog Shader broke at some point from 2021 to 2022. No idea why. So I reimplemented in the new Shader graph full screen effects yesterday because I cbf dealing with these breaking updates

safe lintel
#

heh, just reported a build issue where a shadergraph shader that worked for 2019-2021 now complains of exceeding the cbuffer slots in the latest editor

rotund token
#

Bugger, don't tell me that

safe lintel
#

i really wish i had some automation going cos I dont remember if I even tested a build prior to this version, been dealing with so many upgraded apis

robust scaffold
#

I spent a lot of time last night thinking about the EntityHierarchy and despite how buggy it is on domain reload, it's actually pretty decent.

#

Decent enough that I think a user (i.e. me) would have it open and used on a regular basis. So recreating and maintaining it is not worth the effort.

#

And I think there's some charm to the flat list that entity debugger presented for their entity list.

#

I would have the Entity Hierarchy window completely replace the regular hierarchy window if it didnt throw a billion (23) errors every reload:

rotund token
#

project is in a bit of a state atm as i'm still updating to 1.0 but i can throw you the profile data

#

just the big spikes at the end, most costly being meshrenderer

#

also 7 seconds on hierarchy window though ๐Ÿ˜

#

from that profile 7 seconds is entities hierarchy rebuilding and 12 seconds seem to be baking

robust scaffold
#

Does anyone know why world time triggers structural changes when updating?

rotund token
#

triggering structural change on what?

robust scaffold
#

Unless universal queries can not have order change filter applied

#

noChange is returning false and the only entity that passes through is World Time.

rotund token
#

world time used to write back to a component

#

i'm not sure if that's the case anymore though

#
    {
        public TimeData Time;
    }

    internal struct WorldTimeQueue : IBufferElementData
    {
        public TimeData Time;
    }```
#

still seems to exist

        {
            EntityManager.SetComponentData(TimeSingleton, new WorldTime() {Time = newTimeData});
            this.Time = newTimeData;
        }```
robust scaffold
#

Order filter should only be structural changes. A write to the component shouldnt trigger it right?

#

unless order is both value and structural change filter...

rotund token
#

oh order change

#

yeah i don't know about why that would trigger

robust scaffold
#

hrm

rotund token
#

you should be able to look at journalling

#

to see what is triggering an ordering change

robust scaffold
#

hrm, actually it's my queries are constantly resetting. Give me a min...

robust scaffold
#

There we go, easier to just do a order check on the entity manager itself.

rotund token
#

going to be honest, i don't really understand the need for this? couldn't you have just reimplemented the chunk part in its own window

#

just seems combined the 2 existing windows into 1

robust scaffold
rotund token
#

in that case i'm all for it!

#

ui toolkit is great

#

i'm most interested in your chunk port

robust scaffold
#

I learned a lot doing this. And I agree, UI toolkit is amazing.

rotund token
#

thats actually new content

robust scaffold
rotund token
#

you have done a great job on it

robust scaffold
#

Because the Entity Hierarchy, minus the bugs, is actually really good.

rotund token
#

it just seems like a pain to maintain

robust scaffold
#

And I really didnt want to spend the time to recreate the EH.

#

I'm using a lot of the backend of the systems tab to create my systems list.

#

So if something back there breaks, the list viewer dies. But the entity list is ultra simple. Just iterate through the worlds and create universal queries.

#

The search functions I might just cut out. Too much work maybe. And I personally havent used them yet. But now it's the chunk viewer. Component viewer might get cut though. I dont like how it looks.

robust scaffold
#

Yea, it's looking like I'm basically recreating DOTS windows but I would argue that I'm recreating classic Entities with DOTS characteristics.

balmy thistle
#

Just need that chunk utilization widget

robust scaffold
#

Yep. Working on that right now.

robust scaffold
#

Alright, for selection to work, there can only be 64 worlds and 16.5M entities in total. Tertle, if you're using more than 16M entities across all worlds, Im sorry but this debugger will not work.

rotund token
#

that's actually not uncommon for me

#

;'(

robust scaffold
#

Yea, which is why I'm thinking of a way around the issue

rotund token
#

while i am no longer hitting my previous highs due to capacity limits, i still like testing on 20M as an equiv

#

i dont think its that big a deal

#

it's a dumb test

#

anything above like 5m is dumb

robust scaffold
#

Main problem is that element list indices are limited to ints. And I'm packing the first 6 bits with world index and the next 24 with entity index.

#

Okay, I got some assertions in there to cause a million errors if entity count gets too high.

rotund token
#

bringing back the old school filter bottom?

#

that was the one thing i really miss

robust scaffold
#

filter bottom?

rotund token
#

button*

#

i much prefer the search all components instead of c=

#

if i have more than like 8? components starting with
StatX
and i can't remember the full name it's very limiting in the drop down

#

or if i don't know what it starts with

#

SuperStatHealth or something, i can search Health

robust scaffold
#

I was thinking about incorporating that into a components subwindow. Next to chunk info.

#

Although hrm, search...

robust scaffold
viral sonnet
#

i've nearly forgotten i ever made this ๐Ÿ˜…

rotund token
#

trippy

#

remake with ECS

viral sonnet
#

yeah, shouldn't take me that long

solemn hollow
# rotund token There's no actual implementation in my library just an abstract class. The nodes...

hmm yes i get that but in my case i dont want the user to write an implementation at all. It is all handled in Editor with a graph UI.
If i dont have ownership over the PhyiscsVelocity Component i cannot add an Attribute/ Interface for it to be discovered. So i cannot codegen the necessary reference to expose it to the user in the UI as a Scriptable Object. I can make him write that reference on his own (or just let him specify the the type he wants to codegen the ref for) but thats bad User Experience :S . I just dont see a way around that atm.

rotund token
#

i don't think the experience is that bad

#

from what i heard, some people don't like populating their components with attributes

#

so would rather be able to just pass a list of types in

#

that they can generate their own way

#

i think flexibility is key anyway

#

that said, im not certain what you're doing so i can't say that this is appropriate at all

solemn hollow
#

hmm passing a list of types is a good idea.
my solutions atm are:
codegen a single ref for a single type (i should probably just make the userexperience here better...)
codegen all refs for components implementing a certain interface
manually write the script

rotund token
#

the problem with attributes is always if they are using your library, they could be using someone elses third party library as well

#

as convenient as they are, often just can't add attributes to things you want

#

unless you do like assembly level attributes with a type

solemn hollow
#

just having a scriptable object where the user can add types from any assembly to codegen references from sounds good enough as an alternative

solemn hollow
rotund token
#

i will be fascinated to have a look

#

you are definitely doing some unique stuff that i haven't seen anyone else do

#

and it's stuff that is focused on what i care about (usability)

solemn hollow
#

i guess early DOTS just attracts a different more hardcore code crowd atm. especially since usability of DOTS itself was not the best for a while ๐Ÿ™‚ glad to hear im not boring you with all my problems

rotund token
#

i hang out here for the interesting problems and inspiration

#

i barely slept last night after our convo

#

and the ideas i had with what i was discussing

#

its been a rough day ^_^'

solemn hollow
#

oh no. i try to not look into discord / any code 1-2 hrs before bed exactly because of that reason

#

emphasis on try...

rotund token
#

I was already in bed trying to get to sleep and restless

#

Checked my phone 2 unity devs responding to my rant

#

And then a fascinating discussion with you

#

Yeah that was a mistake

solemn hollow
#

lets not make the unity devs feel bad for answering here! ๐Ÿ˜„ its so great they check this channel from time to time

rotund token
#

It's just my obsessive need to reply

#

Devs in public channel has been great

solemn hollow
#

btw i am having the same kind of issues with other "packages" as well.
Abilitites can stun. Movement needs to react to stun. now both "packages" would need the same Stun component to work together or have unnecessary duplicate data.
I need a general pattern to solve this interop between packages / assemblies

rustic rain
#

or create 3rd one

#

with common buffs

solemn hollow
#

but if its packages i have no ownership over the components. i cannot combine them. id want to have a way to so to say write adapters between them

rustic rain
#

๐Ÿค”

#

why do you not have ownership over said packages?

solemn hollow
#

sure you have ownership and could potentially edit the source but it then breaks with every update...

rustic rain
#

wouldn't it be vice versa?

#

like, if you hardcode reference to specific component type

#

it would be persistent between updates

#

meanwhile some soft link using reflection or smth

#

will more likely to break between updates

solemn hollow
#

what i mean is if you update the package you need to redo your changes to the source

rustic rain
#

I don't get it. Are those your packages or not?

solemn hollow
#

for the sake of argument no

rustic rain
#

๐Ÿฅด

#

I don't understand why, but one way I see it

#

your packages use static init method

#

at some point

#

which obtain through reflection assembly attribute

#

which contains type

#

which then you use to get ComponentType

#

you do it with both packages and now they are dependent on this attribute, which gets assigned in assembly which references them

rotund token
#

you need to ref count it ^_^'

#

(this is why i'm so in favour of one write, many read)

solemn hollow
#

i know im drifting into hypotheticals here but if id use someone elses ability package id assume he had that handled internally. id just have a way to trigger a stun from anywhere and also read from anywhere that i am stunned.
my issues arise when id have another package like AI that would need to reason about Stun. now it needs a way to know that the AI.StunComponent is the same as the Ability.StunComponent.

#

And both components can actually be totally different.... there would just be a way to interpret one into the other

rustic rain
#

I figured for myself that implemented mechanic cannot be modified, so if it wants to use specific component - it will only use that. And if someone wants to change that - he has to disable mechanic (system) all together and create his own

solemn hollow
#

as i said i as a user of both packages would need an "AdapterComponent"

rustic rain
#

or just add new that will work together

#

otherwise we go into spaghetti zone where one depends on the other...

solemn hollow
rustic rain
#

why not have one hierarchy?

#

main package with most of core stuff and then packages that only rely on it, but not on other

#

or vice versa

solemn hollow
#

unity themselves dont have that problem because they only ever have one package of a kind and just declare their components as the standard to use ones. when other users create packages they dont have that luxury

solemn hollow
rustic rain
#

why wouldn't 3rd party packages work?

#

as in mods

solemn hollow
#

how? youd need a core package that every dev would agree to?

rustic rain
#

they have a luxury to reference everything main game has

#

ahem. Are you talking about game modding or smth else?

solemn hollow
#

i am talking about packages in unity

rustic rain
#

๐Ÿค”

#

I think Unity uses compiler constraints for that

#
#if PACKAGE_X
use <T> comp
#elseif
use <Y> comp
#endif
solemn hollow
#

yes and they can do that because they know all of their packages and only care for theirs

rotund token
#

but stun is just an index in a buffer

#

that represents an arbitrary stat 'stun'

solemn hollow
#

true. makes it even more complicated :S

rotund token
#

thats effectively how my stat library works

#

there are no components, just 1 fixed buffer that represents everything

solemn hollow
#

yes i remember. there are so many different ways that a 1:1 translation of components cant work

#

so maybe duplicating the data into the specific Package Components is the only real way to interop ...

solemn hollow
#

Atleast for packages I create I could imagine some kind of AdapterAspect that needs to be adjusted outside of the package itself where the user can implement his own logic on how to read for example tertles stat Buffer.

rustic rain
#

why even bother with packages though?

#

"Everyone wants to write a framework, but no one wants to use one"

solemn hollow
#

cause i cant write everything from scratch every single time

rustic rain
#

but smth like movement and ability which depends on specific Stunned component doesn't sound very generic to begin with

#

Could probably limit it to smth not directly related to game mechanics

late mural
#

if i work out my chunk like this: cs int2 Chunk = new int2((int)transform.position.x / ChunkSize, (int)transform.position.z / ChunkSize); Then logically i should workout my chunks centre world space position like this right? cs int3 ChunkCentre = new int3(Chunk.x * ChunkSize / 2, 0, Chunk.y * ChunkSize / 2); From here though im less certain, like how would i work out the chunks max corner position, like this?```cs
int3 ChunkMaxCorner = ChunkCentre * 2;

solemn hollow
#

movement is not a thing id want to have generic. i do have a rather generic abilitysystem though.

rustic rain
#

I mean systems like that usually don't rely on anything but entities packages, so

#

and you are likely to change it to suit needs of game anyway

solemn hollow
late mural
#

i also dont even know if my ChunkSize is a halfsize or one full length lol

rotund token
late mural
solemn hollow
#

why is your ChunkCentre not based on translation but on chunkposition?
id say you should probably look at how tilemaps work as an example to do this

#

nvm makes sense

late mural
#

ok ill have a look at how tilemaps work, thanks

late mural
solemn hollow
#

โœ… Get the Project files and Utilities at https://cmonkey.co/gridsystem
๐ŸŒ Get my Complete Courses! โœ… https://unitycodemonkey.com/courses
Let's make a Grid System that we can use to split our World into various Grid Cells.
Then we can use that to make a Heatmap or a Pathfinding Map with avoid/desire areas or a Building Grid System.

Complete Grid ...

โ–ถ Play video
oblique cosmos
#

I just upgraded to pre.15, replaced all the transform related stuff in my code and now I'm running into the strangest issue. I'm not entirely sure what's happening, but something's not right with my transforms now and it basically broke everything. I made a little test object to figure out what's happening:

#

Test has a little move component (as simple as it gets, really), body is just a box, wings is another box and the two guns are also just boxes

#

Oddly, the body moves fine, the rest stay at origin

#

And it confuses me to no end oO

rustic rain
oblique cosmos
#

It's a gameobject

rustic rain
#

how does it look in hierarchy then?

oblique cosmos
rustic rain
#

try without live conversion

oblique cosmos
#

Same thing

rustic rain
#

I mean hierarchy

oblique cosmos
#

I'm not sure I follow?

rustic rain
#

show hierarchy

#

with closed subscene

#

live conversion is borked

#

it won't work correctly

#

and it shows game objects

#

not entities

oblique cosmos
#

You mean this?

rustic rain
#

open up your entity

#

whole hierarchy

oblique cosmos
#

Well, that's the entire scene, there's only one object in there which I would assume is the cube, since that's actually moving. So I guess the question is why did the rest get loose?!

rustic rain
oblique cosmos
#

Don't mind the changed IDs, was just playing around

#

But yea, that's the cube

#

Hm. With that only the one single gun gets left behind

#

Uh... okay, now children randomly teleport around when I change scale (building a second test object to narrow this down). Something seems really messed up right now. Also upgraded to b16, anything known about that version being weird with transforms or something?

rustic rain
#

Meaning other gets unattached for some reason

oblique cosmos
#

Yup, it would appear so. I can't seem to figure out why though. Hmmm. Maybe I should run this test on an empty project, perhaps some system somewhere is doing shady stuff ๐Ÿค”

rustic rain
#

If wings is physics object

#

No parent for it

#

Physics object can't be children

oblique cosmos
#

They are basic primitives, they have whatever new objects have

rustic rain
#

Check subscene outside of game mod

#

How does it look?

#

Is it already borked or still OK?

oblique cosmos
#

I'm not sure what you mean "outside of game mode"?

rustic rain
#

Don't press Play

#

Bad wording ๐Ÿ˜…

oblique cosmos
#

I mean, they just appear in the normal gameobject form then, no?

#

(I'm frankly still struggling to figure out the entities hierachy...)

late mural
#

wondering what would be the Unity.Mathematics version of FloorToInt()?

rustic rain
#

And look in hirtarchy

oblique cosmos
#

Uh... this is presumably my ignorance speaking, but everything just disappears and the scene says not loaded?!

#

Ah!

#

Okay, uhh

#

Well, yup, still looks borked

rustic rain
#

Then figure out your baking code

#

It breaks at this stage

oblique cosmos
#

Hmmmm

#

That worked fine before?!

#

Wait, that can't even be it, can it? I'd imagine it breaks even without anything attached. Lemme test...

#

Yea, it someone only actually make the first object I add a child and everything else gets thrown out (or something like that, unclear)

#

Whether it has any baking on my end or not

#

Hmmmmmmmm. I just deleted the physics package on an out there hunch and now it randomly seems to be working ๐Ÿค”

#

Uhh... yup, everything is back to working as expected...

rustic rain
#

You sure your wings aren't physics objects?

oblique cosmos
#

Yup, as I said, I just made the thing to narrow things down, it's literally just a bunch of right click add cube type of deal. I mean, I supppose that means they have colliders, but that shouldn't explode everything, should it?

#

Nevermind... apparently it does explode everything. Huh...

#

Welp, guess I have some reading to do on the physics system, huh?

safe lintel
#

is it normal behaviour for managed bits to disappear in subscenes that are open? like particle effects, visual effects, terrain? I dont remember this happening prior to 1.0.x

stone osprey
#

Implemented a own quadtree for having AOI events when an entity left or entered or even stayed in the AOI of the player for example.

How would you implement those "events" ? As event entities like : Entity{ AOIEvent{ firstEntity, secondEntity }, AOIEntered } ? This way systems could react easily to those to network stuff e.g.

Any downside of this approach ?

solemn hollow
#

you have other options like NativeStream to write events in parallel onto it. or if parallel is not necassary just a Dynamicbuffer on a singleton Evententity where you list all the events.

stone osprey
# solemn hollow downside is you have structural changes each frame which are quite expensive if ...

Oh, probably described it badly...

I basically mean that i realize AOI events as seperate entities... like when a new entity appears inside the players AOI, it will create a Entity{ AOIEvent{ firstEntity, secondEntity }, AOIEntered } entity which acts as an event. No structural changes here... and that one can be queried for systems to react to it.

Oh one problem i see is that this would still be kinda expensive since the AOIEvent references two entities and we need to acess their components manually then : manager.GetComponentData<..>(aoiEvent.firstEntity); ...

#

However thats probably cheaper than doing structural changes ?

solemn hollow
#

spawning an entity is a structural change

#

what i do is just tagging all Entities with a component that are in the AOI of the player. works well enough for my usecase. and i think structural changes are ok if your objects stay in the area for long enough.
this way it lets me query all objects in the AOI directly

stone osprey
#

Oh i thought you mean adding/removing components ^^

Well tagging entities is actually also a structural change right ? And probably even more expensive since it copies the entity to a different archetype/chunk... So will it might be more performant to just spawn in event entities ? ^^

solemn hollow
#

with tagging i refer to adding / removing empty components. its a structural change yep

viral sonnet
#

the best thing is to not design events as entities

solemn hollow
#

how was LOD handled by unity?

viral sonnet
#

the only exception now is if the event entity is persistent and enable/disable can be used

solemn hollow
#

that should be a good pointer on how to do this

stone osprey
stone osprey
viral sonnet
#

because of the structural change overhead

delicate swan
#

I thought Unity still recommends the tagging style for event-based on less-then-per-frame events

solemn hollow
solemn hollow
#

filtering chunks incurs a structural change but down the line reduces your cache misses. its a tradeoff

stone osprey
#

Does unity really recommends this ? Kinda funny since i always here "avoid structural changes !!!!" and similar stuff

viral sonnet
#

it's okay if the entity count is low but that solution doesn't scale well

solemn hollow
#

@viral sonnet what would you say how is your usage of tagging vs enable/disable?

delicate swan
solemn hollow
#

id say i do 90% tags 10% disables max

viral sonnet
stone osprey
#

For large amounts of entities i could actually think that event entities are pretty fast... since like a Entity{ StayedInAOI{ first, second }} entity has the size of a few bytes... the commandbuffer could bulk create them fairly easily and fast i assume. And the query speed would be considered "perfect".

solemn hollow
delicate swan
viral sonnet
#

no it's not. i have tested this to death. command buffer is even worse

#

what you want is pre-allocated nativelist, nativestream or my parallel list which you can find in my discord profile (oh wait, i'll add the link ๐Ÿ˜„ )

stone osprey
stone osprey
solemn hollow
viral sonnet
#

and it's on a per-usage basis. in case you can utilize an enabled comp you should. that's also very fast but for everything else, specialized data containers will work best.

stone osprey
delicate swan
#

Wouldnโ€™t it be simpler to use distance calculations over actually collision detection for persistent area triggers?

viral sonnet
#

AOI is area of influence?

delicate swan
viral sonnet
#

so for my solution, similar to any mmo where you enter a certain radius of an enemy and the enemy aggros the player i used collisionWorld.OverlapSphere and write to my parallelList. i've tested triggers for this and that went really bad

#

manual overlapSphere checks scale really well

solemn hollow
#

someone did a test a while ago where he checked wether its just faster to do the distance calculation in comparision to using Physics. if i recall correctly the outcome was that you need a really high number of entities before the physics package pulls ahead

#

there should be a forum thread around

delicate swan
#

Unless you have a lot of dynamic interactions that need to hot-load special effect components, I would imagine the constant expensive of some vector math might be more predictable then arbitrary physics collision checks

viral sonnet
#

yep, straight up brute force works really well too

solemn hollow
#

ooof i just checked my LOD system and i am using math.distance

#

instead of distancesq

viral sonnet
#

that assumes a small count to check against but even what is considered "small" today, is quite big and easily in the 20k+ range

solemn hollow
#

and it doesnt even matter. not visible in profiler for my entity counts

delicate swan
#

Yeah, my problem is the physics system is already doing all those exact same distance checks for itโ€™s batching pass for collecting objects that might collide

#

So unless you actually need the physics simulation aspect of it, I would think it would be cheaper to just do the distance checks yourself on simpler volumes like rectangles or circles

solemn hollow
delicate swan
# solemn hollow for area of interest you dont need any shapes

That was my thought, if itโ€™s just distance really, especially for static positions, might be worth it to create a system that saves those positions on a distance query component at the start, then just checks for distance < triggerDistance every frame in parallel, trigger some action via a book change when in distance

#

Bool* not book, damn it ac

#

Consistent cost is better then potential hitch in my book, especially with ECS where we get such tight control over memory/processing

dense crypt
viral sonnet
#

i handle each nativecontainer in a singleton struct with proper dependencies. before that i had to juggle jobhandles

#

it works really great. now i don't have to think about it anymore

delicate swan
#

Might as well throw it out here, anyone have a good idea how to handle a system where providing a essentially string ID returns a collection of methods for creating/updating particular archetypes of entities?

My initial thought was an interface with the methods, but Iโ€™m having trouble loading the various implementation types into some sort of queryable system, my last resort is hand coding a large switch statement that just returns instanced structs, but I would prefer a more automatic solution

#

I thought of using a source generator and a registration attribute to create the switch statement on the fly during compile, but I cannot get scoping figured out for the generator and asmdefs,

#

Oh, forgot to say Iโ€™m going for compile time constants as a constraint,

otherwise I would just use attributes to spin up a hash map of id/interface instances in a static class and use that, but I need it fast and accessible from job code, so static constants are best bet

viral sonnet
#

hm, i don't have a good answer. have you considered generic systems?

#

source gen is the most powerful and flexible for this.

#

i use a mix for my stat system. that is, source gen and generic system/jobs

delicate swan
#

Hmm, I had not thought to containerize it with a generic, use constraints to enforce the interface, but thinking further on it, I would still need to hardcode the generics. I kinda wish attributes could run and do source modification at compile time without an external analyzer

viral sonnet
#

yeah, no way around it when you want it at compile stage.

#

the generics would implement the interface at least. if not, code gen is your only option. then you are pretty much free to do anything

delicate swan
#

That seems to be where Iโ€™m headed.

Iโ€™ve source generators before, so itโ€™s not too bad, but Iโ€™m having the most trouble with Unityโ€™s weird scoping and inconsistent docs/behaviors vs normal c#, or maybe Iโ€™m just misunderstanding something

delicate swan
rotund token
#

I'm really struggling to understand how an open world workflow can work with dots and current baking.
As far as I can tell, any change that triggers a domain reload (or just opening unity) requires all subscenes to be re-baked even if it changes no dependencies (editor only assembly with post processing volumes)

A test area of 256x256 takes my 3900x 30s seconds to bake
Extrapolating to a 4096x4096 area which is 256 larger, would therefore take 128min or 2 hours to bake (now i don't believe it'd actually take that long but you get the idea.)

#

Seems like some type of caching is missing here

#

Even deleting an unused material that was previously used for a full screen pass on the renderer re-triggered all my bakers somehow

delicate swan
#

I thought that normal baking was more for less repetitive concepts like players or enemies, IIRC there is a way to batch gameobject conversion for larger sets of near-duplicates

viral sonnet
#

tertle, that all sounds quite horrible ๐Ÿ˜ฆ i wonder why it's that slow. that's absurd.

rotund token
#

Just takes a while to get every material/renderer