Access Components from changed Entities before change?

Is there a good solution to attain the old Components from a changed DefaultEntity from DefaultEntitySet?

I’m trying to write a roguelike, and to display the map, I use an array of chars (simplified, because on one field can be multiple things, but the concept is the same for this issue). On initialization of the map I create an EntitySet over the components Position and RenderComponent, which contains the char as which this thing should be displayed. Then I write these chars at the according positions in my display array. Whenever an entity is added, I do it the same, whenever one is removed, I clear the according tile. No problem so far.
But when the position of an entity changes, I’d have to clear the previous tile and set the next. Setting the next is no problem, as I have the data in the entity. But how do I know which tile to clear? I only see very complex workarounds for this, as implementing EntityComponentListener myself or track which char comes from which entity, but maybe I’m just blind at this point?

Well how about this?

Way one:
Get all renderable entites,
clear all
render everything.

Way two:
Get all renderable entities,
in your rendersystem keep track between entity and currently renderd by using a hashmap
if something changes, get the last used position from the hashmap clear it and set the new one.

Something like this is just the thing I want to avoid, I’m looking for a way to get the Position or RenderComponent just before it is overwritten. This would be much less complicated, I’m just not sure how to do it with the api as it is.

Well as far as i know there is no way to do so, as it is not intended to be done like this.

@Toboi said: Is there a good solution to attain the old Components from a changed DefaultEntity from DefaultEntitySet?

I’m trying to write a roguelike, and to display the map, I use an array of chars (simplified, because on one field can be multiple things, but the concept is the same for this issue). On initialization of the map I create an EntitySet over the components Position and RenderComponent, which contains the char as which this thing should be displayed. Then I write these chars at the according positions in my display array. Whenever an entity is added, I do it the same, whenever one is removed, I clear the according tile. No problem so far.
But when the position of an entity changes, I’d have to clear the previous tile and set the next. Setting the next is no problem, as I have the data in the entity. But how do I know which tile to clear? I only see very complex workarounds for this, as implementing EntityComponentListener myself or track which char comes from which entity, but maybe I’m just blind at this point?

By the way, thanks for providing a concrete use-case as it’s really helpful when discussing these questions.

As Empire mentions, this cannot be done and it’s not intended to work like this. In fact, the position could have potentially changed 900 times before you got to your update of it so trying to get the “last value” is really only relevant in the context of its local use.

If you are storing a map with entities in it then maybe you should put the actual entities in it. Then at least you can move the entity instead of randomly stabbing things into the map. This would also let you support stacked things like when one player is over a door and then moves off the door.

And otherwise, your current approach is really fragile for a few reasons and this “last change” issue is really just illuminating a potential design problem. I think you’ll be happier in the long run if you fix that. It’s not really any harder than what you are doing now and potentially has a few side benefits.

I’m sure we could help if you need it.

@pspeed said: And otherwise, your current approach is really fragile for a few reasons and this "last change" issue is really just illuminating a potential design problem. I think you'll be happier in the long run if you fix that. It's not really any harder than what you are doing now and potentially has a few side benefits.
Yeah, I see...

How would you do it, then? The one approach is to read the entities into pre-“rendered” mapdata, which causes the issue of tracking the entities and is even apart from that not really a nice solution, as you stated.
The other approach could be to render the map always new from the entities. But here I see at least one problem. I want to display tiles with more than one entity flashing between the entities, like in dwarf fortress. If I render the map always new, there would be no place to store data like which entity was shown last (at least no straight-forward, nice way I can think of).
Do you have any inspiration for me at this problem?

Besides that, I’ve already buried the idea of making really everything (like each tile’s data, each wall etc) into an own entity, I played around with it a bit and I already found out that it took about half a second to switch between levels, because I’d have to reread the whole render-entityset for one level.
Here I see two solutions, again. The first would be to mix OOP and ES and storing the map data outside the ES. Doesn’t sound good to me, I would probably regret this.
The other would be to create a MapComponent with this data… No nice solution, either. It’s not a aspect of an entity, more like the whole entity is defined by a single component. So maybe there is a third way which just won’t come to my mind?

Hashmap, the answer is nearly always a hashmap.

In the par tthat does the rendering add a hashmap with entityid to mywhatever object.

Where mywhatever objects stores wich one is last displayed.

what exactly si slow with your entity renderset? The actual issuing of the update? or the logic that processes it.

@Toboi said: Yeah, I see...

How would you do it, then? The one approach is to read the entities into pre-“rendered” mapdata, which causes the issue of tracking the entities and is even apart from that not really a nice solution, as you stated.
The other approach could be to render the map always new from the entities. But here I see at least one problem. I want to display tiles with more than one entity flashing between the entities, like in dwarf fortress. If I render the map always new, there would be no place to store data like which entity was shown last (at least no straight-forward, nice way I can think of).
Do you have any inspiration for me at this problem?

Besides that, I’ve already buried the idea of making really everything (like each tile’s data, each wall etc) into an own entity, I played around with it a bit and I already found out that it took about half a second to switch between levels, because I’d have to reread the whole render-entityset for one level.
Here I see two solutions, again. The first would be to mix OOP and ES and storing the map data outside the ES. Doesn’t sound good to me, I would probably regret this.
The other would be to create a MapComponent with this data… No nice solution, either. It’s not a aspect of an entity, more like the whole entity is defined by a single component. So maybe there is a third way which just won’t come to my mind?

Is this for the map of where the game is happening or just for a visual display? Or is it both really?

It sounds like maybe the visual representations of objects are being mixed with the entities. The first should be a view of the second and will almost always necessarily have its own objects. Like a spatial for an entity in scene graph terms.

@Empire Phoenix said: Hashmap, the answer is nearly always a hashmap.

In the par tthat does the rendering add a hashmap with entityid to mywhatever object.

Where mywhatever objects stores wich one is last displayed.

I'm not absolutely clear about that... maybe it could work with a hasmap tile/position to mywhatever object, since the problem is that I have to distinguish multiple entities.
what exactly si slow with your entity renderset? The actual issuing of the update? or the logic that processes it.
The part where I reread the entity set for the actual height layer: [java] entityData.getEntities(new FieldFilter(Position.class, "z", this.layer), Position.class, RenderComponent.class);[/java]
@pspeed said: Is this for the map of where the game is happening or just for a visual display? Or is it both really?

It sounds like maybe the visual representations of objects are being mixed with the entities. The first should be a view of the second and will almost always necessarily have its own objects. Like a spatial for an entity in scene graph terms.


The map represents the whole place of the game, so it holds a value for each tile. Either for open space or for a type of wall. I’d use an array int for my map data, with int values assigned to block types. Whenever I get to render, I’d take this array and use a lookup-table to match these values to their actual display char, and create a (not es-based) object for the view. The values from the array would also be used for e.g. collision detection. So far everything is okay, I think.

But where I probably already mixed it up, is everything that is not represented in the map data, so everything that is not static, as items, buildings, units. My first approach was to give all these things a RenderComponent with their graphical representation. But this comes to a problem at least at the point where I want to change the view of a entity, e.g. change the color to red for a hurt unit.
So my next idea is to use entity sets to define how a entity is represented, e.g.
[java]entityData.get(new HealthBelowFilter(30), Position.class)[/java]
and represent every entity within this set as a red char. What lets me hesitate to use this approach is that I’d have to hardcode everything, so not very elegant, too.

For me, I would do it thusly:

Map data is independent of ES (as you already have). Map visualization is done with that.

Then you have some graphical representation of entities… whether they are spatials, whatever. They don’t know anything about the map data… that’s a game logic problem. The spatial (or whatever) is plopped down right on the map based on its current state and position. If the position changes then you move it. If the state changes then you change it.

So your game view code has like:
-map: int[][][] or whatever displays the map
-Map<EntityId,Spatial> displays the non-static objects

I don’t see any reason to try and back the non-static objects right into the maze. If you do need to do something like detect where other items are so you can just display one at a time then I’d use a separate map int[][] structure for that (in fact, this is more or less exactly what Monkey Trap is doing on the game-logic side). And then it’s just a matter of checking to see if that int[][] already has this entity ID or not and swapping them every so often and changing the cull hint or whatever.

1 Like

Now I got it!
What really messed me up was that mixing of visual representation and data. What I’ve done now is basically what you suggested. First I create the view of the map data. Then I create EntityViews, based upon the components RenderComponent and Position and synced with the EntityData via the EntitySet.
For the moment I just take all of the EntityViews, iterate through them and draw them over the map (so the last entity is shown per tile), but now I think I’d be able to implement a stacking mechanism much easier, I really struggled with the distinction of data and view. Thank you for your help!

@Toboi said: Now I got it! What really messed me up was that mixing of visual representation and data. What I've done now is basically what you suggested. First I create the view of the map data. Then I create EntityViews, based upon the components RenderComponent and Position and synced with the EntityData via the EntitySet. For the moment I just take all of the EntityViews, iterate through them and draw them over the map (so the last entity is shown per tile), but now I think I'd be able to implement a stacking mechanism much easier, I really struggled with the distinction of data and view. Thank you for your help!

Glad the conversation worked out! :slight_smile: