I’m working through a big performance oriented refactor right now and I’m trying to decide on the best shape for wilderplace’s state. I figured I’d share my thinking so far in public in case anyone has any advice for me.
What are the goals of Wilderplace’s state?
Here are the options I’m looking at. In all examples, the objects with an ‘id’ would also have other properties like ‘disabled’ and ‘hidden’ ect.
const state = {
entityIds: ['a', 'b', 'c'],
entityPositionData: {
a: { boardPosition: [0, 0, 0], screenPosition: [1, -1] },
b: { boardPosition: [0, 1, 0], screenPosition: [1, 0] },
c: { boardPosition: [1, 0, 0], screenPosition: [2, -1] },
},
boardWithEntities: [
[[{ id: 'a', type: 'MONSTR'}], [{ id: 'c', type: 'WARDEN'}]],
[[{ id: 'b', type: 'PLAYER'}]]
]
}
I like this option because it’s straightforward to read/update entities while traversing the board. The downside is that I need to do two lookups to get an entity’s properties based on it’s ID:
const state = {
entityIds: ['a', 'b', 'c'],
entitiesWithPositionData: {
a: { id: 'a', type: 'MONSTR', boardPosition: [0, 0, 0], screenPosition: [1, -1] },
b: { id: 'b', type: 'PLAYER', boardPosition: [0, 1, 0], screenPosition: [1, 0] },
c: { id: 'c', type: 'WARDEN', boardPosition: [1, 0, 0], screenPosition: [2, -1] },
},
board: [
[['a'], ['c']],
[['b']]
]
}
I like this option because it’s straightforward to lookup entities from their IDs. The downside is that it’s more awkward to read or update entities while traversing the board:
const state = {
entityIds: ['a', 'b', 'c'],
entitiesWithPositionData: {
a: { id: 'a', type: 'MONSTR', boardPosition: [0, 0, 0], screenPosition: [1, -1] },
b: { id: 'b', type: 'PLAYER', boardPosition: [0, 1, 0], screenPosition: [1, 0] },
c: { id: 'c', type: 'WARDEN', boardPosition: [1, 0, 0], screenPosition: [2, -1] },
},
boardWithEntities: [
[[{ id: 'a', type: 'MONSTR' }], [{ id: 'c', type: 'WARDEN' }]],
[[{ id: 'b', type: 'PLAYER' }]]
]
}
This is the kitchen sink option. It’s easy to lookup entities either by position or by id. The downside is that, because I’m using Immutable.js (which I regret using but that ship has sailed), I can’t save entities by reference and mutate them. I’d need to ensure I synchronized the copies of entities across both data structures whenever making updates:
I am leaning toward option 1, but I’m curious what the rest of the world thinks. Should I be pre-calculating and storing even more data, like neighbors, so my base data structure is more graph-like? Any option will be better than what I have now, which is just a multidimensional board array with entities inside it. The downside to that: I have to derive both my entity list and position data from the board on all state changes. I think any of the options above will lead to less work to update state and many fewer React re-renders.
👋 Thanks!
Wilderplace is now on Steam! The best way to keep up with the game’s development is to join the discord.