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

Cafu News Cafu News

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.

entity-hierarchy.png

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.


License

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.


Website

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. ;-)


Summary

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.

mapeditor_groups_contextmenu.png
Image Detail Image Download

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.

Progress on the Entity Component System

by Carsten Fuchs | Thursday, 2014-05-22
In my previous news post "More about Component Systems" I presented the central ideas and concepts about the two component systems that we are about to introduce to the Cafu Engine. Since then, a lot of work has been achieved, and it is time for an update:

The biggest challenge and the focus of my efforts has been the porting of the old DeathMatch game code to the new component system. This was very successful, and in fact the old DeathMatch game code could be entirely removed and be replaced with newly-written components that have just the right mix of C++ and Lua script code.

In fact, the successful removal of the old, intertwined and tricky DeathMatch C++ code was the key step that motivated me to write this news update. However, that doesn't mean that we're done yet. Some things had consciously (and temporarily) to be broken and must now be fixed again, and other things are not yet as they should be. Here is a summary of the technical aspects:


Updates to the repository

If you're following the Cafu source code repository, especially on branch master-vc2012 or entity-component-system, the following recent changes are important:

  • I just tagged revision 1debdc3 (of 2013-05-25, almost exactly one year old!) with name pre-entity-component-system. This is the revision where our master branch was at the time when the development of the entity component system was begun. The annotated tag message is this:
    Code:
    This is the last revision before the extensive work was begun to introduce a
    component system for game entities to Cafu.

    It is expected that the development will take a long time. Although it is
    intended to keep backwards-compatibility wherever possible, it is expected
    that compatibility to now existing binary files (especially `cw` world files)
    and to custom Lua map scripts (e.g. `TechDemo.lua`) must and will be given up
    in the process.

    Contrary to the already completed introduction of a component system for GUI
    windows, it is expected that the upcoming work is of a long-running nature,
    comes with extensive changes to almost all parts of the Cafu Engine, and is
    possibly "open-ended". It is therefore developed in the `master` branch rather
    than a feature branch that would run for months and years, and in the meantime
    only leave `master` back at this commit, which will sooner rather than later
    become old and unsupported.

    Also see http://www.cafu.de/forum/viewtopic.php?p=6212#p6212 for additional
    information.

  • Next, I fast-forwarded branch master to entity-component-system (integrating entity-component-system into master), in which until now the entity component system was developed, then deleted the now no longer needed branch entity-component-system (and master-vc2012 as well).

  • If you are among those who, like me, had checked out branch entity-component-system, and possibly based work on it, you can use these steps to update your working copy (the steps are shown for Windows, but are very similar under Linux):
    Code:
    # Fetch all the new branches, commits and tags:
    > git fetch --all --prune
    > git fetch --tags

    # Clean up the working copy, i.e. stash or commit local uncommitted changes
    # as necessary, and (on latest entity-component-system), delete possible
    # leftovers from previous revisions:
    > rd /s Games\DeathMatch\Code
    > rd /s Games\VSWM

    # Checkout the "old" master branch, and fast-forward to origin/master:
    > git checkout master       # old master
    > git merge origin/master --ff-only

    # In my case, it was sufficient to delete the now obsolete local branch,
    # however if you have based own work on it, you'll rather want to rebase it
    # onto or merge into master first.
    > git branch -d entity-component-system

Please note that although I felt that this is the right time to continue the development of the entity component system in the master branch rather than keeping it further artificially separated in the now gone entity-component-system, at this time master is not in a state where a release could be made from it: In fact, if you compile and run it, you will quickly find a lot of problems.

These problems are well known to me (but any feedback is welcome, don't fear duplicate reports), and the rest of this news post summarizes the problems and the plans to resolve them.


Plans regarding "Player Prototype" entities

Implementing the "carried weapons" of a human player is, in all its details, surprisingly difficult. A lot more difficult than the code for monsters and other non-player entities. In fact I managed to move its previous, old implementation into the component system -- but there it is still old and inflexible code, and not in the useful and helpful spirit of the component system as everything else.

Also, moving the code necessitated some compromises, and these compromises, while they made it possible to integrate entity-component-system into master, are also responsible for the "broken" look and feel of today's (May 2014's) master.

Pondering this gave raise to another insight: So far, we have no concept for human player entities in the component system at all! That is, giving the map designer a chance to make any settings or script code adjustments for the human player entities that are supposed to spawn in the map was just not possible.

To fix all this, the idea is to introduce a new special entity that acts as a "Player Prototype". Of this new entity, exactly one instance exists in each map that the map designer can use to customize all details to his heart's contents, including that of possibly carried weapons. The Cafu Engine then spawns an entity for each human player that joins the map by cloning the "Player Prototype".

Among others, the player prototype entity has a list of components of type "CarriedWeapon", whose properties and script callbacks define one weapon each, and each such weapon would be completely self-contained, keeping information about e.g. its availability to the player ("has it been picked up earlier?"), whether it is active or holstered (more than one weapon can be active at a time, e.g left and right hands), the current, minimum and maximum ammo, and so on.

Developing this "Player Prototype", the carried weapons, and all related functionality will amount to a total rewrite of the old code, and be the immediate goal of my next steps -- this is exactly what we have introduced the component system for, after all! Even if it is not obvious from this text alone, when done you will see that the result is very very worthwhile! :wohow:


More work to be done

The above is crucial, but there is still a lot more important work to be done, and branch master, despite my promoting it as described above, currently has known bugs and generally not the quality that we normally strive to achieve and are used to.

Most importantly, the carried weapons must be fixed as described above. However, also the particle engine needs a thorough overhaul, and we really have to re-implement the precaching feature also for our component system, whose current lack causes noticeable lag.

Finally, the Map Editor is the only part left that is not yet adapted to the entity component system. This is very important, as the Map Editor is often the program that new users look at first.

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

Server state and client effects in online games

by Carsten Fuchs | Sunday, 2014-01-19
As explained in my previous news post, I am currently migrating the old DeathMatch game code to the new Component System architecture. Just this afternoon I finished dealing with the "hand grenade" entities in the new system, and I found that they're noteworthy in many regards:

  • Hand grenades are both dynamically created during the course of a game (when the player throws them) and dynamically removed again (after they have exploded and their traces have gone). This makes them different from many other entities that are defined in map files and often exist from the beginning to the end of the map.
  • Hand grenades employ more components than other entities in order to implement their functionality:
    • Model (the hand grenade model as thrown through the map),
    • Physics (for computing the flight path and dealing with collisions, e.g. with walls and the floor),
    • Script (for controlling the details, e.g. letting the detonation timer tick and implementing the explosion effects),
    • Light (for the flare when the hand grenade explodes),
    • Sound (for the sound at the time of the explosion),
    • ParticleSystem (for the smoke and spark particles at the explosion).
  • They very well demonstrate the distinction between Server State and Client Effects.

It is the last point that I would like to highlight in this post, because a good understanding of it is crucial for game development with Cafu:


Server State

The server state is characterized by the following properties:

  • It is synchronized via the game server to all clients,
  • every player (client) sees the same results and consequences,
  • server state is relevant for gameplay.

Typical examples are drawbridges, the position and state of elevators and doors, details about opponents, etc.
As a side note, events are often a result of a change in the server state, and transferred to the clients as such.


Client Effects

Client effects can be triggered by some event in the server state, but besides that, they:

  • run independently of each other on the clients only,
  • are often used for eye-candy,
  • it's ok if not everyone sees exactly the same (not relevant for gameplay).

Examples include particle effects such as smoke, sparks and small pieces of debris, many fade or transition effects, model animation frames, etc.


Having both

An important insight is that we sometimes need both server state and client effects combined.

For example, consider a light source that illuminates an otherwise pitch black part of a labyrinth. Whether the light source is on or off clearly makes an important difference for players who try to navigate the labyrinth, and so the state of the light source is managed as a part of the server state.

However, there are also other kinds of light sources, e.g. those that are on, but steadily flicker or pulse. This is often a means to create a specific atmosphere to a map, but the exact amplitude of the flicker or pulse is really not something that needs synchronization over the network.

In fact, as a combination we may wish that the light source's on or off state is synchronized to everyone, and if it is on, have it have a client-side flicker effect for eye-candy.

This is exactly what we can (starting with commit d11c6a9) achieve with the light source components, and what I now employ with the hand grenades: When a hand grenade explodes, the related light source is turned on in order to mimic the bright flare of the explosion. However, the exact details of how the bright light fades, changes its color from white over yellow to red, shrinks and eventually disappears (all in about half a second), needs not be synchronized over the network.

Instead, a very simple script method is used to implement this. Here is its entire code:

Code:
local clTime = 0.0
local Duration = 0.5

function Light:ClientEffect(t)
    if not self:get("On") then
        clTime = 0.0
        return false
    end

    clTime = clTime + t

    if clTime >= Duration then
        return true, 0, 0, 0, 0
    end

    local Amount = 1.0 - clTime/Duration

    return true, Amount, Amount*Amount, Amount*Amount*Amount, 400.0
end

Well, this is one of the reasons why I love the new component system! :loveit:

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