Skip to main content
TheLastofUsPoster

Weekly Log #2 – C++, E3 and The Last of Us

This was a long week. We had E3 conferences starting Sunday night (for Brazil) and ending on Tuesday, with a lot of awesome – official – announcements: Fallout 4 (my next love), Dishonored 2, Doom 4 and new IPs such as Horizon (which looks very promising), unravel and others. During the week I’ve been playing Fallout shelter also announced on E3, which is a good-looking and funny mobile game, but has the same problems of other farming games: there is no end and it gets bored fast.

In the weekend, I start-and-finished The Last of Us. Man! What a game! I love post-apocalyptic games with adult narrative. My only regret is that I didn’t gave more time to it – I had to play on easy in order to finish in this weekend because I won’t be able to play it for the next week, and if I have more than 1 week gap between my gaming sections, I just can’t continue from where I stopped.

C++

Even with all stuff that happened this week, I almost finished the Accelerated C++ book. Here are some highlights:

Maps

You can create ordered maps defined in <map> and unordered maps defined in <unordered_map>. Their usage is similar, but map is slower to add new items due to the ordering function. Usage:

If you try to access a nonexistent key in the map, this key will be created automatically.

Maps return pair objects as iterators. A pair type is defined as pair<const K, V> and has the following attributes (to key and value, respectively):

About double angle brackets

In cases like map<string, vector<int>>, the compiler may have problem to parse the statement (due to the >> symbol), so it is recommended to use map<string, vector<int> > (with the space). This seems to be a an old practice, I doubt that compilers nowadays still have such problems.

Default arguments

You can use default arguments on function parameters, like Python:

Notice that, the parameters with default arguments must be the last items on the list.

Constant methods

C++ has a mechanism to protect object from write access, for example when you define a function like:

where non_writable is constant. When a parameter is defined as constant, C++ only allows to read public attributes and call const methods, such as:

Brackets on const maps

Due to the constant restriction described above, constant maps don’t have the operator [ ], because this operator changes the map when the key doesn’t exist.

Generics/Templates

Generics are called templates in C++ and is used as:

With stand-alone functions you don’t have to specify the template explicitly, e.g.:

The typename keyword

C++ has so many features on it that sometimes the compiler simply doesn’t know what to do. For instance, when you try to define a variable within a subtype defined inside a template, like this:

In this case, the compiler interprets SubType as a static member of T, thus, it tries to multiply SubType with ptr, causing an runtime error. Because of this, you always must use the typename keyword, avoiding compiler mis-interpretation:

Reference: http://stackoverflow.com/questions/1600936/officially-what-is-typename-for

Iterator categories

There are 5 types of iterators. They are divided by what they can do (thus, which operators are allowed) with the object they reference. The categories are:

  • Input
  • Output
  • Forward
  • Bidirectional
  • Random access

Consult http://www.cplusplus.com/reference/iterator/ to see the table of all operations these iterators handle

Stream iterators

istream and ostream can be used as iterators:

This piece of code sends all elements of a vector v to the console output.

Default constructor

To avoid double initialization when you create an object, you must use the constructor initializers:

Without this, C++ initializes the object attributes before the constructor body, and in constructor you probably will initialize the attributes again.

Pointers

Just a reminder:

  • &x returns the address of the object x
  • *x returns the object in the address x

Pointers to functions

You can create pointers to functions as:

This creates a pointer fp of a function that receives and return int values. Notice that you don’t have to use &my_function, because C++ convert functions automatically. The same can be applied to the usage (you don’t have to call (*fp)(2), only fp(3)).

You can also return a pointer to function from another function, this is a bit tricky because you have to use typedef to declare the pointer before:

To return a pointer to a function that uses template is trickier, you will have to define a struct with the pointer and return the struct.

Arrays

C++ arrays are pointers to values and, thus, they can be used as iterators:

Notice that, the variable array stores only the first pointer, thus *a == 2.

The index usage array[3] is equivalent to say *(array+3).

Because array is only a bunch of pointers, you don’t have the type_size directly, but you can use size_t from <cstddef>.

File streams

Using input or output files is pretty easy:

The usage is the same as cin and cout.

Specific streams

Instead of cout, you can use cerr for error output (it is preemptive, so it prints the string when it is called), and clog for logging (non-preemptive).

New and delete

To allocate and deallocate objects manually, use new and delete:

If you allocate an object manually, it will only be deallocate manually too. You must be very careful to avoid memory problems!

Explicit constructors

C++ allow explicit and implicit object initialization:

The explicit keyword prevents the compiler to use the wrong constructor due to wrong type conversions:

This

Another reminder: this is a pointer to the object.

Copy constructor

Passing an object by value to a function, returning an object by value from a function, or simply assigning one object to another variable, implicitly copies the object. The constructor used in the case is called copy constructor:

Rule of the three

To control all creation and deletion process of a class, you must implement at least the following methods:

Citing the book:

Because copy constructor, destructor, and assignment operator are so tightly coupled, the relationship among them has become known as the rule of three: If your class needs a destructor, it probably needs a copy constructor and an assignment operator too.

ShowCover

Weekly Log #1 – Motivation and C++

I started this blog intended to post my developments and things that I’ve been learning during my path towards game industry. But, in general, I’ve only been writing tutorials and releases notes. Tutorials are pretty hard to do, because I like to create examples, format, make images, revise, and give details about what I’m writing about, and releases notes are only published when I have a release to announce. Both demand time, which I don’t have much lately. In consequence, my posts now have about 1-month gaps among them, and this isn’t good.

Thus, in order to keep my initial plan and write more frequently, I’m creating a weekly log, starting with this one, so I can register and tell what I’m studying or developing.

C++

In this post I will only talk about C++, which I’ve been studying almost exclusively.

First thing to say is, I’m following the book Accelerated C++ by Andrew Koenig and Barbara Moo. The book is pretty good, but I wouldn’t recommend for a total beginner. In my opinion you should learn the basic on other languages before getting this book – and language.

I am learning C++ in depth because I want to have some experience on the AAA industry, so this is pretty much obligatory. I understand that C++ is a pretty powerful language, but damn, this language is complex as hell. Notice that I’m not talking about syntax or readability, I’m talking about the concepts behind every feature of C++. There is a lot of redundancy (you can solve problems in a dozen of different ways) which seems to be caused by the performance concern (generally there is a super – but complex – parsimonious solution).

During the course of this book (and the followings) I will share more my thought about the language. For now, I’m going to give some highlights of interesting stuff on the book:

Abstraction

The author’s give a pretty good definition of abstraction right on preface:

We define abstraction as selective ignorance – concentrating on the ideas that are relevant to the task at hand, and ignoring everything else

Containers and size_type

Most STL containers provide a size_type type, which defines the appropriate type to hold the number of elements of a given container. For example, to move through a string, you should use:

instead of:

The reasons of that is because the number of elements in the container may be bigger than what int (or unsigned int, etc..) can handle.

The & operator

The & denotes a reference to some variable.

As a good practice, you should use const to tell programmer when your function does not have intention to change the parameter value. E.g.:

The istream objects

istreams have a failure state that is kept until cleared, thus, if you put a string on to this:

you won’t be able to read anything until you clear the stream:

lvalue

Non-const arguments can only receive lvalues  (can’t be anonymous):

The same is valid for return values.

Header files

You must avoid the use of using inside the header files, because your never know how the source file will use the variables. Avoiding using you avoid unnecessary conflicts.

Also, you must always use the preprocessor directives:

because compiler insert the header code into the source files that import the header. Without it, the definitions would repeat several times causing errors.

Inline functions

Inlines functions are cool, they only exists before compiling. The compiler copy the body of the inline function where it is called. Use this to avoid the overhead by function calls.

Built-in exceptions

Import <stdexcept> to use the default error classes:

  • logic_error
  • domain_error
  • invalid_argument
  • length_error
  • out_of_range
  • runtime_error
  • range_error
  • overflow_error
  • underflow_error

using:

Vector limitations

Vectors are optimized for random access and pushing/removing items from the beginning or end. Other operations are slow. The reasons for that is that vector move all elements back or forward when you change items at middle of the container.

Note: for fast insertions or removing, use list. However, list items can only be accessed sequentially.

Iterators

Iterators are cool, and in general are implemented as pointers (but not true all the time). You can use the following iterators:

each one for a specific situation: const to handle const values, reverse to reversed loops, iterator for common loops. For instance, to move through a string you can do:

Overloaded function as arguments

You must avoid using overloaded function as arguments to functions, because the compiler can have problems to decide which function to use. Instead you should use an auxiliary function.

Static variables

You can use static storage class specifier on local variables inside functions. A static variable is created the first time the function is called and reused in subsequent calls.

Using functions as arguments

To create functions that receive other functions as parameters:


A final note: the STL has A LOT of interesting things, for instance, check the algorithm package.

step3

Creating circular worlds like Democracy

Last Ludum Dare I implemented a circular world for my game. I wanted to do that for some time, but before this LD I had no idea how to implement such a thing. Now I see that is pretty easy to do so. In this post I will explain how to create a circular world like the one I used in Democracy.

The beauty of a circular world is that we can work only with the radius of the planet, ignoring its position at the screen. So, first thing to do is defining our planet to a radius “r” (lets say 150px) and to screen position (0, 0). To center the planet in the window, you move the camera to (-w/2, -h/2) where w is the window width and h is the window height. You should see something like this:

step1

Now that we have an empty world, lets add some objects on it. All objects must have a position in this world, but this position isn’t the same of in screen, it is simpler. Suppose that at the point (0, r), what could be the north of our planet, is the angle 0°, then the east (r, 0) is 90° and so on, until the north point again. See the image below for reference:

step1-2

Now our object can be at positions like 47° or 270°, but we still must draw it into the screen. That’s pretty simple. Let’s say we have a sprite with (s_w, s_h), width and height, respectively. Then we set its screen position to (0, 0) and its anchor to (0, r+s_h). With this we have an sprite at the north point 0°, to relocate it to 306° we simply set its rotation as “sprite.rotation = 306” and done!

step2
White box is at north (0°) and the red box is at 306°.

Additionally you can also set the height of the object in that world (the distance of that object to the ground). To put a cloud at 30px high, you simply add the height to the sprites anchor, such that anchor is (0, r + s_w + height):

step3

Sometimes you may find useful to convert the world position, now (position, height), to the screen position. For example, to add some particles. So, to find the screen coordinates (x, y) of an object at (position, height) you do:

Contrarily, when you want to convert the screen position to world coordinates, for example to find where the mouse is pointing. You can do:

Simple right?

Let me know if you found this article useful, or if you have an alternative way to do that, or yet, if you created some circular world based on this. Cheers!

platform - Copy

Creatine 1.0.0!

Ludum Dare is great! Not just because it motivates me to create (and finish) a new game, but also because I use it to update Creatine. So, as usual, after the compo I’m releasing another version creatine, now the release 1.0.0!

This version is big. It has a lot of new stuff and a lot of changes for the old features. But before talking about the modifications and additions to the library, let me talk about how I was felling about creatine 0.2…

To be honest, I wasn’t happy about the previous version, I added several classes to handle storage, sound, layout, scenes, among other things. But they weren’t working together, there were some annoying bugs (in special with transitions) and I was spending a good time rewriting the same base structure for new games, over and over.  So I decided to rethink some things: how can I make my development easier and faster? My conclusions and desires after that:

  • I want to use a visual editor to build my scenes, something like Overlap2D or one tool of my own.
  • I need more flexibility for fast prototypes (sometimes I just want to test some idea).
  • Modularity is cool, but is not a great deal. A class that controls all modules would be more useful and would save some time by eliminating the base common structure that I was rewriting every project.
  • I need more fluffy things, more juice, which means that have to be easy to add particles and visual or sound effects to the game.
  • I want to have a physic system and other predefined behaviors easy to use in my games (such as a platform system, or 2d top-down movement and collision system).
  • Other details that I don’t remember right now (it is Sunday 11PM, give me a break!).

With these things in mind, I started to update creatine.

Game

The main addition to creatine is the Game object. The game is now the core of my library, because it is the responsible to create and initialize all game systems. For example: it is the game that creates the canvas element; the game also stores all creatine helpers (now called managers), such as the director (SceneManager), the device,  display and many others.

The game class is based on Phaser core, so if you know Phaser you may find this familiar. A game has 5 states: ”boot”, “preload”, “create”, “update” and “draw”. In the boot state you can initialize 3th-party libraries and some configuration of the engine. In preload, you will set which files should be loaded by the engine and may be show a preload scene. In the create state you will create and initialize all game objects, including scenes and object pools. The update and draw states are the main loop, and are executed every tick. You can use these state by passing functions to the game:

The first argument of the Game class is the configuration object. This could be only an url to a JSON file containing the configuration. Notice that, with this, I will try to keep all engine data-driven, so you will be able to configure everything using this parameter. Right now, it has the following default values:

To set configuration you can do:

or yet:

where ‘myconfig.json’ is the json file containing the configuration values.

Resources and Factories

Creatine now have an interface to PreloadJS (the ResourceManager) and a factory manager. The resource manager helps you to load general assets in a more pleasant way and also helps you to load specific assets (such as spritesheets and audiosprites) in an easier way. For example, now you can set which files you want to preload in the preload state:

Or you could define these assets in the manifest (pretty much like how you do with PreloadJS):

With your stuff loaded, you can create objects easier:

 

Scenes and Transitions

Scenes now have some default method that you should override to use, such as “enter”, “pause”, “resume”… To create a scene, you must define a new class inheriting the scene class, an easy way to do that is by using the new shortcut:

You can also create your scenes before starting the application and register them to the director, using an unique identifier:

Transitions are now working as they should be! You can use any transition in any function (replace, push or pop), repeatedly, or without having to wait the current transition.

Input handlers

We have input now! Keyboard, gamepads, mouse and touch. They don’t work together yet, but they are pretty cool already. Instead of putting code here, I suggest that you take a look into the creatine example folder and into the API documentation.

In the next releases I want to create a common Input or Control object that group all type of inputs together. So instead of checking the state of the keyboard, mouse and touch, you could simply check game.control.isDown('action a') . Moreover, you should be able to redefine the input commands.

Particles!

Particles are so so so so cool! Creatine uses the cocos2d particle style. So if you want to create some fire you do:

Unfortunately, the current particle system has some limitations. For example, it cannot change the particle colors due to performance. It also must be updated manually, sometimes I forget that!

Sounds and Storage

The SoundManager is simpler now, it does not separate music from sound effects, but you still can add sound groups to it. The coolest thing is that sound works together with the StorageManager, so when you change the volume or the mute, the sound manager stores this information locally and you don’t have to worry about that anymore!

Legacy Stuff

Some things will be changed to a better structure, such as the layout managers and the custom display objects. They are still in creatine but they weren’t updated this time.

Moar of Creatine

To now more about new stuffs in creatine, check it out:

You can also contact me for any doubt or suggestion.

fsm

Finite State Machines in Javascript

I’ve been talking a lot about Behavior Trees (BTs) lately, partially because I’m using them for my PhD. But although, BTs provide a powerful and flexible tool to model game agents, this method still have problems.

Suppose you want to model a bunch of sheeps (just like my last Ludum Dare game “Baa Ram Ewe”), these sheep have simple behaviors: “run from cursor”, “stay near to neighbor sheeps”, “don’t collide with neighbor sheeps” and “follow velocity and direction of neighbors”. A sheep can also have 4 states: “idle” when it is just eating grass, “obey” when it is being herded by the player (using the mouse), “stopping” between obey and idle, and “fear” when a predator is near. The behaviors are always executing, but they may have different weight for different states of the sheep. For example, when a sheep is “obey”-ing, it try to be near other sheeps more than when it is eating grass or running scared.

Modeling this as a Behavior Tree is hard because:

  1. BTs don’t really model states well. There is no default mechanism to define or consult which state an agent is; and
  2. All behaviors are executed each tick, thus this agent wouldn’t exploit the BT advantages of constrained executions.

Notice that, you still can model these sheeps with BTs, but the final model would be a lot more complex than it would be using other simple methods.

In previous posts, I also talked about how Behavior Trees have several advantages over Finite State Machines (FSMs). But, in cases like this a FSM is a lot useful and considerably easier to use than BTs.

Implementation

Like my Behavior Tree implementation, I want to use a single instance of a FSM to control multiple agents, so if a game has 100 of creatures using the same behaviors, only a single FSM instance is needed, saving a lot of memory. To do this, each agent must have its own memory, which is used by the FSM and the states to store and retrieve internal information. This memory is also useful to store sensorial information, such as the distance to nearest obstacles, last enemy position, etc.

First, consider that all states and machines have a different id, created using the following function:

and to simply inheritance, we will use the Class function:

We will use a Blackboard as memory for our agents. Notice that, this is the same blackboard used in my behavior trees.

We will also use a state object that implements the following methods:

  • enter“: called by the FSM when a transition occurs and this state is now the current;
  • exit“, called by the FSM when a transition occurs and this state is not the current one anymore; and
  • tick“, called by the FSM every tick in the machine. This method contains the actual behavior code for each state.

Our FSM will have the following methods:

  • add(name, state)“: adds a new state to the FSM, this state is identified by a unique name.
  • get(name)“: returns the state instance registered in the FSM, given a name.
  • list()“: returns the list of state names in the FSM.
  • name(memory)“: return the name of the current state. It can be null if there is no current state.
  • to(name, target, memory)“: perform a transition from the current state to the provided state name.
  • tick(target, memory)“: tick the FSM, which propagates to the current state.

Notice that, some methods must receive the blackboard and the target object as parameters, which can be a little annoying – this is the downside of using a single FSM to control multiple agents – but the cost is small compared to the gain in memory.

The target parameter is usually the agent being controlled, but in practice it can be any kind of object such as DOM elements, function or variables.

Example

Using a simple Boiding algorithm, we have 3 states: “idle”, “obey” and “stopping”.

Use the mouse to move the white balls:

(more…)