In game design and development, especially in engine development, logical loops are an important part. loops determine the basic logic and running mode of the game, in different development environments and languages, the definition of the loop is even quite different. What I want to share with you is the way and practice of Loop Design in Silverlight game development.
The following content comes from previous game development experience and may be more detailed in related articles in other languages. I would like to discuss the application in Silverlight game development here.
NOTE: If your data structure study is poor, don't read it. You may vomit. If your data structure study is great, don't read it. You may vomit blood.
In the traditional development concept, No matter any development environment, it cannot escape While. The code is generally like this:
While (true)
{
If (GameExit () = true)
Break;
Else
GameLoop ();
}
This code method is just a model that can be understood as a state machine that constantly checks the status.
In Silverlight game development, can we also use this application? Basically, most of the current practice is to implement a Root department. In this regard, dark blue's right hand and many other friends have various solutions, if you are interested, you can find their articles. Thread, Storyboard, Rendering, and DispatcherTimer are the beginning of a good loop.
For games, especially online games, we will face a large amount of interaction, which may come from users or their own game logic, just as the most realistic problem is, when a game shows more than 100 roles on the same screen, is the game stuck? In the early days, I got into a misunderstanding, presenting a sufficient number of roles is the maximum performance (3.0 shows that 600 roles are not card-free), but it seems that this is not the case now, because simply presenting roles involves hundreds of roles, it is most important to ensure that a game is still smooth during execution, because the combat logic, interface logic, and scenario manager occupy system resources when there is no time, at this time, the role is not as simple as a few pictures, and their equipment, components, and special effects will become a burden for game developers.
In this case, the optimization cycle process is very important. As a team experience, this time we will discuss it together, if you have any good ideas or suggestions, please share them with us: The names of the five cycle design patterns below are messy. Please forgive me.
For a game as a whole, the loop is used most often as an animation. In this research, I have summarized the five loop modes that can be applied in the Silverlight game design, these methods are very common in traditional game development, but no one is willing to share them for two reasons: first, they are too simple to tell jokes, and second, they are too mysterious, we need to encapsulate it so that we can fool people,
Well, let's design a scenario: There is a LogicLoop method in OBJ, which implements the simplest method internally, switches the animation frame and goes in one direction, it will continue from the beginning. There are a lot of OBJ in the scenario.
1. Self-circulation
Self-built loops are easy to understand. For example, if an elf control implements a loop internally to continuously detect and execute logic, developers do not need to do anything separately, new users only need to execute the logic themselves. This method is very convenient and easy to develop, and there is no relationship between them, in this case, we need to use the design mode such as Singleton to solve the problem of mutual integration. The figure is as follows:
Obviously, one of the biggest problems with our own logic is our independent performance occupation. If a scenario (not the same screen) has hundreds of such loops, then the various threads of the game will eat a lot of CPU, especially when using Thread, Storyboard, DispatcherTimer.
2. Chain Loop
Our own logic has their own cycle consumption problems. Is there a way to unify their cycle logic into a loop? If we have learned the data structure, we can do it through a linked list, the basic principle is to put each loop body into a large loop, then execute the loop logic from the first one, only once, and then the next one, and then come back to continue the execution. The model is as follows:
This is a common processing method that can greatly reduce system consumption, and C # provides good iterators and other traversal functions, making it easier to combine the object-oriented approach. The sample code is as follows:
Public class obj
{
Public virtual void OnLogic ();
}
List <obj> ObjList = new List <obj> ();
Public void OnLoop ()
{
Foreach (var item in ObjList)
{
Item. OnLogic ();
}
}
The biggest advantage of a chain loop is to centralize all the independent loops into a large loop logic. One problem that needs attention is dynamic processing, because the generation and destruction of objects in the game are very frequent, and a set change occurs during the loop, it is dangerous. There are two ways to do this, array conversion and collection judgment are respectively. array conversion is very easy. The collection is copied to an array, and each element of the array is recycled. The collection judgment is to mark the object, pick a recycle list at the right time and clear it at the right time.
The advantages of a chain loop can create a game's RootHead, add all the elements to this RootHead, create a main loop, and traverse it. Of course, you need to use the base class to achieve the goal.
Is this a good way? In some cases, yes, it can solve the performance loss. Of course, if the internal implementation logic is too complicated, sometimes another thread may have to be used. In gaming products, there is a more direct requirement, that is, the level problem. That is to say, some loop bodies are system-level, while some may be just a picture, how big is the game loop to accommodate everything? For example, if there is a logical loop in Scenario Management, will it be directly added to this large loop? When a game is running, some loops are not required at specific times, or they do not need to be executed, which also causes obstacles for subsequent development, in our MMOROG engine, the maximum number of applications is the following cycle pattern.
Iii. subtree Loop
As the name suggests, a subtree loop uses a tree structure to process the cyclic logic. In our actual application, it can be divided into two types: an active subtree loop and a fixed stator tree loop, this article mainly describes the fixed subtree loop mode.
We know that there are many systems in a game, such as the scenario system, combat system, team system, guild system, chat system ...... N systems, do they have a loop inside themselves? From an intuitive perspective, the above system may not require loops, but the fact is not the case. For example, the team system may have a loop to process the judgment logic to complete the activities such as teaming and moving, although this logic is simple, for example, whether the guild system needs to refresh the guild list every 10 seconds ......
As shown in, we use sub-objects to create a tree and traverse them one by one. During the execution process, we can use iterations or recursion, there is no big difference between Subtrees, but for performance, we can make some interesting optimizations. When a system is shut down, it is not executed in the tree-the specific method depends on the situation, whether it is split or logical decision. The effect we get is that the elements under the closed sub-tree won't execute a loop. It's much simpler and easier than a chain, and all the elements are broken.
Subtree loops are very commonly used at the system level. They are more useful for logic with frequent replacements, such as special effects animation and map systems, specific algorithms and operations have clear answers in data structure, where you can find what you want :).
Iv. interval Loop
In a strict sense, the interval loop is a judgment method in the loop, rather than an implementation mode. The principle is to split all parts of the game system and mount them into different loop structures, if the chain type and subtree type are an Object set, the interval type can be said to be a type of Objects collection, as shown in the following illustration:
At the large system level, the interval type can split the most performance-consuming part and complete the loop in another thread (or loop structure), such as the combat system, Map Processing, and scenario manager, in the scenario manager, you can also bring an interval loop to split the scenario, then process the objects in a region range (if you think about whether the above image can be made into a two-dimensional array ?), You just need to turn a blind eye to the loop logic beyond the region range. Otherwise, you need to deal with N roles in a large scenario, whether in itself, chain, or subtree, there will be a large amount of overhead.
The biggest advantage of the Interval Type is that it enhances the range determination. If it is well written, it can be combined with multiple values to use a two-dimensional (three-dimensional) array to complete the distribution of each loop logic, the algorithm here may be a little interesting, similar to the combination of hash and List. Note that when an object (OBJ) what will happen from range 1 to range 2 :)
V. Combined Cycle
In fact, a combined cycle is a very lazy part, because it combines the first four types. In game development, it is not the best method of the above, but adapted to local conditions, what kind of model can meet what kind of needs, not just to achieve efficiency and efficiency, but also pay more attention to the degree of smoothness of future development and avoid rework.
As shown in, we can clearly analyze the applications of different cyclic methods in different environments:
Self-loop is more suitable for the interface, because it is relatively fixed, and there are not many complex logic, of course, this is only applicable in the Silverlight UI, in fact, the main logic is a large self-loop, the Root Loop Method is an internal loop.
Compared to the second-level game system, the chain loop concatenates all the systems to achieve fast traversal. However, the next level of the system is a sub-tree loop, the system elements are all in one system, and the following sub-tree may also have a chain style, which is obviously the most frequent combination method.
Interval loops are mainly used in scenario systems. A chain loop or sub-tree loop may be required. The specific situation depends on the design mode of the game. If a single scenario (such as a map) it is a singleton method, so it is more appropriate to use a chain loop to drive the loop logic. If a single scenario is new, it is easier to use a subtree to switch the connection.
The above is a small summary of our experience in MMORPG. In the above example, we use a combined loop (nonsense, all-inclusive), but for some small games, it is recommended that you do not design this complex part. For large online games, the importance of program design is extraordinary. Finally, I have read many saying that web games cannot provide performance, I think most of the performance problems are not the technology itself, but developers are not clear about the nature of a game, and when and how we can achieve what purpose, I can find some inspiration for developers, and I have an explanation for my own ideas :).