Open abhishek-exists opened 11 months ago
This runs the flood fill algorithm for every player, every time someone returns to their captured area. I'm worried this won't run very efficiently once there are a handful of players in game. If I'm not mistaken, the old server didn't have this either for the same reason.
I think the fix would be to keep track of whose land was taken, and then only update the score of those players.
Another option would be to run a timer and only update the score every few minutes or so. But I'm not sure what the ideal frequency should be, and I reckon it would have to be pretty low for it to be meaningful.
Yeah, you're right.
I think the fix would be to keep track of whose land was taken and then only update the score of those players.
This should be the optimal solution. I'm thinking of returning playerIDs from the FillRect()
method inside utils.js
.
The only thing that bothers me is that, possibly not the best way to write things, I have to propagate back the PlayerIDs to the Game.js
.
Lmk, this is ok
For info: the old server recalculates your own score whenever you finish a trail or every one minute
I think you might be able to collect the player ids in the if (testFillNode(node)) {
statement in updateCapturedArea.js
The signature of Arena.updateCapturedArea()
would have to be changed a bit to return an object instead of just the new score.
Player.updateCapturedArea()
can then use the object to both update its own score, and provide this.game
with a list of players that need to be updated.
I think you might be able to collect the player ids in the
if (testFillNode(node)) {
statement in updateCapturedArea.js The signature ofArena.updateCapturedArea()
would have to be changed a bit to return an object instead of just the new score.Player.updateCapturedArea()
can then use the object to both update its own score, and providethis.game
with a list of players that need to be updated.
I tried this logic, and the only issue I found was that it returned all nearby players whose boundary was adjacent to the current player. So, even if he captures blocks outside the window,. testnode()
will return the player ID of those players
function testFillNode(coord) {
if (coord.x < bounds.min.x || coord.y < bounds.min.y) return false;
if (coord.x >= bounds.max.x || coord.y >= bounds.max.y) return false;
const alreadyFilled = floodFillMask[coord.x][coord.y];
// We've already seen this node, so we can skip it.
if (alreadyFilled) return false;
// append player Id's
if (arenaValue !== playerId && arenaValue !== 0 && arenaValue !== -1) {
capturedPlayers.add(arenaValue);
}
return arenaValue != playerId;
}
Hmm that seems fine by me. Although I do wonder why that is the case because judging from the code snippet you sent I'm not really sure why that would happen.
Its happening because in the updateCapturedArea()
method, you have created a padding mask of 1 block around the player's old bound area, and while iterating over the entire captured area, we'll check all nodes, which leads to the addition of this.
How can I check the only area that the player has currently captured?
Ah I see, that makes sense.
I think the problem here lies in that testFillNode
is fired for every tile within the bounds, but not necessarily on all the tiles that will be replaced.
I think what you'll want to do is to do is perform the check within the callback of compressTiles
at the very end.
Fixes #135
I've left a case when player is still moving (have
trailVertices
) as in this case player will either die or capture their block which will update their scores.