#archived-dots

1 messages · Page 158 of 1

tight blade
#

This isn't critical, but if any of you were interested in taking a look, I'm shopping for critique on this system for manually iterating through entity pairs
https://forum.unity.com/threads/critique-my-usage-of-manual-iteration-to-check-distance-between-all-pairs-of-certain-entities.930624/

zinc plinth
#

@tight blade this looks fine, tho I'm scratching my head into why you would compare entities between chunks but not within chunks

tight blade
#

because if you're only comparing within chunks, you wouldnt be checking against every entity

zinc plinth
#

also I think you made a typo var translations = chunk.GetNativeArray(TranslationType); var translations2 = chunk.GetNativeArray(TranslationType); var mycomponents = chunk.GetNativeArray(MyComponentType); var mycomponents2 = chunk.GetNativeArray(MyComponentType); you're getting from the same chunk instead of using chunk & chunk2

tight blade
#

thanks!

#

fixing...

zinc plinth
#

but what I mean is that 2 entities from the same chunk will never be compared against one another

#

and idk if it's the behavior you want

tight blade
#

they would. if you see how the combo list is implemented, it includes pairs of the same index

#

(1, 1), (2, 2), etc, are in there

#

so in certain jobs, chunk and chunk2 will be the same chunk and ...

#

oh. right. so that would check distance against itself and always be true haha

#

so thats a bug.

#

fixed it with an if and a comment

deft stump
#

@pliant pike I suggest looking up BlobAssets as a way to "convert" SOs.

#

also... does the GOConversion world get destroyed once it converts everything to the destination world?

zinc plinth
#

yes

#

also, a new conversion world is created & destroyed each time you do ConvertGOHierarchy, so be mindfull of what and when you convert stuff manually

pliant pike
#

@deft stump yeah thanks, that's why I'm going to turn them into, I'm just trying to figure out the intermediate step

odd ridge
#

@zinc plinth why not use a shared component? I was thinking, if I have a shared component / tag, all the entities that are in a same cell will have the same archetype and be next to each other in memory. if I use a flat array for my grid, then I only keep pointers to the entities in this grid right?

zinc plinth
#

@odd ridge because then you have 1 chunk minimum per coordinate

#

and this is bad

#

just on a 100 by 100 grid it's already a nightmare

#

you want the least amount of chunks possible in your worlds

odd ridge
#

I see, so I'm better off keeping all my entities in 1 chunk, and then my grid structure keeps pointers to each entity that belong in each cell?

#

pointers or entity ids

zinc plinth
#

the Entity struct with it's fields is a "reference" to the actual entity in theentity storage

#

you store the Entity struct in a component/buffer to be able to go from 1 to the other

#

here you want a buffer

#

I also suggest using InternalBufferCapacity(0) for your IBED to make it go imediately into heap

#

because 1 chunk will never be enough to store your while grid

odd ridge
#

do you know some resource to read about spatial grid implementation in dots / data oriented ?

#

it sounds like it doesn't belong in there

#

if I use buffers, it's just like making a normal gameobject, but wrapped into a ECS component, isn't it?

coarse turtle
#

like spatial hash maps?

#

I use that for my own 2D physics system

tight blade
#

is there a factorial function in math anywhere? or is there a c# syntax for that or anything like that?

zinc plinth
#

it's still DOP, just imagine the Entity struct to be an array index

#

it's ofc not the best way to go; it would be better to do without it

#

but for some things there's just no way around it

#

one limitation is that ECB(.Concurrent ?) doesn't allow to write components with Entity fields from jobs for some reason, but all of that linking mostly get done at instantiation time on main thread anyway

#

and buffers are just fancy arrays, it's still ordered memory; tho you won't often read it sequencially

odd ridge
#

@zinc plinth what you said about chunks made me think. DOTS says to use empty component as tags. for example, I could have a IsJumping tag to put certain entities in a given state, and a IsCrouching, and a IsRunning, etc. but doesn't adding tags create even more chunks? 3 different tags would mean 2^3 possible archetypes, or 8 different chunks. it's exponential. what do you say about that?

zinc plinth
#

that's still very few chunks

in the case of a 100 by 100 grid with shared components, you have 10 thousand chunks that will be next to empty

rancid geode
#

@odd ridge they are working to have a new "Enabled" property for all CD/BED (even tags) so that you won't need to add/remove components in runtime, just enable/disable (which will work as if adding and removing, but without changing the archetype, and parallelable)

zinc plinth
#

ho neat

rancid geode
odd ridge
#

@rancid geode they will still have to be rearranged in memory if you want good cache coherency so I'm not sure how that's helping

#

oh, that's not for performance, just to reduce boilerplate right?

rancid geode
#

@odd ridge no, they won't be moving between chunks anymore

#

Enabled/Disable will act as if you Added/Removed the components, but it won't be actually remove component when disabled

#

So I consider that it is both to reduce boilerplate and for performance

odd ridge
#

@rancid geode doesn't this add branching code in your system? having to check whether each component is active or not when iterating?

rancid geode
#

See the post I linked to, it wont be necessary. For now, if you want to prepare your code for that feature, yes you will need to branch the condition yourself

zinc plinth
#

I'm so confused

#

if I try to resize a buffer in Convert after applying an archetype, mu entity inspector throws unicode string null reference errors if I select that entity

#

I get NullReferenceException: Object reference not set to an instance of an object Unity.Collections.NumberedWords.ToString () (at Library/PackageCache/com.unity.collections@0.9.0-preview.6/Unity.Collections/Unicode.cs:807)

#

I already got this error before, but I don't remember how I solved it --'

#

it feels like the whole entity gets deallocated as soon as I resize, which makes absolute no sense o.0

#

so it's something in the WordStorage that somehow is wrong

#

I have to find a repro because this is driving me insane

#

ok thank god this is an easy repro

#

now to try to shave it down

#

hooooo

#

I FOUND IT!

#

but I'm still sooo confused

#

so the problem has to do with buffers of component containing public Entity fields

#

the stuff that takes care of drawing the entity inspector will try to read that newly resized buffer contaning Entity; and will try to go fetch a name corresponding to this entity; but I guess the buffer data isn't cleared before given to us so you don't have neat Entity.null values, but a bunch of random nonsense

#

and the WordStorage will try to get the name associated at that Entity using it's Index

#

but it'll just fall out of allocated space and throw a null reference

#

jeez whenlifegetsatyou

#

so I just have to MemSet the buffer to a bunch of zeroes

#

so yea you have to do this var buffer = em.AddBuffer<MyBufferElement>(entity); buffer.ResizeUninitialized(100); UnsafeUtility.MemClear(buffer.GetUnsafePtr(), UnsafeUtility.SizeOf<MyBufferElement>() * 100);

zinc plinth
#

at least I'm not insane and it isn't a weird niche bug from my setup 😁

hollow sorrel
#

@odd ridge didn't get a chance to reply until now but torsina pretty much covered all of it
i don't know what your game's design is like but if you want a typical 2d grid like in a roguelike then a flat array (in this case dynamicbuffer) is prob the way to go
it's hard to make generic statements like this because the point of data oriented design is you optimize for the most common code path

odd ridge
#

@hollow sorrel I'm trying to replicate something like starcraft. entities move on a 2d grid, many entities can be on a single cell. the grid is used for movement and collision detection for combat.

zinc plinth
#

you'll use the cells for buildings, moving units on grid tiles doesn't make sense unless you want them to be stacked on the cell

#

use raycasts to select your entities as targets

#

and good luck for the path finding monkaCan

toxic mural
#

Is the DOTS Editor only for Project Tiny?

hollow sorrel
#

@odd ridge not sure if this would be best solution but you could store a nested array with an array for each grid tile, but since nested nativearrays/dynamicbuffers aren't possible you'd have to fiddle with unsafearrays or similar

#

dunno if a dynamicbuffer that holds unsafearrays is a good way

odd ridge
#

@zinc plinth I would use grid tiles for spatial partitioning. units move physically like normal, but enter/leave cells as they move around. that way, I can just peek into 1 cell to find all the units in this spot

hollow sorrel
#

i think storing dynamic entities in your map data structure is something you wanna avoid if you can help it

odd ridge
#

@zinc plinth like a quadtree, but it's a fixed grid

#

@hollow sorrel I want to use a grid like you would use a quadtree. why not a quadtree? well, I suppose a fixed grid is much cheaper to compute

hollow sorrel
#

oh if this is for spatial partitioning look into NativeMultiHashmap

odd ridge
#

yes

low tangle
#

The reason you are having trouble is that you need to separate your data

#

When you are looking at a tile in one system, you only want that unit/tile/entity to contain the minimal amount of data

#

Flat array for tile visuals, use to construct and render

#

Flat tile array for collision and pathing

#

Flat array with unit buckets for storing where a unit is

#

Flat array of units

#

Replace flat array with entity and you have a ecs structure

#

IDs and tagging for when you need to cross reference out of your flat array

odd ridge
#

@low tangle in all cases, a tile map in ecs would be flatened?

#

@hollow sorrel is there a DOTS demo using NativeMultiHashMap?

hollow sorrel
#

i think the boids demo in ecs sample project uses nmhm

low tangle
#

making the tiles out flatten can also mean one entity per

#

you want to be using those entitys as inputs to acceleration structures like nativemultihashmap and caching them within logical groups, or typically just per system

#

what I mean is you might have a 'physics' simulation structure, which contains the physics world, as a reflection of the entitys you modify and react to

#

those entities are brought into the physics structure in any way, (delta, naive copy em all) and then your much easier to formulate or more performant logic can be done on that properly formatted data (hopefully multi threaded using the job system and very fast)

#

complex problems require some sort of outside ecs world data to be created and stored, which is what the native memory system and job system manipulating them is for

#

most of the time, people really just need to create a bunch of entities to store some trait. Then in a system not directly related to that trait, but needs to check it, that system would just need to hash them entities to do its kernel of logic

odd ridge
#

can you add many components of a same type to a same entity? in other words, can an entity have multiple Position components?

low tangle
#

thats what buffers are for

#

you can also hint how many typically they need (or known fixed amount) with a compiler tag

odd ridge
#

@low tangle are buffers stored inside components themselves?

#

and by buffer, do you mean having a NativeArray of components inside a component?

low tangle
#

no, actual construct

#

dynamic buffer

wanton apex
#

Hi !
I'm facing very strange issue. I have a Loot system, every ennemies have a DynamicBuffer of Entities, when an ennemi die, it have a chance to spawn a loot, pick random in the buffer. It works great in the Editor, but in a Build I don't get any entities spawn, even if I set the loot probability to 100%.
Is there a known issue in Build that could explain that?
Thanks in advance

#

I'm using Entities 0.11.1

odd ridge
#

@low tangle is this still cache friendly? wouldn't accessing these buffers be a random access?

low tangle
#

no, thats what internalbuffer is for

#

it reserves space in the same buffer the entity data is stored

#

if you add more then that, then yes it will jump to a new native array to store it instead of within the component SOA

#

size it right, or use a fixed amount matching or less than internal buffer count and it will be the same as accessing a component * n

eager jungle
#

hey guys, anyone has a good pointer to either : trail renderers with ECS, and / or using vfx graph with ecs?

odd ridge
#

I want to add a RemoveComponent component that removes another component after 5 seconds.
Now I want to implement it for another component. is there a way to do this without duplicating both the component and the system?

mint iron
#

reuse the same component?

coarse turtle
#

you could create a sort of mask value and when certain bit flags are up you just remove certain components

ocean cloud
#

use generics

#

although that is technically duplicating

#

how do you guys implement delays/waits in ECS? I'm still using coroutines in systems and although it works there's a lot of gotchas within timing and generally the performance isn't good

willow plaza
#

Is it a delay of the whole system or for certain entity?

ocean cloud
#

for certain entity

willow plaza
#

Perhaps add a delay component? And make a delay system countdown and remove it. While other systems can ignore entities with this component in their queries.

opaque ledge
#

pretty much yeah

tawdry tree
#

What do they trigger? The obvious would be to just add a delay component - one field for the start time, and one for delay. that or just one field for when to activate

ocean cloud
#

Ah I see

tawdry tree
#

I'm a fan of delay systems that don't increment anything, but just check "is it time?" yet

ocean cloud
#

Yeah me too

#

like calculate the finishTime ahead then just check

willow plaza
#

what if you want to affect the timer speed. Let's say there's something on delay and you increase the timescale by 2. If you precalculate the delay it's not gonna be affected by that time scale.

tawdry tree
#

time.time tho

#

It should be affected by timescale

wanton apex
#

Hi,
It looks like I have a system that is not included in Build. Is there a common reason? I don't know how to fix it. It works in Editor but not in build... Here is the system in question :

#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

[UpdateAfter(typeof(ApplySimpleDamageSystem))]
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class LootSystem : SystemBase
{
    EntityCommandBuffer buffer;
    protected override void OnCreate()
    {
        buffer = World.GetExistingSystem<EndSimulationEntityCommandBufferSystem>().CreateCommandBuffer();
        Debug.Log("Loot System Created");
        
    }

    protected override void OnUpdate()
    {
        var ecb = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>().CreateCommandBuffer().ToConcurrent();
       
        var random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(0.0f, 1000000.0f));
        //Debug.Log(ecb);
        Entities.
            WithNativeDisableParallelForRestriction(ecb).
            ForEach((int entityInQueryIndex, Entity entity, in DynamicBuffer<LootDynamicBuffer> lootBuffer, in LootComponent loot, in HealthComponent health, in Translation tr) =>
        {
            if (health.CurrentLife <= 0.0f)
            {
                var proba = loot.probability;
                var rdm = random.NextFloat(0.0f, 1.0f);
                var rdmIndexFloat = random.NextFloat(0.0f, 1.0f);
                var rdmIndex = (int)(rdmIndexFloat * (lootBuffer.Length));
                if(rdm < proba)
                {
                    var lootEntity = lootBuffer[rdmIndex].entity;
                    var e = ecb.Instantiate(entityInQueryIndex, lootEntity);
                    ecb.SetComponent(entityInQueryIndex, e, new Translation { Value = tr.Value });
                }

            }
        }).WithBurst().ScheduleParallel();
        Debug.LogError("SPAWN LOOT");
        World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>().AddJobHandleForProducer(this.Dependency);
    }
}
willow plaza
#

time.time tho
@tawdry tree right. Kinda missed that point. 😄

pliant pike
#

I don't suppose anyone knows how you destroy a system(from within that system)?

#
 var bakasystem = EntityManager.World.GetExistingSystem<ScriptabtleObjectConvert>();

        EntityManager.World.DestroySystem(bakasystem);```
#

I guess I can do that or is there maybe a better way?

buoyant ivy
#

i just started learning ecs and was just wondering how to create an entity archetype. ( not using any "convert to entity" stuff ) I see you can make one from an array of ComponentTypes but after looking at the docs i can't figure out how to make a component type or exactly what they are, i imagine they are references to unity components or something.

#

or is ecs really just designed to best be used as a hybrid system and not by itself ?

#

hm i guess the best way is to create an empty entity, add components to it, than save the archetype somewhere ? so archetypes are a runtime thing, they aren't defined beforehand ?

cosmic nexus
ocean cloud
#

hm i guess the best way is to create an empty entity, add components to it, than save the archetype somewhere ? so archetypes are a runtime thing, they aren't defined beforehand ?
@buoyant ivy
you don't need to save the archetype, yes it's runtime thing, when you use AddComponent / RemoveComponent, the entity archetype changes
you define archetypes if you want to CreateEntity with a defined "structure"

buoyant ivy
#

so whats the general idea of how to code stuff in ecs. Do you make gameobject prefabs and just convert those ?
Or do you define archetypes in code and instantiate in code? And I don't really see how to define archetypes in the code other than just stringing together a bunch of addcomponent removecomponent things ?

#

and how would you get stuff like rigidbody and all those special components? just need to put them on a gameobject and convert them or is there like some function you can call that gets the ecs version of a rigidbody for example

ocean cloud
#

I use gameobject prefabs just because I want to easily edit my prefabs in the editor

#

but yes you can instantiate in code directly

#

physics is in a totally different package here in ECS, see Unity.Physics

buoyant ivy
#

ah i see so you have to use those functions to manipulate the object yourself instead of having a rigidbody automatically do it ?

ocean cloud
#

Nah, it has rigidbody, colliders, and all that stuff but just different, you manipulate them (like velocities, collision events, etc) through ECS

buoyant ivy
#

oh ok

#

so if i had a rigidbody and used the convert script, is it basically converting it to the Unity.Physics equivalent ?

ocean cloud
#

sadly no

buoyant ivy
#

wait so what happens in that case, does it just not work ?

ocean cloud
#

I think that rigidbody component will just be removed when you convert to entity

#

there's PhysicsBody component if I remember that right, that is a component that you can add to gameobjects and will be correctly converted to the ECS version

buoyant ivy
#

yea you are right i just tried it the rigidbody just dissapears

ocean cloud
#

yeah you need PhysicsBody component, the configurations are a little similar with the classic stuff

#

btw anyone know how to schedule jobs after EndSimulationEntityCommandBufferSystem without creating a new system after it?

buoyant ivy
#

can you tell me how to add a physics body component to an entity

ocean cloud
#

just do it from gameobject

buoyant ivy
#

is it entitymanager addcomponent is it entitycommandbuffer or what

#

ok

#

i guess this system was designed as a hybrid system then

ocean cloud
#

physics components are a pain to add from code now

#

well it's technically full ECS at runtime, you just use gameobjects for authoring

buoyant ivy
#

ok i see

#

so where does the main game loop get written. is it in one of these SystemBase files ?

ocean cloud
#

you create a new class derived from SystemBase, and override method OnUpdate

buoyant ivy
#

ok and you basically run jobs and stuff from there ? is the idea to have multiple systems or just one system as like the main game loop ?

ocean cloud
#

yes, multiple systems

buoyant ivy
#

so they effectively are like how the monobehavior Update was before, if you have 5 systems i guess it runs all their OnUpdate functions on the main thread right ?

ocean cloud
#

yup, but now every data are stored in a centralized entities

buoyant ivy
#

and the idea is you loop through those entities in some kind of multi threaded job or something and update them from what i understand

#

why does EntityManager and EntityCommandBuffer both have functions to add a component ? is one thread safe and the other isn't ?

ocean cloud
#

EntityCommandBuffer is just a deferred commands for EntityManager

#

calling EntityManager will make a sync-point, which forces all jobs to be completed before proceeding

#

so ECB is a way to minimize these sync-points

buoyant ivy
#

oh ok so will ecb defer the action rather than waiting for them to be completed ?

ocean cloud
#

ECB just defer the actions to be executed later (near the end of the frame)

buoyant ivy
#

ok i see thanks

#

does that mean all jobs will be done by the end of the frame ?

#

if you have a gameobject prefab, can you instantiate that into ecs ? or would you just do GameObject.Instantiate and then the conversion script would just run immediately and do it?

ocean cloud
#

there is EntityManager.Instantiate(entity),
don't instantiate gameobjects, every prefabs that you convert to entity will have a special "Prefab" component, this prefab entity is to be used with EntityManager.Instantiate(entity)

buoyant ivy
#

how do i even get the prefab into the System since i can't drag it into the monobehavior inspector? since its not a monobehavior

#

do i need to use the Resource.Load or whatever it is

ocean cloud
#

no, you have to make one monobehavior as a "prefab manager" or some sorts

#

with IDeclareReferencedPrefabs

#

then you fill the given list with your prefabs, then every prefabs you referenced will appear in the ECS world

#

If I remember that correctly 😕 , just try it

buoyant ivy
#

ok thanks. can you tell me how to use the entity query thing for foreach ? foreach seems to just take a function and not the query created by GetEntityQuery ?

ocean cloud
#

noo they're different

#

in foreach unity will read your lambda parameters and build the query from that

#

e.g. (MyComponent a, ref Translation t, ref Rotation rot) => ... will query all entities with all three, MyComponent, Translation, and Rotation but you take MyComponent as readonly because without ref

buoyant ivy
#

i see thanks

#

what about the "in" keyword there what would that be for

#

if you had it

#

theres an example that uses (..., in Velocity velocity) =>

ocean cloud
#

idk never used that myself, I think that is similar with ref maybe?

buoyant ivy
#

I see thanks

#

do i need to do something to make my systembase run ?

#

oh does logging not work from inside them ?

#

i think its running its just not logging

#

oh yea its working just not the logs

rancid geode
#

e.g. (MyComponent a, ref Translation t, ref Rotation rot) => ... will query all entities with all three, MyComponent, Translation, and Rotation but you take MyComponent as readonly because without ref
@ocean cloud if you want to make it readonly, use "in", use no keywords for object references (class-based ICD or UnityEngine.Component)
also, the order should always be ("all class-based references", "all with ref keyword", "all with in keyword")

buoyant ivy
#

ok i see thanks

#

so i noticed the ecs physics doesnt interact with classic unity physics. so if you have like an asset system that uses all monobehaviors and various physics stuff, does this basically mean you just cant really use ECS unless you completely rewrite that particular system ?

rancid geode
#

the Unity Physics package have conversion system for all (or almost all?) "classic" unity physics components

#

so if you want to go with the new Unity Physics package, you can just use your prefabs with Rigidbody, Colliders and stuff from the "classic" one and they will be properly converted to their "ECS physcis" version

ocean cloud
#

@rancid geode ah thanks for fixing, but isn't the order of ref doesn't matter? I often used refs in the middle

buoyant ivy
#

i dont think they do, it didn't seem to when i tried. also do monobehaviors get converted ?

rancid geode
#

@rancid geode ah thanks for fixing, but isn't the order of ref doesn't matter? I often used refs in the middle
@ocean cloud not sure if following, you just can't do something like: (in Translation t, ref Rotation r), instead you should do (ref Rotation r, in Translation t)

ocean cloud
#

ah ok, (in Translation t, ref Rotation r) doesn't work but (Translation t, ref Rotation r) works, I often use the latter

buoyant ivy
#

for example the steamvr plugin has hands and all these monobehaviors you can attach to objects to pick them up and stuff. i would guess this wouldn't just work out of the box if you attach the convert to ECS script to them.

rancid geode
#

i dont think they do, it didn't seem to when i tried. also do monobehaviors get converted ?
@buoyant ivy you have the Unity Physics installed and are you covnerting your GameObjects properly?
and no, MonoBehaviours don't get converted automatically, you need to write your own conversion system for that, but you can add a MonoBehaviour to your entity (but you won't be able to use it with Burst or in another thread, so you would do something like that:

Entities.WithoutBurst().ForEach((MyCustomMonoBehaviour behaviour, ref Translation t) => ....).Run(); 
buoyant ivy
#

maybe i didnt have physics installed when i tried it let me try again

rancid geode
#

ah ok, (in Translation t, ref Rotation r) doesn't work but (Translation t, ref Rotation r) works, I often use the latter
@ocean cloud this isn't a good practice as you will be copying the Translation value for each interaction, using the in keyword you get a readonly reference for it

#

for example the steamvr plugin has hands and all these monobehaviors you can attach to objects to pick them up and stuff. i would guess this wouldn't just work out of the box if you attach the convert to ECS script to them.
@buoyant ivy correct, it won't

buoyant ivy
#

yea you are right i must have tried it before i installed physics

#

so rigidbody does convert

ocean cloud
#

@ocean cloud this isn't a good practice as you will be copying the Translation value for each interaction, using the in keyword you get a readonly reference for it
@rancid geode Alright thanks, never used in before, but now I know

buoyant ivy
#

@rancid geode so are you saying that it won't directly convert but you can kind of do it by running
Entities.WithoutBurst().ForEach((MyCustomMonoBehaviour behaviour, ref Translation t) => ....).Run();

#

will it have access to the monobehavior related functions properly or are those going to be throwing all errors and stuff

ocean cloud
#

but even if I have physics package installed the classic rigidbody doesn't get converted, I have to use Physics Body
rigidbody just dissapear in my entity

buoyant ivy
#

i guess they will fail if they are trying to access rigidbody and stuff right

rancid geode
#

yes, but you will still need to make a conversion system or an authoring component to it to your entity

#

i guess they will fail if they are trying to access rigidbody and stuff right
@buoyant ivy you can access UnityEngine.Component stuff just fine that way, just remember that it won't be good performance-wise, and you will always need to use WithoutBurst() and Run()

buoyant ivy
#

but what i mean is rigidbody wont exist right because it becomes PhysicsBody

#

or are you saying the regular rigidbody would actually still work on ECS if you manually add it and then call it with that WithoutBurst Run() thing

#

how can i actually add a monobehavior to an entity?

#

oh but if you added rigidbody and called it without burst orw hatever it would still use the old physics system so it wouldnt solve the problem anyway i'd guess

rancid geode
#

well, kinf of both haha yes, if you use Unity Physics package it will convert your rigidbody to a physics body (and then you should use Physics Body to manipulate your entities)
if you don't want to use the Unity Physics package, you can work with Unity classic physics by using standard rigidbody with your entities

#

oh but if you added rigidbody and called it without burst orw hatever it would still use the old physics system so it wouldnt solve the problem anyway i'd guess
@buoyant ivy yeah, correct

#

they are different stuff

#

the Unity Physics package just provide a simple way to use your already authored prefabs within their system, they don't really work together

buoyant ivy
#

right so you basically have to rewrite any assets you have that dont use the new system ( if they involve physics at least )

rancid geode
#

right so you basically have to rewrite any assets you have that dont use the new system ( if they involve physics at least )
@buoyant ivy basically, yes

buoyant ivy
#

i see thanks

#

id guess thats one of the big detriments for people to try using this system

elfin plume
#

Hmm when should we use Jobs think, character controller/AI?

minor sluice
#

Hi, I just have 2 short questions:
where is the best resource to get an up to date ecs tutorial, should I just go to the packages pages documentation?
and what unity version is minimally required to support the latest package versions for ecs,jobs etc.? is 2019.2 fine?

safe lintel
#

package page for docs(double check latest under the version button), samples repo on github for examples

most tutorials should have transferrable knowledge but theres a good chance of them being out of date, double check the date they were created against the packages that you have installed

minor sluice
#

thank you for the fast response!

#

I'll have a look

rancid geode
#

The latest package (0.11) requires 2019.3.12 or newer, and future releases will require 2020.1

odd ridge
#

I have a MovementSystem that increases a position and checks for destination. when destination is reached, the movement component is removed. in pseudocode ```MovementSystem {
foreach(Movement m) {
m.transition += m.speed * timescale;

    if (m.transition > 1.f) {
        delete(m);
    }
}

}```

#

is there a way to trigger the removal of the component without having to check for it every time? I want to avoid branching code so that the compute of the movement is as fast as possible, but not sure how to check for removal otherwise

zinc plinth
#

@odd ridge unless this takes 5ms+ to run; don't worry about it

#

your cpu does a shitton of work for branch prediction anyway

odd ridge
#

@zinc plinth not that it's a problem right now, just trying to learn what would the alternatives be if it would be a problem

#

how could you speed that up if needed

zinc plinth
#

to my knowledge there's no way to do what you're asking

odd ridge
#

alright

coarse turtle
#

dont know from the top of my head, but you could try IJobParallelForFilter (or something like that, I may have swapped the order in the job name) - if the end result you care about is a compact collection of elements you want to process on

zinc plinth
#

@coarse turtle that branching will happen even if under the hood GWaobloChildPepeShrug

coarse turtle
#

Yea

#

I understand that - since it's a filter 👀 but i was only suggesting it if they cared about the end result without having some conditional checks to process something ¯_(ツ)_/¯

zinc plinth
#

ye I get it

tho personally I find it better for this to not be hidden

odd ridge
#

so you're saying splitting the compute and the conditional check would allow the compute to be vectorized (no branching)

coarse turtle
#

there's branching under the hood as what @zinc plinth stated

zinc plinth
#

you'd have to check burst output to see if it's vectorized

odd ridge
#

is it still happening per entity?

zinc plinth
#

you could go the sledgehammer route and throw simd at it yourself

odd ridge
#

I'm not a fan of that, I like to help the compiler simd it for me you know ;p

zinc plinth
#

but seriously don't waste time on this unless you really have to

odd ridge
#

that's why I'm looking to remove the branching

zinc plinth
#

this is so early optimization it's absurd

odd ridge
#

I'm more studying about the techniques of how I would optimize if needed than anything

#

like I don't need this to be fast, just wanting to learn

zinc plinth
#

first check if burst doesn't vectorize this already

#

and I would be quite confident it does

odd ridge
#

alright

#

yeah?

odd ridge
#

thanks

mint iron
#

@odd ridge have a look at math.select and math.compress

odd ridge
#

@mint iron I watched it all. only question I have is, he says to adopt a simd mindset, which requires processing stuff vertically, but how can you use simd instructions in ECS if your ForEach loop only feeds you 1 piece of data per iteration? I would need 4 of them at once no?

zinc plinth
#

you use the job system

#

as in actual Job structs and not ForEach codegen

#

throw your native arrays of components at it, do your vectorized magic, and boom

odd ridge
#

all the demos I read were using the ForEach stuff, can you point an example of using native arrays instead?

odd ridge
#

@zinc plinth does this mean no ECS?

low tangle
#

to do smid instructions in ecs you need to switch from a foreach lambda to a jobchunk and iterate the chunk entities yourself

#

this is what will let you run the for loop within the job at +=4 (whatever smid amount your packing)

#

and access entity[i+0] entity[i+1] .. entities's data structs

#

and then do some sort of fused op with all n of those values

zinc plinth
#

is anybody familiar with RotationPivot and/or RotationPivotTranslation and how we can use them ?

rocky obsidian
#

is there any way to change the material for the RenderMesh?

opaque ledge
#

most likely, have you tried to get RenderMesh component and changed the material and set back in ?

#

RenderMesh is SharedComponent, so i think you have to use entityManager.GetSharedComponentData

deft stump
#

You can store the material in some blob and then assign it to the rendermesh component.

lusty otter
#

Do I still get performance benefit from Burst if I'm doing single threaded things and no SIMD stuffs?

dull copper
#

burst does "simd stuffs" for you

#

but short answer would be: yes for most cases

#

there's interop overhead from using burst which would be an issue if you used it for some really trivial things as then you'd pay the cost for the overhead alone basically

lusty otter
#

How harsh is the overhead?

gusty comet
#

afaik one of the biggest performance benefits of burst is the fact that it results in native code, even if your code cannot be simd'ed

#

it doesn't have the il2cpp overhead either, so it becomes faster than that too

#

if you are doing gamecode stuff, you should take the simd as an extra bonus

#

I wouldn't strive for cache efficiency at all for gameplay code tbh

#

do that stuff when it makes sense

dull copper
#

I always suggest you try things on your own

#

if measuring these yourself is an issue, I wouldn't bother at all 🙂

lusty otter
#

Sure.

#

IL2Cpp overhead is pretty rough for my project, it has a lot of recursive function calls.

#

Guess I'll give it a shot.

pulsar jay
#

Is there any way to copy an IntPtr from a native dll into a NativeArray?

mint iron
#

i'm not sure the issue @pulsar jay if its public in the dll you can just copy it, if its private you'll have to use reflection. If its not .net and not exported you'll have to reverse engineer it.

pulsar jay
#

its public. But how do I copy it? Marshal.Copy worked for managed arrays but how can I copy into a native array?

mint iron
#

you need to copy a single IntPtr into a NativeArray? or its a ptr to an array that needs to be converted into a NativeArray?

#

you can use UnsafeUtility.MemCpy(void* destination, void* source, long size)

#

so assuming you have a source ptr, you can just create a new NativeArray and GetUnsafePtr() on it for the destination ptr. and size is amount in bytes to copy so you'll have to UnsafeUtility.SizeOf<T>() and multiply it by the element count

pulsar jay
#

yeah it is pointing to an array

#

but UnsafeUtility.MemCpy needs an usafe context doesnt it?

minor sluice
#

you can set the whole project to allow for unsafe code in the project settings

#

*player settings

pulsar jay
#

atm I do a memcpy into a managed array and initialize the native array with it which somehow works without unsafe context

#

would be nice if I could avoid it as it seems to be possible

minor sluice
#

I think I haven't ever done job/native stuff without setting the project to allow for unsafe code, but I don't know what the recommended way is

mint iron
#

i would just set project to unsafe. Basically all of ECS is written as unsafe code.

#

there's nothing unsafe about it, except that a) you can crash unity if you mess something up, and b) you can create leaks if you forget to dipose something you allocated

pulsar jay
#

there is nothing unsafe about unsafe 🤔 😀

mint iron
#

theres nothing unsafe about unsafe except the unsafe parts 😄

pulsar jay
#

I was just wondering as NativeArrays manage to copy around all kinds of stuff without unsafe

mint iron
#

if you look at the source though, its just a wrapper around unsafe stuff. In other words, it looks safe to you, but its really not.

north bay
#

They just hide the unsafe stuff

pulsar jay
#

oh thats interesting. I thought if sth is unsafe I can only call it from unsafe code. didnt know you can hide it away

minor sluice
#

I'm not even sure if the unsafe internal stuff that is hidden from the api works reliably if you don't set the project to unsafe?

#

it'd be interesting if they manage to do it though

mint iron
#

its its set per dll and the entities dll can be marked unsafe while the users project can be set to normal. (can also be wrapped in unsafe { } brackets within safe code but yeah)

gusty comet
#

Hi! I'm looking into generating my own subscenes through code. Do you know a good way I could study the way subscenes get created?

minor sluice
#

ah, good to know, thx

mint iron
pulsar jay
#

I see. Thx. Was just worried to set the whole project to unsafe as wrapping only this part in usafe didnt help. But I will just try to flag the dll as unsafe then

mint iron
#

@odd ridge you can also use WithCode https://docs.unity3d.com/Packages/com.unity.entities@0.11/manual/ecs_job_withcode.html now with SystemBase instead of an IJob

@gusty comet short answer is there is no easy/official way. Long answer is its probably possible: i would check the scene management part of the entities package, there's a SceneSystem that might be insightful for how to actually load them properly. But my understanding is that a subscene is just a gameObject with a SubScene.cs script on it that references a normal scene asset. And they're managed with normal loading/unloading and then processed into ECS SubScene

lusty otter
#

Welp, I redid my code to use NativeArray instead of managed array as the first step to integrate Job System and Burst.

#

And that crashed the editor when the call stack reaches 15 or so levels.

#

If I just change everything back to using managed arrays, it works just fine.

#

If I build it with the NativeArray version and deploy it on Android it works just fine on device.

#

I remember having some of these weird issues and that what made me ditch all these in the first place.

odd cipher
#

I still don't really understand how to fix this aside from adding [NativeDisableParallelForRestriction]

#

this is the code that is making this ```csharp
Tile t = chunkTiles[index];

for (int x = 0; x < spriteSize; x++) {
int pixelX = (t.chunkX * spriteSize) + x;
for (int y = 0; y < spriteSize; y++) {
int pixelY = (t.chunkY * spriteSize) + y;
colors[pixelX + textureHeight * pixelY] = c[x + spriteSize * y];
}
}

#

specifically this line colors[pixelX + textureHeight * pixelY] = c[x + spriteSize * y];

ocean cloud
#

Hey guys, is there a way to disable some default systems such as EndSimulationEntityCommandBufferSystem other than destroying those system in OnCreate?

deft stump
#

why do you need to disable them?

zinc plinth
#

And ESECBS is generally the go to ECBS for most things you want to do, so this is a bit confusing

#

And I don't know if some internal systems don't use it for sole stuff

#

So you may break stuff by removing it

lusty otter
#

How would I go about reporting a bug in a huge project, which would require setting up a backend server to reproduce?

#

Is the only way to just strip down the project piece by piece? That would take so much development time to do.

ocean cloud
#

why do you need to disable them?
@deft stump Because I have my own ECBS with some additional features that I need

#

well tbh they can live together, just not comfortable seeing 2 ESECBS

low tangle
#

ICustomBootstrap

ocean cloud
#

Thanks!

zinc plinth
#

@lusty otter strip piece by piece or redo a blank project and work your way up to repro

#

It's either surprisingly easy, or astonishingly difficult 😁

lusty otter
#

😔

#

I'm fairly certain it's something low level, I remember the old builds with Burst and Job System would crash on iOS on something around that call stack as well.

#

I guess I'll just have to put away other stuffs and focus on this first, and there's no telling if it will get fixed.

gusty comet
#

Yo, does Entities.Foreach provide a quick way of requiring tags or should I go with the previous methods?

zinc plinth
#

.With<componentA>

gusty comet
#

yjc

#

thx*

buoyant ivy
#

anyone know why referencing a static singleton component monobehavior from within a burst job actually works despite giving you an error?
it shows an error like this one time
loading from a non-readonly static field 'TestTriggerInstance._instance' is not supported
but it actually proceeds to work as i see my log from that monobehavior being printed out. and all following executions work without that error.

amber flicker
#

Anyone seen Missing Profiler.EndSample (BeginSample and EndSample count must match): Render Camera Previous 5 samples: Render Camera Render Camera Inl_Render Transparents Inl_Render Opaques FindMainCamera In the scope: Render Camera Render Camera UnityEngine.CoreModule.dll!UnityEngine.Rendering::RenderPipelineManager.DoRenderLoop_Internal() PlayerLoop Main Thread when using the profiler with Hybrid Renderer v2 in the 2020.1 beta's?

gusty comet
#

If I 'member right monobehavs are not thread safe so they may fuck you up randomly @buoyant ivy

#

Tho, I'm just refreshing my knowledge atm.

buoyant ivy
#

so the error is just to tell you that it may or may not work then i guess

#

but it doesnt actually like error out and prevent you from doing it

gusty comet
#

Basically undefined behaviour and that's a bad thing

amber flicker
#

yea I think that's right - in the future they may disallow / error out though

buoyant ivy
#

ok i see, makes sense

#

is there a way to just execute a job without the entities query? like Job.do(() => {...}).Schedule();
or something like that ?

amber flicker
#

there's Job.WithCode

buoyant ivy
#

oh ok thanks

amber flicker
#

you can also create job structs and execute those

gusty comet
#

I too I'm looking into taking ECS out of the job system because my current project requires a lot of in-game mesh manipulation, the shared comp system really hampers me.

#

I'd personally love a RenderMeshUnOptimized comp for this kind of use cases

safe lintel
#

Yeah I get those @amber flicker with hybrid v1 and 2020.2, pretty sure its urp for me.

amber flicker
#

thanks @safe lintel yea it's URP - found a reported issue - back to built-in for me 🙂

safe lintel
#

The previous package didn't do that if you want to revert

amber flicker
#

hmm might be an option - previous urp package right?

safe lintel
#

Yep, the first 9.0 package shouldn't have those issues

amber flicker
buoyant ivy
#

cool thanks for the link

amber flicker
#

^ though not about Job.WithCode, just lambdas

buoyant ivy
#

i dont suppose there is a way to make a rigidbody use the dots physics ?

#

theres no way for a gameobject to interact with a dots object essentially ?

amber flicker
#

to combine both physics systems you'd need to e.g. have a duplicate of one of them being simulated in the other - i.e. the rigidbody with a physicsbody - though I'm not sure how you then resolve the two - suspect this is covered on the forums

buoyant ivy
#

so you mean like have an entity and inside that entity it has a reference to the gameobject also and you maintain them in sync

amber flicker
#

The physics simulations are independent of each other. You would need to have either your entity also simulated in physx or an entity representation of your gameobject simulated in dots physics. I don't know the best way to go about this - I'd first be really sure you want dots physics at all, second really sure you want to mix both then check out what posts already exist on the forum about it as I haven't even installed the package yet 🙂

buoyant ivy
#

well is there any way to use ecs/dots with the regular physics, no right?

amber flicker
#

sure - that's what 'hybrid' is about

buoyant ivy
#

i thuoght hybrid was just so you could author entities in the editor and convert them into ecs

#

entities can actually use classic physics rigidbodies and stuff ?

#

are you implying some kind of setup where you have gameobjects in the game and then counterpart entities for each of them that maintains data that is processed by the burst jobs and then set back into the monobehaviors or something like that ?

buoyant ivy
#

is the dots renderer faster than the regular one? and if so how so exactly, is it because of shared components, or is the renderer itself just faster because of multi threading or something ?

gusty comet
#

It ought to be faster

buoyant ivy
#

so would doing something like having entities that render in dots but have a counterpart gameobject with a collider and rigidbody (but not renderer) outside of dots actually perform better than just vanilla unity ?

safe lintel
#

@buoyant ivy what is the problem that you are facing with wanting dual physics systems also interacting with each other?

buoyant ivy
#

well maybe i just dont understand how the hybrid works but how else would you have things in dots interacting with things outside of dots ?

#

i was just trying to figure out if there was really any way to use the steamvr asset with dots, that asset just uses the classic physics and monobehaviors for everything, so i was under the impression that you'd have to just completely rewrite the whole thing to make it work with dots right ?

safe lintel
#

when interacting with any gameobjects, essentially it will need to be done on the mainthread, if steamvr is physx i am assuming it will be more trouble than its worth to replicate it in a transparent entity physics sim alongside it

buoyant ivy
#

so does that basicaly mean if you use this asset you cant really use the ecs system for much

safe lintel
#

well, its not impossible at all, its just how much work do you want to do 🙂

buoyant ivy
#

would there be any advantage to just having stuff render in dots but have the physics in vanilla

#

or probably not really worth the overhead to do that

safe lintel
#

id suggest to try to make a simple test where you can click and drag to pickup say a physx rigidbody, and have ecs physics follow it, and then press a button to have the reverse where you manipulate a ecs rigidbody and then have the gameobject follow it. just like a sphere on a ground plane.
there is a simple example of manipulating an ecs rigidbody in this fashion in the physics samples repo(which itself is inside the entity component samples repo)
i think going through that yourself it will become pretty clear just what kind of work scaling that up to a full project would entail, and you would have a better understanding how hybrid works

#

i also think that rendering in dots atm is like a real mishmash, if your current logic in physx runs fine most likely it will render fine without dots

buoyant ivy
#

is physx the vanilla unity physics ?

#

anyway thanks for the info

safe lintel
#

yeah physx is gameobject physics

amber flicker
#

sorry, only getting to glance at this atm but what @safe lintel says 👍 . Also, for context - currently rendering with pure entities is not much faster than traditional. Most savings come from manipulation of transforms - computing stuff related to your units/entities. Not to mention all the bugs, new physics and hybrid renderer are not yet much faster than e.g. urp + batching + physx.

buoyant ivy
#

oh ok I see thanks

safe lintel
#

yep like urp in dots doesnt support additional lights other than the main light with the latest hybrid renderer v2
and then in hybrid renderer v1 it supports stuff like ambient light by accident 😅

buoyant ivy
#

oh ok still pretty wip then

amber flicker
#

very - physics is also quite painful in some ways atm from what I understand

buoyant ivy
#

is the job system worth trying to use outside of dots

amber flicker
#

dots includes the job system.. if you mean outside of entities/ecs, then yea, it is

safe lintel
#

yes, imo if you can job+burst it without dots then definitely do it

buoyant ivy
#

oh ok cool thanks

safe lintel
#

many new unity packages use jobs and under the hood the engine uses jobs, afaik its pretty mature and solid to use

buoyant ivy
#

nice

tight blade
#

oh my gooood I dont understand how to convert something from local space to world space using the float4x4 of a LocalToWorld

#

I thought the whole point was that you should be able to just multiply the the float4x4 by the float4(xyz of local position, 1for scale) to get world position

zinc plinth
#

Matrix4x4.Inverse(transformMatrix).MultiplyPoint(Position);

#

owait that's world to local sorry

#

idk if it's the same math for the other side

#

so you use LocalToParent as the matrix and your pos would be in local space too

#

try that and see Shrugging

tight blade
#

what is this Matrix4x4 api?

#

sounds conceptually correct, though. So you're saying you wouldnt take the inverse of the matrix, youd just do whatever MultiplyPoint is doing with the LocalToWorld 4x4 and the position?

zinc plinth
#

no, I just mean don't use LocalToWorld but LocalToParent as the inverted matrix, and your f3 position is in local space; and you should maybe get world space coordinates

#

as I said, try and see

tight blade
#

no there is no LocalToParent in this situation

zinc plinth
#

from local space to world space

#

there is no local space without LocalToParent

tight blade
#

how do you mean? I have coordinates that are relative to the parent. So there is object A and object B. Object B is at 0,0, 0.5 relative to object A

zinc plinth
#

yes, then your object B has the LocalToParent component

tight blade
#

negative, it is not a child of Object A

#

it is the anchor point of a fixed joint

#

it is always a fixed position from the object it refers to, but it is not, in and of itself, a child entity

zinc plinth
#

have coordinates that are relative to the parent.

it is not a child dude use the right terms then --'

if your entity only has LocalToWorld it's in world space; and if you have a coordinate offset from that entity for whatever your point is then just add the entity's coordinate to get world space

#

like....

tight blade
#

ah, you would prefer offset then, I see! adding the coordinates is insufficient to calculate the position of the offset, because the rotation of the object has to be factored in

zinc plinth
#

and if you have coordinate set for your entity will have a translation which gives you the f3 of your coordinates in that object's space

#

and yes it is suficient because rotation doesn't mater since your point is not by any mean in local space

#

it's just an offset from a world space coordinate

#

or you're unclear again

tight blade
#

you are winning this argument, torsina 🙂

zinc plinth
#

I don't care about winning; I want to help you but you're really damn unclear

tight blade
#

alright. so, I have an offset, that offset is relative to an object, including its rotation. heres a way to describe this. I want to find the worldspace position of the point 5 units in front of my character's nose. locally speaking it is at 0,0,5 (5 units on the characters z axis away). you cant just convert the character's position to world coordinates and add 5 to the z value, because 5 units in world Z are in a different direction than 5 units in character space

#

so, given an entity, how would you find the worldspace of the position 5 units in front of that entity

#

is that sufficiently clear?

#

so if the character is currently turned such that their local Z axis is aligned with the worlds X axis, I need to find the character's world space position +5 on the X axis, because now 5 units in front of the character refers to the X axis in world space.

#

does that make sense @zinc plinth ?

zinc plinth
#

show the code on how that point is defined please

tight blade
zinc plinth
#

rootT ?
pivotT ?

tight blade
#

T referring to the transform

#

so, it is defined by taking the pivots world position and using the root transforms InverseTransformPoint api

#

thus, its world space is converted into the local space of the Root

tight blade
#

ohhhh my god I figured it out.

#

or... wait.

#

maybe...

mint iron
#

new physics and hybrid renderer are not yet much faster than e.g. urp + batching + physx.
which is not too surprising if you look at the collider setup, its pretty much doing a full hull-hull for everything with a lot of branching, no simd. + rebuilding the BVH every frame. That's why it sits there eating 2ms while nothing is happening. Maybe havok is better.

safe lintel
#

that 2 ms is kinda painful to look at 🙃

zinc plinth
#

especially when you only have completly static physics colliders only meant for collison casting😁

hollow sorrel
#

i get stateless is part of the design but couldn't they cache that stuff (acceleration structures) and still have the actual data be stateless

#

it is pretty weird how even if you only use 1 collider it's still 2ms

mint iron
#

I guess you have a lot of overhead in all the physics system too

#

I read a paper on dynamic BVH and I think you can probably make it so the dynamic version replicates what a complete rebuild would produce. But its not easy.

rocky obsidian
#

however, it does not seem to be very performant

#

is there a better way to do this? like job chunks or burst?

zinc plinth
#

there aren't material property blocks in the hybrid renderer ?

mint iron
#

I thought they added that with v2

zinc plinth
#

cuz that would help you alot @rocky obsidian

rocky obsidian
#

ok

zinc plinth
#

replacing materials is one of the worst thing you can do

rocky obsidian
#

can you specify what you mean by material property blocks?

zinc plinth
#

this feels like it would be easily done in shaders instead tho

#

which would be infinetely better than anything done on cpu

rocky obsidian
#

so a simple shader graph

zinc plinth
#

could also be done in hlsl Shrugging

#

(I think it's hlsl?)

rocky obsidian
#

this thingy

#

thx

#

eh, ill use graphs since i have no idea how to do this XD

zinc plinth
#

yup hlsl

#

if I may recommend something

rocky obsidian
#

ok

#

oof

#

5 hours lol

zinc plinth
#

but it's good acegikBlush

rocky obsidian
#

ok

rocky obsidian
#

@zinc plinth with hlsl, do i still need to do SetSharedComponentData on the RenderMesh?

zinc plinth
#

you just set the material shader as the one you created

rocky obsidian
#

hmmm

#

ah, i have an idea

rocky obsidian
#

aha

#

material is a class

#

so therefore

#

even though the RenderMesh returned is a struct, and therefore, separate

#

the material pointer points to the same object

#

so i initialize a material on play, and then change the color of that material without setting shared component data

hollow sorrel
#

that way you can keep using the same material but have per-instance color overrides which is much more performant than seperate material for each

zinc plinth
#

that's pretty awesome actually Eyes

valid atlas
#

Question:
If most of my entities are unique in behaviour (no crowd/mass work here), how will DOTS be beneficial for me?

safe lintel
#

less coupling of logic, easier refactoring code/adding new features

rancid geode
#

performance-wise, you may get benefit of being able to process all those unique behaviours in parallel (which MonoBehaviour can't)

deft stump
#

better battery life for your mobile players too

rocky obsidian
#

@zinc plinth @hollow sorrel thx so much!

hollow sorrel
#

another benefit of ecs is that gameobject+monobehaviours are really slow compared to even regular C# classes

valid atlas
#

Thank you @safe lintel @rancid geode @deft stump @hollow sorrel
That gives me a good hint n insight.

gusty comet
#

Since this is the dot chat... ⚫

odd ridge
untold night
#

Go to "Project Settings > Package Manager > Enable Preview Packages".

They moved the preview switch out of the package manager itself

hollow sorrel
#

it won't show up with that either

#

ran into the same thing a couple days ago too

odd ridge
#

well.. the problem is I did enable that, like you can see in the picture I posted, I have the preview packages

#

and I can't find Entities in the list..

#

I have to join the beta to even access it?

hollow sorrel
#

as seen in the link

#

you have to add it manually now

odd ridge
#

Unable to add [com.unity.entities]: Package name 'com.unity.entities' is invalid

#

wut

#

okay, it worked on third attempt ;p

amber flicker
#

So.. it's been a few months and I've come back to trying to make a build. Does anyone know the rules? When do I need to use the new build pipeline? Is it when you use subscenes? Only for tiny?

tawdry tree
#

Should be able to do as before?
Pretty sure subscenes are optional (use them for the subscene workflow)

amber flicker
#

But does that require new build pipeline? And how do the platform packages fit in? They didn’t use to do anything before..?

craggy orbit
#

you need the new build pipeline to build with subscenes, afaik. you also have to build from the build asset instead of the normal menu

#

no clue about anything else though

#

also requires IL2CPP backend, i think

amber flicker
#

oh? is that true?

craggy orbit
#

last time i tried to build with Mono, subscenes didn't appear, so i'm 94% sure that IL2CPP is required

#

Burst needs everything to be AOT too i think, so IL2CPP makes sense

amber flicker
#

hmm interesting

#

but I get No valid build pipeline found for EmptyBuildConfiguration. At least one component that derives from IBuildPipelineComponent must be present.

#

I took a look at the examples but I didn't see any of them on a recent version of entities etc so struggling to find an example of what I need.

craggy orbit
amber flicker
#

hmm I wonder if I need the platforms.windows package

craggy orbit
#

oh wait no

#

there it is

#

you do need it, iirc

amber flicker
#

thanks - trying now

craggy orbit
#

as well as Platforms Desktop, though i think it's a dependency of Platforms Windows so it should auto install

amber flicker
#

you're right, it did, though nothing extra automatically appears in my platforms dropdown

craggy orbit
#

yeahhh i have that issue too right now. you should be able to open up the asset in a text editor and change the platform manually

#

"Platform": "Windows",

amber flicker
#

wuuuttt... haha thank you, i'll try. I'm on 0.3.0 preview 4 for all platforms as it's a dependency of latest entities. I guess they've improved that with more recent platform versions

craggy orbit
#

im on 0.5.0 preview 6 with the same issue 😅

amber flicker
#

actually it was already there - starts building fine now thank you

craggy orbit
#

cant even update to the latest because it needs a newer entities version 🙃

#

yeah no problem 🙂

amber flicker
#

damn, was hoping that would fix the error I was getting - found some on the forum with the same error but not really any resolution. Seen this?

#
  at Unity.Jobs.IJobBurstScheduableExtensions.Schedule[T] (T jobData, Unity.Jobs.JobHandle dependsOn) [0x0001d] in ..\com.unity.jobs@0.2.10-preview.12\Unity.Jobs\IJobBurstScheduable.cs:42 
  at Unity.Entities.ChunkIterationUtility.PreparePrefilteredChunkLists (System.Int32 unfilteredChunkCount, Unity.Entities.UnsafeMatchingArchetypePtrList archetypes, Unity.Entities.EntityQueryFilter filter, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode, Unity.Collections.NativeArray`1[System.Byte]& prefilterDataArray, System.Void*& deferredCountData) [0x000cf] in ..\com.unity.entities@0.11.1-preview.4\Unity.Entities\Iterators\ChunkIterationUtility.cs:439 ```
craggy orbit
#

never seen it, sorry 😦 you're using IL2CPP, right?

amber flicker
#

yea

#

ok thank you - at least it's building now - will investigate

craggy orbit
#

no clue then

#

yeah no problem 🙂 i've got my own share of issues with it. could be a bug

craggy orbit
#

when i'm scheduling jobs, am i correct in passing in the previous job as a dependency? like so

Dependency = job1.Schedule(Dependency);
Dependency = job2.Schedule(Dependency);
Dependency = job3.Schedule(Dependency);
``` or should i be creating new dependencies for each job and combining them at the end, if they can run alongside each other?
amber flicker
#

that looks fine to me

pliant pike
#

I thought you didn't need to do that with systembase 🤔

tawdry tree
#

If they can run side-by-side, you might get better perf from combining them.

var jobHandle1 = job1.Schedule(Dependency);
var jobHandle2 = job2.Schedule(Dependency);
var jobHandle3 = job3.Schedule(Dependency);
Dependency = JobHandle.CombineAll(jobHandle1, jobHandle2, jobHandle3);

As for what you're doing, unless you need to get the jobhandle (ex. for a concurrent ECB), SystemBase should automagically compile to do the same if you leave out any reference to Dependency.

craggy orbit
#

oh nice! will this only work for Entities.ForEach, or can i do IJobChunk, IJobParallelFor, etc. scheduling this way as well (all within SystemBase, of course)?

tawdry tree
craggy orbit
#

ah silly me. should work for normal jobs too, according to the code up there 😅

#

oh

#

hm alright

#

thanks for the link! i'll give it a read

#

ah bummer. seems i can't get back as much performance as i'd hoped. still good to know. thanks again!

low oasis
#

I'm looking into using worlds as a way to revert back to a previous state, but how would I go about COPYING the data from one world to another or duplicating world data? Moving data doesn't really help when I need versions of the data.

#

Also looking at ways to store information in ECS and I'm not sure if I'm doing it right. Let's say I have a set of points that make up a road. I want to read those in and make a mesh out of it. That means I need the points in order and I may be adding sections anywhere in that list. So I need to get the entities in order and have access to all the data to look backwards or forwards along the points.

zinc plinth
#

Depends if you need versions of every single entity, if so your allocated space will grow really damn fast

#

And the only real way to do that would be to do stuff that would inherit from SystemBase and EntityManager to save everything you need

#

But as I said this will be really costly

#

If you just want to do a rollback effect for your game, I recommend just saving your translations and rotations for the concerned entities each frame into a buffer

low oasis
#

not planning on saving everything, just the base data entities for the lines. From that I can turn it into a road or any other line. A bunch of positions with some extra data

vagrant surge
#

@low oasis remember not everything has to be on the ecs

#

its perfectly fine to have a single entity, with a Road component, and said Road component has an array of points

low oasis
#

@vagrant surge as a dynamic buffer you mean?

vagrant surge
#

nah just array

low oasis
#

though arrays in and entity didn't work

tight blade
#

quick qq I could cut in, Simurr. Does anyone know off hand which system applies gravity? I want to set my system to update just after that

tawdry tree
#

Physics simulations happen in the physics world, I believe.
A separate world means separate systems, but it should be listed in the entity debugger.

tight blade
#

ahh, right. good point

tawdry tree
#

I mean, it does mean you could theoretically make your system run in that world, but I don't even want to try to wrap my head around the complexities and potential issues that'd lead to

tight blade
#

Right. Fortunately I'm testing something far less complex. I just wanted to set an entities Translation directly, independently of physics, so I wanted to set the position post physics

#

[UpdateAfter(typeof(ExportPhysicsWorld))] worked just fine. Thanks for reminding me to look in the entity debugger 😛

tawdry tree
#

ExportPhysicsWorld is definitely the one to go after for anything relying on an accurate position with physics...

prisma anchor
#

When I use GameObjectConversionUtility.ConvertGameObjectHierarchy my prefab collides normally. When I use EntityManager.Instanstiate I receive multiple collision events? Has anyone had this happen? Or is this better for the physics channel?

tawdry tree
#

And yeah, the Entity debugger is all sorts of useful

#

@prisma anchor Sounds like you might might be having two entities on top of each other? Have you verified in the entity debugger that this is not the case?

prisma anchor
#

yes, its only one entity.

#

If I use a ConvertAndDestroy Component and leave the prefab in the scene everything works fine.

icy kestrel
#

Does anyone know how I can write to a NativeMultiHashMap in an IJobParallelFor job? I've come across "Concurrent" but this does not exist in my project. The error I'm getting is this:

tawdry tree
#

Sounds like it doesn't actually support parallel writing.
You can work around it by using a container that does support parallel writing, and writing that to the hashmap afterwards.
That or some other workaround.

icy kestrel
#

Hmm, the reason I used it was because it's the only way I know of implementing a "2D Array" in a job system. What I need is to receive a path which is a set of positions from each job. And, I don't know how many positions there will be. Can you recommend anything to simulate this?

odd cipher
#

Honestly I would recommend just using 1D arrays.

icy kestrel
#

How can I get, say 1000, 1D arrays from a parallel job?

tawdry tree
#

Yeah, you probably want to use a flattened 2D array

odd cipher
#

disguise a 1D array as a 2D one I suppose

tawdry tree
#

If you are not familiar with the concept of flattening arrays, you should look it up

#

But in short, you turn

[ [11, 12, 13]
[21, 22, 23]
[31, 32, 33]]
into
[11, 12, 13, 21, 22, 23, 31, 32, 33]
You probably want some helper functions to easily convert between 2d coords and the flattened index (as I assume you're working with a 2d coord system here), and you can either come up with that or you own or do some quick searching - it's not exactly a new problem, just search for "flatten array helper" or something

icy kestrel
#

Ok thanks, my array lengths can't be predicted though, is that an issue here?

odd cipher
#

You can use a NativeList

#

That won't require a length when creating it

icy kestrel
#

Cool, I just assumed a list wouldn't support parallel writing

odd cipher
#

99% sure it does

#

also a common way to do it is simply by doing x * arrayWidth + y when indexing

#

not sure what the best way to go about it is with lists but it should be fine

tawdry tree
#

With flattened arrays you need to know the size of all but the last side at the time of use.

odd cipher
#

it might have to be an array now that I think about it

tawdry tree
#

@icy kestrel When you say array lengths can't be predicted, do you mean that they change over time, or simply that they are of arbitrary size?

icy kestrel
#

2nd

tawdry tree
#

As long as you know the size when you make and use them you're good

#

On the other hand, if you want to resize them you need to do a whole mess with offsetting most elements.

#

The NativeArray structure will actually resize itself if you try to outgrow it, though of course it's better if you instantiate it with exactly the size you need, or slightly larger

icy kestrel
#

I shouldn't be resizing it

tawdry tree
#

The idea then is that, when you make the array, you make it with the width*height as size.
Then, when accessing it, you code will look something like

//when inserting
arr[FlatIndexFromCoord(12, 34)] = item;
//if you are, for example, doing a for loop over each element:
pos = CoordFromFlatIndex(123);

Where FlatIndexFromCoord and CoordFromFlatIndex are static helper methods

#

You could of course shorten the names, and some trickery with using static and using ___ = ___ can make the code look a bit pretties than otherwise

icy kestrel
#

Oh, I meant I wasn't resizing again in runtime but yeah the width of each path will be different

tawdry tree
#

Oh, so you have a jagged array of uneven size... that makes things a lot more complicated.

icy kestrel
#

Yeah, a path could take 1000 coords or just 1 lol

tawdry tree
#

Care to explain the use case here? Might be possible to simplify it

#

Any reason why you're keeping track of many paths in the same array? Do they have any relation?

icy kestrel
#

The only reason I am keeping them inside 1 array is because I thought that was needed for the Job System

#

I have an A* algorithm which provides a simplified path. The path needs to be returned in the job somehow (1-1000+ points)

tawdry tree
#

If they 'belong' to an entity (as returned from the Entities.ForEach), you should use DynamicBuffers

#

Yeah, a pathfinding path is definitely a job for a dynamicbuffer. That removes the extra dimension

icy kestrel
#

I'm still working with oop and making use of purely the Job System and Burst

tawdry tree
#

Ah, so no ECS, just jobs and burst?

icy kestrel
#

Yeah, I didn't see a channel specific for Jobs

tawdry tree
#

That does complicate things slightly, yeah.

#

One possibility is to use single jobs instead of the big parallel jobs and give each their own NativeArray. That can still be run parallel, by the way, just a bit more manually.

#

Especially since you might want to recalculate or change the path of only a subset of things in a given frame

#

That way each MonoBehavior ultimately has its own path saved in a NativeArray, and you don't need to change that unless the path changes.

#

@icy kestrel Do you have a structure in place to run all the pathfinding from the same bit of code?

icy kestrel
#

Yeah

#

And, there is a check whether or not they need it already

#

They get that information from a statemachine

tawdry tree
#

Rough code to merge a bunch of jobhandles from jobs you create then and there:

var jobHandles = new NativeArray<JobHandle>(Allocator.Temp);
//Use proper loop in your code
foreach(var thing in needsUpdate) { 
  var jobhandle = new AStarJob(/*inputs*/).Schedule();
  jobhandles.Add(jobHandle);
}
JobHandle.CompleteAll(jobHandles); //Complete now
//OR
var combinedhandle = JobHandle.CombineDependencies(jobHandles); //If you don't want to complete now
jobHandles.Dispose();
icy kestrel
#

Ok, that doesn't look too bad xd. Would you recommend converting an entire project to ECS without any knowledge of it or stick with oop for this project?

tawdry tree
#

If you've already started with OOP, just using jobs and burst can give you a ton of performance where it really matters

#

Also, DOTS is rather unfinished when it comes to functionality at the moment - the basics (ECS, jobs, burst) are pretty solid, but if you want stuff like physics, animation, easily working in 2d, etc you gotta do it yourself.

icy kestrel
#

I think I'll pass for now then

tawdry tree
#

All in all, I recommend the full DOTS stack only to learn about it or if you have a simple project and have the time and motivation to code entire game systems for yourself.

#

Conversely, burstified jobs are a great addition to any game with some code that is fairly heavy(such as pathfinding), as you can generally work with more familiar methods (C# OOP with GameObjects), and still get great perf where it counts.

icy kestrel
#

Yeah I'm sure I will be using it a couple more times

#

With the above system you showed me, how do I get the individual paths? Is it something like jobHandles[0].path etc

tawdry tree
#

The usual tips for optimization apply:
-Make reasonably good good
-If you suspect bad perf, profile it to get hard numbers!
-Focus on one thing at a time
-Focus on the things which are the easiest to optimize first (often the ones that takes the most time, but later on that may change)

#

To get the individual paths, what you want as "inputs" to the code I gave is something like a list of the inputs, where each index of the list will match the index of the job being done, or you could do a dictionary to match the inputs with the outputs

odd cipher
#

Would merging two job handles help with performance?

tawdry tree
#

Combining jobhandles means you can easily complete or wait for all of them at the same time. otherwise you need to .Complete each of them individually. In code like this that would also force them to run sequentially instead of in parallel.

#

You probably also need to actually save the jobs, since you can't access the job, and thus outputs, from the jobhandle.
Exception to that is if you send the NativeArray for the path in as a reference.
Basically something like:

//MonoBehaviors needing path updates
foreach (var mbNeedingPath in mbsNeedingPaths){
  var job = new AStarJob{
    PathArray = ref mbNeedingPath.Patharray
    //other stuff
  };
  //other stuff
}

With this you should theoretically not need to check the output value, as it would set it directly in the monobehavior. Similarly, you could grab the jobhandle and not even complete it this frame.
You would want the jobhandle to check if it's already running a job next time it needs recalc, and of course you'd need to check .IsComplete each frame if you didn't send the path array by reference.
(to be clear I have no idea if this will work - it will most definitely not work without minor modifications)

#

For pathing you probably want to finish on the same frame, unless that causes lag, but for very heavy jobs (procedural generation comes to mind), grabbing the jobhandle and just checking .IsComplete each frame is a simple way to offload heavy work with minimal perf cost (unless you seriously overuse/abuse it)

tight blade
#

Nice. This is some awesome content, @tawdry tree .

#

I have a far less reasonable line of questioning if anyone wants to take a swing at it

tawdry tree
#

Thanks, I have thought about this... a little bit.
Okay maybe a lot
Okay maybe it's what my brain does when I go to bed at a reasonable time as opposed to whatever my sleeping cycle says

#

So what's the line of questioning?

tight blade
#

I feel that 😂

#

Basically its about working with chunks and wondering whether or not you can constrain the size of each chunk that you are operating on

#

The concept I have in my brain is a "sister system" where two queries are operated on at once.

so you have an AComp and a BComp. and for every entity with an AComp, an entity with a BComp is also created.

then in an IJobParallelFor you get two sets of chunks, populated with the AComp entities and BComp entities respectively. Since they are created at the same time, they should have the same offsets in their respective vectors.

#

and it seems that the offset part is actually true, somewhat to my surprise

#

the issue is that the chunks are often mismatched in size

#

the actual operation being tested here is very simple and could easily be accomplished in a different way:

#

its just setting the little sisters translation to the big sister's translation

tawdry tree
#

My big question here is "what the hell are you trying to accomplish and why?"
but for some kinda paired thing, what you could do is, I dunno, sharedcomponent with two distinct values?

tight blade
#

right. in that operation its absurd, and in fact I picked this example to work on because I've already implemented it in a simpler way. testing like for like and all that

#

its actually part of my mental model of how an ECS system should work. You don't have traditional graph relationships between entities to rely on when programming -- instead you're programming with rectangles

#

but using a shared offset from the beginning of your archetype vector is something that could open up a type of entity relationship processing that can be done without using the entity manager

#

now, in my case, I'm planning to use it to process relationships between the locations of physics entities, which arent allowed to have a LocalToParent that relates their local spaces to each other

icy kestrel
#

Just ran some very basic tests for the manual parallel jobs, looks good! Thanks for the help^^

tawdry tree
#

Happy to help 🙂

tight blade
#

Anyway, like I said this is an unreasonable line of questioning. its just bizarrely close to actually working, so I thought I'd ask if anyone had any ideas

zinc plinth
#

urhhh, I thought serialization would leave me alone after I did my property drawer, but no --'
https://i.imgur.com/CHnKcMQ.png these 2 should have the value of the one on the right; the log is taken in Convert of that object

#

and I have no idea why the value isn't applied

tight blade
#

huh, I guess jobs dont have to execute on chunks, do they? I could probably just pull in the array of components instead of the chunks and then split it up myself...

zinc plinth
#

yes you can

tight blade
#

nice, cool. well I guess frankensistersystem still has a shot then 😅

mint iron
#

by offset do you mean index in chunk?

tight blade
#

archetype offset, actually

mint iron
#

you should be fine using GetNativeArray because that will scan all the components on the archetypes and get the correct offset, but otherwise it will only work with the exact same archetype I think.

tight blade
#

so the third element in the bigsister archetype array matches with the third element in the littlesister archetype array

#

right, yeah. the issue is that these are two different archetypes, but they are always created in pairs, so the entities should have the same offset in their own respective archetypes

#

the CreateArchetypeChunkArray -> GetNativeArray strategy is failing for exactly the reason you are mentioning -- they're different archetypes, so the chunks are cut up differently

mint iron
#

it might also be assuming the chunks are empty to start with, they will do things like merge chunks sometimes when adding entities.

#

or adding/removing components from some entities in a chunk

tight blade
#

that makes sense. Im doing it in a very laboratory setting. just setting placing n of these pairs in the editor and pressing play

#

So, I dont know much about NativeSlice s and how they are represented in memory. I need to cut up the ToComponentDataArray into batches, and I'm wondering if I should try having the job operate on an array of NativeSlices or if I should copy the slices of the original NativeArray into their own arrays

#

I'm wondering if trying to operate on the slices themselves would effectively be violating shared memory rules, since they would all be referring to the same underlying array

mint iron
#

I think I looked at NativeSlice once and decided it was way too restrictive to bother with

#

just use the pointer imo

#

you will probably overlap if you use multiple threads on the same array, even if they never touch the same index, because of cache line sizes.

tight blade
#

hmmm

mint iron
#

which is a problem because every time one of them write, it discard the copy of the cache line the other thread was looking at

tight blade
#

so what do you mean by "just use the pointer"?

mint iron
#

GetUnsafePtr() and then use it like an array myPointer[index] and your slices are just a range of indexes

tight blade
#

ahhh

#

wait, isn't there some kind of restriction set up now though where jobs are only allowed to write to the index of their jobIndex parameter?

mint iron
#

there are no rules if you just have a ptr.

tight blade
#

nice, nice

mint iron
#

but you can also screw things up if you try writing to stuff that you shouldn't 😄

tight blade
#

right hahaha

#

well what are the odds I would make a mistake though? that'll never happen

prisma anchor
#

On ICollisionEventJob, I just want to reflect the entity's velocity. But it slows down, any Ideas? the Physics Body's Linear damping is 0 and Physics shape Friction is 0

tight blade
#

I know this isn't what you're asking, but does using restitution not work for your use case?

prisma anchor
#

That is zero, as I'm using the ICollisionEventJob to modify the velocity:

             var colliderComponent = ColliderEventImpulseGroup[entityB];
                var velocityComponent = PhysicsVelocityGroup[entityA];
                var translationComponent = TranslationGroup[entityA];

                var velocity = math.reflect(velocityComponent.Linear, colliderComponent.normal);

                velocityComponent.Linear = velocity;
                velocityComponent.Angular = float3.zero;
                translationComponent.Value += velocity * 0.01f; //nudge to not have multiple events

                PhysicsVelocityGroup[entityA] = velocityComponent;
                TranslationGroup[entityA] = translationComponent;```
#

The first collision causes the vel to be half, its not my doing. (I think)

tight blade
#

just brainstorming - is the behavior the same if you preserve angular velocity?

prisma anchor
#

Yea, its the same behaviour if I remove .Angular = zero

tight blade
#

again, apologies, I havent worked with collisions yet. But I take it multiplying the velocity by 2 doesn't get you what you need? That reflect function isn't taking friction into account, so it might just be arbitrarily dispersing half the force through the normal plane

#

I think generally reflection divides the force through a reflection vector and an incident vector, right? the combination of those two vectors produces the original vector?

#

so maybe the result needs to be normalized against that?

#

wait thats refraction. I dont know what I'm talking about

#

dont listen to me.

prisma anchor
#

Haha, ok. Reflection is: r=d−2(d⋅n)n. where n is normalized. Unity just made the method for us in math.reflect

odd ridge
#

does someone know why there is so little use of the avx2 instructions? when I see simd, it's always old avx with xmm registers. isn't it a waste of potential to ignore the much wider avx2 instructions?

dull copper
#

@odd ridge I don't know what you mean by that, burst does support SIMD up to AVX2

odd ridge
#

do I have to give it a special flag for it to use avx2?

dull copper
#

on my own tests, there was small but negligible improvement over AVX, there was bigger perf bump from SSE4 to AVX but even that's probably smaller than you'd expect

#

just go to player settings-> aot burst setting or something like that

#

there should be option to set burst targets

odd ridge
#

thanks

dull copper
#

also if you want to do perf testing do test it in actual build

#

@odd ridge just to be clear, Burst can automatically swap the SIMD instructions by the target computer, so if target computer only supports SSE4, it'll use that and if the computer supports AVX or AVX2, it'll take that set instead in use (as long as you've allowed all these on your build settings)

#

there's been some bugs for the automated target selection in past but they always get fixed

odd ridge
#

how do you enable hybrid renderer v2?

#

is it used by default?

opaque ledge
#

no its not

#

you need URP/HDRP 9 and 2020.1 and define "ENABLE_HYBRID_RENDERER_V2" or something, you can find more info on hybrid renderer manual

stark sonnet
#

Hi, I wanna make some simple states enemy ai, currently watching this: https://www.youtube.com/watch?v=db0KWYaWfeM&feature=youtu.be, but he mentions he already has an A* pathfinding script ready, so i go to the video where he makes it and he makes it (lol), I then find out he also has vids on all of this using DOTS (I'm not familiar with DOTS at all), in these vids, the performance and speed to get the pathfinding is waay better and faster, but he has 2 videos on the topic of DOTS pathfinding (One for the base and how fast it is: https://www.youtube.com/watch?v=1bO1FdEThnU, and one depending on that video and how you can make it more performant: https://www.youtube.com/watch?v=ubUPVu_DeVk (my game will be for mobile, so i need the performance)) and I also need to spawn enemies which he has this video for: https://www.youtube.com/watch?v=pk-C_h0WJZs . As I said I'm not experience with DOTS at all, neither with A* pathfinding, as my previous games had very simple enemy AI, and some didn't need enemy AI at all. So My final 2 questions:
Q1: Do i need to change the whole project to DOTS if i just need to make enemies using dots, or can i just make the enemies and use basic MonoBehaviours on the rest of the project?
Q2: Is it worth It to go with DOTS or just do basic A* pathfinding, and if i go with basic A* pathfinding, would it be a good idea later in the development of the game, to change to DOTS or I just stick with basic A* pathfinding?
Sorry For that long message i'm just really lost

tawdry tree
stark sonnet
#

So A* Pathfinding (basic) is what i should go with?

tawdry tree
#

In short, you can use jobs and burst without ECS, and by using those for performance-heavy parts, such as A*, you can get the perf you need.
You will want to run the jobs in parallel, either with one of the parallel job types or by scheduling multiple single jobs (as explained in the discussion linked)

stark sonnet
#

ik nothing about jobs neither tbh

tawdry tree
#

A* pathfinding is what you want if you're doing pathfinding on a grid, though for gameobjects there is already built-in pathfinding using navmesh (which is pretty darn fast even for many agents) which might be better use of your time

#

If you know nothing about jobs or ECS; then migrating to DOTS is a terrible idea

stark sonnet
#
  • 2D *
#

isn't navmesh just for 3D

#

?

tawdry tree
#

It works just fine on a 2d plane

stark sonnet
#

I'll Just go with A* pathfinding

tawdry tree
#

If you're not familiar with A* from before, I highly suggest checking out navmesh first to see if it suits your purpose - it might save you a lot of work

stark sonnet
#

no tuts are there for navmesh on 2d

tawdry tree
#

2d is just 3d where you don't care about the Z axis

stark sonnet
#

true

#

besides this, i imported 2d entities before this conversation, and this happened

tawdry tree
#

package dependencies can get whacky

#

Uninstall it, close unity, delete the library/packagecache folder, then restart unity

stark sonnet
#

alright

tawdry tree
#

Clear the entire cache -it will be redownloaded

stark sonnet
#

alright

#

Done!

#

gonna open unity

sharp flax
stark sonnet
#

Library\PackageCache\com.unity.2d.animation@3.2.3\Runtime\TransformAccessJob.cs(196,62): error CS1061: 'NativeHashMap<int, TransformAccessJob.TransformData>' does not contain a definition for 'Length' and no accessible extension method 'Length' accepting a first argument of type 'NativeHashMap<int, TransformAccessJob.TransformData>' could be found (are you missing a using directive or an assembly reference?)
got this error still

#

@tawdry tree

tawdry tree
#

Can you enter play mode?

stark sonnet
#

Nope

#

just clicked import into project, even tho it was imported already

tawdry tree
#

Under advanced, toggle OFF "show dependencies"

stark sonnet
#

alright

tawdry tree
#

That reduces some noise. After that, i suggest removing erroring packages you don't use

stark sonnet
#

i have animations in the project

tawdry tree
#

Skeletal animations?

#

Sprite animations =/= 2d Animations

stark sonnet
#

nope, sprite sheets

#

Sprite animations =/= 2d Animations
really?

#

how can i delete it tho?

tawdry tree
#

If you read the descriptions, you'll see that the pacakge is sfor skeletal anims

stark sonnet
#

pretty sure there is something to do with this?

#

btw this is what the error is located?

tawdry tree
#

Hmm, that might confuse it, yes. The samples should probably not be in non-sample projects

stark sonnet
#

should i delete any of them?

tawdry tree
#

As a general rule you shouldn't be getting errors in any packages when things are installed correctly...

#

Remove it if you don't need it?

stark sonnet
#

alright

#

i tried removing it before, didn't work, i'm trying again now

#

i see now

#

i'm removing that 2d psd importer

tawdry tree
#

Ask in #💻┃code-beginner on how to fix package issues, not the topic here and I don't know a sure-fire way to do it ^.^

stark sonnet
#

i don't have ps y did i download it in the first place lmao

tawdry tree
#

If you used a template it comes with that

stark sonnet
#

yep, it's fixed now anyways

#

back to the main point, why not use DOTS, can't i just spend a couple of days learning their basics?

tawdry tree
#

The basics are in place, but it's lacking tooling and functionality all over the place

stark sonnet
#

also, my game "could" be multiplayer, would DOTS help

#

The basics are in place, but it's lacking tooling and functionality all over the place
@tawdry tree i don't understand

tawdry tree
#

Do you want animation? You'd need to code that yourself

#

Want X? probably need to code that yourself

stark sonnet
#

can't i just make the enemies DOTS, or i have to make the whole project DOTS?

tawdry tree
#

In the current state of DOTS, combining DOTS and GOs is painful

deft stump
#

the enemies in DOTS and the player in Classic Unity?
yep, no.

stark sonnet
#

Alright

tawdry tree
#

Use jobs for heavy work, that's a good place to start

#

Maybe for a later project you can do DOTS form the beginning

stark sonnet
#

then DOTS is out of the way, NavMesh seems very 3D based, watching brackeys' vid on it

tawdry tree
#

If you use mavmesh in orthogonal mode it seems like it's 2D ^.^

stark sonnet
#

but these stuff just need a third axis, what's your problem with A*?

tawdry tree
#

It doesn't need a third axis

#

Do A* if you want

#

I'm just suggesting that you could get a better result with less effort using what's already there

stark sonnet
#

but A* is grid based

#

right>

tawdry tree
#

Yes

stark sonnet
#

huh?

tawdry tree
#

If you specifically want grid-based movement, A* does that

#

navmesh let's you walk in more than just 8 directions, tho

stark sonnet
#

If you specifically want grid-based movement, A* does that
@tawdry tree i DON'T want grid based movement, it's an RPG style game

tawdry tree
#

Then you can't use basics A*

stark sonnet
#

can i use NavMesh with tilemaps, pretty sure yes, just making sure

tawdry tree
#

Yeah you can

tawdry tree
#

Are you that opposed to using the built-in navmesh stuff?

stark sonnet
#

I just read (past) that it's for 3d

#

but as you said, it is available for 2d

tawdry tree
#

It's made for 3d, but can just as easily be used for 2d

stark sonnet
#

just scared, it would be harder for 2d

tawdry tree
#

Not really

#

Just make all walls "3d" in that they have a 3d navmesh obstacle

stark sonnet
#

this is the game currently, for example i want the zombie to walk past me with avoiding some of the tiles in the tilemap

#

Just make all walls "3d" in that they have a 3d navmesh obstacle
@tawdry tree wdym? i don't understand?

tawdry tree
#

Navmesh system uses navmesh agents (they pathfind), navmesh obstacels (cannot move here), and navmesh surface (can move here)

stark sonnet
#

alright, so on the tilemap i DON'T want him to be able to walk on, i could make them "Obstacles" am i wrong here?

tawdry tree
#

Indeed

#

Giant navmesh surface underneath (using a plane), and collider tiles are obstacles

stark sonnet
#

Giant navmesh surface underneath (using a plane), and collider tiles are obstacles
@tawdry tree i'm lost here? can u improvise?

amber flicker
#

@stark sonnet It sounds like you're quite new to Unity and/or development - Dots channel is likely the wrong place to start 😅 - fwiw I'd recommend going through some more tutorials and checking out #💻┃code-beginner

stark sonnet
#

indeeed, i am new, but not that new, i just haven't gotten into any of these stuff, so i'm asking, i didn't know if DOTS was hard or not, so i asked, thx tho

amber flicker
#

my advice for you (other than to not listen to people's advice) is to avoid dots for now unless you want to do it for the learning - parts of it are simple in their elegance but a lot does require deep knowledge to make stuff

tawdry tree
#

Now that I'm finished with that match I can explain a bit better in DMs, if you want @stark sonnet

stark sonnet
#

sure!

#

my advice for you (other than to not listen to people's advice) is to avoid dots for now unless you want to do it for the learning - parts of it are simple in their elegance but a lot does require deep knowledge to make stuff
@amber flicker i'm tryna learn, i have no commercial purpose in any of this, i'm just a kid who makes games for fun! that's it!

amber flicker
#

I understand - most of us have been there - @tawdry tree is very kind - treat him well 😄

stark sonnet
#

I don't have a credit card in, on my itch acc

deft stump
#

is there a way to change the name of an entity in ecb?

amber flicker
#

Don’t think so

#

Though I could be wrong

zinc plinth
#

that's because strings aren't blittable, so you won't be able to outside the main thread @deft stump

deft stump
#

crap... well, I'll just ICD it. I just need it for debugging purposes anyways

gusty comet
#

How ready is DOTS as of today? I'm thinking about using it for a new project that I want to start releasing testing builds for within a year. What parts of it is most risky to invest in?

#

From what I've gathered so far, the authoring workflow is the one thing that might change a lot. But I'm still very new to dots

zinc plinth
#

the authoring workflow is a great tool but it's not at all necessary; I preferred not to use it at all rather than have patches of it in some random places because it couldn't do all I wanted

#

then archetypes become your best friends

#

it's a bit tedious to get right at first for entities that have a mesh and/or physics, but once you note down every component the entity needs by itself you can add all your stuff

deft stump
#

imo, right now the current api is solid enough that you can make a decent game with it.
but it's still really bad at optimizing fewer than 50 entities. (just GO it, if that's the use case)
if you're planning to use it for 2D you either need to install Tiny which is a whole other can of worms.
or do the hard route of making a material for your sprites.

blazing skiff
#

any news on the network component?

gusty comet
#

@zinc plinth Oh, very cool. How does that work when you create levels though?

zinc plinth
#

levels ?

gusty comet
#

@zinc plinth Scenes, worlds, in the editor

zinc plinth
#

(you don't have to ping me everytime)

gusty comet
#

Sorry, old irc habit 😅

zinc plinth
#

and the authoring workflow is for components, I'm confused that you talk about it for scenes; and worlds are their own can of worms

gusty comet
#

Alright then, I'll just read up some more on dots (and maybe experiment with it) and then come back.

zinc plinth
#

the "authoring" workflow makes that you can add entity components as monobehaviors to the gameobject that will be converted

#

tho that's with a big asterisk

pliant pike
#

I don't suppose anyone knows if they've changed GameObjectConversionSystems recently?

#

I'm trying to get one to run some kind some code I'm even following a tutorial but it doesn't seem to work at all

zinc plinth
#

that's not helping us to help you

pliant pike
#

yeah I don't know I just thought they ran at the beginning of the program automatically

deft stump
#

the GOConversion hasn't changed

gusty comet
#

@pliant pike Give us the smallest non-working example code you could give us that recreates the issue. And what you expect would happen. And what actually happens.

pliant pike
#
public class TestGameObjectConvert : GameObjectConversionSystem
{   
    protected override void OnUpdate()
    {
        Debug.Log("Why arent you working");
    }
}```
#

that does nothing for instance

zinc plinth
#

of course it won't if your go gets converted as soon as it's instantiated

#

Start isn't even called in that instance

#

Awake will be called tho

pliant pike
#

but just going by this tutorial the guy does similar and his works

#

at 8 mins you can see the code

deft stump
#

that should work

pliant pike
#

you can't put that code on an object

mint iron
#

maybe you need live link enabled 🤔 maybe also a subscene.

low oasis
#

How would I go about getting Entities in a sorted order? Or rather, components from entities in a sorted order.
Maybe a dynamic buffer, but the only examples I see of those are very simple with one value and a specified size but my component has 5 ints, 2 bools a float and a float3.
there are a few systems that would edit this data, but for most it's read only, but still needs to be in order and traversable. Would be nice to be able to loop through it in burst compiled jobs as well. It's very confusing trying to find more specific information about ecs... Most examples are just really simple

tardy spoke
#

Has anyone run across any good recent tutorials on ECS? It seems to be evolving fairly rapidly, haha. Looking for the simplest intro around for my feeble brain.

amber flicker
#

@tardy spoke Codemonkey's are the only ones I'm ambiently aware of and I think certainly the recent ones are quite up-to-date. Not sure beyond that sorry. Unity's samples are kept fairly up-to-date and provide a reasonable reference. I'm expecting things to change a bit again within the next few months though - I think they're working on the editor, instantiating prefabs and other related aspects but the non-conversion/editor stuff has stabilised a fair bit I believe.

#

@low oasis The first thing that I think of is a sorted NativeArray or even NativeList that has been allocated using Allocator.Persistent. This can live in a system and you can get at it in other systems via EntityManager.GetExistingSystem<SomeSystem>().mySortedArray. Perhaps that doesn't answer your question - let me know

tardy spoke
#

@amber flicker Thanks I'll check them out. I got through a bit of a Udemy course (Called Unity Dots Fundamentals) that was really good at the beginning but ramped up in difficulty pretty quickly. Would likely be a good pace for fairly competent programmers, but I got fairly lost, haha.

Just skimming through the ECS codemonkey's videos on YouTube this is pretty much exactly what I was looking for! Thanks.

amber flicker
#

Awesome - thanks for letting me know that Udemy course exists - especially if it goes fairly deep into some things - useful to know what materials are out there

tardy spoke
#

Yeah, he builds the whole game in 6 hours, so it's nice because the course is on the shorter side - but the downside of that is it moves fairly quick and skips some theory.

#

Also I have a question for people experienced with ECS -

I'm working on a game that will eventually likely end up being done in ECS as it's a very suitable use case for it (large numbers of players/enemies tracked on a SpatialOS server).

I currently suck at ECS, and the game is just starting to be built.

Is it likely more efficient to:

A) Build what I can in regular Unity programming style then convert it down the line to ECS when I'm more familiar with it.

B) Just start building the whole thing in ECS even though it'll cause the progress to be slower at first.

zinc plinth
#

Game Academy.school's tutorials are up to date and I learned way more from them than from codemonkey

#

@tardy spoke B

#

because you'll have to rewrite from scratch anyway

tardy spoke
#

Thanks, I'll take a look at them as well.

amber flicker
#

My opinion: If you plan to release within 1-2 years and it's a somewhat commercial enterprise, then maybe A. If your livelihood doesn't depend on it, you want to also get into dots and you like pain, then B. As an example, I simply can't build my project at the moment (it compiles fine). That isn't uncommon atm but of course will improve. Once you get into dots I think it's hard not to want to do everything that way.. but in reality, you could just use it in a more targeted fashion for perf critical points like pathfinding. In reality people so often are more gpu bound than anything and optimising things like many units usually requires gpu animation via textures.

zinc plinth
#

some game genres are way more cpu than gpu bound tho

tardy spoke
#

Nah, it's a hobby/experiment my friend and I are just doing for fun and unrelated to finances, haha. We're definitely picturing a 2-5 year range for the project to finish, if ever. It's a big one.

amber flicker
#

Then B 😄 - go have fun!

tardy spoke
#

Lol, it's a bizarre project. We're attempting to make a VR MMORPG that runs on Oculus quest for kicks. The CPU/GPU restrictions are unbelievable. Has to run 72FPS with 4X MSAA minimum.

We're actually not even convinced yet that it's possible, the tests we've done so far are right on the line.

amber flicker
#

on quest you get 4xmsaa pretty much for free I believe but certainly, it's a tricky target - trying to remember the quest game I saw with thousands of units/characters

tardy spoke
#

Yeah, I'll have to look into that because I have it set to do 4X MSAA on URP so I'll have to see how that's being applied

amber flicker
#

gpu animation will do a lot for you I'd say - be sure to avoid Unity's animator controllers etc

tardy spoke
#

Yeah, I'm going to need literally every possible optimization. It's a hilariously fun project though. Super challenging.

amber flicker
tardy spoke
#

Haha I have a list of resources that I'm throwing all these links into for when I need them in 1+ year, haha. 🙂

#

Simple but very fast GPU vertex shader based animation system for Unity.Entities lol well that's perfect because we're using vertex colors with no lighting

tardy spoke
#

Just watching some of these tutorials - any workflow benefits from using the conversion workflow vs pure ECS either way?

It seems like my friend who is doing the level design might appreciate being able to put characters and stuff where they're supposed to go as opposed them just being invisible until runtime? Is the conversion workflow pretty much the standard approach?

gusty comet
#

conversion is the only direction for the unity devs as far as I understand it

#

pure ecs is a thing of the past really, you can go out of your way to achieve that, but Unity doesn't really care about that anymore

#

once the entire ecs ecosystem is in place, then they'll probably work on pure ecs, since at that point it makes total sense

#

but that's years from now

#

literally

tawdry tree
#

There are a couple ways to do conversion, though they share a lot of techniques.
One way is to use entity subscenes - they will automatically convert all objects on build. Another is to add the ConvertToEntity monobehavior.
Either way, the programmers ought to make authoring components that are handy to use for building a scene - both for their own sake with testing and development, and for any designers.

#

Realistically speaking, there are no benefits to completely eschewing GameObjects, though you want gameobjects to exist as little as possible to get the full benefits of, and to make the DOTS (coding) workflow easier.
That means GameObjects during design, of course, and you would likely also have prefab GameObjects, again made during design.
You want conversion to be pretty much part of "starting the game", and to never touch a gameobject (in code) afterwards, though at the current moment this isn't quite possible for most games.

gusty comet
#

Hi, anyone could give me a little help with rendering meshes in ecs? I've seen some tutorial but I must be doing something wrong

zinc plinth
#

if you can at all do it, use a gameobject with conversion instead of adding the components yourself

#

I have the xzjv seal of approval 😁

mint iron
#

alex is writing an essay

#

or went for a snack half way through a message

zinc plinth
#

or both Eyes

tardy spoke
#

@tawdry tree Right, so you would for example have gameObject prefabs say for certain "enemies" or something, but you're instantiating copies of those prefabs as entities when you "start the game"?

Also I'll look into the entity subscenes, because that sounds like something that would be useful.

Yeah from the videos and the way people call it the "conversion workflow" makes it sound like another common workflow exists - where as for real world applications it seems that it doesn't. Would seem like making a game with your hands tied behind your back to not be able to visualize the positioning of anything in your game at all until the game is actually started. I mean, maybe some simple simulations could be run like that, but not any sort of "game".

#

And as far as I can tell there really isn't a performance penalty for using the convert to entity mono behaviour vs instantiating via script, but I could be wrong there.

#

Haha, yeah I type a lot. Many questions! Turns out, there's a lot I don't know. 🤷‍♂️

zinc plinth
#

subscenes are a big pain to work with rn, so I'd advice to wait untill you understand more how ecs work before starting using them

mint iron
#

I tend to agree, they are very buggy, they crash my unity all the time.

safe lintel
#

the benefit is that you arent reinventing the wheel each time you want an entity, where it can easily be converted from a gameobject. there are many systems to handle conversion with more on the way and afaik unity want it to cover the vast majority of use cases.

In situations where it doesnt get converted to your liking manual conversion via the IConvertGameObjectToEntity interface can be used to explicitly describe what you want.
If you dont wish to use any of the conversion systems it might be a good idea to post on the forums to get the attention of the devs how conversion isnt handling your own use case but I think you would be fighting against the tide if you simply just dont wish to use any of this as unity consider it the official and best workflow for dots

tardy spoke
#

Right, no I have no problem with that at all, I was just verifying that that is in fact how most people are working in ECS currently. The videos make it sound like their are multiple workflows but it seems like everyone is really on the same wavelength in terms of authoring in gameObjects and converting them to entities at runtime. Makes sense to me.

mint iron
#

there really isn't a performance penalty for using the convert to entity mono behaviour
runtime conversion we were told has been abandoned, its likely still only around until sub-scenes are reliable enough. But more to your comment, there is a cost compared to sub-scenes, it might be small if you're not converting much, but subscenes pre-convert all your stuff in the editor and save it as a blob that can be pretty close to being straight copied into the format a world requires. that means you can load heaps of data really fast with no/minimal processing on it. At least that's the dream.

zinc plinth
#

a really big thing is also to have entity prefabs; to avoid spawning a GO each time you want an entity

tardy spoke
#

I have an additional question if anyone wants to answer it, but feel free not to because it's kind of a vague question.

Is virtually every ECS programming operation done with the foreach loop method on the components? Is there any common operations BESIDES that, or is that pretty much "what you're working with" and you just figure out how to solve your "problem" within that limitation/structure?

#

Also isn't this just turning into LISP programming? Hahahah

#

Moving modern programming back to ideas that came out in 1960 (which were really good ideas).

zinc plinth
#

well, on must stuff you want to "process action on all components of archetype X"

tardy spoke
#

Yeah, that's what I mean. On most things, that's what you want to do - but CAN you do anything different?

#

Or rather than "can", SHOULD you ever be doing anything different? Or is it all ideally performed within that one structure? ForEach --> if it has these components --> do action.

zinc plinth
#

well jobs can hide the loop from you and have the index in your Execute, but appart from that I don't see how you would do it diferently

and ecs is completly built around component iteration, that's why we can care about cpu cache lines

deft stump
#

Even if you were to collect the components via query, store it in a native array, then do operation on. You would have to for loop it any way

tardy spoke
#

Right, so the correct approach is to try is to frame your problem so that it's solved by that ForEach process - virtually regardless of the "type" of problem, whether you're manipulating 1 entity with ECS or 100,000, correct?

#

Like if I want to just move my player character 2 inches to the left, still runs through the loop, correct? Because the memory has been optimized via ECS to be efficient at that operation even if it's cycling through everything just to find the one entity?

zinc plinth
#

even if you only have 1 instance of your "problem" in the current world; you'll put a loop on it just in case there's more than 1 instance of it at some point

tardy spoke
#

Right, to me that makes a lot of sense.

zinc plinth
#

by doing so you avoid alot of troubleshooting of not doing loops too

tardy spoke
#

ECS to me makes a lot more sense than MonoBehaviours from a practical standpoint, but my background isn't OO. I'm a lousy javascript programmer that does mostly functional.

tawdry tree
#

@tardy spoke Give an entity the Prefab component and store the reference, then you can spawn a copy in pure ECS with EntityManager.Instantiate(Entity).
I always have a simple authoring component for Prefab which just adds the Prefab component to the entity on conversion, and you could have separate conversion scripts that, say, store the entity reference to somewhere useful (such as handing it to a system)

tardy spoke
#

That's a great idea

zinc plinth
#

^ doing this for my grid tiles went from creating 10K+ GO and going through conversion for all of them and having 10s+ load time; to having a entity prefab of it and loading in less than a ms

tardy spoke
#

That's awesome! The decrease in loading time wouldn't go amiss for sure.

tardy spoke
#

Woah, those subscenes look super cool. My solution for running a 20km map in VR without huge jitter problems was something along these lines - https://youtu.be/FwNMUCqKsz4 - but I'm thinking if SubScenes are coming down the line I could just do a "regular" floating player origin and load small sections of the map without even implementing the static "physics world" as I demonstrate in that video - since you're only dealing with maybe several hundred moving colliders per "level", it may not be the same computational problem it was with monoBehaviours.

If ECS can handle dealing with a lot of moving colliders more efficiently it'll save me a ton of headaches, haha.

#

Actually if the subscenes reset the origin point, which they most likely do, then I actually don't have to do any of this... hahaha.

zinc plinth
#

I would be really surprised if they do @tardy spoke

those entities are in the same world as the rest, so their LocalToWorld refer to the same thing

pliant pike
#

@mint iron Thanks for that suggestion, it appears you do need a converted subscene for gameobjectconversionsystems to run, just converted a random cube, and they work, Thanks

tardy spoke
#

@zinc plinth dang, I assumed with the mega city demo that that was exactly what they did.

Unity can get pretty shaky around 10km out from the origin due to floating point rounding errors. They're more pronounced in VR.

zinc plinth
#

as I said, "I would be really surprised if they do", as in I didn't see if they were

#

so maybe they are Shrugging

mint iron
#

you need a nasa super computer to open the mega city demo :S

tardy spoke
#

@zinc plinth Yeah, it'd be nice, but due to potential technical challenges and limitations they proooobably don't. For example, doing a physics calculations is tricky if the origin moves discretely. You could do a Continuous Floating Origin like in my video though and move the entire world in reverse (Futurama style. The ship doesn't move, the universe moves around the ship) - ECS would probably actually be ideal for that. The issue is you lose static lighting and stuff doing that. And other implications of course, multiplayer requires the server to translate the location of enemies to your players local translation, etc.

zinc plinth
#

you could apply some lense effect via shaders to make it seem as tho the objects are far away but in reality they're not that much

#

would keep your in the "safe" float range

icy kestrel
#

Can anyone explain why this piece of code only works when the for loop runs once? I've started it at different points but if it runs > 1 time my CPU usage goes up to 100% and the game never starts. This is just inside a Start() function. (Not using DOTS, just Job System)

zinc plinth
#

then it's your job going in endless loop

#

debug it

icy kestrel
#

Ok thanks

tardy spoke
#

@zinc plinth that's an interesting idea and i've never seen that done. Also unfortunately I don't think I'm good enough with shaders to be able to make that work, haha. Off topic - I was going to look into if it's possible to create a shader that enlarges pixels to use as a "low poly"-esque sniper rifle scope in VR, haha. I imagine it is, but my knowledge is pretty much limited to a bit of shadergraph.

On topic - just built my first ECS component and System... it changes a component float called hello to 42 and then starts moving the component +10 increments in the 'ol Y axis... needless to say... it's incredible. 🤷‍♂️

#

I'm thinking that generally it may be more flexible to keep components holding only a singular piece of data because my instinct was to use the System in that way. I instinctively tried to use .WithAll() to filter for the float I put inside the component instead of on the name of the actual component... seems like if you keep it to a singular piece of data, you're removing a potentially unnecessary layer of abstraction between components and the data they hold. I'm sure there's exceptions to that, but that's my inclination.