0
\$\begingroup\$

I am trying to use an ECS for my 2d game at the moment. Up until now I had my world subdivided into chunks (as minecraft does) of size 64x64. They are loaded and drawn when they come onto screen. I did this to reduce the drawing calls.

How would something like this work in an ECS? I would say my Chunks have the following properties at the moment: tile_is_water[64,64], humidity[64,64], sprite_batch (the thing that is drawn)

At some intervals I will need to call some kind of updatefunction which uses tile_is_water and humidity to generate a new sprite_batch (but not very often, these change rarely). On every frame I need to draw the sprite_batch. On every (or maybe every few) frame I need to check which areas are visible and set some kind of flag s.t. I only draw the visible ones.

It would help me a lot of someone could explain to me what the components, the entities and systems would be in this case.

Edit: To clarify. I don't have this modelled as an ECS yet and I have problems modelling this particular issue. What I have until now is just seperated everything into components: Components: Is_Water_Area, HumidityArea, SpriteBatch Is_Water_Area and HumidityArea just contain the corresponding 64x64 arrays and sprite_batch contains the drawable spritebatch. I also have a BatchDrawer system that draws everything that has a SpriteBatch. But where do I do the updating of the SpriteBatch for example? Where do I check which areas are drawn?

For example I could just check this every frame or I could keep a list of drawable Areas and update that. But where would I keep such a list of the drawable areas?

\$\endgroup\$
  • 1
    \$\begingroup\$ I'm not sure I understand what's being asked here. There's no official way you must apply ECS to any particular problem, and no special rules anyone will enforce on you if that problem happens to be a chunked world. Have you run into any particular trouble with a particular component plan, that you'd like feedback on how to correct/improve? \$\endgroup\$ – DMGregory Feb 12 '18 at 18:12
  • \$\begingroup\$ I haven't done this yet in an ECS, I wanted to get some suggestions on how I could structure this. I had a hard time finding a good solution. I can update the question with the idea I had \$\endgroup\$ – fubal Feb 12 '18 at 20:03
  • \$\begingroup\$ Better yet: just implement your idea. You don't need to ask the committee of internet strangers for permission first. If, in the course of implementing it, you discover something you don't like about the idea, or a challenge you're unsure how to resolve, post that as a question here. This will tend to attract much more focused & constructive answers. \$\endgroup\$ – DMGregory Feb 12 '18 at 20:06
  • \$\begingroup\$ I now updated with more specific issues (where to handle the "which areas are drawn" and where to save something like a list of entities-to-draw) \$\endgroup\$ – fubal Feb 12 '18 at 20:09
1
\$\begingroup\$

This answer is focused on how I would approach solving the problem instead of a prebaked specific answer.

For google reference, the basic ideas are based on broad phase and narrow phase collision detection.

First, list out the facts and invariants that you can depend on. E.g.

  • Size of Chunk.
  • Player movement
  • Calculate (d) the time required for a player to cross one Chunk of map.
  • Calculate (d_2) the time required to traverse 1/2 of one Chunk.

Create a Component for tracking Player_Loaded_Chunks

Create a System which runs every (d_2) intervals of time. (d_2 because you need to load the world BEFORE it comes into view)

foreach available chunk:
    Is the player within (d) travel time of a chunk which is not loaded/generated/rendered yet?
        yup
            Load the chunk the player just moved into range of.
            (Other Systems should use this as a trigger to create your various Terrain/Object/Map entities in that chunk)
        nope
            chunk out of range, ignore
foreach loaded chunk:
    Is the player OUT OF RANGE of this already loaded chunk?
        yup
            Unload the chunk
        nope
            keep it loaded

This approach allows you to run far less than every frame, potentially only every few seconds.

Obviously you'll need to tune many factors for your specific case.

  • Are you allowing teleports? Better have a teleport delay to allow loading the other end of the map

  • Speed boosting items? Same deal.

  • If your chunks are huge, you can't hold as many in memory, but you run the algorithm less often
  • If your chunks are tiny compared to player speed, you need to run the load/unload more often

Highly advanced drawing to add flavor to this answer:

Updated

\$\endgroup\$
  • \$\begingroup\$ Thanks a lot, this is indeed very helpful in general. But my question was actually about how this kind of behaviour normally is implemented into an Entity-Component-System. Especially which kind of Components and Systems would be handling stuff like this. Would I have an IsArea Component on my areas and a System that requires isArea and just runs the above code? \$\endgroup\$ – fubal Feb 12 '18 at 21:50
  • \$\begingroup\$ As DMGregory noted, there is no "correct" or "normal" way to implement ECS, which makes it highly dependent on how you, fubal have implemented it. For example, my ECS Components do not even have a Type. They simply have properties. My Chunk System then checks if the Entity has 'ChunkId' AND 'X' AND 'Y' AND 'Width' AND 'Height', then concludes this entity is treated as having a Chunk Component. \$\endgroup\$ – Kal_Torak Feb 12 '18 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.