Brainstorming on a web-based multi-user game design...

I'm not into the whole gaming thing, but I suspect that what I'm looking for isn't anything particularly new. It's a way to connect several players to the same board game using a couple of different web apps.

Imagine a game like cribbage, dominos, Monopoly, or Scrabble, where you have several players at different locations playing the same game. Anywhere from 2 to 6 or so players per game.

On my laptop or computer I'd be running a common game app (the "Board app") that shows something like a table-top with the game board and some stats and whatnot on it. It's accessible via a website URL. It's either a shared web page or perhaps a video stream (I'd prefer a shared web page for lower bandwidth).

A player can join the game somehow on some device that lets them view the board on a large screen, maybe their home TV, and they'd be able to also connect via a second device like their phone or a tablet to manage their resources, called the "Player app".

Let's take Scrabble as an example. Everybody gets to see the same playing surface as the Board app's view. Then each player uses the Player app on their phone or tablet to manage the letter tiles they are dealt. They could play around with different word combinations and how they'd fit on the main board, without anybody else seeing what they're doing.

When it's their turn, they'd be able to press a button sequence and tell the game "put this string of letters starting at this box on the main board going in this direction" and the tiles would be rendered on the common playing surface in the Board app that's visible to all players.

What I'm wondering about is ways that one could implement the underlying communications channels needed by such a design.

If it's a card game, there are cards you might want to toss away and maybe replace. If it's a game that uses dice, you'd spin and then direct where you want your playing piece to move on the board, following up with other options that might apply. That all depends on the logic and rules of the game.

But they all require the same underlying mechanism: a common board, private areas for players, and a way for the Player app to tell the Board app what the player wants their move to be.

The Board app is a "display only" app that lets everybody see the current state of the playing board.

The Player app lets them manage their own playing pieces and do whatever they want "off-screen". When it's their turn to play, they can tell the Board app, "Here's my move".

How could this be implemented? I can see how this could be done under Windows on a LAN, but I'm drawing a blank on how to do it using web apps running in the various browsers.

1 Like

Hm. It sounds fundamentally like you're trying to share "state" between groups of users? IE, the current state of the board and player pieces, card hands, the deck, or whatever. A given app needs to access the same shared state as other users participating in the same game. Ideally, the rules for changing state (the game rules) are such that you can take the current state and a player move and get a new state without too much effort. IE, the current scrabble board with the played tiles, undrawn tiles and player tiles and current scores, and then a player makes a play, so you get a new state with the new scrabble board, fewer tiles to draw, and updated player tiles.

Lots of options, depending largely on how many users, the size of the state data and how quickly you want the state changes distributed to the players. State data changes could be distributed as a diff (only what has changed) if the state data is large, so no worries there.

One option is for them to connect to a shared websocket server. The server has the current game state and might be what enforces the rules. Subscribers to the websocket server can then be immediately notified of the new game state (or diff or whatever) as part of how websockets work. The limitation here I think is that it might be difficult to maintain a lot of websocket connections on one server, and you'd have to do a bit of work to handle connections that are lost. Like someone turns off their phone and then goes back into the app at a later time. Doable.

A REST API (XData) could do something similar but with a bit of polling involved to check whether the game state has changed. A "scoreboard" mechanism of some kind could make this more efficient, so it can just ask when the game state last changed. The game state itself could just be a database object. The "Scrabble" table might have a record for each game. A column for the game state. A unique game identifier. a timestamp tracking when the last move was made. That sort of thing. Would be a good use for something like StellarDS.

The LAN idea, where there is no server, could work where essentially everyone playing has a copy of the game state and whoever is making a play sends the new state (or whatever is needed to get to the new state) to the other players. Provisions have to be made again for players that drop out periodically (network wise). A centralized server might be used to help establish or find the connections between the players (the lobby in a game for example) but then they could all exchange data amongst themselves after that, using something like an MQTT broker/server to handle messaging between the apps. If setup efficiently A mosquitto instance (MQTT broker) running on a Raspberry Pi could likely host many thousands of games, given that they're not all pushing messages continually 24/7.

I'm sure those could be combined in different ways as well, maybe using XData with WebSockets for more timely notifications instead of having to do some kind of polling. I'm sure there are dozens of other ways to do this, depending on the particular limits that you might hit with any of these kinds of things.

I have done this in a backgammon game using XData to post the moves and it works very well but I obviously only ever have two players,

1 Like

Care to share a few more details? I know it's possible, but I'm looking for what sort of "plumbing" is being used.

The XData server handles multiple games between different users. I use GUID's for each player in the game and record that information in the moves table record. I have a timer in the app to see if any new moves have been made for the game users are in and if so process them. I record the date time of the move and when the last move was processed to avoid getting the same move again.

1 Like

I think that WebSockets might be overkill inasmuch as they're scarce resources and I don't need the tight instant coupling they afford. MQTT seems like a far more light-weight approach, and the details needed for any given move can easily fit in the small message sizes MQTT supports.

I think the Game State would be maintained in the Board App. It would enable each player to submit a move when it's their turn, and maybe do additional things before disabling that player's ability to make a move, and switching to the next player.

We could say that a given Player would have "focus" and could submit a move and do whatever else is needed. Without focus, some features would be disabled, but they could still do things for their own needs. Eg, for Scrabble, they'd be given more tiles to use before losing focus, and then they could play around by rearranging the tiles to spell words. But only the player with focus would be able to post a move.

I chose to use XData so that I could really so what was going on by examining the tables used. This way there is only one connection to the database and as XData is stateless it seems to work well. If there were thousands of users - who knows? Mainly users play against the computer so in this case it is not necessary to post these moves.

1 Like

Do you have info to support this claim? Why does Websocket scarce resources, especially compared to constant polling from the client?

It's basically a client/server architecture as you have one central app maintaining the state of all of the clients. The interaction rate has a very low duty-cycle -- I mean, look how much time it takes between people's turns on a regular board game! That's not changing here. Players often take a minute or more between moves. Having real-time connections is wasted in this situation. Polling seems ideal. Heck, you could use Email as a messaging platform if you wanted and it would work fine! (I'm not building a bot network! It's for real people to use.)

I asked the question because I'm trying to expand my understanding of how to approach things in this sort of environment. The answers I'm getting are like "I'd use PVC pipes" vs. "I'd use copper pipes." The problem is, the server and all of the players are in different cities, and a message written on a 1" square Post-It note needs to be sent back to the server and then out to the next player between each move.

In my mind, polling seems to be the most efficient approach, but I'm asking for insights from others. :slight_smile:

So how would YOU approach making multiple WEB Core apps interact in this scenario, taking into consideration that they're all running in a decoupled distributed multi-processor environment and the clients are all buried inside of a web browser?

I think the problem with polling isn't so much about the delay but rather the amount of traffic that could result. Say you poll once per minute. If you have 60 concurrent users, that's one request per second on average. Continually.

Using WebSockets, you have to maintain a connection, so there are some server resources and state allocated there to be mindful of, but the only traffic is when plays are made. So for the same 60 concurrent users, there might be an average of one request per minute rather than per second. Significantly lower network traffic. A bit more work to distribute the load when users increase, ensuring players in the same game share the same websocket server, that sort of thing.

And they don't have to be mutually exclusive. Things like logins and getting the original board, managing the user lobby, that kind of thing, could be handled by XData via its REST API, and then users could connect to a WebSockets server (perhaps provided by the same XData server) when they join a game. All the while, everything is passed back and forth to a database.

Part of the fun with TMS WEB Core (and TMS XData) is that you can wire up multiple connections to multiple things, have all the comms stuff working asynchronously, and just update the UI when stuff changes.

Note that in the same XData server you can have the regular endpoints and also WebSockets endpoints.

Let me ask this: for web pages that have AJAX widgets on them, and if someone posts something that causes one of the widgets to change, say like above here that shows someone added a comment, how is that widget being informed of the state change? Is it polling regularly? Or is it using a WebSocket? Or something else?

Because I see these kinds of things on virtually every web page I visit these days. Amazon, eBay, FB, LI, IG, Target, Walmart, ... they're constatly being updated. Nobody seems to give a rip about the traffic involved. They chew up memory like it doesn't matter and force my computer to reset every few weeks.

I realize that "in theory" there might be a little more traffic involved to alert one of the Player apps that it has "focus" so the player can post a move, but it's a FAR CRY from what most big and even small (eg, little WP sites) are doing today, and nobody seems to care or even worry about it.

Also, if I look in my server weblogs, the vast majority of traffic is scripts pounding away on my server looking for known exploits to burrow into my server. This is just a "cost of doing business" these days. Having a few player pinging with a short message every minute is such a tiny amount of activity that I can't wrap my head around why it would be a problem. Especially since most people seem to have their email set for one-minute polling.

I realize these things do "add up" over time, but that's why you host thing in the cloud -- so you can add more resources that let your server fit the needs of the traffic you're getting.

That's why I said it is a question about scale. For a handful of users, none of this matters. If you're running FB or Walmart.com, then that's a different story, and there are 2700 different ways of optimizing every bit of every comm channel.

Or you don't care and just pay the $10,000 AWS bill when it comes in each month. That works, too. It's all a game of where do you want to put in the effort and what are your options to mitigate and avoid all costs.

As for your question about how apps update, I'd wager probably something like 80% of everything like that goes through a REST API. It's also why many public APIs have rate-limiting of some kind, so everyone checking their email every minute doesn't blow up their system.

The good news is that many services (like XData) are extremely efficient so even a small server like you'd get with a bottom tier 2GB virtual server can likely handle quite a large number of users (given that they're not all concurrent) before you'd even notice.

And, on top of all that, we live in a world where the MVP rules all, so getting something to work is often the beginning and ending of the exercise. Making it work better, cheaper or faster is a post-acquisition task in the minds of many.

2 Likes

So the AJAX widgets are polling the server via a REST API?

Quite often, yes. The coding mechanism that is used to trigger the call to the REST API varies no doubt, but from the server perspective, it just sees a request incoming like any other. In TMS WEB Core, this might be triggered with a TWebTimer or some other logic. The mechanism used to issue the REST API request can also vary quite a bit, from direct calls in JavaScript, to HTMX, or to the more familiar Delphi equivalents.

How aggressively the polling is scheduled is a function of what people can get away with before being blocked, often, or whatever the minimum is that makes sense for the application.

HI Wagner,
where I can find documentation about WebSockets in Xdata?
Thanks

Blog post:

and official documentation:

https://doc.tmssoftware.com/biz/sparkle/guide/websockets.html

Hi Wagner,
thank you.
But I thought there was specific documentation related to WebSockets in the Xdata services! :-)
Standard documentation regarding Sparkle and WebSocket is readily available.
I apologize.
:-)

1 Like

Actually the example provided in the mentioned doc and even the demo, uses XData services.

Ok Wagner,
Thank you.

1 Like