Giter Club home page Giter Club logo

Comments (5)

genaray avatar genaray commented on May 18, 2024

Hey there! :)

If i understand the problem correctly its basically like this?

  • Entity is ready to die, enters the large if statement
  • Entity gets removed one of the components (Burn, Shock etc)
  • The Console.WriteLine("Hello"); gets entered since the entity is suddenly alive again

Correct? ^^
If that's the case, that's actually intended behaviour. Changing an entity structure changes the entity at exact that moment. And the entity is being removed from its current slot and gets moved to another archetype. The previous slot is being filled with another entity to ensure tight packed arrays. And therefore the passed refs change.

Such behaviour basically acts as some sort of "synchronisation" point and should be handled with care. You have those options:

  • Do structural changes at the end of the lambda, that way you wont mess up the refs.
  • Use the CommandBuffer to buffer and playback those changes at a later point. (However the recent nuget has a small bug with that one, the master fixed it).
  • Create defensive copies of components and entities in the lambda, but that would make the code less readable.
  • Or just separate the queries to ensure like a one query = one purpose doctrine.

Other ECS frameworks buffer such operations during a query to play them back after the query is finished. However, that brings many new problems and an awful speed.
I actually think that the way you solved it, is the most elegant way. And probably even the most readable :>

And thanks a lot! I hope its clearer now ^^ (Also make sure to try out Arch 1.2.3 without the beta tag, that one fixes a few other things too).
Im gonna mention that somewhere in the wiki soon :)

Edit : entity.RemoveRange(typeof(Body), typeof(Burn), typeof(Slow), typeof(Shock));
Make sure to use entity.Remove<Body,Burn,Slow,Shock>() instead. Or the single calls after one another. Best paired with has operations. RemoveRange is a operation which is actually for scenarios where the types are not known during compile time and will be much slower ^^

from arch.

proc-gen avatar proc-gen commented on May 18, 2024

Makes sense! My last foray into using an ECS was with https://github.com/PeteyChan/SimpleECS, which I had to pull the project source in to even use it on my own project. That one did buffer the operations and I was kind of used to that.

I'll try that update for entity.Remove. I was still having issues with the individual entity.Has followed by entity.Remove for each component type. Essentially, the enemies would die and still be on screen, though I didn't dig into why and that's when I moved to entity.RemoveRange.

from arch.

genaray avatar genaray commented on May 18, 2024

I'll try that update for entity.Remove. I was still having issues with the individual entity.Has followed by entity.Remove for each component type. Essentially, the enemies would die and still be on screen, though I didn't dig into why and that's when I moved to entity.RemoveRange.

Thats actually interesting aswell. If that persists with the latest 1.2.3 non beta version... Please tell me in that case ^^ i actually need every bug report i can get to fix all remaining bugs once and for all :D

Im actually using arch in my gameserver and its working fine rn. But everyone uses stuff differently so im probably avoiding such a bug by acciddent :)

So would be great if you could try that out and report hack here :)

from arch.

proc-gen avatar proc-gen commented on May 18, 2024

It was me making the same mistake after moving it from one query to another. If I had put the if statements after removing the Body, it likely would have worked just fine.

This is what I had before the RemoveRange. (Switching to Remove<> worked!)

world.Query(in query, (in Entity entity, ref EntityStatus entityStatus, ref Body body) => 
            { 
                if(entityStatus.State != State.Alive)
                {
                    if (entity.Has<Burn>())
                    {
                        entity.Remove<Burn>();
                    }
                    if (entity.Has<Slow>())
                    {
                        entity.Remove<Slow>();
                    }
                    if (entity.Has<Shock>())
                    {
                        entity.Remove<Shock>();
                    }

                    physicsWorld.DestroyBody(body);
                    entity.Remove<Body>();
                }
            });

from arch.

genaray avatar genaray commented on May 18, 2024

Glad to hear! :D
Yeah it actually takes time to understand whats exactly going on behind the scenes, but once understood it will be worth it. Its like a high risk/high reward scenario ^^

If there any other issues, lemme know! :)

Probably a .TryRemove<>() alternative could come in handy

from arch.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.