What is ceramic?
Ceramic is a cross-platform framework that lets you create 2D apps and games written in the Haxe programming language.
It can export natively to desktop (windows, mac, linux), mobile (ios, android), web (js + webgl) and unity projects.
Ceramic was under quiet development for several years. It started as some kind of personal project and then grew into something that I use daily to create various kind of apps and ship real games in production.
Note: this article is a bit technical and a background in game or software development may be required to understand all of its contents.
So, why ceramic?
It may seem odd not to use mainstream software like Unity to create video games or other graphics intensive apps. Why setting up an entire new tool?
Wished an open-source tool between Phaser and Unity for 2D apps/games
Unity is nice, you can build a lot of things with it. But I come from a background where I enjoyed a lot lighter, more code-centric and 2D oriented tools on the web like Pixi or Phaser.
What is great with Phaser or Pixi is how simple they are to get started. You simply write a few javascript files, load them in your browser and yay, you got something working already! Unfortunately, all this joy and fun is focused to the web. It works great in web browsers, can work on mobile but to do so you need to embed a pixi or phaser app as a webview inside an iOS or Android app, and performances won’t be as good as if you created a native app.
On the other hand, you could use Unity to create games and apps that can be exported to native platforms, but the steps required become more complicated and you start to depend on a huge closed source software to write ANY app or game. Everything you create has to display a Unity splash-screen unless you pay a license fee.
It is totally OK to pay license fees to use Unity in the context of a professional game studio. But I personally create plenty of tiny games, apps, creative coding projects as an individual and wanted to find an alternative that doesn’t depend on something as heavy as Unity.
Then, how to have a tool that can target the Web, but also natively target platforms like iOS, Android, PC, while still keeping most of the benefits of Phaser or Pixi: being open-source, easy to use and not huge like Unity?
Meet Haxe
The Haxe programming language lets you write code that can be transpiled into other languages such as C++, Javascript or C#. Yes, that means you write a single codebase that can then be converted to C++ or JS and run natively or in the browser!
As a comparison, Unity needs to perform quite complicated transformations to make your game run in the browser: it needs to transpile your C# code into C++ via IL2CPP, then transform the resulting C++ code into WebAssembly via emscripten. The whole process is pretty slow and means you cannot iterate quickly when testing a web export of your app/game. With Haxe, transpiling your code into javascript and running it in the browser is a matter of a few seconds!
Haxe is an excellent open-source programming language and I really enjoy using it daily. It has some good features making it very powerful and scalable (macros, strictly typed, enums and pattern matching) yet is fairly easy to pick up if you already know more common languages like C#, JS, Java, AS3 or TypeScript.
Tools to create cross-platform native games already exist within the Haxe community:
- OpenFL (Rymdkapsel, Papers Please)
- HaxeFlixel (Defender Quest, Friday Night Funkin’)
- Heaps (Dead Cells, Northgard, Evoland)
- Kha (CrossCode, Armory3D)
- Luxe (The Wesport Independent)
I tried these one by one before starting to work on ceramic, even did some projects with some, here’s some feedback:
OpenFL | OpenFL is the most popular way to export native apps with Haxe. It’s great if you want to migrate a Flash project to Haxe because it provides the same API. That’s also the main reason it had issues for me. I don’t need to carry the whole Flash API and all the dependencies it needs (cairo, freetype…), which make it more complicated to grasp if I want to fix something inside (talking from actual experience with the tool here). It’s still a very important tool in the haxe community and a lot of developers are using it. |
HaxeFlixel | Same spirit as Phaser, which is nice. HaxeFlixel has pretty good documentation which is a plus. It is however built on top of OpenFL and that became an issue for me: I shipped a game at a time HaxeFlixel was stuck in some older version of OpenFL (legacy). Needed to export Android Studio projects, but that was only available in some newer OpenFL that didn’t work with HaxeFlixel. This was a very bad experience for me at the time. I managed to workaround the issue by setting up an entire alternative build system for Android and iOS. These are not good memories. |
Heaps | Nice high level API and great games made with it. The tech seems solid and also provides a 3D pipeline. However, making it work on mobile was somewhat difficult and not 100% supported. It was not really an option for me as iOS and Android were the primary platforms I wanted to target at the time. |
Kha | Kha is impressive. That said I didn’t dare to invest much in it, because I was not comfortable with using a tech I don’t understand much and that I can’t fix myself in case I face a problem with it. Also, if I used Kha, I would have needed to create some high level API anyway because Kha is a bit too much lower level for my daily usage. Some developers are doing awesome things with Kha though. |
Luxe | A game framework with very few dependencies yet quite versatile. I liked it a lot and used it for a while for my projects. It was providing most of the features needed, and the internals were pretty clear and approachable, which was handy in case I needed to improve/fix something inside. Unfortunately its Haxe version got discontinued (but you can check out the new luxe if you want, which is now written in C++ and using wren scripting). |
Note: although I had some issues with these tools, they are great and make a lot of developers happy. I am only talking about my personal experience, which is subjective and tied to my preferences and project needs. You should definitely check these out yourself! I don’t consider ceramic as being a better tool than those. It’s just a different option with its pros and cons and ways of solving problems ✨.
Say hello to ceramic
I started working on ceramic once Luxe (its haxe version) somehow got discontinued. Ceramic started as a wrapper around Luxe. Like, a high level API that runs on top of Luxe. I maintained a fork of Luxe for a while to ensure it worked well with ceramic and newer versions of Haxe. Then ceramic slowly evolved into something else. I created a backend system to separate the public API from its internals and to prepare for better cross-platform support.
Backends are simply modules that let you port the engine to new platforms without having to rewrite the entire engine. It only contains the low level code strictly necessary to load assets, display graphics on screen, play audio, handle input…
Ceramic’s first backend was using Luxe internally. It was very convenient at the time because it allowed to put very quickly the engine on foot, target mobile, desktop and webgl just fine. Performances were fairly good but not optimal because luxe was not really intended to be used this way, but it was a good transitional state and allowed to design ceramic’s high level API as I go.
This transitional state lasted for a few years, until I did set up a more tailored backend called Clay. Basically, clay does the same as luxe internals, but specifically adapted to be used with ceramic, with only the features needed that don’t overlap with ceramic features.
That’s how ceramic still works today.
Ceramic architecture
There are currently 3 backends: Clay, Headless and Unity. Clay is the default backend, Headless allows to run ceramic as a server or a CLI script and Unity backend exports your whole ceramic project into a Unity project (this specific part about Unity will be explained in a future article).
With this separation of concerns between high level API and backends, ceramic is designed from the grounds up to be portable. New backends could be added in the future to handle new platforms, without having to change the high level API. The latest addition is the Unity backend, which is pretty new for now but already successfully runs ceramic apps like my latest jam game.
Ceramic doesn’t provide any 3D pipeline like Heaps or Kha, it is focused on 2D and tries to do that very well. These are some of the things ceramic provides out of the box on every backend (no audio/graphics context on headless/node.js):
- Display tree: Create hierarchies of nested visual objects like you would do in Flash or Pixi.
- Multi-texture batching: Fast rendering of 2D objects, even if they use different textures. This can drastically reduce the number of draw calls in your app and make it run better.
- “Free” additive blending: Switching between standard and additive blending can cost you additional draw calls and destroy performances in some engines. This is not the case with ceramic, which premultiplies alpha of your images automatically and allows to draw both blendings in a single draw call (see this article for reference).
- Text rendering: No dependency with font rasterization libraries. Render bitmap fonts, with support of MSDF (multichannel signed distance field) to draw them at any resolution.
- 2D Quad and Mesh rendering: Draw anything composed of squares or triangles, textured or not. They can be batched together.
- Audio playback API: Play sounds and background music.
- Event system: Handle input and other events of your ceramic app with its built-in macro-based event system. Create your own events with very little boilerplate code.
- Data model, observable and serialization API: Create haxe classes that store data and that can be incrementally serialized to disk. Bind autorunnable callbacks to observable properties like you would do with mobx autorun and do reactive programming. Ceramic does that by tightly integrating with another library I wrote called tracker.
- UI toolkit: Construct advanced layouts with Haxe (see an example of what can be done with it here).
- Spritesheet, Tilemap & 2D Camera: Load tilemaps created with Tiled Map Editor or from code, display animated spritesheets and use a Camera API to follow your player on the map. This will be improved in the future to support Aseprite format and some other map editors (I’m looking at you LDtk 👀).
- 2D Physics: Support Arcade Physics (ported from phaser arcade physics) and Nape Physics.
- Spine animations: If you use Spine to create animations, ceramic can read and display these out of the box.
- Entity-Component architecture: Create entities and attach components to them for better modularity of your code.
- State Machine: A macro-based state machine implementation to manage states with minimum boilerplate code (a bit similar to StateKit).
- Visual Studio Code integration: Work on your ceramic projects using the dedicated VSCode extension.
- Command line tools: Ceramic comes with CLI tools to build & run your project as well as exporting it for the different platforms it supports. It can for instance be used to export an Xcode project for iOS or an Android Studio project for Android.
- Plugin system: Ceramic is fully extensible with plugins. You can add CLI commands, a new backend or just more high level features with a plugin.
Each of these features should deserve several articles and extensive documentation. This blog article is hopefully a starting point to more content that will show how to use ceramic 🤞.
How is ceramic used?
Creating ceramic was a way for me to experiment new things. Not only for creating games, but also create some generative art / creative coding projects (see this installation or most of my animations posted on instagram, which are all made with ceramic).
We also use ceramic at our game studio (La Gamerie) and released a few games with it on iOS and Android (see our latest game Make More Views, which contains advanced UI, a lot of animations using Spine, fully customizable room and avatar etc… all made with ceramic).
What now?
I hope this article gave you a little more information about what ceramic is and that made you want to try it!
Start creating your first ceramic project with the next article: Getting started with ceramic.
Also, feel free to leave a reply below if you have more questions about ceramic that this article didn’t answer!
Feel you should really include the NME toolkit in the list above, it’s similar to OpenFL but it uses c++ in browser, and cppia makes android prototyping very simple via acadnme, and looks like it has some good IOS/mac support on the way. Armory3D should also get a mention next to Kha as it opens up tooling.
@Nanjizal Armory3D was mentioned in the article already 🙂
Regarding NME, the list is not exhaustive anyway, might have forgotten some other tools as well. Anyway, NME pretty similar to OpenFL as you said which is not what I was looking for at the time. Being able to iterate quickly on the web version via JS (so, not via C++) is also important in my case.
CPPIA is great, and I tried once to integrate it with ceramic. Unfortunately I did hit some edge cases that I didn’t have the time to investigate yet so this is in standby for now. Might try again at some point!
Been following ceramic’s development for quite a while and I’m extremely happy to see it become more mature!
Thanks a lot for your work and for sharing it, can’t wait to try it out :]
@Fat-Leech Glad to know and happy that you’ll give it a try 🙂