#archived-dots

1 messages ยท Page 33 of 1

rotund token
#

oh agreed

#

but i think it'd be an easy assumption to make as it's how it's worked so long

#

i've seen a few people ask aboutt the addjobhandle stuff

misty wedge
#

This works btw, thanks. I had to restart the editor though for it to refresh properly

rustic rain
#

hold up

#

if I use

#

SystemAPI.QueryBuilder

#

in OnUpdate

#

will it cache it in OnCreate instead?

rotund token
#

yes

#

i just wish it also had a RequireForUpdate() option included

rustic rain
#

Unity should mention whether method can run in OnUpdate ngl ๐Ÿ˜…

rotund token
#

all systemapi methods can

#

from memory

#
/// Gives a fluent API for constructing EntityQueries similar to the EntityQueryBuilder. This API statically constructs the query as part of the system, and creates the query in the system's OnCreate.
/// Calling this method should allow for construction of EntityQueries with almost no run-time performance overhead."
/// </summary>
public static SystemAPIQueryBuilder QueryBuilder()```
just to confirm
proud jackal
#

Indeed, SystemAPI.QueryBuilder does caching in OnCreate you can always check sourcegen, when in doubt :3

rustic rain
#

Dude, I need this for type handles

rotund token
#

I have already politely asked Dani for this ๐Ÿ˜„

rustic rain
#

will actually make things so much compact

rotund token
#

i know right!

#

i'm so hyped

proud jackal
#

Hehe :3

rotund token
#

i feel somepoint soon, i'm going to be complaining that ISystem includes OnCreate/OnDestroy by default

#

as most of mine will be empty

#

and i'd prefer them to be like OnStart/OnStop running optional interface

proud jackal
#

Hopefully default implemented interfaces will fix that part!

rotund token
#

that's true!

#

that's a good solution

rustic rain
#

for now, that's the best I could implement for short code

private ShipMovementJob _job;
        protected override void OnCreate()
        {
            _job.ltws = GetComponentLookup<LocalToWorld>(true);
            _job.entityTypeHandle = GetEntityTypeHandle();
            _job.translationHandle = GetComponentTypeHandle<Translation>();
            _job.rotationTypeHandle = GetComponentTypeHandle<Rotation>();
            _job.gtpTypeHandle = GetComponentTypeHandle<GetToPoint>();
            _job.shipHandle = GetComponentTypeHandle<ShipComp>(true);
            _job.actionHandle = GetBufferTypeHandle<QueuedAction>();
        }
        protected override void OnUpdate()
        {
            var buffer = SystemAPI.GetSingleton<EndTickSimulationCommandBuffer.Singleton>()
                .CreateCommandBuffer(World.Unmanaged);
            _job.buffer = buffer.AsParallelWriter();

            _job.ltws.Update(this);
            _job.entityTypeHandle.Update(this);
            _job.translationHandle.Update(this);
            _job.rotationTypeHandle.Update(this);
            _job.gtpTypeHandle.Update(this);
            _job.shipHandle.Update(this);
            _job.actionHandle.Update(this);

            Dependency = _job.ScheduleParallel(SystemAPI.QueryBuilder()
                    .WithAllRW<QueuedAction>()
                    .WithAllRW<Translation>()
                    .WithAllRW<Rotation>()
                    .WithAllRW<GetToPoint>()
                    .WithAll<ShipComp>()
                    .Build(),
                Dependency);
        }
rotund token
#

_job.ltws = GetComponentLookup<LocalToWorld>(true);

#

you could turn that into systemapi

#

but it's only saving 1 line

#

~~actually does it save any ~~

rustic rain
#

what method?

rotund token
#

oh yeah it does

misty wedge
#

It'd save the update call

rustic rain
#

oh

rotund token
#

SystemAPI.GetComponentLookup<LocalToWorld>

rustic rain
#

yay, one line saved

#

xD

#

anyways, system went from 200 to 131 real quick

hot basin
#

aspects will not help?

rustic rain
#

hm

#

in fact, they should

misty wedge
#

I'm still not sure if I should store my queries in the system or use QueryBuilder when scheduling the job

proud jackal
#

Well, it has no perf diff, so purely a design choice (only slightly on iteration time)

misty wedge
#

Yeah I know, I was talking design wise

rotund token
#

i don't really wnat to do requireforupdate(query) in update
so that's the 1 thing that causes me on occasion to do it in oncreate
i can work around a lot of these though by simply using the attribute

rustic rain
#

I'm just was so busy with fixing project's conversion, selection system and all that stuff
I just now managed to get to converting all my IJobEntityWithBatch and systems xD

misty wedge
rotund token
#

sometimes specific query

#

(i did just add i can often use attribute)

misty wedge
#

Ah, I missed it

rustic rain
#

do aspects support type handles?

proud jackal
#

Aspects create typehandles :3

readonly partial struct SomeAspect : IAspect {
  readonly RefRW<MyComponent> myComponentReference;
}

will make a SomeAspect.TypeHandle that is used in OnCreate and Updated at call site (that's what IJobEntity, Query, and even Entities.ForEach use)

misty wedge
#

And then you only get a single typehandle for the entire aspect instead of multiple?

proud jackal
#

Indeed

misty wedge
#

Alright, that's how I thought they worked, but I haven't used them yet

rustic rain
#

ugh

#

can't I use it in IJobChunk?

misty wedge
#

I think you can?

#

Just pass the type handle to the job

rustic rain
#

I still don't get how to get type handle

proud jackal
#

Tho, It's not a supported API to use any of the functionality we create as backing for Aspects (aka stuff like SomeAspect.TypeHandle and SomeAspect.EntityLookup is not something we will promise not to change, so be careful!), tho we do want to publically expose something in the future!

proud jackal
rustic rain
#

Hold on, any example?

#

manual only has specific entity or codegened IJobEntity

proud jackal
#

Try seeing the system code that is generated from doing:

OnUpdate(){
  new myIJobEntityThatUsesSomeAspect().Schedule();
}
rotund token
#

from a very quick look since i haven't looked at aspects yet, if you're doing things manually it seems to generate nice little structs for you

            var aspectHandle = new ColliderAspect.TypeHandle(ref state, true);
            
            // on update
            aspectHandle.Update(ref state);
            
            // in job
            var resolved aspectHandle.Resolve(chunk);
            for(var i = 0; i < chunk.length; i++)
                var aspect = resolved[i];
rustic rain
#

oh, just like that?

proud jackal
#

But again, just like using InternalCompilerInterface is a not supported to use, this is danger, we might change it without warrant so is MyAspect.TypeHandle, MyAspect.ResolvedChunk and MyAspect.EntityLookup.

#

Not like that sentence stops people from using it, same goes for internal functions apperantly ugh... ๐Ÿ˜†

rotund token
#

all people read is "... supported to use ..."

rustic rain
#

are buffers supported in aspects?

proud jackal
rotund token
#

i was actually shocked how few extensions i wrote broke in 1.0 that relied on internal access

rustic rain
#

so yeah, buffers work

#

hm

#

why buffers are not defined

#

as RO or RW?

#

buffer type handles do require it

proud jackal
#

Indeed, they simply didn't get as much care as IComponentData tohrushrug2

misty wedge
#

What do they default to? RW?

rustic rain
#

so, they are just RW?

proud jackal
#

Yup

misty wedge
#

I'm guessing this is the same case for the Query API

proud jackal
#

Indeed, those are the two cases!

rustic rain
#

I'm guessing Aspects require compilation to get TypeHandle generated?

#

sadly my project has tons of errors rn xD

proud jackal
rotund token
#

"Project has compile errors so won't code generate. Project needs code generation to not have compile errors" ๐Ÿ˜†

rustic rain
#

yeah, I'm afraid to get into one of those cycles

rotund token
#

i think it's generally not an issue

spice vale
#

About the system entity chunk fragmentation chat earlier, I wanted to add my 2 cents:

#

Maybe they will change the way system data is stored in the future. Why else would they: 1) make the system entity internal and give us specific overloads to access system data. 2) make queries discard systems by default. So I'd say lets just enjoy using system entities for now and hope unity fixes the chunk fragmentation issue for us later.

proud jackal
gusty comet
#

Ok I am somewhat confused. I seem to have borked something during install of entities and entities graphics somehow? I did a fresh install of the beta of 2022.2 and get lots of errors for the collections dependency?

#

And given the amount and type it seems like its literally not registering a package but the collections package was installed as a dependency, and no errors during install at all

spice vale
#

have you restarted the editor since install?

gusty comet
#

not yet gonna try that now

spice vale
#

try it, usually fixes such errors

gusty comet
#

given it misses keyword, I was wondering if its not linking properly

#

ok restarting boils it down to one error now.
Library\PackageCache\com.unity.2d.animation@9.0.0\Runtime\TransformAccessJob.cs(165,62): error CS1955: Non-invocable member 'NativeHashMap<int, TransformAccessJob.TransformData>.Count' cannot be used like a method.

viral sonnet
spice vale
gusty comet
#

Tried several times now with no luck

viral sonnet
#

that said it would be nice if unity respected asmdefs and compiles them even when the main source can't be

#

@gusty comet are you in an asmdef and missing the reference?

gusty comet
#

I have no clue what asmdef even is so I assume no

viral sonnet
#

hehe, ok, then no asmdef ๐Ÿ˜„

gusty comet
#

Fresh unity install out of the box, clean new project, just added the two packages as per install instruction

viral sonnet
#

api level on .net standard 2.1?

gusty comet
#

I have changed literally nothing.

misty wedge
#

What entities version are you using?

gusty comet
#

The one it fetched when I queried for com.unity.entities and com.unity.entities.graphics

misty wedge
#

So I'm guessing 1.0?

gusty comet
#

as per install instructions

#

yep 1.0 experimental 8

misty wedge
#

I don't think you can use entities@1.0.0-exp.8 with unity.2d.animation@9.0

#

The error you are getting is from the changed NativeHashMap API

#

I don't think the 2d package has been version matched to the entities 1.0 release

viral sonnet
#

good catch, that seems most likely

gusty comet
#

Can I revert to an older version of unity.2d.animation

misty wedge
#

No

#

I would assume not

gusty comet
#

So 2d devs are still effed, now more then ever...

#

I am getting sick of this bs

misty wedge
#

The package isn't released yet...

gusty comet
#

They promised 2d support for what... 2 years now?

spice vale
#

maybe it would work to downgrade collections package?

misty wedge
#

Yes, and it's still not finished

misty wedge
spice vale
#

oh ok

balmy thistle
misty wedge
#

Yeah I am wondering the same thing

#

I don't think that was ever promised

#

Unless they mean project tiny or something

gusty comet
#

ever since the unity tiny release

#

they said that full 2d support will follow shortly

#

and 2 years is by no definition shortly.

balmy thistle
#

where?

drowsy pagoda
#

What's a good way to check if entity exists and is enabled from within IJobEntity?

viral sonnet
#

you can downgrade to entities 0.51. if the package manager is not able to, edit the manifest.json in the packages folder

misty wedge
drowsy pagoda
#

No. Another one.

gusty comet
#

I specifically wanted to test baking which afair is not a thing in 0.51

drowsy pagoda
#

the one part of execute has a component that has a Target of type Entity

#

just need to check if that target is alive each frame while target is set.

viral sonnet
#

then use 1.0 and render with GOs and sprites

#

jason, you'd so that with a componentlookup

gusty comet
#

I mean how when the default installed 2d package breaks it?

balmy thistle
misty wedge
rustic rain
#

oh wait

#

no, I mixed it up

drowsy pagoda
#

lol

gusty comet
rustic rain
#

kek

misty wedge
misty wedge
viral sonnet
#

oh sorry, didn't catch that then - was just on mobile ๐Ÿ˜„

misty wedge
#

I guess you could check Translation if you aren't stripping them @drowsy pagoda

#

Simulate would probably also work

viral sonnet
misty wedge
#

Yeah but what if the target doesn't have the component

#

It can be any entity

viral sonnet
#

i dunno, bad design i'd say ๐Ÿ˜„

#

surely it has some component

misty wedge
#

Well yeah, but if it could be one of 5 archetypes with no overlapping components you'd have to check them all

#

So ideally something that is always on an entity

rotund token
#

HasComponent and Exists have always been the same thing

misty wedge
#

I feel like there should be an explicit way to check for existence, simply from a semantic point to make what is happening clearer

rustic rain
#

why check for existance though

rustic rain
#

if you have entity you most probably want some component on it

misty wedge
#

In case the entity was destroyed

viral sonnet
rustic rain
#

so checking component should be the way I guess?

rotund token
#

EntityStorageInfoLookup

rotund token
#

EntityStorageInfoLookup has

        /// Reports whether the specified <see cref="Entity"/> instance still refers to a valid entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>True if the entity exists and is valid, and returns false if
        /// the Entity instance refers to an entity that has been destroyed.</returns>
        public bool Exists(Entity entity)```
viral sonnet
#

yeah, that works

rotund token
#

[0.12.0] - 2020-05-27
Added BufferFromEntity.HasComponent(), with the same meaning as the existing .Exists() call (which is now 'deprecated).

Deprecated ComponentDataFromEntity.Exists(); Use .HasComponent() instead.

#

Exist had been deprecated for over 2 years

viral sonnet
#
        {
            int index = entity.Index;

            ValidateEntity(entity);

            var versionMatches = m_VersionByEntity[index] == entity.Version;
            var hasChunk = m_EntityInChunkByEntity[index].Chunk != null;

            return versionMatches && hasChunk;
        }``` it's a very seperate call though?
#
        {
            if (!Exists(entity))
                return false;

            var archetype = m_ArchetypeByEntity[entity.Index];
            if (Hint.Unlikely(archetype != cache.Archetype))
                cache.Update(archetype, type);
            return cache.IndexInArchetype != -1;
        }``` i don't know what you mean tertle
misty wedge
#

I think he meant that's the way to check

#

e.g. pass the storage info to a job

rotund token
#

i'm saying exists/hascomponent on componentfromentity were the same

rotund token
viral sonnet
#

the HasComponent is from ComponentLookup which calls Exists

rotund token
#

yes?

viral sonnet
#

which all funnel to EntityComponentStore

rotund token
#

if you have an entity that only has a translation component and you call hascomponent on it for rotation

#

it will return false

#

if you call exists on it

#

it will return true
they have different usages

misty wedge
#

@drowsy pagoda so to answer the question use EntityStorageInfoLookup

drowsy pagoda
#

and that is burst job safe right?

rotund token
#

yes

#

there's a SystemAPI version of it as well

viral sonnet
#

i haven't said anything different ๐Ÿ˜„ point is Exists is not accessible anymore on ComponentLookup. Should it even be there? Debatable. Unity removed it probably because of the overlap of EntityStorageInfoLookup

rotund token
#

you're missing my point there

#

the old Exists on ComponentLookup was exactly the same as HasComponent

#

it didn't check if an entity exists (well it did but it also)

#

it checked if a component exists

#

it was simply renamed to HasComponent to clear up this confusion

viral sonnet
#

i posted the code above. that's 2 very different things. nothing changed from 0.51 to 1.0

misty wedge
#

I think it's correct that it's been removed from ComponentLookup

#

It didn't make a lot of sense before

viral sonnet
#

and i actually don't get it because one complaint i had is that HasComponent does an Exists check which is overhead when you in fact do know that the entity exists

drowsy pagoda
rotund token
#

you don't use it in IJobEntity

#

you use it in the system and pass it to IJobEntity

#

new myJob
{
StorageInfo = SystemAPI.GetComponentLookup(),
}.Schudule()

drowsy pagoda
#

ah. duh.

#

thx

misty wedge
viral sonnet
rotund token
#

no

#

Schudule, my custom awesome scheduler

misty wedge
#

Oh it was renamed toSchudule

rotund token
#

i don't make mistakes

#

๐Ÿ˜„

rustic rain
#

btw

misty wedge
#

careful there, I certainly do make mistakes

rotund token
#

you saw nothing

rustic rain
#

hasn't there been anything about ability to move entity to existing one?

#

I really would love a feature to Instantiate entity into existing Index/Version

viral sonnet
#

entities old god edition new myJob { StorageInfo = SystemAPI.GetComponentLookup(), }.sch'thulu()

rustic rain
#

๐Ÿคฃ

viral sonnet
#

this just gets better and better ๐Ÿ˜„

drowsy pagoda
#

that's weird, i did that and it's still giving me that failed generator error.

rotund token
#

code

drowsy pagoda
#

I am constructing the job from a SystemBase@OnUpdate, and inside OnUpdate there is a call to a private method that does that construction.

rustic rain
#

Have you tried making a sacrifice? ๐Ÿคฃ

misty wedge
drowsy pagoda
#

I think you might be right.

#

I'm gonna try changing private method to static. see if that does anything.

misty wedge
#

That won't work

viral sonnet
#

it's easier if you post code

misty wedge
#

It needs the world to get the storage info

rotund token
#

SystemAPI must be called from within a system

drowsy pagoda
#

nope

#

i mean yeah it does. nope as in it doesn't wokr because of that lol

misty wedge
#

use that

drowsy pagoda
#

No I can't because that's for a specific entity that I must know about

misty wedge
#

Actually, wrong one

drowsy pagoda
#

I need this for a parallel job

#

I stripped code from that private method and placed it directly inside OnUpdate. Still same error!

misty wedge
#

Try CheckedStateRef.GetEntityStorageInfoLookup()

drowsy pagoda
#

got it now, works in private method too. Basically you can't use SystemAPI inside a constructor. You have to use it only where you assign a variable directly. Then pass that var into the job construction.

misty wedge
#

Well yes, it has to be inside a system

rotund token
#

yeah i would not really recommend using job constructors

misty wedge
#

Especially since it's just more code to write

rustic rain
#

code hating gang

misty wedge
#

less code = gud

rustic rain
#

soo...

#

I really need a feature

#

to instantiate entity into another

#

basically, so all systems can get reference to entity in OnCreate

#

but since it's loaded through SubScene

#

whatever is loaded will be assigned only after subscene loaded

misty wedge
#

Why do you need it in on create

rustic rain
#

because there's no other way (simple way) to get entity reference in ISystem

misty wedge
#

Read it from a component

rustic rain
#

unless you do if(entity= null) in OnUpdate

misty wedge
#

That you bake

rotund token
#

IStartRunning?

rustic rain
#

which I hate

#

no.

#

besides

#

OnStartRunning is practically OnUpdate

#

for a lot of such cases, so

misty wedge
#

Not if you have requirements

rotund token
#

a lot less so now that everything is alwaysupdate

#

by default now onstartrunning is much more like oncreate ๐Ÿ˜„

rustic rain
#

anyways, I still need this functionality

misty wedge
#

Why not put it on a baked component? Sounds infinitely easier

rotund token
#

it's not /that/ hard to implement yourself

#

archetype.getcomponents

#

and dynamictypehandle

rustic rain
#

yeah, already looking into Instantiate

misty wedge
#

So you want to manually set index and version to get a reference to an entity?

rustic rain
#

no

#

I want to create singleton

#

with specific tag

#

and then once subScene is loaded

#

this singleton will change it's archetype and comp data to be clone of loaded entity

rotund token
#

is this just to avoid the singleton pattern?

#

so you can cache your entity

misty wedge
#

How will you keep the system from running before that is done?

rustic rain
misty wedge
#

Why not just get that singleton then once everything has loaded

rustic rain
rustic rain
misty wedge
#

Since your system is waiting you can use OnStartRunning to cache the entity

#

Once the subscene has loaded

rustic rain
#

easy with SystemBase

rotund token
#

yeah i still don't get your hate with this but whatever it's doable!
we do something like this at work, we strip an existing entity back to no components then add a bunch of new components onto it to change it's archetype

rustic rain
#

superhard with ISystem

rotund token
#

(this is done to have creatures morph into something new and allowing things that are already targeting them to keep targeting them)

rustic rain
#

yeah, in my case it's morphing entity, kek

misty wedge
rustic rain
#

this is the whole point why I need it

rotund token
#

but we completely change what it is

#

give it a new prefab effectively

misty wedge
#

I'm guessing the reason for this is make it fast (instead of just a bunch of add / remove components)

rotund token
#

it's unknown what components need to be removed/added

#

the larva becomes a butterfly kind of thing

rustic rain
#

for example here's one of use cases:

  1. some systems (mostly input related) rely on entity selection (just a square basically)
  2. I get or create singleton of that selection entity in OnCreate
  3. once it's actually loaded, I attach all data to that singleton
    Profit
rotund token
#

i mean, i disagree with the reasoning behind what issues wants to use it for but it's his architecture so he can set it up how he wants and it is totally doable and useful so it would be kind of nice to have a built in way to easily do this

rustic rain
#

for now I construct entity manually through code

#

but it broke after update

#

that's why I want to depend on conversion with SubScene instead

#

to get perfect graphics of selection I want

#

hmm

#

so there's Dynamic type handle for shared?

rotund token
#

dynamictypehandle can be used for any component

rustic rain
#

even shared?

rotund token
#

you dont need it for shared

#

there's a shared version instead ๐Ÿ˜„

#

DynamicSharedComponentTypeHandle

rustic rain
#

that's what I asked kek

#

so for now it seems easy

rotund token
#

oh i missunderstood

#

basically what you need to do from top of my head
A.SetArchetype() from B components
Add some kind of filter component to either A/B to differentiate them chunks
Execute a job, get handles to A/B
Just iterate every component and memcpy using dynamic handles from B to A

rustic rain
#

no need for filter, I already know source and target entity

rotund token
#

oh i guess you could just compare entities in the chunk

#

just remember to use dynamic handles you need to iterate the chunk

rustic rain
#

yeah, pretty much

rotund token
#

not do a lookup on entity

pliant pike
#

wow sometimes DOTS drives me crazy I've suddenly got a whole system that's stopped running it was fine before and now suddenly its like "nah I'm fed up not running anymore" leahWTF

rustic rain
#

what's funny is that it's potentially burst compatible

rotund token
#

it totally is

#

we do it in burst

rustic rain
#

meaning such morphing can be done even in runtime

#

for game specific logic

rotund token
#

that's what we do

#

it's only done in runtime for us

rustic rain
#

I can totally see the benefit for swapping bodies with corpses

#

for example

rotund token
#

side note: if you want to get real low and dirty, you can do this without dynamic type handles

#

you just have to get really into the entity component store

rustic rain
#

would rather let dth resolve it for me

pliant pike
#

I think I've got a bug I don't understand this warning Ignoring invalid [UpdateAfter] attribute on PlayerDamageSystem targeting TurretAttackSystem.

rustic rain
#

at least that would be persistent between updates

pliant pike
#

they are both literally in the same group ๐Ÿ˜•

rotund token
#

are they in the same world though

pliant pike
#

I only have one world I hope

misty wedge
#

Is there a way to run some specific code not if it's running as part of a test?

#

like a compile guard or something

misty wedge
#

basically ignore a piece of code if it's running as part of a test

rustic rain
#

hmm

#

can make it a conditional method

misty wedge
#

what's the condition

rustic rain
#

compilation define

misty wedge
#

Is there one for unity tests?

rustic rain
#

no idea

rotund token
#

it's an odd request because your tests are meant to be testing your runtime code!

#

i'm not sure [conditional] will work as it'd require a recompile

misty wedge
#

Yeah, it's an editor test that's instantiating a client system, and that system enables an input system, which I don't think is allowed in the editor

pliant pike
#

I think it might be Aline that's just breaking my whole project

rotund token
#

odd

pliant pike
#

I keep getting a nativearray error not disposed from Aline when I'm just randomly compiling

misty wedge
#

Are you using it in editor code?

pliant pike
#

nope I don't think so

#

is it possible for a entities.foreach to be running but your just not getting any debug.logs from it? ๐Ÿ˜•

#

Its just bemusing I can see the system is running, the entities.foreach does not even though the entities exist for it

#

neh mind, sorry, its always me doing something stupid using a return instead of a break before the job leahHMM

balmy thistle
#

Happens to the best of us

misty wedge
#

GetSingleton can't be a managed type?

#

and there doesn't seem to be a managed version

rotund token
#

best is just

#

EntityManager.GetComponentObject<T>(GetSingletonEntity<T>())

#

and maybe write an extension method for it

misty wedge
#

Yeah I was just confused since everything else seems to be there

#

I still don't know if I should be running my tests as editor or play mode tests

#

play mode takes forever pensive

rotund token
#

they serve different purposes

#

running nice, isolated editor tests for code coverage can help a lot on refactors and changes

#

but a set of intergration tests via play mode tests can provide better actual bug catching when things comes together

misty wedge
#

Why can't you run integration tests as an editor test?

rotund token
#

because unity doesn't tick

#

you want to simulate the actual full game

misty wedge
#

Couldn't you just tick them manually? You want the test to abort after a certain amount of time anyways

rotund token
#

tick what manually?

misty wedge
#

worlds

rotund token
#

you're forgetting about gameobjects

#

cameras

#

ui

#

coroutines

misty wedge
#

Yeah there's some stuff that's a bit trickier but I feel like ECS especially is easier to run integrations as editor tests

#

Do playmode tests do a domain reload between each test?

whole gyro
# rotund token basically what you need to do from top of my head A.SetArchetype() from B compon...

This sounds incredible useful. I currently need to do lots of entity swapping and it is quite annoying and error prone to update everything that references the old entity. It would be amazing if there was a way to change an entity's archetype in place. Even better if it could keep its old data (like translation and rotation) but only if the component exists on the new archeype. And any new components would just use the defaults from the prefab.

rustic notch
#

Hi all! I'm developing my new dots project using unity 2021.3.11f. I've got a trouble. Every first time entering the game after I recompile my code, the Unity gets no response forever until I shutdown it externally. After re-launch the unity, it can run successfully. But once I change my code and recompile, the next time when I enter the game, it gets stuck again. This is very annoying. I've checked the EditorLog, there is nothing helpful, every log seems normal. Anybody can help? Thanks!

rotund token
#

Bit off topic but curious why if you were starting a new project you would target 0.51 and 2021.3 instead of 1.0 and 2022.2?

#

as for your issue, i'd suggest hooking up a debugger when it's stuck and force breaking to see what code it's looping in

rustic notch
#

Oh! Is the 1.0 released?

#

I'd definitely try the 1.0 version. I never know that

rotund token
#

yes it is

rustic notch
#

omg. Thanks!

drowsy pagoda
#

Can I use my own BakingSystem to instantiate some prefabs before any other SystemBase initializes?

whole gyro
drowsy pagoda
#

ah right....

whole gyro
#

But yes, you can set up prefabs in baking

misty wedge
drowsy pagoda
#

Yeah, I am doing some manual bootstrapping, but running into a bunch of race conditions lol. Trying to synchronize it proper.

misty wedge
#

What race conditions are you running into?

#

I'd assume you just need to set up the scene loading systems first, tick them a few times to load your scenes, then instantiate everything else

drowsy pagoda
#

Yeah, it's simple stuff, just wanted to funnel it all into one place so in case I need to bootstrap more stuff, I'd just drop it in that basket instead.

misty wedge
viral sonnet
#

this whole entity swapping thing would be somewhat easier when ecb createEntity would return valid entity ids

viral sonnet
#

i think the problem is with parallel creates

rotund token
misty wedge
#

Also how do you even do that from a playmode test? I thought controlling the editor playmode state is only possible from within an editor test

rotund token
#

1 being load game, enter, save quit, load save

#

the 2 other are loading and faking things like player not spawning for a while etc

misty wedge
#

I'm kind of trying to figure out how I want to set it up. Either domain reload between playmode tests, don't domain reload between playmode tests and dispose and rebuild ECS state, or run it all in editor tests

#

I don't have a lot of gameobject logic

rotund token
#

why do you need domain reloads

#

can you not enter play mode, exit play mode, enter play mode

#

without your game blowing up

misty wedge
#

Doesn't re-entering playing do a domain reload?

rotund token
#

no

#

well not these days

misty wedge
#

Really? I always get one when hitting play

rotund token
#

since most people turn off domain reload

misty wedge
#

Eh, I doubt that

#

It's on by default, and people like to use static state

rotund token
#

it's highly recommend tot urn off domain reload with entities

#

it significantly speeds up your iteration time

#

it's recommended by unity

misty wedge
#

I think that depends on how often you change code vs how often you enter play mode

rotund token
#

it's in the documentation to do

#

on the the first installation page

misty wedge
#

Maybe for entities, but not for "normal" unity

rotund token
#

i'm not talking about normal unity, we're in the dots channel

#

normal people use a lot of statics

misty wedge
#

I know, I wasn't sure if you were talking about dots exclusive when you said "most people"

rotund token
#

fair

misty wedge
#

Anyways, can you just change the playmode state in a playmode test? What does that do if you run the playmode test standalone?

rotund token
#

i havent run a standalone in years

#

so i cant remember

misty wedge
#

I don't really plan to, but I'm guessing that's editor only functionality

rotund token
#

too time consuming to make a build to run tests

#

we have QA for that ๐Ÿ˜„

#

i suspect from what i understand

#

it'd work the same way though as editor

misty wedge
#

It'd restart the player?

rotund token
#

it doesn't really leave play mode it kind of just resets it (maybe let me test)

misty wedge
#

Huh

rotund token
#

so play mode tests runs it's own scene

#

then loads your scene into it

#

(this caused some issues with world startup time for me originally, i had to tweak some stuff)

#

here let me just run our tests quickly

#

i havent done this in like a year

#

(we run all these tests on dedicated machines anytime someone puts a pull request up)

#

(no one actually runs them themselves unless they fail)

#

yeah it never left playmode

misty wedge
#

In the editor?

rotund token
#

yes

misty wedge
#

How are you resetting the ECS state then?

rotund token
#

im not doing anything

#

i hit play

#

it does it

misty wedge
#

And it resets between each test?

rotund token
#

            // We want any error/exception to cause us to stop the test straight away
            // Otherwise we could get in a situation where the test never ends
            Application.logMessageReceived += (condition, trace, type) => {
                if (type == LogType.Error || type == LogType.Exception) {
                    _fail = true;
                }
            };

            yield return WaitForInit();
            yield return RunTests(true);
        }```
#

this is my test

#

WaitForInit waits for an event from
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
that's in our actual game

#

and RunTests just calls
StartGame
Save&Quit
LoadGame
Save&Quit

misty wedge
#

So all tests in RunTests are ran on the same ECS world state?

rotund token
#

no

misty wedge
#

I still don't understand what is disposing the world state then

rotund token
#

๐Ÿคทโ€โ™‚๏ธ

#

no idea

misty wedge
#

If I have two test files, and one loads the scene, loads my client and server world, and then another test without setup in a second file runs, the world is still there

#

I know with editor tests you can change the current editor play state (even if I can't for the life of me find the documentation for it right now, I saw it earlier...)

rotund token
#

well all our tests

#

shutdown the previous world

misty wedge
#

By just disposing it?

#

I'm guessing just in a test teardown function or something

rotund token
#

StartGame creates world

#

Save&Quit destroys world

#

it's just normal app cycle

misty wedge
#

Alright, then it makes more sense. I thought from the way you described it you were entering and exiting playmode in the tests and resetting world state that way (which would probably still be pretty fast with no domain reload on playmode entering)

rotund token
#

(i did think it entered/exited play mode, but yeah only after testing it runs it in one go)

misty wedge
#

I guess both approaches would work. Yours is faster I'm guessing, the other approach is more robust against dangling static state (which shouldn't be there in the first place)

#

I'm still not sure how I should be handling unity scene references when moving system state to singletons

#

I guess caching them with stuff like Object.FindXXX variants would work, but I'm not sure if that's the best way

#

And alternative would be to have a single monobehaviour with the references and fetch that, but I'm not a huge fan of that either

rotund token
#

I'm still not sure how I should be handling unity scene references when moving system state to singletons

#

what scene references? like subscenes?

misty wedge
#

If I just need something that's part of the unity scene

#

e.g. a UIDocument component for setting the root visual element or something

#

or the camera

rotund token
#

oh

#

yeah the only thing in my scene is UIDocument

#

and i just do a FindObjectOfType in the root of the 1 system that cares about it

#

could probably register it as a singleton or something

#

but i've encapsulated it's to only 1 system

misty wedge
#

Alright. It's not a huge deal, it's mainly some leftover debugging stuff that uses the old ui system to display some textures

rotund token
#

oh and my directional light just because its covenient when i open subscenes to have light

misty wedge
rotund token
#

nope

#

its converted

#

exists in a subscene

#

with all my cinemachine virtual cameras / brains etc

misty wedge
#

I thought it may have been a mainly aural experience

#

to explain the lack of a camera

misty wedge
#

Or how does the baking system handle that

rotund token
#

ah i think so

#

cant remember where the baker for it is

misty wedge
#

How is the graphics package btw? I haven't looked at it at all

rotund token
#

yeah it sin graphics package

#

HYBRID_ENTITIES_CAMERA_CONVERSION

#

you need to define that though

rotund token
rustic notch
#

Hi all, after upgrading to Unity 2022.2.0 and using Entities 1.0, I get this compile error of Havok Physics:

#

Is there any compatible Havok package available for Entities 1.0?

rotund token
#

no

misty wedge
#

I don't think it has been updated yet

rotund token
#

Havok Physics for Unity to land directly with the pre-release: we made some adjustments to the pricing of Havok Physics for Unity that required a few changes. We chose to land all of it properly directly with the pre-release and skip the beta phase. More details on pricing here.

rustic notch
#

OK, I'll switch back to Unity Physics. It's fine

#

In Unity 2022 I often got this frustrating Hold on

#

Seems it will never end

brave field
#

Loading Entity Scene failed because the entity header file couldn't be resolved. This might be caused by a failed import of the entity scene. Please take a look at the SubScene MonoBehaviour that references this scene or at the asset import worker log xxx

#

๐Ÿ‘€ Subscene still not really stable yet

misty wedge
#

Yeah that happens sometimes

rotund token
viral sonnet
#

yep, 1.0 needs a lot more clear entities cache than 0.51

rustic notch
rotund token
#

try clear your subscenes

#

apart from that really not sure

#

what is the mesh you are selecting

misty wedge
#

I have this weird issue again where my burst code throws an exception and non-burst doesn't, so annoying...

#

No idea why it pops up randomly

#

It's also ignoring all my breakpoints for some reason which really doesn't help...

molten flame
rotund token
#

oddly easier to debug

rustic rain
#

Sometimes requires also to restart editor

rustic notch
rustic rain
#

wait what

#

ComponentType doesn't have size of type?

#

bruh

spice vale
#

use typemanager

rustic rain
spice vale
#

GetTypeInfo() first

rustic rain
#

ah, forgot about that one

#

@rotund token any idea what's next?

        public static void InstantiateInto(this EntityManager em, Entity source, Entity target)
        {
            var sourceChunk = em.GetChunk(source);
            var targetArchetype = sourceChunk.Archetype;


            em.SetArchetype(target, targetArchetype);

            var targetChunk = em.GetChunk(target);


            var targetTypes = targetArchetype.GetComponentTypes();

            foreach (var targetType in targetTypes)
            {
                if (targetType.IsZeroSized) continue;

                var typeInfo = TypeManager.GetTypeInfo(targetType.TypeIndex);


                var dynamicTypeHandle = em.GetDynamicComponentTypeHandle(targetType);
                var componentData =
                    sourceChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeInfo.SizeInChunk);
                
                
            }
        }
#

Dynamic data array is readonly

rotund token
#

Literally just get the target chunk and do a memcopy

rustic rain
#

๐Ÿค”

#

but I don't know address of component data

rotund token
#

You just need to figure out if index 0 or 1 is target or source by checking entity

stone osprey
#

One think i dont understand based on the documentation and the dots source code...

A archetype chunk is 16 kb right ? Does one chunk only store 16kb of one single component : [Health, Health, Health...] or does it basically store all the archetypes components but limited to 16 kb : [Entity, Entity, Entity], [Health, Health, Health], [Transform, Transform, Transform] ?

And when we query for Entity, Health for example, is then a new chunk being created ? If the purpose of a chunk is to fill the L1 cache, than it would make more sense to load only a 16 kb chunk of only Entity, Health therefore the chunk with Transform would waste L1 cache since transform isnt needed in the query... or how is this handled ?

rustic rain
rotund token
#

You told me when I asked yesterday you knew what was source vs target

rustic rain
#

I do

#

but how do I get memory pointer

#

to component data of specific entity in chunk?

#

for selected component type

rotund token
#

Use entity type handle

#

To figure out indices of each entity

#

Then just read at the address + index * size of component

rustic rain
#

chunks are defragmented, right?

brave field
rotund token
stone osprey
rotund token
rotund token
#

It just returns a pointer to start of each component

stone osprey
#

Alright, thanks ^^

rustic rain
#

I got my targetEntity index

#

do I still have to iterate over component types

#

or maybe I can simply copy over whole memory chunk

rotund token
#

they're probably in same chunk

#

you dont need to iterate

#

you just access it directly

rustic rain
#

are components layed out per entity or per type in chunk?

#

as in, can I memcpy archetype chunk size based of index or?

rustic rain
#

ok

#

so I do need type handles to figure pointer to memory

rotund token
#

it's just going to be
byte* componentPtr;
UnsafeUtility.MemCpy(componentPtr + destinationIndex * sizeOfComponent, componentPtr + sourceIndex * sizeOfComponent, sizeOfComponent)

#

something like that

#

where sourcePtr just = (byte*)componentData.GetUnsafePtr;

rustic rain
#

how do I get componentData though?

#

var componentData = sourceChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeInfo.SizeInChunk);

#

is that it?

rotund token
#

yes

#

i copied your name

#

that should be a nativearray<byte> right

rustic rain
#

which made me questioned

#

allthough

#

judging by source it's fine

#

it's created from existing memory based of bointer

rotund token
#

what do you mean it's readonly

rustic rain
stone osprey
#

Btw what happens if an entity has theoretical so many components or so big ones that it does not fit into one chunk ?

rotund token
#

you will crash

stone osprey
#

So there is actually a component (size) limit ? Unity does not handle such cases and increases the chunk size for example internally ?

rotund token
#

chunk size is fixed

stone osprey
#

Well kinda interesting... i think such cases will never occur but however.

rotund token
#

i've put more than 16kb on a single entity accidently

#

it's not hard with a buffer

#

though it has to be kind of intentional

#

(was trying to fully fill a chunk)

#

you won't crash in editor i should say, it will just error telling you

stone osprey
#

Hmmm... i could probably also crash it some day.
There tons of items in my game, recipes and other inventory/player related stuff.
When i attach that data to the player itself it could actually happen that it will blow up those 16kb at some point.

rustic rain
#

hmm

#

void* can't be added to int

rustic rain
#

right

#
            foreach (var targetType in targetTypes)
            {
                if (targetType.IsZeroSized) continue;
                var typeInfo = TypeManager.GetTypeInfo(targetType.TypeIndex);
                var typeSize = typeInfo.SizeInChunk;


                var dynamicTypeHandle = em.GetDynamicComponentTypeHandle(targetType);
                var sourceData =
                    sourceChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeSize);

                var targetData =
                    targetChunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicTypeHandle, typeSize);

                var sourcePtr = (byte*)sourceData.GetUnsafePtr();
                var targetPtr = (byte*)targetData.GetUnsafePtr();

                UnsafeUtility.MemCpy(targetPtr + targetEntityIndex * typeSize,
                    sourcePtr + sourceEntityIndex * typeSize,
                    typeSize);
            }
#

so that should be it

deft pilot
#

this might not be related to dots, but i think dots is causing it

rotund token
#

now run it and crash

#

๐Ÿ˜„

deft pilot
#

this method is being called by OnCreate by a system

rustic rain
#

right

deft pilot
#

is it possible that its being called so early that tilemap hasn't been initialized yet?

rotund token
#

default behaviour of entities is to initialize world before scene has loaded

deft pilot
#

i see

#

crap

rotund token
#

you can override this behaviour easy enough

deft pilot
#

oh okay cool was about to hack around this

rotund token
#

add
UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD

#

to your defines

#

this is the default bootstrap

    {
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void Initialize()
        {
            DefaultWorldInitialization.Initialize("Default World", false);
            GameObjectSceneUtility.AddGameObjectSceneReferences();
        }
    }```
#

(will be disabled with that define)
just copy/paste it and change BeforeSceneLoad to AfterSceneLoad

rustic rain
#

damn, how can I test this feature quick? ๐Ÿ˜…

#

I don't have anything setup for it

#

oh I know

rotund token
#

just create 2 entities

#

1 empty

#

1 with a translation

#

run it

rustic rain
#

yeah

rotund token
#

i forgot there's kind of a side effect

#

your subscenes won't auto load

#

i've disabled this behaviour long ago so i forget about this

#

the world needs to be created before MonoBehaviour.OnEnable runs for subscenes to be auto loaded

deft pilot
#

technically...

#

i could just hack around this

rotund token
#

just use OnStartRunning?

deft pilot
#

thats one way

#

or create an entity with a tag

#

thats like

#

"create my shit"

#

and capture it on all the systems

#

would prefer not to do that

#

so gonna test OnStartRunning first

#

or...

#

or i just calculate world coordinates

#

without using tilemap

rotund token
#

stops simulation/presentation updating

#

until the subscenes i need have loaded

#

(and now handles if you open/close them at runtime when it nukes your entities for a few frames)

#

just a universal, yep I need these subscenes before I can start playing

deft pilot
#

nice gotta create my own impl of something like this eventually

#

thanks for the example

rustic rain
#

ok, instantiation works

#

now gotta do shared comp part

rotund token
#

i'm not certain how you do that if your shared components are managed

rustic rain
#

wait a second

#

hmmm

#

I feel like

#

there's an easier way to achieve it

#

๐Ÿค”

#

well

#

managed components do work

#
            var em = state.EntityManager;
            var e = em.CreateEntity(typeof(Translation));
            var kek = em.CreateEntity(typeof(LocalToWorld), typeof(Transform));

            em.SetName(e, "TestTargetEntity");
            em.SetName(kek, "TestSourceEntity");

            em.SetComponentData(kek, new LocalToWorld { Value = float4x4.identity });
            em.SetComponentObject(kek, typeof(Transform), new GameObject().transform);

            em.InstantiateInto(kek, e);

I tested it this way

#

gotta try it bursted

rotund token
#

im not seeing a managed component?

rustic rain
rotund token
#

oh you mean Transform

#

how are you copying that?

rustic rain
#

no burst though

rotund token
#

i didn't even expect managed components to be accessible this way

rustic rain
#

no, i checked inspector

#

they are same

#

Same object

rotund token
#

wonder if they're just stored as a collection of pointers in a chunk

#

i never really thought about how they were stored

#

so you just memcpy the pointer

#

makes sense

#

what i don't understand is how they'd pin this

rustic rain
#

Probably index

#

to managed array

rotund token
#

oh yeah

rustic rain
#

at least, that's what I would do

rotund token
#

yep that's totally what happens

#

it's same as scd

#

now you mention it i do recall seeing this implementation

deft pilot
#

whats the main culprit for something like this to happen?

#

tried to move things to OnStartRunning

#

and for some reason its not creating any entities

#

and its doubling up on the gameobject scene entity for some reason

#
        protected override void OnStartRunning()
        {
            Debug.Log("OnStartRunning PlayerResourceSystem");
            this.playerAddGoldQuery = EntityManager.CreateEntityQuery(typeof(PlayerAddGoldComponent));
            this.playerAddLivesQuery = EntityManager.CreateEntityQuery(typeof(PlayerAddLivesComponent));

            var entity = EntityManager.CreateEntity();
            EntityManager.AddComponentData(entity, new PlayerAddGoldComponent() { Value = StartingGold });
        }
#

pretty much all its doing

rustic rain
#

is there attribute similiar to BurstDiscard

#

but vice versa?

rotund token
#

i think the opposite is BurstCompile?

#

i don't get it

rustic rain
#

I need log message to know

#

if it's bursted or not

rotund token
#

you use burst discard for this

#
IsNotBursted(ref isNotBursted);

[BurstDiscard]
private void IsNotBursted(ref bool isNotBursted)
{
    isNotBursted = true;
}```
#

something like that

rustic rain
#

ah, forgot about that trick

late mural
#

does terrain work with entities yet, or still not?

late mural
rustic rain
#
    [BurstCompile]
    public static class TestKek
    {
        [BurstCompile]
        public static void BreakStuff(ref EntityManager em, ref Entity a, ref Entity b)
        {
            em.InstantiateInto(a, b);
            BurstCheck();
        }

bruh, why direct call not getting bursted?

rotund token
#

You should get a warning why

#

(pretty sure you can't do that)

rustic rain
#

bruh

#

now it bursted

#

after 4 recompiles

#

well

#

managed comps copied over fine

#

with burst

#

nvm

#

I'd dumb

#

I started test before burst compiled

#

๐Ÿ˜…

#

and no, shared comps didn't copy

deft pilot
#

@rotund token kill me cs private void Start() { var defaultInjectionWorld = World.DefaultGameObjectInjectionWorld; defaultInjectionWorld.GetExistingSystem<GridSystem>().Initialize(); defaultInjectionWorld.GetExistingSystem<PlayerResourceSystem>().Initialize();

#

how i hacked around it

#

removed OnCreate/OnRunning from all systems

#

and just made a mb call them

#

(made it a method on the system)

late mural
#

probably find ive asked this before (sorry if i have....), but is there any builtin way to convert a regular array to a native array fast? Either that or get mesh vertices as a nativearray to begin with (basically just tryna convert mesh data to be in pointer arrays using those fast bursted job parallel for loop thingies)

spice vale
#

There is UnsafeUtility.PinGCArrayAndGetDataAddress() and UnsafeUtility.ReleaseGCObject() if you want to use a normal array's pointer in a job

minor sapphire
#

so in here, they explain there are two ways to deal with MeshData, the old way, based on copying arrays of data, and the new way built with dots and jobs in mind

#

it's a little bit of messing around with to get it sorted in your head but that should get you most of the way there

late mural
#

ok fascinating, dots may make things faster but wow it always makes what is usually 3 lines of code suddely become 10, if not more lol

minor sapphire
#

yes, for mesh manipulation it's very worth it

late mural
#

dont really think im manipulating a mesh, just tryna convert the data to be in pointer arrays lol

spice vale
late mural
rustic rain
#

@rotund token so, I found this

            foreach (var targetType in targetTypes)
            {
                if (!targetType.IsSharedComponent) continue;
                var handle = em.GetDynamicSharedComponentTypeHandle(targetType);

                var sharedComponentIndex = sourceChunk.GetSharedComponentIndex(handle);

                var access = em.GetCheckedEntityDataAccess();
                var store = access->EntityComponentStore;
                
                store->SetSharedComponentDataIndex(target, targetType, sharedComponentIndex);
            }
rustic rain
#

feels like I'm not doing it best way though

#

as in, no safety or anything

late mural
spice vale
#

Why do you think so?

late mural
#

wait nevermind, i misread it, sorry lol

rustic rain
#

yep, tons of errors

spice vale
#

It's just pinning the managed array (not changing location) and building a nativearray from that

#

then you can dispose it to release the managed array again

late mural
#

oh ok fascinating

rustic rain
#

๐Ÿ”ฅ

#

looks like I did it

#

Entity instantiation into existing entity

#

burst compiled

spice vale
#

btw Issue, wouldn't EntityManager.SwapComponents() also work? just swap the components with an empty entity?

#

oh, nvm, they must have same components

#

How is this even possible? Assert.IsNotNull(instance); // runs this line fine Assert.IsFalse(instance == null); // Throws here

late mural
#

ok i managed to get this working (i think?), but how would i do it for triangles? ```cs
VertsLooping VertJob = new VertsLooping();
VertJob.RWVerts = RWVertices;

                    using (var dataArray = Mesh.AcquireReadOnlyMeshData(TriMesh))
                    {
                        var data = dataArray[0];
                        var Verts = new NativeArray<Vector3>(TriMesh.vertexCount, Allocator.TempJob);
                        data.GetVertices(Verts);
                        VertJob.Verts = Verts;
                    }

                    JobHandle VertHandle = VertJob.Schedule(TriMesh.vertices.Length, BatchSize);
#

there aint any GetTriangles function it appears....

rustic rain
spice vale
#

I do?

rustic rain
#

oh, hm

spice vale
#

instance is a gameobject, only possibility is if they did something weird in equals overload i guess

mild ledge
#

I have more of a architectural question. How would you guys make a dots based mechanic where you can have many different modifiers on projectiles. Think how the binding of isaac works. A item can add fire damage to your shot and another can add splitting on impact and a third adds bouncyness. Would I have to make a component and a system for each modifier or how can I aproach this ?

coarse turtle
late mural
dense storm
#

Anyone here got samples on how to use new input system with dots directly from input actions?

coarse turtle
spice vale
# mild ledge I have more of a architectural question. How would you guys make a dots based me...

It really depends on the kind of modifier what is best. If its just a damage type modifier, all that is required is basically an enum alongside the damage. For the projectiles I would probably have one system that handles the movement and collision detection, maybe the same system reads some metadata about the projectiles and handles bouncing and spawning of more projectiles if the splitting modifier.

mild ledge
#

@spice vale " reads some metadata about the projectiles and handles bouncing and spawning of more projectiles if the splitting modifier." But what is this metadata exactly ? A component ? Wont this result in a bunch of if(HasSplitOnImpact) if(HasBounce) etc etc ?

spice vale
#

Yes, or you could make the projectile movement system spawn different events when it collides based on the modifiers and let separate systems react to those. But Imo why would you have a separate system for bounce? to me that seems like it should go in the movement system, its just a redirection of the velocity.

mild ledge
#

I'm not opposed to having the bounce be done in the same system, but how do I "notify this system" that I have picked up the bouncy bullets power up

#

Add a component to all bullet entities and then what? Do a if check in the system ?

spice vale
#

yes why not?

mild ledge
#

I dont know why not.... I'm not experienced in dots at all. It's why Im asking

#

seems somehow redundant to be checking on possible thousands of bullets each time if we have a power up picked up or not

spice vale
#

when you add the bouncy component to some projectiles, these projectiles will end up in a separate chunk, so in your movement system you can just check what kind of chunk you are processing atm and do the conditional on chunk level rather than per entity.

#

by using an IJobChunk

mild ledge
#

interesting. I was planing on having the bullets be pooled, so picking up a modifier will work on "non-active bullets" and when the active ones return to the pool they will get the new modifiers

spice vale
#

if the bullets are entities you don't gain anything from pooling

mild ledge
#

you dont ? I know there is no garbage when you create entities but surely there must be some cost ?

spice vale
#

I haven't done any performance testing but to my knowledge it is very cheap to create entities, and pooling is not advised for

mild ledge
#

do you have a link to resources going into why pooling is not advised ?

spice vale
mild ledge
#

thanks

rustic rain
rotund token
#

Nicely done

stone osprey
#

Btw hat happens if i delete an entity in the first archetype chunk ?
Will the next entity land up in that spot ? Or will that spot stay "unused" for ever ?

spice vale
#

the last entity will take its spot

stone osprey
#

Yeah but... the last entity from all chunks ? Or the last entity from the chunk i deleted it from ?

spice vale
#

from the chunk it was deleted from

stone osprey
#

Yeah but in this case the chunk has a unused spot ? Is that going to be unused for ever ? Im not sure if my question was well defined enough...

But each archetype has a list of chunks. Lets say our archetype has 5 of them, all of them are full...
Now we remove an entity from the first chunk. Is now the last entity from the fifth chunk moved into the first chunk and takes its place ?

spice vale
#

Assuming the five chunks has an entity capacity of 100 each, when we delete the first entity of the first chunk, the entity that is last in the first chunk (index 99) will be moved to to the first spot (index 0)

#

Note that this index in the chunk is not the same as the index inside the entity struct

rustic rain
stone osprey
#

Yeah but than we have a gap in the first chunk since there now 99 used entities in there when there can actually fit 100 into...
And my question is, will this gap fill up when we add more entities ? Or will that chunk have one unused spot forever ?

rustic rain
#

that's how it avoids fragmentation

spice vale
#

it will fill up

rustic rain
stone osprey
#

Ah finally, thanks... i just began to believe that at some point we could have like 5 chunks with only 5 used entities in it while the other 95 are still unused... that would be kinda bad

spice vale
#

Chunks of same archetype are not guaranteed to be next to each other

rustic rain
#

but that would be the result of removing entities

#

and you'd need to create enough for 5 chunks first

#

potentially

#

at some point in the future, we'll have chunk GC

#

๐Ÿคฃ

stone osprey
#

I mean... wouldnt it be smart to move the last entity from the last chunk into the removed spot ?
Would take the same amount of processing power and would instantly fill up the void being left over... so we will never have holes in our chunks... once the last chunk is empty, it could be disposed

spice vale
#

actually, maybe thats how they do it, now I became unsure.

rustic rain
spice vale
stone osprey
#

^

#

Because its the same effort and doesnt create ANY gaps

rustic rain
#

wha?

#

I literally said that this is what it does

#

kek

stone osprey
#

"but only inside chunk"

rustic rain
#

just not among whole archetype, only among chunk

stone osprey
#

Probably a communication problem exists here

mild ledge
#

what if you remove the last entity in a chunk ?

rustic rain
mild ledge
#

so it's wasted space

rustic rain
#

yes

mild ledge
#

so why not move the last entity from the same archytype from the last non full chunk to that spot

stone osprey
#

^

mild ledge
#

if I understood genar correctly

stone osprey
#

Thanks, thats better explained

rustic rain
#

idk

stone osprey
#

Therefore, we would never have any gaps at all, wuuuu party

rustic rain
#

that's the task for unity

mild ledge
#

then again finding the last not fully filled chunk might be troublesome

#

do chunks have a isFull property ?

stone osprey
#

Not really... with that mechanic you would exactly know that the last chunk is always the one with space in it

#

I bet they have an array somewhere, so its a direct operation... not that complicated to get the last chunk then

rustic rain
#

here's the question

#

why it's probably not that simple

#

when you remove entity

#

it's only checking current chunk

mild ledge
#

I'm still very unsure how to design my bullet mechanic. What I want is basically what The Binding of Isaac does. Pick up a item -> Change bullet behaviour

rustic rain
#

so if you remove frist entity in chunk. You need to fill that slot

#

and you also suggest to fill that chunk from all other chunks?

#

based on which one is not filled?

#

sounds hella expensive

stone osprey
#

Not from all the other chunks, from the last one. That shouldnt be much more expensive. And the gap avoidance comes also in handy since it increases the cache friendliness

#

( You can stuff more of that current chunk into the l1 cache )

mild ledge
#

again how do we know this isnt what unity does under the hood?

stone osprey
#

No idea, its all blank speculation but pretty funny

rustic rain
#

it's all C#

#

with comments

#

kek

mild ledge
#

can you like not kek on every other line? If reading the code is so simple go read it, comeback and end the discussion

spice vale
#

checking right now, looks like they move the last entities in the same chunk

#

would love to know why they decided on this.

#
// Move component data from the end to where we deleted components
var startIndex = chunk->Count - patchCount;
ChunkDataUtility.Copy(chunk, startIndex, chunk, indexInChunk, patchCount);
ChunkDataUtility.CloneEnabledBits(chunk, startIndex, chunk, indexInChunk, patchCount);
var clearStartIndex = chunk->Count - batchCount;
ChunkDataUtility.ClearPaddingBits(chunk, clearStartIndex, batchCount);
rustic rain
#

I'd say

#

the reason behind it that if you do structural change on other chunk

#

it'll do order version and change filter version change

#

causing systems that rely on it run again on all entities in chunk

spice vale
#

But you don't need to tick version of you just move them no?

rustic rain
#

you do

#

it's order version

spice vale
#

but data is same

rustic rain
#

order isn't

#

references are invalidated

#

(kind of)

spice vale
#

they are regardless

mild ledge
spice vale
#

no you need a job, system does nothing in itself

rustic rain
#

all systems run on main thread, in very precise order
To run code in parallel you need to schedule a job, yes

mild ledge
#
     public void OnUpdate(ref SystemState state)
     {
         var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI);
 
+        // WithAll adds a constraint to the query, specifying that every entity should have such component.
+        foreach (var transform in SystemAPI.Query<TransformAspect>().WithAll<Turret>())
         {
             transform.RotateWorld(rotation);
         }
     }```
#

So this will run for each Turrent

#

on the main thread

rustic rain
#

this is mainthread only

#

yes

mild ledge
#

so if I want to multithread my system

rustic rain
#

you need to create a job

#

take a look at IJobEntity

mild ledge
#

I would schedule a IJobEntity or IJobChunk from that system

rustic rain
#

it's very simple to implement, codegen based job

rustic rain
#

fun fact, none of actual code you wrote in OnUpdate is really executed xD

#

only codegen based on it will

mild ledge
#

you mean that it gets compiled down by the burst compiller etc

rustic rain
#

not really, it gets codegened with .net code generators

#

they get codegened into other methods

#

smth like this

#

and they are actually what gets called

mild ledge
#

I..see

misty wedge
#

You can also just look at what was generated after the compiler ran in your IDE

#

I think that makes it a bit clearer

mild ledge
#

So.... what ECS gives me in terms of perf over lets say a Job with transform access is that entities are neatly stores and order in memory

rustic rain
#

what is it called?

#

right

viral sonnet
#

data layout is only 1 part of entities. the data layout makes it easy to multi thread. the biggest performance gain is from burst.

rustic rain
#

I heard Raid Shadow legends chose ECS exactly for a reason, so that they keep project easy to mantain over time

pliant pike
#

I'm really starting to miss being able to select objects in the scene view while running, I have an errant cube sitting in the middle of scene no clue where its came from leahWTF

pliant pike
#

I'm on 0.51, does it work in 1.0 alpha then

rustic rain
#

yeah

pliant pike
#

is it difficult and a lot of trouble to upgrade

rustic rain
#

yeah

#

I'm still upgrading

#

xD

#

Lost quite a lot of functionality, took at lot to restore

#

still haven't gotten all of it back

pliant pike
#

yeah I think I'll stick with 0.51 for now

#

it seems like its better to just start a whole new project with 1.0

#

although I could just create a new project in 1.0 and then transfer scripts over one by one ๐Ÿค”

balmy thistle
rustic rain
#

it's because I heavily relied on RenderMesh

#

and since it's gone... welp

#

xD

balmy thistle
#

Thanks, just like to help people know what they're getting into before they start an upgrade attempt

rustic rain
#

I do need help though, because I just can't understand the idea behind RenderMeshArray and MaterialMeshInfo

#

var mesh = rma.GetMesh(mmi);
for example this is 100% of all times is null

#

so I temporarily rely on this var mesh = rma.Meshes[mmi.Mesh - 2];
Which also doesn't work all the time

misty wedge
#

What is the intended way to signal another system in a high performance way now that state should exist on components? a NativeStream?

spice vale
#

Native stream can only be written to once, I'd use a list or a custom collection instead if you want to be able to write from more than one other system

misty wedge
#

You need to re-create it after writing to it once? thonk

spice vale
#

after you end the for each index you can't open that index again

misty wedge
#

Not even if I close it?

spice vale
#

close?

misty wedge
#

There's a function to signal that reading has ended

spice vale
#

.EndForEachIndex()

misty wedge
#

That one

spice vale
#

yeah if I remember correctly you can't open that index again

#

only for reading

misty wedge
#

But a single thread can share the reader right?

spice vale
#

I mean you can read in parallel too

misty wedge
#

I just need something to signal to another system that something has happened, but I'd rather not create entities for this

#

I guess an alternative would be to compile a function pointer and store that in the component

spice vale
#

do you need a list? why not just set a system's singleton

misty wedge
#

It's a method atm called by another system that takes arguments, and it can be called multiple times per frame

spice vale
#

so if you don't need to write to this in parallel i'd go with a nativelist on a component on the system's entity

misty wedge
#

Sure, that'd be possible, but then anything that can grab that list could also clear it for example

spice vale
#

Yeah that's unavoidable i guess

misty wedge
#

I'll try the function pointer route and see how I like it

#

Nevermind, the function uses managed types ๐Ÿ˜…

#

list it is

#

I guess the "classical" way of avoiding this issue is making the native list private in the component and adding methods to it, but the DOTS crusaders would probably object to that

spice vale
#

I was going to suggest that, but realized that the system would not be able to clear the list then

misty wedge
#

Sure, if the component is inside the system, then it has access to the fields

spice vale
#

Oh

misty wedge
#

Alternative would be to put it outside the system and make it internal

spice vale
#

but internal is quite broad

misty wedge
#

Yeah, that's why I'm putting it in the system ๐Ÿ™‚

spice vale
#

well if that works that's excellent

misty wedge
#

I also like the namespacing more that way

#

e.g. MySystemName.State

#

instead of MySystemNameState

#

It's the same thing the ECB systems do, e.g. EndSimulationCommandBufferSystem.Singleton

spice vale
#

But wait, It doesn't work?

#

State must be public

misty wedge
#

State can be public inside the system

spice vale
#

and if you want to hide something inside state, that needs to be private, hiding it from both the system and anything else.

misty wedge
#

You're right, my bad, I was thinking the other way around

#

e.g. accessing private state on the system inside the component inside the system

viral sonnet
misty wedge
#

How do you work with them though? You need to recreate them each frame?

viral sonnet
#

yes

misty wedge
#

Write everything, then read?

viral sonnet
#

yeah

misty wedge
#

so with e.g. WorldUpdateAllocator or something