-
Notifications
You must be signed in to change notification settings - Fork 715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Out of the box in game chat support #460
Comments
I'm not opposed to this idea, especially if it can be configured nicely so that users that don't need it don't incur any cost. We'd just need someone to sign up for this as I have my hands full with other areas of the framework. |
@nicolodavis If I were to do this, do you have a recommended approach in mind? |
We currently store game data in two areas:
The areas above are two key spaces in the same table (although in theory it is possible to change the storage adapters to use two entirely different tables for this). For chat, I'd propose using a separate table that is able to store messages between players per game in a nice normalized flat structure.
Links: |
Yesss, I want this. Can this be opt-in, though? Preferably on a per-game basis? I assume we'd have a pre-built chat component for the front-end while offering options to implement your own front-end (similar to the current lobby discussion). |
Yes I'd hope that we make this opt in. We can also implement (as a first step) a purely ephemeral chat that uses the existing socket layer. That way you don't have to worry about storage, which might be exactly what some people want. |
I want to implement this, it is one of the most important features missing on FBG right now. Cant we really re-use the current store ? I was thinking something on the sorts of: For sending messages:
For listing all messages for all players:
Each message could be a specific action type on the store/reducer, and change the state on a separate part of the state object. This will mean that if a user reloads the page, the messages are still going to be there (retrieved from the store). In fact, this is so close to what Plugins offer that I thought I could do it in a plugin, but I had trouble with the Plugins API not being exposed to the Board |
@flamecoals Would be great if you could do this! I’m not sure about storing chat messages in the main game state. Given that chat could be fairly busy involving all players simultaneously, it would potentially increase the risk for race conditions once chat messages are trying to write to the same blob as the main game engine. We should probably add database methods for reading or adding to a game’s chat messages, which could be implemented in a transactionally safe way similar to how the deltalog is currently appended in How do you think we can manage enabling/disabling chat? 💭 One nice to have feature would be the ability for game logic to post a chat messages, enabling game achievements or events in the chat log. One further alternative to consider would be not to store chat messages at all, just providing an ephemeral chat room for players connected at any one moment. (Potentially a good idea from a privacy perspective, because users are more likely to reveal personal information in a chat, and storing that data could introduce oversight headaches.) |
I didn't know that the main game state could run into a race condition, because the store is always changed using a message and reducers for each state transactions... Can you detail more about how this can run into a race condition? Some of the moves I have on my games are "clicks" which are very frequent and I've never noticed race conditions. Enabling/disabling chat could probably be done on the game or client configuration with a flag? If we use a plugin under the hood, the game logic could easily post chat messages. This even makes me think that we should maybe just invest in the plugin API and maybe make a plugin available for users that want, but maybe not a built-in in BGIO |
Currently the reducer guards against race conditions using an incrementing state ID. Every move, the state ID increments and the reducer checks to make sure actions are sequential. If it receives a bad state ID, the action is rejected. This approach isn’t so helpful in an asynchronous, multi-client context because two users could send messages more or less simultaneously (each with the same state ID) and one of the two would be rejected as its state ID would be “stale”. Chat would presumably be more permissive: message order is not crucial, so as long as the database’s message appending logic is atomic, parallel writes should be possible. Improving the plugin API would be a great outcome too, to allow more custom behaviour without needing to fork the code. |
I'm not sure if using the game state to store chat messages (even through a plugin) is a good idea. It makes application state too closely coupled with game state. Note that the Plugin API already supports intercepting custom actions (even bypassing the state ID check), so I don't think you need any changes to BGIO to implement this via a plugin. I think a cleaner approach would be to allow associating custom user data to game instances via the API that the lobby uses. We already have this in the form of game |
Thanks for the response @nicolodavis, the issue with using lobby in my mind is that it is a REST API and we do pooling to check if the lobby status changes. I believe that would be a waste of resources to use the same technique for chat,and that it fits much more a websocket style communication. Also, how would the board use the lobby API? Through the metadata object ? What about the users that do not implement lobby, would they not be able to implement text chat? For instance, in local or AI games we do not use the lobby API at all in FBG. Which would be useful if the game itself might send messages? |
Note that you will be serializing / deserializing the entire game state for every chat message, which seems like a bigger waste of resources than polling. Also, the game creation API is not limited to REST. We could use GraphQL or web sockets to implement it. I'm proposing that we look at how we can improve that to support chat rather than sticking it into the game state. |
I don't agree that it would be a bigger waste of resource, serializing and desserializing happens only in memory and the only thing that goes through the network is the message. While polling might need to go through the network every X seconds, with or without new messages, which can drain the battery of mobile phones easily. |
The chat API could very well use boardgame.io's websocket backend to do realtime updates. We just need to make sure that the data sits in a separate section of the storage (analogous to metadata, but could be something new) and is wired through the system so that it is available on the client. That said, there is no harm in trying to write a plugin first. No changes are required in boardgame.io as far as I can tell. |
I tried to write the plug-in yesterday, but the new plugin API wasn't available at the Board render() ctx, so I couldn't list the messages there and I couldn't call the API to add a new message. I even deleted the code, but I could try again ... Are the plugins API supposed to be available in that ctx too? (In the render() on react components?) I might do a fiddle just to test the concept |
You'll need to read the data from Events can be dispatched to plugins using You would only need to interact with |
Ok, thanks for the pointers ! I will try to add plug-in support to this use case then :) |
It’s worth noting that this is only currently the case for sending the message, not receiving it. Once a plugin’s action is processed on the server, all clients would receive an update event containing the entire updated game state. I wasn’t aware of the |
Yes, the number of bytes sent on the network is going to be at least an order of magnitude larger than the chat message itself. Same with storage in the database. Each chat message is going to duplicate the entire game state and store it in a new record (unless you use a storage implementation that merely overwrites the game state in-place). Perhaps an easy way to fix this is to introduce an option to the Plugin API to indicate that data for that particular plugin needs to sit in a new column in the database? This would effectively allow you to decouple plugin data from the game state and address most of the concerns in this thread. @flamecoals @delucis What do you think? |
Done in #871 / #879 and released in 0.43.0 thanks to @tomasvidhall 🎉 |
Any plan for out of the box in game chat support?
This would be very helpful.
The text was updated successfully, but these errors were encountered: