Quantcast
Viewing all articles
Browse latest Browse all 17825

Spring RTS Engineering Internals

Spring is a free open source RTS game engine originally created by Stefan Johansson and Robin Westberg, members of the Swedish Yankspankers game clan. Originally intended to bring the gameplay experience of Total Annihilation into three dimensions, the engine has since evolved to support a plethora of more modern and more flexible features, including built-in high-level extensibility through a Lua scripting interface.

Any developer who wants to contribute to Spring RTS or any other open source project needs to understand the existing code, and for that he can read the documentation, explore forums, read comments from code or read the code itself.

Another way is to use tools and query the code base. Like SQL for a relational database, CppDepend provides the CQLinq language to request the code and help to understand C/C++ within. It’s also free for open source projects.

In this article we will analyze Spring RTS with CppDepend to discover some internal design choices.

Paradigm used


C++ is not just an object-oriented language. As Bjarne Stroustrup points out, “C++ is a multi-paradigmed language.” It supports many different styles of programs, or paradigms, and object-oriented programming is only one of these. Some of the others are procedural programming and generic programming.

Procedural Paradigm


Global functions

Let’s search for all global functions inside the Spring engine:

from m in Methods where m.IsGlobal && !m.IsThirdParty select m

Image may be NSFW.
Clik here to view.
Attached Image: spring22.png


5092 functions are global, which represents around 20% of all the Spring methods. But what’s interesting is that these functions are grouped by namespaces which makes the code modular and easy to understand.

Structures

In a procedural program, modules interact by reading and writing a state that is stored in shared data structures. Let’s search for all data structures defined by Spring:

from t in Types where t.IsStructure && t.Methods.Count()==0
select t

Image may be NSFW.
Clik here to view.
Attached Image: spring27.png


Static functions

In general, it’s better to declare a function as static unless you have a specific need to call it from another source file.

from m in Methods where m.IsGlobal && m.IsStatic

Image may be NSFW.
Clik here to view.
Attached Image: spring26.png


Functions candidate to be static

from m in Methods where m.IsGlobal && !m.IsStatic && !m.IsThirdParty
&& m.MethodsCallingMe.Where(a=>a.SourceDecls.FirstOrDefault()!=null && a.SourceDecls.FirstOrDefault().SourceFile.FilePathString!=m.SourceDecls.FirstOrDefault().SourceFile.FilePathString).Count()==0
select m

Image may be NSFW.
Clik here to view.
Attached Image: spring29.png


Object Oriented paradigm


The object-oriented paradigm makes extensive use of virtual functions and polymorphism, let’s search for virtual methods.

from m in Methods where m.IsVirtual select m

Image may be NSFW.
Clik here to view.
Attached Image: spring2.png


And to have a better idea of existing virtual methods, we can use the Metric View.

In the Metric View, the code base is represented through a Treemap. Treemapping is a method for displaying tree-structured data by using nested rectangles. The tree structure used in a CppDepend treemap is the usual code hierarchy:
  • Projects contains namespaces.
  • Namespaces contains types.
  • Types contain methods and fields.
The treemap view provides a useful way to represent the result of a CQLinq request, so we can visually see the types concerned by the request.

Image may be NSFW.
Clik here to view.
Attached Image: spring3.png


As we can observe, virtual methods are not widely used.

Abstract classes

Low coupling is desirable because a change in one area of an application will require less changes throughout the entire application. In the long run, this could alleviate a lot of time, effort, and cost associated with modifying and adding new features to an application. Using abstract classes can improve the low coupling; let’s search for all abstract classes:

from t in Types where t.IsAbstract select t

Image may be NSFW.
Clik here to view.
Attached Image: spring4.png


Inheritence

In object-oriented programming (OOP), inheritance is a way to establish Is-a relationship between objects. It is often confused as a way to reuse the existing code which is not a good practice because inheritance for implementation reuse leads to Tight Coupling. Re-usability of code is achieved through composition (Composition over inheritance). Let’s search for all classes having at least one base class:

from t in Types where t.BaseClasses.Count()>0 select t

The Metric view shows us that many classes are concerned, and inheritance is mainly used.

Image may be NSFW.
Clik here to view.
Attached Image: spring16.png


Generic Programming

C++ provides unique abilities to express the ideas of Generic Programming through templates. Templates provide a form of parametric polymorphism that allows the expression of generic algorithms and data structures. The instantiation mechanism of C++ templates insures that when a generic algorithm or data structure is used, a fully-optimized and specialized version will be created and tailored for that particular use, allowing generic algorithms to be as efficient as their non-generic counterparts.

In the C++ world two schools are very popular: Object Oriented Programming and Generic Programming, each approach has their advocates, this article explains the tension between them. Let’s search if Spring uses templates:

from t in Types where t.IsGeneric && !t.IsThirdParty select t

Image may be NSFW.
Clik here to view.
Attached Image: spring6.png


Spring RTS uses template classes, especially for containers and utility classes. We can also search for generic methods:

from m in Methods where m.IsGeneric && !m.IsThirdParty select m

Image may be NSFW.
Clik here to view.
Attached Image: spring7.png


Only some methods are templated.

Spring RTS startup


To understand what happens when the RTS engine starts, let’s begin with the dependency graph concerning some methods invoked by the entry point WinMain.

Image may be NSFW.
Clik here to view.
Attached Image: spring9.png


When the engine starts it searches for the existing cores to exploit all the processing machine power, and after that delegates the initialization to the SpringApp class. Let’s search what happens when the Initialize method is invoked.

from m in Methods where m.IsUsedBy ("SpringApp.Initialize()") && !m.IsThirdParty
select new { m }

Image may be NSFW.
Clik here to view.
Attached Image: spring10.png


This method initializes all the other classes with which it collaborates like LuaOpenGL, CMyMath and CGlobalRendering, and after it invokes the startup method. And here’s the dependency graph of the startup method.

Image may be NSFW.
Clik here to view.
Attached Image: spring11.png


External frameworks used


When developing a product, it’s preferable to not reinvent the wheel and reuse proven and mature frameworks. Let’s search for external types used by Spring.

from t in Types where t.IsUsedBy ("rts")
select new { t }

Image may be NSFW.
Clik here to view.
Attached Image: spring25.png


Spring RTS uses mainly boost, this library is aimed at a wide range of C++ users and application domains. They range from general-purpose libraries like the smart pointer library, to operating system abstractions like Boost FileSystem, to libraries primarily aimed at other library developers and advanced C++ users, like the template metaprogramming (MPL) and domain-specific language (DSL) creation (Proto).

For example concerning network communication Spring uses the boost.asio library, which provides developers with a consistent asynchronous model using a modern C++ approach.

Conclusion


For any developer using the Spring RTS, or any new code base, it’s better to know sometimes how it works internally, for which the better approach is to go inside the code source. In this case we have found that the Spring RTS code is very simple to understand and evolve.

Viewing all articles
Browse latest Browse all 17825

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>