Crimild v4.5 is out!

Crimild v4.5 is already available in Github!

The most important feature included in this new version is a modular Particle System. The idea behind this new design is that each part of the system is setup using one or more modules, each describing behaviors for particle generation, update and rendering. Modules handle specific properties (like position, velocity or color) and there are many options already available. I suggest you take a look at the Particle Showcase demo to have a glimpse at the new Particle System in action.

Screen Shot 2017-05-14 at 8.46.28 PM

This version also features a working interactive console for simulations. Such tool is extremely useful to change simulation parameters at run-time. Screen Shot 2017-05-10 at 1.09.08 AM

Of course, it is possible to extend the default functionality by implementing custom commands for your own simulations too!

The Profiler has received a huge improvement too! It now displays additional run-time information and a real-time frame-rate histogram:

Screen Shot 2017-05-11 at 10.32.54 AM

 

Other improvements and changes can be seen in the Release Notes for version 4.5

Go to Crimild’s Github page to get your hands on the new version. All of the example projects have been updated as well to include all of the newest features and improvements.

Feel free to contact me if you have any questions or comments.

See you around!

 

Your wish, my command (console)

A couple of weeks ago, when I was working on a secret project of mine , the following situation occurred:

Each level in the game is composed of several sections. Some of them are interactive, requiring the player to do something (like traversing a path or killing enemies). Cut-scenes are played in-between those sections, triggered by some event happening in the game world (for example, when the player reaches a predefined point in the map).

As you might have guessed, it’s very frustrating to play entire sections of the level just to reach the last cut-scene and realizing that some actors were misplaced. Despite the fact that everything is based on Lua scripts and that reloading them is very fast, we still need to replay at least a couple of sections just to verify that our changes worked. It would be great to have a tool to trigger those animations and any other events as soon as the level loads, right?

Of course.

And what better tool for such a situation than an interactive console?… Actually, a scene editor would be much better. Maybe one embedding a script editor. Oh, oh! Visual scripting will be great too… and also… Ok, fine, it’s not the best solution, but bear with me.

Anyway, the interactive console is very simple to use. You press the tile (~) character in your keyboard and a prompt appears waiting for you to input commands. Yes, it’s pretty similar to UNIX terminals and it even has a command history and scrollable text, although there is no support for autocompletion at the moment.

Implementing new commands is as simple as registering a name and a callback that will be triggered whenever the user inputs such text into the prompt. For example:

Console::getInstance()->registerCommand( crimild::alloc< SimpleConsoleCommand>( "foo", []( Console *console, ConsoleCommand::ConsoleCommandArgs const &args ) {
   console->printLine( "Bar" );
}));

Here is the console in action:

Screen Shot 2017-05-10 at 1.09.08 AM

Probably the most useful command at the moment is the set one, which lets you change settings values while the game is running. For example, you can enable the profiler change the value of the profiler.enable variable like this:

set profiler.enabled=1

Screen Shot 2017-05-10 at 1.12.06 AM.png

The best part is that the console is already included into the Simulation framework and will be available as part of the next release (any time now). The only requirements is that you, the application developer, are responsible for providing a System Font to be used during the rendering phase. The same is true for the Profiler, btw.

See you next time!

The Ghost of Refactors Past…

…has come to hunt me once again. Although this time it’s not because of mistakes that I did. Instead, the problem lies in something that I missed completely.

Can you spot the problem in the following code?

void SomeObject::save( Stream &s )
{
   std::size_t count = getElementCount();
   s.write( count );
}

Well, it turns out std::size_t is NOT PLATFORM INDEPENDENT. And here’s the twist: I knew that since, well, forever, but I never paid any attention to it. That is, until it became a problem. And the problem was EVERYWHERE in the code.

First thing first. The C++ standard has this to say about std::size_t:

typedef /*implementation-defined*/ size_t;

 

What’s that supposed to mean? Basically, std::size_t may have different precision depending on the platform. For example, in a 32-bit architecture, std::size_t may be represented as a 32-bit unsigned integer. Something similar happens in a 64-bit platform.

Wait.

std::size_t is supposed to help portability, right? That’s its whole purpose. And that’s true, of course. There’s nothing wrong with std::size_t itself.

Check the code above again. Go on, I’ll wait.

So, whenever we create a [binary] stream to serialize the scene, we can’t use std::size_t because it’s just plain wrong. It will be saved as a 32-bit integer in some platforms and 64-bit in others. Later, when the stream is loaded, the number of bytes read will depend on whatever the precision of the current platform is, regardless of what was used when saving. See the problem?

This means that we can’t share binary streams between different platforms because the data might be interpreted in different ways, leading to errors when generating scenes.

For the past few years, my main setup have been OS X and iOS, both 64-bit platforms. But one day I had to use streaming on 32-bit Android phones and, as you might have guessed by now, all hell break loose…

Entering crimild::types

I had to made a call here: either we can keep using std::size_t everywhere and handle the special case in the Stream class itself; or we can make use of fixed precision types for all values (specially integers) and therefore guaranteeing that the code will be platform independent.

I went for the second approach, which seems to me to be right choice. At the time of this writing, the new types are:

namespace crimild {

   using Int8 = int8_t;
   using Int16 = int16_t;
   using Int32 = int32_t;
   using Int64 = int64_t;

   using UInt8 = uint8_t;
   using UInt16 = uint16_t;
   using UInt32 = uint32_t;
   using UInt64 = uint64_t;

   using Real32 = float;
   using Real64 = double;

   using Bool = bool;
 
   using Size = UInt64;
}

As you can see, crimild::Size is always defined as a 64-bit unsigned integer regardless of the platform.

Yet that means I need to change every single type definition in the current code so it uses the new types. As you might have guessed, it’s a lot of work, so I’m going to do it on the fly. I think I already tackled the critical code (that is, streaming) by the time I’m writing this post, but there’s still much to be reviewed.

New code already makes use of the platform-independent types. For example, the new particle system is employing UInt32, Real64 and other new types and–

Oh, right, I haven’t talked about the new particle system yet… Well, spoiler alert: there’s a new particle system.

You want to know more? Come back next week, then 🙂