Skip to content
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

Feature request: multiplayer game with server API and more features #8817

Open
CrsiX opened this issue Mar 5, 2023 · 76 comments
Open

Feature request: multiplayer game with server API and more features #8817

CrsiX opened this issue Mar 5, 2023 · 76 comments

Comments

@CrsiX
Copy link
Contributor

CrsiX commented Mar 5, 2023

Hi, we really like the game but the multiplayer functionality just sucks, sorry. (And the server is pretty ... hacky. Maybe a plain FTP server would have been a better choice).

Therefore, we would like to put our hands on a new multiplayer service. We essentially build our own server (in Rust) while also hooking the relevant client functionality. Additionally, we integrate feature requests such as the following:

However, we would like some help on integrating some of the stuff in the client app. For example, we build the server and the API and all of the network-related code, while someone else could jump in to tweak the user interface to make use of the newly available features (e.g. chatting or username/password instead of UUIDs).

Side question: how many people are currently using your public multiplayer service? A rough approximation (20 a day or 20k a day)?

@CrsiX CrsiX added the feature label Mar 5, 2023
@yairm210
Copy link
Owner

yairm210 commented Mar 5, 2023

That's a question for @touhidurrr, he built the server at https://github.com/touhidurrr/UncivServer.xyz
Given the '3M requests per day' I assume we're talking more in the 20K range

I have no problem with overhauling the API (current API was basically a MVP for migrating away from Dropbox, hence the FTP-ness)
But we need to let existing users retain their current games.

This means one of the following:

  • Changing the implementation together with uncivserver.xyz
  • Adding an alternate implementation alongside the existing one

I would obviously prefer the former but @touhidurrr also has his own free time restrictions.

@GGGuenni has been leading the recent changes for passwords &c so he's more relevant to this than I am
As I have stated many times in the past, this is super outside of the roadmap for the project - but if you have people willing to work on it from both sides, then why not

Starting with the basics - 'create multiplayer game and allow others to join'.
We'll want to start with a really stripped-down POC:

  • One player creates the game with set number of players, game options, etc
  • All initial players (except the owner?) are AIs. Each player who 'joins' the game effectively replaces one of the AIs, so we can start the game at any point with the same amount of players
  • Uploads to server (GameSetupInfo, including a new field: "creator ID" for the person who created and can start this game), which registers this as a 'lobby game
  • Other players can retrieve 'lobby games' and ask to join.
  • When a player joins:
    • If there is an AI he can replace - does so
    • If not: error message to user
  • Creator gets updates of new players joining the game and can decide at any point to 'start the game'
    • Server gets message 'game starting' to disallow other players from joining and to remove from 'lobby'
    • After the new game is created, it is uploaded to server

That's already a lot of work, and this doesn't include issues like

  • Closing inactive lobby games after X amount of time
  • 'leaving' games before they have started
  • Someone creates a game and then closes the app - how does he get it back

@touhidurrr
Copy link
Contributor

touhidurrr commented Mar 5, 2023

why not websocket?
i think current fileserver is good enough, but if we want to implement all those features you are talking about,websocket might be better.
also, i would be free after a week or so, at the time my mid term examination finishes. jobless now.

@yairm210
Copy link
Owner

yairm210 commented Mar 5, 2023

I'm not against, do whatever feels best to y'all

@touhidurrr
Copy link
Contributor

touhidurrr commented Mar 5, 2023

Also due to some issues, i am actually rewriting UncivServer.xyz.

@myOmikron
Copy link

Hey guys, I'm with @CrsiX,

nice to hear that you're open to improvements in this regard :)

But we need to let existing users retain their current games.

I'd personally would go for a new implementation, let's call it v2 for now. It makes it easier to make design choices if you don't try to reuse the existing implementation. So I think it would be best to add another option to the multiplayer settings for this, like it is now for dropbox vs uncivserver.xyz

We're also open for any contributions, regardless if it is code or suggestions regarding API design @touhidurrr and @GGGuenni.

We'll want to start with a really stripped-down POC:

The suggested scope sounds reasonable for a first prototype


why not websocket?
i think current fileserver is good enough, but if we want to implement all those features you are talking about,websocket might be better.
also, i would be free after a week or so, at the time my mid term examination finishes. jobless now.

I think websockets would greatly improve the load on the server, as there's no "is there any new data?" like requests anymore.

I would use an API for the lobby mangement and go for websockets for exchanging the actual game data (and chatting in the later implementation).

@touhidurrr
Copy link
Contributor

Ok, or let's split this into separate parts and implement them one by one:
I would like to work on the lobby and chat feature first. Preferably in-game chat.
The concept of in-game chat is pretty simple. You would join via WebSocket and any message you send will be broadcasted to other players. There would be no chat logs stored on the server, and if you go out of the game then you lose the chats. This is actually pretty common and examples are chat in google wrokspace products (meet, docs, sheets etc.), IRC chats etc.
I think this can be done within a week or less.

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 5, 2023

As far as I understand you, @touhidurrr, you "just" want to improve the current multiplayer handling with a few new features (and a server re-write on your side). However, "our" current approach is completely overhauling the whole multiplayer handling. That's why I said earlier:

we build the server and the API and all of the network-related code

This includes both server and client. Therefore, the question: do you want to participate in designing and implementing the new architecture? Because splitting the work only makes sense if we pull together.

Our server implementation work already started here: https://github.com/hopfenspace/runciv

@touhidurrr
Copy link
Contributor

touhidurrr commented Mar 5, 2023

However, "our" current approach is completely overhauling the whole multiplayer handling.

Oh, I think I misunderstood the context of the issue. Good work!

the question: do you want to participate in designing and implementing the new architecture?

I don't know rust, so no. However, I would like to participate on the design aspect of it. I already have many design concepts in my mind for many features like Lobby, Chat, etc. But not as a REST API but as a WebSocket server. Obviously, some endpoints can be REST but overall it is better to avoid REST as a whole to make the mp experience feel more seamless. As polling is not really a pleasant experience for anyone. I guess it is time to write them down and take opinions and start working on them. I guess we can share our design choices and discuss among us to build the best Multiplayer server ever.
Also, the focus should not be just rust but a good standard that can improve the Multiplayer experience as a whole.

@touhidurrr
Copy link
Contributor

Side question: how many people are currently using your public multiplayer service? A rough approximation (20 a day or 20k a day)?

I think this is the data you are looking for:
image
total_requests_2023-03-05T19_03_02.562Z.csv
unique_visitors_2023-03-05T19_03_02.564Z.csv

Also see:
https://docs.google.com/spreadsheets/d/e/2PACX-1vSPk2pf0_SGVm08pXLmrJjStlVh33ItHweVOYFdqqP9Ghtec1rvTuz9GmfP-zQIWfiB2TGtJU7kn6Lu/pubchart?oid=2039282213&format=image

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 5, 2023

Thanks for the insight. Around 100k users is a good value for this game, but no stressful amount for a good server as well.

Do you want to join us at the discussion page? :)

@touhidurrr
Copy link
Contributor

touhidurrr commented Mar 5, 2023

Thanks for the insight. Around 100k users is a good value for this game, but no stressful amount for a good server as well.

This is monthly statistics, but yes, that is not considered as high volume traffic.

Do you want to join us at the discussion page? :)

Yes. I read your rust code and there is some things that I would like to talk about. However, I would prefer if for Unciv Multiplayer v2, we discuss a list of features that we would like to implement, open a new issue with a checklist in this repo and then start working on that. Also, @yairm210 from you post #8817 (comment), I am not sure if you want to maintain UncivServer.jar and it would be good if you could clarify that, but regardless I think it would be good if we open a new branch to and start writing proper docs UncivServer API and possibly implementation for UncivServer.jar (given that many players from time to time want to start a server locally) and the client.

@yairm210
Copy link
Owner

yairm210 commented Mar 5, 2023

Unciv.jar can die as far as I'm concerned. It was just a temporary hack to demonstrate the API so people who wanted to stop using Dropbox could.

@yairm210
Copy link
Owner

yairm210 commented Mar 5, 2023

Like with everything, I'm in favor of burning all the old stuff to the ground - provided that we have a replacement that's been tested and that we can phase out the old gradually.
Which is why it's important for us to maintain compatibility to the current server, at least until such a time that the current server uses the new format, or - alternatively - all of our users successfully migrate to the new one.

@touhidurrr
Copy link
Contributor

Which is why it's important for us to maintain compatibility to the current server

I think this is a good time to share this poll:
image

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 5, 2023

Which is why it's important for us to maintain compatibility to the current server, at least until such a time that the current server uses the new format, or - alternatively - all of our users successfully migrate to the new one.

I think the following mechanism solves the problem with relatively low effort (at the time the new server is stable and ready):

  • A user wants to start a new game => the user implicitly uses the new server (v2) and stores a version flag in the list of known games (this could also be added to "v1 games"), but it falls back to a v1 server if the server is v1 (see below)
  • A user wants to resume an existing game where the version is known => it uses the respective version
  • A user wants to resume an existing game where the version is not known => the user implicitly uses the old server (v1), but when a 404 arrives, it tries to use the new server (v2) -- then, at some point, this behavior is inverted to use v2 by default with a fallback to v1

But what about the server address? It just continues to work. The aforementioned mechanism is a kind of version auto-detection. However, to make things perfectly clear, I would like to introduce a new endpoint: GET /api/version. This endpoint determines the API version as simple JSON body with a single integer. E.g., for all current servers, it yields {"version": 1}. For our implementation, it returns {"version": 2} instead.

Note that currently we plan to have a completely different user handling. Therefore, this approach requires significant client-side rework (and extension). I'm already looking into it...

@yairm210
Copy link
Owner

yairm210 commented Mar 5, 2023

That already exists in the /isalive check, it should already return the version for password-authenticated servers
Implemented by @GGGuenni
We could have it as an entirely different endpoint, YMMV

@GGGuenni
Copy link
Collaborator

GGGuenni commented Mar 6, 2023

Yea I was planing to introduce Websockets with the next server feature: Lobbys
I don't know how much our ideas are clashing though but we can probably find a solution we can agree on
I will say though that chat is nothing I want to work on, so I won't be helping to implement that

I went with the server features approach to give server owners (and developers) enough time to adopt changes and to be able to deprecate individual modules instead of replacing everything at once as soon as the old "dropbox way" of doing things isn't used anymore
The feature set endpoint could be moved to it's own endpoint but I don't really see a reason to do so since we would need to make two API calls instead of one

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 7, 2023

I went with the server features approach to give server owners (and developers) enough time to adopt changes and to be able to deprecate individual modules instead of replacing everything at once as soon as the old "dropbox way" of doing things isn't used anymore

An understandable approach. But the number of server developers and server operators is pretty limited, AFAIK. Is it really useful to have long periods of upgrade?


You can find our currently implemented API here: https://runciv.hopfenspace.org/docs/
Note that it changes rapidly, since we're implementing with a fast-forward approach. You can try those features, if you want.

I'm going to implement the PoC mentioned above, so that we can further elaborate the next steps, because it requires a lot of UI work, too.

@SomeTroglodyte
Copy link
Collaborator

Unciv.jar can die

You mean the Unciv_Server_.jar included in the main Project - I concur. And that "beer iron" code looks - from a very superficial look - like a significant amount of investment and expertise.

@touhidurrr
Copy link
Contributor

touhidurrr commented Mar 9, 2023

Unciv Multiplayer v2 Protocol (proposal):

Standards:
Multiplayer v2 will be a WebSocket only protocol. The previous rest api's might still be supported for backward compatibility. However, no further development of any REST API will be considered a good standard.

Message format:
All messages would be valid jsons and have to have a cmd property. all other properties will be camel case. shorter but readable properties are advised to be used.
responses should have the same cmd value.

/isalive

Commands & Responses:
--Ping
ping
> {"cmd":"ping"}
< {"cmd":"ping"}
must ping every 10s or a client would be deemed intactive.

--Popup
servers can send popup commands to display a popup to clientside.
< {"cmd":"popup","text":"text"}

--Errors
same as popup, but client should display this as error
< {"cmd":"error","data":error"}

--Accounts
register
> {"cmd":"register","user":"username","pass":"password","email":"email"}
[ email is optional, some servers can choose to support it]

[--to be continued]

@touhidurrr
Copy link
Contributor

@yairm210 @GGGuenni @myOmikron @CrsiX is something like this good enough? in websocket, everyone seems to make their own protocol. but json seems to be commonly used.

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 9, 2023

Multiplayer v2 will be a WebSocket only protocol. The previous rest api's might still be supported for backward compatibility. However, no further development of any REST API will be considered a good standard.

I oppose this proposal for two reasons.

  • A REST API is simpler for a big number of common tools (e.g. curl or your Browser) and it can easily be used for management tasks (like logging in, registering accounts, managing friends, ...). Additionally, a HTTP API is stateless in the first place, whereas WebSockets are not. It's easier to handle user authentication via HTTP and only then allow to create authenticated WebSockets (i.e., don't handle auth via WebSockets).
  • There's a well defined standard for HTTP APIs - OpenAPI (formerly Swagger). We're using it right now to document the REST API. Anyone can automatically process this specifications to build a client/server that uses the HTTP API (see https://openapi-generator.tech/). AFAIK, there's currently no OpenAPI (or similar) standard for WebSocket connectivity.

--Ping
ping

WebSocket has built-in Frame types. Two of them are Ping and Pong. Therefore, we're not defining our own Ping mechanism, but rather use the one provided by the supporting WS library.

--Popup
servers can send popup commands to display a popup to clientside.

This is too generic in my opinion and it makes internationalization harder. I would therefore prefer common codes for all possible messages, so that a) the implementations can use enums for them instead of strings and b) those enums can be translated to all different languages. It would be better to indicate the type of pop-up (e.g. ClientDisconnected, ServerFailure, ...).


We've also started to work on a WebSocket protocol. It's built on JSON sent via WebSocket Text frames and structured like the following:

{
    "type": "string_indicating_the_message_type",
    "content": {
        // various content based on the message type, which allows for easier parsing by libraries
    }
}

There are already a few defined types: InvalidMessage, FinishedTurn, UpdateGameData, ClientDisconnected, ClientReconnected
The structure of the content field is solely determined by one of the types.

@touhidurrr
Copy link
Contributor

touhidurrr commented Mar 9, 2023

@CrsiX I the main reason for avoiding REST APIs is to avoid polling. Is there any reason of making things complicated by keeping REST API alongside WebSocket? I see no point in that.
OpenAPI is just another standard and a way of documenting REST APIs, the argument here is whether there is any reason to keep REST APIs in the first place.
WebSocket is needed to ditch the current polling mechanism that Unciv uses.
And Since we are trying to redefine the Multiplayer experience in Unciv, most of the people in this chat have the sentiment of ditching v1 and completely rebuilding v2 in this chat. I see no reason of keeping legacy REST APIs when WebSocket is being implemented.

To ensure a seamless Multiplayer Experience, everything is better to be built on WebSocket from scratch.

@touhidurrr
Copy link
Contributor

This is too generic in my opinion and it makes internationalization harder. I would therefore prefer common codes for all possible messages, so that a) the implementations can use enums for them instead of strings and b) those enums can be translated to all different languages. It would be better to indicate the type of pop-up (e.g. ClientDisconnected, ServerFailure, ...).

I agree with that, but there should be ways to send popup messages from the server. Maybe we can implement types for that.

@touhidurrr
Copy link
Contributor

"type": "string_indicating_the_message_type",

Also kindly use camelCase, they are more readable.

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 9, 2023

I agree with that, but there should be ways to send popup messages from the server. Maybe we can implement types for that.

Could you name me a use case for that feature?

@myOmikron
Copy link

myOmikron commented Mar 9, 2023

I see no reason of keeping legacy REST APIs when WebSocket is being implemented.

To ensure a seamless Multiplayer Experience, everything is better to be built on WebSocket from scratch.

I kindly disagree with this statement.

Websockets are great for working with events that don't use the request / response pattern, e.g. pushing your turn results as one event that is sent to the server. Or pushing this updated state to all the other clients.

If you want to force a req/res pattern onto websockets, there are a few downsites doing so:

  • websockets are low-level by default, you are adding more work to design a layer to synchronize events
  • websockets aren't able to multiplex, which means every action should be moved to its own task to do its blocking work, like db lookups, etc. Due to that, you have to fiddle together your whole sender / receiver tasks and keep track of them.

These are concerns that you don't have, when doing HTTP requests, as they are already solved by the nature of HTTP requests themself.

@CrsiX I the main reason for avoiding REST APIs is to avoid polling. Is there any reason of making things complicated by keeping REST API alongside WebSocket? I see no point in that.

So I'm totally onboard with you regarding everything that is related to any kind of polling. But things like a register endpoint should be handled the easiest way - with plain old http requests.

Normally, I don't like the way how microsoft designs its systems, but this article also makes some additional valid points.


Also kindly use camelCase, they are more readable.

I also disagree with this statement, but as I don't have a strong preference here, fine 4 me.

@touhidurrr
Copy link
Contributor

I agree with that, but there should be ways to send popup messages from the server. Maybe we can implement types for that.

Could you name me a use case for that feature?

This would allow a greater server - user relationship. Things like server events would be possible.

@touhidurrr
Copy link
Contributor

Also, did you prefix everything with /api? So, will your server address be https://runciv.hopfenspace.org or https://runciv.hopfenspace.org/api?

Also, where is /isalive?
image

@touhidurrr
Copy link
Contributor

touhidurrr commented Apr 22, 2023

Also this is too confusing... I am not sure how this will work. Currently Unciv assigns a random UUID to the client upon installation. Now it looks like you are preserving both UUID and username. Now the confusing part is what happens when the user signs up, uninstalls the client, and then tries to log in. What will be the UUID in this case? Will it be the old one or the new one? And if the user has to set a username in the first place then why do we need a UUID? Also what happens to the games that are currently being played? They also have the user ids of the players.

I am a bit confused about how this works, can you kindly explain?

image

@CrsiX
Copy link
Contributor Author

CrsiX commented Apr 22, 2023

Also, did you prefix everything with /api? So, will your server address be https://runciv.hopfenspace.org or https://runciv.hopfenspace.org/api?

We prefixed everything with /api. The reason for that prefix is to easily allow the use of / and other non-API endpoints, which allow a web page or something similar to be served there. Of course, that may be changed (e.g. strip the /api from the API definition but set the baseUrl to include /api).

Also, where is /isalive?

At first, we have decided against such an endpoint:

  1. If you want to check if a server is reachable, just call some arbitrary endpoint. If you receive a response (even if it may be 401 or 404), the server is reachable. A dedicated endpoint which just returns true is not helpful.
  2. The /api/version endpoint fits into the rest of our API schema, since its no versioned endpoint, i.e. the purpose is to determine the version of the running backend. In our case, the response is therefore {"version": 2}.

Of course, the server can be changed. So, if /isalive is an important endpoint, we could just integrate it.

Note: in the current client, I'm checking the /isalive endpoint to determine if it's an old APIv1 implementation, because all of them return a 200 response. But since we didn't define that endpoint, it's 400 in the new APIv2. That would need to be changed, too.

@CrsiX
Copy link
Contributor Author

CrsiX commented Apr 22, 2023

I am a bit confused about how this works, can you kindly explain?

Sure. So, why a user UUID in the first place? Well, we want to uniquely identify an account. All data associated with an account may change (username, display name, password, games, whatever ...), so that UUID is the anchor to identify the user across the account's lifetime. (The UUID is also the primary key in the database.)

How do you map from a username to a UUID? Either you use the dedicated endpoint lookup or you login with username and password and use GET /accounts/me to receive your own UUID. Since it won't change, you can safely store it on the client (until logout or uninstall).

Currently Unciv assigns a random UUID to the client upon installation. Now it looks like you are preserving both UUID and username.

We can't let the client decide which UUID it will become on the server, that would just be completely broken. As lined out above, the username (plus password) is used to login. It doesn't matter if it's a new installation, another device, another timeline. The successful authentication provides the UUID. It will then overwrite the UUID of the client. (Yes, this means going back to the old API is currently not possible after first use of the new API. I have a warning popup before the first login which displays the old UUID of the player, so that it's possible to manually reset the UUID.)

Also what happens to the games that are currently being played? They also have the user ids of the players.

There's currently no plan of an "easy" transition from APIv1 to APIv2. You stop/complete all APIv1 games and then start with APIv2. Why that? Because a) we can't let the user decide on any UUIDs and b) it's just a PoC for now. Those transitions can be checked later on.

However, playing with APIv2-players only works of course. So if we have player A and player B both registered to our server, they can play the game happily together, because their UUIDs match what's in the game files. (I have tested up to four concurrent players, so I assume it's working with even more reliably.)

@touhidurrr
Copy link
Contributor

There's currently no plan of an "easy" transition from APIv1 to APIv2. You stop/complete all APIv1 games and then start with APIv2. Why that? Because a) we can't let the user decide on any UUIDs and b) it's just a PoC for now. Those transitions can be checked later on.

So, it boils down to me needing to make a tool for safe transition of UUIDs. Noted.

@CrsiX
Copy link
Contributor Author

CrsiX commented Apr 22, 2023

So, it boils down to me needing to make a tool for safe transition of UUIDs. Noted.

I'm not sure about that yet. It would mean that there's a transition where all "old" user IDs are mapped to "new" user IDs at once. It may be possible, but it's not very easy. Therefore, I suggest to keep all those transitioning stuff on hold for now :)

@touhidurrr
Copy link
Contributor

Also, @CrsiX can you add a flags parameter to users? like { flags: ["admin", "moderator" ] }

@CrsiX
Copy link
Contributor Author

CrsiX commented Apr 22, 2023

Also, @CrsiX can you add a flags parameter to users? like { flags: ["admin", "moderator" ] }

What exactly do you mean? What are those flags possibly used for? I assume you want something like different privilege levels, so which feature would need privileges in the first place? We have no privilege system at the moment (except for lobbies, where the owner of the lobby can do more than the members of the lobby, like kicking users and starting the game).
Could you please give some examples for the usage of such flags?

@touhidurrr
Copy link
Contributor

They would just appear as badges next to user. A cool thing.

@yairm210
Copy link
Owner

Let's get something working end to end for users before we start expanding into "nice to have"s :)

@CrsiX
Copy link
Contributor Author

CrsiX commented Apr 23, 2023

They would just appear as badges next to user. A cool thing.

But what's the purpose of such a badge? And how would you earn it, who decides which user gets such a badge? Things like moderator or admin need the server operator or an entity with comparable "power" to give & take those badges. IMHO, this is much more complex than it could be useful. If the user could change / set his own badge, then it would be rendered useless (or, purely aesthetically, with no real meaning for the game).

@touhidurrr
Copy link
Contributor

touhidurrr commented Apr 23, 2023

But what's the purpose of such a badge? And how would you earn it, who decides which user gets such a badge? Things like moderator or admin need the server operator or an entity with comparable "power" to give & take those badges. IMHO, this is much more complex than it could be useful. If the user could change/set his own badge, then it would be rendered useless (or, purely aesthetically, with no real meaning for the game).

With this things like Server messages and Server bots would be possible. With verified badges. Also, people often asks me to do stuff like fix broken games, delete games, change user ids, etc. So, I want an admon badge. . Maybe the server can even give exp and levels to users. Things like this make the game more engaging.

Anyways, let's launch a working v2 first and then we can maybe add these features.

@CrsiX
Copy link
Contributor Author

CrsiX commented Apr 23, 2023

With this things like Server messages and Server bots would be possible. With verified badges. Also, people often asks me to do stuff like fix broken games, delete games, change user ids, etc. So, I want an admon badge. . Maybe the server can even give exp and levels to users. Things like this make the game more engaging.

Thanks for clarification, I now understand what you meant. Some things are really nice ideas, indeed. :)

@CrsiX
Copy link
Contributor Author

CrsiX commented May 9, 2023

I'm planning on introducing persistence later on. Part of this persistence will be the list of games and their game states, as well as the game chats. Since my data formats need to be different than all currently available data formats in the game, I wanted to introduce a new directory that stores the data specific to those new game mechanics. At the moment, the game saves the following files and directories (afaict):

  • GameSettings.json
  • MultiplayerGames
  • SaveFiles

I want to add a new directory MultiplayerGamesV2 (working name, may get another name?) and some sub-directories that allows me to organize details related to new multiplayer games.
It would then provide the following files/dirs:

  • MultiplayerGamesV2/Games.json for a list of the currently played games as well as some details about them, for example
    • last player
    • last activity
    • data ID
    • game ID
    • game name
    • multiplayer server the game is played on
    • may also include the details currently available in GameInfoPreview
    • file version
  • MultiplayerGamesV2/Games/{some-uuid}.json for the full GameInfo of a save game, just as the old format in SaveFiles -- all extra meta information should be placed in the above Games.json file; the different storage directory is important to prevent issues with APIv1 games
  • MultiplayerGamesV2/Chats.json for a list game chats and its meta information
    • chat rooms
      • multiplayer server the chat room is hosted on
      • members
      • UUID
    • file version
  • MultiplayerGamesV2/Chats/{some-uuid}.json for the full history of an active chat room (lobbies may not be stored there, since they are usually not so important)
    • we have the scenario of a really long-running game with a few thousand chat messages in mind, therefore splitting the single chat rooms into their own files
    • the chat rooms should be cleared when the game has been completed, of course

All of those new persistent data should always be

  • backward-compatible and future-extensible (hence the file version)
  • contain the detail which multiplayer server they were used with, so that moving between them is easy

@SomeTroglodyte
Copy link
Collaborator

That sounds more like a job for sql(ite)

@CrsiX
Copy link
Contributor Author

CrsiX commented May 9, 2023

That sounds more like a job for sql(ite)

Fair. We already discussed it internally. And it is the better alternative, indeed. However, since I didn't dive into Kotlin/SQLite/Android integrations yet, I just came up with the good old JSON. And wouldn't it require yet another dependency? I remember that Android provides some SQLite db for applications, does it? And it would require cross-platform support, of course. Quick searching brings up Exposed as an ORM, for example. I could start by evaluating the support of those/alternatives to integrate them properly into the game, if you don't have something in favor?

@CrsiX
Copy link
Contributor Author

CrsiX commented May 10, 2023

By the way, do you want to check out the current state of our implementation? I've just created an alpha release here. 🎉

You can freely test the new features and user interfaces that I've created there. I'm always open for suggestions and improvements. Just make sure to open any issues related to the new mechanics at our fork. Of course, you can also check out our dev branch and build it for yourself.
Thank you very much :)

@SomeTroglodyte
Copy link
Collaborator

alpha release here.

Uh, I don't do multiplayer. But thanks for the confidence. I can confirm that checking out your branch builds and runs perfectly fine - and I see no difference, that's how good I know the MP side of Unciv. Besides, I redirect server to a not-open port on localhost to silence all that chatter (& less stutter in single-player gaming). 🤷

Copy link

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 15 days.

@CrsiX
Copy link
Contributor Author

CrsiX commented Mar 18, 2024

Dear GitHub Actions bot, even though I was inactive, I currently still plan to bring this feature into existence at some point in the future :)
That said, I don't know when this will be >.<

@CrsiX
Copy link
Contributor Author

CrsiX commented Dec 29, 2024

Hi everyone, (ping @yairm210 @SomeTroglodyte ).

This issue has been open for a long time and nobody else stepped up to continue working on it (somewhat expected). I know that I said I would continue working on it, but due to time constraints I did not.

Is there interest from your side to continue pursuing a nice multiplayer experience?
The related PR is too huge and out-of-date (trying to merge it resulted in a huge number of lines of conflicts, so that's practically not viable). That said, my "current" (>14 months old) state of the game worked well with almost all required features.
If there's still interest to create a multiplayer game out of this, I could continue working on it. I'd need to start over again more or less from the start anyways.

(The server code at https://github.com/hopfenspace/runciv has been updated yesterday and is fully functional again. The server we had hosted a year ago has been shut down, though.)

@touhidurrr
Copy link
Contributor

touhidurrr commented Dec 29, 2024

This issue has been open for a long time and nobody else stepped up to continue working on it (somewhat expected). I know that I said I would continue working on it, but due to time constraints I did not.

Actually I did, but my goals and approach both were totally different. Mostly because of me not wanting to invest a lot of time in learning Kotlin, Java / Kotlin ecosystem, libGDX etc. I guess). My approach is here (funny but also fully functional). I actually had a lot of interest in Multiplayer v2 and I might have been able to contribute more strongly if my skills in this ecosystem was better.

Anyways. although these are different, let me know if you can make these two compatible. That's all.

spoiler
Actually it is not really v2, but somewhat between v1 and v2 I guess? Maybe v1.1? You can consider implementing this in Unciv before moving into v2 also I guess.

@touhidurrr
Copy link
Contributor

touhidurrr commented Dec 29, 2024

If there's still interest to create a multiplayer game out of this, I could continue working on it. I'd need to start over again more or less from the start anyways.

I think you can try standardizing WebSocket on Unciv first then gradually keep adding new features on top of it like suggested before. For example, if just games were passed on top of a WebSocket protocol instead of HTTP, we would have an in-game chatting system already. That is certainly one way to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants