I was thinking just now about multiplayer games.
There’s a couple of popular control methods,
Such as the “take turns” system that works well for board games (chess, chequers) and turn based games like Teeny Tank:
Then there’s two people sharing the same Arduboy:
There’s also peer to peer (hard to implement - even needs micro to micro cable):
Then there’s using a PC as a hub - the “Server” as it where.
I wrote a game people loved in school on the Archimedes (over 25 years ago now) - a multiplayer (up to 4 players) “Snake” that had “speed up” and “slow down” apples, “Slow down ALL other players” as well as a “tunnel” button that made a “worm hole” under the ground that immediately moved the snake forward several pixels.
The dynamics made was interesting - a slow snake was at a disadvantage - there would be often spirals created where the faster snake on the “outside” of the spiral keeps getting ahead and turning towards the slower worm. They’re done for! But no! They can worm-hole out of there - an instant jump 20 pixels forward under the faster worm. A sudden turn, and the fast worm is dead!
The speed implementation was easy - instead of “X += 1”, the speed would be a decimal “X
+= speed” where speed is something like 0.1 Checking at the “head” of the worm just as it moves a pixel is used for detection. This is better than always checking one pixel ahead - which would not give a slower travelling snake a chance to turn out of the way of the body of a worm in front of them.
I think I’ll use the PC as a server - my question then is would several Arduboy’s connect to the PC on different COM ports?
I could poll the COM ports in .Net for Arduboy names, and keep track of them as they’re added and removed.
The interesting bit then is the abstraction of the worms head position and how its direction changes, and then the body.
Would I send run-length-encoded body updates? Sounds good - draw the head from the head backwards - e.g. up 20 pixels from the head, left 20, down 10. That’s 2 bytes for each corner. Direction, and length. Or maybe even one byte? Bit 0 and 1 are direction, bit 2 to 7 are length - up to 32 pixels…
If the connection is ALWAYS solid - we could send a single byte per snake on each frame that says “Situation same as last time”, so no “path description” is sent instead of the 1 to 9 bytes depending on snake turns. Say there’s 4 players and 10 turns each - that’s 40 bytes per frame, and maybe 30 frames a second. The speed of the serial connection would have to be high to move those 1,200 bytes per second. Hm, maybe 15 frames a second?
Maybe sending a zero 5 times then a number - tells the devices to start that phase of the game - waiting in the foyer, playing the game, viewing the final scores and winner, and back around.
Graphics are easy - pixels. Though how big to make the board? Larger than the display? How’d we store the board, and detect hits? Check bytes? Use the “GetPixel” function? It’s likely better on the server… the PC.
In that case - we can use a 2D array of BYTE’s - a 500 x 500 board is a tiny amount of memory on the PC, and can be checked for collisions extremely easily.
We could send each Arduboy the actual OLED DISPLAY RAM it needs for its display!
Made from the 2D grid packed into stripes of vertical bytes aligned to the OLED RAM, and streamed to the Arduboy.
This opens up a new world of animations and pixel art - we’d have the PC’s memory to store them all in! The PC then streams them to the Arduboy… just like a remote desktop.
Hmm… there’s such a huge amount to design for such a simple snake game… awesome!