Progress on the Entity Component System

News about the Cafu Engine. Subscribe to the related ImageCafu News feed to stay informed.
Locked
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:
Progress on the Entity Component System

Post by Carsten » 2014-05-22, 16:38

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: Select all

    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: Select all

    # 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.
Best regards,
Carsten
SoulRider
Posts:95
Joined:2014-04-06, 00:16

Re: Progress on the Entity Component System

Post by SoulRider » 2014-05-25, 20:52

Great news. I haven't been doing any work on this, as I have been working on a new NS2 mod project, and I've been waiting for the component system to get into a more finished state.

I have been keeping my build up to date with your changes, and it's good to see the progress being made.

As regards the carried weapon component system. It seems like a good idea would be to implement 2 different components, a weapon component, and a WeaponOwner component. The weapon deals with the weapons themselves, and the WeaponOwner deals with holstering, and managing the relationship of the weapons. a simple network flag can be added - isHolstered = true for example, to then handle the appropriate weapon.

It's just a suggestion, it's how I was planning to do it, as I felt the current code was way too complex for dealing with the weapons. Keep up the good work, and I will be getting more into the engine when the component systems are finished, and my current project is a bit further along..
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Progress on the Entity Component System

Post by Carsten » 2014-05-27, 21:02

Hi SoulRider,

many thanks for your feed-back! :-)
SoulRider wrote:I haven't been doing any work on this, as I have been working on a new NS2 mod project, and I've been waiting for the component system to get into a more finished state.
Yes, at this point the situation is unfortunately a bit awkward, as I need a bit more time to bring things into the shape they should be in. But progress looks good (more below), and it's good to hear that you seem to have found a good alternative for the meantime. ;-)

As regards the carried weapon component system. It seems like a good idea would be to implement 2 different components, a weapon component, and a WeaponOwner component. [...]
Thanks, this is very much appreciated. In fact I was already working along these lines, except that my WeaponOwner is currently integrated with the common HumanPlayer component. But splitting this into two can easily and naturally be done at any time, whenever it feels necessary or right.

In fact my only real problem is that I would like to base some of the weapon state on the progress of the animation sequences, and would like to be efficient about it regarding network updates (there is no point in wasting bandwidth by synchronizing each animation frame over the network), and would like to get this right with regards to the client "prediction" feature, which is very important for smooth first-person movement, first-person events, etc.

For example, reaching the end of a "reloading" animation sequence should be the event that is responsible for whatever happens next, e.g. switching to idle state, firing the next shot, holstering, etc., so that the transition to the related new animation sequence is seamless. But not wastefully sync'ing animation frames and at the same time making sure that things are always fine between client, server, and the client's prediction requires some additional thought. The old code had a solution for this, but I'm not quite happy with it and would like to review it carefully.

Everything else should be a piece of cake, :cheesy: and the upcoming series of commits that I'm currently preparing locally already implements quite a lot of the weapon's logic in Lua.

Keep up the good work, and I will be getting more into the engine when the component systems are finished, and my current project is a bit further along..
It is at this time hard to provide a deadline, but I will definitively keep you and everyone informed on the progress, especially as soon as I feel that the (entity) component system is ready for productive work. :up:
Best regards,
Carsten
SoulRider
Posts:95
Joined:2014-04-06, 00:16

Re: Progress on the Entity Component System

Post by SoulRider » 2014-05-28, 01:02

Carsten wrote: In fact my only real problem is that I would like to base some of the weapon state on the progress of the animation sequences, and would like to be efficient about it regarding network updates (there is no point in wasting bandwidth by synchronizing each animation frame over the network), and would like to get this right with regards to the client "prediction" feature, which is very important for smooth first-person movement, first-person events, etc.

For example, reaching the end of a "reloading" animation sequence should be the event that is responsible for whatever happens next, e.g. switching to idle state, firing the next shot, holstering, etc., so that the transition to the related new animation sequence is seamless. But not wastefully sync'ing animation frames and at the same time making sure that things are always fine between client, server, and the client's prediction requires some additional thought. The old code had a solution for this, but I'm not quite happy with it and would like to review it carefully.
NS2 uses animations to control things like reloading speed etc, they have animation graphs and blends etc. A reload animation will be set to 4 secs for example, and this can be changed by setting a model animation state to reload, and even pass an overidden variable to change the speed if you wish. The animations have 'Tags' which are called from the code to initiate them. In code you can disallow firing while reloading for example. I have personally found the implementation to be very server heavy, although not overly network heavy. I believe this is because the client always knows it's animation state, and only needs a server message about the time the animation started for other players, so it can run the animation correctly for the client. Here is setting the animation code from NS2 for the ARC.lua file-

Code: Select all

function ARC:OnUpdateAnimationInput(modelMixin)

    PROFILE("ARC:OnUpdateAnimationInput")
    
    local activity = "none"
    if self.mode == ARC.kMode.Targeting and self.deployMode == ARC.kDeployMode.Deployed then
        activity = "primary"
    end
    modelMixin:SetAnimationInput("activity", activity)
    
    local deployed = self.deployMode == ARC.kDeployMode.Deploying or self.deployMode == ARC.kDeployMode.Deployed
    modelMixin:SetAnimationInput("deployed", deployed)
    
    local move = "idle"
    if self.mode == ARC.kMode.Moving and self.deployMode == ARC.kDeployMode.Undeployed then
        move = "run"
    end
    modelMixin:SetAnimationInput("move", move)
    
end
There are other modes set elsewhere. The construct mixin will add parameters like Built, the live mixin using paramters like Alive. These all add together and are used in combination to make sure the right animations are running, but often means you need 4 or 5 states active at once. When you have every model processing multiple animation states every cycle, the server gets hit very hard.
Carsten wrote: It is at this time hard to provide a deadline, but I will definitively keep you and everyone informed on the progress, especially as soon as I feel that the (entity) component system is ready for productive work. :up:
I will be keeping an eye open, I still download and compile your updates everytime, so I see your changes and the progress being made. I really look forward to getting my teeth into it in more depth in a few months.
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: Progress on the Entity Component System

Post by Carsten » 2014-06-01, 09:51

Thanks for the additional details!

We too have support for blending (also among unrelated) animation sequences, so that smooth transitions are possible, and for channels, so that the animation for the legs can be set independently from the animation for the torso, etc. The current code employs the blending feature whenever appropriate, whereas the channels feature, although readily available, is not yet used.

Overall, progress is very good. My recent series of commits culminated in a4f6aec, and I'm working on more. :up:
Best regards,
Carsten
Locked

Who is online

Users browsing this forum: No registered users and 6 guests