E
E
Evgeny Glebov2017-03-22 18:07:26
Software design
Evgeny Glebov, 2017-03-22 18:07:26

Complex business logic. How to take everything into account?

Hello. The situation is this. There is a game server
(2 parts of the server: processing user requests and realtime handlers (flights, battles, etc.))
At the moment:
- there are about 20 entities (ship, fleet, user ...)
- 50 types of requests from users (upgrade ship, create a fleet...)
- 5 realtime processors (flights, battles, mining...).
If I want to add a new type of request from the user (for example, delete a spaceship), I have to take this into account in all places (in combat and in other requests). If I forget it somewhere, then a bug appears. What will happen in a year? When there will be 100 entities...
How to deal with such complex business logic with a large set of rules? Maybe there are some tools or approaches?
CM. comment
response: #comment_433231

Answer the question

In order to leave comments, you need to log in

3 answer(s)
N
nirvimel, 2017-03-22
@GLeBaTi

A few banal OOP principles (applied to your project):
Entities that are affected by a particular request must either inherit from the same class or implement one interface (in addition to other interfaces) that has methods for managing these entities that are necessary to implement this request .
Requests must also be grouped into a class tree or inherit a set of interfaces. Entities may interact not with specific request classes, but with common interfaces, which are not as numerous as there are different requests.
The same with realtime handlers and, in general, with any elements of logic.

X
xmoonlight, 2017-03-22
@xmoonlight

- there are about 20 entities (ship, fleet, user...)
- 50 types of requests from users (upgrade a ship, create a fleet...)
- 5 realtime handlers (flights, battles, mining...).
Point by point:
1. entity = noun
2. object properties = adjective
3. object action request type = action/verb
4. real-time handler = trigger/heart-beat/time-tracker
Now to add something new , just use the object inheritance of the desired architectural design pattern of the links created in advance.

V
Vladislav Kilin, 2017-03-22
@Quilin

In very tightly coupled systems like this one, the ActorModel pattern works well. The idea is that your code is divided into a huge bunch of tiny subroutines, each of which can -
perform atomic actions
- send messages to other actors
- create new actors
the queue will send new messages, creating an action graph. Any process can be visualized in the form of such a graph.
As for your specific case, I got the impression that you are more interested in working with a single store of game object data. There are also a lot of interesting solutions for this, for example, Unidirectional Data Flow.
Storing the state of the game in one single place, accessing it through layers-mappers. There are several options for implementing change interception - it can be an immutable state, for which it will be enough to calculate the delta between the old and new, publishing changes globally, so that program sections that are interested in these changes pick them up themselves, or a reactive state that remembers who it was contacted for what data and notifies them of specific changes directly at the time of their application.
Of course, for complex game mechanics, it is absolutely necessary to write and maintain unit and integration tests. With testing, you will avoid a huge pile of bugs, such as the notorious "if I forget it somewhere."
But in any of these cases, as one programmer wisely said: "Architecture is easy to come up with complex", meaning that one should strive to simplify it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question