#archived-dots

1 messages Β· Page 267 of 1

rotund token
#

that simply auto fires existing events if it's already been triggered

rustic rain
#

I don't really see your point

#

you mean I should just do some Method

#

which will add something to List

#

and then do some logic of triggering code itself?

rotund token
#
    {
        private event Action<bool> myEvent;
        private bool initialized;

        public event Action<bool> MyEvent
        {
            add
            {
                myEvent += value;
                if (initialized)
                {
                    value.Invoke(true);
                }
            }
            remove { myEvent -= value; }
        }

        protected override void OnCreate()
        {
            initialized = true;
            myEvent.Invoke(true);
        }
#

is one way you can tackle it

#

(where bool is _playerInput etc)

#

apart from that

#

dont call code like this in OnStart

#

maybe call it on OnStartRunning instead

rustic rain
#

yeah

#

I thought so

#

hmmm

#

that's a very curious one

                myEvent += value;
                if (initialized)
                {
                    value.Invoke(true);
                }
#

didn't know it was even possible

#

and microsoft manual never even mentioned it

#

lol

rotund token
#

you're not the first person i've talked to who hasn't realized you can have custom event implementations

#

some pretty experienced devs haven't known this

rustic rain
#

overall events aren't very popular

#

at least

rotund token
#

i feel like in regular c#/oop they are pretty popular

rustic rain
#

It's hard to find tutorials from mainstream ppl

#

which will explain them well

rotund token
#

i just let rider teach me everything πŸ˜„

rustic rain
#

hmm, under what circumstances Entity can change?
Basically I want to save player entity in field OnStartRunning and then use it

#

Do I need certain checks or it'll remain same through all cycle of World?

rotund token
#

Entities will never change

#

Unless you destroy it

void wadi
#

hi guys, when i press play in my dots project the cubes disappear, i can get them to stay if i select 'convert and inject' but my understanding is that unity should render an entity.. i have the entity rendering package installed. Can i ask for help here?

rotund token
#

what render pipeline

covert lagoon
void wadi
covert lagoon
#

I know that to start with you can check the "Package Manager" window for the presence of the "Universal RP" package in your project

void wadi
covert lagoon
#

The material's name, if it's the default material, or at least the material's shader's name, should contain "URP" iirc

void wadi
#

seems right i think

covert lagoon
#

Yes

#

Are there errors or warnings in the console?

void wadi
#

none

covert lagoon
#

Do you have the NetCode package installed?

void wadi
#

yes i do

covert lagoon
#

Then I think I know what the issue is

#

You need to create a subscene GameObject, give it a component called something like "Convert To Client Server Entity," and put your cubes inside that subscene

void wadi
covert lagoon
#

I think so

rotund token
#

oh yeah if you have netcode that entity has converted into wrong world

#

good call

void wadi
#

nice it works! thank you so much

i removed the netcode package

sorry one lastquestion... im trying to find some basic docs/tutes on dots/ecs just so i can learn the basics, is there anyone any of you would recommend?

rotund token
#

I can't really recommend anyone as I've never read a tutorial for dots but I would at the very least recommend checking out the samples

rustic rain
#

I really dislike the idea of having system in Update for sole purpose of doing authoring

solemn hollow
rustic rain
#

yep

#

that's what I have been busy with

#

hmm

#

is there any reason why during Start of Mono, some entity is not initialized?

#

var player = inputController.GetSingletonEntity<PlayerTag>();
Trying to get playerEntity during Start

#

in mono

coarse turtle
#

the subscene hasn't fully streamed yet to the world if you're using subscene authoring?

rustic rain
#

hm

#

if subscene is in edit mode it works fine

#

that's no good

#

is there a way to get access to GetSingletonEntity method without getting systems first?

#

yeah, there is

#

weird one ngl

#
            var player = World.DefaultGameObjectInjectionWorld.EntityManager.CreateEntityQuery(typeof(PlayerTag
                ))
                .GetSingletonEntity();
rustic rain
#

Is it a practical idea to create system with empty update for each mechanic?

solemn hollow
#

not sure what you mean by empty update? are you talking about making every system reactive?

rustic rain
#

thus my OnUpdate is empty

solemn hollow
#

should be perfectly fine

viral sonnet
rustic rain
#

it's not called from update

#

not even from systems

#

kek

#

It's fine, I found a way

viral sonnet
#

some form of yielding in an IEnumerator Start() also works

rustic rain
#

hmmm, is there a way to run SharedComponent filter in query through excluding?

#

as in

#

I have 100 shared component types

#

I need to query through 99 of them

#

and only leave 1 untouched

pliant pike
#

probably best to use an if or a tag

calm edge
#

is it possible to disable batching for objects using hybrid renderer?

solemn hollow
# rustic rain and only leave 1 untouched

This sounds like you actually dont want to use a shared comp. should be much better to have a normal component and filter out with an if like @pliant pike suggested. is this about your room sharedComp?

rustic rain
#

yeah

#

I don't see any other option but shared component

solemn hollow
#

so you probably want to not process the room where the player is at?

rustic rain
#

not really

#

player is irrelevant

#

It's about switching rendering

#

mostly

solemn hollow
#

well anyways its about an "active room"

rustic rain
#

yeah, kind of

solemn hollow
#

so like calabi suggested you could filter it with a tag. give all entities that are in the activeroom a tag. that should be really really cheap since you can do that with a batchcommand and a query with your RoomSharedCompData. There wont be any memory copied around since you split up your chunks with the SharedCompData accordingly.

misty wedge
#

InvalidProgramException: Invalid IL code in WorldGeneration.Systems.WorldTextureCreationSystem:CreateDebuggingTextures

#

What have I done

rotund token
#

bad things 😱

rustic rain
#
            var desc = new EntityQueryDesc()
            {
                All = new[] {ComponentType.ReadOnly<InSystemComponent>(),},
                None = new[] {ComponentType.Exclude<DisableRendering>(), ComponentType.Exclude<StarTag>(),},
                Any = new[] {ComponentType.ReadOnly<CompanionLink>(), ComponentType.ReadOnly<RenderMesh>(),}
            };
            _toDisableQuery = GetEntityQuery(desc);
#

wat

rotund token
#

still having the issue?

#

from memory you shouldn't use excludes in EntityQueryDesc

#

though I thought it had a specific error

rustic rain
#

well I had to split it into 2 different queries

rotund token
#

why?

rustic rain
#

cause error remains

#

and I don't see any other option of having Any in entity query

rotund token
#

Assert.IsTrue(ComponentType.AccessMode.ReadOnly == type.AccessModeType);

#

i think it's failing on your None line

#

because you're using Exclude

rustic rain
#

oh

rustic rain
#

I should have used ReadOnly

#

I didn't realise it

digital kestrel
#

does anyone's hybrid renderer take up like 1-2ms per frame even when there are no entities in your scene?

hot basin
#

turn off checks

digital kestrel
hot basin
#

everyone for jobs and burst

rotund token
#

jobsdebugger as well

viral sonnet
#

what does jobs debugger even do?

#

The JobsDebugger feature detects and reports many classes of concurrency programming errors (e.g. race conditions, missing synchronization, etc.) which are traditionally very difficult to isolate and reproduce. The JobsDebugger can detect these issues statically, so rather than getting a catastrophic bug once every million runs, you get an error 100% of the time saying "hey, this code could potentially produce a catastrophic bug". If it's spamming the console, that's usually a sign of a bug that should be fixed

digital kestrel
viral sonnet
#

To answer myself but I must say, I always have it on and never ever had even one message by it. Curious that it should detect race conditions. I had one, nothing was shown. Is the debugger overriden with NativeDisableParallelForRestriction?

rotund token
#

dependency warnings are all jobs debugger

#

NativeDisableParallelForRestriction
yes this turns off the safety

#

you are telling the jobs debugger that you aren't causing a concurrency issue, ignore it

#

You are trying to write to X, system Y is using blah blah

viral sonnet
#

alright, then I will turn it off even though it doesn't add too much overhead. Build speed and editor speed with leak/safety checks off is nearly 1:1

wraith urchin
#

So i was searching for a ecs rigidbody constraints implementation, and so after a lot of research i found the solution on this server actually, the soultion it is in the sample projects of unity https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/PhysicsSamples/Assets/Demos/4. Joints/Scripts/Conversion/PhysicsJointConversionSystem.cs

From here you need to 4 files, 1 is the system that converts the constraints to physics joints, and the other 3 are the components and more to perform the game object entity's conversion. The files are :

  • Limit DOF Joint.cs
  • Base Joint.cs
  • Based Body Pair Connector.cs

And the system

  • Physic Joint Conversion System

The key concepts are: physics body, constraint, joints.
Also exist another solution, take an SystemBase and use PhysicsMass Component in the ForEach query, next in the loop take the atribute InverseInertia and set all te axis xyz to 0f, and that works fine to, but i dont know the cost on the perfomant, because you are doing this in OnUpdate.
Hope this will help anothers to implement an easy solution on the future :3

GitHub

Contribute to Unity-Technologies/EntityComponentSystemSamples development by creating an account on GitHub.

white island
#

how do you make a nativearray of arrays, or some sort of workaround

#

my job's output is an array

#

Wait, does my job even need to be parallel? I'm doing this job for each entity that meets certain conditions...

#

ugh I dont know

rustic rain
#

but I never actually looked through them, so can't help

white island
#

Ok so. I have a system, that checks through a list of entities and if they have a flag that says they need a path recalculated, it recalculates their path. Is an IJob appropriate for the pathfinding job?

rotund token
#

to do your actual pathfinding?

#

probably not unless you only have a couple of things pathfinding per frame

#

it's potentially one of the costlier operations and benefits the most from separating into threads

rustic rain
#

oh yeah, I do remember comparison of non-job vs job vs job+ecs vs job+ecs+burst

rustic rain
#

How to disable SharedComponent filter on query?

#

I set it and then I want to unset it

white island
#

InvalidOperationException: The Unity.Collections.NativeList`1[System.Int32] has been declared as [WriteOnly] in the job, but you are reading from it.
what.

#

how do I uh, make it readable.

#

how did this even happen.

rustic rain
#

can you show the code?

rotund token
white island
#

uuh here

NativeList<int> closedList = new NativeList<int>(Allocator.Temp);

//...

closedList.Add(workingNode); //add to closed list
NativeList<int> validConnections = getValidConnections(connectionsSource, workingNode, closedList); //find all open connections

//...

static NativeList<int> getValidConnections(NativeArray<Connection> graph, int source, NativeArray<int> cList)
        {
            //loops through connections and finds all valid ones that start at source
            NativeList<int> vConnections = new NativeList<int>(Allocator.Temp);
            foreach (Connection c in graph)
            {
                //Loop through connections and find valid connections
                if ( //HERE
                    c.from == source && //if right source
                    c.isTraversable() && //if it is traversable
                    !cList.Contains(c.to) //if c.to not in the closed list
                )
                {

Im not sure what the needed code is

rustic rain
#

poggie woggie

rotund token
white island
#

a... pointer?

rustic rain
white island
rustic rain
#

error might be there

white island
#

No I put a //HERE where the runtime tells me the error is

#

Although I believe it’s talking about the !cList.Contains()

#

getValidConnections is defined outside of Execute, but that hasnt been a problem before

rustic rain
#

What I mean is that your job fields can literally be faulty

white island
#

closedList is not a job field, it's defined inside of Execute

rustic rain
#

what about cList

white island
# rustic rain what about `cList`

cList is a parameter of a function.
static NativeList<int> getValidConnections(NativeArray<Connection> graph, int source, NativeArray<int> cList)

rustic rain
#

I mean, how is it defined

#

your error tells that it's WriteOnly

white island
#

closedList is passed into cList at NativeList<int> validConnections = getValidConnections(connectionsSource, workingNode, closedList); //find all open connections

#

and closedList is defined simply as NativeList<int> closedList = new NativeList<int>(Allocator.Temp);

#

what im saying is how is it defined as readonly

#

i mean writeonly

rustic rain
#

Any idea how multiple shared components affect chunks?
If I will use about 4 shared component types just for game logic, is it going to hurt anything in any way?
Mostly I want them for filtering

#

which I use extensively

rotund token
#

well it could

#

depending how many variations you have

#

every unique combo will be a different chunk

#

btw you are limited to 8 shared components max

rustic rain
#

oh

rotund token
#

and by default in a subscene unity adds like 6 ^_^'

rustic rain
#

feels bad

rotund token
#

worse in netcode

#
Physics - PhysicsWorldIndex
Entities - BlobAssetOwner, SceneSection, SceneTag , EditorRenderData
Netcode - SharedGhostTypeComponent, SubSceneGhostComponentHash, GhostDistancePartitionShared```
#

create 2 of these in a subscene with netcode

#

and you hit 9 components and get an exception

rustic rain
#

πŸ‘΄

rotund token
#

(I've already talked to unity about this)

rustic rain
#

kinda wish a type of component

#

just for filtering option

rotund token
#

I believe it's called ISharedComponentData πŸ˜„

rustic rain
#

so you can for example use enums

sharp stump
#

Okay, super basic question, sorry I am a noob, but do I have to use the Hybrid Renderer in ECS? Is that the only path to rendering entities?

rustic rain
#

no, but it's the easiest one

#

if you want you may just not install it and instead render entities any way you want

#

or not render them at all

#

if your goal is to have some ECS subsystem outside of world space

sharp stump
rustic rain
#

well, any way you can do render in Unity is your option

#

attaching GameObjects (which btw hybrid already does for certain kind of components)

#

rendering through Graphics API

#

or maybe you have some other 3rd party solution

#

Hybrid does all of it for you

#

so I wouldn't be interested in doing it any other way

sharp stump
#

Oooooh! cool! Thanks I just looked up the graphics api. That looks like the right door to help me understand rendering.

rustic rain
#

Good luck, it's not simple

sharp stump
#

Does the hybrid renderer require you use GameObjects? I am interested in a project using no OOP at all. I am still trying to grasp a lot of the nuance

rustic rain
#

no

#

but DOTS is considering conversion workflow as crucial part of itself so

#

basically, authoring through game objects is almost a must

muted field
#

think im going to ditch job system for time being, might try a gpu for my algorithm instead, dealing with pointers is just annoying me

sharp stump
#

hmm, thats a shame. Sounds like there are some limitations if I do not use GameObjects and the Hybrid Renderer

rustic rain
#

game objects need to exist only during development

#

during runtime they cease to exist

#

unless ofc you tie some system to it

sharp stump
#

is that just for sanity sake so you can use the other unity tools and so forth?

rustic rain
#

which I do a lot rn, since there are no alternatives to many classic Unity components

#

for example LineRenderer

muted field
#

on the roadmap they are going to tie game objects to it for the 1.0 release

#

what ever that will mean is a mystery however

honest plinth
# sharp stump hmm, thats a shame. Sounds like there are some limitations if I do not use GameO...

It should be perfectly fine to spawn do manual setup for the Hybrid Renderer. Conversion kind of only sets up a base set of components, and we have some exposed API you should be using to set that up from code. If it turns out we want to refactor something there (we have done a few times already).
But the simplest way is GO authoring and prefab spawning for sure.

If you don't want to author using GO you need to write a lot of the editor tools yourself somehow

misty wedge
#

If I'm storing an e.g. UnsafeMultiHashmap inside a component, is it possible to add to that map in parallel? Or do you always need to do AsParallelWriter before scheduling the job?

rustic rain
#

AsParallelWriter is for parallel writing

#

Adding*

#

without it you'll get errors

solemn hollow
#

There is probably no way to get a Generic ChangeFilter for a query going right? im getting this error :
"Type Attribute cannot be used with WithChangeFilter as generic types and parameters are not allowed"

#

Id like to not filter inside a job with checking whether the Chunk has changed since that would mean id schedule it every frame despite it beeing very rare to occur.

misty wedge
#

e.g. 100 entities reference a single entity that has a component with the hashmap, and I want all 100 entities to write something to the hashmap in parallel

#
var hashmapFromEntity = GetComponentDataFromEntity<HashMapContainer>(false);
Entities.ForEach((Entity e, in EntityReference reference) => 
{
  var referencedEntity = reference.Entity;
  var hashmap = hashmapFromEntity[referencedEntity];
  var parallel = hashmap.AsParallelWriter();
  parallel.TryAdd(...)
})
#

as an example

#

I've never looked at how the parallel writers work in detail, but I think it should be fine in theory?

#

The only thing I'm not 100% sure on is if the code-gen handles setting the thread index properly, but I guess I can just test it

solemn hollow
#

@misty wedge Havent tried any of that so i cant help with that implementation but i know @rotund token made a DynamicHashmap which sounds like what you want

misty wedge
#

iirc you can't write to it in parallel though

solemn hollow
#

ah alright sry. out of interest what are you building that makes the parallel write necassary?

misty wedge
#

It's not necessary, I was just wondering 🀷

uncut rover
#

Since it's based on a dynamic buffer it will be on an entity. So I think you actually would need to go out of your way to write to it in parallel. Most likely you will work in parallel on multiple entities but each entities will be worked on in a single thread and so the buffer will. The read/write dependency should take care of the rest.

solemn hollow
#

yeah hes working the other way around though. not looping over the entities with the hashmap.

misty wedge
#

the dynamichashmap is not writable to in parallel. I was asking about an hashmap inside of a component earlier, and if you can do AsParallelWriter inside a job

solemn hollow
#

i have a very similiar usecase actually. what i do is to loop over all Entities with the Hashmap in a job and then have another manual chunk interation inside of the job that fills the hashmap

#

that makes it parallel without the need to write to the same hashmap in parallel

#

i think that was also what @uncut rover meant?

rustic rain
#

hmm

#

how large can component be in terms of fields?

#

I am afraid my Pathfinding component is about to get

#

5 more fields of float3

#

kek

viral sonnet
#

that said, UnsafeContainers in IComps are problematic because of disposing them

#

I would also suggest to go with tertles DynamicHashMap. Did so myself

misty wedge
#

I use systemstatecomponents to clean up the unsafe containers

viral sonnet
misty wedge
viral sonnet
#

TBH, and I'm sorry to say that but that's bad design and really slow, with lots of stalling

misty wedge
#

Writing to a container in parallel is bad design?

viral sonnet
#

NativeHashMap, NativeList in naive approach. yes

misty wedge
#

Then why even have it

viral sonnet
#

I don't know πŸ™‚ unity thought why not without any further implications. The problem is the stalling of Interlocked. It's so bad, that even a single thread can be faster

#

and that doesn't even count the frame timing multiplied by the amount of worker threads

#

it's bad design because the parallel writer has bad design

misty wedge
#

For my use case using a single thread is almost assuredly faster (the majority of entities are writing to the same container), I just wanted to know if it was possible

#

You are right, if all of them write to the same container, there is no way using multiple threads can be faster (since they would all just block each other)

viral sonnet
#

it's possible but yeah, I don't think you'd be happy with the results. alternatives are better

#

but sadly they are all a bit more complicated/involved

misty wedge
#

It's not a performance bottleneck or anything like I mentioned further up, I just wanted to know if the code-gen handles setting the thread index if you call AsParallel inside of a job πŸ˜…

viral sonnet
#

there's no codegen involved for [NativeSetThreadIndex] which the parallel writers use

misty wedge
#

What are they talking about here then?

viral sonnet
#

Not sure, technically it could be code-gen or DI. /shrug

misty wedge
#

Regardless, I think the intention is to use AsParallelWriter outside of the job and pass the struct into it

viral sonnet
#

yes

#

which is a problem in itself because you don't know which hashmap you're gonna use

misty wedge
#

Yep

#

I don't think it's an issue for my project though, I was just wondering

rustic rain
#

hmm

#

is there a way to pack some kind of simple data

#

into bytes

#

and then reinterpret it upon unpacking?

#

I want to create a dynamic Buffer of action queue

solemn hollow
#

is dynamicbuffer.reinterpret all you need?

rustic rain
#

probably not

#

no, it's not that

#

here what what I think about

#

I want to have dynamic buffer of struct with 2 fields
ComponentType
ByteArray

#

So upon Adding to buffer I write some data to that ByteArray

#

let's say I want to pack 3 floats and 1 Entity in it

#

then once other system gets to it, it unpacks it

#

and this way I will have struct based delegate

#

xD

solemn hollow
#

what i did is to not use ByteArray but define a "GenericAxis" struct (Entity and Score field). then when i want to read from a generic DynamicBuffer i reinterpret it into a GenericAxis first.

rustic rain
#

nah, it's not about AI

#

actually

#

it's more about packing data

#

this same thing can have usage outside of AI

solemn hollow
#

yes its just where i use it. just wanted to give an example

rustic rain
#

thing is, my argument list I want to pack is not supposed of certain size

#

supposed to be*

#

I want to be able to pack any amount of data, until certain byte limi

solemn hollow
#

well dyncamicBuffer wont let you add ByteArrays with dynamic size i guess

rustic rain
#

no need for dynamic

#

I need fixed size

#

thing is

#

I have no idea how any of that even works

#

xD

viral sonnet
#

when the byte array is fixed you can cast it to anything as long as you know what it is. you'd need an additional flag to know that but when the byte array has a dynamic length it can't reside in the bufferElement. You'd need a pointer from the bufferElement to the dynamic byte array

rustic rain
#

I am fine with fixed size

#

I just want to know what I need

viral sonnet
#
   public class MySystemTime
   {
      [FieldOffset(0)]public ushort wYear;
      [FieldOffset(2)]public ushort wMonth;
      [FieldOffset(4)]public ushort wDayOfWeek;
      [FieldOffset(6)]public ushort wDay;
      [FieldOffset(8)]public ushort wHour;
      [FieldOffset(10)]public ushort wMinute;
      [FieldOffset(12)]public ushort wSecond;
      [FieldOffset(14)]public ushort wMilliseconds;
   }``` example of fixed size layouts
rustic rain
#

but how can I even make it?

#

do I need

#

fixedByteList?

solemn hollow
#

should you even make it in the first place? πŸ˜„

rustic rain
#

well, I decided I do want to have action queue

#

I just don't see my AI without it

viral sonnet
#

same method really but it doesn't need any byte arrays

#

you just take the size of the largest struct you would have

#

and others are just living inside this block and are reinterpreted

rustic rain
#

well, yeah. That's kind of how I imagined it

#

I just write as many bytes as I want, and then read them

#

upon certain limit ofc

#

What I ask is what type do I write my arguments

#

let's say I have 3 float3 and 1 Entity

viral sonnet
#

the common denominator is a byte

#

when my head math is correct that would be 44 bytes.

#

so you can allocate 44 bytes and reinterpret to the struct you mentioned

rustic rain
#
    public struct QueuedAction : IBufferElementData
    {
        public ComponentType type;
        public FixedBytes126 args;
    }
#

so kinda like this?

viral sonnet
#

yeah sure

rustic rain
#

hmmm

#

and how do I write my argument list to it?

#

while bursted

#

and the same way

#

read

viral sonnet
#

you cast the args to the struct. (best to use a ref) and write the values to the struct. same goes for reading.

#

writing and reading from more than 1 thread would cause a race condition

#

in that case Interlocked has to be used

rustic rain
#

isn't it already thread safe?

#

since you can't access same component from 2 jobs if one is written to

viral sonnet
#

if you don't use BufferFromEntity for random lookups, it's safe

rustic rain
#
        private struct KekWorks
        {
            public float3 kek;
            public float3 works;
            public float3 yep;
            public Entity lul;
        }
        
        protected override void OnCreate()
        {
            var queue = new QueuedAction();
            queue.type = ComponentType.ReadOnly<GetToPoint>();
            var args = new KekWorks()
            {
                kek = new float3(1,2,3),
                works = new float3(1,2,3),
                yep = new float3(1,2,3),
                lul = Entity.Null
            };
            queue.args = (FixedBytes126) args;


        }

So this doesn't let me cast it just like that

#

and I need to be able to do it in bursted job

viral sonnet
#

google gives plenty of good answers for casting structs to bytes: ```byte[] getBytes(CIFSPacket str) {
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];

IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;

}``` code looks different in unity c#. Marshal is UnsafeUtility

#

so write a method that casts it to FixedBytes126

solemn hollow
#

I am trying to get a generic Effect System to work. I dont want to use PolyComponents for it because i actually want to have control over the ordering of EffectTypes.

What i plan right now is to have an EffecthandlerSys<T> that loops over Effects<T> and calls Update on them. T implements IEffect which contains the Update Method. The Update Method just calls a UpdateFunction inside a static UtilityClass Update<T>. Now in my theory i can implement the diffrent update logic inside the Utility class for each type of effect i create.

Sounds like i should try it?

coarse turtle
viral sonnet
#

good idea, much easier

viral sonnet
solemn hollow
#

No i am talking about the update order of systems. For example I want to be able to update Effects that modify attributes on a character before updating Effects that are based on Attributes on the Character

#

So PolyComponents that would call Update on any Effects randomly would be bad.

#

Noob follow up question. If i had an Update<T> and an Update<ConcreteEffect> would Update<T> only always be called if i did not define the ConcreteType?

#

sry i probably worded that very wrong.

#

So to say would Update<T> function as a standart implementation?

rustic rain
viral sonnet
#

as long as ConcreteType exists in your code the according system is created

rustic rain
#

I think I'm on a right path

#

but I don't get what's next

solemn hollow
viral sonnet
#

otherwise I can't say much about the effect design. I believe you are over complicating it but maybe your game design requires it?

#

yeah then nothing should be created

solemn hollow
coarse turtle
rustic rain
#

huh

coarse turtle
#

it's a bunch of casting, but i imagine queue.args just stores FixedBytes126 and isn't a pointer

rustic rain
#

it does work

#

how do I cast it back?

viral sonnet
#

most games now use raw stats. stuff like int -> mana/spell hit or that sort is really oldschool. also quite hard to balance

solemn hollow
#

and why not support everything everywhere all at once. what could go wrong

coarse turtle
viral sonnet
#

I still say go for it! πŸ™‚

solemn hollow
#

sry discord didnt let me write "/s" πŸ˜„

viral sonnet
#

if it works it'll be cool

solemn hollow
#

What i am really doing right now is coding for a game that i want to make in the future in a game i am making right now xD

#

The one right now is much easier and could be done non generic but the next one will be huge :S

#

Its a bad idea i know

#

Its just some Systems like AI and Abilities i want to do more generic

viral sonnet
#

let's play the question game. you use effects, I want to have an absorb buff for 9 seconds that can absorb 100 damage. when the 100 damage are absorbed i want to have an explosion that damages badies and heals allies. if the buff just expires nothing will happen. how will you handle it in a very capsuled environment?

rustic rain
#

huh, looks like it works

#
            KekWorks lul = default;
            Job.WithCode(() =>
                {
                    var queue = new QueuedAction();
                    queue.type = ComponentType.ReadOnly<GetToPoint>();

                    var kek = stackalloc KekWorks[1];
                    kek[0] = new KekWorks()
                    {
                        kek = new float3(3, 2, 1),
                        works = new float3(1, 2, 3),
                        yep = new float3(5, 6, 7),
                        lul = new Entity() {Version = 2, Index = 500}
                    };

                    queue.args = *(FixedBytes126*) (byte*) kek;

                    lul = UnsafeUtility.As<FixedBytes126, KekWorks>(ref queue.args);
                })
                .WithBurst()
                .Run();

            Debug.Log(lul.kek);
            Debug.Log(lul.works);
            Debug.Log(lul.yep);
            Debug.Log(lul.lul);

How can I check whether it gets bursted for real?

viral sonnet
#

green bar in timeline profiler

#

πŸ™‚

coarse turtle
#

lol - you can also look at the burst inspector and find the job

#

see if the instructions get vectorized

solemn hollow
coarse turtle
#

i wonder if Job.WithCode(()= > {}) will generate IJobFor structs in the future - can't recall if they're still generating IJob πŸ€”

rustic rain
#

IJob

#

kek

solemn hollow
#

Its not that my AbilitySystem has everything there could ever be yet but it is extremely easy to extend and reuse

rustic rain
#

so I assume it gets bursted

#

so problem

#

good

#

now the hardest part

#

how do I read it xD

#

Let's say I pack KekWorks

#

into DynamicBuffer

#

my ActionQueue system reads current index of this buffer and adds component

#

to entity

#

now next system needs to read it...

solemn hollow
rustic rain
#

hmm

#

I guess, I'll just read buffer

#

same way

viral sonnet
viral sonnet
solemn hollow
#

The effect is applied when an ability hits a target. DamageEvents are in a DynamicBuffer on the Target. The effect could tick every frame if it has tickrate. so i could implement a function that polls for damageevents on the target and for example does another 10 damage. was that the question?

#

and yes abilties are tied to the damagesystem i use. Dependencies in ECS are a major painpoint for me ATM

#

Especially when AI gets involved which tends to read from Components splattered around multiple assemblies its really ugly

#

I havent seen any discussions on how to handle Encapsulation of Systems (in term of big Systems like AI, Abilities, Pathfinding etc). Looking at Physics it doesnt look like i want to do it like that. would be copying around alot of data for each system

solemn hollow
#

I would love if you could somehow define sth like componentAlias. So you could link up Systems with the Same Components but diffrent internal names

#

idk

viral sonnet
#

Yeah, answered my question. I went a pretty different route because I wanted insane scaling so some things like DynamicBuffers where a no go

digital kestrel
#

does anyone's inspector (game object inspector) mess up / misalign when you add things to do ... particularly ECS related scripts

viral sonnet
#

No, never had that issue. Are CustomEditors involved?

digital kestrel
#

I'm using a few packages so probably but none on that game object

viral sonnet
#

do all GOs look like this then or just this one? also which unity version?

digital kestrel
#

yes if you add/remove components to them, 2020.3.31f1

#

i'm updating it to 2020.3.34f1 to see if it fixes the issue

viral sonnet
#

I can't remember seeing that in 31f1. Maybe even skipped it, right now I have 33f1 myself. Yeah, try an update, hopefully it will fix it.

digital kestrel
#

yeah seems like it's better now

#

it was either the version or the act of upgrading that fixed it lol

#

thanks

viral sonnet
#

hopefully it stays that way. that bug would annoy me to no end

solemn hollow
viral sonnet
#

because of race conditions I bundled them all. took me quite a while to come to the final implementation. i basically have 3 arrays now. 1 with source entities, 1 with target entities and 1 with the combat events itself. all 3 are then used for 2 hashmaps where the key is source/target-> combat event. then a system goes over the entities and polls events which are then processed. so in that sense, only 1 system is actually receiving damage events. other systems are only aware of damage events because I write trigger flags from this system

solemn hollow
#

So until you get Disable Components you cant skip the polling work right?

viral sonnet
#

even with I wouldn't be able to. the polling itself is stupid fast. no issue there

solemn hollow
#

I cant either because of sth like Dynbuffer.IsEmptyIgnoreFilter not existing

#

Well but the systemoverhead is what always annoys me

viral sonnet
#

the whole didChange is sketchy anyway. just getting a write handle increases the version so IMO it's useless

solemn hollow
#

yes i agree. alot of work and overhead needed to make it work right

viral sonnet
#

which system overhead? chunk iteration with ComponentTypes has hardly any

solemn hollow
#

hm 0.03-0.05 ms for me most of the time when using dynbuffers. havent looked into it too much

#

but i definetly got too many systems running πŸ™‚

viral sonnet
#

i mean that can add up but that's not much.

solemn hollow
#

no but would be nice to skip it when those systems are designed to run once every 100 frames πŸ˜„

viral sonnet
#

how many do you have?

solemn hollow
#

oof dont make me count. my AI alone runs 60atm

#

so i guess im at 130 or sth

viral sonnet
#

oh wow πŸ˜„

#

maybe you should look into component groups and manual updating

solemn hollow
#

AI takes 2ms on main

solemn hollow
viral sonnet
#

if you don't need your systems to run every frame that's the way to go. best to look into the FixedUpdate group or whatever they called it

#
[UpdateAfter(typeof(FixedStepSimulationSystemGroup))]
public class Stage1SystemGroup : ComponentSystemGroup
{
}```
#
    public partial class AIThinkSystem : SystemBase```
solemn hollow
#

oh lol i know about ComponentSystemGroups ^^sry

viral sonnet
#

there's an override for ShouldUpdate in the component group. I used this once when I wanted to create a fast-forward/timelapse in a prototype. Basically have lots of updates in 1 frame

#

but same goes for something when you want to control the flow how and when you update it

solemn hollow
#

my AI systemgroup updates every frame but a TimeSlicer/Loadbalancer based on ChangeFilters enables only Systems that are needed for a subset of the agents

viral sonnet
#

sounds funky

solemn hollow
#

was super easy and ultra effective πŸ˜„

#

i have a component "LoadBalanced" which at the start of the frame is written to for all chunks i wanna update. then each AI system has a changeFilter for LoadBalanced

#

So first frame i write to 10 chunks in loadbalanced. second frame into the next 10

viral sonnet
#

is this a chunk component? you might want to look into those

solemn hollow
#

not necassary i think. i only need to declare write access. i dont have to actually write.

#

im not sure how to manage chunk components correctly yet.

#

am afraid of having to have some bookkeeping for them

viral sonnet
#

don't you need the same for the LoadBalanced? How does the system know which chunks to process next?

#

and if you add/remove the structural change overhead is quite significant

solemn hollow
#
public partial class LoadBalanceTickSys : SystemBase
{
    private EntityQuery loadBalanceQuery;
    private const int loadBalancedChunkCount = 10;
    private NativeList<ArchetypeChunk> loadBalancedChunk;
    private EntityQuery alwaysUpdateQuery;
    
    private int updateIndex;
    
    protected override void OnCreate()
    {
        alwaysUpdateQuery = GetEntityQuery(ComponentType.ReadWrite<DisableLoadBalance>());
        loadBalanceQuery = GetEntityQuery(
            new EntityQueryDesc
            {
                All = new[] {ComponentType.ReadWrite<LoadBalanced>()},
                None = new[] {ComponentType.ReadOnly<DisableLoadBalance>()}
            }
        );
        
        loadBalancedChunk = new NativeList<ArchetypeChunk>(Allocator.Persistent);
        
    }

    protected override void OnUpdate()
    {
        var alwaysUpdateChunks = alwaysUpdateQuery.CreateArchetypeChunkArray(Allocator.TempJob);
        var chunks = loadBalanceQuery.CreateArchetypeChunkArray(Allocator.TempJob);
        
        loadBalancedChunk.Clear();

        for (int i = 0; i < loadBalancedChunkCount; i++)
        {
            if (updateIndex > chunks.Length - 1)
            {
                updateIndex = 0;
            }
            loadBalancedChunk.Add(chunks[updateIndex]);
            updateIndex++;
        }
        loadBalancedChunk.AddRange(alwaysUpdateChunks);
        Dependency = new LoadBalanceJob
        {
            chunks = loadBalancedChunk,
            loadBalancedHandle = GetComponentTypeHandle<LoadBalanced>(false)
        }.ScheduleParallel(loadBalancedChunk.Length, 1, Dependency);

        alwaysUpdateChunks.Dispose(Dependency);
        chunks.Dispose(Dependency);
    }

    protected override void OnDestroy()
    {
        loadBalancedChunk.Dispose(Dependency);
    }  
}```
#
[BurstCompile]
    private struct LoadBalanceJob : IJobFor
    {
        [ReadOnly] public NativeList<ArchetypeChunk> chunks;
        public ComponentTypeHandle<LoadBalanced> loadBalancedHandle;
        
        public void Execute(int index)
        {
            var loadBalanced = chunks[index].GetNativeArray(loadBalancedHandle);
        }
    }```
#

literally all

#

sry its not really cleaned up yet. naming could be much better

viral sonnet
#

np, I see what it does. could be some edge cases where chunks are skipped, processed 2 times when chunks are created/destroyed, no?

solemn hollow
#

yes true. wasnt something i needed to consider. more updates dont produce wrong results in my case

viral sonnet
#

anway, really nice solution

solemn hollow
#

feels hacky but simple

viral sonnet
#

on the topic of chunk comps. they are pretty much the same as icomps, api is nice and straight forward. what one could do is write back the tick when the chunk should be next updated for example. still would require some form of polling though

solemn hollow
#

it would be so cool to be able to write own filters for queries...

#

imagine the performance gains you could achieve by rejecting chunks super early based on arbitrary logic

viral sonnet
#

CreateArchetypeChunkArray has lots of untapped potential

solemn hollow
#

need to look at it at some point. atm i try to stay as highlevel as possible to not break things on package updates.

solemn hollow
#

So back to my question from earlier :

{
    public static void Calculate<T>()
    {
        Debug.Log("base implementation");
    }
    
    public static void Calculate<Speed>()
    {
        Debug.Log("custom implementation");
    }
}```

tried it now but doesnt work as i thought it would 😦
#

Compiler Error says both functions have the same signiture. that was what i was hoping wouldnt happen.

viral sonnet
#

would renaming Calculate<T> into BaseCalculate<T> make sense?

solemn hollow
#

well that sure is possible but the point is i cannot do a implementation for <Speed>, <Health>,<...>. Noob error. havent understood how Compiler works with Generics yet

#

I would need to name a CalculateMethod for each implementation. On the other hand when i think about it most implementations are rather similar anyways

viral sonnet
#

generics is like a form of code-gen. instead of writing a method for each type the compiler does it for you. that leaves you with overlaps though like in your case

solemn hollow
#
public struct Attribute<T> : IComponentData where T : IComponentData,IAttribute
{
    public float Value;
    public float baseValue;
    public float previousValue;
    
    public void Calculate()
    {
        AttributeCalcUtility.Calculate<T>(this);
    }
}```
viral sonnet
#

overrides in classes are much easier to handle but then burst doesn't work

#

seems like a good "base" πŸ™‚

solemn hollow
#

well the problem is i wanted to do some kind of smart switching on the type here. if i have it this way i cannot rename the functions in AttributeCalcUtility to sth like CalculateSpeed

#

Maybe i am forced to do a switch on the type ?

viral sonnet
#

seems so

#

switches in burst, as long as every case is implemented are translated to a jump table so super fast

solemn hollow
#

and since every system always takes the same branch it should be np anyway right?

#

branch prediction will always be right

viral sonnet
#

i think so but I'm no expert on this. I can only say as much that it will be no problem performance wise

solemn hollow
#

Still i hate switches just for the fact that i need to edit in 2 files when i add sth new... wanted to work with a partial static here to be able to implement the function in the same file i define the component. I guess i would have to use codegen to do that now. I havent ever set up Codegenerators so im not sure if it is worth the hassle? PhilSA got it working somehow.

white island
coarse turtle
coarse turtle
# white island yes

I don't see an associated job for this? Would be hard to tell what the problem is πŸ€”

white island
#

hang on i have to stop this code making an infinite loop

viral sonnet
solemn hollow
#

I bet id run into another roadblock i dont see yet though πŸ˜„

#

I just want to reduce dublicate code as much as possible. if id implement all effects and then it turns out i need to change sth in the architecture i would have to touch every single one of those systems spread across multiple files for each effect...
using generic Systems i can change the Architecture really fast. sure its more complicated to design but i find it more maintainable. It also will enable my gamedesigner to create effects in a EditorTool without me.

calm edge
#

@solemn hollow if you do a switch on the type in a generic it will get compiled out to only the correct case

solemn hollow
calm edge
#

oh

solemn hollow
#

typeof is not allowed in burst

calm edge
#

maybe check the latest docs for burst because I remember something about using generics in a special way

rotund token
#

All the interesting discussions happen when I'm asleep

rustic rain
#

You can awlays respond to earlier message

#

better late than never

#

xD

solemn hollow
rotund token
#

5:30 atm, really need to sleep in

solemn hollow
rotund token
#

Australia

#

So you know, opposite side of the world from everyone

solemn hollow
#

Well good thing programmers Day/Night cycle is random anyways

rotund token
#

Can you just use is keyword manarz

#

Effectively let's you do type checks in burst without boxing

solemn hollow
#

hmm how?

dont i need to do

switch(typeof(T))
  case : T is Speed
rotund token
#

Let me get out of bed because I'm not going on my phone

solemn hollow
#

hmm ill be here later too. so dont hurry

rotund token
#

too late you already got me up

#
    {
        public static void Calculate<T>(T attribute)
            where T : unmanaged, IAttribute
        {
            switch (attribute)
            {
                case Speed speed:
                    Calculate(speed);
                    break;
                case Meth meth:
                    Calculate(meth);
                    break;
                default:
                    // default calcation
                    break;
            }
        }

        private static void Calculate(Speed speed)
        {
            Debug.Log("custom implementation");
        }
        
        private static void Calculate(Meth meth)
        {
            Debug.Log("custom implementation");
        }
    }```
solemn hollow
#

great ill feel bad the rest of the day now because of some guy on the other side of the glode πŸ˜„

rotund token
#

or in if form

#
    {
        public static void Calculate<T>(T attribute)
            where T : unmanaged, IAttribute
        {
            if (attribute is Speed speed)
            {
                Calculate(speed);
            }
            else if (attribute is Meth meth)
            {
                Calculate(meth);
            }
            else
            {
                // default calcuation
            }
        }

        private static void Calculate(Speed speed)
        {
            Debug.Log("custom implementation");
        }

        private static void Calculate(Meth meth)
        {
            Debug.Log("custom implementation");
        }
    }```
#

(haven't read your problem just looked at the double generic code issue you posted)

solemn hollow
#

oh damn thats perfect. i was to stupid to pass attribute.

#

Thats what happens if you don't have a background in Coding πŸ™‚

rotund token
#

i dont have abackground in coding πŸ˜›

solemn hollow
#

Im sure at some point u did exactly the same mistake then!

rotund token
#

electrical engineer + masters in cryptography

#

that was a good use of money 🀣

solemn hollow
#

well atleast problemsolving skills are universal i guess

rotund token
#

oh yeah problem solving has always been my strength

#

i actually only recently considered using 'is' to type check in burst

#

cant remember what my use case was though

solemn hollow
#

I kinda feel bad to not ask some of those questions on the forum. Those discussions will be buried forever.

rotund token
#

that's an interesting point

#

its a little silly how often i've googled something and I find the solution on the forums posted from my past self 😐

solemn hollow
#

I still cant get it to work..

public partial class AttributeCalculationSys<T> : SystemBase
where T : IComponentData,IAttribute
{
    private EntityQuery attributeCalculationQuery;
    
    protected override void OnCreate()
    {
        attributeCalculationQuery = GetEntityQuery(ComponentType.ReadOnly<Attribute<T>>(),ComponentType.ReadOnly<AttributeModifier<T>>());
        attributeCalculationQuery.ResetFilter();
        attributeCalculationQuery.AddChangedVersionFilter(ComponentType.ReadOnly<RecalculateAttributes>());
    }

    protected override void OnUpdate()
    {
        Dependency = new CalculateAttributesJob
        {
            attributeHandle = default,
            modifierHandle = default
        }.ScheduleParallel(attributeCalculationQuery,Dependency);
    }

    [BurstCompile]
    public struct CalculateAttributesJob : IJobEntityBatch
    {
        public ComponentTypeHandle<Attribute<T>> attributeHandle;
        public ComponentTypeHandle<AttributeModifier<T>> modifierHandle;

        public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
        {
            var attributeArr = batchInChunk.GetNativeArray(attributeHandle);
            var modifierArr = batchInChunk.GetNativeArray(modifierHandle);

            for (int entityInChunkIndex = 0; entityInChunkIndex < batchInChunk.Count; entityInChunkIndex++)
            {
                var attribute = attributeArr[entityInChunkIndex];
                var modifier = modifierArr[entityInChunkIndex];
                
                AttributeCalcUtility.Calculate<T>( attribute);
            }
        }
    }
}
#
public static class AttributeCalcUtility
{

    public static void Calculate<T>(T attribute)
    {
        if (attribute is Speed)
        {
            
        }
    }
}```
#

The problem is that i cannot pass a parameter of Type T

rotund token
#

what's the compile error?

#

you need to restrict T in calculate

#

where T : IComponentData,IAttribute

solemn hollow
#

attribute is of type Attribute<T>

rotund token
#

umanaged*

#

as well probably

viral sonnet
#

missing the <T> on CalculateAttributesJob.

rotund token
#

public partial class AttributeCalculationSys<T> : SystemBase
where T : IComponentData,IAttribute

i'd definitely put unmanaged on this as well

rotund token
solemn hollow
#

but how to i "extract" T from attributes to pass along

viral sonnet
#

i'm pretty sure it's still needed. otherwise ignore me πŸ˜„

solemn hollow
#

its not needed. doing it in my AI systems like that too

rotund token
#

oh you mean this part
Attribute<T>

#
        where T : unmanaged, IAttribute
    {
        if (attribute is Attribute<Speed>)
        {
            
        }
    }```
solemn hollow
#

duh. i should go to bed omg.

#

Is there a way to create an instance of a generic System in the defaultworld without explicitly adding it? Some Attribute or sth?

rotund token
#

you have a generic job in here which needs to be registered with burst

#

how are you doing that?

solemn hollow
#

I'll just declare it where i create that Concrete Attribute

#

So basically above in my SpeedAttributeAuthoring

#

ideally i would like to have a single small file to write to create a new effect. but not sure if i can do that just yet

rotund token
#
    where T : unmanaged, IComponentData
{
    private EntityQuery query;

    protected override void OnCreate()
    {
        this.query = this.GetEntityQuery(ComponentType.ReadOnly<T>());
    }
    
    protected abstract GenericJob CreateJob();
    
    protected override void OnUpdate()
    {
        var job = this.CreateJob();
        job.StateType = this.GetComponentTypeHandle<T>(true);
        this.Dependency = stateJob.ScheduleParallel(this.query, this.Dependency);
    }
    
    [BurstCompile]
    public struct GenericJob : IJobEntityBatch
    {
        internal ComponentTypeHandle<T> StateType;

        // Code ...
    }
}

public class GenericImplementation : GenericBase<Menu>
{
    protected override GenericJob CreateJob() => default;
}```
#

this is my pattern for how i handle generic jobs/systems

#

i just give each an implementation and create a default job which is enough to satisfy burst

#

another developer jumps in, implements a new GenericBase they don't have to worry about setting up bootstraps, or attributes or anything

solemn hollow
#

oh that is so much smarter than i do it in my AI i think.

#

I use MakeGenericType to create instances for my Systems.

rotund token
#

yeah i hate that thing

#

this all came about to avoid having to use it

solemn hollow
#

Ah but nvm i cant do it like that for AI since a Scriptable Object defines the Types i need for the Instance

#

too much hassle to rewrite that now i think^^

rotund token
#

hmm in UnityEngine.Object

#
    public int GetInstanceID()
    {
      this.EnsureRunningOnMainThread();
      return this.m_InstanceID;
    }```
#

can anyone think why this needs to be mainthread

#

i feel like InstanceID doesn't change

solemn hollow
#

lifecycle stuff?

rotund token
#

public override int GetHashCode() => this.m_InstanceID;

#

right below it

#

its returned without a safety check

#

via gethashcode

coarse turtle
#

i think instance id only changes between project sessions*

rotund token
#

i just want to read Mesh.InstanceID

#

in a job

#

just going to work around it with GetHashCode

#

instead of using some magic

coarse turtle
#

yea i've no idea why it's main thread only πŸ€” dunno what Unity is doing on the native side to create the instance id tho πŸ‘€

mystic mountain
#

My brain is breaking. I have a component that is somehow messing up with parenting after instancing an entity. I've found that if I remove the authoring component it doesn't break, and if I add or replace with another dummy authoring component it doesn't break either. Now I've strapped all usage and references to this authoring component, cleaned the Library folder, and it still messes up. Neither of the authorings are actually even adding any component to the entity.

rustic rain
#

wdym by messing up parenting?

mystic mountain
rotund token
#
        {
            [ReadOnly]
            public SharedComponentTypeHandle<RenderMesh> RenderMeshType;

            public NativeHashMap<int, int>.ParallelWriter MeshMap;

            public EntityManager EntityManager;

            public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
            {
                var meshIndex = batchInChunk.GetSharedComponentIndex(this.RenderMeshType);
                var renderMesh = this.EntityManager.GetSharedComponentData<RenderMesh>(meshIndex);
                var instanceID = renderMesh.mesh.GetHashCode(); // This returns instanceID it just bypasses unneeded main thread check
                this.MeshMap.TryAdd(meshIndex, instanceID); // failure is fine, means already added
            }
        }```
this solved so many issues for me
#

so nice being able to pass EntityManager to jobs

#

anyway jaws those pictures look the same i have no idea what's going on πŸ˜„

#

oh wait no they dont

#

there's a hole

#

without seeing your magic component and related code can't really say much though!

mystic mountain
#
    public struct VisualStateDummy : IComponentData
    {
        
    }
    
    public class VisualStateAuthoring : MonoBehaviour, IConvertGameObjectToEntity
    {
        public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
        {
            dstManager.AddComponentData<VisualStateDummy>(entity);
        }
    }

Not much to see x)

solemn hollow
#

Is there any System that interacts with VisualStateDummy right now?

mystic mountain
#

Nope. Nothing references the authoring anymore, the dummy was never used but something I just created to see if it's something about not adding any component in the convert step.

solemn hollow
#

Just to make sure. you are on the right unity version?

#

2020.3.30 +

mystic mountain
#

Yes .33

#

But I think this has to be some weird deterministic error which is caused by some other code.

solemn hollow
#

have you cleared the entity cache?

mystic mountain
#

Yes, cleared library, sceneDependencyCache and through the menu to clear entities.

viral sonnet
#

we also support the IRefCounted interface, which (if you're careful) allows you to store a single copy of an underlying resource across all World's in your app.
What's that about?

#

When Google only has 1750 results you know you are in obscure shit

rotund token
#

let's you share resources across worlds via sharedcomponentdata

#

BlobAssetOwner inherits it for example - check it out for an example

viral sonnet
#

interesting usage, reminds me of how the GC works

rotund token
#

for example, moving colliders to a new world doesn't need to duplicate the collider memory

solemn hollow
#

Should there be a Universe Abstraction? :S

viral sonnet
#

Hm, can we use this to make a proper implementation to use UnsafeContainers in IComps?

rotund token
#

its only used in ISharedComponentData manage store

viral sonnet
#

the IRefCounted is universal

rotund token
#

its only called in ManagedComponentStore

#

When disposing or creating ISharedComponentData

#

you can make an interface with the exact same methods

#

it doesn't mean it magically works πŸ˜„

viral sonnet
#

ah, I thought I have to call them myself

rotund token
#

sure you can call release/retain

#

but there's nothing magic about this interface

viral sonnet
#

yeah, more like the idea/principle of doing this

rotund token
#

you could use your own interface and system for handling this

viral sonnet
#

having the possibility to use unsafe containers in IComps without any worries sounds like a good idea to me

rotund token
#

don't really see how you're going to do this

viral sonnet
#

sounds like a challenge!

rotund token
#

well you can't use RemoveCompoennt or DestroyEntity ever

#

until you release

viral sonnet
#

ISystemStateData can handle that problem

rotund token
#

so your strategy is to add a bunch of archetype changes

#

and if you're just using ISystemStateData can't you just dispose the container

#

why do you need to ref count it

viral sonnet
#

😦

rotund token
#

also ISystemStateData still doesn't help if you just destroy world or stop play mode etc

viral sonnet
#

the ref counting is for this case

rotund token
#

(this is actually a really good use of IRefCounted btw, you can do cleanup on world destruction)

viral sonnet
#

but sure, I get your point. πŸ™‚

#

it would be close to implement a custom garbage collector

rotund token
#

already done that for my AI ^_^'

#

blobs caused too many issues

#

just wrote my own memory management

viral sonnet
#

what happened?

rotund token
#

nothing

#

works great

viral sonnet
#

nah, I mean what prompted you to write your own memory management

rotund token
#

because i couldn't use blobs

#

and i didn't want to deal with disposing the memory individually

#

and the memory has a lifecycle of the entire worlds life

#

so i can just allocate arbitrary then clean it up all at once

viral sonnet
#

so every AI was having their own blob data?

rotund token
#

nah this is for the graph

#

all AI share the same graph memory

solemn hollow
#

Sounds like another tertleTool comming soon πŸ™‚

#

@rotund token On the subject of tools: did you manage to get your DynamicHashmap readable in the Inspector?

rotund token
#

nah never tried

#

was an enzi problem πŸ˜„

#

where i use it at the moment i have no need to inspect

solemn hollow
#

it could be a me problem too

rotund token
#

it only exists on a few singleton entities

#

for fast lookup of prefabs and a few other things

#

so i had never tried to inspect it

#

until i run into a case of needing it myself probably too lazy to look into it

solemn hollow
#

np i wont be needing it soon πŸ˜„

rotund token
#

just write add the DebuggerTypeProxy and inspect it in code via entity journalling

#

i love how i can break point on an entity field now and look at all it's components

#

has dramatically increased debugging ability

#

unity has not got enough credit for this

solemn hollow
#

true. my problem would be that someone without an IDE would need to inspect it.
I think my AI performance could actually greatly benefit from your DynamicHashMaps if id replace my DynamicBuffers with them.

#

because i allocate a hashmap in each job i schedule anyways and combine my InputAxis for each Target in there

rotund token
#

i really want to write a
FixedHashMap4096 or something

solemn hollow
#

So you can have them in chunkmemory?

rotund token
#

nah just so i can have small ones in jobs instead of Temp allocated

#

you can sometimes get a decent speedup using FixedList instead of a NativeList(Temp)

viral sonnet
solemn hollow
#

ah i see

viral sonnet
viral sonnet
#

@solemn hollow as we were talking before about effects and you mentioned a slow effect. why would you need an update for that? or rather, what would be updated?

solemn hollow
#

Each effect has a TickRate. If it is set to 0 the effect is only applied once. Its not really an Update() but an ApplyEffect(). I simplified a bit earlier

#

What i try to achieve is having effects that cost nothing while not ticking aside from needing to check if they have to tick.

viral sonnet
#

ah yeah, why not just a component tag?

#

but I dunno, solving things with tags. it's the same as polling under the hood πŸ˜„

solemn hollow
#

because effects can stack and i need to keep track which effect runs out when

solemn hollow
#

To not have to poll i have a ApplyEffect and an UndoEffect. Effects are Entities with a DynamicBuffer with references to the targets and when the targets got the effect applied

#

So i just have to loop over all appliedEffects and check whether they timed out. if so i undo the modification of the relevant Component

viral sonnet
#

my effects are all polled by tick (when they even have a tickrate). not sure if i will ever change this as my effects are entities. well more a container, it's just one big comp, every other data is in a blob

solemn hollow
#

i cant remember why i decided to do it with one EffectEntity and a Dynamicbuffer instead of many EffectEntities. I had a point there.

viral sonnet
#

I think both solutions are very valid and both have their pros and cons

#

some things are easier, some are harder

solemn hollow
#

yep. im sure it was just a convenience thing for me. but what was clear is tagging Targets was not the way to go

viral sonnet
#

my removal of effects sadly needs a structural change with SystemStateData. maybe I get around of not needing this anymore

solemn hollow
#

are you talking about destroying the effect or sth else?

viral sonnet
#

destroying the effect. well adding too

solemn hollow
#

im too lazy to do entitypooling atm

viral sonnet
#

this is pretty old code but never changed. the need was, does target have effect X, if so do something special. the method to find was so expensive so I made a global lookup table of effect types. now I can just query this hashmap if there's a certain effect on an entity

#

entity pooling doesn't have much use. my spells were using it once πŸ™‚

#

way too costly

solemn hollow
#

sadly im making a 2.5D game with 2D Bone animations

#

so my entites drag around a gameobject

#

so i guess pooling both would be adviseable

viral sonnet
#

maybe I will use it someday for the effects. But creating > 10k is such a niche case I won't bother with it

viral sonnet
solemn hollow
#

nice thx ill look into it.

#

atm i am instanciating entities that spawn a companionobject...

#

pretty expensive

viral sonnet
#

when you say companion, a gameobject, right?

solemn hollow
#

both depending on the case actually T_T

viral sonnet
#

ok πŸ˜„

solemn hollow
#

a gameobject i spawn myself to make use of animations and sometimes a companiongameobject because i just have an entity with a spriterenderer or vfx

#

For abilities its actually only the latter

viral sonnet
#

yeah, i see, we all pretty much deal with the same dumb shit πŸ˜„

#

insane scale and then -> plop some GOs

solemn hollow
#

yep and this scale in the design always makes it so much more complicated than a normal game would be xD

#

If Id use DOTS for stuff i do with monoB i bet it wouldnt be complicated at all

#

with stuff i mean reasonable gamedesign

rotund token
#

where would the fun be though

solemn hollow
#

hopefully in the game id would have finished by now πŸ˜„

viral sonnet
#

make games not engines -> yeah, hold my beer, I make uhmm something

#

I have no artist(s) so I'm not making a game anway πŸ˜„

#

the dream of using asset store art has died long ago

kindred cipher
#

programmer art is a thing. It does not mean your game has to be ugly

solemn hollow
#

soon AI will be good enough to make programmer art beautiful

kindred cipher
#

who knows. I think a lot is picking a style you can manage. Be that by creating stuff yourself or a style thats easily found in the assets store/other libraries for free or little coin.

#

then again what do I know. I write code for a living (not games) and just dabble in 3d/2d for hobby. Just installed unity for laughs. πŸ€·β€β™‚οΈ (don't even know what dots stands for as the channel name) πŸ˜…

rotund token
#

Need talented 3D artist looking for a great opportunity on the next big thing. Need AAA realistic graphics. Reimbursed by revenue share.

#

You telling me, that doesn't work?!

kindred cipher
#

glances up at channel description.. its Data-Oriented Technology Stack appearantly 😁

kindred cipher
solemn hollow
kindred cipher
#

all idea people who want to make the next MMORPG by themselves.. they just need a team of artists (and coders and animators)

rotund token
#

Unique idea, can't share super secret.

#

Fortnite with cars 🀯

kindred cipher
viral sonnet
#

that's my programmer art. at one point I just can't stomach it anymore 😦

#

whoa sorry that got big

rotund token
#

i see textures

#

already too pretty

kindred cipher
viral sonnet
#

really? thanks

kindred cipher
#

and dude I recently started playing "forgive me father". Some indie fps that got high praise. Its not that hot and the levels are really effing ugly. Like.. screw blaming that on "retro style". People still made nice stuff back in the day. Still it seems pretty succesful and many people enjoy it

#

so don't hate on yourself too much, its not productive anyway. πŸ’™

viral sonnet
#

thanks for the encouragement πŸ™‚ would it not be for my day job I'd continue with it

kindred cipher
#

I don't really code "for fun". Its just a job (not gamedev either). But I like dabbling in 3d and well.. Unity is pretty fun for prototyping and mucking about. So not doing anything serious but having fun.

viral sonnet
#

it is fun and oh so time consuming πŸ˜„

kindred cipher
#

beats being bored or wallowing in existential dread right? πŸ€·β€β™‚οΈ 😁

viral sonnet
#

for sure and much better than watching tv all day like the rest does in their free time πŸ˜„

muted field
#

how do you use this iterator from a NativeMultiHashMap ?

#

want to do a simple for loop through all elements related to the key

#

but its not clear how to use it

viral sonnet
#

do it with an enumerator var enumerator = threatTargetEvents.GetValuesForKey(mainEntity); { while (enumerator.MoveNext()) { //ref var te = ref enumerator.Current; var te = enumerator.Current;

muted field
#

oh i see

#

thanks

#

i thought iterating through data like this was slow for native containers compared to regular for loops

#

i remember reading some where that using foreach for example was not a good idea

viral sonnet
#

that was a long time ago where forEach produced garbage in mono

muted field
#

i meant for native containers not mono stuff

#

it was some benchtest some one did

viral sonnet
#

well a hashmap is not a linear array

muted field
#

oh is it not ?

#

i thought the values were in a native array

#

like key,native array <value>

viral sonnet
#

yeah but it's unsorted and has holes (potentially) so iteration is through the bucket

muted field
#

holes?

viral sonnet
#

if you remove a key

#

the gist of a hashmap

#

quite a bit more involved than just 2 arrays

muted field
#

i see

#

maybe i should opt for a <Key,NativeList<Value>> of my own so i can iterate my values easily

viral sonnet
#

it works really well though, I can assure you that

muted field
#

seems odd they wouldn't just use a list to collect all the values to me

viral sonnet
#

sadly that won't work, only with unsafe containers

#

yeah, I thought the same. most native containers could be improved in lots of ways

muted field
#

yeh the lack of not being able to have containers within containers without unsafe is one of my biggest complaints πŸ˜„

#

it would make life so much simpler

viral sonnet
#

but it's still in local space even when some elements are skipped. imagine a huge hashmap and 100s of pointers everywhere in memory

#

good chance that it will be slower then if you iterate over more values by keys

muted field
#

oh i wouldn't iterate over keys only values

#

i cant imagine when some one would iterate keys

solemn hollow
#

πŸŒ• πŸ‘‹

white island
#

how can I reverse a native list?

#

i mean I guess i dont really need to but it would be nice

viral sonnet
#

do you really wanna take the hit of the memory copy or sort? just iterate from the end to the beginning

viral sonnet
#

anyone knows a safe version to get pointers from a MB component like the animator? (unsafe code is okay! haha)

viral sonnet
#

ArgumentException: GCHandle value belongs to a different domain ... meh 😦

muted field
white island
#

Fair enough

viral sonnet
#

i want to use a NHM instead of private Dictionary<Entity, Animator> animatorLookup; so I need to get the pointer of the animator because classes won't work in NHM

#

this failed with the posted error msg

rotund token
#
        {
            [ReadOnly]
            public SharedComponentDataFromEntity<RenderMesh> RenderMeshes;```
The code I write sometimes makes me laugh
solemn hollow
#

in a good or bad way? :9

rotund token
#

well i wanted to access shared components in jobs in parallel

#

so i wrote my own SharedComponentDataFromEntity

#

now i can

solemn hollow
#

Oh wait you wrote your own SCDFE 0.o

#

gj!

rotund token
#

yes

#

its pretty simple

#

obviously it doesn't work in burst but works fine in a regular job

#

but i wanted to access shared components in jobs without main thread sync points

#
        {
            [ReadOnly]
            public SharedComponentTypeHandle<RenderMesh> RenderMeshType;

            [ReadOnly]
            public SharedComponentDataFromEntity<RenderMesh> RenderMeshes;

            public NativeHashMap<int, int>.ParallelWriter MeshMap;

            public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
            {
                var meshIndex = batchInChunk.GetSharedComponentIndex(this.RenderMeshType);
                var renderMesh = this.RenderMeshes[meshIndex];
                var instanceID = renderMesh.mesh.GetHashCode(); // This returns instanceID it just bypasses unneeded main thread check
                this.MeshMap.TryAdd(meshIndex, instanceID); // failure is fine, means already added
            }
        }```
#

my nice little job

solemn hollow
#

nice! That looks super handy

rotund token
#
    public unsafe struct SharedComponentDataFromEntity<T>
        where T : struct, ISharedComponentData
    {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
        private readonly AtomicSafetyHandle m_Safety;
#endif
        [NativeDisableUnsafePtrRestriction]
        private readonly EntityDataAccess* m_Access;


#if ENABLE_UNITY_COLLECTIONS_CHECKS
        internal SharedComponentDataFromEntity(EntityDataAccess* access, AtomicSafetyHandle safety)
        {
            m_Safety = safety;
            m_Access = access;
        }

#else
        internal SharedComponentDataFromEntity(EntityDataAccess* access)
        {
            m_Access = access;
        }
#endif

        public T this[int index]
        {
            get
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
#endif
                return m_Access->GetSharedComponentData<T>(index);
            }
        }
    }```
this is all it is - have not fleshed it out yet
#

very simple

#

technically unsafe because i'm doing a read only check but in theory as the shared component could be managed and store a class etc you could write to it

#

but yeah that's on you

solemn hollow
#

i need to learn writing my own containers too at some point it seems. I couldnt do it

rotund token
#

just like, if you call GetUnsafeReadonlyPtr() and write to it, can't help you. enjoy the crashes

rotund token
#

just adding the attribute ensures some checks (aliasing) etc are performed

solemn hollow
#

ah ok. yes i have no clue how all those checks are working. I know nothing about how to use Safetyhandles and dont dare to touch pointers yet

rotund token
#

for the most part you dont need to do anything with safetys

#

store it, make sure it's called m_Safety

#

in read methods use
AtomicSafetyHandle.CheckReadAndThrow(m_Safety);
in write methods use
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);

#

that's about it πŸ˜„

#

assign it with
DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, Allocator);
dispose with
DisposeSentinel.Dispose(ref m_Safety, ref m_DisposeSentinel);

#

thats about the whole safety system setup/use

solemn hollow
#

oh that sound easy enough!

#

whats that about :
```public T this[int index]````

#

never seen this syntax

rotund token
#

that's in array indexer

#

you know, how you access an array
myarray[1234]

solemn hollow
#

yep i just didnt know you can do it with this[]

#

i see

#

never wrote containers πŸ™‚

#

btw i get this error : Burst error BC1020: Boxing a valuetype Attribute1<Speed>` to a managed object is not supported

#

from the code we spoke about yesterday

#
public static void Calculate<T>(Attribute<T> attribute) where T : IComponentData
    {
        if (attribute is Attribute<Speed>)
        {
            
        }
    }```
rotund token
#

where T : IComponentData

#

you need to restrict it to unmanaged

#

where T : unmanaged, IComponentData

#

otherwise compiling thinks it could be a class

solemn hollow
#

yes i tried it and didnt work. but i think my error was not ristricting it in Attribute<T> struct too

#

am compiling rn

rotund token
#

needs to be restricted everywhere

#

im 70% sure this should work =S

solemn hollow
#

hmm Error is still there.

solemn hollow
#

welp im giving up on switching over type for now. Going back to good old enums...

muted field
#

πŸ€”

rotund token
#

nah that's right

#

if you have 0 elements movenext returns false

muted field
#

oh so the iterator starts before the first element

rustic rain
#

how to remove DynamicBuffer<T> from entity?

#

through RemoveComponent<T>?

rotund token
#

yep

rustic rain
#

Do you have any idea how to make Action queue in ECS?

#

I sit for 2 days already, can't figure out the way

#

I thought of packing it this way. But with this approach I can't figure out how to unpack it, without hard-coding system for it for every possible queued action.

    public struct QueuedAction : IBufferElementData
    {
        public ComponentType type;
        public FixedBytes126 args;
    }
rotund token
#

i guess question i have for you is

#

why would more than 1 system unpack it

rustic rain
#

because I don't know how to unpack it without knowing type beforehand

#

at best

rotund token
#

i mean, why is it the responsibility of more than 1 system to ever unpack it

rustic rain
#

I'd simply just pack struct into byte array

#

and then read it fully

#

then add as component

#

but I have no idea whether it's possible at all

#

UnsafeUtility.As<FixedBytes126, KekWorks>(ref queue.args);
Reading it when it's known type is simple

#

but when it's unknown...

solemn hollow
#

again im not quite sure why you dont try out PhilSA s PolyComponents. I think they work for IBufferElementData too.

rustic rain
#

I guess I'll have to try

#

well, I looked through it again - that's not it

#

My actions work with completely different data structures, so that just not gonna do it

solemn hollow
#

what kind of parameters do your actions actually need?

rustic rain
#

Literally any

#

pathfinding action requires one set

#

some other action requires completely different one

solemn hollow
#

all of my actions just take TargetEntity,AgentEntity and anything else would be handled by other systems.

#

give an example of action parameters as you would need them

rustic rain
#

pathfinding will require literally all space related components (ltw, translation, ltp and etc)

#

target finding action will require HashMap

#

it's all handled in different systems through different queries

solemn hollow
#

and you want to have a single System that handles Pathfinding,Targetfinding,Moving etc?

rustic rain
#

no, I want to have system that can queue different actions

#

let's say I want to do a complex action:
go to target 1, then to target 2, and then do a flip

solemn hollow
#

but you tag your entity with the action that should be executed right?

#

So why isnt it enough to pass: target 1, type goto ; target 2, type goto; target null, type flip

#

and your action systems then can read the necassary other data and execute their actions

#

u dont need to pass pathfinding data to the Action. you can get it from a different Component in the query of your GoToActionSys

rustic rain
#

I figured how to do chain

#

but not how to pass arguments

#

so basically

#

If I want to do queue of 3 go to actions

#

Once first go to is done, I only know type of next action

#

but not argument

#

as in, where exactly to go to

#

I can solve this by making unpacker of packed argument list for literally every system of action that can be queued

#

but I find this approach really meh

#

I guess I'd need generic abstract system

#

that will get auto generated

#

through inheritance

solemn hollow
#

what. im getting more confused by the minute ^^
why dont you have a DynamicBuffer<ActionQueue>

#

filled with structs : ActionQueue{
actionType,
actionTarget
}

#

and your AI just fills them

#

why do you need to pass along arbitrary data. you can always get the data you need when you need it later on in other systems in other components and then read from it

rustic rain
#

because action queue can consist of different actions

#

right now I am making mechanic of "jumping between star systems"

#

where character needs to get to edge of star system it is in right now, teleport to other system, and then do slight movement from edge of target system.

#

of course I can make a unique queue component that will hold all data required for this action list

#

but when I'll need another complex action

#

I'm gonna have to do it again

muted field
#

\o/ finally got my job system to work without unsafe stuff

#

took a bit of fiddling

solemn hollow
#

Yes have the AI decide what targetStarSystem you need to go one after the other.
Let it fill the Buffer with the Targets and the ActionTypes. Add the ActionType of first Action in the buffer to the Entity as a Tag. Then have the MovementSystem get all entities with that MoveAction and move it towards the target specified in The ActionQueueBuffer[0]

muted field
#

oh are you the one who mentioned utlity ai the other day?

#

i been watching some videos on it - seems like its very similar to goap

rustic rain
#

it's for player controls

#

at very least xD

solemn hollow
#

it does not matter who decides the action though. player or AI

rustic rain
#

hm

solemn hollow
#

i have implemented it this way. i just skipped the DynamicBuffer part

rustic rain
#

So you have Entity target?

#

hm

#

I do get your point rn

#

I guess I can try to figure out a way

#

to create a general argument list

solemn hollow
#

this is the tag that i add to run the Goto

rustic rain
#

yeah, I see your point

solemn hollow
#

this is what would be your actionqueue

rustic rain
#

it does make a lot of sense

#

it's just that not 100% what I wanted, as it's limited

solemn hollow
#

i have more data on there cause of debugging

rustic rain
#

in data I can send

#

So what I guess rn

solemn hollow
#

the thing is you dont want to send data. you just query it

rustic rain
#

is that I can make a struct with:
float3
Entity
ComponentType

#

and pack it in any way I want

#

then target system of ComponentType will get those float3 and Entity

#

and figure out what to do with it

#

not the best I hoped for, but still works

#

allthough...

#

it still raises a question, of how do I pass that data

#

I assume, I can just use action queue buffer as base for literally all action systems

solemn hollow
#

every actionsystem has a query like this:

#

ActionComponentTag,ActionQueue,DataActionNeeds1,DataActionNeeds2...

#

like the MovementSystem would get MovementSpeed and Path. (Path was created before by PathfindingSys)

muted field
#

umm what is this error

#

ive never seen this before

solemn hollow
#

same

rustic rain
#

ok, I like the idea behind using action queue all the time

rotund token
rustic rain
#

With it I can avoid adding ComponentTypes to Action components

solemn hollow
#
public partial class UAIFleeSys : SystemBase
    {
        protected override void OnUpdate()
        {
            
            Dependency = Entities.ForEach(
                (ref FleeAction fleeAction, ref NavDestination navDestination,
                    in DecisionActionData actionData , in LocalToWorld position) =>
                {
                    if (HasComponent<LocalToWorld>(actionData.targetEntity))
                    {
                        float3 directionFloat = GetComponent<LocalToWorld>(actionData.targetEntity).Position - position.Position;
                        Vector3 direction = new Vector3(directionFloat.x, directionFloat.y, directionFloat.z);
                
                        Vector3 targetPos = new Vector3(position.Position.x, position.Position.y, position.Position.z) - direction.normalized;// * speed;
                        {
                             navDestination.requestedDestination = targetPos; 
                        }
                    }
                }).ScheduleParallel(Dependency);
        }
    }
    public struct FleeAction : IComponentData
    {
        public ActionState actionState;
    }
#

this is how flee looks for example

muted field
solemn hollow
#

You can see im using the DecisionActionData to read the target and the FleeActionTag to know this system has to execute

rustic rain
#

yeah, I get that part

#

now I just need to make it work πŸ™‚

solemn hollow
# muted field i been watching some videos on it - seems like its very similar to goap

sry i was distracted. GOAP is very different. Utility AI does not traverse any PlanningGraphs to plan steps ahead. It just directly reacts to changing environments based on a Score assigned to each individual action. It does not try to maximise a score over multiple actions or sth. But through good setup of the ActionUtilities you can achieve pretty much the same behaviour as if you would plan ahead.

solemn hollow
#

Forgot to mention: GOAP often uses UtilityScores to Decide which goal to persue. So in that sense that Goal choosing can be seen as a form of UtilityAi

#

does someone already have a working entitypicker? Like at runtime selecting an entity in the scene and showing its Inspector? Cant believe its still not in 0.50 :S

rustic rain
#

yeah

#

Just edit GenerateColors
With the query you want to select

#

assign _camera field to camera you select from

#

and call OnClick

solemn hollow
#

thanks!

rotund token
#

if you want

solemn hollow
#

Will be the next thing ill add. need to first get those pesky AbilityEffects running

rotund token
#

i have a significantly improved performance version of that

#

also with support for hybrid skinned mesh renderers

rustic rain
#

could you paste it again?

rotund token
#

dont think i've actually pasted it completely before

#

let me bundle it

solemn hollow
#

i mean sure i want an improved version πŸ™‚ Does it actually work with sprite renderers?

solemn hollow
#

arrrg

rotund token
#

i only added skinnedmeshrenderers

#

but you can see how i did htat and probably do it for spriterenderers as well

solemn hollow
#

well thats even better. then ill learn sth along the way

rustic rain
#
            Entities.WithSharedComponentFilter(system)
                .WithAll<Selectable>()
                .ForEach((Entity e, RenderMesh mesh, ref LocalToWorld localToWorld) =>
                {
                    if (mesh.mesh == null)
                    {
                        return;
                    }

                    _entityIndexToVersion[e.Index] = e.Version;
                    _idMaterialPropertyBlock.SetColor(ColorPropertyID, IndexToColor(e.Index));
                    cmd.DrawMesh(mesh.mesh, localToWorld.Value, _idMaterial, mesh.subMesh, 0, _idMaterialPropertyBlock);
                })
                .WithoutBurst()
                .Run();

Here key code for it

#

if you can figure out how to do it with sprite renderer

#

that would be great

rotund token
#
            {
                this.matrices.Clear();
                this.colors.Clear();
                this.propertyBlock.Clear();

                this.colors.AddRangeNative(chunk.Colors.Ptr, chunk.Colors.Length);
                this.propertyBlock.SetVectorArray(this.colorPropertyID, this.colors);

                this.matrices.AddRangeNative(chunk.Transforms.Ptr, chunk.Transforms.Length);
                var matrixArray = NoAllocHelpers.ExtractArrayFromListT(this.matrices);

                var mesh = this.system.World.EntityManager.GetSharedComponentData<RenderMesh>(chunk.Mesh);

                this.commandBuffer.DrawMeshInstanced(mesh.mesh, mesh.subMesh, this.material, -1, matrixArray, this.matrices.Count, this.propertyBlock);
            }```
#

so yeah i changed it to this

#

1 per chunk instead of entity

rustic rain
#

and what about collecting chunk data?

#

oh

rotund token
#

burst job

rustic rain
#

hm

rotund token
#

to generate colors