Entity Component Systems Shootout: EntityX, Anax, Artemis (C++)

I tried out the three most popular Entity Component Systems (EntityX, Anax, Artemis-Cpp) and am now ready to report how they compare to each other. I will also share some benchmark results obtained simply by using Xcode unit tests and its measureBlock: method.

You’ll find the Entity Component Systems test project on github with EntityX, Anax and Artemis already integrated and working. If you need help installing these ECS libraries to your own project you’ll find my previous ECS article about installing ECS libraries helpful.

Let’s start comparing the APIs, then we’ll look at benchmark results.

Creating the World

The “world” object is the container for all entities. Note that I decided to create these objects with new solely because of compile errors. You can of course create the worlds on the stack as well and use dot notation instead.

Artemis already provides a glimpse at its more verbose nature.

Creating Entities with Components

At the core of an ECS you’ll work with entities and their components. This code will create an entity, add components to it, register it with the world and finally delete it.

EntityX is clearly the easiest and least error-prone to work with. It does not require “activating” or “refreshing” the entity in order to register it with the world and to register its components with the component systems.

Anax requires you to activate the entity after creating it. Don’t forget to do so or the entity’s components will not be processed by the component systems. Furthermore you also have to refresh the world whenever the active status of an entity has changed, although you can bulk the creation of multiple entities and then only refresh the world once per frame.

It sure would have been nice if Anax would just do that automatically. Because there’s one big problem with that: if you refresh the world without any entity changing its active state, Anax effectively stops processing all entities!

Artemis requires you to refresh the entity after creating it, but it also has you create instances of the component classes on the heap with the new keyword.

Interestingly, EntityX prefers to destroy entities, Anax likes to “kill” them (even though they aren’t necessarily “living” things) and Artemis is quite technically correct and just removes entities from the world.

Creating Components

Let’s take a closer look at the components and how they are designed.

Again, EntityX shows off its simplicity. Components merely need to be structs – that’s all! Though Anax merely wants you to subclass the struct from anax::Component so there’s not much give or take here.

Artemis requires you to use subclasses of artemis::Component for its components. Constructor and members ought to be public hence the public: specifier must be added.

Overall in all three ECS the creation of components is simplistic. After all, they merely represent chunks of data with EntityX taking that point to the absolute minimum.

Creating Component Systems

Component systems implement game logic by using the entities components. Such systems need to require a specific set of components to work with (dependencies), they need to obtain a list of (active) entities with such components, and they need to call a processing function that typically runs every frame.

Again you can see the verbosity increasing from EntityX over Anax to Artemis. Both EntityX and Anax continue to prefer structs.

EntityX uses an update method with three parameters where entityx::EntityManager is identical to the world->entities member. The event manager is exclusive to EntityX as it’s the only ECS with a built-in event system that allows events to be passed on to registered receivers – a way to allow components to communicate with other, unrelated components.

EntityX then uses

to specify the dependent components. This means the provided lambda function runs for every active entity that has both Position_EntityX and Direction_EntityX components. The lambda takes an entity as parameter plus one parameter for each dependent component.

Anax in contrast requires you to specify dependencies at the top of the system:

It then simply calls the system’s update method that just takes a delta time parameter.

Meaning you have to get the list of entities and enumerate over it yourself, plus getting each entity’s components during enumeration. Anax is more verbose but also more flexible, and that flexibility might allow for multithreading component system updates. Neither EntityX nor Artemis can offer that, as they already pass in a reference to an entity in the system’s update method.

Artemis’ component systems feel bloated in comparison, yet they’re still reasonably short for a class. You have to register the system’s dependencies in the constructor:

You will also need instances of artemis::ComponentMapper for each component, I presume this is Artemis’ way of filtering entities based on their components. The processEntity method is called for each entity and the mappers provide the entity’s components. Also the delta time – if you need it – needs to be obtained from the world.

Overall you won’t have that many systems in a project so the verbosity should not really be an issues, with most of the code going into the processing (update) functions anyway.

Registering Component Systems

Let’s compare how the component systems are registered with the world object.

Here each ECS has its own style. EntityX wants you to add the type and then configure the systems which calls the system’s function of the same name. This allows each system to perform post-init tasks such as registering itself as an event listener.

Anax merely wants you to pass in a reference to a system. This will automatically call the system’s initialize function.

Artemis is slightly different as it has a dedicated SystemManager to which you “set” new instances of the system classes. The initializeAll method will then call each system’s initialize function.

Overall EntityX has a slight advantage when it comes to simplicity of the API with Artemis taking the back row as it feels more like “classic” C++.

Updating Component Systems

Typically every frame you’ll want to update the systems, which then runs their processing (update) function.

In EntityX you simply call update_all and done. However this means the order of component system updates depends on the order they were added to the world, and it makes it more difficult to temporarily disable systems.

Anax allows you to manually change the execution order of systems by manually calling them. This allows you to easily skip certain systems based on game state (ie game paused, player died).

Artemis once again has you jump through more hoops than needed, though overall the lack of brevity is still negligible.

Benchmark Results

Curious to see how these ECS compare against each other in terms of performance? I know I was. And I was somewhat surprised by the results.

All Equal: Creating & Removing Entities

One thing ahead of time: creating and removing entities as well as assigning components to them takes almost the same time for each ECS. Artemis takes marginally more time for this, but it almost seems like this is a tradeoff for its fast component system update performance.

In any case, creating and destroying entities isn’t a performance critical aspect, as you’ll be doing that relatively rarely at runtime, while updating the component systems is a task performed for most entities every frame. So I decided to focus on that aspect.

In any case, if you do need to create and throw away a lot of entities per frame, you should consider simply deactivating and pooling deactivated entities to minimize the create/destroy overhead. It seems Anax with its builtin entity activation system and entity caches may perform rather well in that area.

Test Setup

For each number of entities I ran the measuring unit test target several times. I stopped running the tests when subsequent runs stopped producing faster results. The results below are the fastest ones I could get, to rule out any OS interference as much as possible.

Of course I used the release configuration with default compiler optimizations but with GCC_FAST_MATH (Relax IEEE Compliance build setting) enabled. Tests were run on OS X 10.11. The time scale (Y) is in thousands of milliseconds (18 = 18,000 milliseconds).

Each test simulates a loop of 1,000 component system updates (aka 1,000 frame updates). If you want the milliseconds for a single frame, divide the results by 1,000. For instance if processing 400 entities takes 2,000 milliseconds then that’s about 2 milliseconds per frame and would account for 1/8th of the 16.666 milliseconds you have per frame for a 60 fps game.

Test Code

This is the code that was profiled for each entity system. Only the code in the MEASURE macro is profiled, the rest is just setup code. Basically all entities contain 2-3 components and there are two systems, all performing the exact same task. The systems don’t do much other than adding/multiplying numbers and assigning them.

Results

I started with 25 entities and kept doubling that number until 3200 entities, to get a feel for how well the systems scale respectively what their overhead in “sparsely populated worlds” might be.

Entity Component System Benchmark Results

Entity Component System Benchmark Results: EntityX doesn’t scale well

One thing becomes apparent: EntityX doesn’t scale well. Its sweet spot is just about 100 entities, from then on it keeps taking ever longer compared to the others.

You can see by the trendlines that both Anax and Artemis scale almost identically, with Artemis maintaining a small but almost constant lead.

Recommendations

EntityX (459 Stars, 85 Watches, 85 Forks) provides the least verbose API and the most functionality. It’s relatively easy to use, it’s built-in event system is a welcome solution to a common component-system problem. I would definitely recommend it to beginners.

However, if you plan on having significantly more than 200-400 entities in the same world you may be better off looking into the other ECS libraries as the performance penalty may become a limiting factor.


Anax (172 Stars, 23 Watches, 16 Forks) is still comparatively easy to use and it’s only marginally more verbose than EntityX. Personally I consider it’s component system API to be the best of them all. If you want the most flexibility and don’t want to compromise on speed (much), Anax will be your best choice.

The downside is that Anax requires you to properly activate new entities and then refresh the world. This extra housekeeping work can be tedious and result in annoying bugs if not done with discipline or some wrapper functions.


Artemis-Cpp (143 Stars, 40 Watches, 59 Forks) is the best choice if utmost performance is of utmost priority, especially if you expect to have several hundreds if not thousands of entities. Artemis is also the only library not using C++11 so it’ll work fine with older compilers and is more likely to be compatible with fringe platforms and their compilers.

I still wouldn’t recommend Artemis though, mainly because there seems to be no project ownership and no updates nor support. Artemis code will also be far more verbose than that of EntityX and Anax. And Anax is still really fast – whether 3,000 entities take 5 or 6 milliseconds to process per frame is almost negligible.

More Things to Consider

  • EntityX has a built-in event system for infrequent exchange of data between component systems. For instance this can be used to decouple audio playback from the systems into its own audio system, or to pass on collision information from the collision system to, for instance, the “projectile” and “entity health” systems. Again: beginner-friendly and simply convenient. However using the event system will take an additional toll on performance.
  • EntityX and Anax support and use C++11. Artemis does not use C++11 features but (of course) compiles fine as C++11 code.
  • EntityX and Anax github repositories are fairly active (commit-wise), with both authors being fairly responsive too. Though for Anax there are curiously few community contributions (just 3 contributors) while EntityX has integrated pull requests from over a dozen contributors. This may be a result of EntityX popularity and being the older project (about 6 months).
  • Artemis’ github repository hasn’t been updated in 2 years, with last responses from library contributors dating back 1.5 years. This makes the project unmaintained and any issues arising from it are likely your own to solve.
  • Multi-threading is certainly not supported out of the box by any ECS. You can’t implement multithreaded component system updates in EntityX and Artemis without heavily modifying the project, as their systems pass a single entity to the system’s update method. The jury is still out there regarding anax, but given that its component system’s update method requires you to iterate over the entities yourself, it seems reasonable to assume that a system could update its entities concurrently. At least as long as you only modify component members.

How to install Entity Component Systems: Anax, EntityX, Artemis (C++)

I’m currently testing three Entity Component System (ECS) libraries for inclusion in TilemapKit: Anax, EntityX, Artemis (C++).

I thought I’ll write down the installation steps for you. Since two of them rely on CMAKE for building they won’t work out of the box when dropped into an Xcode project.

The steps outlined here are tested with a new SpriteKit project created with Xcode 7.1 and compile for OS X. I assume iOS will be the same.

Working knowledge of Xcode and github is assumed. Also remember: if you use Objective-C and C++ together in the same project you’ll have to rename the .m files to .mm to compile the code as Objective-C++.

Adding Anax to an Xcode project

Anax uses CMAKE as build system. Therefore if you want to use it in a “regular” project that doesn’t use CMAKE the library requires a couple code changes, mainly replacing the CMAKE variables with actual values and fixing a compiler warning. It is still fairly easy to set up, should take less than 15 minutes.

  • Clone the repository
  • Rename include/anax/Config.hpp.inl to Config.hpp
  • Add all files in folders include and src to the desired target
  • Edit Config.hpp:
    • Replace all occurances of #cmakedefine with #define
    • Replace all CMAKE @identifier@ variables with actual values (see CMakeLists.txt for current values).
    • The affected lines and their values are:
  • Optional: edit EntityIdPool.cpp (line ~74). In function ::get change the return line to this one (cast added to suppress compiler warning):
  • Edit target’s Build Settings:
    • Locate the Header Search Paths setting
    • Add an entry pointing to anax’ include folder, for instance: $(SRCROOT)/anax/include
  • Import the main header in a source file:
    • #import "anax.hpp"
  • Done! Anax should compile without warnings using Xcode’s default build settings.

Adding EntityX to an Xcode project

EntityX also uses CMAKE and requires a few minor code changes as well. You should also ensure to not add or to remove all files with the _test suffix – unfortunately these unit tests are in the same folders as the rest of the source files. Nevertheless EntityX is easy to set up in less than 15 minutes.

  • Clone the repository
  • Rename entity/config.h.in to config.h
  • Add the folder entityx/entityx to the desired target
    • Note: that’s the folder containing config.h
    • Caution: do not add or subsequently remove all files with _test.cc suffix. You do not need to include the unit tests. Including them will cause linker errors (duplicate symbols).
      • It’s these files you should remove/avoid: Benchmarks_test.cc, Dependencies_test.cc, Entity_test.cc, Event_test.cc, Pool_test.cc, System_test.cc, TagsComponent_test.cc
  • Edit Config.h:
    • Replace all CMAKE @identifier@ variables with actual values (see CMakeLists.txt for current values).
    • The affected lines and their values are:
  • Edit target’s Build Settings:
    • Locate the Header Search Paths setting
    • Add an entry pointing to EntityX’ root folder (where README.md is), for instance: $(SRCROOT)/entityx
      • Caution: do not point the header search path to the entityx/entityx folder but the folder above that!
  • Import the main header in a source file:
    • #import "entityx.hpp"
  • Done! EntityX should compile without warnings using Xcode’s default build settings.

Adding Artemis-Cpp to an Xcode project

Artemis-Cpp is the easiest ECS to install as it does not rely on CMAKE. It only requires an (optional) code fix to avoid an ominous warning that occurs only in Xcode 7. Artemis should be ready to work with in under 10 minutes.

  • Clone the repository
  • Add all files in folders include and src to the desired target
    • Optional: you may want to remove the file Entity (no extension), it’s empty and doesn’t seem to serve any purpose.
  • Optional: edit SystemManager.cpp (line ~30):
    • Adding a cast to (void) fixes the warning: Expression with side effects will be evaluated despite being used as an operand to ‘typeid’
  • Edit target’s Build Settings:
    • Locate the Header Search Paths setting
    • Add an entry pointing to Artemis’ include folder, for instance: $(SRCROOT)/Artemis-Cpp/include
  • Import the main header in a source file:
    • #import "Artemis.h"
  • Done! Artemis-Cpp should compile without warnings using Xcode’s default build settings.

Which one should I go with?

I can’t say that yet – I’m still evaluating and benchmarking. I’ll post a summary of what I like/dislike about each ECS and which one I’ll be going with for TilemapKit by tomorrow. Stay tuned!

TilemapKit++ (Cocos2d-x) now runs on Windows

Not that bad for a day of work. :)

Screen Shot 2015-10-09 at 22.08.33

So this is TilemapKit++ running on Windows 7 with Visual Studio 2015 (Community) and Cocos2d-x v3.8. The semi-transparancy is intentional (and correct).

An update for the current TilemapKit++ early access build is now imminent. Probably tomorrow if everything goes according to plan, otherwise tuesday. I’ll push an update for the ObjC version as well which will include a couple minor fixes.

PS: Here’s how to get this working with the (v0.75 or newer) early access version:

  • Add all source files located in the TilemapKit Framework folders: ModelCpp, NodesCocos2dx, pugixml and – unlike for other platforms – also add the zlib files.
  • Edit “Include Directories” to include the above folders.
  • #include "TKMapNode.hpp"

Lessons learned porting legacy code to C++

This article is for programmers who are in the process of porting their code to C++. Primarily if the original source code is ObjC but most of these tips can be applied in general when porting to C++ from other languages.

This is my experience and processes adapted while porting TilemapKit from Objective-C to C++ (check current status).

The Recommended C++ Porting Process

Assuming that the port isn’t (supposed to be) a complete rewrite but rather a (more or less) 1:1 copy of the original code over to another language, I found that the following process works wonders:

  • Create the to-be-ported class or method in C++
  • Copy & paste the original code (entire class or individual methods) into the C++ class or method
  • Comment out the original, non-C++ code (you may need to edit or remove existing multiline comments in the original code)
  • Start re-implementing the code in C++ line-by-line
  • You will quickly find that you need to add extra members, methods or even classes – you have two choices:
    1. create the dependent classes or methods as stubs, initialised to or returning safe default values
    2. comment out the use of dependent classes and method calls but do initialise local values (as stand-in for return/out values) with a safe default value
  • For every chunk of code that you’ve successfully re-implemented in C++, remove the corresponding lines of code from the original, commented-out source code.
    • That way all remaining “original code” comments become your TODO list, or at least things you should come back later, review, and decide whether there’s still something left to do or not. If not, simply remove the remaining commented code.

The important part of this is adding the original source code as your TODO list right inside the class/method you are porting. By leaving any remaining unported code fragments you create reminders for you that there might still be something left to do. Leaving commented out code fragments may have different (but valid) reasons:

  • You wanted to get a working build more quickly.
  • You aren’t sure whether you’ll need that code/feature/hack in C++ anyway.
  • The remaining code may be non-trivial to re-implement and you want to leave it to another time where you’ll have more time or the mental energy to think about it.

Taming the STL with typedef

One issue with the STL is that it quickly creates a hard to read mess of convoluted code. Specifically so for developers who have been programming with modern languages and are used to being treated with highly readable, intuitive framework code.

Instead, you are required to write crap like this, this is just the declaration of a member variable:

Of course, once you start writing more code you may have methods that take a _terrainsByGID instance as parameter, so you’ll have to declare this whole shebang again over and over multiple times. You know this will become a huge problem!

So, if you think that using namespace std; would solve most STL readability issues, it just doesn’t – it only cuts off the tip of the iceberg. It’s also going to increase the risk of conflicting APIs since there’s a good chance that another namespace you are using also includes methods like begin() or end() or find().

What you should be doing is to not use any STL names directly in your code, but instead create typedefs for every variation you need. This way you’ll reduce mental load, you cut down on the amount of code to write, you make it easier to autocomplete types and to perhaps later change their type (ie when changing from unordered_map to hashed_set perhaps), and lastly you’ll improve overall readability of your code while tremendously reducing chances of making stupid mistakes!

Simply add a global header where you typedef all the uses of STL collections and such. For the above example you would need:

You’ll notice how these typedefs naturally build on each other and using a proper naming scheme makes the intentions easy to understand, even for new programmers. The member variable then, and all its uses in method parameters, simply become:

And you could pass an instance to this complex map to a function like so:

Whoops! This is C++ that almost feels modern!

Global functions emulating Framework behavior

Another thing I found greatly useful was to re-implement all those functions in Cocoa that STL doesn’t have as global functions of the same or similar name. You can do so most easily by writing static C functions, possibly even inlined. Don’t be afraid or ashamed to write C functions!

Take, for instance, NSString’s lastPathComponent method that returns a string’s last path component – either the last folder’s name or the filename. There is no such thing in STL. Hence I wrote this in a globally included header file:

What used to be several lines of convoluted code, now becomes a single function call that you can run regardless of what class you’re in. Of course, if you wanted to you could also create a helper C++ class and stuff those functions in there, but personally I prefer to be able to do this:

Over this:

But this is up to you, and the latter is preferable if you want to avoid any risk of potential name clashes.

The important part is to be meticulous about creating separate functions for every task that you are used to having right in the framework that you were used to using. Trust me: the next time you’ll need the same or similar functionality, you won’t remember how to write that code. Plus you’d be duplicating the code, and we all know that’s wrong.

PS: You probably assumed this already but just to confirm: String and StringRef are typedefs that map to std::string and const std::string& types.

Name your Spaces!

It seems so obvious to C++ developers but chances are you are porting your code from a language that doesn’t have a namespace keyword. In Objective-C for instance it is customary to prefix your classes to avoid name clashes:

Stop doing that in C++! You get to use namespaces instead. Much better!

You would enclose all your code’s header and implementation files in the same namespace. That makes it easy for you to write code like this:

Outside your project’s code you can either do:

to do the same or simply prefix the classes with your namespace name, for instance an end-user of your framework without the using directive would have to write:

There, no clashes yet if someone wanted to, they could get rid of the TK:: prefix by a using directive.

Going full auto?

C++11 knows the auto keyword. This is essentially similar to Objective-C’s id type or Swift’s let/var keywords. It allows you to declare a variable whose type is inferred by the compiler given the context. For instance you can rewrite this:

into this:

So it does safe some typing. Problem with auto is that it can not be applied in all situations, which limits its usefulness. Plus it does hide the type and therefore may actually make reading the code harder! Take this example for instance:

Okay, so what is instance again? You can’t tell by glancing over the code. Personally, in such cases I would try to avoid using auto at least until I’m more familiar with the API. Until then, I’d simply write it as usual:

Oh wow, that was actually a reference being returned, not a pointer. Who would have thought?

To const or not to const?

Ensuring const correctness in your code is important. More so if you create a framework/API for other users.

However, it’s not easy to grasp that concept if your language doesn’t support or use const as extensively as C++ does. So I bet most would eventually give up and not use const at all. Yup, that code works, but it will not be the best, fastest, safest C++ code you can write.

It’s well worth the time to read up on const correctness and start implementing it, even though it’ll bother and mess with you seemingly unpredictably. You’ll get errors simply because of your use of const, and every time you have to analyse that situation and decide whether const really applies here or not, or whether you made a bad design choice and need to refactor your code. That kind of thinking helps improve your code quality, and const correctness is one way of getting there.

However the downside is that it requires discipline. And you may want to forego this if you’re under time pressure. I understand. Still, keep it in the back of your mind and fix it later. But know that it will be even more painful to do so later on because the bad design decisions have already been made and are in use now.

So this is simply a call to action for you to look into const correctness and learn that concept if you aren’t aware of it yet.

Pass by value or by reference?

One question that comes up early when writing C++ code is the difference between passing parameters by value or by reference. In Objective-C it’s really simple: you pass a pointer to the method. Done.

In C++ you can either do that, or pass by reference. You should prefer the latter whenever possible:

Both functions behave exactly the same, except for the fact that the dereference operator changes from -> to a simple dot in the latter instance:

There’s one other difference: references can’t be NULL (well, they can but this constitutes a really bad programming error that you know better not to make). So you needn’t check for null at all.

Passing by reference has another benefit: if the passed object is created on the stack and it’s a large struct, then pass by reference will be faster than pass by value, because it would have to copy the entire struct’s memory and create a new one. So this is said to be most efficient:

This also lets the function modify the struct created by the caller. So even if the differences compared to passing pointers seem marginal, passing by reference should be the default choice whenever possible, while you still need to resort to passing pointers when they need to be NULL, or other reasons.

There are many subtleties surrounding this topic. Passing by value can be faster, and so can using C++11’s move semantics to avoid making additional copies of const references.

But overall, you will be fine (and safer) using (const) references as the default function argument type over pointers or passing by value.

Inline Property Accessors

Yup, C++ most tedious aspect. For every private member variable you may need to write a getter and optionally a setter method. These are typically prefixed with get and set, respectively.

Fortunately, there’s at least one shortcut: inlining accessor methods straight in the header file. So rather than declaring the accessors in the header and implementing it in the cpp file, you can add the simple accessors straight in the header file

This prevents your implementation file from being cluttered with simple accessor methods. Unfortunately, that’s about it. You can try improve on the brevity of this boilerplate code using either preprocessor macros or complete classes encapsulating properties, but the former is ripe with documentation issues (doxygen doesn’t pick up on macro-ified getters/setter) and the latter seems like plain and simple overkill.

PS: Notice how the getter has a trailing const keyword? That’s to tell both you and the compiler that calling this method will not modify the class members. This allows the compiler to perform certain optimisations (depending on context) and is one aspect to const correctness (see above).

That’s it, for now!

I hope you find some of this interesting. Please leave a comment if you have any questions or suggestions.

If I come across something of interest while porting TilemapKit to C++ (Cocos2d-x) I’ll let you know.

TilemapKit Store opens September 8th

Grand TilemapKit Store Opening

September 8th – that’s tuesday next week. The day before Apple’s media event.

TilemapKit ObjC Source Code will be priced at $75 for Indies, $175 for Pros (>$100k revenue, contract work, priority support).
I’m afraid EU customers will also need to pay VAT on top of that.

If you would like to buy TilemapKit right now, I could use more testers to go through the purchase process. Just send me an email to sales@tilemapkit.com.

Hint: If you’re clever you’ll also find a way to get there straight away. 😉

It’ll be a release candidate, initially

The initial version will be 0.9x and I prefer to call it a “release candidate”. Although TilemapKit has been thoroughly tested, it has not been field-tested yet.

I’m confident that you’ll be satisfied and happy with TilemapKit but I’m also certain you’ll find a number of things that could be better, and that I really really want to fix and improve right away.

Starting as a release candidate is mainly a matter of confidence for me. It’s by far the largest, most exciting (read: scariest) product launch I’ve ever done. Once I feel confident, there’s the other thing I could do …

Pay less for no source?

I could release one or several TilemapKit versions as precompiled, binary framework in the $20 to $35 price range.

If you are more interested in paying less than getting TilemapKit’s source code, please vote here. This task will be accepted if it reaches 100 votes. I recommend to share the link if you really want the cheaper “no source” version. 😉

Will TilemapKit work with Apple TV 4?

Oh, so you heard the rumors, too? :)

To be honest: I don’t know. Yet.

If the rumors turn out to be true and the Apple TV 4 really is a gaming-enabled (speak: “has a game controller”) device with a developer SDK, I’ll certainly run TilemapKit on it the moment the SDK is released and adapt TilemapKit to run well on it.

I’m pretty confident that with SpriteKit the adaptation should be straightforward. I’ll certainly try it with Cocos2D-SpriteBuilder too and will report any issues (or fix them myself if possible).

How is the Cocos2D-X port coming along?

Last week I’ve started working on a C++ port of the model classes. The C++ model will eventually become the backbone for the Objective-C API, but without requiring you to change file extensions (to .mm). Objective-C (and Swift) users should ideally not even notice the change.

Once the C++ model code is done and working, I’ll plug it into a Cocos2D-X project and start porting the rendering code to C++ and Cocos2D-X. Testing on iOS and Android first, then later other mobile platforms and eventually desktop platforms.

I will do my best to get the Cocos2D-X port done by the end of the year. Without leaning too much out of the window I say it’s quite possible to make a release (for at least iOS and Android) in November, depending on what kind of time-eating head-scratchers I run into. More details and updates on this roadmap item and the TilemapKit++ class reference.

PS: I’m going to write a blog post about how going back to C++ feels like and what I did to ease development.

What about TilemapKit for other engines?

After the C++ port? Quite possible. And exciting to think about. Even for non-C++ engines. Of course it also depends on existing user’s requests.

Again, I’ll take your advice, and would appreciate a call to action in your engine’s community. Say, if suddenly a large number of Unity users were to express interest in a TilemapKit port for Unity, I would certainly consider doing that. Despite the fact that it would have to be ported to C#, despite the fact that there’s already several TMX and tilemap products available on the Unity Asset Store.

Please make a request, ideally add the port request here or leave a comment or send me a tweet to @gaminghorror.