Zatacka is a multiplayer game played generally on one computer. You can view it’s source on Github and play the game on the website.
But what’s more interesting from a techinal perspective is that how I got there (strong JavaScript warning).
Firstly I finished a version where I based all my knowledge on the actual pixels of the canvas. I called getImageData for the entire canvas because calling it is very costy. That means creating a Uint8ClampedArray with the size of boardWidth * boardHeight * 4
(4: red, green, blue, alpha) bytes which is around 3.4MiB for my normal sized (654x1366) screen. If I make an array that big at every 16ms (60fps) then that fills in my 4GiB memory in 19 seconds (note: there is no way to reuse the buffer). This time is similar at different screen and memory sizes, and is definitely not good. The forced garbage collecting introduces way too big lags.
So next I tried many small getImageData calls. Six 10x10 getImageData call is around 15ms (at this point I have to mention that my laptop is low-end with its i3-3217U processor; if I have no performance problem, not many will have). JavaScript’s performance is not really consistent, so occasionally it still had a little lag.
Okay, then I shouldn’t use getImageData. I’ll maintain the image data myself and then paint it with putImageData. Well, putImageData turned out to be way more expensive.
My final attempt was to maintain the canvas and a different array with all the needed data, so I don’t have to call get/putImageData at all. Out of 2940 frames, 11 frames were above 1ms, and they were [1.6199999999953434, 1.2799999999988358, 1.1599999999743886, 1.1400000000139698, 1.2600000000093132, 2.2399999999906868, 1.040000000008149, 1.040000000008149, 2.860000000015134, 6.1600000000034925, 1.0799999999871943, 1.0399999999790452]
with completely incoherent indicies.
That’s a freakingly good performance.