nesbox / TIC-80

TIC-80 is a fantasy computer for making, playing and sharing tiny games.
https://tic80.com
MIT License
4.93k stars 479 forks source link

Playing with other player across internet #457

Open jahodfra opened 6 years ago

jahodfra commented 6 years ago

How to play cartridges when co-player lives across the town? I suppose that voice communication can be more or less solved (e.g. by hangouts call). So I consider only synchronization of player actions:

We can send player actions specific to the game to the server. And game specific logic on the server could reconcile these actions with the game state and send the game state back to the clients. The client than reconciles it with its own state and displays it. The game have to be designed from the top down around the network protocol. The advantage is that game withstand larger network lag, can have more players, it makes harder to cheat.

I think the previous approach is quite hard to apply to existing game. So I am more interested to just have 2 running instances of the game sharing their controllers.

I suppose we can send short messages to the server about pressed keys on each client. The server would have sliding window and send back pressed keys to client with e.g. 3 seconds of history. If the client receives older message it ignores it, otherwise it will replay all actions. Due to the lag inherent in collecting keyboard events and sending them to clients the game requires quite low ping.

If we accept lag 100ms we can expect 30ms from keyboard, 16ms from drawing routine. So we require ping to be less than 54ms. This should enable playing on a same continent with good internet connection.

Necessary changes:

I am not sure how hard is to implement this in JS (browsers do not allow sending UDP to any server). Also this feature is just an idea.

hashalon commented 6 years ago

What you are proposing is what a high level API would do. Yet the API of TIC-80 is designed to be low level. I think a few functions to connect clients and send messages using UDP or TCP would be more than enough.

I believe that until now, nesbox didn't want to implement any network features.

jahodfra commented 6 years ago

It depends. It can be considered hi-level, because it is quite complicated to implement. On the other hand the API is not really network interface and the cartridge would not be required to know anything about the network setup.

I had this idea so I decided to documented it as possible choice. It's up to nesbox to decide what he wants in tic-80.

MineRobber9000 commented 6 years ago

It's not high-level because it's complicated, it's high level because, as you put it, "the API is not really network interface and the cartridge would not be required to know anything about the network setup". High-level means that most of the details are abstracted away.

jahodfra commented 6 years ago

@MineRobber9000 Does you comment means that you would rather have direct control over TCP/IP stack?

nesbox commented 6 years ago

I like the idea of network controllers sharing, but if you want your game to be synchronized you have to exchange input data on every tick (60 times per second), which will work in local network.

With ping > 15ms, you could exchange gamepad data on every 3-4th tick for example (~45-60ms), I did similar things in my previous emulation project. The server is very easy to implement, it just waits for connection of two players and receives/sends gamepad data each other.

Players could connect via Gamepad Configuration in the Game Menu, select server, enter code/pass or something to connect...

I'll think about it... Thanks

msx80 commented 6 years ago

i think that, in any case, we should put as much functionality as possible in TIC (as opposed on the cartidge code), as things like "multiplayer lobbies" etc can take a lot of space if you only have 64k of code.

Also, i don't think just "sending keystroke" around would work in the generic case. Probably is fine in LAN but on the internet lag is a bad beast and it's often required to be dealt with with compensating algorithms. You cannot just expect the lag to be "low enought". And the compensation algorithms are often specific to the game or even the functionality (for example FPS games have separated tecniques for "sniper" weapons than regular weapons).

MineRobber9000 commented 6 years ago

I just had a cool idea: what if there was a "network co-processor"? You make a buffer in your main code that works as the co-processor's memory and then you can write Lua/JS/Wren/whatever up to around 32-64K of code for the coprocessor and it will run on its own.

RobLoach commented 5 years ago

This could work through the TIC-80 libretro core via RetroArch Netplay. As long as we can get a serialized state of the currently running game, then it would work.

RobLoach commented 5 years ago

Confirmed RetroArch Netplay works with TIC-80 through https://tic.computer/play?cart=893

tic-80--netplay

The key is to store all information in pmem. Load it at the beginning of the TIC, save it at the end.... Curious how network performance would be.

jahodfra commented 5 years ago

@RobLoach great idea! I have to try it at home.

RobLoach commented 4 years ago

Here's another quick video I did demonstrating RetroArch's Rewind on the above cart....

ezgif-2-88217809a0e0

jminor commented 3 years ago

Here's a proof of concept which allows you to play together remotely via WebRTC just by sharing a URL with other people: http://pixelverse.org/experiments/webremoteplay/

jminor commented 3 years ago

If you try ^ I'm curious to hear if it works for you. I'm seeing some reliability issues more on some browsers/platforms than others.

nesbox commented 3 years ago

I tested and it works on Chrome. Thank you :)

revdeluxe commented 2 years ago

maintaining server is expensive... why not make use of gan(global area network), and yes it's hamachi/zerotier-one/etc(either use VPN, PTP, RPTP HUBS) ... since they already have servers running globally using these service can save cost, time, and brain power implementing a state of the art relay... a RPTP(relayed peer to peer) can be the best choice for this though... find any IRC chat relay then PTP there.

BuoYancYdabl commented 2 years ago

maintaining server is expensive... why not make use of gan(global area network), and yes it's hamachi/zerotier-one/etc(either use VPN, PTP, RPTP HUBS) ... since they already have servers running globally using these service can save cost, time, and brain power implementing a state of the art relay... a RPTP(relayed peer to peer) can be the best choice for this though... find any IRC chat relay then PTP there.

Good idea, having same thoughts! One player basically hosts game, another one joins it. Game will be calculated and send from host to joined one(s) without expensive game servers using tunneling apps.