"A Thief's Melody" is my current game project. It's a 3D cartoon adventure/stealth game with a contemplative atmosphere, somewhere between "Zelda" and "Beyond Good and Evil", for Windows, Linux and MacOS. It was greenlit on Steam in May 2015. Currently, the code is 80% complete and the content 70%. This provides ~8h of gameplay on 5 chapters. A playable demo containing the whole chapter 1 is available on the official website:
The trailer of the game.
- In an ocean-covered world, play a young thief studying at the Guild
- Learn various skills: climbing, stealth, fight, bow, grapple, and much more...
- Fight or avoid pirates, guards and robots
- Collect gems, paintings and flowers
- Bring back balance to the world by curing ill animals
- Fight huge Guardians
- Explore freely a cartoon open world on the back of a turtle
I've been working on this game since 2012, creating everything from A to Z. It's my biggest personal project. During the creation process, I worked on various fields, a few of which are described here below. Some points are discussed more in details on my dev blog:
Development is made with Unity and MonoDevelop in C#, with a component based approach. Some features went through many iterations and different stages of prototyping, test and integration. At the moment, there are more or less 400 files for 40 000 code lines.
I worked on the following:
- Control of the main character and the camera, "3rd person" type (3C), AZERTY & QWERTY, keyboard/mouse or joypad compatible
- Climbing system enabling the character to climb everywhere, automatic detection of the best anchor points
- Fighting system with blocking, attack chains and charge
- Range weapons with 3rd person aiming
- Enemy/boss AI, hero visibility computation, path finding and navigating, dynamic weapon change, sound awareness
- Animal AI, behavior variations
- Dynamic and continuous loading of an open and cyclic (toric) world
- Day/night cycle
- Various gameplay mechanics: switches/doors/keys, platforms, turrets, loose ground, explosive plants, ...
- Dialog system with multiple choices
- Localisation system (French & English at the moment, Spanish planned)
- HUD, menus, mini map, inventory and collections
- Data saving system
- Helper functions, mathematic utils, ...
- Various tools, among which a level importer from Blender (see the corresponding section)
From the start, I tried to release a demo on a regular basis: every 2 weeks at the start, and now every 2 months, because the content doesn't change that much.
Tests & Debug
Tests are critical. Even with the best will and the greatest focus in the world, we always introduce bugs. That's why I test my game several dozen times a day. I asked external testers to help me and I provide them with new levels regularly. I set up a test procedure and I list every bug on a central file.
I also set up a few non-regression tests, and some test levels for the most critical features.
For such a big project, I had to adopt naming conventions for a better readability. I also regularly update a whole file set about classical mistakes, problems and non-trivial design choices.
I wrote many shaders during this project, and many went through several evolutions (optimisation, upgrade, ...). The most interesting are the following ones:
A shader on which I spent quite some time is the vegetation shader:
- Procedural animation
- Works on billboards and 3D objects
- Creation & use of a seamless noise texture to simulate the vertex displacement from the wind
- Use of a 2nd texture coordinate set to manage wind sensibility
- Strength, frequency and offset wind parameters on the 3 axes
- Color-variation seamless texture with correction factor
Terrain with procedural mapping
The texture mapping of complex terrains (with holes, arches, tunnels, ...) can quickly become difficult to set up, even more when the geometry is modified on each gameplay iteration. That's why I set up a shader handling the texture mapping with this kind of terrain, providing enough parameters to keep some artistic control on the final rendering.
- Auto-UV mapping using 4 textures: default, top, vertical, underneath, with the 3 latest accepting alpha channel
- Smooth tunable transitions between each texture
- Seamless noise texture and associated factors to add variations/displacement on textures
- Use of vertex color to add secondary textures on specific places (moss, little rocks, ground, ...)
- Seamless noise texture and associated factors to create normal variations generating more natural and less smooth transitions between textures
For the level creation, I chose to use Blender over Unity. Blender is not really a level editor, but it offers the direct modelling and texturing of environments and objects. Furthermore, it's very efficient for level prototyping. Then, I had to develop a tool to convert Blender files into levels/scenes in Unity. I tackled various problems:
- A complex object hierarchy
- The need to convert a few objects in "smart/scripted" objects in Unity (prefab)
- The management of logical links between objects (eg this switch opens that door)
- The management of ordered links between objects (eg passage points for an enemy path)
- The management of properties for each objets (eg this chest contains this power-up, this object doesn't react to collision, ...)
- The optimization of the geometry in the memory to find a nice trade-off between the vertex number per object and the number of objects to render.
3D Models & Textures
Every environment, character and object in the game is modeled in Blender. The texture in hand-painted in Krita, GIMP, Inkscape or Blender. I chose a naive, cartoon, and colored art-direction style.
Time-lapse of the creation of an explosive plant with Blender & Krita.
Time-lapse of the creation of a wooden crate with Blender & Krita.
Character and object animations are made in Blender. The main character currently has 40 animations, and enemies have 20. I use a classical method with key frames. The biggest difficulty is to create loopable animations, with continuity in position, orientation, and their respective derivatives. For the complex animations of characters and animals, I used references.
Boss animations are partly made in Blender and partly procedural. Indeed, most of the bosses are huge and their bone hierarchy (dragon spine, tentacles, fists/arms) often aim at the character. Thus, their positions have to be modified in real time to adapt to the hero position. Some movements are built by dynamically mixing several parametric equations to create some kind of movement variety.
As the project is advancing, each level contains more and more objects, and the game starts to lag. Hence, I had to make a few optimization pass, namely:
- Make the maximum of objects static for rendering and collision
- Move animations to shaders if possible
- Lower the script number per object and lower the execution time
- Lower the call frequency for secondary functions
- Restructure the code to perform quick tests first and avoid wasting time
- Disable objects/component based on the distance to the camera
- Keep all this compatible with real-time background level loading
- Adapt the resolution of 3D models and textures to boost loading, display and disk use
Sounds & Musics
Sounds are made of free sounds that I mix together and on which I perform a few classical processings (normalisation, equalisation, fading, pitch, ...). The greatest difficulty, once more, is to create loopable stereo sounds.
For the musics, I used 2 DAW MIDI softwares: LMMS (Linux Multi Media Studio) and Ardour. I mixed soundfonts, synthesizers, and virtual instruments via VST plugins. I learned drums when I was younger so I understood rythm creation quite quickly, but I had a harder time with music theory, harmony, ...
Web & Community
I set up an official website for my game:
I also have a dev blog on which I post more or less technical articles, and various versions of the demo:
I'm on the following social networks: