#archived-dots

1 messages ยท Page 212 of 1

ocean tundra
#

oh wow

#

had no idea

#

nice find

#

ps you have the older entities version

#

latest is 0.17

sullen mason
#

๐Ÿค” does not seem to give me the option to update

ocean tundra
#

older unity version then

sullen mason
#

ah, okay.. I wonder if thats where this problem is coming from

sullen mason
#

okay, made some progress- that error has disappeared now ive updated unity and all packages,

#

getting a new error when i try and build through the windows build config asset however:

#

Build BuildConfig failed after 1.35s.
Editor's active Build Target needed to be switched to StandaloneWindows64 (BuildTargetGroup Standalone). Please wait for switch to complete and then build again.

sullen mason
#

^ ignore that. didnt see the last part there ๐Ÿ˜‚

#
    protected override void OnUpdate()
    {
        Entities.WithAll<MoveForward>().ForEach((ref Translation trans, ref Rotation rot, ref MoveForward moveForward) =>
        {
            trans.Value += moveForward.speed * Time.DeltaTime * math.forward(rot.Value);
        });
    }```
is there any way i can iterate over every second-third entity, alternating between all of them over 2-3 frames instead of all of them every frame? ๐Ÿค”
ocean tundra
#

๐Ÿ˜› thinking like a DOTS natural

#

but not really ๐Ÿ˜›

#

but if you use schedule parallel you get them all updating in different threads

#

breaking them up between different frames could be done with 2 different ways

#

use a tag component (different tags per different frame

#

or the new WithFilter lets you provide a native list of entities that the Foreach will use

#

also there a ton of issues with that code

sullen mason
#

im mostly just trying to figure out how to get the max amount of entities on screen, doing "something" at once

#

not sure if the tag solution would work well for what im trying to achieve by the end though

#

๐Ÿค”

zenith wyvern
#

You can use Time.ElapsedTime- include entityInQueryIndex in your foreach and discard indices based on the elapsed time

sullen mason
#

not sure what you mean there Sark, could you give me an example to work with?

zenith wyvern
#
var time = Time.ElapsedTime;
Entities.ForEach((int entityInQueryIndex, ref Translation translation, ..etc)=>
{
  if(!((int)time % entityCount) == entityInQueryIndex) return;
  // Do whatever
}
#

Something like that

#

That would run over your entities in order over time

ocean tundra
#

what is entityInQueryIndex?

#

i always thought it was just a int thats always the same for a entity?

zenith wyvern
#

It's just in the index of the entity for the given query. So it will always go from 0-Total#OfEntitiesIntheQuery

ocean tundra
#

yea ok so how does that work with your time if above

#

that would mean you only ever loop over every entity 1ce

zenith wyvern
#

Yeah I added a modulus to fix it

ocean tundra
#

nice

#

yea that makes sense

sullen mason
#

am I still applying WithAll here? because I now have an error:

zenith wyvern
#

Not really a sensible way to do it since you can't rely on the order of your entities, but it's a fast rough way to do what you want

sullen mason
ocean tundra
#

yea you had a tone of errors in your code @sullen mason ๐Ÿ˜›

#

cant have a component in WIthAll and also in the Foreach parameters

zenith wyvern
sullen mason
#

previously, it was:

        Entities.WithAll<MoveForward>().ForEach((ref Translation trans, ref Rotation rot, ref MoveForward moveForward) =>
        {
            trans.Value += moveForward.speed * Time.DeltaTime * math.forward(rot.Value);
        });```
#

i just tried to shoehorn the int in there ๐Ÿ˜‚

        Entities.WithAll<MoveForward>().ForEach((int entityInQueryIndex, ref Translation trans, ref Rotation rot, ref MoveForward moveForward) => {

        });```
zenith wyvern
#

And yeah what roy said, you don't use WithAll if your component is already in the query - it's implied that the component is required

sullen mason
#

@ocean tundra it was actually working (the first example) ๐Ÿค”

ocean tundra
#

your also missing Run, Schedule or ScheduleParaell

zenith wyvern
#

Is this in a ComponentSystem?

sullen mason
#

yep

ocean tundra
#

oh yea thats the old stuff

sullen mason
#

damnit ๐Ÿ˜‚

ocean tundra
#

use SystemBase instead

zenith wyvern
#

Read that page, it will explain how to write systems. It's all very detailed and up to date

sullen mason
#

sweet, thanks again ๐Ÿ‘

#
partial class MovementSystem : SystemBase
{
    private EntityQuery query;
    
    protected override void OnUpdate()
    {
        var entityCount = query.CalculateEntityCount();
        var time = Time.ElapsedTime;

        Entities.ForEach((int entityInQueryIndex, ref Translation translation, ref MoveForward moveForward) =>
        {
            if(!((int)time % entityCount == entityInQueryIndex)) return;
        }).ScheduleParallel();
    }
}```
#

looking better? ๐Ÿค”

ocean tundra
#

getting closer

#

you need

#

Entities.StoreEntityQuery(ref query) or something like that

sullen mason
#

ah rgr. explains my error

#

the example they have provided:

#
    private EntityQuery query;
    protected override void OnUpdate()
    {
        int dataCount = query.CalculateEntityCount();
        NativeArray<float> dataSquared = new NativeArray<float>(dataCount, Allocator.Temp);
        
        Entities.WithStoreEntityQueryInField(ref query).ForEach((int entityInQueryIndex, in Data data) =>
            {
                dataSquared[entityInQueryIndex] = data.Value * data.Value;
            }).ScheduleParallel();

        Job.WithCode(() =>
            {
                var v = dataSquared[dataSquared.Length - 1];
            }).WithDisposeOnCompletion(dataSquared).Schedule();
    }```
#

in Data data

#

what is this?

ocean tundra
#

magic

sullen mason
#

should mine be in MoveForward moveForward?

ocean tundra
#

in = read only

#

ref = read write

zenith wyvern
#

From the manual

ocean tundra
#

its a further optmization

sullen mason
#

how did i not see that ๐Ÿ‘€

#

i feel like this is "mt. stupid" all over again...

zenith wyvern
#

Eh, dots is super complicated, it takes a long time to grasp everything. Don't expect it to click immediately

sullen mason
#

jesus, just got "something to work", immediate performance increase with the whole schedule parallel

ocean tundra
#

yea it took me awhile

#

i always liked its ideas

sullen mason
#
    private EntityQuery query;
    protected override void OnUpdate()
    {
        var entityCount = query.CalculateEntityCount();
        var time = Time.ElapsedTime;

        Entities.WithStoreEntityQueryInField(ref query).ForEach((int entityInQueryIndex, ref Translation translation, ref Rotation rotation, ref MoveForward moveForward) =>
            {
                //if(!((int)time % entityCount == entityInQueryIndex)) return;
                translation.Value += moveForward.speed * math.forward(rotation.Value);
            }).ScheduleParallel();
    }```
#

okay, im now here

#

acceptable?

ocean tundra
#

well MoveForward could be in instead of ref

sullen mason
#

rgr,

ocean tundra
#

and your not using delta time ๐Ÿ˜›

sullen mason
#

the commented out statement caused nothing to happen

ocean tundra
#

still should follow that rule

sullen mason
#

and using delta time caused an error

#

"get_time" cant be called inside ScheduleParalle,

#

only WithoutBurst or Run

ocean tundra
#

yea

#

so that var time = Time.deltatime

#

then you use that time

#

cant use any globals or things inside the foreach

sullen mason
#

the sight of 100,000 cubes moving across the screen is oddly satisfying

ocean tundra
#

haha yea

sullen mason
#

last time i tried this was a few years ago, dont think i could get 5000 ๐Ÿค”

#

                if(!((int)time % entityCount == entityInQueryIndex)) return;```
#

so, this line really isnt working at the moment... though I have no idea what "time" is

ocean tundra
#

you probably need a seprate elapsedtime

plain silo
#

hi this isnt a DOTS question but i'm looking for an advanced developer and dont see a channel on this topic. What happens if i import some assets that use Addressables and use the asset in my scene but do not import the Addressables package? i'm able to build and run and it looks fine, and i dont see any errors even in the logs. Specifically i'm using the AR foundation Onboarding UX assets which use the Localization package.

karmic pilot
#

is the addressables package included as a dependency somewhere?

plain silo
#

in the original project but i exported the folders and imported them into my own project

#

the folders include one named AddressableAssetsData

sullen mason
#
        Entities.WithStoreEntityQueryInField(ref query).ForEach((int entityInQueryIndex, ref Translation translation, ref Rotation rotation, in MoveForward moveForward) => {
            translation.Value += moveForward.speed * dTime * math.forward(rotation.Value);
        }).ScheduleParallel();    ```
will this only iterate entities with those components?
pulsar jay
sullen mason
#

got it. i seem to gain no performance from splitting the statement into two separated by an extra component ๐Ÿค”

pulsar jay
#

why would you split it?

sullen mason
#

so i can act on half each frame

#

instead of all of them every frame

pulsar jay
#

yeah I wouldnt think that makes much of a difference

#

Did anything change about bool not being blittable? It seems like I can just use it in components without unity complaining?

karmic pilot
#

you can use it, the question is just whether it makes sense. if you are using bool in a component, I would think twice whether this is the right design and there are no alternatives

#

depending on your use case, there are multiple options available

sullen mason
#

how can I get a random float inside a lambda expression? ๐Ÿค”

pulsar jay
karmic pilot
#

I guess boolean is still not blittable in c#, but it works as a field in ECS components due to some internal logic voodoo ๐Ÿ™‚ haven't paid much attention to it, but there are no mentions of it anywhere in changelogs

#

hm, according to at least their own version history, bool has been supported since version 0.1.0 in IComponentData ๐Ÿ™‚

opaque sluice
#

how versions,ECS can in unity for LTS

low oasis
#

Trying to use System.Guid with Burst and it is complaining a lot about managed vs unmanaged code. And yet, it hasn't complained (yet) about a struct I have that is just 2 guid variables. ??

solid estuary
#

is networking with DOTS any harder than normal?

trail portal
#

Trying to free memory from NativeArray with NativeArray.Dispose and get
InvalidOperationException: The native container has been set to undisposable and cannot be deallocated. How do I free NativeArray memory?

karmic basin
#

Which allocator did you use ?

trail portal
#

Allocator.Persistent, theres no documentation on allocators

karmic basin
#

use Temp or TempJob

trail portal
#

Is there documentation on those?

karmic basin
#

Basically Temp is for the frame

trail portal
#

Temp doesnt work at all and throws errors

karmic basin
#

TempJob is around 4 frames so use it with jobs

trail portal
#

TempJob gives me the same error as Persistent

karmic basin
#

persistent is self explanatory

trail portal
#

Persistent isnt, how do you free it?

#

To me it seems like the API isn't even finished or documented yet they released it anyways.

karmic basin
#

usually you dispose a Persistent on systemBas.OnDestroy()

trail portal
#

How though, NativeArray.Dispose gives errors like I mention above.

karmic basin
trail portal
karmic basin
#

Yeah right some parts are becoming more stable, like Burst and Jobs.

trail portal
#

Soo anyone know how to create a persistent NativeArray and Dispose it?

karmic basin
#

Mind sharing some code ?

#

could be you're tryig to dispose although job isnt finished

#

things like that

#

you can also only clear it if you need

trail portal
#

In Awake

In OnDestroy

#

Used by AsyncGPUReadback each frame, which should be unused in OnDestroy?

#

And even then you cant stop AsyncGPUReadback requests all you can do is wait for it to finish, waiting in OnDestroy wont work because Unity wont be processing GPU calls.

karmic basin
#

Sorry I'm not knowledgeable with AsyncGPUReadback

slim nebula
#

I don't know of one but I definitely don't know close to everything. someone else might know

amber flicker
#

I think there's a Stop component or similar

trail portal
#

So let me get this straight, the only way to use NativeArray without errors is to create a new one every frame with Allocator.Temp? Like there's no way to allocate a NativeArray once and re use it for multiple frames? It's so bad for garbage collection...

amber flicker
#

just got to be careful dealing with statics

trail portal
#

@amber flicker Then why do I get errors?

amber flicker
#

try instead: if(narray.IsCreated) narray.Dispose();

solid rock
#

Related to DOTS - I was doing some reading in preparation for trying out the Job system for the first time recently. I saw that only NativeArray is available by default, but ECS adds other containers like Native queues and dynamic lists. Is it possible to use those advanced container types from ECS without fully embracing ECS?

trail portal
#

It is created I check in my rendering code before reading the array

amber flicker
solid rock
amber flicker
amber flicker
solid rock
#

Ok

#

Thanks

trail portal
#

Like I said its possible the async read request is not finished in OnDestroy, but Unity doesnt give you a way to wait for it in OnDestroy because no rendering code is updated/run during that.

#

So I get why Disposing of the in use NativeArray would cause errors, but annoyed that Unity doesn't provide anyway to handle this.

amber flicker
#

Could you cover this by in the async callback doing if(!narray.IsCreated) return ?

trail portal
#

Theres no async callback, it simply checks if the request is done every frame.

#

I can confirm though, it actually doesnt throw errors about 1/10 times when the async request is done.

amber flicker
#

I don't understand... you're not creating an array every frame right?

trail portal
#

No like I said above its allocated once in Awake with Allocator.Persistent

amber flicker
#

If you put something on hastebin or similar I'll take a look but I'm missing some understanding of the issue

trail portal
#

Hmm they say GetData isnt possible but I can access the NativeArray by array indexing just fine

#

That also doesnt mention the Dispose error I'm running into

#

Here's some of my code

                if (asyncReadbackSupport)
                {
                    asyncRequest = AsyncGPUReadback.RequestIntoNativeArray<float>(ref narray, renderTexture);
                }
                    //AsyncGPUReadback.RequestIntoNativeArray
            }
            if (asyncReadbackSupport)
            {
                if (asyncRequest.done)
                {
                    if (asyncRequest.hasError) Debug.Log("error");
                    else Debug.Log("test " + narray[0]);
                    readFrameDelay = 0;
                  //  Debug.Log("done");
                }
            }```
karmic basin
#

It's not the same question ?

trail portal
#

I'm not sure it depends if GetData is the same as directly accessing the native array like I do at

outputs in console with different float values, so it seems like if GetData doesnt work then direct access does?

#

But why would they be different?

#

Like I said before it seems like this API is unfinished, Unity devs themselves aren't sure what is and what isn't

amber flicker
#

wait are you overwriting your asyncrequest with the same narray?

trail portal
#

renderFrame isnt true until the last asyncRequest.done = true

#

So it overwrites the request but only after its done

karmic basin
#

Aren't you supposed to read with asyncRequest.GetData() when .done ?

#

ANyway that might not be the problem

#

But I would fetch as it's expected

hollow sorrel
trail portal
#

If its really a NativeArray you shouldnt need GetData, it should just be there in native memory...

hollow sorrel
#

i dunno about that api specifically, but isn't unity itself responsible for disposing the array returned by getdata?

trail portal
#

@hollow sorrel What does that mean?

#

I'm not using GetData.

hollow sorrel
#

NativeArray = custom allocated memory, it does not get garbage collected like .net managed memory does

#

that's why you need to manually dispose

karmic basin
hollow sorrel
#

ah yea looks like you are responsible for RequestIntoNativeArray according to that link

trail portal
#

Well RIP guess its not possible then

#

Yes I repeat my statement, this API is not ready.

#

Also seems to just randomly crash my editor when using AsyncGPUReadback, but thats unrelated to NativeArray's.

karmic basin
#

And looks like also there's a completion callback.

stone osprey
#

How do we handle "dependencies" between entities ? I have a mob which looks like this : Entity{ Mob, ..., Localisation{ name:"Wolve", ... } and a popup entity which looks like this : Entity{ Popup, Localisation{ popupTitle:"Select action on $", ... }... The problem is the following, as you can see, theres a placeholder in the popup title, the $ which is quite important. Because i wanna change its title quite easily ( reusing that popup for different entities ). And thats the problem, the spawned popup should use the "localisations" from the entity it was spawned from. How do (could we do) that ? :/

night venture
#

@stone osprey you want compoA form entityA get access to compoB from entityB ?

warm panther
#

Can I have a Singleton that is defined by two components? (I have a value component and would like to have a tag that makes this entity the one whose value is relevant; but I'm struggling at reading a single value from
GetSingletonEntity<Tag>)

#

EntityManager.GetComponentData<FloatingPosition>(GetSingletonEntity<TagFloatingOrigin>());

#

I'd really like to not go through the EM here.

night venture
stone osprey
#

@night venture Not really... i want that entity A uses data of Entity B in general... Like theres a entity acting as a "Name provider" and one that is the "Name receiver"... in this case the mob is the first one and the popup the second one

zenith wyvern
warm panther
#

Yeah but the data I care about is in another component.

#

Not in the tag.

night venture
zenith wyvern
#

Oh I see what you mean

warm panther
#

The tag is an empty struct. ๐Ÿ™‚

stone osprey
#

@night venture Theres a "SpawnPopUpOnClickSystem" i wrote ^^

warm panther
#

Alternative is to make a system that at some point copies the value into a singleton component. This is what I currently have, and it's nontrivial because of some timing issues, and also requires a standalone entity to hold this component (or duplicating a double3 data on an already pretty large entity)

zenith wyvern
night venture
warm panther
zenith wyvern
#

No, the extension method would be for SystemBase

#

Just to easily wrap that behavior in a simpler call

stone osprey
#

But well... i should ask my questions in a different way : I want an entity ( Mob), which spawns on click a Popup. That popup should show the name of the entity which "created" the popup. How would you do that ? ^^

#

And it should be pretty flexible*

warm panther
#

What is this sorcery? ๐Ÿ˜„

zenith wyvern
warm panther
#

Yeah not the prettiest line of code up there.

#

I don't know, am I not introducing yet another sync point by speaking to the EntityManager?

night venture
#

sorry, wrong destination

zenith wyvern
#

It's not like a "structural change" sync point where it's forcing all jobs to complete - since you're only reading components it would only force jobs to complete which are writing to those components. But thinking the call is ugly and trying to avoid reading on the main thread are two different problems, which are you worried about?

warm panther
#

Call isn't THAT ugly.

night venture
#

@warm panther i could try helping you if you explain me what Can I have a Singleton that is defined by two components? is

warm panther
night venture
#

that's not a singleton...that's...how wat it called...composition?

#

hold a sec

warm panther
#

Wat.

#

A singleton is anything of which there is only one instance.

#

I guess my deeper issue here is, what does GetSingleton<ICD> do under the hood that makes it acceptable over all the other ways like GetComponentDataFromEntity<...> with a query; especially when there really is only one entity.

night venture
#

let me explain first, ok?

#

you said "Only one entity exists that has both component A and B"

#

then, the singleton is the entity, not the component

stone osprey
#

@night venture That is possible... but it is actually pretty inflexible ๐Ÿ˜ฎ There must be a smarter way to create a popup which uses the data of a mob

warm panther
#

But Unity's implementation after some digging expressly disallows this type of composed Singleton.

zenith wyvern
#

Wait you mean the code you posted where you get the tag entity then get the component via that entity isn't working?

warm panther
#

So that answers my question, which is sad, but I guess this won't be a performance issue where I need to use it.

night venture
night venture
warm panther
warm panther
zenith wyvern
#

There is HasComponent

warm panther
#

(getting an omega man vibe here)

warm panther
night venture
warm panther
#

I'll just ensure the tag is never somewhere it makes no sense.

warm panther
night venture
#

for example, i could foreach.has_brain.dont_have_heart

#

Entities.WithAll<brain>.WithNone<heart>.Foreach <-non-working humans

zenith wyvern
#

I don't know, I've met some pretty heartless people who claimed to have brains

warm panther
#

Concrete examples:

  • I have space ships, these have a position
  • I have a tag, this is the focused ship and camera centric origin for the renderer (used by my own TRSToLocalToWorldSystem)
  • now, that tag only makes sense when it exists on an entity that has a position, and that tag also only ever exists once.
  • if I focus another ship, the tag gets removed from one and added to the other.
  • the system that does the camera centric rendering then calculates the data from the new "origin" singleton, which is that other ship.
night venture
#

you are making a "current selected ship" tag?

warm panther
zenith wyvern
warm panther
# night venture you are making a "current selected ship" tag?

It's more complex than that, but yeah, for all intents and purposes, I am doing that. But I don't care at all about the selection tag, I care about the data that is associated with this. But I don't want to copy the data into the selection tag - it's a double3 and there will be more; and this is actually one of the biggest entity types in my game already.

warm panther
safe lintel
#

sorry, whats the actual issue with the concrete example?

warm panther
night venture
zenith wyvern
#

Can't you just do a ForEach that includes your tag

#

By your own description it would only match one entity

night venture
safe lintel
#

you could use the chunk.HasComponent to process that particular tag?

night venture
#

but i vn't been able to understand what is his question/need so far

#

xD

warm panther
#

In the end it's 3 lines of code but this derailed into a discussion whether a Singleton is still a singleton if it has more than one component.

#

๐Ÿ˜„

night venture
#

so the problem is you dont like/looking for something better than entities.withall<selection_tag>.foreach ?

safe lintel
#

whats the issue making a query that specifically includes the tag? i guess id need to see more code to understand why your trying to avoid entitymanager ๐Ÿคท

warm panther
# night venture so the problem is you dont like/looking for something better than entities.witha...
            var position = EntityManager.GetComponentData<FloatingPosition>(GetSingletonEntity<TagFloatingOrigin>()).position;
            var floating_to_local_to_world_job = new FloatingToLocalToWorld()
            {
                origin = position, 
                RotationTypeHandle = rotation_type, CompositeRotationTypeHandle = composite_rotation_type, TranslationTypeHandle = translation_type, ScaleTypeHandle = scale_type,
                NonUniformScaleTypeHandle = non_uniform_scale_type, CompositeScaleTypeHandle = composite_scale_type, LocalToWorldTypeHandle = local_to_world_type, LastSystemVersion = LastSystemVersion
            };

I look for something better than the 1st line, ideally with the semantics of a singleton:
-> having the tag on an non-floating entity means there is no origin.

#

(or being disallowed to place the tag, but that's probably against ECS principles)

night venture
#

talking about the first line only, that's probably the best way to do it, although i wouldn't use a singleton

zenith wyvern
#

That seems like the right way to do it to me. If you wanted to avoid syncing your data on the main thread you can replace the GetSingleton stuff with a Job.WithCode where you pass in a NativeReference to retrieve your origin data that you then pass into the next job(s)

safe lintel
#

you could use cdfe inside the job itself, but at the end of the day I think you're already doing the preferred way

warm panther
zenith wyvern
#

And I will say although it might seem ugly it is very easy to understand what you're doing with that code which is worth something

warm panther
#

I agree.

night venture
safe lintel
#

did you want to avoid tying the system to requiring the singleton? could just make an if hassingleton statement

warm panther
#

And it will guaranteed crash if there's a bad Singleton entity configuration, which is good.

night venture
#

a bad singleton configuration is bad xD

warm panther
#

My previous solution copies the data, but that's actually worse and that's how I got here ๐Ÿ˜„

safe lintel
#

two things, could move the system into a specific systemgroup that has other sync points, use cdfe inside the job, or just shrug and not worry ๐Ÿ™‚

karmic basin
#

@stone osprey I wouldnt do UI nor Localization with dots. At least not this year ๐Ÿ™‚

warm panther
#

So it begins... ๐Ÿ˜„

#

By removing 1 system and 2 writes, and several lines of code (net), I now resolved my annoying race conditions that caused the origin to jitter because it could be updated at the wrong time.

Not counting this lengthy discussion here, this was most economical. ๐Ÿ™‚ Thanks all, though, it was important to explore the intricacies ๐Ÿฆ†

stone osprey
#

@karmic basin Oh i dont use dots for UI ๐Ÿ˜„ Only for the UI's DATA. Not for rendering it etc.

warm panther
#

Wow ShareX melts when capturing from that screen. This runs at 120 fps, never mind the video.

stone osprey
#

@night venture The problem i see in this solution is... that its hard coded and runs every frame...

#

Its just not flexible

night venture
#

inside SpawnPopUpOnClickSystem

#

couldnt u?

warm panther
#

Hmmmmmm.

#

The RequireSingletonForUpdate somehow makes the system show up as only working on the origin entity. I'll use a TryGetSingleton instead but that's unexpected.

#

Really interesting insight... this may be editor only, because the rest does move.

#

Ah duh.

#

There's an archetype selection field at the top

#

So works as expected. ๐Ÿ™‚ Progress!

#

Also, 69 matching entities, nice.

night venture
#

glad to hear.

stone osprey
#

@night venture Well i think im just gonna do it like you said... cant find a nicer way. Probably this is also "clean" :


Entity{ Mob, Localisations{ name:"Wolve" }, OnClickPopUp{ popUpType : "type", localisations : ...}}

OnClickPopUpSystem then "copies" the localisations component into the "OnClickPopUp" component which gets processed by another system to make the popup spawn. The popup gets a copy of that
#

Besides that im struggling with another issue.

stone osprey
#

I have the popup and the mob. A click on the mob opened the popup. When i click the popup, i wanna make my player run to the mob. Sounds simple... probably i made it a bit too complex. But for the future i probably dont just wanna run to the mob that spawned the popup. So i thought about splitting it up like this...


public struct OnClickMove{

  public enum Who{ CLICKER, CLICKED, BOTH }
  public Vector2 position;
  public Who whoShouldMove;
}

public struct OnClickMoveToEntityThatWasClicked{}

Entity{ PopUp, OnClickMove, OnClickMoveToEntityThatWasClicekd }

Entities.ForEach((Clicked, OnClickMoveTo, OnClickMoveToEntityThatWasClicked, PopUp) => {
   // Determine the entity that was clicked, copy its position into the OnClickMove
});

Entities.ForEach((Clicked, OnClickMoveTo) => {
  // Make entity move to position
});
#

Is this too atomic ?

#

So i kinda thought about a "OnClickMove" struct... which contains a pos... and when its combined with "OnClickMoveToEntity" we copy the entity position inside it to make the entity move to that position.

#

This could be extended in the future... so for example if we wanna move to a random location upon click we could simply have something like this Entity{ OnClickMove, OnClickMoveRandom} and a system which generates a random position and copies it into the OnClickMove

#

Is this too complicated ?

night venture
#

@stone osprey believe it or not. this could be handled on a similar way as what @warm panther was doing

#

add a tag (empty component) to the mob you are clicking [ie: focusing]. trigger a system to move player to entity_position_which_has_focus_component

stone osprey
#

Isnt that what im doing in my example above ? My tag component is "Clicked" and the only difference here is that i have a "OnClickMoveTo" and a "OnClickMoveToEntityThatWasClicked"

#

I actually just wanna know if its too atomatic to have a "OnClickMove" that stores a vec2 and a "OnClickMoveTo..." which defines where we wanna move and copies that location inside "OnClickMoveTo" ๐Ÿ˜„

#

So kinda like a consumer/producer

night venture
#

I'm not storing the position, but moving to (focused) entity position.

stone osprey
#

Ah i see ^^ but in general im just confused about one aspect

#

There so many damn ways.

night venture
#

xDDDD

#

let me give you my personal advice after years of coding

#

do it any way...it doesn't matter if good, perfect, chunky...

#

you'll always have time to improve it

#

otherwise, at the end of the day, you wont have anything

#

talking about crappy things: Another newbie question!

my tile can have either a road or sidewalk component.
if it's a road, material.color (not an sprite yet) would be black.
else, if its a sidewalk, would be grey.

ie: component implies color + component change material color

whats the correct way to do this?

stone osprey
#

What i actually mean is... We could either have one huge component OnClickMoveTo{ exact definition of where in which case }
Or we could split it up... like OnClickMoveTo{ pos } and OnClickMoveToPositionProvider{ ... }
So how do we decide what a component should contain ? When do we split them ? When do we merge them ?

night venture
#

knuth rules!

stone osprey
#

The disadvantage with huge components is... that they are mostly to inflexible. What if we wanna move to a random location ? Well we need to edit the component and add new functions to it or whatever.

#

We could also have only specialised components like OnClickMoveToClickedEntity and without having a OnClickMoveTo

#

But i have no idea where it makes sense to have which one

night venture
#

do one thing. tiny, simple, even dumb...but do it fine

gusty comet
#

Do you guys have any idea how can I remove some things (children objects or classes from MB)
before conversion happens?
im using

public class PlanetAuthoring : MonoBehaviour, IConvertGameObjectToEntity
night venture
#

a job that moves from A to B is much better

night venture
stone osprey
#

Whats a linux binary approach ? xD

night venture
#

do one thing. tiny, simple, even dumb...but do it fine

stone osprey
#

So just splitting every component till its atomic ?

night venture
#

to sum up...

stone osprey
#

Thats tiny, simple and will do it fine

night venture
#

+1 for We could also have only specialised components like OnClickMoveToClickedEntity and without having a OnClickMoveTo

#

@stone osprey look, here i got an example....

#

quoting myself:
talking about crappy things: Another newbie question!

my tile can have either a road or sidewalk component.
if it's a road, material.color (not an sprite yet) would be black.
else, if its a sidewalk, would be grey.

ie: component implies color + component change material color
whats the correct way to do this?

#

my brain just come out with a "probably bad" idea: a job which, depending on each component, set material.color.
it would be a pita...like if(road) color=black, if(sidewalk)color=grey

#

and that's propbably not even ECS correct

#

but, once done, i can improve it as much as i want

#

so...i'll give it a couple more minutes to someone come and tell me the CORRECT way, or ill do that monkey-code and keep moving forward

stone osprey
#

Hmmm... im always looking for a beautifull and flexible way. But i somehow get the feeling that theres never one. I just wonder how "big" game developers do this. Because when i watch at their code, it always feels "perfect". Minecraft bedrock is a great example. They are using an ECS and theres a wiki where they exposed their components and their data... and it makes perfectly sense how they did it.

night venture
#

are you getting paid for your game coding skills?

stone osprey
#

No xD

night venture
#

once you do it, you'll have learned enough to do as they ๐Ÿ˜‰

stone osprey
#

Thats true ^^ but they still need some criteria's i guess. To split components up or to determine what components they need for what tasks. Furthermore im a ... how you call it in english... a "perfectionist". I hate it when something ugly or inflexible.

night venture
#

having SOMETHING is probably ahead than 90% of people

#

it took me years to learn that

sturdy rune
#

and you can always come back to it

#

that's why ECS is awesome

#

systems are decoupled

#

or should be

night venture
#

and now...TileColorSystem xD

sturdy rune
#

think of writing drivers for an embedded system. you want to be able to rewrite them but some times it is about getting the job done

#

and like, optimization code can get insanely UGLY but it does a way better job than what your beautiful code might do

stone osprey
#

Well thats understandable :/ I also get the feeling that sometimes scripting makes more sense. For example in my "OnClick" example above, it would be way easier to just execute a callback that determines that happens upon clicking that entity... like OnClick{ Action<Entity,Entity> onClick } and then we could hook a method, lambda or interface in it to execute the logic. Because such "do something upon click" logic is pretty hard to convert into data

#

Positions, Transforms, Players, Mobs, Stats even Buffs are all data... but probably its just not so clean to convert "OnClick" logic into data.

night venture
#

events are not data

#

events trigger data changes

#

events=>systems

stone osprey
#

Yes of course... but the data changes are often hard to express as components. Like you have a wanna make a entity teleport away upon click... its probably easier to express them as callbacks instead. But thats not ECS like

night venture
#

click->trigger job(system) to move object

#

do you remember my question about how to set color on tiles...?

#

ugly as fuck, but already working and i can move forward:

public class TileColorSystem : SystemBase {
    public void colorize() {
        Entities.WithAll<RoadComponent>().ForEach((ref RenderMesh mesh) => {
            mesh.material.color = Color.black;
        }).Run();
        Entities.WithAll<SidewalkComponent>().ForEach((ref RenderMesh mesh) => {
            mesh.material.color = Color.grey;
        }).Run();
    }
    protected override void OnUpdate() {}
}
#

perhaps tomorrow, i'll try improvements

stone osprey
#

Hmmm... ok, probably i still need to learn that its about to get things done. Not about over engineering the code till you can sell it as a NFT

night venture
#
Entities.WithAll<RoadComponent>().ForEach((ref RenderMesh mesh) => {
    mesh.material.color = Color.black;
}).Run();

complains with:
Entities.ForEach uses ISharedComponentType RenderMesh. This is only supported when using .WithoutBurst() and .Run()

Googling a bit, but if anyone know how to solve it, I'll appreciate the paste ๐Ÿ˜‰ @turbid sundial

ocean tundra
#

@night venture ๐Ÿ˜›

#

it clearly says

#

use .Run and .WithoutBurst()

night venture
ocean tundra
#

you need without burst before run

night venture
#
        Entities.WithAll<RoadComponent>().ForEach((in RenderMesh mesh) => {
            mesh.material.color = new Color(1f,0f,0f);
        }).WithoutBurst().Run();
ocean tundra
#

yea

#

oh

night venture
#

its not working for other issuesxD

ocean tundra
#

your mesh is marked as in

acoustic spire
#

Is Unity Tiny compatible with the main DOTS and its desktop platforms?
I see it's mostly focused on web and mobile and contains some tasty packages like UI and Text which don't exist in Entities package

ocean tundra
#

and im pretty sure rendermesh is a class not a struct

gusty comet
#

how to set local position in dots?

ocean tundra
#

so no in or ref

night venture
#

btw...do you guys do manager = World.DefaultGameObjectInjectionWorld.EntityManager; on each class? do u setup a singleton? am i missing something?

gusty comet
#

i do translation.Value =

#

but its world position

night venture
ocean tundra
#

@night venture in Systembase EntityManager exsists as a property

#

in = readonly

#

ref = read write

#

for STRUCTS

night venture
#

dont lie

#

ref=reference ๐Ÿ˜›

ocean tundra
night venture
#

i used ref, but it was complaining...before reinventing the wheel, let me repeat the question:

ocean tundra
#

dont use ref

#

dont use in

#

just a normal parameter

night venture
#

talking about crappy things: Another newbie question!

my tile can have either a road or sidewalk component.
if it's a road, material.color (not an sprite yet) would be black.
else, if its a sidewalk, would be grey.

ie: component implies color + component change material color
whats the correct way to do this?

gusty comet
#

authoring

ocean tundra
#

@night venture Are you using Hybrid Renderer? and _V2?

night venture
gusty comet
#

kinda everything is very complex

#

in ecs

ocean tundra
#

else what your doing should work once you fix the parameter

gusty comet
ocean tundra
#

@gusty comet btw your not on latest docs

gusty comet
#

you would think its some dots' version of transform

ocean tundra
#

yea it is a dots transform system ๐Ÿ˜›

gusty comet
#

why are they showing these diagrams with different orders? what does it mean

ocean tundra
#

everything that made up the old transform system isnt 100% needed in dots

#

you can have transforms with only positions (translation)

#

no scale or rotation if you wanted

gusty comet
#

i need localposition tho(set)

ocean tundra
#

plus they are explaining how to extend/replace parts of it if you need

#

yea so translation will be local to parent

#

@gusty comet yea in your child you should just be able to set translation and that is 'local' space

gusty comet
#

i set translation value of child

#
            translation.Value = orbital;
ocean tundra
#

how/where are you setting it?

gusty comet
#

but it works not the way it worked with localPosition assign

#

OnUpdate

ocean tundra
#

yea a bit more then that:P

#

code?

#

and your 100% sure your not setting parent translation as well?

night venture
#

ok...going back to the previous message where i refered my previous message and so on:

my tile can have either a road or sidewalk component.
if it's a road, material.color (not an sprite yet) would be black.
else, if its a sidewalk, would be grey.

ie: component implies color + component change material color
whats the correct way to do this?

Im actually invoking a class method which contains:

Entities.WithAll<RoadComponent>().ForEach((RenderMesh mesh) => {
    mesh.material.color = new Color(1f,0f,0f);
}).WithoutBurst().Run();
ocean tundra
#

if your project is setup for hybrid and v2

gusty comet
#

ohh

#

maybe it worked all along roycon

#

i jsut didnt realize cus my orbit lines dissapeared kek

#

but it indeed follows them

ocean tundra
#

@night venture if its not setup for v2 i thought that would have worked, but ive just reread the sharedcomponent doc and not sure you can edit those in a ForEach

#

since is a memcoppy under the hood

gusty comet
#

wat

night venture
ocean tundra
#

ok so use matieral overrides

#

you should just be able to add MaterialColor and it will be happy

night venture
# ocean tundra ok so use matieral overrides

to double check if i understood:

[MaterialProperty("_Color", MaterialPropertyFormat.Float4)]
public struct MyOwnColor : IComponentData{}

and selecting MyOwnColor instead of renderMesh in foreach?

ocean tundra
#

Yea that should work

#

But they're should be a built in one you can use too

#

No need to create a custom component

night venture
#

SpecularColor?

ocean tundra
#

Materialcolor

night venture
#

BaseColor..i dont see MaterialColor

ocean tundra
#

Hmm it was in the docs

#

Base color sounds right tho

night venture
#

anyway, withouburst+run and no ref should work and im getting another error, so im going to fix that first

ocean tundra
#

No I don't think we can editor shared components in foreach

#

I thought we could

#

But not sure now

#

I honestly don't use them much

#

I've only built 1 to split up my rts entities by player

night venture
#

ok....without the material color change(the code above), every tile is created and visible (i setup a default blue)

#

but, once the code is present, it shouts:
InvalidOperationException: object is not initialized or has already been destroyed

my concern is...how i know, in a parallel world, if objects are created?

#

i think you may need more code....

#
for (int i = 0; i < list.GetLength(0); i++) {
    for (int j = 0; j < list.GetLength(1); j++) {
        tiles[i, j] = EntityManager.CreateEntity(archetype);
        //FIXME here cause its like adding default color :P
        Material material = new Material(Shader.Find("Standard"));
        material.color = Color.blue;
        EntityManager.AddSharedComponentData(tiles[i, j], new RenderMesh {
            mesh = mesh,
            material = material
        });
        EntityManager.AddComponentData(tiles[i, j], new Translation {
            Value = new float3(i, 0f, j)
        });
        foreach (ISerializableComponent c in list[i, j]) {
            c.addComponent(EntityManager, tiles[i, j]);
        }
        Debug.Log("here OK...");
        new TileColorSystem().colorize();
    }
}
ocean tundra
#

well you cant new up a system like that

night venture
#

"neither" create entities like that...

#

lets go one battle after another

ocean tundra
#

you can create entities like that

#

tho i would use a prefab rather then archetype, they both do the same thing

night venture
#

isn't better to use buffer...whatever or another system instead of a loop?

ocean tundra
#

meh its fine

#

this is loading code

#

you should have some sort of loading screen anyway

#

yes you can get more performance out of the batch entity manager APIs or using a Entity Command Buffer

#

but both add complexity for code that probably dosnt need it

#

if this was every frame then yes, use those

night venture
#

ok...we'll take on that tomorrow

#

what about the colorize system?

#

it is a "good" approach?

ocean tundra
#

so you cant new up a system like that

#

no

night venture
#

(beside is wrong)

ocean tundra
#

you can just remove that line

#

and let the default system creation handle it

#

it wont run if theres no entities matching its query

night venture
#

but there are...roads are still present

#

i mean...please, have in mind the objective and the approach

ocean tundra
#

??

night venture
#

my tile can have either a road or sidewalk component.
if it's a road, material.color (not an sprite yet) would be black.
else, if its a sidewalk, would be grey.

ocean tundra
#

yea

night venture
#

im using a system to change color. is that ok?

ocean tundra
#

the system will still exist and run

#

just as a normal system, not part of this loading code

night venture
#

ok...

#

and u telling me not to invoke the method

ocean tundra
#

no

#

it wont work

night venture
#

but let the system do that....oncreate?

ocean tundra
#

??

night venture
#
public class TileColorSystem : SystemBase {
    public void colorize() {
        Entities.WithAll<RoadComponent>().ForEach((RenderMesh mesh) => {
            mesh.material.color = new Color(1f,0f,0f);
        }).WithoutBurst().Run();

        Entities.WithAll<SidewalkComponent>().ForEach((RenderMesh mesh) => {
            mesh.material.color = new Color(0f, 1f, 0f);
        }).WithoutBurst().Run();
    }
    protected override void OnUpdate() {}
}
ocean tundra
#

for systems that do stuff ONCE to a entity a good idea is to use WithAll/WithNone
and a entity command buffer so it only runs once

#

yea so that will work fine, but it will be setting mesh color every frame

#

even after its already set it

#

oh also its not in onupdate

night venture
#

no...that's why is not made every frame, but once

#

i want to change the color/sprite/whatever once

ocean tundra
#

i wish unitys docs supported contributions

night venture
#

so, it's my understanding to invoke a function who does it

gusty comet
#

What happens to monobehaviours when authoring/converting?

ocean tundra
#

so you should use the tag / with none pattern

night venture
ocean tundra
#

grab a entity command buffer
in your foreach do your material set
then add a tag component, this tag component should be in your Foreach query .WithNone

gusty comet
#

Oh

night venture
#

gameobjects destroyed, monobehaviours are code...

gusty comet
#

But hes still in memory

gusty comet
#

I mean your scene size is bigger with all these monos and their public vars

ocean tundra
ocean tundra
#

oh a easyier option (but maybe not better) is to grab the existing system and then call collerise

#

World.GetExistingSystem<SYSTEMNAME>().collorise

night venture
# ocean tundra yea exactly

that sound ugly...apart from that, it would create a scalability issue if i want my systems to setup several things...one "colored", another "decorated", another "...".....

#

there might be a better option

ocean tundra
#

@night venture its actally a very common pattern in DOTS

gusty comet
#

I still havent figured out how to remove child before conversion happens

ocean tundra
#

how are you converting?

gusty comet
#

Authoring

ocean tundra
#

i mean subscenes or converttoentity

gusty comet
#

Latter

ocean tundra
#

theres a stop convert or something like that

gusty comet
#

Oh

gusty comet
#

Nice lol

#

Theres component like this

night venture
ocean tundra
#

yup both work

#

tags dont really take up space

#

so dont really need to worry too much

night venture
#

is there a way to crate tags "dinamically" without the incredible burden of creating a file, naming it, opening in the editor... ?

ocean tundra
#

nope

#

dots hates that

#

all code must exist at compile time

#

it dosnt even like generics

gusty comet
#

Can you deactivate entity

ocean tundra
#

yea

#

theres a Disable? Disabled? Component you can add

#

BUT from memory it didnt disable children

#

that may have changed

gusty comet
#

I need to either destroy entities or deactivate mesh

ocean tundra
#

theres also a DisableRendering or something

night venture
#

as far as you know...is there a way to have a system "sleep" until you wake it up or to run a job doing something like....
new SystemBase({}).Run()

im still trying to bypass that "pending_color" tag at all costs xD

ocean tundra
#

RequireForUpdate maybe

#

There's a require singleton too

#

That's probably what you want

#

Do you loading, then at the end create your singleton 'trigger' entity
Your system will 'sleep' waiting for that, it runs, then at the end deletes the singleton

night venture
#

sounds good...you said RequireForUpdate ?

ocean tundra
#

Require singleton

#

Or something like that

#

Definitely has singleton in its name :p

#

And you do that in oncreate

night venture
#

i see...so you are creating the system/object at some moment

#

and it starts running then...as a trigger

ocean tundra
#

?? You never create the system, unity does that

#

Your just telling unity that this system has extra update rules. OnUpdate will only be called if ecs meets them

#

By default all systems have a rule requiring at least one entity to match any Entityquery

night venture
#

ok. ill have a look at this tomorrow after work

gusty comet
#

Um

night venture
#

thanks as usual, ill let you know my next issues ๐Ÿ˜›

gusty comet
#

Psychologist mode

gusty comet
#

Is it possible to store list of entities in MB and create/destroy them as appropriate? Also from mb

ocean tundra
#

probably

#

but why

gusty comet
#

I despawn models when far

ocean tundra
#

you dont really need to worry about that in dots

#

but if you do want it you should look at megacity/subscenes

#

using subscenes you can quickly remove/add chunks of a world

#

it depends on how big/complex your world is

gusty comet
#

Idk man

#

The world is moving

#

R subscenes still good

ocean tundra
#

well even if the world is moveing

#

you still must have some sort of global pos

#

then you just need to break that up into a chunk pos

#

and link subscene to chunk pos

#

the hard part is you might need to hook into the subscene load process somewhere to update the 'actual' pos of all the subscene entities

#

should be possable tho

gusty comet
#

Its space game

#

These scenes would be loaded anyway

ocean tundra
#

sorry i was talking about all subscenes

#

ps love space games

#

๐Ÿ™‚

stone osprey
#

Im back with more questions...

I need to calculate damage and resistence.For example theres physical damage, magic damage and resistence in my game.

How would you calculate the damage when one entity attacks the other one ? Do we need a formula or are there other ways ?

ocean tundra
#

well definitly some sort of formular

#

but also what sort of code pattern do you want to use ๐Ÿ˜›

#

simplist to understand is the event entities pattern, gameplay triggers damage somehow, spawns a 'damage' entity, this entity has the initial damage (pre resistance calc) and the target entity

#

you could also have a 'take damage' component you add to the entity, but this limits you to 1 damage source per frame

#

or a 'take damage' buffer, which is the same as the component but without the limit of 1 per frame

#

or you can get more complicated and use things like the event system ๐Ÿ˜› on the fourms

#

personally i like the buffer or the event entity aproch

#

next how 'dynamic' do you want your damage types to be

#

easiest to code/understand is FIXED, so you create a magic resistance component, a magic damage component ect and then systems to operate on them

#

adding a new damage type is a bit of work in that case

north bay
#

For simple stuff the buffer approach is fine, for everything more complicated having entities to indicate damage events is superior in my experience

ocean tundra
#

finally create systems to 'process' the damage, breaking it into some sort of pipeline
Initial Damage === Resistance SYstem ==> post resistance damage === armor system ==> post armor damage == actual damage system ==> health

#

and dont forget to clean up the data as you go

#

@north bay my issue with event entities is it can make the dots enities inspector useless

#

i had a case where i was creating/deleting every frame

#

so the inspector goes crazy adding/removing and reordering all the entities

north bay
ocean tundra
#

yea true

stone osprey
#

Wow thats a lot... So wait ^^ So i actually have "PhysicalDamage", "PhysicalResistence" and a damage event entity wich has components to calculate the "real" damage that is getting applied on the defending entity.

So the damage entity basically looks at the attacker stats, at the defender stats and applies a formula to them ?

Are there any examples ? ^^ Whats a more dynamic approach ? What if i want a entity that takes 50% less damage from physical damage ? :)

ocean tundra
#

i dont know any examples

#

there are definitly more dynamic ways

#

but i think that would be most performat ๐Ÿ˜›

#

the damage entity will be loaded with all the attackers stats it needs and the target entity, keeping random data lookups low

#

more dynamic is maybe a enum of damage type

#

you will still need some sort of switch somewhere to split the caculations

#

even more dynamic would be enum + buffer stuff
so you have a enum of your damage types
and the enum int, links to a dynamic buffer index
those dynamic buffer(s) will be things like resistance buffer

#

i would just recommend a nice 'simple' start and then expand it as you go

#

simple = damage entity/buffer... doing direct damage to health component

stone osprey
#

Thanks :) damn... I could really need a list of possible ways.

What i want is actually the following, different damage/resistence types and need some sort of damage and resistence buff ^^ based on different conditions.

An example is : a mob which takes 50% more physical damage from players wearing a holy armor when its night.

So kinda complicated ^^

#

And of course the opposite. Some sort of damage buff

ocean tundra
#

yea so on attack you spawn the do damage entity
Figure out the attackers stats somehow (im assuming you have this bit already) and copy them into the attack componet (for fixed damage types) or into some sort of buffer (For dynamic)
then you foreach all attack components

  • look up the target entity
  • gather its resistances
  • do damage caculation
  • apply damage
#

so the 50% more damage example
Attack component: Damage = 10
Attack Component physical damage buff = 1.5

(you could have a intermediate step to sum that, making further cacls easier)

foreach attack
physical resistance = target entity.get physical resistance
damage = (attack.damage * damage buff) / physical resistance
target entity. reduce health (damage)

#

poor mans sudo code example ๐Ÿ˜›

stone osprey
#

Alright, thanks ^^ the final question... Is there any way to automate such an formula ? Or do we need to hardcode it ? xD Because i could actually imagine that some entities use another damage formula ^^

ocean tundra
#

so get it working first

#

๐Ÿ˜›

#

but then yes you could begin to expand it to some sort of enum/int lookup

#

so intead of get physical resistance

#

its something like get resistance with id (1)

#

i find once you see the 'hard coded' structure its simpler to expand/design the 'generic' version

#

(but dont use actual generics ๐Ÿ˜› )

stone osprey
#

Hmmm... Thats something i dont quite understand. I think the damage calculation does involve multiple damage types.

Like damage = PhysicalDamage + MagicDamage / Resistence...

So if i add new damage types or resistences, i need to update that formula. So i guess theres no way to auto-construct such a formula :/

ocean tundra
#

well you could create 2 damage entities

#

each with a different damage type

#

so the caluclations all stay the same (and simple), but each 'attack' could spawn many attack entities

#

so another example ๐Ÿ˜›

#

fire sword attack
spawns 2 attack event entities

Entity 1:

Damage = 15;
Type = DamageTypes.Physical;

Entity 2

Damage = 5;
Type = DamageTypes.Fire;
AddDamageOverTime
{
Damage = 2;
Type = DamageTypes.Fire
Time = 10s
}

DamageSystem:

Foreach DamageEntity
Resistance = GetResistanceFor(damageEntity.Type, damageEntity.Target)
damage = ....
damageEntity.Target.TakeDamage(damage)
stone osprey
#

That makes sense... But this doesnt solve the "automatic" or dynamic formula issue... So we still need to provide one formula for all our calculations right ? Theres no way around that. So each time we add a new damage time, we would be forced to update the formula ^^ well the more i think about it... The more i assume such a formula is always required.

ocean tundra
#

well not really

#

the damage formual will always be the same no matter what damage type it is

#

its the values in the formular that changes

#

mainly resistance (armor)

#

so those values (resistances) would be stored on the target entities in a dynamic buffer

#

Resistance

DamageType = DamageTypeEnum
Resistance = %
#

you just look up the one you need

#

and feed the resistance into your caculation

#

i cant think of a case where you would have a whole separate damage formula

#

and to a player that would be very weird and confursing

#

modifiers on your damage is easy to express too
like maybe you want to skip resistance (eg for a critical hit)
you could just add a tag component to your attack event entity
and skip it in the inital damage system (using WithNone)

#

that will work too if you think up use cases where you need a whole seprate formula

stone osprey
#

Hmmm... Thats right... Furthermore its not common to add a new damage type like every day. I just know that wow has plenty types. Like poison damage, fire damage, physical, magic, light, shadow and so on. Thats actually pretty interesting.

A way i could imagine is
'
Type: Physical,
Index: 0,
Operator: +,
Type: Magic,
Index: 1,
Operator: /
'

Which produces something like "+Physical/Magic"

ocean tundra
#

i think that would get super complicated but could work

#

instead of opperator you could also look at function pointers in burst

#

basicly burst compatable delegates

#

but start simple!!!

#

KISS

#

๐Ÿ˜›

#

also enums are magic and can have values that are NOT definned in the inital enum

#

making extention via mods or something possiable

#

eg enum damage type
Physical = 1
Magic =2
...
fire = 20

DamageType = (DamageType)888 is valid

stone osprey
#

Well it would be pretty flexible to add new types. But yeah probably overengineering. I bet WOW just has a huge calculation formula they use... Damn i wanna get an insight into that ^^

Its actually kinda sad that there no articles about that topic. But the enum thing is pretty cool :D i actually avoided them because i thought that they are not extendable ^^

ocean tundra
#

pretty sure theres a reverse enginerred wow server somewere

#

that will have the caculation in

#

yea under the hood enums are just a data type

#

defaulting to int

#

you can change that too

#

eg enum DamageType : byte

#

will take up less space in your components (good thing) but will limit you to byte max value = 255

stone osprey
#

Well thats really a good think ^^

#

Lets say we want physical damage attacks deal more damage against entities with magic resistence. Would this be part of the damage calculation formula ? Or would the damage entity "buff"/increase its damage when a magic resistence was detected ?

ocean tundra
#

i wouldnt put this in the damage formula

#

instead somewhere else

#

i would modify the resistances

#

so if physical resistance = 50% i would set magic resistace -(negative) 25% or something

#

so again you would have some sort of 'pipeline of resistances'
eg

gather up all equipment resistances and skill resistances => into initial resistances buffer => calculate resistance 'fights' ==> final resistances buffer

#

(wasnt sure what to call physical offsetting magical resistances ๐Ÿ˜› )

#

with dots its great to keep things 'small'

#

and way easier too

#

so damage is just that, do damage, all resistances/buffs/modifiers are calculated separably and just 'fed' into the calculations

#

also that whole 'data flow' thing is very relevant

stone osprey
#

Hmmm... So we would basically create buffs for the player or mob. Like "Do 10% more damage when you wear a holy sword" and at the same time we would have some sort of buff system for the damage entities "Make physical damage deal double the damage when defender has no magic resistence" ? Thats all i can imagine ^^

ocean tundra
#

Yea probably

#

As you go and build it after you have the initial bits in you will probably see ways to make it more extendable

#

But the core you should KISS

#

Makes maintaining it better

#

And you can easily extend/swap the 'data' flow if you need using things like with all/with none/ write groups

stone osprey
#

So i should just start with basic damage, then go with types and a formula, then go with stats buffing and then go with additional requirements like such weird cases where fire damage does more damage to specific entities ? ^^ sounds valid...

Just saw a huge plus with damage entities... You can change them pretty easily.

Like "Entity{ Sword{ damageEntity : 1 }, PhysicalDamage{...}}"

And then having some sort of damage entity "Entity{Damage, PhysicalDamage, MoreDamageIf{ animal, 20% }}" so could even change and add different damage calculations and additions easily.

#

I never thought its that difficult to add a "cool" and exciting damage system

solid rock
#

Am I allowed to access ScriptableObjects from a job?

#

e.g. can the Job struct or any of the data inside it reference a ScriptableObject? I'm guessing no

ornate jasper
#

Hi does anyone know if itโ€™s possible to add a component to an entity in SystemBase Entities.Foreach ?

zenith wyvern
#

Long story short you need to use WithStructuralChanges().Run() if you're doing it in a ForEach

#

Or use a command buffer

ocean tundra
#

@ornate jasper of course you can

#

but the question is more like "how do i get a reference to a scriptable object?"

#

so the simplest (and worst ๐Ÿ˜› ) is to use references, and references.Load

#

the much better way is to use Addressables and Addressable.LoadAsync

zenith wyvern
#

You can't use reference/managed types in jobs

ocean tundra
#

but its also a good idea to consider what/why you need this,
As what Sark just said, even if you can get the ScriptableObject, you cant use it in jobs/Foreach and will have to write annoying boilerplate to copy/move data around so you can use it in a Job

#

its likely a singleton entity will work for most cases of scriptable objects

#

or some custom converstion code to take a Scriptable Object and spit out entities

remote crater
#

Very concise and fast read.

solid rock
#

I only need to put [ReadOnly] on the NativeContainer fields inside my IJob struct, not on any fields I put in a class that is managing the job execution, right?

ocean tundra
#

@solid rock are you talking about the containing system?

solid rock
#

I'm talking about this:

    public struct ProcessFluidNetworks : IJobParallelFor {
        public NativeList<FluidBuffer> buffers;

        [ReadOnly]
        public NativeMultiHashMap<int, int> relationships;

        public void Execute(int index) {
        }
    }```
#

I need readonly there if I want it to be readonly, right?

#

But I don't need ReadOnly here:

#
    public class FluidJobTester : MonoBehaviour {
        public NativeList<FluidBuffer> buffers;

        [Readonly]
        public NativeMultiHashMap<int, int> relationships;
        private void OnEnable() {
            buffers = new NativeList<FluidBuffer>(Allocator.Persistent);
            relationships = new NativeMultiHashMap<int, int>(500, Allocator.Persistent);
        }

        private void OnDisable() {
            buffers.Dispose();
            relationships.Dispose();
        }

        private void Update() {
            ProcessFluidNetworks job = new ProcessFluidNetworks();
            job.buffers = buffers;
            job.relationships = relationships;
            job.Schedule(...);
// etc...
#

right @ocean tundra ?

ocean tundra
#

i havnt really mixed jobs and monobehaviours but you shouldnt need readonly there

#

only in the job struct

solid rock
#

yeah that's my thinking too

#

thanks

solid rock
#
        [ReadOnly]
        public NativeMultiHashMap<int, int> relationships;

        public void Execute(int index) {
            if (relationships.TryGetFirstValue(index, out int neighbor, out var iterator)) {
                ProcessRelationship(neighbor);

                while (relationships.TryGetNextValue(out neighbor, ref iterator)) {
                    ProcessRelationship(neighbor);
                }
            }
        }```
#

Is there any better way of iterating over NativeMultiHashMap values?

#

Or is this pretty much it?

remote crater
#

how do you set the exact facing of a DOTS object via EULER angles?

ocean tundra
#

@solid rock kinda

#

you can use do... while instead

#

i had never used that loop type before ๐Ÿ˜›

remote crater
#

I know Angular = new Vector3(rb.transform.rotation.x, rb.transform.rotation.y, rb.transform.rotation.z)

#

But that just changes the rotation

#

I want to change exact facing.

solid rock
#

what's the diference in your mind between changing the "rotation" and changing the "exact facing"?

solid rock
remote crater
#

Angular is the velocity of rotation

#

Changing the facing means no rotational velocity, but directly look in a direction.

solid rock
#

rb.rotation = <some quaternion>

#

if you want to use euler angles:
rb.rotation = Quaternion.Euler(x, y, z);

#

but that's for Rigidbodies

remote crater
#

I am not setting rb.rotation

safe lintel
#

you can also use the RotationEulerXYZ or zyx/yxz components @remote crater

#

its documented in the TransformSystem of the entities docs

remote crater
#

I am using my rb.rotation to try and set facing of a mimic object

#

I read that

#

I cant make heads or tails of it

#

No sample code

solid rock
remote crater
#

Maybe I can find sample code in the demos...

safe lintel
#

just take it a little slower, each section describes a scenario, its not like you need to read every combination

solid rock
#

whatever you're setting the rotation of should also be able to accept a quaternion

safe lintel
#

tldr just add RotationEulerXYZ to your entity and set the euler angles there, there are more combos if you want them but you dont need to use them

remote crater
#

Who cares about rb anymore. How do I set the facing to be (0,45,90)?

#

I simply dont know syntax, I'm not dumb

safe lintel
#

its a component like Rotation, EntityManager.AddComponent(entity, new RotationEulerXYZ{Value = new float3(0,45,90)});

remote crater
#

ty

#

Ty very much

#

That is giving a syntax error

safe lintel
#

whatis it saying

remote crater
#

ntityManager.AddComponent(GameBoardModel.playerEntity, new RotationEulerXYZ { Value = new float3(0, 45, 90) }); //error = Cannot convert from unity.transforms.RotationEulerXYZ to Unity.Entities.ComponentType

#

Of course I have an E to start

zenith wyvern
#

I think it should be AddComponentData.

remote crater
#

dif error location

#

let me post .png

#

You guys rule btw

#

for actually helping

ocean tundra
#

where are you doing that?

#

you need a proper reference to entitymanager

remote crater
#

My entity manager reference is proper

ocean tundra
#

whys it light blue?

remote crater
#

Cuz it moves entities n stuff

ocean tundra
#

different color theme?

remote crater
#

probs

#

light blue = valid and clickable to me

#

Visual studio is kinda weird

#

but passab;le

#

Once I have a mimic player, I will enable collisions then world build. I'm excited

#

Could have something playable in 2 days or so

zenith wyvern
#

That's a basic C# error. You don't have an "EntityManager" at that scope so it thinks you're trying to call a static method.

remote crater
#

But I do

#

That same entity manager

#

five or so lines up

#

is working

#

just off screen

ocean tundra
#

share more code please

remote crater
#

That linear mimics my player gameobject with entity

#

So I have velocity mimiced ๐Ÿ™‚

ocean tundra
#

its clearly not the same entity manager

remote crater
#

WOW!

ocean tundra
#

GameboardModel.entityManager

remote crater
#

Thats what i get from copy pasting crappy code from eons ago thinking everything was valid

#

ty bro

ocean tundra
#

๐Ÿ˜›

remote crater
#

If I run this code over and over every 15 ms: GameBoardModel.entityManager.AddComponentData(GameBoardModel.playerEntity, new RotationEulerXYZ { Value = new float3(0, 45, 90) });

#

Will it keep creating new components?

#

Bingo!

#

Works!

ocean tundra
#

it wont be very performant

remote crater
#

ty

#

I know

#

I only have one object that is player that does this

#

all the rest is pure dots

#

My architecture was based on the idea that you always want one function coded, and never two of the same function you update over and over

#

By constraining it to my player controls, I can change both gameobject player and entity player with same code

#

Since my game has different play modes

#

I'm so happy man, you got me over a major tech wall

#

Been looking at dots for months. I think I finally got it

#

The funniest part is no one told me about DOTS

#

I made a post on Unity forum: Anyway I can use Visual Studio to write multithreaded code to unlock cores in unity

#

and someone directed me to dots. I'm so happy, feels like the universe is smiling at me

#

If anyone wants free steam keys(game is live now, but not the mmo part yet), pm me

minor sapphire
#

Excuse me people, but...
You can use fixed arrays. Therefore you have to mark the struct unsafe. The field declaration looks like this: public fixed int Foo[6]. The compiler knows itยดs size at compile time and can inline the array instead of storing it on the heap.

#

This is a thing?? You can have arrays in IComponentData?

#

Is this one of those things that only 2% of people are aware of, or did I just miss a game changer here lol

karmic pilot
#

guess you missed it ๐Ÿ™‚ was there since version 0.1.0-preview

#

generally it is recommended to just look at the source code/source code docs for IComponentData to see what is supported. Even possible without checking out the package:
https://github.com/needle-mirror/com.unity.entities/blob/master/Unity.Entities/IComponentData.cs

minor sapphire
#

oof

zenith wyvern
#

I don't know much about unsafe stuff, but my understanding is burst is horrible at optimizing it. I expect you're better off using FixedLists which have been in for a long time

rare dew
#

I call it unsafe oriented programming

half jay
#

Using ISystemBase will work that all code inside OnUpdate will be bursted or should create Job and job will be bursted? Also i can't see any ISystemBase systems in DOTS compiler

night venture
#

@half jay you mean public class MySystem : SystemBase {...} ?

half jay
night venture
#

I'm using this:

using Unity.Entities;
using Unity.Jobs;
using Unity.Transforms;

public class CarMove : SystemBase {
    protected override void OnUpdate() {
        Entities.WithAll<Car>().ForEach((ref Translation position) => {
            position.Value.x -= 0.01f;
        }).Run();
    }
}
#

dots engine invokes the OnUpdate and my cars move

amber flicker
half jay
amber flicker
#

I haven't noticed much of a performance improvement - I'd be curious if you do

half jay
karmic basin
#

You can also use Jobs.WithCode() lamba inside SystemBase, if you want a bursted job without iterating with entities foreach.

gusty comet
#

Where do u guys learn from? Id say 2019 and some 2020 vids show outdated dots stuff

karmic basin
# gusty comet Where do u guys learn from? Id say 2019 and some 2020 vids show outdated dots st...
  1. Official manual. It's kept up-to-date. Check pinned messages on this channel. There's a bunch dedicated to those new packages.
  2. Official samples on github. Also kept up-to-date within days after new releases. https://github.com/Unity-Technologies/EntityComponentSystemSamples
  3. Official forum. Follow the DOTS subforum from time to time.
  4. Unite videos from 2019 yeah, like you said they got old pretty fast. You can still grab the concepts and read changelogs to update the syntax.
  5. A few blogs. Some did a really nice job dissecting ECS when there was close to none docs. Can get old fast too but still enlightening.
  6. Dig source code. It's open enough to access it.
  7. Here
night venture
#

I have a moving entity(car) going over a map. I would like to know when the car reaches map's end.
I though using a collider trigger would be a valid approach. Otherwise, please, let me know.

So, to sum up: I though to add a "boxcollider" to an entity, which triggers a job (to destroy the object)
I'm trying not to use conversion neither authoring, so i'll appreciate a pure code approach.

do this approach feel correct to you?

karmic basin
#

Depends a lot on your game. If the map is a square and you want to check entities trespassing boundaries, the more efficient way is to check distance fro origin and remove when greater than.

#

Trigger area is more re-usable for other game mechanics once figured out

#

"A job to destroy the object": how many entities ? only 1 (player car) ? Or thousands ?

night venture
karmic basin
#

You know your game better. Try something, if you're stuck people on this channel will help

night venture
#

trying to setup a BoxCollider on my tile to detect when a car "hits" the end of the map i tried adding a component:

EntityManager.AddComponentData(tiles[i, j], new PhysicsCollider {
    Value = BoxCollider.Create(new BoxGeometry {
        Center = new float3(0.5f, 0.5f, 0.5f),
        Size = new float3(1f, 1f, 1f)
        //Orientation quaternion exists here...
    })
});

I'm getting: ArgumentException: Orientation quaternion(0f, 0f, 0f, 0f) is not valid.

Do I need to give an "orientation"? what it would be?

amber flicker
#

quaternion.identity

night venture
#

and that means...?

#

of course, it works, but i dont know what im doing with that...

safe lintel
#

a quaternion of 0,0,0,0 is invalid

amber flicker
#

yea exactly. For the equivalent, you need the identity matrix when dealing with quaternions.

night venture
#

whats the w?

#

and...identity means "not rotated"?

amber flicker
#

this might be a bit more involved than you expected.. I'd recommend watching some youtube videos about quaternions (there are many)

night venture
#

oks...added on todo list

#

๐Ÿ™‚

safe lintel
#

i always think of identity as like an acceptable zero value but i personally dont fully understand quaternions ๐Ÿ˜‰

night venture
#

i got it!

#

its simple!!! w=angle!!!

#

so, instead of identity (0,0,0,1) ๐Ÿ˜„

karmic pilot
#

that is what quaternion.identity does internally as well ๐Ÿ™‚

night venture
#

The same way EntityManager exists as a property in Systembase ...does it physics world? or do I need to =World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>(); everywhere I use it?

hollow sorrel
#

@night venture you need to do that everywhere you use it, but World is also a property of Systembase so you can just do World.GetExistingSystem<BuildPhysicsWorld>();

#

also note that while you can cache the system, you can't store PhysicsWorld so if you are using it in onupdate you need to do buildPhysicsWorld.PhysicsWorld every frame because it modifies the struct
edit: tho maybe getting a ref also works, haven't tried that

night venture
#

Similar to SystemBase being used instead of ComponentSystem, should I use something to replace IJOB ? (trying to learn how to capture collision events) ? Perhaps ICollisionEventsJob ?

low oasis
#

I'm looking for a DOTS safe UUID option. System.Guid doesn't seem to be able to cut it. Running into quite a few problems with it (managed / unmanaged code etc.). All the options I keep seeing also just use strings, which, again... DOTS/ECS

#

I also see EntityGuid, but that seems too specific to the entity system to be used generally

night venture
low oasis
#

serialize/deserialize to save to a file. The data needs a uuid, the entity uuid can change because of how we are saving world data and reloading from json - @night venture

naive ice
#

I was able to simplify a bunch of systems down to Entities.ForEach when upgrading an old DOTS project

naive ice
night venture
# naive ice I was able to simplify a bunch of systems down to Entities.ForEach when upgradin...

I have a moving entity with an attached PhysicsCollider component and also a static entity(not moving) with another PhysicsCollider component.
I'm trying to detect the collision or handle when the distance to collision (physicsWorld.CollisionWorld.CalculateDistance) is lower than 1f...
Every example i have seen so far is different form the other, outdated, requires unsafe Collider* cast...
PS: Im not trying to port anything, but trying to do it from scratch with "pure ECS".

night venture
naive ice
safe lintel
#

generally physics collider stuff in dots will require unsafe. its just the way it is at the moment

night venture
low oasis
karmic basin
#

You would need a PhysicsBody too if it's moving

karmic basin
#

I recommend converting from a GO and check what componets are added

#

and probs a physicsShape

night venture
night venture
# karmic basin You would need a PhysicsBody too if it's moving

i didn't feel it were necessary...seems this could work also:

        EntityManager.AddComponentData(e, new PhysicsCollider {
            Value = BoxCollider.Create(new BoxGeometry {
                Center = new float3(0.5f, 0.5f, 0.5f),
                Orientation = quaternion.identity,
                Size = new float3(1f, 1f, 1f)
            })
        });

PS: english grammar: is feel or felt?

karmic basin
#

Could prolly be enough for a static collider ๐Ÿคทโ€โ™‚๏ธ

safe lintel
#

well maybe not collision events, but its likely you will need it enabled for collider casts, or getting/setting any physics material

naive ice
# low oasis Which is fine until I want to read the saved data from outside Unity

Right - so what I would do is create the UID outside of ECS, perhaps a UIDComponentData that you attach to entities that need them. Create a system for it that fills in any freshly-added UIDComponentData with single-threaded, deterministic-if-desired UIDs; then you can safely move those UIDs in and out of your World and trust that they're still unique. ๐Ÿ™‚

ocean tundra
#

Use Guid

#

its kinda big size wise but always unique

naive ice
naive ice
# ocean tundra its kinda big size wise but always unique

In 99.9% of cases... I managed to run into that .1%. ๐Ÿ˜ But yes, you could absolutely drop Guid into the system I described if that's what your after. I am inferring that the original issue is that you can't just directly interact with the Guid class from within a Job, which will still need to be resolved in any case.

ocean tundra
#

?? guid is a struct, it should be fine in a job

night venture
ocean tundra
#

but yea 99.99% of the time its fine, ive never managed to run into that .1% tho

#

and even tho i recommended guid im not using it either. instead i give a int ID during conversion

naive ice
ocean tundra
#

guid is too big for me to network, 128 bits is too much when i can get away with less then 32

naive ice
ocean tundra
#

yea... never tried making a guid from a job

low oasis
#

I was just trying to compare against an UNSET Guid and it was a pain

ocean tundra
#

hmmm thats annoying

naive ice
#

Yup, for the reason described above. Unfortunately you're probably not going to get satisfactory results for your situation without writing some extra code to put ECS-friendly Guid generation into its own system

ocean tundra
#

i swear i didnt have those issues

#

but i guess i wasnt directly using the guid for much

#

just looking up values from a hashmap

naive ice
#

If you just want a quick and dirty probably-unique-thing you could do a hash function based on other attributes, but I wouldn't recommend it for anything other than a 5 second proof of concept ๐Ÿ˜„

north bay
#

Unity mathmematics has Hash128

#

That's actually in Unity.Entities not mathematics

ocean tundra
#

i also used entity as a unique id for a bit

#

worked fine

coarse turtle
#

i've used math.hash(void*...) for some stuff since it uses the xxhash32 algo

ocean tundra
#

nice

#

i didnt know about that

night venture
#

hey @ocean tundra any experience with PhysicsCollider? im struggling to have this working

ocean tundra
#

a bit

#

i mostly use it via the subscene authoring flow now

night venture
#

would you say authoring is the way to go? (or gameobjects and all that non-ecs will eventually dissapear?)

ocean tundra
#

yea authoring is definitly the way to go

#

unity has confirmed its the recommended way to use DOTS

safe lintel
#

gameobjects arent going anywhere, use authoring and save yourself the hassle of fighting it

ocean tundra
#

and they arent killing MBs or GOs anytime soon

ocean tundra
#

will be like 10 years at the min

#

more like 30 ๐Ÿ˜›

safe lintel
#

at the current rate never ๐Ÿฅฒ

ocean tundra
#

haha yea

safe lintel
#

anyway authoring stuff also works nicely with subscene conversion

night venture
#

ok...then tomorrow ill refactor to use that. ill probably need your "theorical" help also...

#

for example: i created a tile map (Entity [,] ) from scratch importing the json file you help me create...if authoring is the way to go, I would rather have to create go from prefabs instead, isnt it?

ocean tundra
#

maybe..

#

i would probably just leave it as is

#

your json file stuff is basicly a mini authoring/subscene replacement

night venture
#

can you elaborate a bit?

ocean tundra
#

your json file, is basicly doing the same thing as subscenes

#

the only way you could 'mix' the 2 is to change your stuff to create from a prefab

#

but whats the point of that, all your components and data is set from json

night venture
#

well...using tilemap+editor, as you suggested, would also be easier

#

anyway, that's for tomorrow...today task was colliders, and im failing at the wuery/detection.
and, as a workaround, i tried to check x/ bounds...but encontered an issue...let me explain:

#

my cars are moving from left to right, increasing position.x

#

once they reached x>8 it's time to recycle them

#

but, in the way im doing it, this code is inside a foreach

#
        Entities.WithAll<Car, DriveWestToEast>().ForEach((Entity e, ref Translation position, in Car car) => {
            position.Value.x += car.speed;
            if (isOutOfBounds(position.Value)) {
                CarSystem.CarRecycle(e);
            }
        }).WithoutBurst().Run();
ocean tundra
#

too much oop

#

๐Ÿ˜›

night venture
#

im sorry xDDDD

ocean tundra
#

no communicating between systems like that

#

instead you Add a Tag component to your entity

night venture
#

based on componentsยฟ?

#

oooooooook

ocean tundra
#

and your car system's Entitys.Foreach has a WithAll<TAG> filter

#

have you ever used SQL?

night venture
#

sure

ocean tundra
#

ECS is basicly that

#

Entities.Foreach...... is just building a WHERE query

night venture
#

well...i think is quite more complex xD

#

but i get what u meanรง

ocean tundra
#

๐Ÿ˜› no sql is way worse

night venture
#

i think i know how foreach works by now

#

couple of questions about that

#

1-if im only reading car.speed....should I use nothing or ref instead of in?

ocean tundra
#

in = read only

night venture
#

ie: does it using in make a copy?

ocean tundra
#

no

#

in and ref are both 'magic' that dont create a copy

#

but ONLY for STRUCTS

#

dont use either for classes

night venture
#

#bUtOnLyFoRsTrUcTs

#

as i have only spent a few days with ECS, i start to noticed they "switched2 from class (OOP) to struct(DO) as the core concept of the paradigm...isnt it?

ocean tundra
#

mostly yea

night venture
#

much like screw objects and classes and use struct and tags

ocean tundra
#

sturcts are easier to manage their memory manually

#

you can still use classes

#

but structs = more performance

night venture
#

and...probably because of my oop background, im a bit concerned about adding a tag to a foreach run onupdate, cause i have to "minimize" what onpudate does

#

structs=same size...

ocean tundra
#

just use a entity command buffer

night venture
#

ill reach that tomorrow xD

#

ok...back to my recycler...

ocean tundra
#

structural changes is something to try minimize, but at the same time required

night venture
#

i have a system responsible of spawning (and now recycling) cars

#

would you have ANOTHER system to move the cars? or it would make sense to have the same system for every car-related thing?

ocean tundra
#

nope more systems

night venture
#

"nope, more systems" or "nope more systems" ? xD

ocean tundra
#

๐Ÿ˜›

#

more systems

#

all the systems

night venture
#

ok...

ocean tundra
#

more systems = better sepration of concerns = easier to maintain and extend