G
G
Georgy Pelageykin2017-10-14 13:54:46
.NET
Georgy Pelageykin, 2017-10-14 13:54:46

What architectural approaches to choose for developing a client-server game?

Good day. I'm trying to understand a little about the implementation of the client-server architecture and there was a misunderstanding of some basic things, I would like to ask the opinion of more experienced developers. It is difficult for me to get out of at least some familiar rut, I have no idea where to start.
Game model
Close to games like Elite/Space Rangers/X. There is a conditional two-dimensional space, in which objects (stars, planets, ships, etc.) exist and interact. Realtime, but "slow", like strategies from Paradox.
The general structure of the world is quite simple, there is no division into zones, i.e. for the most part, the world is the totality of all objects and the relationships between them.
What am I trying to get

  1. The server is running on the host, probably a regular self-written C# application. The server is authoritarian, the entire game state is located and simulated on it.
  2. Connected Unity clients receive from the server only available to them (visible by the sensors of the player's ships, for example) information about the game world and draw it.

To begin with, I want to make a simple receipt from the server of the simplest game world (stars / planets) and their rendering by the client.
Basically the questions are:

  1. I experimented with the implementation of similar mechanics in the single-player version, everything was quite simple there:
    • Any persistent entity has a JSON serializable DTO (simple data store) associated with it, including the game world root.
    • These entities can create their own DTO from their data (and from the entities nested in them), or recover from it. Those. DTO is a generic way to create something or save/restore it.
    • Saving/loading the world is just creating/restoring some WorldContext.

    This works well, the world is relatively easy to save/restore, but only in one piece.
    If I understand correctly, this method is not used for server applications, because. data can be easily lost in a crash, and periodically saving the world in one piece can cause freezes. Those. keeping the whole world in RAM and periodically dumping it into json would be a bad decision.
    After reading articlesfrom mail.ru on this topic, and did not realize what is stored in the database and what is in RAM, and how to apply it to my case, how the state of the game is "smeared" between the state in memory and the database. For example, if the state of a ship's structure is stored in the database, should it exist as an object in memory, or is it read from the database when it needs to be accessed? Or do they usually write some kind of automatic caching / flushing systems in the database?
    Most of this, of course, is irrelevant to me, but would it be a justified decision to initially do all the simulation entirely in RAM and keep the database up to date as the game progresses (i.e. constantly write changes, but not read), and if necessary later to organize the unloading from the memory of certain large collections of objects? Or am I thinking in the wrong direction at all?

  2. How, in fact, to synchronize the client and server? Even a simple world at the initial stages of development quickly becomes voluminous in terms of the number of heterogeneous entities / data in them, especially with the advent of complex objects like ships, while in tutorials for some UNet, they usually synchronize the player’s position and a couple of parameters by hand and on this stop. I got something like this save.json .
    I'm thinking about the option to create an instance of the same world simulation on the client as on the server. Load data arriving from the server into it, creating your own local "partial simulation", thus reusing the code from the server (it remains only to create its graphical representation). But the data may come incomplete (say, instead of the detailed structure of the enemy ship, some conditional NoAccess< ShipStructure >), which will have to be processed and, accordingly, litter the server code.
    In any case, it is not very clear how to carry out synchronization directly. As I understand it, when the state of the object changes (say, the ship changed the thrust vector), you need to send the updated serialized ship to the client, where he will reload it into his simulation (I plan to use a component approach, so only the responsible component will need to be updated).
    How bad is this idea? After all, in some EVE Online it is hardly possible to run a simulation on the client, what in this case can come to the client there?

  3. At the moment I don't want to use photon/analogues and plan to limit myself to some open source libraries. How much do I lose from this approach and what network libraries can be useful? Read about things like SignalR for example. And can using ASP.NET (possibly core) as a basis give anything, or is its use meaningless for such purposes?

I understand that there is not and cannot be an unambiguous answer to such questions, but I would be glad to know at least the degree of stupidity of the decisions I have described. I looked for information in the same EVE dev blogs, but they mostly write about more "adult" things. In what direction would you begin to implement the described game model? It would be interesting to hear.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Alexandrov, 2017-10-14
@ArXen42

1) Divide the world into "chunks", i.e. just squares of a certain size. In the case of 2d, this will be very convenient.
2) The server processes only those chunks in which the players are located, in the absence of a player in it, then it is saved to the screw\bd. On the client, chunks are also unloaded from memory if they go into a new chunk.
3) You will need a system to predict which chunk should be loaded. Let's say knowing the direction of the player, we assume that he will fall into such and such a chunk, which means we load it in advance.
4) When approaching a chunk, send the player its full state, and after that only what changes in it.
5) Part of the calculations for linear (predictable) objects can only be synchronized periodically. For example, a flying asteroid is logically calculated both on the client and on the server, but only in the event of events (collision, for example) there is synchronization between the client-server.
On a note, the more linear (i.e. predictable) objects, the less you can synchronize them. In addition, this will immediately give a bonus in the form of a fairly simple implementation of interpolation and extrapolation.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question