• Register

Re:creation is an action adventure game where you play as an undead knight. You can kill enemies and then control them with your ghost to use their abilities to solve various puzzle. Your main quest is to show that undeads are actually not bad and don't like hurting people. You do this as you try to stop evil Necromancer King who uses undeads as slaves and tells people lies about undead people. The game is being developed by Elias Daler (@eliasdaler).

  • View media
  • View media
  • View media
  • View media
  • View media
  • View media
Post article RSS Articles

Read this post on my blog here.

The last few months I was very busy finishing my bachelor’s degree (it’s over, I got an “A”!). But still, I’ve managed to do some cool stuff and improve the engine structure and tools in the last couple of months.

This dev log will be released in two parts. In this part I’m going to talk about game stuff I did and stuff I changed about Lua/C++ integration. In the second part I’ll talk about engine tools I’ve made with ImGui and different refactoring I’ve done.

Game stuff

Here’s one of the latest screenshots of the game. Houses were previously just big sprites, but right now they’re composed out of tiles which lets me reuse them for other houses and build new buildings more quickly.

i2yn8x4


The main character got some graphics improvements!

xqtlpud


Now he looks a lot more undeadly and has some awesome confidence in him! You’ll still sometimes see old character sprite occasionally because I haven’t redrawn all character animations yet.

s1kfulv


And here’s some fun little cutscene I’ve made for testing new Action List system (see below for more details about action lists)

There’s some awesome ideas and prototype stuff I have done but don’t want to show yet. :)

Lua changes

My scripting approach changed a lot during the last few months. One of the reasons for that change was the observation that calling Lua from C++ takes a really long time compared to calling C++ from Lua. I wrote about it in the last dev log, but now I’ll write a bit more about that.

Remaking event manager in Lua

I’ve previously implemented a simple event manager in C++ and it worked great. You registered callbacks for event types, you queued events and then event manager looped over event queue by calling registered callbacks.

But what about Lua? I’ve approached this in straightforward way at first: by storing references to Lua functions and calling them on particular event.
This worked well, but wasn’t quite as fast as I expected. I realized that the approach must differ depending on type of callback:

  • What if callbacks are C++ functions?
    Easy, I just used std::function for them. C++ being called from C++, what can be better?
  • What if callbacks are Lua functions?
    Basically, I had a situation like this:

    for(auto& event : eventQueue) {
        ... // call Lua callbacks
    }

    See the problem? If eventQueue is big or there are lots of callbacks to be called, Lua is going to be called a lot from C++ and that’s slow. There’s a better way to do this: pass array of events in Lua function and then call all Lua callbacks there:

    luaProcessEvents(eventQueueLuaTable); // in C++

    -- in Lua
    function EventManager:processEvents(events)
        for _, event in ipairs(events) do
            ... -- call Lua callback
        end
    end

Interestingly enough, this made a huge difference in performance! That’s because if I had to call 20 Lua callbacks with old approach, I’ll do it in 20 C++ -> Lua calls, but now it’ll just be one Lua call to EventManager:processEvents and every callback will be called from there, and now there’s no need to store Lua callbacks in C++ and no need to call Lua from C++ for each callback. Neat!

Of course, now I had to store Lua callbacks in Lua. It makes sense, doesn’t it? That’s why there’s now two event managers: C++ event manager and Lua event manager. They work quite well together.

Remaking entity states in Lua

Previously some entity states (states as in state machines) were hard coded in C++.

This wasn’t quite what I wanted, so I’ve managed to create script states for new states which I didn’t want to write in C++ (See Advanced Script Machines section here). But then came the old problem: lots of C++ -> Lua calls, because sometimes state has to do something in each frame.

The answer came naturally: I just implemented Entity State Machine in Lua! But then I realized that I could just move all entity states in Lua to make my life easier. And now there’s only a tiny bit of game logic left in C++! Most of it is in Lua and it’s great: this allows me to write stuff more quickly and create as much states as I want without recompiling.

Action Lists in Lua

Action lists were a great addition to scripting in my game. This allowed me to easily create sequences of actions which are meant to be done one after another. It’s not as easy as it may seems at first.

Quick recap of what action lists do. Suppose you want to do some cutscene like this:

  • Hero goes to a point on the map
  • Breaks the door
  • Says “hello”
  • Sits on the chair

You can’t just do it like this:

-- inside some Lua function
hero:goTo(somePoint)
hero:break(theDoor)
hero:say("Hello")
hero:sit(theChair)

That’s because some actions will take more than one frame so you can’t just call one function after another. You can do that only when the action is finished. And that’s where Action Lists are used. You create a list of events and then the first action starts to execute. Action list manager repeatedly checks if the action is finished.

For example, GoToAction checks if the entity arrived at the destination. If it did, the action is considered to be finished and the next one executes.

Previously all actions were implemented in C++, but I could provide some Lua functions to be called at the beginning or at the end of the action. Action lists were created in Lua as tables which were then converted to C++ instances of Actions.

But then I realized: why do I need C++ here? What if I implement all Actions in Lua and then call each Action List’s execute function inside some ActionListManager:update? And that’s what I did! Now all actions and action lists are implemented, created and stored in Lua! The implementation is much easier to modify, expand and use.

At one point I needed some Lua OOP lib for implementing stuff and I used middleclass for that.

Here’s an example of DelayAction in Lua:

local Action = require("action")

local DelayAction = class("DelayAction", Action)

function DelayAction:initialize(params)
    Action.initialize(self, params)
    self.time = params.time
    self.currentTime = 0
end

function DelayAction:update(dt)
    self.currentTime = self.currentTime + dt
    if self.currentTime >= self.time then
        self.isFinished = true
    end
end

return DelayAction

This action just waits for specified amount of time and then is marked as finished when the time passes. It can be created like this:


local action = DelayAction { time = 500 } -- wait for 500 ms

Note: DelayAction{…} is equal to this function call: DelayAction({…}) just in case you’re confused. I didn’t know about that Lua allowed this for a long time.

And here‘s another, more complex example with lots of different actions being done.
The gif below shows how each action of this ActionList are executed in a cutscene:

lgaocuw


What’s great is that new action types can easily be added in Lua which allows fast iteration for me and some great modding capabilities in the future!

Writing Lua is easy and relaxing

Rewriting stuff from C++ to Lua and writing new stuff purely in Lua was a great experience. In the past I’ve used Lua mostly just for calling C++ stuff, but now I’ve realized that I can actually do a lot more in Lua. And writing pure Lua code is amazingly fast compared to C++. It’s more compact too sometimes. Just by rewriting C++ stuff in Lua, I’ve got rid of ~1.5k lines of code!

It’s hard to explain what makes Lua so easy to write compared to C++, probably it has to do something with dynamic typing (imagine if auto and function templates very everywhere), heterogeneous containers (tables), awesome arrays and really cool dictionaries (tables again!).

Someone said that writing Lua is pretty close to writing pseudo-code and I fully agree. Sometimes I just write some pseudo-code which is close to Lua and then I realize that I can easily transform it into valid Lua code just by doing some small modifications. Isn’t that amazing?

Burning bridges and praising the Sun

cmb0ifbxeaeeewb


LuaBridge was a Lua/C++ binding library I’ve used for a very long time. It was pretty great, but certainly wasn’t perfect and had some pretty serious faults. Recently I’ve come across amazing library called sol2 and it amazed me right away.
It has everything I ever wanted from Lua/C++ binding library and even more! It isn’t perfect, but it does everything that I need and it does it pretty fast.
There’s a lot of stuff to be said about what sol2, but I think I’ll devote an entire article to it.

Right now I’m helping The PhD (the creator of sol2) to make the library better. The amount of work being done on the project by him is just incredible and there are some changes I’ve proposed that already became part of the library.

Still, here are some things I like about it:

  • Written in modern C++, no crazy macros needed
  • Currently maintained and expands very quickly
  • Has lots of features which lots of libraries don’t have
  • Very fast!
  • Has very clean and simple interface. Lua stack is completely hidden from you
  • Works with Lua 5.1-5.3. and LuaJIT without noticeable differences

Sol2 is pretty close to being the best Lua/C++ library ever.

I’ve managed to port all my Lua/C++ code from LuaBridge to sol2 in a couple of hours thanks to wrappers I’ve made around LuaBridge. I’ll show how they work and why you should make them in the next Using Lua with C++ in Practice article.

End of part 1

That’s it for now, thanks for reading!
The next part as I said will be about in-game dev tools and some major C++ refactorings I’ve done. See ya!

Don’t miss the second part by following me: @EliasDaler

Re:creation dev log. January-February 2016. Better art, sounds

Re:creation dev log. January-February 2016. Better art, sounds

News 3 comments

Two months have passed since the last dev log. I had lots of time to work on the game and here’s what I’ve managed to work on... Cutscenes, Lua/C...

Progress update (January 2016)

Progress update (January 2016)

News 2 comments

Redrawn lots of art, cutscene system, items that you can pick up!

Re:creation dev log. 2015. The most productive year yet

Re:creation dev log. 2015. The most productive year yet

News 6 comments

I talk about the stuff I've done in 2015. It has been a great year!

Re:creation dev log. November 2015. Epic refactoring, shadows and more!

Re:creation dev log. November 2015. Epic refactoring, shadows and more!

News 4 comments

Here's the stuff I did this Novemeber. I've remade lots of stuff in the engine and made the game prettier by adding shadows and other cool stuff

Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.

Follow Report Profile
Icon
Re:creation
Platforms
Windows, Mac, Linux
Creator
eliasdaler
Engine
SFML
Contact
Send Message
Release date
Game watch
Follow
Share
Style
Genre
Adventure
Theme
Fantasy
Players
Single Player
Project
Indie
Twitter

Latest tweets from @eliasdaler

Ever experienced the folowing? 1) See someone's great blog post 2) Read other stuff from there, be impressed 3) De… T.co

Jan 17 2019

RT @EliasDaler: Eliasdaler.github.io First dev log of Tomb Painter is here. Here's what I've been working on for the last 1.5 y… T.co

Jan 17 2019

RT @ocornut: dear imgui 1.67 released: tabs, font atlas fixes, reszing from edges and dozens of other additions and fixes.… T.co

Jan 14 2019

Eliasdaler.github.io First dev log of Tomb Painter is here. Here's what I've been working on for the last 1.5 y… T.co

Jan 6 2019

I'm finally doing it! Publishing tomorrow. Stay tuned :) #gamedev #indiedev #TombPainter T.co

Jan 5 2019

Embed Buttons
Link to Re:creation by selecting a button and using the embed code provided more...
Re:creation
Statistics
Last Update
Watchers
44 members
Articles
7
You may also like