boardgameio / p2p Goto Github PK
View Code? Open in Web Editor NEWExperimental peer-to-peer multiplayer transport for boardgame.io
Home Page: https://codesandbox.io/s/boardgame-io-p2p-demo-0loyd?file=/src/App.tsx
License: MIT License
Experimental peer-to-peer multiplayer transport for boardgame.io
Home Page: https://codesandbox.io/s/boardgame-io-p2p-demo-0loyd?file=/src/App.tsx
License: MIT License
PeerJS can emit various error types via peer.on('error', ...)
.
We should attach some error handling logic after creating the peer:
Line 158 in f84a73a
Using PeerJS’s 'unavailable-id'
error type, it might be possible to automatically decide which client is the host.
All clients would initially attempt to claim the host ID.
If a client receives the 'unavailable-id'
error, that indicates a peer has already taken the role of host and the client should attempt to connect to the existing host.
API could be P2P({ isHost: 'auto' })
.
This has the advantage of the web app not needing to decide who hosts in advance. Just fire up the P2P
transport and the first client to connect will host.
The disadvantage would likely be primarily for longer running games once #3 is implemented. With state persistence it would probably be desirable to have a static host. Some form of #4 could mitigate that: any client can host and all clients persist state.
If a peer tries to connect before the host is online, the connection will fail and never succeed even once the host does come online. Some kind of polling retry logic would make sense here to pick up hosts that (re)connect late.
Currently anyone with the match ID can play as any other player. Some system to support credentials seems like a good idea.
The P2PHost
currently uses an in-memory storage implementation to hold match state. This means navigating, closing a tab, or just stopping/hiding the client will usually result in that state being lost.
We should use a persistent storage layer (e.g. using localStorage
or indexedDB
) and offer some options for how long matches should persist for as well as some way to delete matches.
This is the only trouble I've run into using the experimental p2p stuff. I'd like players to be assigned sequential playerIDs as they join. If anyone could point me in the right direction, I would really appreciate it.
Currently a single client acts as the host and all communications pass through them.
The host could provide connected clients with the peer IDs of all other clients so that they can also establish connections between each other (a “full-mesh topology”). At that point, various other possibilities arise: each client could be responsible for processing and emitting their own state updates instead of sending an action to be processed and emitted by the host. Then if the host drops out, the clients (via their existing connections) could agree a new host amongst themselves and keep playing.
A variation on this would be the host just transmitting a list of IDs for all connected peers to allow them to establish connections only in the case the host goes offline.
Decentralization would also mean storing match state in all clients, which would also be more robust.
This should probably be an optional feature.
I think we should try to make the library as p2p as possible.
To achieve true p2p one thing we need to get rid of this the need for a host.
In boardgame.io a host is the one entity that is trusted by all clients.
The responsibility of the host are the following:
To get rid of the host, these responsibility need to be handled trustless from within all clients.
Authentication will be handled like in any other p2p network through public-key cryptography.
And this is the only part where we need some sort of trust to a single entity.
Not to verify identities but to initiate a game and to invite other players to that game.
Ones the game has started that trust is no longer needed.
Every client can verify moves from any other client, because their communication will be signed by the users private key.
This is one of the trickier challenges to overcome.
In boardgame.io the random values need to be random, that means nobody should be able to control the outcome of the random value. Secondly the random value need to be secret so nobody but the client ,who created the random value, knows what that value is. Because that value might be used to draw a random card or do anything else that is random and secret to the client.
To generate a random value like mentioned above.
The clients that needs a random value, sends a request to all clients. Part of that request is a random value that is encrypted by that client. Because the value is send before any other parts of the random value are known, there is no way to choose the value to get a wanted outcome. Secondly because this value is encrypted by the client, the other client cant influence the outcome by choosing a value that fits their needs. This also means nobody but the client who asked for the random value can know what that value is.
Clients private state is encrypted and replicated to all clients.
This is an another interesting problem. Since there a certain parts that needs to be secret during the game. Verification can only happen in certain situations. For example when a random card is drawn. That move can only be verified after that card should no longer be kept secret. There maybe a way to find these things automatically. But to allow for most compatibility. The moves in a game can only be verified after the game has ended. So when ctx.events.endGame() is called every client publishs their encryption key(s) these keys can then be used by any client to find out if the game has been cheated in. This is an important charakteristik of a p2p network. Trust needs to be replaced by verification.
There is an another Problem that need to be adressed since some games will require that mechanism. To draw a random card from a pile and keep that hidden. Its not enough to keep the random value hidden. The card will need to be removed from the pile. Observing the removal will give a way what card was drawn. To make that work, every card in the pile will need to be encrypted with a diffrent key. And these keys will need to be splitted and every client gets one part of the key. So when a card is drawn. Every client sends their part to the client that has drawn the card. That way only the client that has drawn the card has all parts of the key and can decrypt and see what card was drawn.
I think this part will need to be investigated futher. Because the encryption of the card will need made without ever giving away the full encryption key.
EDIT: It seems like somebody far smarter has already solved this issue. Its called Mental Poker But we would need to evaluate if full distribution is performat enough.
playerView
is not yet implemented when sending state updates to clients:
Lines 86 to 98 in f84a73a
Prerequisite: expose Done in boardgameio/boardgame.io@20817aagetFilterPlayerView
in boardgame.io
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.