0

I'm currently developing a game with a top down map and units on it with Vue3. I have a Unit Store where I keep all my unit objects in an array and each unit is placed on the map based on its coordinates. I have a method in my store to retrieve all units on the same coordinates:

public getUnitsAt(coordinates: Coordinates): Array<Unit> {
    return this.state.units.filter((unit) => unit.coordinates.x === coordinates.x && unit.coordinates.y === coordinates.y);
}

In most cases this is enough to display these units in a list. Now I introduced towns with their own town view component and I want to display the units that are "outside" of the town, but still on the same coordinates. So I use this:

const outsideUnits = computed(() => unitStore.getUnitsAt(town.coordinates));

So far so good, but now I want to be able to sort these outsideUnits, by telling a specific unit to move to the front. The problem is that this array is already a filtered array copy from the store. So I can probably sort this computed property, but as soon another unit is added to the store this gets recomputed and my order is lost. Any ideas how I can still have an up to date array of units, but be able to sort?

If a unit moves from a nearby field to the same field, it should automatically be in front.

2
  • can you clarify what you mean by be in front, do you mean first in the array? Also is your concern that you may be inefficient with memory or cpu? Commented Oct 19, 2020 at 18:35
  • @Daniel yes, to be at index 0, so new items I would then unshift. Memory is only a minor concern; as long as I am using objects as entries sorting should only sort references and not the whole object. Commented Oct 19, 2020 at 18:44

1 Answer 1

1

Based on your comment about memory being a minor concern, I would think of this problem/solution like a document store noSQL DB where the optimization is targeted toward reads, that means that more work is done up-front on the write (updating sometimes the same data at multiple places) because the idea is that the writes happen less frequently than the reads.

some things to keep in mind

  • a method, like getUnitsAt, the result doesn't get cached, so every time you call it it will run the function.
  • if you want the data to be persistent, then you need to store it.

I would suggest using a computed value that stores all the relevant tiles' information in an object.

For example unitOrder['12_6'] would return [unit6, unit3, unit4], where 12_6 would be the x and y coordinates. (But would be better to abstract the index lookup through a method like posToKey = (x,y)=> [x,y].join('_'))

The trick is to maintain the unit order, so anytime there is a change of position on any unit, the previous and last position need to be updated. Optimizations can be made where only tiles that have more than one unit are tracked, and the lookup is abstracted by a method that would handle missing position keys. It might also be worthwhile to limit use of Vue's reactivity, since it may add overhead that's not needed(YMMV); for example, if you're relying on a change, instead of making the unitOrder reactive, you could do a reactive outsideUnitsChanged = ref(0) variable that keep incrementing whenever there's a substantive change. This would prevent triggering multiple updates (when you remove unit from one position and again when you add it)

Hope that makes sense.

TSU, I'd keep the data structures non-reactive, and only utilize Vue as a way representing the the data.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this sounds like a good idea, though I'd use a Map instead of an object. I only need this unitOrder on tiles with a town on it, so this shouldn't be a big overhead. And regarding reactivity, that is something I definitely need to look into with time. Currently almost everything is reactive and as you say this could cause some overhead with changes like just switching positions that needs a splice and an unshift in my case.
I now have the issue on keeping this map up to date. My current solution is far from optimal as I check on each unit turn if it is old coordinates has a town and thus needs to be removed from the local Map; and vice versa it he new coordinates I need to add it to the Map.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.