Last two months were pretty awesome. I had lots of free time and was able to implement lots of new stuff!

Recreation mechanic

Let’s start with a gameplay gif:

It’s another example of recreation mechanic.

For those who don’t know, recreation mechanic is the main mechanic in my game. When undead hero kills people, he can leave his body and control dead people with his ghost. He gains their abilities to progress through the game and solve various puzzles. But he can’t leave his body behind for a long time because he can’t carry the hammer while controlling other people. The hammer can do some stuff which normal weapons can’t. (break some floors, for example)

This hammer is very heavy so he can’t carry other weapons. So, for example, in order to shoot arrows, you need to kill archers and control them with your ghost.

He can also use his ghost to reach inaccessible areas. But this won’t be very useful if there are no corpses lying there because he won’t be able to interact with the world this way. But it has another use: you can look around and see what you have to deal with next. This will be very helpful when solving complex puzzles.

Here’s another example which I posted already but made look a bit prettier:



Corpses have weight, so you can use it to push buttons and some other stuff.

SFML forums dev log

I’ve started a dev log on SFML forums. This lets me post short notes about the stuff I’m working on. This also lets people discuss stuff about my game and engine. It also lets people provide in-depth feedback which I appreciate a lot.

There’s some awesome discussion about entity/component/system happening there, so make sure to check it out, if you’re interested.

I also plan to start dev log on TIGSource later which will mostly mirror dev log on SFML forums.

Alan the Blasterous

Alan the Blasterous is a pyromaniac addicted to explosions and you need to rescue him from the cell where he is kept by evil humans. He’s very intelligent and humble person… when he’s not talking about explosions. See for yourself:

(Fun fact: this is the first character which has name now.)

GUI

I’ve also redone GUI completely:

GUI also displays contextual tips because main action button will have different uses depending on the context. (This was cleverly used in Anodyne in some moments. RIP, some people I’ve tried to talk with.)

Bitmap fonts

I’ve had a basic system for bitmap fonts for a while but it was too slow because I’ve used sf::Sprite for each letter which was a big waste.

Now I’m using sf::VertexArray for a whole string so I have to one draw call per string instead of tons of draw calls for each letter!

I’ve also discovered a very useful tool called BMFont which can convert any font into a bitmap and add some outlines or other effects if necessary.

It produces a .png (and many other formats if you choose!) and a .fnt file which is a plain text file which is very easy to parse and then use it for drawing.

Maybe I’ll write a short tutorial about it. It’s a great tool.

Events

This was a huge thing on programming side of my game.

Short example: GUI needs to know player’s hp at any given moment. It can check player’s hp in each frame but that’s not very efficient. I use Observer pattern. Systems and entities can subscribe to any other system or entity and receive messages from them. But I’ve done more than that. I’ve made callbacks so I can map system member function to event type and it will be called if entity sends that event.

So, when player entity sends HpChangedEvent, GUISystem::onHpChanged() is called. Here’s how it looks in the code:

gui->registerCallback<HpChangedEvent>(&GUIPlayingState::onHpChange); player->addObserver<HpChangedEvent>(gui); void GUIPlayingState::onHpChange(int senderId, const std::shared_ptr& e) { auto event = std::dynamic_pointer_cast(e); int hp = event->hp; ... // do some stuff! }

This made me rethink lots of stuff about system interaction and led to lots of decoupling which is great and made the code a lot better. For example. GUI system doesn’t need to know how HPComponent works anymore, it just gets the only thing it’s interested in: HP value. Systems which respond to user input don’t need to check input for themselves, InputSystem does it and sends ButtonPressedEvent for those systems who are interested. And there are a lot of more examples of decoupling which can happen.

I’ve made event system with some neat C++11 features like std::type_index and std::bind. There’s some possibility that I’ll write a complete tutorial about this event system because it works better than I’ve expected.

Some animations

I’m also making basic human sprite, so I won’t have to redraw lots of stuff. This also led to a better walking and attack animation than I had before!

Archers

Archers are a great display of stuff I’ve done recently.

First of all, all items now have scripted functions called use. So, when you use a sword, script function is called and sword attack starts. When archer uses his bow, bow attacks starts. I’ll add more items in the future (potions, spells, etc.) and they’ll have scripted use functions too. This makes code a lot better than it have used to be (all items were hard-coded!)

And I’ve made scripted attacks. They works almost the same as script states (enter, execute, exit functions). I’ve also added pre/post attack animations which make attacks look a lot better visually.

Arrows are entities like any other but with some cool scripting. They are a great example of how awesome Lua scripting is! I had realized that I can implement arrows using scripts without using C++ code. And I did.

You can find more info and some scripts here.

Level chunks

I’ve remade level rendering method. Instead of using lots of sprites for each tiles, I use chunks. Chunk is a collection of sprites which has sf::VertexArray. This lets me draw levels in chunks instead of drawing in tile by tile. A lot less draw calls! Draw calls are very expensive compared to other stuff so this is a big perfomance improvement and level rendering is 3 to 4 times faster now!

Storing level in form of chunks is useful too, because I don’t need to store lots of empty areas in level file now. Previously, level was a big 2D array, so I needed to keep data about empty spaces to save its form. But looks how many empty spaces there may be in one level. And it’s just a small example. Now I don’t need to save empty chunks to file so it’s a lot more efficient method of storing level data.

What’s next?

Not much in next month, unfortunately. I’ll have lots of exams and I need to spend lots of time studying to do good. But I’ll not forget about my game during this month. I’ll prototype some stuff, think about new puzzles and draw some concept art from time to time.

And that’s it. When I was writing this post, I’ve realized that last two months were one of the most productive months in my life. So much stuff done! I hope you’ve enjoyed this post.

If you want to follow my gamedev process more closely, you can follow me on twitter or read my dev log on SFML forums!