Multi-agent systems in the construction of virtual spaces

    One of the critical problems that arise when building multi-user systems is scaling. There are various solutions to this problem: sharding, service model, Entity-Component System. Today we will consider all the options and also discuss a practical case for solving the issue. Join now!

    Part 1.
    Part 2.

    I hand over the word to the authors.

    Traditional approaches to building multi-user systems. Service Architecture

    Historically, the first method of solving the problem of scaling was sharding - the division of the entire system into a number of servers on any basis without a common state of the world. That is, up to a certain number of users they could be on the same server, see each other and interact with each other; but when adding new ones, they turned out to be in a copy of the virtual space running on another server, and, accordingly, could not interact with others. It is clear that this is not a solution, it is a workaround. And although sharding quite makes sense now, in many cases, approaches are required that allow you to actually increase the possible load on the server.

    The second common technique is the service model. The server has a number of components that can be duplicated fairly easily. For example, this is a database and work with it, or an asset server, which forwards them to a client, or an authorization server. All these services are distinguished by the fact that you can have them in several instances and parallelize requests for them.

    The main problem is a shared state.

    But the main problem lies elsewhere. What to do with a specific state of the world, the state of the virtual space? Suppose our “world” consists of one 3D - scene, a set of objects on it and several connected users. Theoretically, we can duplicate some software components that are responsible for working with the scene on the server side. But the problem is that the state of the scene is one thing that is common to all these components. Accordingly, when parallelizing handlers, we need to somehow solve the problem of synchronization of working with data, and at the same time we can lose more in performance than we can win on parallelism.

    Solution: Entity-Component System. Problems in the DVO case

    One of the relatively recent approaches to such problems is ECS (Entity - Component System). In this embodiment, we represent the object of the system as an entity with some properties. For example, it may be the position of an object in space and its speed. In this case, all that we store on the object itself is only some data, but not the logic of working with them. That is, in our case, six numbers will simply be assigned to the object — the coordinate vector and the velocity vector.

    The second part of ECS is a worker, a system that works with a specific type of component. For example, in our case it could be a system that changes the coordinates of an object every second, adding speed to them. The basic idea is that the worker does not know anything about the object as such - it simply has a queue, a pipeline of components, which it must process according to certain rules. Accordingly, we can parallelize workers, just as services are parallelized.

    Agent systems as a method of writing parallel code

    The multi-agent approach is also not a special novelty, but recently the interest in agent systems has been growing. There are a number of fairly good articles telling about it in detail, so here we briefly list only the most general principles of such systems:

    1. The main component of the system is a component called an agent or actor. It is somewhat similar to the object familiar to everyone, but the actor has no public methods, the only way to communicate with him is to send him a message;
    2. To send a message to the agent there is the concept of “links”. A link provides an interface (in different implementations, it can look very different), which allows you to send messages. One of the important properties here is location transparency (location transparency), and the presence of each agent’s address — a string that allows you to get a link to the agent regardless of its physical position, i.e. the agent can be located and work in the agent system on the same computer, and maybe on another - in this case, the link is obtained at a certain network address;
    3. The agent has a message queue, and they are processed sequentially. An agent can be a state machine that changes states and message handlers in order to react to them;
    4. As a rule, multi-agent systems are hierarchical, that is, agents form a kind of tree. At the same time, an error in one of the agents does not stop the entire system; only a specific agent is disabled, sending an error message to its ancestor. One of the popular approaches to handling such errors is let it crash - if an agent drops, we simply create a new copy of it;
    5. Creating a new agent is not a resource-intensive operation, while creating the system itself is very costly.

    Quite often, agent systems are used just in the approach using ECS. Since the agent system makes it very easy to create the required number of workers and parallelize their work, simply distributing the message flow between them, this looks like a very promising approach. For example, this is how SpatialOS from Improbable works.

    The problems here arise in a slightly different plane. The ECS approach is quite simple, but in principle it cannot be called intuitive, especially for inexperienced programmers. Therefore, the creation of custom code in such a system is a fairly non-trivial task. There are also issues with the portability of different objects between instances of virtual space servers, because along with the object we have to transfer all workers, if they (for this type of component) are not present on another server. In principle, some implementations of agent systems allow us to solve some of these problems, but we chose a different approach.

    Our case - the essence of DVO as an agent

    In our case, each virtual space object is an agent, or rather, a system of agents. Comparing with the classic ECS, we can say that each entity has a system of “micro-workers”, tied to the object itself. At the same time, all the advantages of the agent system are saved (that is, we can run such an object in a separate thread, on a separate machine, etc., simply by changing the server settings), but the object remains portable, and writing scripts for it does not require ECS division .

    In this case, the state of the world is divided into the state of individual objects, and each of them can be processed separately. On the client, we also build an agent system, which is a kind of reflection of the state of the server, and we associate each client agent with a server agent. Among other things, it also increases the reliability of the system, since if an individual object fails, only this object is turned off, and not the entire virtual space.
    A bit more in detail, it looks like this:

    Any space object is a small agent system consisting of the main agent of the entity, which is created when the server starts, which is not the component container agent and the set of message processing components. To connect the client, the network transparency property is used, that is, each specific object on the client has a link to the server agent object. At the same time, when connecting, a new agent is dynamically created, which is a descendant of the main agent.

    The client system also creates an agent system, but the entity agents in it are formed by a message from the server. Once created, the agent receives a link to the server agent and creates a message processing component that includes queues to receive and send messages from the server. A Unity object is also created, and the client parts of the object components inherited from MonoBehaviour. In this case, the Unity part and the agent part work in different threads, the message handler is responsible for synchronization (if possible, it is minimized).

    Something like this (without any particular details) looks like the implementation of dynamic virtual space in the JIF variant. In the next article we will tell you about personal big data and work with statistics, as well as about the blockchain.

    The authors

    Company Jedium - Microsoft Partner company working in the field of virtual, augmented reality and artificial intelligence. Jedium has developed a framework to simplify the development of complex projects on Unity, part of which is publicly available on GitHub . Jedium plans to replenish the repository with new modules of the framework, as well as integration solutions with Microsoft Azure.

    Vitaly Chaschin - Software developer with more than 10 years of experience in the design and implementation of three-dimensional client-server applications - from concept to full implementation and integration of applications and virtual reality solutions. Systems Architect Jedium LLC, MSc in IT.

    Alexey Sarafanov

    marketing manager at Jedium LLC.

    Sergey Kudryavtsev

    CEO and founder of Jedium LLC.

    Also popular now: