realtime-multiplayer-in-html5
realtime-multiplayer-in-html5 copied to clipboard
Support for event filtering based on proximity/relevance
For medium and large maps(rooms) with more than just a few players or npcs in each map, sending all state updates could significantly impact performance and is not really needed because only a handful of these events are expected to be visible to the player at a given point in time.
A simple server algorithm could be used to only send to the player the events which are happening at his vicinity.
Here's a (naive) working example of what I mean:
https://jsfiddle.net/y9sovv4s/
Total events without filtering: 64 Total events to be sent to a given player after area filtering: 16
In the 8x8 grid with 5x5 awareness, like in the example a 75% percent reduction in payload data was a complished. In a 12x12 grid that would have been 90% savings. Not bad! :wink:
Just edit AbstractGame.js
function getStateForPlayer (player) { return { serverTime: getTime(), ownPlayer: player.toJSON(), players: Array.from(players.values()).filter(otherPlayer => { return otherPlayer !== player; }).map(player => player.toJSON()), events: eventsFired.filter((event) => { return event.getFiredBy() !== player; }).map((event) => event.toJSON()) }; }
and change players to close players 🎱
@asdfuken : wow, looks like a nice and elegant solution, indeed. However to avoid the server having to recalculate the close players array at evry update, which could be expensive, a distance cache could be implemented. Events sources could be cached as 'close', 'near' and 'far' according to distance. After a given time, say, 1 second, the cache would be recalculated testing only against the 'near' group (which could have entered the 'close' zone). The 'far' group could be skipped at this point and tested again only at a later time, to save on computing resources
Just for the record, here's my rookie attempt at storing events in a 2000x2000 sparse matrix and thus bypass the "regions" approach that I mentioned above. I'm using math.js to return a subsection of the main matrix corresponding to the area that is visible to the player: https://jsfiddle.net/3o9tfm9g/
The results: total events received by the server: 69 total events within 400px range of a player positioned at x=200,y=200: 11
Just don't ask me how fast or slow this code is, I really have no idea :smile: