The open-source game engine and graphics engine for multiplayer, cross-platform, real-time 3D action

Cafu News Cafu News

Client features – a technical overview

by Carsten Fuchs | Thursday, 2015-07-16
In my previous news post "Client features revisited", I talked about several important client features and how they have recently been improved.

As promised there, although this is rather a technical documentation than suitable prose for a news post, I would still like to provide a brief overview on how the previously covered features work and how they interact with each other.

The Basics

As implemented in class ClientStateInGameT, a client that has joined a game world has these crucial tasks to complete in each video frame:


        // Draw the current state of the game world on screen.

        // Everything else that is important in each game loop:
        //   - process any network packets that might have arrived from the server
        //     (apply server updates and run reprediction as described below),
        //   - collect and process player input.

For a start, we can assume that the Render() method (and any nested Draw() methods) that are responsible for rendering the client world are "constant". As explained later, this is not exactly true in the strict sense of the C++ const keyword, but it is true in the sense that when the drawing is done and the CaClientWorldT::Draw() method returns, the client's world state is exactly the same as it was when the drawing began.

That leaves the client's main loop (ClientStateInGameT::MainLoop()) to be considered.

If an SC1_FrameInfo message arrived from the server, all game entities (that are relevant for the client) are updated to the state of server frame "X". As the server also indicates the growing ID of our client's player command that it has accounted for up to server frame "X", the locally available player commands that have not yet been accounted for since frame "X" are re-applied ("reprediction").

Player input from mouse and keyboard is collected in each video frame and stored in a PlayerCommandT struct. It then is:
  • sent to the server (for the server's authoritative processing),
  • "predicted": applied locally and stored for future reprediction,
  • cleared (for the next loop iteration).

Interim Result

At this point, it is important to note that the above described client implements full networking support with prediction and reprediction, but not yet with any of the extra features mentioned in my previous post.

Especially note that the client's game world is always in state "X" as last received from the server, where additionally the local player input is applied to the client's player entity.

Adding Interpolation, Reconciliation and Client Effects

The crucial idea is that our client world is generally always kept in the above described state: latest server state "X" + prediction.

This is a very important invariant of the prediction feature, because otherwise, if interpolation or other effects modified the world state, the prediction would find a different state when locally applying player input than the server would, which in turn introduces stuttering as it breaks the prediction feature.

Therefore, in ClientStateInGameT::MainLoop() we make sure to (only) take note of anything that might affect the effects. Most prominently, if a new SC1_FrameInfo server update arrives, new target values for the interpolations are recorded – but the values themselves are updated as if interpolation didn't exist.

The last piece of the puzzle is in CaClientWorldT::Draw(), which is actually responsible for rendering the world:
  • it activates the interpolation, reconciliation and client effects, updating all variables to their proper values,
  • renders the world in the prepared state,
  • restores the previous values back to "latest server state X + prediction".


Besides the processing of incoming server updates and outgoing player input, the client has a lot more to accomplish before a good game experience can be rendered. The key idea is to keep the client's world state always at the latest received server state "X", with local prediction applied.

Interpolation, reconciliation and client effects are kept and maintained independently. Although the code for these features affects several source files, this encapsulation helps with readability and correctness.

In this regard, we now have a very good and powerful framework. It is used to implement several important examples already, and I hope to utilize these facilities more often and more extensively in the future – I can still think of a lot of effects that I would like to see but that aren't there yet, e.g. head bopping when the player is walking or running, rotating items, swinging and flickering light source, and so on.

As always, your comments, feed-back or help are very much appreciated!

Post and read comments about this news item at the related forum topic.

Client features revisited

by Carsten Fuchs | Wednesday, 2015-07-01
Among Cafu's most prominent and important features are the networking code and, closely related to that, the client prediction feature. These two together implement a client-server network model that allows fast multi-player games over the internet, where the prediction makes sure that network lag is compensated for so that the game feels fast and responsive for all participating players.

Building on this basis, Cafu also implements some complementing features that further improve the client experience: Automatic interpolation is available so that also the movement, colors and other attributes of "non-player" entities get smoothly updated with the client framerate, even if they actually receive updates over the network with the much lower server framerate. And there is a broad spectrum of client effects that create a great visual experience that is entirely independent from the server: model animations are played, particles effects rendered, and so on. I've written more about client effects in my news post Server state and client effects in online games.

However, recently it was time for a revision: When the player was riding a lift as implemented in our new Mover component, the movement of the lift and/or the (relative) movement of player itself (being pushed by the lift) was not yet ideal. Lifts are run and operated on the server, which makes them difficult to integrate with the client prediction of a riding player.
It quickly turned out that reconciliation, a sub-feature of client prediction that "smoothly" fixes mismatches of the prediction results against the server, was still missing and that riding lifts would become a perfect experience as a side effect of adding the more general reconciliation (sub-)feature.

Other minor issues with the old code included that our interpolation feature (and the temporary world state related to it) must not accidentally interfere with the client prediction, and that while our own local human player is fully covered by prediction, other (3rd person) human player entities should be covered by interpolation instead.

At that opportunity, but independent from the above, I wanted to achieve a better (generic, powerful and simple) means for implementing "pure" client effects, so that game and map designers could easily add features like these (some long existing, some still missing):

  • 1st person (the local human player):
    • head swaying (in state FrozenSpectator, currently still implemented in ComponentHumanPlayerT via sync'ed m_HeadSway member),
    • head bopping when walking / running,
    • smooth stepping on staircases.
  • 3rd person (monsters, other human players, game objects, etc.):
    • properly advanced model animations,
    • light sources that pulsate, swing, move, ...
    • items that rotate, bop, circle, ...
Last but not least, also largely independent from the above, I wanted to clean up the client's source code. These client feature are complex, and I wanted to have them as clearly and comprehensibly implemented as possible, providing a good code design for C++ developers.

In summary, these are the existing and new features that I wanted to cover:

  • server updates (authoritative frame updates as received over the network from the server),
  • prediction (handles the instant processing of input for the local human player), with sub-features:
    • reprediction,
    • reconciliation;
  • interpolation (updates monsters, 3rd person players and other game objects smoothly with the client's framerate),
  • client effects (generic server-independent effects as outlined above).
It had taken me a while to implement all this, but the work has turned out to be very worthwhile and successful, and has been committed already (merge commit is eea2f04 of 2015-06-18).

I would also like to summarize the main technical ideas behind the new client's code structure, but considering the length of this post, I'll rather postpone them to a future news post, coming soon.

Post and read comments about this news item at the related forum topic.

Progress and plans for 2015

by Carsten Fuchs | Friday, 2015-01-02
Dear friends,

as every time around the New Year, I would like to briefly summarize the current developments and plans regarding the Cafu Engine.

Entity Component System

Generally, the development of the Cafu Engine progresses steadily and continuously, and the Entity Component System is still at the center of the attention.

In 2014, we have been able to complete the transition of the DeathMatch example game from the old, class-hierarchy based implementation to the new Entity Component System.
This also involved many changes to the Cafu Engine core. In its entirety, this was a complicated task, because many "specialties" that were "somehow" hacked into the code before had to be implemented in a much different (and cleaner) manner in the new code. Another large part of the changes involved the Map Editor, which has undergone a large number of high-quality improvements in order to reflect the new features brought by the Entity Component System.

In 2015, with the bulk of the efforts already achieved, our focus will be on the finishing and polishing of the related details. For example, practical work with the Map Editor will expose areas where the new functionality is not yet properly accessible, some of the above mentioned specialties are in fact still undone or need another revision, and most importantly, the new features of the Component System must not only be implemented, but also be employed and presented. Specifically, one of my very next tasks will be to revise and fix the "moving entities" code, so that the player can actually ride on moving platforms, in lifts, etc.

In short, there is still quite some work to accomplish, but all details are looking very very well, and I'm very much looking forward to it. :up:

You can see additional high-level considerations about previous related work in our News. If you would like to follow the Cafu development progress more closely, you can also register yourself to watch the Cafu Git Repository at Bitbucket, or subscribe to the related Image activity feed.


In the course of the last year, we have been asked several times about the Cafu Engine licensing model. Currently, Cafu is dually licensed: both as free software under the GNU General Public License (GPLv3) and optionally under a custom, commercial license.

At this time, we're considering to release future versions of the Cafu Engine under an even more liberal license, e.g. under the MIT or BSD license. However, no decision has been made yet and will only be done in the course of 2015.

We will also take the opportunity to clarify and simplify the process of contributing to the Cafu Engine, which should be as easy and straightforward as possible, in the hope to attract more developers.


Also planned is a redesign of the primary website. The current website has served us well for many years, but as new design aesthetics and web technologies have changed the way how websites are built, I have been planning to modernize it for a long time, e.g. to make it "responsive" so that it works well on mobile devices, and to update and clean-up its contents.

This endeavor is complicated by the fact that we use several sub-systems that are actually independent of each other (main www website, support forums, documentation wiki, issue tracker, reference documentation), but should still present themselves in a common, consistent theme as much as possible. However, as always the Cafu Engine programming has higher priority than updates to the website, so please don't expect results anytime soon! ;-)

Game Assets

Finally, another change that I would like to see happen is a modernization of our DeathMatch example game assets, especially more recent and more detailed game maps, models, textures, etc. I already have quite concrete ideas and plans for how this can be achieved, but it is really still to early to say more about it at this time. ;-)


I wish you all a lot of fun with the Cafu Engine, and above all that 2015 may be a happy and peaceful year for everyone!

Post and read comments about this news item at the related forum topic.

Reintroducing “layers” (aka “groups”) to the Map Editor

by Carsten Fuchs | Monday, 2014-11-17
A while ago, in September, I considered it a good idea to remove the "groups" feature from the Map Editor. This was fueled by the observation that entities too can naturally and inherently serve for grouping the individual elements in a map. Keeping a second, explicit mechanism for the same purpose (the "groups" feature) only seemed to be a redundant burden. Therefore, the intention was to turn the existing two methods for grouping into a single method, to be implemented by having entities subsume the functionality of the former groups, thus making groups fully redundant so that they could be removed without loss.

Alas, after the change was complete and a considerable effort had been spent to make entities and entity hierarchies work as well as groups did, the first tests and feedback quickly showed that it didn't work out, and that my assessment of the situation (and my enthusiasm for entities, or in fact, the entity component system) did this time not lead to the desired solution. Practically speaking, we found that the "groups", as they were implemented before, were just too good and too convenient to be removed: my attempt to achieve the same with entities was just not on par (think e.g. of the "Hide Other" button). Considering this more closely, it turned out that this was not a problem of the implementation, but of a more principal nature:

Entities and their hierarchies are an excellent way to organize (group) map elements in terms of the game or the virtual world that is being developed: You use entities to model game objects like players, opponents, cars, lifts, or anything else that is relevant for the game.

Groups, however, serve a quite different organizational purpose that, in hindsight, is orthogonal to that of entities: With groups, you express features that are important to the map designer's workflow or are of technical relevance – but not to the logical modeling of a virtual game world.

Therefore, I'm currently working on undoing the commits that removed "groups" from the Map Editor, and on reintroducing them soon. At the same time, I will take the opportunity to rename the former "groups" to "layers", because "groups" is a too general word (entities group map elements, too!), whereas "layers", with their analogy to 2D drawing programs, seem to describe the purpose of the feature in a more precise and more intuitive manner.

In summary:

  • Entities group map elements by their logical meaning in the virtual game world, as observed by players, as needed by script authors, as seen by the core engine, etc.
  • Layers group map elements to facilitate technical details for the map designer, e.g. to temporarily hide objects, to lock them from being accidentally modified, etc.

Note that this is currently still a work in progress: I'll post here again as soon as the reintroduce-groups branch is completely implemented and committed. :up:

Post and read comments about this news item at the related forum topic.

Article about client prediction at Heise Developer

by Carsten Fuchs | Monday, 2014-09-01
Today there was another very nice article at the renowned German publisher Heise about compensating the lag in online games by means of the "client prediction" technique:

Verzögerungen in Online-Spielen durch Client-Side Prediction kompensieren (text is in German)

The author Christian Oeing explains the basics of online games whose simulated world is managed by a central, authoritative game server that clients can connect to. It is very well described how network latency affects basic implementations of such client-server setups, and how this causes the player to perceive the game as sluggish or lagged. As the key matter of the article, Christian explains how the "client prediction" can be used to compensate for the network lag. As "client prediction" can, quasi as a side effect, cause the client's idea of the world state and that of the server to disagree, the author also describes the techniques that can be use to overcome such divergencies: "reconciliation" (or "reprediction", in Cafu lingo) and interpolation.

What makes the article special and my definitive recommendation (for those among you who speak German), is that all this is written in a very readable manner that is easy to follow and understand – and the huge coincidence that everything that he describes is also implemented in the Cafu Engine since several years. (To be precise, Cafu implements the "client prediction" and the very important "reprediction" features, but deals with interpolation only in a slightly different manner than described in the article.) Thus, especially for those who want to familiarize themselves with the Cafu networking code but find the comments and internal documentation too terse, the article is a must read.

If you don't speak German, the article also provides links to English texts:

In the meanwhile, we're still very busy with finishing the details of our newly introduced Component Systems.
The basic work is all long done, but I would still like to fix a few more loose ties in the Map Editor before this very fundamental project can be declared done and ready for public consumption. :cheesy: :up:

Post and read comments about this news item at the related forum topic.

Article about entity component systems at Heise Developer

by Carsten Fuchs | Friday, 2014-07-18
As an interesting coincidence, the renowned German publisher Heise today published an article in their online Developers section about entity component systems:

Component-Based Entity Systems in Spielen (text is in German)

The text is a very nice description of entity component systems, and quite similar to my recent news post More about Component Systems of January 2014 (see our News and Announcements for related posts and follow-ups).

The authors present some additional details that are slightly different from ours, but the crucial elements, namely using aggregation rather than class hierarchies for feature "management", and using flexible means for managing each component's data (variables), exactly match ours.

In summary, the text is a great additional view on component systems. Comparing its details to ours is interesting and provides additional perspective and insights. :up:

Post and read comments about this news item at the related forum topic.