SFML community forums

General => SFML projects => Topic started by: Elias Daler on May 02, 2015, 04:05:52 pm

Title: Re:creation - a top down action adventure about undeads [hiatus]
Post by: Elias Daler on May 02, 2015, 04:05:52 pm
(http://i.imgur.com/By9ICGM.png)

Site: https://eliasdaler.github.io/re-creation
Developers: Elias Daler (https://twitter.com/EliasDaler) (programming, art, game and level design, story, etc.), Torchkas (https://twitter.com/Torchkas) (music and sound effects)
Dev logs (old): https://eliasdaler.wordpress.com/tag/devlog/
Dev logs (new): https://eliasdaler.github.io/tags/#Dev+log
Progress screenshot album: http://imgur.com/a/luoFe
Twitter: @eliasdaler (http://twitter.com/eliasdaler)
Platforms: PC, Mac, Linux
Release date: When it's done

(http://button.indiedb.com/popularity/medium/games/42897.png) (http://www.indiedb.com/games/recreation)

The coolest screenshot yet (January 2016):
(http://i.imgur.com/n3eUCxD.png)

Hello, my name is Elias Daler and this will be a dev log of my game!
I'm a solo hobby developer and work on the game in my free time so the progress won't be very fast I hope I'll post some interesting stuff from time to time! You can read previous dev logs here (https://eliasdaler.wordpress.com/tag/devlog/).

The development of this game started in October 2013.
I'm writing the game in C++ and use SFML. I also use Lua for scripting. I'll try to explain how my game works in next posts. I'll write about how I use scripting, how my entity/component/system works and lots of more programming stuff!

Story
The main hero is an undead knight who was betrayed by his partner, Necromancer, during a fight with a giant demon. When the hero raises from the dead, he realizes that lots of time has passed since his death. The Great War between humans and undeads is being fought for several centuries. Necromancer is still alive. He actually became a Lich. He has lots of power and uses undeads as a cheap working force. The hero explores society of undeads and finds out that they don’t actually want to kill humans. They just don’t want people to use them for training and steal their treasure! The hero decides to stop the war and prove that undeads are not that evil as it seems.

(http://i.imgur.com/vg6jQ0x.gif)
Undead City becomes hero's new home.

Gameplay
The gameplay is very similar to top-down 2D Zelda games with the exception of the main mechanic of the game, called recreation.
At any point of the game, you can become a ghost and travel through objects easily.
You can also control enemies you killed with it to get their abilities and solve various puzzles. Here's how it works:

(http://i.imgur.com/qKa48U9.gif)

You can't carry any weapons other than a hammer in the game, so you need to control enemies with bows to be able to use arrows, enemies with shields, to be able to block attacks etc. If you're killed when you're controlling someone else, your ghost will automatically return to your body and the person which you were in will respawn shortly after (because you can't solve some puzzles without other bodies).

Here's are some puzzles which you can solve with recreation mechanic:

(http://i.imgur.com/pQ9culg.gif)

(http://i.imgur.com/u9CYS5p.gif)

Other gifs / screenshots:

(http://i.imgur.com/u8G0Opu.gif)
NPC's are interesting...

(http://i.imgur.com/W8VL5i7.gif)
Hero reacting to items he gets from chests

(http://i.imgur.com/RdZvdlI.gif)
Boss fight

As this is the first post, I'll edit it from time to time to add the latest and coolest screenshots and gifs.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 02, 2015, 05:17:11 pm
This is very outdated and doesn't reflect the state of the project well. I'll write about current architecture some day! (Posted on 21-02-17)

Some programming stuff.

I use C++11 with SFML and Lua for scripting. The most important aspect of the engine is entity/component/system model. Here's my implementation of it.
Entities are different objects in the game: characters, houses, items, etc.
Each entity has unique id (which is used to identify them) and a number of components.
So, characters have: GraphicsComponent, MovementComponent, CollisionComponent, HealthComponent, etc.
Static objects don't need all of that so they only have GraphicsComponent and CollisionComponent.

So, entities are made from "blocks". Those blocks can have unique behaviour by scripting. But I'll talk more about that later.

Basically, it looks like this in code:

class Entity {
public:
    ... // some stuff
private:
    int uid;
    std::vector<std::unique_ptr<Component>> components;
    ... // some other stuff
};

Component is simply a collection of data. For example, GraphicsComponent holds sprite and other stuff related to graphics, MovementComponent has velocity, etc.-etc.

Systems operate on components. Basically most of the game logics is there.
For example, MovementSystem iterates over MovementComponent's of active objects and adds  to a current position for each entity. Most systems operate on one type of component and it doesn't matter to them what entity any component belongs to. This makes adding new types of entities easy as I don't have to change logics very often.

Entity definitions are stored in Lua scripts. Here's an example of a chest entity: http://pastebin.com/P3mAD8NN
As you can see, every component parameter is here but I can also define functions in Lua script. This let's me specify object behaviour so it's not hard coded in C++! This is very useful as I don't have to recompile the game very often.
Lots of Lua function have bindings to functions in C++, so I can use this function in a script:
setAnimation(someEntity, "animationName")
which will call this function in C++
void setAnimation(ind entityId, const std::string& animationName) {
    auto e = engine_system.em->getEntity(entityId);
    ... // code to set animation
}

Notice, that I don't pass around pointers or entity references but instead pass ints which is faster.
Getting entity from id is also fast, as each entitiy is stoped in a hash map and can be quickly accessed by unique id.

Once the entity templated is loaded in C++, every entity of this "class" is created with the template which is a lot faster than reading properties from scripts over and over.

There's some basic support for "inheritance" so if some entities have lots in common, they can use other entities properties, overwrite some properties and add new components.
Here's an example of that a chest that uses different sprite:  http://pastebin.com/6pQKJz5P
As you can see, there's no need to copy-paste everything, I can just change some of the parameters, the rest will be copied from base entity.

(https://i.imgur.com/aMK1rfA.png)
Chest vs super_chest. The only thing different is the graphics and size.

(You can read more about inheritance and scripting here (https://eliasdaler.wordpress.com/2015/03/30/recreation-dev-log-march-2015/))

My game also has in-game level editor.
(http://i.imgur.com/rjedWLB.gif)
Bigger gif: http://i.imgur.com/8HtWIYU.webm
It has lots of features: tile map editing, multiple object selection and moving, object creation, undo, etc.

And that's basically it. If you have some questions, feel free to ask!
(I'll write about messaging between systems, events and decoupling soon!)
Title: Re:creation - a top down action rpg about undeads
Post by: Raincode on May 02, 2015, 06:13:00 pm
This looks pretty awesome! I could imagine it was a lot of work. When did you start it? Do you have some screenshots from earlier development stages?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 02, 2015, 06:39:13 pm
This looks pretty awesome! I could imagine it was a lot of work. When did you start it? Do you have some screenshots from earlier development stages?

Thanks a lot! I've started it in October 2013 (should probably add this to the first post, ha-ha).
Here (http://imgur.com/a/luoFe#86) is a progress album of my game. (I'll add it to the first post too)
Title: Re:creation - a top down action rpg about undeads
Post by: Cirrus Minor on May 02, 2015, 07:11:59 pm
It looks really nice and fun!
Are you making the 2D-art?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 02, 2015, 08:47:04 pm
It looks really nice and fun!
Are you making the 2D-art?

Thanks! Yes, I do. I would love to have an artist working with me, but I don't have money or artistic friends, so the only thing left to do is to do my own art. :D
Title: Re:creation - a top down action rpg about undeads
Post by: Lo-X on May 02, 2015, 11:09:33 pm
The game looks awesome but your post also is!

I'm very interested in reading more about systems and how they communicate with each other. I'm also interested in the Lua binding (what did you use, what did you bind).

What do you think about getting rid of the Entity class and just store arrays of components indexed by the entity ID ? It's something I read a lot about.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 02, 2015, 11:42:40 pm
The game looks awesome but your post also is!

I'm very interested in reading more about systems and how they communicate with each other. I'm also interested in the Lua binding (what did you use, what did you bind).
Thanks!

I use LuaBridge for binding. It's a fantastic and easy to use library and I've also written two articles about it on my blog. :)
I'm binding any function which needs to be called from the scripts. For example, here's how setVelocityX function looks in C++:

void setVelocityX(int entityId, float vx) {
    auto e = engine_system.em->getEntity(entityId);
    auto mc = e->get<MovementComponent>();
    if(mc) {
        mc->setVX(vx);
    } else {
        engine_system.log->write("Entity named" + e->getName() + " doesn't have MovementComponent!", LogManager::ERR);
    }
}

Then I can use LuaBridge and just write
getGlobalNamespace(L).addFunction("setVX", setVelocityX)

And then call it in scripts, for example in init() function (stored in entity template table) which is called when the entity is created:

init = function(this)
    setVX(this, 0.05)
end

So, when I call any Lua function, I pass entity id as a parameter which is later used to get entity in C++ after Lua function calls some C++ functions.

What do you think about getting rid of the Entity class and just store arrays of components indexed by the entity ID ? It's something I read a lot about.

I'm thinking about it and this can be a lot more efficient than what I use now. (Faster iteration, less cache misses, object pools...)
And I'll possibly implement it this way at some point in future and I won't have to change lots of code. (There's no need for it now though, as I don't see any perfomance related issues with the stuff I have now).
The only thing which I can't figure out is how to actually create arrays for each component and then easily get it.
For example, suppose I want to be able to get some component this way:
auto mc = get<MovementComponent>(entityId);
So, I need some kind of type/component array mapping. And while the key can be a std::type_index, what will the value of the map be? I can't store arrays of different types in one std::map.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on May 03, 2015, 01:31:46 am
As I've understood, one way of doing it is by having each System own an array of the Component it manages.

Something like:
template<typename T, typename std::enable_if<std::is_base_of<Component>::value>::type* = nullptr>
class System
{
      public:
            System();
           
            virtual void update(float dt) = 0;
           
            T& get(int idx);

      private:
            container_of_your_choice<T> components;
};
 

Something like that. It can be pretty much however you want of course.
Then just derive from that for each System/Component type, implement any virtual functions you have, and there you go.

So like:
class GraphicsSystem : public System<GraphicsComponent>
{
      // stuff goes here...
};
 

I'm planning to adjust my own code base to something like this soonTM.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 03, 2015, 08:39:41 am
I've done this before, but this led to another problem: I couldn't store Systems in one collection and had to update them like this:
void EntityManager::update() {
    renderingSystem->update();
    collisionSystem->update();
    ... // etc.
}
So, every time I add a new system, I need to add it to update, process and other
 functions, because I can't just iterate over all of them. (And I had to insert it in particular order everywhere, because it matters)

I have this instead now, because I have a base class EntitySystem and std::vector<EntitySystem*> systems:
void EntityManager::update() {
    for(auto it != systems.begin(); it != systems.end(); ++it) {
        (*it)->update();
    }
}

RenderingSystem looks like this, for example:
class RenderingSystem : public EntitySystem {
public:
    ...
private:
   std::vector<GraphicsComponent*> components
}
So, every system has it's own vector of components (and if systems needs to operate on two different types of components, it can!), but I still can store systems in one place and easily add new systems.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on May 03, 2015, 07:56:31 pm
Ah. I see. Well, I guess you could then have a BaseSystem class of sorts that System<T> inherits from, and then have a container of BaseSystem*s or something, if each System<T> is all going to have the same functions. Then you could iterate over all the systems. And just add them to the container in the order you need them to update.

Though I do like your method as well.

It's interesting to see the different methods people come up with!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 04, 2015, 10:55:37 am
That's a good suggestion, maybe I'll try it out someday. :)

And I love to see different ways of doing stuff, I hope my dev log will inspire others and they'll show off their ways of doing things.
Title: Re:creation - a top down action rpg about undeads
Post by: ChronicRat on May 04, 2015, 11:11:47 am
Cool, I don't like "pixel" styled games but this one is really fun.
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on May 04, 2015, 12:08:18 pm
This looks stunning! :-)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 04, 2015, 01:32:11 pm
Cool, I don't like "pixel" styled games but this one is really fun.

Thanks! I use pixel art because creating high-res art is really hard while working solo. It also looks less professional when done by not very skilled artist. I try to make my pixel art look unique, though!

This looks stunning! :-)
Thanks a lot! :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 05, 2015, 12:41:52 am
(http://i.imgur.com/4ujBOn8.gif)
Made smooth level transition. Area name is displayed.
Title: Re:creation - a top down action rpg about undeads
Post by: fakepotato on May 05, 2015, 02:23:22 am
Awesome ... just have no other words to express my feelings about this...
And your second post forced me to acknowledge component-based system and LUA-scripts.
It's really inspiring thread!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 05, 2015, 07:50:53 am
Awesome ... just have no other words to express my feelings about this...
And your second post forced me to acknowledge component-based system and LUA-scripts.
It's really inspiring thread!

Thanks!
ECS and scripting are one of the greatest things ever. They make code a lot cleaner and flexible. If you have some questions about implementation, feel free to ask!
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 05, 2015, 01:28:43 pm
Pretty great project! Do you do all gameplay logic in systems? You always process your game data in a serial fashion, rather than the old inner object logic?

Also, each system gets its own storage container of components it acts on?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 05, 2015, 02:27:51 pm
Pretty great project! Do you do all gameplay logic in systems? You always process your game data in a serial fashion, rather than the old inner object logic?

Also, each system gets its own storage container of components it acts on?

Thanks!
No, not all logic is in systems. There are also some common Entity state classes (idle, attack, move, dying, falling, etc.) which have a bit of gameplay logic. And there is also gameplay logic in scripts because some entities have unique behaviour which needs to be scripted. For example, the witch in Undead City which turns pages in the book, her behaviour is not just a simple animation: it's scripted (here's the script (http://pastebin.com/9B3rnyDm)).

Most data is scripted but there's some data which is stored in C++ code. This is mostly temporary because making this data scriptable takes some time, it's just faster to write non-scripted code.

Systems have vectors of pointers to components. When entity is created, it's passed in each system which checks if it has component the system uses. If entity has one, system adds pointer to the component to the vector. This is not the ideal way of doing things, but it works pretty good for now.
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 05, 2015, 02:38:36 pm
Thanks for your answer. You are a very sensible engineer, you only deserve praise here :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 05, 2015, 02:43:40 pm
Thanks for your answer. You are a very sensible engineer, you only deserve praise here :)

No problem. Thank you. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on May 06, 2015, 05:32:19 pm
Wow. This looks amazing.
Well done.
Title: Re:creation - a top down action rpg about undeads
Post by: iride on May 06, 2015, 05:37:19 pm

I'm thinking about it and this can be a lot more efficient than what I use now. (Faster iteration, less cache misses, object pools...)
And I'll possibly implement it this way at some point in future and I won't have to change lots of code. (There's no need for it now though, as I don't see any perfomance related issues with the stuff I have now).
The only thing which I can't figure out is how to actually create arrays for each component and then easily get it.
For example, suppose I want to be able to get some component this way:
auto mc = get<MovementComponent>(entityId);
So, I need some kind of type/component array mapping. And while the key can be a std::type_index, what will the value of the map be? I can't store arrays of different types in one std::map.

The way i implemented that is assigning unique ids(starting at 0) to each component at compile time.
Then you store these components in a vector.
Then you can retrieve each component by its id.
If an entity doesn't have that component, it can return nullptr.

template <class C>
C * get(int id)
{
     std::vector<Component*> & v = getComponentsofEntity(id);
     return static_cast<C*>(v[C::getUniqueID()]);
}
 
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 06, 2015, 05:40:55 pm
Damn, this game is ridiculously amazing. It honestly looks like the sort of gameboy game that I would still buy. I tried to make something similar a couple of years ago. Two years and 14000 lines of code later, it is pitiful compared to this. I am amazed by the quality of things like this that people put on here.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 06, 2015, 06:33:51 pm
@Jesper Juhl Thanks a lot!

@iride That's almost how I do it now (I use dynamic_cast instead of component ids, though. But we were talking about components being stored in arrays of particular component type. Something like std::vector<GraphicsComponent>, std::vector<MovementComponent>, etc. Getting components from there is an issue.

@shadowmouse
Thanks! That's my biggest project ever. 20k lines of code and still doing well. It's mainly because of scripting and ECS, I think. If I tried to use OOP for this, I wouldn't be able to progress that far. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 07, 2015, 02:17:35 am
I am dying to see how the game will play. I am so supporting this :D

btw, my first serious game also had 20k loc, but didn't get to be as clean or good as yours, unfortunately :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 07, 2015, 07:55:42 am
@Grimshaw Thanks! Glad to hear it. :)

Progress update.

Okay, so arrows are not hard coded anymore!
(http://i.imgur.com/LxUaeEW.gif)
I've added some of Lua/C++ binding functions to be able to script arrows. Here's how item system works now.
Each item has its "use" function which gets called every time player or entity uses an item. In case of bow, "use" function sets player in AttackState and sets current attack to "bow_attack".
Each attack has its enter, execute and exit functions. Enter function is called when the attack starts, execute function gets called every frame during the attack and exit function is called when the attack stops.

In case of bow_attack, its "execute" function looks like this:
execute = function(vars, owner)
    if(getCurrentAnimationFrame(owner) == 1 and not vars.createdArrow) then
        arrow = createEntity("arrow", getPosition(owner))
        setChildEntity(owner, arrow)
        setDirection(arrow, getDirection(owner))
        setScriptState(arrow, "IdleState")
        vars.createdArrow = true
    end
end
Arrow is not created when bow animation starts. Animation has a little delay.
vars is a table which gets created when attack starts. It can be used to store variables in different parts of attack scripting code. When this function is called the first time, vars.createdArrow is nil, but when vars.createdArrow = true line is called, variable "createadArrow" is created in vars table which I can later use to not create arrows twice (player animation can be on second frame of animation for some time).

Arrow scripting code is a bit trickier. Here's how its ScriptStateMachineComponent looks:
ScriptStateMachineComponent = {
    states = {
        IdleState = {
            enter = function(self, entity)
                direction = getDirection(entity)
                moveSpeedX = getMoveSpeedX(entity)
                moveSpeedY = getMoveSpeedY(entity)
               
                setAnimation(entity, "idle." .. direction)
                setDamageDirection(entity, direction)
               
                if(direction == "Up") then
                    setVelocity(entity, 0.0, -moveSpeedY)
                    setDamageRect(entity, 0.0, 0.0, 9.0, 4.0)
                elseif(direction == "Down") then
                    setVelocity(entity, 0.0, moveSpeedY)
                    setDamageRect(entity, 0.0, 8.0, 9.0, 4.0)
                elseif(direction == "Left") then
                    setVelocity(entity, -moveSpeedX, 0.0)
                    setDamageRect(entity, 0.0, 0.0, 4.0, 9.0)
                elseif(direction == "Right") then
                    setVelocity(entity, moveSpeedX, 0.0)
                    setDamageRect(entity, 0.0, 10.0, 4.0, 9.0)
                end
               
                playSound("res/sounds/arrow_shoot.wav")
            end,
            execute = function(self, entity)
            end,
            exit = function(self, entity)
            end
        },
        StuckState = {
            enter = function(self, entity)
                setAnimation(entity, "stuck." .. getDirection(entity))
                startTimer(entity, "killTimer")
                setVelocity(entity, 0.0, 0.0)
                disableComponent(entity, "CollisionComponent")
                disableComponent(entity, "DamageComponent")
            end,
            execute = function(self, entity)
                if(timerFinished(entity, "killTimer")) then
                    killEntity(entity)
                    stopTimer(entity, "killTimer")
                end
            end,
            exit = function(self, entity)
            end
        },
    }
},
It's mostly self explanatory. There's some other code for arrow collision and damaging, but I won't post it as its pretty obvious. :)
Title: Re:creation - a top down action rpg about undeads
Post by: ChronicRat on May 07, 2015, 12:27:48 pm
Lua is beautiful. Do you use some sort of OOP realisation under Lua or only table like these?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 07, 2015, 01:20:50 pm
Indeed. Tables are pretty much enough for such tasks. If I need to get some values from them in C++, I can easily do it with LuaBridge. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 07, 2015, 02:32:13 pm
Do you actually find Lua beautiful?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 07, 2015, 02:58:18 pm
Do you actually find Lua beautiful?
Yeah. It's simplicity is pretty great. Speed is another cool thing about it. And it's pretty easy to bind Lua with C++ using binding libraries.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on May 07, 2015, 07:31:38 pm
I just noticed that you use parentheses around the condition in if statements in Lua, is that a style preference?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 07, 2015, 08:32:06 pm
Added archers!
(http://i.imgur.com/LNGqqXe.png)

dabbertorres, yeah, it's just easier to find the condition visually.
Title: Re:creation - a top down action rpg about undeads
Post by: Ricky on May 07, 2015, 09:41:38 pm
Do you actually find Lua beautiful?
Yeah. It's simplicity is pretty great. Speed is another cool thing about it. And it's pretty easy to bind Lua with C++ using binding libraries.

I was using LuaGlue for a bit but the project owner hasn't updated in a while and LuaBridge also allow JIT
Title: Re:creation - a top down action rpg about undeads
Post by: ChronicRat on May 08, 2015, 06:43:55 am
Do you actually find Lua beautiful?
What else could be simpler, smaller and faster? Lua is ideal! =)
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 08, 2015, 01:58:56 pm
simpler smaller and faster, its debatable but I can agree on, but I was asking about beautiful.. it looks like the ugliest thing ever to me, despite knowing its advantages and having used it before
Title: Re:creation - a top down action rpg about undeads
Post by: ChronicRat on May 08, 2015, 03:04:58 pm
It looks like you just never met ugly code. =) And Lua code by Elias Daler is really good.
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 08, 2015, 05:25:14 pm
Call me biased but I am just more of a C style syntax man :p
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 09, 2015, 07:27:47 am
By the way, here's a new gameplay gif!
You can't carry bows or any other weapons other than your hammer (it's too heavy!).
So, in order to shoot arrows, you need to kill archers and control them with your ghost. Also, ghost can fly which helps too.
(http://i.imgur.com/jJ0qLxR.gif)
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 09, 2015, 02:16:49 pm
That ghost idea is really cool! Looking forward to feel how it plays :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 09, 2015, 11:40:33 pm
Thanks!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 14, 2015, 07:47:30 am
Don't have much time to work on the game this games (lots of study!).
But I've recently optimized level drawing a lot. I was using sf::Sprite for each tile and was drawing every one of them seen on the screen. Now I use chunks of sf::VertexArray. This improved rendering perfomance by 4x-5x which is very awesome.
(http://i.imgur.com/rkz3gmu.png)
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on May 14, 2015, 12:44:30 pm
Did you really struggle to render a few sprites on the screen? This kind of game usually needs no optimization in rendering, modern cards hold a lot more draw calls than that :D
Title: Re:creation - a top down action rpg about undeads
Post by: fakepotato on May 14, 2015, 04:28:50 pm
Your tutorials about Lua bindings are awesome.
I have question, though. What about security? Everyone can see and edit scripts.
You recommend encode them to binary/resource files, or compile as libraries? What's your method?
As far as i know, your re:creation game won't be open source, so i suppose you solved that problem somehow to hide realization from users.
Thanks for replies  :)
Title: Re:creation - a top down action rpg about undeads
Post by: Lo-X on May 14, 2015, 05:17:16 pm
You recommend encode them to binary/resource files, or compile as libraries? What's your method?

I don't know what he does but Lua is "compilable" with luac
Title: Re:creation - a top down action rpg about undeads
Post by: fakepotato on May 14, 2015, 05:25:32 pm
So luac is 100% safe?
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on May 14, 2015, 05:40:02 pm
Are you trying to say that you think something is "safe" (from tampering) because it is in binary and not script form?  If so, you are mistaken - and that goes for not just lua but your c++ object files as well.
Title: Re:creation - a top down action rpg about undeads
Post by: Ricky on May 14, 2015, 06:05:56 pm
So luac is 100% safe?

I say embrace modding because just look what it did for Minecraft. It helps build a community around your product and also means that the community is making content that you don't have to and you still make sales!

I'd totally let the community tear the game apart and do what they wanted.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 14, 2015, 06:23:52 pm

 
Did you really struggle to render a few sprites on the screen? This kind of game usually needs no optimization in rendering, modern cards hold a lot more draw calls than that :D
Nah, it was running in 60 FPS all the time. Rendering was just taking too long compared to other stuff and I've thought I could optimize it a bit. This chunk system even helped me realize how to store levels more efficiently so it's a double win!

Your tutorials about Lua bindings are awesome.
I have question, though. What about security? Everyone can see and edit scripts.
You recommend encode them to binary/resource files, or compile as libraries? What's your method?
As far as i know, your re:creation game won't be open source, so i suppose you solved that problem somehow to hide realization from users.
Thanks for replies  :)
Thanks!
I have no problems with users reading and editing my scripts. I can say I even embrace that. Modding is awesome (this is what got me into gamedev!) and I'll do some stuff to help modders mod my game if they show some interest in it (some documentation, some tools like level editor, etc.). I think it's a good thing that people may use my scripts because it may help them improve their scripting or see awesomeness of Lua!
As for luac... Maybe I'll use it if scripts slow down my game. But it makes modding harder which is not what I want. :)

So luac is 100% safe?

I say embrace modding because just look what it did for Minecraft. It helps build a community around your product and also means that the community is making content that you don't have to and you still make sales!

I'd totally let the community tear the game apart and do what they wanted.

Totally agreed!
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 14, 2015, 06:39:43 pm
Can you tell me the advantages of using scripts instead of just writing it in c++? I was just thinking how hard can it be to just translate the lua into c++ and then not have to use another language.

P.S. I'm pretty sure you've been stealing my ideas directly out of my head, because about a year ago, I was going to make a game which used a similar game mechanic as the game, but with a different context, I never told anyone about it, didn't finish or post it, and then a year later you've made what looks like a brilliant game based around a concept I couldn't be bothered to make the artwork for.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 14, 2015, 07:13:16 pm
Can you tell me the advantages of using scripts instead of just writing it in c++? I was just thinking how hard can it be to just translate the lua into c++ and then not have to use another language.
The main advantage is getting rid of hard coded values and hard coded gameplay logic in C++. Scripts make your code a lot more flexible (no need to recompile if you change anything in them). They are also useful in Entity/Component/System because you can't create a class for each type of an entity and writing lots of if/else stuff for different objects is just awful.
So, for example, when I have objects which will behave uniquely if you collide with them, I just write a script function and it gets the job done.

P.S. I'm pretty sure you've been stealing my ideas directly out of my head, because about a year ago, I was going to make a game which used a similar game mechanic as the game, but with a different context, I never told anyone about it, didn't finish or post it, and then a year later you've made what looks like a brilliant game based around a concept I couldn't be bothered to make the artwork for.
Great minds think alike, haha! Thanks. :)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 14, 2015, 07:17:22 pm
Ah I think I get what you're talking about. Well, I get why you do it anyway, I don't think I'll ever leave pure c++ because I prefer the object orientated style, where I give classes identifiers so the in the given example, the class can tell whether or not the think it collided with is special. Oh, and for the record, I think your way of controlling enemies is better than mine because mine was something like venom from spiderman in that you played as a symbiotic goo and so I would have had to draw a player controlled version of every enemy instead of your way of just controlling them.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on May 14, 2015, 07:20:30 pm
What about security? Everyone can see and edit scripts.
You recommend encode them to binary/resource files, or compile as libraries? What's your method?

There are plenty of Lua decompilers out there, and the output tends to be pretty straightforward.

Can you tell me the advantages of using scripts instead of just writing it in c++? I was just thinking how hard can it be to just translate the lua into c++ and then not have to use another language.

1. You don't have to recompile the whole game every time you make a change.

2. Lua is more flexible than C++ in some ways, which can make some tasks easier to accomplish in Lua.

3. Lua is a higher-level language than C++, generally, you can get more done in less time.

4. Makes it easier to include modding support.

5. Helps to keep your C++ code clean. Less implementation specific stuff clogging it up.

6. Almost requires a good design for your C++ code. Having messy C++ code can make it more difficult to bind it to Lua.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 14, 2015, 07:31:47 pm
Ah I think I get what you're talking about. Well, I get why you do it anyway, I don't think I'll ever leave pure c++ because I prefer the object orientated style, where I give classes identifiers so the in the given example, the class can tell whether or not the think it collided with is special. Oh, and for the record, I think your way of controlling enemies is better than mine because mine was something like venom from spiderman in that you played as a symbiotic goo and so I would have had to draw a player controlled version of every enemy instead of your way of just controlling them.

You can mix OOP and Lua quite easily. No need to recompile is a big thing for gamedev. I can change and fine-tune gameplay logic and different variables during the run time. This makes development a lot faster.

And dabbertorres wrote about some cool advantages I've missed. I strongly encourage you to try out scripts. If you don't like them - no problem, everyone has their own dev process. But just trying out different stuff is great and can improve your code a lot, especially scripting.
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 14, 2015, 07:34:20 pm
I have done some stuff with Unity, is that the same thing?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 14, 2015, 07:55:38 pm
I have done some stuff with Unity, is that the same thing?
I've never used Unity, so I can't tell (but I know that it has cool scripting system so I think you can make changes when your game is running). Basically it works like this for my game:

1) Load the game
2) Test some stuff
3) Make some changes in a script
4) Reload the script using in-game console
5) Changes are now in the game and I can test stuff again. :)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 14, 2015, 07:59:43 pm
Yeah that's pretty much how it is in Unity.
When you want to do that, you make the variable you want to change visible in the inspector and then change it while you're running the program. Then put the value in the scripts when you stop the program.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 15, 2015, 09:41:30 am
I've improved level format
(http://i.imgur.com/nOCWXng.png)
See these dark gray squares? These are empty chunks. There maybe a lot of them because levels may not be in form of a rectangle. 
When I didn't use chunks, I've had to save large empty areas because all tiles were stored in one big 2d array. So it looked like this in a file (-1 is an empty tile id):

1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,...
1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,...
1,1,4,1,5,1,1,1,-1,-1,-1,-1,-1,-1,...
1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,...
1,1,1,5,1,1,1,1,-1,-1,-1,-1,-1,-1,...
1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,...
1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,...

Lots of space wasted, right? Not anymore! Now I store levels like this (posX and posY indicate index of top-left tile in chunk):

...
chunk posX=-8 posY=-13
42,42,42,42,42,42,42,42,
30,30,30,30,30,30,30,30,
9,9,9,9,9,9,9,9,
13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,
52,52,52,52,52,52,52,52,
1,1,1,1,1,11,1,1,
31,1,11,2,1,1,23,1,
chunk posX=-32 posY=-5
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
1,1,1,1,1,13,13,13,
...

Chunks are still stored in one 2d array (it's easier to work with them that way), but empty chunks are very lightweight (all they have is empty sf::VertexArray and std::vector<std::vector<int>>) so it's not a problem.
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 15, 2015, 10:32:50 am
Could I suggest filling the empty spaces with dense forest (just copy and paste your trees), because that makes it look more realistic, while still means you don't have rectangular levels.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 15, 2015, 04:27:16 pm
Could I suggest filling the empty spaces with dense forest (just copy and paste your trees), because that makes it look more realistic, while still means you don't have rectangular levels.
There's no need to do that, player won't ever see those areas, that's why keeping information about this areas is a waste of space.
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 15, 2015, 04:30:55 pm
I was thinking along the lines of if you were going to make the big open areas scroll continuously or if you might start zoomed out when the player enters a new area, so they got some idea of what it was like, and then you zoom in to their position. Oh and for the record, I didn't mean program in data about the trees I just meant have some record that that area was empty and make something that fills all empty areas in whenever they would be visible.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 15, 2015, 04:34:42 pm
I was thinking along the lines of if you were going to make the big open areas scroll continuously or if you might start zoomed out when the player enters a new area, so they got some idea of what it was like, and then you zoom in to their position. Oh and for the record, I didn't mean program in data about the trees I just meant have some record that that area was empty and make something that fills all empty areas in whenever they would be visible.
Yeah, if player will be able to see it zoomed out, I would do it. But probably I'll just make a map which won't represent game world 1:1 but will be like in A Link to the Past.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 19, 2015, 10:19:53 am
Doing some animations. What do you think?
(http://i.imgur.com/1zDC6z1.gif) (http://i.imgur.com/D6AEkWX.gif)

Old animation for comparison (it sucks!)
(http://i.imgur.com/vKVpOwu.gif)
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on May 19, 2015, 10:21:41 am
I'm no designer, but: Nice! :-)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 19, 2015, 10:30:58 am
I'm no designer, but: Nice! :-)
Thanks. It's very hard to draw in that perspective. I've tried different shapes for character sprite and this one looks the best. It's very styled (don't even compare that with Chrono Trigger or Secret of Mana! :D) but I think it looks okay.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on May 19, 2015, 08:03:16 pm
The top (new) graphics do look better than the bottom (old) graphic but the top-right one (new, clothed) looks like he has had his left arm amputated! :o

By the way, this project looks really well done. Good work! :)
Title: Re:creation - a top down action rpg about undeads
Post by: Jabberwocky on May 20, 2015, 12:46:50 am
Looks great, Elias.  Thanks for sharing.

I enjoyed your write-up on the ECS model you're using.  I'm also using ECS.  It can be a bit of work t get set up properly.  But once you do, there's massive flexibility in designing different kinds of game objects.  I doubt I'd ever go back to using anything different.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 20, 2015, 01:18:17 am
@Hapax Thanks!
Well, the right arm... it's just one pixel wide (instead of two). It looks a bit weird, but with two it looks even worse, but I'll try to find some balance (can't make it 1.5 pixels, unfortunately!)

@Jabberwocky Thanks! Glad you've enjoyed it.
Yeah, once you get ECS, there's no way back. I've tried to do normal OOP and ended with almost ECS (all classes differed mostly by data, so why not get rid of classes at all in that case? :D)

Oh, and I'm working on attack animation now. It's not perfect but starting to actually look decent.
(http://i.imgur.com/FOw3qBY.gif)
Title: Re:creation - a top down action rpg about undeads
Post by: Jabberwocky on May 20, 2015, 05:19:29 pm
I hope you don't mind a bit more discussion on ECS. 

Overall, our implementations of ECS seem pretty similar.

One minor, although significant difference is that you store a vector/array of pointers to components.  That will be totally fine for a game which doesn't have a huge number of entities/components operating at once, as looks to be the case with your game, given that it works screen by screen.

For a game that does process a huge number of entities at once, say a large, dynamic, open world game with entities that continue to operate while off-screen, you would lose some performance because of the pointers.  It's a cache miss problem, because while the pointers are arranged sequentially in memory, the actual component data is not.  So when a system iterates over an array of components, it's jumping all over memory.

It's more optimal to store a straight up array of components, not component pointers.  i.e.

class ComponentSystem
{
private:
   // not this:
   // std::vector<Component*> m_components;
   // but this:
   std::vector<Component> m_components;
};

Then, when you iterate over m_components, it's all sequential memory, which is really fast.  The biggest problem with this approach is that when m_components grows, as can happen when you add new elements, two tricky things happen:

1.  It invalidates any Component pointers or references which may currently be in use by your gamesystem code, since the vector moves in memory.  This can lead to some nasty dangling pointer/reference bugs if you're not very careful about when you add components to the vector, in relation to when you operate on components within the vector.

2.  It calls constructors and destructors on every component in the vector, which can lead to unintended consequences if you treat your constructors and destructors as meaning the entity/component is being created and destroyed in a gameplay sense.

Bottom line, arrays of pointers are easier (avoiding the problems above), provide all the flexibility of an ECS, and work great for most games.  They do lose some of the performance benefits of an ECS, but that's only important for a few kinds of massive, open world games.  So this is not a critique of your approach at all (it seems really good!), just some of the thoughts I've had. 
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 20, 2015, 06:13:32 pm
I don't mind this disscussion at all. In fact, I pretty much welcome it because it may lead to something interesting and help me and other people find out about different approaches and tricks.

std::vector<Component> m_components;
Nope, can't do that. How do I store different components in one vector? Only through pointers (well, I can use shared_ptr, but I'll fix that later). If you try to store derived classes instances in one vector, object slicing happens. :)

Just run this code and see what happens:

class A {
public:
    virtual void print() {
        std::cout << "A " << std::endl;
    }
};

class B : public A {
public:
    void print() override {
        std::cout << "B" << std::endl;
    }
};

int main() {
    A a;
    B b;
    std::vector<A> c;
    c.push_back(a);
    c.push_back(b);
    for (auto it = c.begin(); it != c.end(); ++it) {
        it->print();
    }
}
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on May 20, 2015, 07:33:15 pm
@Hapax Thanks!
the right arm... it's just one pixel wide
Ah, I think I see it now. I stand, though, by the fact it looks initially like that single pixel-wide part is a part of the sword so the arm looks like it's missing below the shoulder  :D
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on May 20, 2015, 07:54:43 pm
1.  It invalidates any Component pointers or references which may currently be in use by your gamesystem code, since the vector moves in memory.  This can lead to some nasty dangling pointer/reference bugs if you're not very careful about when you add components to the vector, in relation to when you operate on components within the vector.
As a solution to this problem, typical ECS implementations use a sort of handles (e.g. integers containing information to index) instead of pointers and references.

2.  It calls constructors and destructors on every component in the vector, which can lead to unintended consequences if you treat your constructors and destructors as meaning the entity/component is being created and destroyed in a gameplay sense.
This can be avoided by providing move constructor and move assignment operator. This adds more maintenance overhead however, so I wouldn't do it carelessly.

std::vector<Component> m_components;
Nope, can't do that. How do I store different components in one vector?
You don't. You use multiple vectors, one per component type.

Components would no longer be owned by entities; each vector would then store the components of multiple entities in the game.
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on May 20, 2015, 08:03:21 pm
The biggest problem with this approach is that when m_components grows, as can happen when you add new elements, two tricky things happen:

1.  It invalidates any Component pointers or references which may currently be in use by your gamesystem code, since the vector moves in memory.  This can lead to some nasty dangling pointer/reference bugs if you're not very careful about when you add components to the vector, in relation to when you operate on components within the vector.
Only if the vectors .size() is equal to its .capacity() will it reallocate. As long as .size() is below .capacity() you are guaranteed that no reallocation will happen and all iterators etc stay valid. So, if you know up-front the maximum number of elements you'll ever need to store you can .reserve() the needed capacity at the beginning and be sure it will never re-allocate.

2.  It calls constructors and destructors on every component in the vector, which can lead to unintended consequences if you treat your constructors and destructors as meaning the entity/component is being created and destroyed in a gameplay sense.
You can avoid that by implementing move constructors and move assignment operators for the objects you store in the vector, since then they can just be moved when the vector reallocates instead of being copied. But remember to make those functions 'noexcept (http://en.cppreference.com/w/cpp/language/noexcept)', since vector will only 'move_if_noexcept (http://en.cppreference.com/w/cpp/utility/move_if_noexcept)' to preserve the strong exception guarantee that C++98 mandates.
Title: Re:creation - a top down action rpg about undeads
Post by: dwarfman78 on May 20, 2015, 08:11:26 pm
i don't want to be nitpicking here but comparing ECS and OOP is like comparing mecanic and an internal combustion engine, one is just an organisation based on the concepts brought by the other. OOP is a paradigm and ECS is a pattern, well it's like you've discovered the lost ark but it exists among many patterns brought in the 90's by the "gang of four".  New paradigm brought by functional programing tends to make most of those design patterns a bit outdated but they still worth something in specific situations.

see here : http://en.wikipedia.org/wiki/Design_Patterns

To be more specific ECS is based on the Composite and Strategy patterns and polymorphism too.

In other words there's nothing wrong with OOP nor something "normal" or not with OOP, inheritance sucks over composition for sure and it tooks us a bunch of years and smell code to realize it, that's all.

btw Elias i'd love to be able to do my own pixel art for my own games as you do, they're very convincing. If i may try to be constructive here i would say that the archer guy is a bit too flashy compared to the other characters.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on May 20, 2015, 08:59:41 pm
I see the method Jabberwocky is talking about. The idea is that there isn't one vector for all Components, there are multiple vectors, one for each Component type.

I went with something very similar to what he is describing.

One system per component type, which contains a vector of all Components of that type (well in a container I called an "AssocMap" (I should rename it to something like "AssocVector"), which is essentially a combined vector/hash map so I can access Components via entity ID, but also have sequential memory storage. Prolly not a novel concept or even a best solution, but I liked the result).

My System Implementation (https://github.com/dabbertorres/Swift2/blob/ecsRedesign/src/EntitySystem/System.hpp)

Then "entities" are simply an ID number, for which I use just use an unsigned int.

It's a little out of date, I have some changes I haven't pushed yet, but it should get my underlying concept across. :)


Anyway, as others have said, I'm absolutely loving the art and the art style!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 20, 2015, 09:14:07 pm
Components would no longer be owned by entities; each vector would then store the components of multiple entities in the game.
Yeah, we've had some disscusion about this around the 2nd page of this thread.
I would love to implement this, but I need some ideas to be able to get particular component by its type. Like this:
auto graphicsComponent = componentSystem->get<GraphicsComponent>(entityId);
Any ideas how to do this if I have vectors for each component type in ComponentSystem?

As for creation and destruction of components... I'm thinking about object pools but I wonder how I could make this work, ha-ha.

i don't want to be nitpicking here but comparing ECS and OOP is like comparing mecanic and an internal combustion engine, one is just an organisation based on the concepts brought by the other. OOP is a paradigm and ECS is a pattern, well it's like you've discovered the lost ark but it exists among many patterns brought in the 90's by the "gang of four".  New paradigm brought by functional programing tends to make most of those design patterns a bit outdated but they still worth something in specific situations.
I should have been more exact. When I'm talking about OOP vs ECS, I'm talking about deep hierarchy trees (Entity->Character->NPC->Monster->Dragon etc.) vs ECS approach. Of course, I'm not against OOP. I'm using it a lot in other stuff. But it's not that great for entities and creating new types of stuff. It leads to well known problems and ECS is a great way to get rid of a lot of them!

In other words there's nothing wrong with OOP nor something "normal" or not with OOP, inheritance sucks over composition for sure and it tooks us a bunch of years and smell code to realize it, that's all.
Completely agreed! OOP is great for some things but sucks for others. Composition is not the only way to solve every problem. But ECS stuff is the main core of my engine that's why I talk a lot about it. :)

btw Elias i'd love to be able to do my own pixel art for my own games as you do, they're very convincing. If i may try to be constructive here i would say that the archer guy is a bit too flashy compared to the other characters.
Thanks and good luck! And I appreciate all the feedback so don't worry about providing it. I agree that it archers are more flashy than other characters, but I've yet to draw other characters. There's not many of them, so I'm just experimenting and look what stuff looks good and what stuff does not.
Some variety is good. :)

@dabbertorres, thanks for your idea, I'll see what I can come up with it in mind.
And thanks for your appreciation of my art. That means a lot to me, considering I'm a beginning artist. And I'm very glad that the style I'm doing my art in looks good enough. (It's not the greatest art I can do, but I can't spend a lot of time on art, so I have to throw out some shading, simplify some things, etc.)

Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on May 20, 2015, 09:25:44 pm
I would love to implement this, but I need some ideas to be able to get particular component by its type. Like this:
auto graphicsComponent = componentSystem->get<GraphicsComponent>(entityId);
Any ideas how to do this if I have vectors for each component type in ComponentSystem?
You have to map types to associative keys that share one type and can be used at runtime. There are multiple approaches: integers returned from templates, std::type_index, ...

Type erasure is the keyword here. You have to transform static type information into dynamic one.


By the way, I completely agree with dwarfman78 regarding OOP vs ECS, unfortunately the term "OOP" is often used wrongly because people think of all the things that can be done wrong with it. Some time ago (http://en.sfml-dev.org/forums/index.php?topic=13793.msg96969#msg96969) I wrote something related:
Quote from: Nexus
I think we should not fall in the typical "OOP vs. components" discussion, in my opinion the view that these concepts are contradictory is a misunderstanding. Often, OOP is associated with overused inheritance and unflexible class hierarchies, and people forget that a entity component system is built on top of most OOP features, too (purists could even consider ECS as a sort of design pattern, but probably there's already another name for it).

Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 20, 2015, 09:31:46 pm
Type erasure is the keyword here. You have to transform static type information into dynamic one.
std::type_index is pretty cool, but how can I map it to particular std::vector?
std::map<std::type_index, std::vector<T>> componentVectors
would be cool to have but I can't do that. What are possible ways to do this?

So, this is what I hope to get:
T* getComponent<T>(int entityId) {
    auto componentVector = ...; // get vector!
    return &componentVector[entityId]; // and some error checking there, of course
}

By the way, I completely agree with dwarfman78 regarding OOP vs ECS, unfortunately the term "OOP" is often used wrongly because people think of all the things that can be done wrong with it. Some time ago (http://en.sfml-dev.org/forums/index.php?topic=13793.msg96969#msg96969) I wrote something related:
Quote from: Nexus
I think we should not fall in the typical "OOP vs. components" discussion, in my opinion the view that these concepts are contradictory is a misunderstanding. Often, OOP is associated with overused inheritance and unflexible class hierarchies, and people forget that a entity component system is built on top of most OOP features, too (purists could even consider ECS as a sort of design pattern, but probably there's already another name for it).
Yeah, I'll be talking about "deep hierarchy/inheritance trees" in the future because it seems to be a lot more accurate term.
Title: Re:creation - a top down action rpg about undeads
Post by: Jabberwocky on May 20, 2015, 09:46:05 pm
How do I store different components in one vector?

Ahh, right!  I somehow missed that you stored your components in the Entity, rather than in the system.  As dabbertorres pointed out (heh), this only works if you store your components in a system, not in the entity.

So there's a system for each component type, e.g. PhysicsSystem which stores a vector of Physics components, e.g.

class PhysicsSystem
{
public:
   // called per-frame.
   // iterates over and updates every Physics component in the game as required
   void Update();

   // retrieve a Physics component
   // simple implementation, in real life you'd want bounds checking
   Physics* GetPhysics(unsigned int index) { return m_physicsComponents[index]; }

   Physics*  CreatePhysics(...);
   void DestroyPhysics(unsigned int index);

private:
   std::vector<Physics> m_physicsComponents;
}
 

You can use c++ templates to make this work for any component in the game, although again this approach is more complex than you need for many types of games.

An Entity is then just a collection of components like this:

enum ComponentType
{
   Physics,
   Graphics,
   // etc...
};

class Entity
{
private:
   // Maps a ComponentType to the index of the component, which must be looked up
   // via the corresponding ComponentSystem.
   // (This particular implementation does not support multiple components of the same type.)
   std::map<ComponentType, unsigned int> m_components;
};


1.  It invalidates any Component pointers or references which may currently be in use by your gamesystem code, since the vector moves in memory.  This can lead to some nasty dangling pointer/reference bugs if you're not very careful about when you add components to the vector, in relation to when you operate on components within the vector.
As a solution to this problem, typical ECS implementations use a sort of handles (e.g. integers containing information to index) instead of pointers and references.

For sure, handles are the way to go.  But even then you can run into trouble.  At some point, you need to turn a handle into a pointer or a reference to call functions on it. 

Here's an example of where you might get into trouble.

void SummonPet(Entity* pEntity)
{
   // ...

   // check my Mana component (or Vitals component, or whatever) to see if I have
   // enough Mana to summon the pet.
   int nManaToSummon = 10;

   Mana* pMana = ManaSystem::GetMana(pEntity);
   if (pMana->GetCurrent() < nManaToSummon)
   {
      return false;
   }

   // ... code to create pet entity here ...

   // decrement mana
   pMana->DecrementCurrent(nManaToSummon);
   // *** CRASH ***
   // The ManaSystem's vector of Mana component may have shifted,
   // because we created a new Entity (the pet) which may itself have required a Mana
   // component, and called ManaSystem::CreateMana.  This invalidates our pMana
   // pointer (dangling pointer bugs, ew!).

   return true;
};
 

____________

re:  move constructors and move assignment operators:

Yep, this is totally one way to solve the problem.

Another way is to just rely on the default destructors and constructors (bitwise copy), for your components, and control your component's lifetimes with a Component::Init() and Component::Destroy() function, which is where you would handle any dynamic mem allocation, for instance.
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on May 20, 2015, 09:46:14 pm
std::map<std::type_index, std::vector<T>> componentVectors
would be cool to have but I can't do that. What are possible ways to do this?
Type erasure, as I said.
struct ComponentVectorBase
{
    virtual ~ComponentVectorBase();
};

template <typename T>
struct ComponentVector : ComponentVectorBase
{
    std::vector<T> components;
};
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 20, 2015, 09:51:51 pm
@Jabberwocky Thanks for your ideas!
But I'm afraid I need more generic approach to do this, because not every component has it's own system and I currently have 18 types of components. Who knows how many I'll add in the future?

@Nexus Oh yeah, that'll do it. Thanks!
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on May 20, 2015, 09:55:08 pm
re:  move constructors and move assignment operators:

Yep, this is totally one way to solve the problem.

Another way is to just rely on the default destructors and constructors (bitwise copy) ...
Where do you get the "bitwise copy" notion from?
The default copy ctor does not do a bitwise copy - it does a member by member copy.
And if you are memcpy()'ing (a bitwise copy) an object, then it better be std::is_pod (http://en.cppreference.com/w/cpp/types/is_pod) / is_trivially_copyable (http://en.cppreference.com/w/cpp/types/is_trivially_copyable).

What exactly do you mean?
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on May 20, 2015, 10:05:34 pm
Here's an example of where you might get into trouble.
True, but as a user of such an ECS you have to be aware that any change to the structure of the components (their addition or removal) invalidates all component pointers and references. That's why you would re-acquire a pointer from the handle.

A component handle can also be encapsulated, so that you don't have to call getComponent() again and again:
ComponentHandle<C> h(components, entity);
C& component = h.get(); // or simply *h

By the way, before everyone reinvents the wheel here: EntityX is a nice ECS library for C++. I don't like too much how it mixes its event system in, and the fact that they provide multiple syntaxes for everything obscures the API a bit, but design-wise, it's definitely worth having a look at. Keep in mind that one tends to overengineer quite a bit when delving too deep into possible optimizations; you should stay realistic about your game's scope before incorporating all kinds of features and neat tricks that you can never exploit.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 20, 2015, 10:12:08 pm
Keep in mind that one tends to overengineer quite a bit when delving too deep into possible optimizations; you should stay realistic about your game's scope before incorporating all kinds of features and neat tricks that you can never exploit.
Totally. That's why I won't rebuild my ECS in near future (maybe when I have some spare time to experiment...). Making stuff like this is fun but I have no problems with perfomance now. My main focus is getting game to very playable state so I can release some demo for people to play around with and give me their feedback. I hope to finish it by the end of this summer. I'm feeling pretty anxious about it, so the demo won't we public for some time, I guess. :)

And I'll take a lot at EntityX some time.
Title: Re:creation - a top down action rpg about undeads
Post by: Jabberwocky on May 20, 2015, 10:26:27 pm
Yep, honestly for a smallish-type game, I think your more simple ECS approach is probably best, Elias.  Like I said earlier, it gives all the flexibility of an ECS, a clean simple solution, but just not the performance benefits (which you likely don't need).


Where do you get the "bitwise copy" notion from?
The default copy ctor does not do a bitwise copy - it does a member by member copy.
And if you are memcpy()'ing (a bitwise copy) an object, then it better be std::is_pod (http://en.cppreference.com/w/cpp/types/is_pod).

What exactly do you mean?

Oh, yeah sorry.  That was confusing on my part.

What I mean is that normally the constructor, copy constructor, assignment operator and destructor is where you would (de)allocate new memory, if needed.  For example, let's say I have an ActiveEffects component, which stores what effects (e.g. spells in an RPG) an entity is currently affected by.

// This is a component which stores effects on an entity
class ActiveEffects
{
private:
   // These are the individual effects which this entity has.
   // e.g. Maybe I cast a spell called "wind runner" on myself that makes me run fast.
   // I need Effect* pointers because there are different kinds of Effect subclasses,
   // e.g.  MoveSpeedEffect, AttributeBoostEffect, etc.
   std::vector<Effect*> m_effects;  
};

Normally, you'd see those pointers and think, I need to write a whole lot of constructor/copy constructor/assignment operator/destructor logic, or I might end up with memory leaks or duplicate pointers. 

For example, your copy constructor might look like this:

ActiveEffects::ActiveEffects(const ActiveEffects& i_rhs)
{
   std::vector<Effect*>::const_iterator it = i_rhs.m_effects.begin();
   std::vector<Effect*>::const_iterator end = i_rhs.m_effects.end();
   for(; it != end; ++it)
   {
      const Effect* pOriginal = *it;
      // This next line doesn't even actually work, because Effect* is pointing at
      // a subclass, but you get the idea...
      Effect* pCopy = new Effect(*pOriginal);
      m_effects.push_back(pCopy);
   }
}
 

So, now every time your vector of ActiveEffect components moves in memory, the copy constructor and destructor is called on every each one.  This is a whole bunch of newing in the copy constructor, and a whole lot of deleting in the destructor.  That's really stupid, because we aren't changing any effects.

Move constructors can solve this.  But now every component in the game, and every data member they contain needs to have:

That's fine, and that's what they're designed for.But my approach is to skip all of those.

The default copy constructor does exactly what I want - it copies the pointers without newing or deleting the Effects.  But that means I can't delete any memory in the destructor (if I did, I would delete all my Effects every time the ActiveEffects vector grew).  Instead, I put my destructor logic in a function called Component::Destroy(), which is called by the ComponentSystem whenever we actually want to destroy a component, rather than just moving it.

Haha, wow this thread is going crazy.  2 new posts while I was typing this up!  Interesting game and tech discussion, I guess.  :)
Title: Re:creation - a top down action rpg about undeads
Post by: Jabberwocky on May 20, 2015, 10:39:33 pm
True, but as a user of such an ECS you have to be aware that any change to the structure of the components (their addition or removal) invalidates all component pointers and references. That's why you would re-acquire a pointer from the handle.

Totally agreed.  That's all I was saying, too. 
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on May 20, 2015, 10:52:38 pm
Move constructors can solve this.  But now every component in the game, and every data member they contain needs to have:
  • assignment operator
  • move assignment operator
  • copy constructor
  • move constructor
Yes, but that doesn't mean the user has to implement them all. For move constructor and assignment operator, he can benefit from the = default mechanism.

The problem is that you're using raw pointers to store memory, which is generally a bad idea (http://www.bromeon.ch/articles/raii.html). If you used std::unique_ptr instead, then destructor and move ctor/op= would come for free.

If you additionally need copy semantics, you can use aurora::CopiedPtr (http://www.bromeon.ch/libraries/aurora/v1.0/tutorial-smartptr.html), and things will just work fine. This smart pointer deep-copies through polymorphic hierarchies.
class MyClass
{
   std::vector<aurora::CopiedPtr<Effect>> effects;
};

MyClass origin = ...;
MyClass copy = origin; // BAM, deep-copy.

This is a really powerful idiom, I still wonder why not even Boost has something alike. Anyway, Aurora does :D


The default copy constructor does exactly what I want - it copies the pointers without newing or deleting the Effects.  But that means I can't delete any memory in the destructor (if I did, I would delete all my Effects every time the ActiveEffects vector grew).  Instead, I put my destructor logic in a function called Component::Destroy(), which is called by the ComponentSystem whenever we actually want to destroy a component, rather than just moving it.
Yes, that's also a possibility. The problem here is that you have to be extra-careful to call the right functions, while constructors and destructors impose a class invariant that guarantees this. For example, with exceptions, the manual calls can easily be forgotten.

@Elias: Tell us if we're going too much off-topic here, then we can continue in another thread ;)
Title: Re:creation - a top down action rpg about undeads
Post by: dwarfman78 on May 20, 2015, 10:53:17 pm
Make games not ECS. 8)

(click to show/hide)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 21, 2015, 08:47:02 am
Some great discussion happening here. ;)

I've posted new dev log on my blog: https://eliasdaler.wordpress.com/2015/05/21/recreation-dev-log-april-may-2015/
It covers what I did in last two months. I'm pretty proud about the progress!
Title: Re:creation - a top down action rpg about undeads
Post by: dwarfman78 on May 21, 2015, 10:19:05 am
Hi Elias, i am wondering as you're using lua scripts, do you intend to let the user modify them ? If not how are you going to package them ?
Title: Re:creation - a top down action rpg about undeads
Post by: eXpl0it3r on May 21, 2015, 11:28:58 am
He's using Lua and as stated before, he won't really pack them, because yay modding! :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 21, 2015, 06:02:08 pm
^ This. I've answered it here  (http://en.sfml-dev.org/forums/index.php?topic=18062.msg130620#msg130620)

For those who may have missed (damn it, my post was the last on the page!)

New dev log is here! (https://eliasdaler.wordpress.com/2015/05/21/recreation-dev-log-april-may-2015/)

I've made lots of stuff and I want you to check it out. ;)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 21, 2015, 06:07:26 pm
I've just read your dev log and I honestly can't say enough good things about this. The callback system is brilliant and I think I'll try and put that sort of thing into the next game I make.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 21, 2015, 06:56:27 pm
I've just read your dev log and I honestly can't say enough good things about this. The callback system is brilliant and I think I'll try and put that sort of thing into the next game I make.
Thanks! You should definitely try. C# has that system already(events and delegates) and I needed to implement something similar in C++.
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on May 21, 2015, 07:01:30 pm
Did you use std::tr1::function for callbacks, or did you just let each class store references to all its observers, each of which would have a function that can be called (probably via inheritance)?
Title: Re:creation - a top down action rpg about undeads
Post by: Lo-X on May 21, 2015, 07:31:38 pm
Did you use std::tr1::function for callbacks

You can use std::function without ::tr1 for a little while now :)

Quote
gui->registerCallback(&GUIPlayingState::onHpChange);
player->addObserver(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!
}

With that code, how do you do the link between you HpChangedEvent and the right callback to call (as your registerCallback() method doesn't take the type of event as parameter. And how do you register callbacks with different signatures ?


I don't like that way of doing so much, because everything is done at execution. Plus you have to tell your Subject class (in that case Player) when the Observer is destroyed.
I prefer compile time Event Systems, zagabar has a good one in his Featherkit lib using structs. Again I guess it's harder to bind such a system to Lua compared to a simple Observer pattern (which does the job well anyway).
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 21, 2015, 07:36:12 pm
Did you use std::tr1::function for callbacks, or did you just let each class store references to all its observers, each of which would have a function that can be called (probably via inheritance)?
Yep, I use std::function (no need to write tr1 in C++11).
Basically, Observer has std::map<std::type_index,std::function> callbacks and onMessage function which just calls callbacks[type_index_of_event].
When Subject fires an event, it calls onMessage function of each observer.

With that code, how do you do the link between you HpChangedEvent and the right callback to call (as your registerCallback() method doesn't take the type of event as parameter. And how do you register callbacks with different signatures ?

I don't like that way of doing so much, because everything is done at execution. Plus you have to tell your Subject class (in that case Player) when the Observer is destroyed.
I prefer compile time Event Systems, zagabar has a good one in his Featherkit lib using structs. Again I guess it's harder to bind such a system to Lua compared to a simple Observer pattern (which does the job well anyway).
Oops, I should fix that. RegisterCallback takes event type as a template argument and maps a function to this type of events.
This should answer all your questions.

I'll check out compile time Event Systems. My system is just one of the first ones I've come up with. Maybe I'll find something more convenient and awesome. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Lo-X on May 21, 2015, 07:47:12 pm
This should answer all your questions.

I'll check out compile time Event Systems. My system is just one of the first ones I've come up with. Maybe I'll find something more convenient and awesome. :)

Yes it does answer ! Maybe the template parameter has been considered as HTML, does happen sometimes on blogs.

The observer pattern way is fine, there's nothing wrong with what your doing. I just wanted to point out other way of achieving messaging, with different pro and cons.

Anyway your game isn't just amazing to see, the code looks nice even if we just have the right to see snapshots :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on May 21, 2015, 09:18:09 pm
Yes it does answer ! Maybe the template parameter has been considered as HTML, does happen sometimes on blogs.

The observer pattern way is fine, there's nothing wrong with what your doing. I just wanted to point out other way of achieving messaging, with different pro and cons.

Anyway your game isn't just amazing to see, the code looks nice even if we just have the right to see snapshots :)

Nah, I probably just forgot to add it. ;)

I like to look at different approaches, so I appreciate when people tell me about different ways of achievening something I did.

And thanks for you kind words! I try to keep my code clean and nice and I'm really proud that people see it.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on June 02, 2015, 01:14:33 pm
So, I didn't have time to work on the game last week because I had to study a lot. I still have to study a lot (exams are coming...) but I now have more free time so I can slowly work on the game. I'm working on the dungeon level now. It's coming along nicely.
So, here's a new screenshot:
(http://i.imgur.com/CVZqnlF.png)
This witch (actually a powerful necromancer!) will help you a lot on your quest. How? I'll tell a bit later when I finish some animations. ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on June 08, 2015, 12:14:16 am
Still working on necromancer grandma. Drew a portrait. Still work in progress. :)
(http://i.imgur.com/ItlRxMd.png)

P.S. Also have some cool ideas for a level called Ghost Town. This was a town full of musicians but all its population is dead now and travels in ghost form. They can't return even become undeads... Why? I won't spoil it, you'll see for yourself later! :D
Title: Re:creation - a top down action rpg about undeads
Post by: JackPS9 on June 08, 2015, 02:00:20 am
Elias, please dont take this wrong only asking cause of your forum profile pic.
But is that necro grandma a family member?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on June 08, 2015, 07:38:26 am
Elias, please dont take this wrong only asking cause of your forum profile pic.
But is that necro grandma a family member?
Ha-ha, no. I just drew my profile pic as a portrait inside the game.
But thanks for the question, it's great. :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on June 10, 2015, 12:54:35 am
I've been working on a platform puzzle (sorry, some tiles are not finished yet!).

See this platform? When you step on the button, it moves in another direction. When you step off the button, it moves as it did before.
(http://i.imgur.com/hqhB826.gif)

You can try to jump on the platform, but what's the point of it? You'll be returned back!
(http://i.imgur.com/rtqc56G.gif)

You have to use recreation to solve that thing. ;)
Title: Re:creation - a top down action rpg about undeads
Post by: ChronicRat on June 10, 2015, 11:28:52 am
You're tricky! =)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on June 11, 2015, 07:04:06 pm
You're tricky! =)
Yeah  ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Jabberwocky on June 12, 2015, 04:03:38 am
Definitely a nifty game mechanic you've got going on, Elias.  Thanks for the updates.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on June 12, 2015, 10:29:02 am
Definitely a nifty game mechanic you've got going on, Elias.  Thanks for the updates.
Thanks! And thank you for reading them and giving feedback. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 08, 2015, 07:35:36 pm
Progress update
I've had lots of exams and successfully passed all of them. This means that I have two months which I can devote to my game. Lots of updates incoming!
 
I've spend some days paying off my "programmer's debt". Lots of bugs were fixed and lots of stuff was optimized. There isn't much to talk about there.
I'll talk about cooler stuff instead.

Forest
(http://i.imgur.com/2qq9TJH.png)
I've spent lots of time redrawing forest tileset. Lost of grass, flowers and cliff tiles... Compare it to the old screenshot:
(http://i.imgur.com/bA5XdJJ.png)

Quite a difference, don't you think?

Tile patterns in level editor
(http://i.imgur.com/rrI5iEb.gif)

This is very handy for level editing. For example, forest tileset has two grass tiles. They alternate between each other in checkboard pattern. Making it all by hand is just too slow, so I made tile patterns scriptable!

Here's how grass pattern script looks:
{
        tileId = 10, -- if this tile selected, pattern below is pasted
        pattern = {
            { 10, 37},
            { 37, 10}
        }
},

10 is first grass tile ID. 37 is another grass tile ID.
When some area is selected, I can press "P" to fill it with current tile's pattern. Each tile can have a corresponding pattern. Patterns can be of any size and it's useful for any stuff that has similar structure.

Input

I've spent some time making input more abstract. I can now save and load input bindings.
I already had a simple input manager which helped me check when some button is pressed, held or released.
Now it's even more abstract. Instead of checking for specific key in C++ code, I check for button tag.
Here's how I check for input now:
if(inputManager->isKeyHeld(ButtonTag::PrimaryAction)) {
...
}
 
Each ButtonTag has a corresponding sf::Keyboard::Key. 

I've also added gamepad support which was a bit harder to make abstract because Dpad and Sticks are not buttons, they have axes. What made it even worse is that coordinate systems for D-pad and left stick differ (so, when up is pressed on the D-pad PovY axis is 100. But when up is pushed on the left stick Y axis is -100!). This was easily fixed and gamepad works fine now.

Future plans
And that's just the beginning. I have lots of plans and ideas and I'm currently remaking some old levels to make them better and more interesting.
I'll have lots of cool stuff to show off soon (new NPC's, new art, some puzzles and all that stuff), so stay tuned!
Title: Re:creation - a top down action rpg about undeads
Post by: Brax on July 08, 2015, 08:25:50 pm
This is awesome!!!  :o
Great work!
Title: Re:creation - a top down action rpg about undeads
Post by: ChronicRat on July 08, 2015, 08:53:23 pm
Quote
Quite a difference, don't you think?
What was changed? =) Ah, flowers, yes, much better.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 08, 2015, 09:08:52 pm
This is awesome!!!  :o
Great work!
Thanks!

Quote
Quite a difference, don't you think?
What was changed? =) Ah, flowers, yes, much better.
Ha-ha, thanks. Flowers, grass (spent lots of time redrawing it, totally worth it because it's more natural and less blocky now) and I've added some cliffs :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 16, 2015, 01:10:33 pm
Okay, this is going to get very technical. :D

I've been working for several days on a new Event Manager. Event manager is very important because it helps me decouple stuff and optimize perfomance a lot.
Previously I had a simple subject/observer system which let observers to subscribe to subjects and provide a callback function which was called if the subject sent an event. But it had some issues: messages could only be sent immediately and for some object to become observer/subject its class should inherit IObserver/ISubject classes. This caused lots of recompilation each time I realized that some object needed to become an observer or a subject and adding new events when they were already sent caused some troubles too.

So I've decided to completely remake event system and add some cool features.
I've made an event queue and got rid of IObserver/ISubject classes.
Each time something needs to send an event, it adds it to the global event queue.
If some entity subscribes to an event of this type, its callback is called during Event Manager sendMessages() function

Here's how objects can subscribe to events:
SomeClass obj;
engine_system.eventM->addListener<SomeEvent>(&obj, &SomeClass::onSomeEvent);

And here's how they can send them:
auto event = std::make_shared<SomeEvent>();
event->someParam = someValue;
engine_system.eventM->queueEvent(event);

I can later get event's parameters by casting them in a callback which is called during EventManager's sendMessages() function:
void SomeObj::onSomeEvent(const std::shared_ptr<Event>& e) {
    auto event = std::dynamic_pointer_cast<SomeEvent>(e); // this is totally a SomeEvent, because this function is called
                                                          // only when e has this type
    std::cout << event->someParam;
}

Callbacks are implemented using std::function and std::bind and here's how they should look:
void Class::CallbackFunc(const std::shared_ptr<Event>& e)

Objects can also subscribe to certain entities to receive events only from them. (Objects receive messages from everyone by default)

For example, GUIPlayingState only needs to know when player's hp changes, so it adds a playerEntity as a subject:
engine_system.eventM->addListener<HpChangedEvent>(&gui, &GUIPlayerState::onPlayerHpChanged);
engine_system.eventM->addSubjectToListener<HpChangedEvent>(&gui, playerEntity);
 

But it doesn't stop here!
I've implemented Lua/C++ event manager too!

Previously, if I needed to observe another entity's state, I called update() entity function in every frame. For example, if a bridge is lowered when a button is pressed, this function was called:

bridge.update = function(bridgeEntity)
    local button = getEntityByTag("BRIDGE_BUTTON")
    if(getScriptState(button) == "ButtonPressedState") then
        setScriptState(bridgeEntity, "BridgeLoweredState")
    end
end

This is obviously not a great solution, because calling this function 60 times per second may be expensive.  It also sucks that I need to check button's state every frame and this may be very expensive too. Especially if lots of entities have their own update functions.

Event manager fixes that problem by calling a callback function only when the button's state changes.

Entities can add callbacks in Lua this way:
addLuaListener(entity, "SomeEvent", func) -- func is some Lua function

They can also subscribe to entities:
subscribeToSubject(entity, "SomeEvent", subjectEntity)

Each time an event is queued in C++ or Lua, both C++ and Lua callbacks are called. And this it very cool, because it makes communication between Lua and C++ even simpler than before.

 Lua callbacks get an event table which can be used to get parameters:
f = function(event)
    print(event.someParam)
end

So, here's how the bridge can subscribe to the button:
addLuaListener(bridge, "ScriptStateChangedEvent", bridge.onBridgeButtonPressed)
subscribeToSubject(bridge, "ScriptStateChangedEvent", button)
   
And here's how a callback looks like:
onBridgeButtonPressed = function(this, event) -- this function is called every time button entity changes its state
    if (event.currentStateName == "ButtonPressedState") then
        setScriptState(bridge, "BridgeLoweredState")
    end
end

In C++ ScriptStateComponent emits ScriptStateChangedEvent everytime a state is changed. Then a callback Lua function gets called. This works!

The implementation is pretty difficult and required lots of template magic, error checking and optimization, so it would take me far too long to write about everything. Ask me any questions and I'll try to answer them. Maybe you have your own cool Event Manager: tell me about it!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 17, 2015, 11:57:57 pm
New title screen. You select menu item with a ghost, just like you select corpses in the game! :D
(http://i.imgur.com/aWgFTlh.png)

Also, meet the Master of Recreation

Dialogue portrait:
(http://i.imgur.com/4dzbUGD.png)
In game sprite:
(http://i.imgur.com/c4jYUBm.png)

This man will teach you some neat combat lessons and he'll show you main principles of recreation technique.

I'm currently working on the tutorial part of the game. I'm trying to make it fun and sometimes unexpected.
I also came up with different situations which will show main concepts of recreation in practice, instead of just displaying them on screen. More of that later!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 23, 2015, 10:48:47 pm
Re:creation TIGSource dev log thread is LIVE!  ;D
http://forums.tigsource.com/index.php?topic=49336.0
This doesn't mean much for people who read this thread, as I would post in both SFML and TIGSource threads. But this may probably give more attention to my game. I would like to hear your reactions in TIGSource thread too.

Btw, I've drawn new death animations and cliff tiles. Here's how the bridge puzzle looks now:
(http://i.imgur.com/u9CYS5p.gif)
I think it's looks less confusing than it did before. (http://i.imgur.com/jJ0qLxR.gif) (also a bit prettier, I think)

I also have some other cool things to show off and I will do it tomorrow, so stay tuned!
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on July 24, 2015, 09:02:59 am
Personally I liked the gravestones, it gave the game some kind of charm in the world of dead bodies. ;)

Cliff tiles look neat.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 24, 2015, 11:25:22 am
Personally I liked the gravestones, it gave the game some kind of charm in the world of dead bodies. ;)

Cliff tiles look neat.

I liked them too, but those gravestones make gameplay a little bit confusing, because you don't see who're going to become. And thanks :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 24, 2015, 01:38:59 pm
(http://i.imgur.com/ecDUZ3q.gif)
Gravestones are back. Now the player can see who's lying in the grave by looking at the weapons near graves!
(http://i.imgur.com/TV3Tl6U.png)
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on July 24, 2015, 06:11:52 pm
Talk about a developer listening to feedback!  ;D

Ok, I actually have a question, though it's more art than programming. Maybe it'd be better for twitter. Oh well.

How do you draw the game's perspective? With the game's sprites, I mean.
You have the "half top-down, half at-an-angle" perspective down really well I think.

Is it all in the art, or are you doing something on the programming side as well?

I've tried drawing sprites in that perspective as well, and I just can't seem to be satisfied with the results. I've never claimed to be an artist though. :)

So, I guess, main question is: Do you have any tips for drawing sprites in the perspective you have in Re:creation?
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on July 24, 2015, 06:37:35 pm
To add on to dabbertorres' questions I have a few of my own.
With the name "Re:creation", where did the colon come from? I actually thought up until now that you'd put two colons as a sort of coding mini-easter egg of having the scope operator in the title, but I just reread it.
Also, if you're open to suggestions I have a few (I appreciate that you can't just put everything everyone thinks of into your game, but if you like any of the suggestions, then please use them).
Slightly changing an enemy's appearance when you possess them. Mainly for convenience if there is a large group of the same type of enemy then it would get confusing as they all look the same as the one you control. Maybe a different skin tone.
An enemy (maybe a wizard of some sort) that can be possessed and has special abilities which mean that you need to possess them, but slowly saps your health when you do.
Ghosts that can possess your body while you are in ghost form and use it to attack you.

Finally, I thought my previous posts of how amazing this is weren't enough so a few more things that I really like, especially about the recent update.
The little flick of the arrow when it hits something is brilliant. It's the tiny details that make games like this great.
The animation of the grave coming out of the ground is really smooth and in general the animation you've done is brilliant.
I'm not sure how, but you've actually managed to make a grass tile that doesn't look repetitive.
:D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 24, 2015, 09:49:39 pm
@dabbertorres Feel free to ask all types of questions here. Stuff gets lost on twitter, it's more accessible for other people there! :)
I've actually written the article about top-down drawing.
Here it is! (https://eliasdaler.wordpress.com/2013/11/20/z-order-in-top-down-2d-games/)
I've optimized it a bit. You can actually sort static (non-moving) objects by z-order only once they're created on the level. Dynamic (moving) objects need to be sorted each frame, and then you can quickly merge them with static object list in O(n) and then render it in the order which is explained in the article. If you have tons of moving objects, you may want to use grid partitioning to sort objects which are in one cell and then merge this stuff together.

With the name "Re:creation", where did the colon come from?
Ha-ha, I came up with this name when this game was a post-apocalyptic steam-punk rpg. So, it's kinda like someone said a reply to an e-mail with the subject "Creation".
 Lots of things have changed since then and I came up with a recreation mechanic. And I thought "Hey, this title still works!". As for colon: it has no meaning now. But I think it makes a game title more recognizable. I might change it someday to something like "The Recreation of Undead Knight" or "The Recreation of Undead *name of the hero*".

Slightly changing an enemy's appearance when you possess them. Mainly for convenience if there is a large group of the same type of enemy then it would get confusing as they all look the same as the one you control. Maybe a different skin tone.
It's already done. Maybe it isn't very obvious, but here's how normal and undead versions of the same NPC look like:
(http://i.imgur.com/R0K6dFK.png)

An enemy (maybe a wizard of some sort) that can be possessed and has special abilities which mean that you need to possess them, but slowly saps your health when you do.

That's a good idea :)

Ghosts that can possess your body while you are in ghost form and use it to attack you.

I've thought about it! :)
Maybe I'll come up with puzzles in which the player will have take care of his body, so nobody would be able to do harm to it. So you'd need to lock yourself in cells, block all paths with some objects, etc.! :D

Finally, I thought my previous posts of how amazing this is weren't enough so a few more things that I really like, especially about the recent update.
The little flick of the arrow when it hits something is brilliant. It's the tiny details that make games like this great.
The animation of the grave coming out of the ground is really smooth and in general the animation you've done is brilliant.
Thanks a lot! Sometimes I spend lots of time trying to fit those little details into tiny sprites. And it's worth it most of the time.

I'm not sure how, but you've actually managed to make a grass tile that doesn't look repetitive.
:D
Here's how.
(http://i.imgur.com/6poH6Ie.png)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 24, 2015, 10:31:56 pm
Progress update

Here's a tileset I've been working on for the past week! (Do you recognize the painting? ;))
(http://i.imgur.com/9sOqc3Y.png)
This is a house of Master of Recreation. He's the guy who will teach you the main principles of recreation and some combat stuff.
This tileset is quite reusable and I'll use it in other houses as most games do.

You can also go into buildings now.
(http://i.imgur.com/3Qv3tNy.gif)
This was quite interesting to make, because it involved attaching AIComponent to the player.
First, door's state is changed to "DoorOpenedState". Then I disable player's CollisionComponent (so he can go through houses's collision box). This is much more easier than making multiple collision boxes for houses.
Then a target inside the house is set and AI turns on, so the character walks in without player doing so. Then a transition effect happens and another target for AI is set and the character goes there. After he arrives at destination, AI turns off and  player can control the character again. CollisionComponent is enabled. Pretty easy and works perfectly well.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on July 25, 2015, 12:57:12 pm
it's kinda like someone said a reply to an e-mail with the subject "Creation".
This is how I always thought it looked  ;)

You can also go into buildings now.
(http://i.imgur.com/3Qv3tNy.gif)
There's a pretty obvious tile edging visible in this GIF. When the player enters the building, the map moves to the right twice. The second time, a lot of vertical edges flash.

I'm impressed with the progress on this project. Good work  :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 25, 2015, 01:17:35 pm
There's a pretty obvious tile edging visible in this GIF. When the player enters the building, the map moves to the right twice. The second time, a lot of vertical edges flash.
Yeah, this is something I really need to fix. I think it's because the camera's sf::View  has non-integer coords. I have to find a way to make sprite stay in the center of the screen. (It shakes a lot if I just use std::round for sf::View's coords)

I'm impressed with the progress on this project. Good work  :)
Thanks a lot!
Title: Re:creation - a top down action rpg about undeads
Post by: UroboroStudio on July 25, 2015, 02:00:04 pm
Great stuff over here!

I like this proyect, it reminds me the old school rpg but with modern ideas. Nice work!

The possesion mechanic is original and a lot of puzzles can be made around this.

Also, let me say, your code is very good and clean. Personally I don't like the composite pattern, I feel more natural and comfortable with hierarchy. But I see similarities in how approach the game structure.

In our game, we also do a z-order rendering but only with entities visible on screen, so we need to filter firts. The average map size is 8000x6000, with 15-25 rooms and 25-100 objects, depending of the room size. So yes, we need to filter the amount of entities to be drawn, and tilesets is the way to go.

Early in the development I used polimorphism to manage the differents enemy types, but adding LUA remove any need of polimorphism and the AI is purely made of lua scripts.

Also I like the way you managed the triggers and events in the game, is similar to ours, and this way is very flexible and customizable.

And believe me, as a programmer, I kwnow how hard and frustating can be doing your own art, but the results are worth it. Good job!

Keep it up!  :)
Title: Re:creation - a top down action rpg about undeads
Post by: Lo-X on July 25, 2015, 03:57:16 pm
I'm so glad you keep us up to date with your project, specially when you provide tech stuff :) Awesome work
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 25, 2015, 05:44:03 pm
@UroboroStudio Thanks a lot for you feedback! And thanks for providing info about your game.
Entity/component/system just makes it easier to create new types of objects with scripts only. No need to write classes, it's pretty cool. :)

@Lo-X Thanks! I'm glad to post updates too! :)

Also, here's a side attack animation I've made. It makes hits very satisfying!
(http://i.imgur.com/b3J3jOa.gif)
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on July 26, 2015, 01:41:29 am
...tile edging...
Yeah, this is something I really need to fix. I think it's because the camera's sf::View  has non-integer coords. I have to find a way to make sprite stay in the center of the screen. (It shakes a lot if I just use std::round for sf::View's coords)
Have you considered pre-rendering to a render texture? Non-integer values can then be used without edging artifacts.
Title: Re:creation - a top down action rpg about undeads
Post by: FRex on July 26, 2015, 06:11:21 am
Or you could try that renderer (evil self promotion :P): https://github.com/SFML/SFML/wiki/Source%3A-ShaderTileMap
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 27, 2015, 07:33:10 pm
Have you considered pre-rendering to a render texture? Non-integer values can then be used without edging artifacts.
Just tried it. Works well most of the time, but there are some artifacts when the camera is shaking a lot. Pretty strange. Are there any examples of doing this properly?

Or you could try that renderer (evil self promotion :P): https://github.com/SFML/SFML/wiki/Source%3A-ShaderTileMap
Sorry, that would require changing lots of stuff I've already wrote :S
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on July 27, 2015, 07:59:27 pm
Have you considered pre-rendering to a render texture? Non-integer values can then be used without edging artifacts.
Just tried it. Works well most of the time, but there are some artifacts when the camera is shaking a lot. Pretty strange. Are there any examples of doing this properly?
I'm not sure there is much to do 'properly'  ;D
What artifacts are you getting? I'm assuming that you're rendering to integer values on a render texture and then displaying the render "sprite" at non-integer (if required) and applying camera shake to this sprite.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on July 28, 2015, 09:22:40 am
Have you considered pre-rendering to a render texture? Non-integer values can then be used without edging artifacts.
Just tried it. Works well most of the time, but there are some artifacts when the camera is shaking a lot. Pretty strange. Are there any examples of doing this properly?
I'm not sure there is much to do 'properly'  ;D
What artifacts are you getting? I'm assuming that you're rendering to integer values on a render texture and then displaying the render "sprite" at non-integer (if required) and applying camera shake to this sprite.

Yes, I'm rendering to integer values and then randomly change view's position (non-integer coords).
I'll try it on a more simple examples, maybe I'm doing something wrong. :S
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 01, 2015, 10:30:24 pm
Nothing special to show off: I'm mostly refactoring my code and making some code a lot better :D
But I've made ladders today:
(http://i.imgur.com/xF1IWB5.gif)
The perpective is quite off, so I'll be working on that!
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on August 03, 2015, 09:24:31 am
I wonder that there's perspective at all. ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on August 03, 2015, 10:04:57 am
Not only the ladder's perspective, but especially the cliffs with a "sideward slope" have a strange perspective. Looking at the trees and game characters, the player is looking a bit from the front, I think you should maintain this consistently.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 03, 2015, 10:42:45 am
Yeah, I agree. To make the perspective better, I need to draw more tiles, though. This is pretty hard but I'll try :)
Check out cliff perspective in Mother 3 (http://starmen.net/mother3/walkthroughs/maps/Chapter%201%20Maps/Forest%20Grotto%20(smoke).png) or in ALttP (http://s1.hulkshare.com/song_images/original/3/f/0/3f081ebcf9d4b30e8e09de2ef939c3d0.jpg?dd=1388552400)
Both look kinda weird, but I think I want my cliffs to look more like in Mother 3.

I've made a quick fix to see how cliffs would look, it's a bit better than what I have now:
(http://i.imgur.com/RrkabAK.png)
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on August 03, 2015, 11:56:30 am
I would make the ladders straight I think. Making it wider at the end looks weird, especially when your character doesn't get bigger climbing it.
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on August 03, 2015, 12:41:37 pm
Elias, the cliff already looks much better on the left edge (not on the right though ;)).

Yes, I'd make ladders straight too. Your graphics follow a parallel projection, so it looks weird when single objects have perspective.
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on August 03, 2015, 01:23:23 pm
+1 Nexus
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 03, 2015, 08:52:22 pm
The cliffs look a whole lot better when seen consistently from one angle (the newer version), in my personal opinion.

The ladder is a weird one, though. It looks slightly odd having perspective but maybe it's necessary to suggest its angle. A flat width ladder would look more like a bridge.

You should also note that this "consistent angle from the front" is not a requirement of this particular style. See the inside scenes where you can see the inside of the "closest" wall.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 04, 2015, 01:08:12 pm
Thanks for the feedback, everyone. I'll try different perspective styles to see what looks the best.

Worked on the tileset today. I think it's a big improvement.
(http://i.imgur.com/8yYQaKg.png)
Still unsure about the perspective.
Here's another way to do it:
(http://i.imgur.com/EJzHdlj.png)
(Notice the bottom part. I don't like that one because it's not that obvious that there are different heights there)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 04, 2015, 02:41:36 pm
I think you should always have a small border around cliffs to show that they are cliffs rather than just a different style of grass. I found an image of some cliffs from a Link to the Past to give an example. Note the cliffs south west from Link, you can still see the face in what is the same perspective as in Re:creation.
(http://s.uvlist.net/l/y2006/08/26447.jpg)
I do realise that depending on how you look at it, it could look like the rocky ground is below the grass in terms of altitude, but the shadows work well to show that they are cliffs.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 05, 2015, 07:00:12 am
@shadowmouse Thanks for your observation. I think not having grass on such cliffs helps to make contrast even more high.

As for the ladder... I've been thinking about perspectives in top-down games. Most games don't use Zelda's perspective (look at the side and bottom walls!)
(http://www.vizzed.com/vizzedboard/retro/user_screenshots/saves31/319161/SNES--Legend%20of%20Zelda%20The%20%20A%20Link%20to%20the%20Past_Jan9%2013_05_58.png)

They use other projection which makes other walls not visible.
Seiken Dentesu 3:
(http://venturebeat.com/wp-content/uploads/2013/03/sd33.jpg)
Chrono Trigger:
(http://www.mobygames.com/images/shots/l/65821-chrono-trigger-snes-screenshot-lucca-s-house.png)

I like this perspective more and it seems that drawing in that perspective is easier. But I feel that this may limit indoor level design. I want some rooms to be connected with each other, but there isn't a good way to show some doors: all doors must be on the wall which player sees. Zelda's perspective lets you put doors on every wall you like.

Any thoughts on this?
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on August 05, 2015, 08:18:46 am
Form follows function; ergo the Zelda one would fit better, clearly.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 05, 2015, 12:12:59 pm
A similar discussion about this kind of perspective (it started with this post (http://en.sfml-dev.org/forums/index.php?topic=14965.msg118035#msg118035)) came up on the forum for Witch Blast, which - as you can see from that thread - ended with sticking to the original perspective, after trying out the other type and considering doors on the near wall etc., although Cirrus Minor did seem to personally prefer the original perspective so it could just be down to your own personal preference.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 05, 2015, 02:12:43 pm
@Tank, indeed!

@Hapax, I'll stay with Zelda-ish perspective for now until I see something that fits the game more. I think I'll mix perspective styles as long as it looks good. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 09, 2015, 12:00:55 am
Didn't have much time to work on the game in the last few days, but I still managed to do something cool.
Levels now support multiple tilesets. I can easily switch between them in the level editor.
(http://i.imgur.com/Zd7TiIT.gif)
Previously, I only had one tileset per level, because I've thought that having city tileset / forest tileset / dungeon tileset etc. for each level would be okay. But then I've realized that it would be cool to mix tilesets instead of copy/pasting some tiles between tilesets
Another issue I'm thinking about is how to assign unique ids to tiles. I've previously used integer ids which were assigned like this:
(http://i.imgur.com/cWR9kDa.png)
This is pretty straightforward approach and it lets me easily get texture coordinates of the tile by its id.
But it leads to some problems:
1) Changing the width of a tileset breaks ids, because they correspond to other tiles.
2) If I change the ordering of tiles, I need to replace their ids with new ones in the level.
So, I need a better approach. I think that generating some tileset file like this:
x=0,y=0,id=G
x=16,y=0,id=G2
...
Then I can freely change width of tileset and swap tiles by changing their ids in a tileset file.

What do you think of that? Maybe there are some cooler methods to store tilesets and levels? :)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 09, 2015, 10:53:28 am
It might well be similar to what you are doing, but you could make an unordered_map which has a key type of either string or int (depending on how you store your level data) and a value type of a user defined struct which stores a reference to an sf::Image (which contains the relevant tile set) and an sf::IntRect for position. This way the code wouldn't be in an easily modifiable file, and you could even store it in a dll so that you can update it easily if you plan on releasing patches rather than entirely new builds of the game.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 09, 2015, 07:28:49 pm
What do you think of that? Maybe there are some cooler methods to store tilesets and levels? :)
I think integer IDs is reasonable for most cases. Changing the width of a tileset is, in effect, inserting new tiles into the set so IDs being reassigned is an expected repercussion. Prepare the width of the tileset in advance, once  :P

That said, an enum could ease this rearrangement (albeit in a rather verbose way):
(click to show/hide)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 09, 2015, 07:32:22 pm
I was going to suggest that, but I thought having position independent from width would make it easier to add tiles as you could just add things at the end of the list with a position that isn't at the bottom of the image.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 10, 2015, 08:50:17 am
It's hard to know the width of the tileset which would be enough. Sometimes I arrange tiles into large chunks, so then it's easier for me to create levels. Using enums is not possible, as it would require hardcoding.
So I think I'll stick with randomly generated ids for now. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 10, 2015, 12:52:06 pm
Using enums is not possible, as it would require hardcoding.
Yes, but only once  :P
Much better than having to re-assigning all the IDs manually and it's pretty lightweight.

Having customised textureRects for each tile seems like overkill for a tileset in a grid but it'll work. The added advantage of this is that you can then start to use irregular tilesets  ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 10, 2015, 02:53:19 pm
Yes, but only once  :P
Huh? But I would need to change this enum each time I add new tile type. And then I would need to recompile. Nope!
And I don't plan to have customized textureRects, all I need is (x,y) coordinate, the tile size would stay the same for all tiles.

Much better than having to re-assigning all the IDs manually and it's pretty lightweight.
I would re-assign only those IDs which I would change in the tileset if I use the method which I talked about.

Suppose that level is stored this way:
GGGGGG
GGGGGG
GGRRGG
GGGGGG
...

G is a grass tile and R is a road tile.
Suppose tileset file looks like this:
x=0,y=0,id=G
x=16,y=0,id=R,
...

What if I've decided to move grass tile in other place in the tileset, like (32,32)?
All I need to do is replace x and y coordinates in tileset file.
x=32,y=32,id=G
x=16,y=0,id=R,
...
The level file would not change at all. :)
If I change the width of the tileset, nothing would change in a tileset, all I need to do is add new tile ids in a tileset file.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 10, 2015, 03:31:33 pm
And I don't plan to have customized textureRects, all I need is (x,y) coordinate, the tile size would stay the same for all tiles.
By customised, I mean that the textureRect's position is customised i.e. out-of-order. In fact, it could be off-grid if the x and y co-ordinates are texture resolution (and it could have a custom size), but I realise now you probably mean that the x and y would be grid positions e.g. x = 6 for the seventh tile on that row.

Much better than having to re-assigning all the IDs manually and it's pretty lightweight.
I would re-assign only those IDs which I would change in the tileset if I use the method which I talked about.
"Re-assigning all the IDs" here meant your original IDs, where you would have to change them all manually.

x=0,y=0,id=G
x=16,y=0,id=R,
...
This is where the enum could still be used: the "id"; you'd be using an identifier anyway.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 10, 2015, 05:30:39 pm
By customised, I mean that the textureRect's position is customised i.e. out-of-order. In fact, it could be off-grid if the x and y co-ordinates are texture resolution (and it could have a custom size), but I realise now you probably mean that the x and y would be grid positions e.g. x = 6 for the seventh tile on that row.
I originally thought about having x and y be positions on the texture, but now I realize than this is not necessary, grid positions are all that is needed.

"Re-assigning all the IDs" here meant your original IDs, where you would have to change them all manually.
Well, that's not that hard, I think :)

This is where the enum could still be used: the "id"; you'd be using an identifier anyway.
As I said before, I can't let myself hardcode stuff (there will be lots of tile types, sometimes near hundred or more), creating some file and then creating std::map from it  seems better for me.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 10, 2015, 06:01:01 pm
"Re-assigning all the IDs" here meant your original IDs, where you would have to change them all manually.
Well, that's not that hard, I think :)
I meant changing the the level manually, as was your first concern.

As I said before, I can't let myself hardcode stuff (there will be lots of tile types, sometimes near hundred or more), creating some file and then creating std::map from it  seems better for me.
Fair enough. Enums can get pretty long, pretty quickly  ;D
The consideration with using an std::map is what to use as the key. Would that still just be an integer? A string?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 11, 2015, 08:07:50 am
I meant changing the the level manually, as was your first concern.
I won't change the level manually, I will change the tileset manually, but maybe I'll write a short program which will let me do this with some cool GUI ;)

Fair enough. Enums can get pretty long, pretty quickly  ;D
The consideration with using an std::map is what to use as the key. Would that still just be an integer? A string?
Enums also make modding harder. People can't create custom tilesets that way, only redraw the existing ones. :)
I think I'll use strings because this would let me assign meaningful ids to some tiles.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 11, 2015, 04:29:38 pm
Going back to an earlier subject, I remembered that you had a problem with implementing a render texture. Did you fix this? An idea came to me randomly: the views on the render texture and window would need to be controlled individually. Odd views may have caused your vibration. I think that's the problem you were having, right?
If it's not this, or you fixed it anyway, just ignore this post  ;D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 12, 2015, 03:59:40 pm
Going back to an earlier subject, I remembered that you had a problem with implementing a render texture. Did you fix this? An idea came to me randomly: the views on the render texture and window would need to be controlled individually. Odd views may have caused your vibration. I think that's the problem you were having, right?
If it's not this, or you fixed it anyway, just ignore this post  ;D

I think that the problem I was having is that view's coordinates were not integer during screen shake (I forgot about that when I was trying to fix that). I'll come back to it later. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 19, 2015, 08:54:43 am
Sorry for the lack of updates. Some RL stuff going on + I have lots of other stuff to work on/learn. :)
I'm mostly doing refactoring now and thinking about making some fundamental systems in the game better and more stable.
There's a lot of stuff to do to make game more polished. This is sometimes very hard and boring, but it needs to be done.
And I've almost completed the first article of "Using Lua in practice" series. I hope to release it today or tomorrow.

I'm also learning some OpenGL. What are some books/tutorials would you recommend? (Preferably OpenGL 3.x because my graphics card doesn't support OpenGL 4, heh).
Title: Re:creation - a top down action rpg about undeads
Post by: victorlevasseur on August 19, 2015, 09:10:00 am
Here is one I used to learn a bit of modern OpenGL : http://www.opengl-tutorial.org/
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 19, 2015, 11:08:32 am
Here is one I used to learn a bit of modern OpenGL : http://www.opengl-tutorial.org/
Thanks, I've read some articles there and they are pretty good :)

Also, Using Lua and C++ in Practice (https://eliasdaler.wordpress.com/2015/08/10/using-lua-and-cpp-in-practice/) is out.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on August 19, 2015, 09:14:28 pm
I'm also learning some OpenGL. What are some books/tutorials would you recommend? (Preferably OpenGL 3.x because my graphics card doesn't support OpenGL 4, heh).

I'm a fan of https://open.gl/. It even has a guide of setting up an OpenGL context and input handling with SFML (along with SDL and GLFW).
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 20, 2015, 07:10:02 am
I'm a fan of https://open.gl/. It even has a guide of setting up an OpenGL context and input handling with SFML (along with SDL and GLFW).
Thanks, I'll check it out :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 21, 2015, 05:47:04 pm
Making walking animations.
(http://i.imgur.com/kh0tCj6.gif)
(http://i.imgur.com/EmQKopQ.gif)

I've made enemies more detalized. I'm a lot more satisfied with how they looks now.
(http://i.imgur.com/YgDbvSe.png)

I need to draw three attack animations (up, down, side) and then I'll work a lot on the battle system. I'll try different stuff.

In most games like top-down Zeldas enemies can attack you in two ways: either by running into you or shooting/throwing some stuff at you.
I want to make attack animations for enemies who carry swords. Zelda doesn't have them, enemies with swords just run into you. But making sword attack work good is harder. I think I'll try to create some pre-attack animation which will indicate that enemy is going to attack so that the player can dodge. Any thoughts on this? I can't think of top-down games like Zelda which had good real time battle system (I want to see how other people have done it)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 21, 2015, 06:11:48 pm
Those animations and new sprites are really good. I like the idea of adding sword swinging as the zelda enemies often look like they have some sort of pike or something and can't swing it, which is stupid (either than or they're just trying to stick you with the pointy end). As for the pre-attack animations, maybe they move their sword arm out, then swing it across they're body to attack? Are you making multiple versions of the knight armour? Like maybe a commander with a different helmet in each group. One suggestion I'd have is to actually draw several versions of the knight (by copy and paste) and give each different hair (black, brown, blond and the occasional ginger), then in your files which hold the data for where you place knights (I'm presuming you didn't hardcode this) you can specify a hair colour, or by default it could be black. This would mean that large groups of knights won't look like clones. It's a similar idea to in Besiege where each time you kill someone, it tells you their name so as to give each enemy some individuality.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on August 21, 2015, 06:24:31 pm
For the attacking, an event/message/etc might work well. Play the attack animation like any other animation, but, make it send a message at the point when you want the attack to damage something.
Have some sort of listener that checks if there is a damageable object in range of the swing. If so, damage that object. If not, do nothing.

Though, that would only make the swing damaging at one point in time. If it's a wide swing, for example, technically it should damage anything it intersects at any point during the animation. In that case, maybe a collision box around the weapon would be good. Then you can just use your existing collision system, probably.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 22, 2015, 12:10:42 am
Looking good :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 22, 2015, 09:00:02 am
@shadowmouse No, the armor would be the same for sword guys, maybe some colors will differ. Making different hair is a good idea, but I need to create some system which will replace colors in sprites, because copy-pasting sprites by hand is a waste of space and time

@dabbertorres The problem is not technical, I'm just thinking what would feel and play the best. It's a game design problem.

@Hapax thanks! :D
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 22, 2015, 09:56:04 am
Maybe make a version of green screening and colour the hair a colour that isn't found anywhere else in the sprite then you can pass the exact value of the green colour and its replacement? You might be able to find a standard green that you can use as a default.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 23, 2015, 08:56:25 am
Maybe make a version of green screening and colour the hair a colour that isn't found anywhere else in the sprite then you can pass the exact value of the green colour and its replacement? You might be able to find a standard green that you can use as a default.
Yeah, this should work, thanks.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 23, 2015, 11:05:26 am
New character! A mysterious cute cat with no name. (yet)
(http://i.imgur.com/MW2oSOH.png)

I'm also drawing sprites for Undead Bar. Lots of cool stuff is drawn already will show off soon!
Here's one of the sprites. I love how much depth the shading adds.
(http://i.imgur.com/6vcRPf1.png)
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on August 23, 2015, 02:44:19 pm
I'm also learning some OpenGL. What are some books/tutorials would you recommend? (Preferably OpenGL 3.x because my graphics card doesn't support OpenGL 4, heh).

I'm a fan of https://open.gl/. It even has a guide of setting up an OpenGL context and input handling with SFML (along with SDL and GLFW).

I prefer http://learnopengl.com/ it starts out almost the same, but has more stuff to do.
Title: Re:creation - a top down action rpg about undeads
Post by: namosca on August 24, 2015, 11:06:54 pm
I would really like to download the game, but I really didnt manage to find the link?

Could you post it to us?

I would prefer (if possible) to have the binaries for windows, instead of having to compile everything myself. I am tiring of compilling errors all the time.

If the game is fun, I would also like to have a look at the source if you can make it available for us!!

Thanks!!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 25, 2015, 08:27:48 am
@SpeCter thanks, I'll check it out!

@namosca The game is not out yet. When the public game is released, you'll know about that either by this thread or my twitter. There will be Win/Linux/Mac OS X binaries, of course.

I'm thinking about open sourcing my game's code, but I think I'll do it after some time after release and if the code is good enough for other people to look at. :)
Title: Re:creation - a top down action rpg about undeads
Post by: SeriousITGuy on August 25, 2015, 11:51:21 am
Thanks for the progress update and the LUA articles. Exactly the thing I want to learn right now. Keep up the great work. Maybe one day you can actually sell this already cool looking game (Steam Greenlight, Itch-io or similar).
And I am very interested in your code, from what I've seen from your articles it must be good quality, so I would be very glad to work through your code base. Maybe you could also right some articles on key points of your engine.
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on August 26, 2015, 08:55:53 am
The cat is great! Nice work. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 26, 2015, 08:10:44 pm
The cat is too cute. Take it away or I may have to steal it and adopt it! <3
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 26, 2015, 08:41:58 pm
Have you thought of a name for it or will you be taking votes?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 26, 2015, 11:30:35 pm
@SeriousITGuy, you're welcome. And thank YOU for reading my articles and dev log. Glad you've enjoyed it. :)
As for the code... As I've said before, only the best parts get posted. My code has some quickly written parts which kinda work but are not good. I'd fix them if I had time... but I don't always have enough.
I plan to write articles about my engine's structure (some of it can already be found in my dev logs and some will be in "Using Lua in Practice" series)

@Tank, thanks!

@Hapax, thanks! :D
And it's not even its final form of cuteness. I will post even more cuter portrait soon.  ;D

@shadowmouse, didn't think of a name for it yet. I need to come up with something clever to show its true character. ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 27, 2015, 12:24:35 am
it's not even its final form of cuteness. I will post even more cuter portrait soon.  ;D
You're going to kill me!
Is what you're suggesting even possible?  ???
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 27, 2015, 01:11:21 am
it's not even its final form of cuteness. I will post even more cuter portrait soon.  ;D
You're going to kill me!
Is what you're suggesting even possible?  ???

Ha-ha. I still don't know the limit of the cuteness I can make! :D
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on August 27, 2015, 08:13:04 am
Re:cuteness - a top down action rpg about kittens
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 27, 2015, 08:24:34 am
Maybe when you finish the game once, you unlock cute mode and all characters become kittens.
Title: Re:creation - a top down action rpg about undeads
Post by: SeriousITGuy on August 27, 2015, 09:52:21 am
Why everyone on the internet freaks out about cats, I don't get it :D
( ok from a game designer point of view a cat could make up a very cool character, something like the cat from Alice in Wonderland :D )

@Elias: Hey it's your code you can do whatever you want. If you plan on writing articles about your engine it is more than enough for me to study on ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 27, 2015, 10:53:47 am
@Tank, that's a good idea for a spin off game! :D

@shadowmouse, that would be cool, but just imagine how much of the artwork I'd have to create!

@SeriousITGuy, cats are cute. People like cute things. ;D
The cat has even more value from the game design point. (It's a secret for now!)
As I write "Using Lua with Practice" articles, I realize that Lua connects a lot in my engine and that's why looking at Lua/C++ stuff I've got is going to give you a pretty good idea of what's going on it my engine. :)

(P.S. I wish there were some good articles/books like this. Game Engine Architecture is the closest I've seen to what I need so far.)
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 27, 2015, 12:56:13 pm
Why everyone on the internet freaks out about cats, I don't get it :D
Did you not see it?
(http://i.imgur.com/MW2oSOH.png)

It's bordering on being as cute as:
(http://i.imgur.com/NwcdVvG.jpg)

The cat has even more value from the game design point. (It's a secret for now!)
Is it related to Egypt?  :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 27, 2015, 07:21:25 pm
@Hapax, nope :P

I've spent 3 hours drawing carpets today. They're pretty hard to draw (especially the round one!)
The stone wall tile was drawn a while ago and I've finally found a place to use it. I'm a lot more satisfied with the look now. (compare it to a previous screenshot!)

(http://i.imgur.com/lFqs8uq.png)
Another carpet:
(http://i.imgur.com/Z8Ipjaj.png)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on August 27, 2015, 07:30:32 pm
That stone and carpet combine really well with the general theme of the place, I think they make it look a lot less generic. Just to clarify, it wasn't generic the first time (especially because of the cat), but it is now even more not generic.
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on August 28, 2015, 08:49:00 am
That looks so cozy that I immediately want to play some x-mas tunes and drink tea while watching the snow outside...just that there's none. Looks nice, I really like your art style :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 28, 2015, 06:03:09 pm
@shadowmouse, thanks! I was trying out some colors (I wanted to see if the place would look better with more of them). Turned out quite good :)

@Tank, thanks! After reading your post I've decided to add some cozy music to this place. I've already written bossa nova track for my game and I think it may fit nicely here. :)

By the way, my awesome GF made this for me!
(http://i.imgur.com/uf4kKio.jpg)

Zelda's "Got item" sound
(http://i.imgur.com/SCO5CYT.png)
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 28, 2015, 10:14:43 pm
By the way, my awesome GF made this for me!
Let's hope you don't change the graphics again!
That's right; today, I looked at your progress album...
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on August 28, 2015, 11:07:58 pm
By the way, my awesome GF made this for me!
Let's hope you don't change the graphics again!
That's right; today, I looked at your progress album...

Ha-ha, well, I can make Re:creation Woolly World now!

What do you think of the progress album?
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on August 29, 2015, 01:58:22 pm
I found it interesting. It's comforting to know how often people change their minds during development!
Still, think of how far along the game would be now if you'd've put all the time into the game development instead of drawing new graphics  ;D
Title: Re:creation - a top down action rpg about undeads
Post by: nebula on August 29, 2015, 04:02:49 pm
Dude this is awesome work.
Really like what you did there!

Keep it up ;-)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 01, 2015, 08:36:03 am
I found it interesting. It's comforting to know how often people change their minds during development!
Still, think of how far along the game would be now if you'd've put all the time into the game development instead of drawing new graphics  ;D

Yeah, I like to look at the progress albums for the same reason. (And it's also pretty interesting to look at my game's progress too! :D)
Yep, the game would be a lot larger and more developed. But think how far along it would be if I worked on it full time? Or if I didn't spend so much time posting about my progress/reading some stuff on reddit/etc.?
There's a lot of reasons for a game taking long to develop. Doing art for yourself is just one of them. And previously I didn't like it (even hated it sometimes). But now I'm pretty okay with that, lots of times I even have lots of fun drawing art. I've just accepted as a fact that finding an artist who's willing to work for revenue share is almost impossible, so all I can do for now is to deal with it! :D

@nebula, thanks!

Progress update
Finally I've figured out the way to store components continuosly in memory. It may not give the significant speed up (but I'll post the results of testing!) but it will be very helpful for the future. (And for other games I'll work on using the same engine).

I'm still working on this, but I will post the source code soon (probably this month) so people can use it for their own games. I would also love for people to propose some ideas about how I can make this system better.
Note that I won't post the source code of my engine. It's a completely separate prototype project with some tests but it would show most of the stuff I'll integrate into the game later.

The main principle is what someone later proposed in this thread.

I have this class:

class IComponentList {
...
};

and this class:

template <typename T>
class ComponentList : public IComponentList {
...
private:
    std::vector<T> components;
}

and then this map:

std::map<std::type_index, IComponentList*> componentLists

where key is std::type_index is std::type_index(typeid(T)) where T is a type of the component a corresponding value (a component list) holds.

I can currently get the list I need like this:

auto& list = ComponentManager::getInstance().getComponentList<SomeComponentType>();
 
The entity class interface remains the same, though. I still have:

class Entity {
...
    std::vector<Component*> components;
}

But now the entity points to components inside the component lists.
This is harder to implement than it looks, because:

1) Changing the position of a component in a component array invalidates the pointer in Entity so I have to change it manually
2) If I insert some new components in some vector L and the size of the vector is more than it's capacity, it will reallocate which means that every component pointer (of component type which L holds) in every entity becomes invalid.

This is not a big problem, though!

The first problem is easily solvable. The second is a bit harder, though.
I can fix it by reserving enough memory for each component vector so it won't reallocate again when the game is running (vectors would need to change it's sizes during level load but this is not critical, changing some pointers is not that hard during that.)
How can I know how much components of each type there will be? Easy. I have a list of every entity on the level in a level file which means that  I can count how much of each component time I would need.
What about entities which could previously create entities when the game was running (like bows which created arrow entities). I won't do this anymore! Allocating memory on when the game is running is bad anyway.
So, each entity can explicitly show that it can create new entities and each component list would get additional size to allocate.
For example, you won't see more than 1-2 arrows flying from the same bow on the screen. This means that I can reuse the same arrow entity over and over again. I will create arrow entity for each bow entity when the level loads and there's no need to create entities during gameplay anymore.
So, those limitations lead to some great improvements of other things! There are more aspects which I'll cover later.

P.S. Anyone knows any good articles about C++ templates? Especially about header dependency aspect of it. I want to make templates the way that they won't cause more recompilation then necessary (this is very easy to make if you're not careful).
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on September 01, 2015, 09:06:39 am
P.S. Anyone knows any good articles about C++ templates? Especially about header dependency aspect of it. I want to make templates the way that they won't cause more recompilation then necessary (this is very easy to make if you're not careful).
Using 'extern template's can help a great deal with that often. See this: http://en.cppreference.com/w/cpp/language/class_template (the section about "Explicit Instantiation")
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on September 01, 2015, 10:22:36 pm
But think how far along it would be if...
I didn't mean to suggest that it is progressing slowly. I'm sorry if it came across that way.
I think it's coming along great and I find its progress fascinating  :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 01, 2015, 11:17:47 pm
@Jesper Juhl, thanks. I've read the article but don't have an idea how to use this effectively (probably because I don't know some stuff about templates and header dependency). Can you provide any useful examples of using extern template in my case?

@Hapax, no offence taken.
Thanks, glad you like the progress :)
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 01, 2015, 11:22:52 pm
Quote from: Elias Daler
What about entities which could previously create entities when the game was running (like bows which created arrow entities). I won't do this anymore! Allocating memory on when the game is running is bad anyway.
A static pool wastes lots of memory and is a really bad idea. Unless you have really low memory requirements, I wouldn't go this way out of lazyness to implement a proper solution ;)

Quote from: Elias Daler
P.S. Anyone knows any good articles about C++ templates? Especially about header dependency aspect of it. I want to make templates the way that they won't cause more recompilation then necessary (this is very easy to make if you're not careful).
Explicit instantiation (see Jesper's post) and type erasure/PImpl are the most promising approaches, but they can only be applied in special cases.

Unfortunately, in most cases you simply don't have another option than keeping templates in the headers. Still, try at least to outsource parts that aren't dependent on template parameters, and avoid too deep dependencies... Sometimes it's worth trading off compile-time type safety for less code bloat and compilation time.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 02, 2015, 06:58:07 am
@Nexus, most additional entities (arrows, bombs, etc.) would be pretty lightweight compared to big ones. For example, one arrow contains GraphicsComponent (sf::Sprite which shares sf::Texture with other arrows) and CollisionComponent (two pointers and one sf::FloatRect).
What's the better way of doing this instead of using object pools? I have one idea: I can still benifit from creating object pool of size which all entities on the level reqiure (I need to load them all anyway). Then I can create additional component lists for entities which may be created during gameplay. When some of these lists need to expand, I would manually swap the pointers after reallocation which won't invalidate the pointers of components stored in a bigger vector (which was used for all entities on the level).

Unfortunately, in most cases you simply don't have another option than keeping templates in the headers. Still, try at least to outsource parts that aren't dependent on template parameters, and avoid too deep dependencies... Sometimes it's worth trading off compile-time type safety for less code bloat and compilation time.
I guess I just don't get how dependant some files become from each other if I use templates.
For example, I have a createComponent<T> free function in ComponentManager.h
If I change some stuff about components for which this template function is created, would this cause ComponentManager.h to recompile too?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 03, 2015, 08:01:06 pm
Small progress update.
Still working on new ECS implementation. Improvements are quite nice. (Sorry, no pretty pictures, working on code)

Suppose I have two entity types:

ghost = GraphicsComponent
tree = GraphicsComponent + CollisionComponent

What if I need to create 4 ghosts and 10 trees? I need to create 14 GraphicsComponent's and 10 CollisionComponent's.
But, simply adding them via push_back to std::vector of GraphicsComponent and CollisionComponent is a bad idea. Why? Because vector will reallocate it's memory array several times invalidating all pointers to GraphicsComponent's and CollisionComponent's! (It will also make lots of copies when doing this).
Imagine if I had hunderds or thousands of components and copying them was not fast...

So, I've used std::vector::reserve instead which makes sure that no allocation will take place.
First, I count how much of each component types will be created. Then I reserve enough memory for each vector. And then I can safely create every entity. No allocations happen during this, yay!
Counting the number of items to reserve is not that easy as it may sound but it didn't take long to implement.

I hope to release source code to this ECS stuff soon! :D
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 04, 2015, 08:57:30 am
The pointer invalidation problem you're talking about is the reason why common ECS implementations store handles, not pointers.

If you have to specifiy an upper bound to the number of components and allocate a fixed number up front, you're severely limiting the usage of your ECS. It may work well for your specific game right now, but you'll have to rethink everything at one point...
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 04, 2015, 01:52:37 pm
@Nexus. Just impelemented handles. They work fine :D
Well, if I don't have an upper bound, this means that a vector may reallocate when some entity is created during the gameplay. This may cause lots of copying which may take a long time causing perfomance drop. The only way to prevent this (that I can think about) is to allocate enough memory up front (and add some additional memory for temporary entities, for example). Are there any other solutions to this problem?
Title: Re:creation - a top down action rpg about undeads
Post by: Laurent on September 04, 2015, 02:02:00 pm
Why don't you allocate components individually, and store pointers to them into your vector? It looks weird to use value/copy semantics on components.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 04, 2015, 03:07:06 pm
Why don't you allocate components individually, and store pointers to them into your vector? It looks weird to use value/copy semantics on components.
Because storing components in one array is better for cache, considering I have to iterate through them in every frame. If you allocate components individually (which I've done before), you get lots of cache misses.

This may seem like an over optimization and I've yet to test speed improvements, but I didn't spend much time making this, so I may throw it away then. :D
Title: Re:creation - a top down action rpg about undeads
Post by: Laurent on September 04, 2015, 03:21:43 pm
Quote
This may seem like an over optimization
This is very likely.

The problem now is that it drives a non-negligible part of your design and implementation. So you should really benchmark now, to avoid this kind of issues, and to possibly save one complete rewrite of the system in a near future ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 04, 2015, 04:45:29 pm
The problem now is that it drives a non-negligible part of your design and implementation. So you should really benchmark now, to avoid this kind of issues, and to possibly save one complete rewrite of the system in a near future ;)

Okay, I'll do that very soon, will report the results in this thread :)
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 04, 2015, 06:42:49 pm
The only way to prevent this (that I can think about) is to allocate enough memory up front (and add some additional memory for temporary entities, for example). Are there any other solutions to this problem?
Yeah, of course. std::vector is not the only container in the world.

[Premature optimization] is very likely.
This is probably true for medium-scale games like Re:creation, but the same can be said for many parts of the ECS, maybe even the choice of an ECS design itself. I think it can't hurt to know some alternatives, even if one is not going to use them in a game. But I definitely agree that profiling makes sense.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 04, 2015, 10:49:52 pm
Yeah, of course. std::vector is not the only container in the world.
I can't think of many data structures which store the data continuously in memory.

[Premature optimization] is very likely.
This is probably true for medium-scale games like Re:creation, but the same can be said for many parts of the ECS, maybe even the choice of an ECS design itself. I think it can't hurt to know some alternatives, even if one is not going to use them in a game. But I definitely agree that profiling makes sense.
There are several reasons for all this new ECS stuff. But yeah, this may not improve the perfomance a lot and I throw away the code without any hesitation.
It was just an interesting challenge which has taught me some things about templates, vectors and some C++11 which I've never knew before. I didn't spend much time doing this, so no regrets. :)

I agree that I have to do profiling. What is the best way to do this? Do I need to create some test data which I'll use or do I need to integrate this new system to be completely sure?
The one way I think I can test this is to compare how much time each system's update() function takes. It involves iteration through std::vector of related components so it may make some difference.
Title: Re:creation - a top down action rpg about undeads
Post by: lezebulon on September 05, 2015, 01:44:01 am
I've been looking at game designs things for year and I always see people praising ECS everywhere, except that I've never seen an ECS actually working well for a medium-sized game or more. Like, I get that an entity is any aggregation of components but I don't get how the logic will be simplified, because the logic would have to be working on the whole entity itself, and not each component independently anyway....

Anyway Elias, you don't need *absolute* contiguous memory for the whole iteration of all the components of a single type. You could store things in like an std::vector < std::array < ComponentType, 128 > > , so that 128 items will be contigous. From an index i, you can easily work out that the object should be placed at index (i/128, i %128), which will end up being calculated really fast. I admit this requires re-coding a whole new data structure but with the requirements you are saying, there is no way around that.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 05, 2015, 06:28:58 am
@lezebulon, ECS worked very well for me. I was getting stuck with standard OOP way of doing things and adding new stuff to the game wasn't this easy.
The logic doesn't have to be working on the whole entity. Most of the time (especially for collision, movement and graphics which is what the game is doing most of the time, other stuff is taking less much time) you don't need the whole entity, you are fine with just a component. So, when I draw entities, I just use graphics components which tell me nothing about what entities are these. When I check collision, I don't care what entities collided, I just care that they're collided and I just call their Lua response functions.

Well, that's a good idea, thanks. This way I can be sure that the vector doesn't take too much space. :)
I'll see if storing components contiguously is giving me advantage first, though. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 05, 2015, 12:09:53 pm
Because storing components in one array is better for cache, considering I have to iterate through them in every frame.
By the way: this whole cache story is only true as long as you iterate over a single component type. And in my experience, many systems need access to multiple components. For all those cases, performance is thrown out the window again.

I agree that I have to do profiling. What is the best way to do this? Do I need to create some test data which I'll use or do I need to integrate this new system to be completely sure?
The profiling should be done on data that is somewhat representative of a typical situation in your game. Ideally, you profile the game itself, but you can already draw conclusions from smaller experiments.

Whether you measure time in code or with an external profiler is your choice.

I admit this requires re-coding a whole new data structure but with the requirements you are saying, there is no way around that.
Such a data structure already exists in the standard library, even if it doesn't let you specify the bunch size. It's called std::deque. Know your tools 8)

Other than that, you have trade-offs like boost::stable_vector and what not. There are enough C++ libraries out there to have a look at before reinventing the wheel ;)
Title: Re:creation - a top down action rpg about undeads
Post by: lezebulon2 on September 05, 2015, 12:54:12 pm
@lezebulon, ECS worked very well for me. I was getting stuck with standard OOP way of doing things and adding new stuff to the game wasn't this easy.
The logic doesn't have to be working on the whole entity. Most of the time (especially for collision, movement and graphics which is what the game is doing most of the time, other stuff is taking less much time) you don't need the whole entity, you are fine with just a component. So, when I draw entities, I just use graphics components which tell me nothing about what entities are these. When I check collision, I don't care what entities collided, I just care that they're collided and I just call their Lua response functions.
But for instance, if thé collision response is to move back the object, how do you tell the graphics component that it has to move?

Àbout needing your data to be contiguous: as I said you probably don't care if instead of iterating over 300 items in an array you do it 3 times for 100 items per array, I doubt thé cache miss world be important
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 05, 2015, 04:37:08 pm
By the way: this whole cache story is only true as long as you iterate over a single component type. And in my experience, many systems need access to multiple components. For all those cases, performance is thrown out the window again.
Yup, agreed. Didn't think of it.

Such a data structure already exists in the standard library, even if it doesn't let you specify the bunch size. It's called std::deque. Know your tools 8)
Didn't know it stored data contiguously. (Well, sort of...). My bad :)

But for instance, if thé collision response is to move back the object, how do you tell the graphics component that it has to move?
Events. Collisions don't happen frequently, so this is not a big perfomance issue.

Progress update
Okay, so I've created this wonderful scene:
(http://i.imgur.com/V3brnTW.gif)
Lots of entities, moving randomly.
I've tested this scene with old ECS system (components are stored randomly in memory) and new ECS system (components are stored contiguously in std::vector).
The results shocked me: there was no perfomance increase.
This is not a dissapointing result for me (but kind of stange... I was expecting at least some perfomance increase). In fact, I'm quite relieved that I don't have to integrate the new system into my project (this would be painful and long).
But this was not a complete waste of time. I've come up with lots of useful improvements for my old system when I was writing the new system, so I'll improve my old system with that. I'll come back to actually making the game soon. So, expect to see some cool screens in the future :)

P.S. Thanks for being critical, everyone. I would be stuck much longer with all that ECS stuff without a healthy dose of a good criticism. :D
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 05, 2015, 04:54:44 pm
Events. Collisions don't happen frequently, so this is not a big perfomance issue.
When I experimented a bit with ECS- and event/message-based systems, I initially had an event system capable of abstracting component inter-dependencies completely. That is, by introducing intermediate event types, a lot of classes wouldn't need to know each other. The event thus acted as an interface.

Everything looked great, but as my design became more complex, I found myself adding a lot of different event classes, most of which were merely adapters to their corresponding components. The need to duplicate data as well as the additional complexity in the data flow led me to rethink this idea. I concluded that code becomes far more understandable if as much functionality as possible is handled in systems, and a system would only affect the components it depends on (as a contract), not components on the other side of the world through events. There are still events for certain features, but it's no longer the main communication approach.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 05, 2015, 05:01:10 pm
@Nexus, so, if CollisionSystem needs to change some entity's speed because of collision, it would just use MovementComponent of the entity which collided directly instead of sending a message to MovementSystem? Am I understanding this right?
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 05, 2015, 05:15:25 pm
That's one possibility, however this design couples the collision detection with collision response. The collision system needs to know all the consequences of colliding, which is not ideal.

The systems affected by collision are already dependent on collision classes, as they react to collision events. So they could as well check the collision component directly. Systems will tend to depend on multiple component rather than one component and multiple events, so the cache aspect might be a bit worse, trading off code flow simplicity (and event's aren't free either). You can also work with both approaches and see what works better.

Sometimes you do need event queues, for delayed processing for example. What I wanted to say, is that in my opinion, the main idea of ECS is to handle communication between components in systems, and handling communication through events is somewhat contradictory to this idea. So I wouldn't use events exclusively, it also makes it quite difficult to understand what happens when. But as usual, combining multiple approaches can lead to the best results.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 05, 2015, 05:35:19 pm
@Nexus, yep, that's kinda what I'm doing at the moment. Sometimes events can lead to non-readable code.
Do you use some scripting for collision response, for example?

Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 05, 2015, 05:38:36 pm
No, I only used Lua to load configuration settings so far. It has been more an experimental project I've worked on a while ago, when I had more time... Not a complete game.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 05, 2015, 05:42:51 pm
So, how are you doing collision response then? There a lot of unique ways and object may react to collision based on its type. I wonder how it can be done without scripting.
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 05, 2015, 06:23:03 pm
Why would you need scripting? The logic can as well be implemented in C++, it's just a question of flexibility.

I used aurora::DoubleDispatcher (http://www.bromeon.ch/libraries/aurora/v1.0/doc/classaurora_1_1_double_dispatcher.html) for collision response.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 05, 2015, 07:07:24 pm
So, do you create free functions for each type of collision response and then bind it to Entity type?
I use scripting because it lets me quickly change the collision response logic quickly. I also use it for interaction response (what happens with entity if player interacts with it by pressing "interact" button)
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on September 05, 2015, 11:54:32 pm
Great job Elias.. very impressed with this project! It creeps me out how similar your ECS looks like to my previous approach. So much is exactly the same to what I used to have. Some parts I still have it, others not so much.

Either way, I think you are doing most things correctly, so just keep going! I don't really agree with some opinions here that oppose yours, but I'd have to support them a bit in saying that you should avoid complexity in favor of usability when the hit isn't very big.

Sometimes the time you save in development by doing something slightly less correct can pay off as well. Engineering time is a resource as much as memory or CPU, consider that :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 06, 2015, 09:02:45 am
@Grimshaw, thank you for encouraging words!
Do you store components contiguously or not?

Sometimes the time you save in development by doing something slightly less correct can pay off as well. Engineering time is a resource as much as memory or CPU, consider that :D
Yep, but it can improve the engine design a lot and save me lots of time in the future. It's hard to be sure from the beginning. :D
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 06, 2015, 03:47:02 pm
It's hard to be sure from the beginning. :D

That's right! I faced this at my project, too. But finally my major performance problems were fixed after reimplementing my ECS. Btw I use a contiguously approach for components only. More highlevel gameplay elements (like items or spells) are dynamically allocated. I haven't tested this referring to performance yet, but I think (of course depending on the type of game) it might be acceptable.

Btw: Your screenshots etc. look really great! I'm curious about the final version :)
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on September 06, 2015, 08:12:42 pm
Just to add other container types to the discussion, I've used Google's dense hash map (https://github.com/dabbertorres/GoogleHashMaps) (I exported from Google Code, I haven't found an official repository since it closed) and haven't noticed issues with it.

In addition, I've found and heard b-trees (https://en.wikipedia.org/wiki/B-tree) (not binary trees) can be a good choice as well.
Title: Re:creation - a top down action rpg about undeads
Post by: lezebulon on September 06, 2015, 09:58:50 pm
Events. Collisions don't happen frequently, so this is not a big perfomance issue.
Sorry I don't get it,
I'm assuming that for collision you run the collision update method on something like std::vector<ColisionCpt> , right ?
In that case, how do you know which entities the event should refer to ? Or does your collision component hold a pointer to an entity ?
And when firing the event, by what system do you know that entity A should respond to the collision by dying (for instance), and that entity B should respond by moving back? Is that because the collision response is a virtual method?
Title: Re:creation - a top down action rpg about undeads
Post by: Grimshaw on September 07, 2015, 02:31:21 am
@Grimshaw, thank you for encouraging words!
Do you store components contiguously or not?

Sometimes the time you save in development by doing something slightly less correct can pay off as well. Engineering time is a resource as much as memory or CPU, consider that :D
Yep, but it can improve the engine design a lot and save me lots of time in the future. It's hard to be sure from the beginning. :D

Yes I do, but its not a hard requirement. I basically have one pool per component type, which hands me N component instances when I ask for them.. So most of them should be contiguous, most of the time, but the world subsystem will work with even components allocated with new if I prefer it. You should totally commit to making the best library of components you can, either with behavior in component or component + system.

How you put these components together could and should be less hardcoded and allow more flexibility from game code.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 07, 2015, 08:48:31 am
@Glocke, well, reworking the system didn't help me. Guess the performance of my game was always pretty okay. Storing components contiguously was more like an exercise, I guess. And thanks!

@dabbertorres, thanks, that looks interesting. Didn't know about those structures.

@lezebulon, yep, all components store the pointer to Entity which owns them. (But I would store entity's id in the future, because I can quickly get entity by its id). So, one system may construct event which contains entity's id and other system will process it.
But I sometimes use the approach which Nexus has told about. Sometimes it's better for system to handle multiple components. In my case, if I need to change some components in one system, I may get this component by another component's owner pointer.

And when firing the event, by what system do you know that entity A should respond to the collision by dying (for instance), and that entity B should respond by moving back? Is that because the collision response is a virtual method?
This is all done by scripting. When two entities collide, a Lua function for each entity is called which does all the stuff.

@Grimshaw, did you notice any perfomance differences when storing components contiguously and not contiguously?
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on September 07, 2015, 01:00:16 pm
Please forgive me if I'm being dense here (I haven't used Lua) but what advantage does the scripted onCollision function have over a C++ std::function callback? Is it purely so that you can change it on the run without recompiling? Or is it something else?
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 07, 2015, 01:35:49 pm
Guess the performance of my game was always pretty okay.
This is all done by scripting. When two entities collide, a Lua function for each entity is called which does all the stuff.
On which type of system have you tested that your performance is pretty ok? I'm curious about testing it on my netbook (despite it is of course no gaming computer^^).
Title: Re:creation - a top down action rpg about undeads
Post by: lezebulon on September 07, 2015, 09:20:12 pm
This is all done by scripting. When two entities collide, a Lua function for each entity is called which does all the stuff.

Sorry I'm really not being clear :)  what I didn't get was, how do you determine which Lua function to call on the entity? At this point, you only know that 2 entities collided, and each entity is defined only by the list of its component (if I understood). So based on this, how do you figure out which Lua response to call ? I can think of several ways of doing it, but none that would be flexible enough and be in O(1)

Sorry I'm asking so much btw, I've always seens tons of ECS thrown around , but on every implementation it seems they never manage to make the whole thing work in constant time (with respect to the number of total component, system, etc). Whereas for me the point of ECS is that it's really easy to scale
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 07, 2015, 11:02:45 pm
Implementing a double dispatch system in O(1) is relatively easy: you create a 2D table of function objects/pointers, where each row and column is indexed by the entity type. Each cell contains the function for the combination of the row and column types. The type can be any criterion stored in any component.

You should really have a look at aurora::DoubleDispatcher (http://www.bromeon.ch/libraries/aurora/v1.0/doc/classaurora_1_1_double_dispatcher.html), it uses std::unordered_map and thus amortized O(1). :)
Title: Re:creation - a top down action rpg about undeads
Post by: lezebulon on September 08, 2015, 01:05:55 am
Implementing a double dispatch system in O(1) is relatively easy: you create a 2D table of function objects/pointers, where each row and column is indexed by the entity type.
Yup, but how is the concept of "entity type" even defined ? Usually the "type" is defined by the class hierarchy, but since there's no class hierarchy in an ECS, for me it's either:
- an entity type is an instance of an entity, which means a full vtable for each instance (still doesn't explain according to what criteria it should be filled)
- an entity type is a given combination of components, which means that they are 2^N possible entity types for a total of N components. Which means that we have to careful think about which combination of component should be dispatched to which virtual function.

I mean, it seems to me that there's always a point where, if we want to keep everything flexible, we are facing a combinatorial explosion simply because an entity could be any combination of components
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 08, 2015, 06:18:15 am
Yup, but how is the concept of "entity type" even defined ?
The type can be any criterion stored in any component.

It may be meaningful to store an attribute in the collision component, if dispatching is used for collision response. Make your dispatcher generic so that it can extract the type as you wish -- that's also what Aurora's implementation does.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 08, 2015, 08:09:22 am
Please forgive me if I'm being dense here (I haven't used Lua) but what advantage does the scripted onCollision function have over a C++ std::function callback? Is it purely so that you can change it on the run without recompiling? Or is it something else?
Yep, I could have used std::function for the same effect. Yep, I mostly use scripts to make quick changing possible. It also helps me to not search the source code when I want to see how some entity works: all entity properties and callback functions are stored in a corresponding script.

On which type of system have you tested that your performance is pretty ok? I'm curious about testing it on my netbook (despite it is of course no gaming computer^^).
I don't really remember which is the oldest PC I've tested it on, but I must say that my laptop is 5 years old and not that powerful. There's nothing to worry about in terms of perfomance. There isn't many sprites on the screen in one moment. There isn't any physics or complex AI.

what I didn't get was, how do you determine which Lua function to call on the entity? At this point, you only know that 2 entities collided, and each entity is defined only by the list of its component (if I understood). So based on this, how do you figure out which Lua response to call ? I can think of several ways of doing it, but none that would be flexible enough and be in O(1)
I store the corresponding function's luabridge::LuaRef in CollisionComponent (this is like a pointer to a function which lets you call this function). O(1)! :D
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 08, 2015, 09:38:12 am
I don't really remember which is the oldest PC I've tested it on, but I must say that my laptop is 5 years old and not that powerful. There's nothing to worry about in terms of perfomance. There isn't many sprites on the screen in one moment. There isn't any physics or complex AI.
5 years old? So the laptop might have a dual core cpu with >2 GHz per core? That's quite much for 2D gaming :) Personally, I'm focused to make my game's core (physics, graphics, basic gameplay logic) run on the very low end hardware (e.g. 2 GB Ram, 1.6 GHz Single Core, Intel OnBoard GPU ^^) .. sometimes it's pure pain, especially when using a heavy combination of non contiguous containers and lots of virtual methods (meanwhile is replaced all non contiguous containers and moved away from too much OOP). But I think the trouble is worth it, because it offers to use additional computer power for more highlevel tasks like AI.

Can you give us a short sketch of your architecture? :) You were talking about your ECS which is object-oriented. What I mean: How do the components message each other? Is there a virtual interface each (sub-)component implements of even overrides? Or do you handle all game logic by calling bound lua functions?
Title: Re:creation - a top down action rpg about undeads
Post by: Otherian on September 08, 2015, 07:59:38 pm
I really love the screenshots of your project. It is very motivating to see a project wich is already so far in its progress :)
I hope you will finish it that we can actually try and play it! Keep up the nice work! :3

Have you taught the whole programming stuff to yourself?
And do you recommend the ECS engine for a 2D-SFML-Game or would you like to change it after you've got to experience it yourself for quite some time? I just ask because I'm planning to start a game-project by myself and am still not sure wich approach to choose...
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 08, 2015, 10:35:50 pm
5 years old? So the laptop might have a dual core cpu with >2 GHz per core? That's quite much for 2D gaming :)
Fair enough. I should test it using other PC's. The game is currently taking 34 Mbs of ram. I think it's pretty okay from RAM point. As for CPU usage, can't be quite sure.

Can you give us a short sketch of your architecture? :) You were talking about your ECS which is object-oriented. What I mean: How do the components message each other? Is there a virtual interface each (sub-)component implements of even overrides? Or do you handle all game logic by calling bound lua functions?
There's a bit of architectural stuff at the beginning of this thread.
I've also written this post about how I use Lua here: http://forums.tigsource.com/index.php?topic=49336.msg1163401#msg1163401
I'll also post a new part of "Using Lua with C++ in Practice" which will show some implementation details which I use in my game (but a bit simplified).

As for messaging... Components don't message each other. Systems do. For example, when some entity dies, it can send a message that a particular entity is dead. DropSystem will receive this message and make this entity drop some item. Messaging greatly reduces dependencies between systems and components. DropComponent and HpComponent don't need to know about each other.
Most logic is stored in Lua, so I don't have virtual functions for entities, pointers to Lua functions do their work instead.
I hope that I don't leave some important details. Feel free to ask more questions!

I really love the screenshots of your project. It is very motivating to see a project wich is already so far in its progress :)
I hope you will finish it that we can actually try and play it! Keep up the nice work! :3
Thanks a lot. I'm glad you like them and I'm glad that my game is motivating. :)

Have you taught the whole programming stuff to yourself?
Yes. Mostly using awesome programming books.

And do you recommend the ECS engine for a 2D-SFML-Game or would you like to change it after you've got to experience it yourself for quite some time? I just ask because I'm planning to start a game-project by myself and am still not sure wich approach to choose...
Once you understand ECS and see how powerful it is, it's hard to go back to standard OOP hierarchy. It just works poorly for games.
Some people only use parts of ECS, but generally composition is the way to go. This is one of the most defining things about ECS.

As for using ECS in you own project, it depends on your programming experience.
If this is one of your first games, I recommend to try out inheritance for a few classes that your game would have.
Then I recommend to start with simple component architecture:
http://gameprogrammingpatterns.com/component.html
You should see the improvement in using this method versus inheritance trees, I think.
Then you can try to implement a simple ECS and try to make some small games with it. Implementing ECS is pretty hard and can take some time, but it's worth it. But on the other hand it may lead you to confusion. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Otherian on September 08, 2015, 11:17:13 pm
Yes. Mostly using awesome programming books.
[...]
As for using ECS in you own project, it depends on your programming experience.
If this is one of your first games, I recommend to try out inheritance for a few classes that your game would have.
Then I recommend to start with simple component architecture:
http://gameprogrammingpatterns.com/component.html
You should see the improvement in using this method versus inheritance trees, I think.
Then you can try to implement a simple ECS and try to make some small games with it. Implementing ECS is pretty hard and can take some time, but it's worth it. But on the other hand it may lead you to confusion. :)
Thanks for your advice :)
Do you have a book recommendation for ECS? (just in case yours was perfect :P)

Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 08, 2015, 11:50:04 pm
You're welcome.
I didn't read any books which talked about ECS. I recommend you to check out these articles:
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
My approach is not exactly the same as described there, but it's pretty close.
I would also recommend you to check out "Game Engine Architecture" by Jason Gregory. It doesn't talk about ECS but shows lots of useful stuff which may be useful when developing a game engine. It's a fantastic book.
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on September 09, 2015, 09:25:19 am
The book does have a second edition which came out recently btw.
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 09, 2015, 10:04:46 am
I'll also post a new part of "Using Lua with C++ in Practice" which will show some implementation details which I use in my game (but a bit simplified).
Great! I'm also looking forward to it, because I plan to introduce Lua to my own game for AI Scripting.

Messaging greatly reduces dependencies between systems and components.
Hell yeah 8)

Can you give us a full list of your component types? I'm sometimes very confused which damage to split over components and which to hold at one place. Maybe I can inspire myself reading about your data split :)
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on September 09, 2015, 02:46:14 pm
From my experiences with different kinds of entity component systems I have to say that the overhead of them is hardly noticabletm.
My current implementation stores components in an unordered_map(<std::type_index,std::vector<Component*>*>) and it can render >50000 moving entities just fine(55fps in debug, 150fps in release) and most time is spent rendering them not processing them.
I'm pretty happy with the results despite it being thrown together in a couple of hours.

You can take a look at it if you want(it is just two header files atm):
ComponentManager.hpp:

#pragma once
#include <vector>
#include <unordered_map>
#include <map>
#include <typeinfo>
#include <typeindex>
#include <algorithm>
#include <tuple>
struct Component
{
   unsigned int entity_id;
};



class ComponentManager
{
   using component_map = std::unordered_map<std::type_index,std::vector<Component*>*>;
public:
   ComponentManager() {}
   ~ComponentManager() {}


   template<typename T,typename... Args>
   void Add(unsigned int ent,Args&&... args)
   {
      std::vector<Component*>* container = map[std::type_index(typeid(T))];
      if(container == nullptr)
      {
         map[std::type_index(typeid(T))] = new std::vector<Component*>();
      }

      map[std::type_index(typeid(T))]->push_back(new T(ent,args...));

   }
   template<typename T>
   bool hasComponent(unsigned int ent)
   {
      auto container = map[std::type_index(typeid(T))];
      if(!container) return false;
      auto it = std::find_if(container->begin(),container->end(),
                             [&] (const Component* e)
      {
         return e->entity_id == ent;
      });
      return it != container->end();
   }
   template<typename T>
   T* getComponent(unsigned int ent)
   {
      auto container = map[std::type_index(typeid(T))];
      auto it = std::find_if(container->begin(),container->end(),
                             [&] (const Component* e)
      {
         return e->entity_id == ent;
      });

      return static_cast<T*>(*it);
   }

   template<typename... Args>
   std::tuple<Args*...> getComponents(unsigned int ent)
   {
      return std::make_tuple(getComponent<Args>(ent)...);
   }

   template<typename... Args>
   bool hasComponents(unsigned int e)
   {
      std::vector<int> result = {hasComponent<Args>(e)...};
      for(auto&& ok : result)
      {
         if(!ok) return false;
      }
      return true;
   }
   component_map map;
};

ComponentSystem.hpp:

#pragma once
#include "ComponentManager.hpp"
#include <iostream>
#include <vector>

struct ComponentSystemBase
{
   ComponentSystemBase()
   {

   }

   virtual void Update(float delta) = 0;
   virtual void EntityUpdated(unsigned int e) = 0;
};

template <typename... Args>
struct ComponentSystem : public ComponentSystemBase
{
   ComponentSystem(ComponentManager& mgr) : manager(mgr)
   {
   }

   virtual void Update(float delta) = 0;
   virtual void EntityUpdated(unsigned int e) override
   {
      if(manager.hasComponents<Args...>(e))
      {
         entities.push_back(e);
         components.push_back(manager.getComponents<Args...>(e));
      }
   }
   ComponentManager& manager;
   std::vector<unsigned int> entities;
   std::vector<std::tuple<Args*...>> components;
};
 

There are some things i'm not happy with like raw-owning pointers and stuff and I could probably add a convenience Entity struct/class which just stores an uid and enables me to write
entity.Add<Position>(10.f,10.f), but that is just nice to have and not needed for the ecs itself.

Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on September 09, 2015, 10:00:34 pm
How common is it to use RTTI (typeid) for ECS designs? That can slow things down or create bloat from what I've seen. I've used enums and been happy.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 09, 2015, 10:11:12 pm
The book does have a second edition which came out recently btw.
Yep, and this book became even more awesome! :D

Thanks for sharing the details of your implementation. It looks very similar to what I've implemented recently.

Can you give us a full list of your component types?
AIComponent, AttachComponent, AttackComponent, CollisionComponent, DamageComponent, DirectionComponent, DropComponent, GraphicsComponent, HealthComponent, InteractionComponent, ItemComponent, MovemenetComponent, NpcComponent, ScriptStateMachineComponent, TeleportComponent, TimerComponent, TriggerComponent.

I'm sometimes very confused which damage to split over components and which to hold at one place. Maybe I can inspire myself reading about your data split :)
I have one component for all types of damages, DamageComponent. It has a enum DamageType, so there's no need to create a separate Component for each type of damage.

How common is it to use RTTI (typeid) for ECS designs? That can slow things down or create bloat from what I've seen. I've used enums and been happy.
Hmm, I don't really know, I didn't check out the source code of different ECS designs. So far I've noticed no performance problems with it. (Well, I could have if I used lots of entities at the same time, but I don't!)

Btw,
Using Lua with C++ in Practice Pt. 2 is out. Check it out (https://eliasdaler.wordpress.com/2015/09/08/using-lua-with-cpp-in-practice-part-2/)!
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on September 09, 2015, 10:15:41 pm
Not that common I think(well entityx uses is as far as I remember) there was no real reason to use it to be honest, I was just lazy :-[

As an alternative you can use something like:
class Type
{
    static size_t counter;

public:
    template<typename T>
    static size_t ID()
    {
        static size_t id = counter++;
        return id;
    }
};
 

You invoke it like that:

Type::ID<YourTypeHere>()

It is threadsafe for most compilers and is resolved at compile time, so it should have almost no overhead.
Only downside is, that the id doesn't have to stay the same in different runs of your application, if that is not a problem it should be better than(imo) using enums, because you don't need any bookkeeping.

Edit:

Nice blogpost I enjoyed reading it(eventhough I don't like Lua..). You should consider using an unordered_map instead of map to store components if you don't care about their order ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 07:34:43 am
I also have to say that my system is build in a way that typeid calls are not performed very often.
For example, every system gets a std::vector<SomeComponent*> and doesn't need to call typeid or casts ever again.
As for entities... Yep, when you get a component from entity, you call typeid, but that's just once and I've never noticed any perfomance issues.

It is threadsafe for most compilers and is resolved at compile time, so it should have almost no overhead.
Only downside is, that the id doesn't have to stay the same in different runs of your application, if that is not a problem it should be better than(imo) using enums, because you don't need any bookkeeping.
Yep, that's a good way of doing such things. I will use it if type_index becomes a problem. :)

Nice blogpost I enjoyed reading it(eventhough I don't like Lua..). You should consider using an unordered_map instead of map to store components if you don't care about their order ;)
Thanks! AFAIK, unordered_map requires more memory to store. Yes, it let's me to get elements in O(1). But std::map lets me get component in O(log(N)). The N is never more than 10, so the difference is not noticeable. But yeah, the order of components doesn't matter, I'm just worried about additional memory which unordered_map requires. (and this varies between implementations).
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 10, 2015, 09:20:12 am
AIComponent, AttachComponent, AttackComponent, CollisionComponent, DamageComponent, DirectionComponent, DropComponent, GraphicsComponent, HealthComponent, InteractionComponent, ItemComponent, MovemenetComponent, NpcComponent, ScriptStateMachineComponent, TeleportComponent, TimerComponent, TriggerComponent.
Thanks! What's the exact use of TeleportComponent? Is it to cause teleports between maps? And could you also tell us about the AttachComponent? :)

You wrote that logic contained by the systems. So: Is damage calculated by the DamageSystem using the corresponding DamageComponent, and propagated to e.g. HealthComponent to finally inflict it (and may cause death - probably as another event?). Am I right?

I have one component for all types of damages, DamageComponent. It has a enum DamageType, so there's no need to create a separate Component for each type of damage.
Sorry, I wanted to write "data" not "damage" :D But yes, a damage type enum is great :) I have one too, very useful.

Using Lua with C++ in Practice Pt. 2 is out. Check it out (https://eliasdaler.wordpress.com/2015/09/08/using-lua-with-cpp-in-practice-part-2/)!
Nice!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 09:48:09 am
Thanks! What's the exact use of TeleportComponent? Is it to cause teleports between maps? And could you also tell us about the AttachComponent? :)
TeleportComponent is used for triggers which teleport you between levels or some places on the level. For example, trigger near every house has TeleportComponent with type "GoInside". Triggers near stairs have "GoUpStairs" or "GoDownStairs" type.

AttachComponent is used for entities which can grab and carry transport other entities. When some entity is attached to other entity, it's moving with this entity. This is used for platforms at the moment, it can also be used for entities which can pick up and carry other entities. (Like NPCs that can pick up boulders and throw them in you)

You wrote that logic contained by the systems. So: Is damage calculated by the DamageSystem using the corresponding DamageComponent, and propagated to e.g. HealthComponent to finally inflict it (and may cause death - probably as another event?). Am I right?
Each entity which has HealthComponent may have damaged function which takes damage value and damage type as parameters and later decides what to do with it.

For example, suppose you have an entity which is kinda resistant to fire damage but can be damaged with ice attacks. The damaged function may look like this:

damaged = function(damageValue, damageType)
    if(damageType == "Fire") then
         decreaseHealth(entity, damageValue / 2)
    elseif(damageType == "Ice") then
         decreaseHealth(entity, damageValue)
    end
end
 
DamageSystem may detect that some entity with DamageComponent collided with entity, it sends "Damaged" event and HealthSystem catches it and calls damaged function.

You have to map enum values to string values to use them in Lua, though.
Title: Re:creation - a top down action rpg about undeads
Post by: nebula on September 10, 2015, 06:36:43 pm
I have a question.
When you release your game, in which languages will it be available?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 09:03:18 pm
I have a question.
When you release your game, in which languages will it be available?
It's originally written in English, I'll also make the Russian translation.(Because I'm from Russia, he-he).
As for other translations: I would love to have German, Spanish, French, Japanese and maybe other translations. If I find some people who would do these translations, this would definitely happen. (If I have enough money to pay them, or if some people volunteer).
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on September 10, 2015, 09:15:36 pm
You'll be happy to find this then (https://docs.google.com/spreadsheets/d/17f0dQawb-s_Fd7DHgmVvJoEGDMH_yoSd8EYigrb0zmM/edit#gid=310116733)! (Translations are on the Master sheet)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 09:31:00 pm
You'll be happy to find this then (https://docs.google.com/spreadsheets/d/17f0dQawb-s_Fd7DHgmVvJoEGDMH_yoSd8EYigrb0zmM/edit#gid=310116733)! (Translations are on the Master sheet)
This looks pretty interesting, thanks. This would only help translate small part of the game. What about dialogues? They have to be translated by people. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on September 10, 2015, 09:32:26 pm
When you release your game, in which languages will it be available?
It's originally written in English, I'll also make the Russian translation.(Because I'm from Russia, he-he).
As for other translations: I would love to have German, Spanish, French, Japanese and maybe other translations. If I find some people who would do these translations, this would definitely happen. (If I have enough money to pay them, or if some people volunteer).
Depending on the amount of text (and your deadline) I'd probably be willing to do a Danish translation for a free copy of the game :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 09:34:22 pm
Depending on the amount of text (and your deadline) I'd probably be willing to do a Danish translation for a free copy of the game :)
Deal. ;)
I don't really know how much text there would be, but I'll contact you when all the text is written. :)
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on September 10, 2015, 09:34:44 pm
I would gladly translate it to german if needed. Could do japanese as well, but i'll stick with my native language  ;)
Title: Re:creation - a top down action rpg about undeads
Post by: AlejandroCoria on September 10, 2015, 09:37:04 pm
It's originally written in English, I'll also make the Russian translation.(Because I'm from Russia, he-he).
As for other translations: I would love to have German, Spanish, French, Japanese and maybe other translations. If I find some people who would do these translations, this would definitely happen. (If I have enough money to pay them, or if some people volunteer).

I would have no problems in translate to Spanish in my free time ;)
(I'm from Argentina)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 09:50:10 pm
@SpeCter, @AlejandroCoria, thanks a lot! I'll start a list of potential translators and I'll message you once the game is mostly done. (This would take some time, though...)
Title: Re:creation - a top down action rpg about undeads
Post by: FRex on September 10, 2015, 10:44:19 pm
Depending on how much text there is I could maybe do a Polish version, but I'm not sure if I'll have the time because university year starts in few weeks. Also - how will it be done technically? Will there be a database of all strings in the game for each language or what? And which Lua version are you using? Also - another solution to nested tables problem littering the code with a lot of calls and checks in C++ is to just use a piece of Lua code like so:
luaL_loadstring(L, "local args = {...} package.loaded['bla.native.draw'] = args[1]");
lua_newtable(L);
//pushing methods
if(lua_pcall(L, 1, 0, 0))
{
//error handling ect.
}
It could be used to return a value from nested tables easily too, few calls, no own type checking of tables  or indexing, ect.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 10, 2015, 11:05:41 pm
Depending on how much text there is I could maybe do a Polish version, but I'm not sure if I'll have the time because university year starts in few weeks.
The translation won't be needed until the game is near release, and this may take a year or two. :)

Also - how will it be done technically? Will there be a database of all strings in the game for each language or what?
I think it would be a bunch of .csv files which you could edit in any editor you want (even in Excel :D)

And which Lua version are you using?
Lua 5.2.

Also - another solution to nested tables problem littering the code with a lot of calls and checks in C++ is to just use a piece of Lua code like so
Hmm, what problem are your referring to? And I can't quite understand what this code does...
Title: Re:creation - a top down action rpg about undeads
Post by: FRex on September 10, 2015, 11:22:47 pm
The problem of not being able to get a nested table just by calling
lua_getglobal(L, "someTable.interestingTable");
as you've written in https://eliasdaler.wordpress.com/2015/09/08/using-lua-with-cpp-in-practice-part-2/
I thought about iterating through name and checking for dots but I decided to not bother (and it'd break on names with dots in them like the module names) and instead push a piece of Lua code to stack and then call it so all type checking, ect. is done by Lua. That piece of code I've shown was to create a new library table and put it under name bla.native.draw into the package.loaded table so require can retrieve it, but you could get any nested table value out the same way:
luaL_loadstring(L, "return some.nested.table.value");
lua_pcall(L, 0, 1, 0)
{
//handle the errors, pop the error message, ect.
}
//some.nested.table.value is now on top of the stack

Quote
Lua 5.2.
Is there any special reason or feature that made you pick this over 5.1? I've used 5.2 for learning Lua because that's what was newest when I started but then went back to 5.1 so I could use LuaJIT if I wanted to and 5.3 issues made me think I made the right choice.
Title: Re:creation - a top down action rpg about undeads
Post by: dabbertorres on September 11, 2015, 05:05:01 am
I've gotten table keys and values like this (https://github.com/dabbertorres/LNA/blob/master/LuaCpp/Details/Details.hpp#L237-L268). It's how I've made an std::map<K, V> out of a Lua table (albeit, a Lua table with keys of the same type, and values of the same type).

I also ended up making syntax to get values from a table like:
bool someBool = luaState["someTable"]["anotherTable"]["yetAnotherTable"]["myBoolFinally"];
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 11, 2015, 10:00:41 am
I would love to have German, Spanish, French, Japanese and maybe other translations.
I could help with the German translation, because I'm German ^^ You could message me once you're ready for translation. Then we'll check whether I have enough time.
Title: Re:creation - a top down action rpg about undeads
Post by: SpeCter on September 11, 2015, 11:52:11 am
I would love to have German, Spanish, French, Japanese and maybe other translations.
I could help with the German translation, because I'm German ^^ You could message me once you're ready for translation. Then we'll check whether I have enough time.

We should work together then, so that when the time comes we won't do things twice ;)
Title: Re:creation - a top down action rpg about undeads
Post by: nebula on September 11, 2015, 01:05:31 pm
I volunteer as a tribute for german translation :'D put me on the list
Title: Re:creation - a top down action rpg about undeads
Post by: Tank on September 11, 2015, 01:29:08 pm
/me volunteers for a German translation.
Title: Re:creation - a top down action rpg about undeads
Post by: Rosme on September 11, 2015, 11:44:45 pm
<- This guy here volunteers for a French translation.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 12, 2015, 12:15:35 am
@FRex, don't really know how fast it is compared to my method. What concerns me is that you'd have to do luaL_loadstring for each table you want to get keys of which just doesn't seem right to me. :S

Quote
Lua 5.2.
Is there any special reason or feature that made you pick this over 5.1? I've used 5.2 for learning Lua because that's what was newest when I started but then went back to 5.1 so I could use LuaJIT if I wanted to and 5.3 issues made me think I made the right choice.
No, that was just the latest version of Lua when I started to do scripting. I didn't consider to use LuaJIT at that moment, so I went with 5.2. I don't think that I use lots of 5.2 features, so I think I can still use LuaJIT if this would be necessary. :)

@dabbertorres, yep, that's the best syntax to have, but implementing it with one function is impossible, but I've tried to create function which would explain the general concept as simple as possible.

To everyone who are volunteering for the translation: I've created a trello list which I would expand.
Thanks for offering your help, it means a lot :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 16, 2015, 12:27:24 pm
Sorry for the lack of updates, been working on some awesome stuff and fixing bugs all week.
I'm working on a combat system and try to make it enjoyable and not boring. So far, the progress is great.
I'll work on the new art soon, so expect some cool screenshots and gifs.

I'm trying to focus more on making the game, not the engine for it, and it feels good. Are there any great articles about this? I want to plan better and focus on what's the most important.

And here's some random concept art:
(http://i.imgur.com/VJrChjK.png)
Title: Re:creation - a top down action rpg about undeads
Post by: Strikerklm96 on September 17, 2015, 05:57:51 am
This game looks awesome :) and as a novice programmer, I had some questions.

How do you make components interact? When a player damages another, what code and functions does that flow through?

For your lua, how does this get translated to an actual c++ instance of a GraphicsComponent?
Do you have to go through and set each value for the instance of GraphicsComponent to each value in the lua?
Like:
GraphicsComponent gc;
gc.filename = lua("GraphicsComponent.filename");
  GraphicsComponent = {
        filename = "res/images/chest.png",
        animated = true,
        defaultAnimation = "closed",
        z = 0,
        animations = {
            closed = {
                frame = {0, 0, 16, 16},
                numOfFrames = 1,
                frameTime = 0,
                looped = false
            },
            opened = {
                frame = {16, 0, 16, 16},
                numOfFrames = 1,
                frameTime = 0,
                looped = false              
            }
        }
    },


Or is there some way to get it to auto assign the values?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 17, 2015, 08:16:18 am
Thanks!

When a player attacks, his weapon creates "damage" entity which contains DamageComponent and CollisionComponent. If CollisionSystem detects that "damage" bounding box intersected with some other entity, this entity's "damaged" Lua function is called. It may look like this:

damaged = function(this, second) -- this - entity which was damaged, second - entity which damaged it
    decreaseHealth(this, getDamageValue(second))
end

I go through each value in C++ when I create GraphicsComponent, yeah. But then I copy this GraphicsComponent in C++ without Lua script.
Title: Re:creation - a top down action rpg about undeads
Post by: Brax on September 17, 2015, 11:17:40 am
@EliasDaler I have a feeling this article might be of some use to you. :)

The art of enemy design in Zelda a link to the past (http://www.gamedev.net/page/resources/_/creative/game-design/the-art-of-enemy-design-in-zelda-a-link-to-the-past-r4147)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 17, 2015, 10:49:46 pm
Thanks a lot. It's very interesting and will be totally useful.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 18, 2015, 09:04:17 am
Another concept art of cafe
(http://i.imgur.com/D02Kwwl.png)
I'm working on art for it, so in-game screenshots will come soon. :)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on September 18, 2015, 05:32:06 pm
I really like the scene you've drawn above. Looks to me (and this is just my take) that you have a retired pirate and one of his fellow pirates who died at sea and then they started a tavern together.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 18, 2015, 11:18:11 pm
I really like the scene you've drawn above. Looks to me (and this is just my take) that you have a retired pirate and one of his fellow pirates who died at sea and then they started a tavern together.
Thanks! That's a good interpretation, ha-ha.
I'm going to post the pixel art of them tomorrow. :D
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on September 18, 2015, 11:21:57 pm
I'm really impressed with what you are with this this game. Keep up the amazing work. It's really impressive.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 19, 2015, 04:45:22 pm
I'm really impressed with what you are with this this game. Keep up the amazing work. It's really impressive.
Thanks a lot. Very glad to hear that. :)

Okay, here's a new screenshot.
Undead cafe which I've been working on lately.
(http://i.imgur.com/PEOdJT3.png)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on September 19, 2015, 05:07:12 pm
Looks brilliant as always. Do the characters in the cafe have backstories/sidequests?
Title: Re:creation - a top down action rpg about undeads
Post by: argh on September 19, 2015, 08:51:18 pm
This game looks amazing! (artwork, colors, layout. well everything is spot on tbh). Keep up the great work. I hope the release date will end some time soon ;)

Just wanted to cheer you on.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 19, 2015, 10:16:45 pm
@shadowmouse, thanks! Yes, all of them have backstories. I thought about making NPCs without any backstory, but I just can't do it! :D
As for the sidequests... probably. I haven't thought about it yet.

@argh, thanks! I'll try to work as hard as I can to finish the game as fast as possible without sacrificing its quality.
And feedback cheers me on for sure, so thanks again. :)

Progress update
Cute undead cat tells about its life:
(http://i.imgur.com/rrcZpty.gif)
And do you recognize the painting behind the cat?

There are some cool changes I've made lately.
First of all, I've changed the dialogue font. Compare it with the old one:
(http://i.imgur.com/DGuTNB5.png)
First of all, the new font is more readable. It also lets me fit a lot more text in the dialogue window.
The text doesn't scroll anymore. I think that separating text by meaningful chunks (1-2 sentences) keeps it more readable. That's how most games do it, anyway.
Because I have to fit as much as I can in one screen, rephrasing stuff is important. I think it's a good thing, because it keeps text short and precise (most people don't like to read long texts in games, unless it's a huge RPG with deep history).

I will also start to add line breaks myself (I was breaking text in lines automatically before). It lets me compose the text manually, so it looks and reads a lot better. If you look closer at NES/SNES games with lots of dialogue, you'll notice that most of the text fits the box very neatly.
To do this more easily, I'll create a tool which will let me edit text in it and immediately see how it will look in the game. This tool would also be useful for translators, I think. (especially for languages which have long words!).
I also added little talking animation which makes things a bit more lively. :D

I'll also start to move animation data from Lua to JSON, so the script won't take as much space as its currently does. For example, main hero's script is now 504 lines. 354 of them is devoted to animation descriptions (location on the sprite sheet, frame time, etc.). And there's no need to keep info like that in Lua files, because this info doesn't use any Lua capabilities. So, I would move each animation description into JSON file and then just write something like this in the script:
GraphicsComponent = {
    ... -- some stuff
    animations = "anim/hero.json"
}
This animation info would be loaded in C++ later.

Oh, and one more thing. I finally came up with the name of the main character! I'll tell you later with some other cool stuff. ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 20, 2015, 01:44:19 pm
I've moved animation descriptions to JSON.
This removed 1047 lines from Lua scripts which is cool, as scripts are now more compact and easier to edit.

I also made a dialogue tool. It took me just half an hour to make!
(http://i.imgur.com/l8ZmDX6.gif)
Yes, line breaks can be easily inserted automatically. But this tool lets me compose the text in such way, that there's no situations like this:

Code: [Select]
Some text, some text, some text
some_very_long_word_which_doesn't_fit_in_previous_line, even more text,
a giant space is left on the first line. Meh, not cool!

This also lets me see how much text I can still fit in this box. I don't want to break one long sentence into several boxes, because this may be not very readable.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 21, 2015, 06:18:38 pm
Here's something another... I've decided to write music for the cafe. Hope you enjoy. :D
https://soundcloud.com/elias-daler/cafe-demo
Title: Re:creation - a top down action rpg about undeads
Post by: nebula on September 22, 2015, 07:50:11 pm
Sounds nice, but where do you want to loop it? :D
Title: Re:creation - a top down action rpg about undeads
Post by: Jesper Juhl on September 22, 2015, 08:02:40 pm
This game is super impressive (and inspirational). When I consider how much I struggle with graphics and sound for my own game (the code I can manage) I almost can't believe you're doing this alone - fscking well done!
My hat comes off for you sir.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 24, 2015, 08:23:56 am
@nebula, thanks! I want to loop it from the measure when the bass starts to play. This is not the beginning of the song, so I would have to figure out a way to loop songs from the specified time.

@Jesper Juhl, thanks a lot. Very glad that it inspires you, this fact inspires me! :D

Btw, I've decided not to use Zelda's perspective anymore. I'll try to remake cafe in FF/Seiken Dentesu's perspectives and Mother 3 perspective. Will post results later. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Mortal on September 24, 2015, 09:53:20 am
i just did quick scan for your older posts and i found that you are making graphic arts and coding but in last posts you're also, making music composing. that indeed impressive. to be honest with you, i can't do that no way, it needs super talent guy like you to accomplish that, ain't me, i'm just average guy who's barely can coding in c++ mostly copy and paste from others. ;D

me too My hat comes off for you sir.

it seems this game is well written and best to learn from. i have question are you going to make this game open source?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 24, 2015, 10:24:29 pm
i just did quick scan for your older posts and i found that you are making graphic arts and coding but in last posts you're also, making music composing. that indeed impressive. to be honest with you, i can't do that no way, it needs super talent guy like you to accomplish that, ain't me, i'm just average guy who's barely can coding in c++ mostly copy and paste from others. ;D

me too My hat comes off for you sir.
Thanks a lot!

Everyone is average (or worse! :D) at one point.
Start with some smaller games (Pong, Tetris, etc.) and read some books on C++. I highly recommend "C++ Primer" by Stanley B. Lippman. Continue working hard and you'll sure become awesome! :D

it seems this game is well written and best to learn from. i have question are you going to make this game open source?
Not sure about all the game being well written, but there are some good parts, at least some working ideas.
I ocassionally post about them in dev log, on my blog or in my tutorials, so you'll understand a lot about my engine if you read this stuff.
There's a possibility that I'll make my game (or at least some part of it, like main components) open source. But to do that, I have to release the game first. I'll see how good the code is when it happens. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 26, 2015, 02:14:17 pm
Okay, here's the biggest change in the art in a long time. I've changed pespective to axonometric 3/4.
(http://i.imgur.com/6hqLHuZ.png)
Just compare it with the old one:
(http://i.imgur.com/BsoAP9z.png)
GIF:
(http://i.imgur.com/TAfsl29.gif)

Drawing in this perspective is a lot easier, because all lines are straight. It's also a lot less confusing and more readable!
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on September 26, 2015, 02:55:33 pm
Are you changing only the inside of buildings, or everything? I'm kind of biased towards the former mode because Zelda games, but I can see why you prefer the new version over the older one.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 27, 2015, 12:56:45 pm
Are you changing only the inside of buildings, or everything?
If you take a look at these screenshots, you'll see that perspective there is already axonometric 3/4. Zelda uses the same perspective outside.

(http://i.imgur.com/EJzHdlj.png)
(http://i.imgur.com/LNGqqXe.png)

I'm kind of biased towards the former mode because Zelda games, but I can see why you prefer the new version over the older one.
I can understand why Zelda perspective may look more appealing. But I've thought about this and figured out that it gives me no advantage at all. It's actually harder to pull off because other stuff should follow this pespective. Now sprites are a lot of easier to make. Compare these two sprites, for example:
(http://i.imgur.com/iMo1XtP.png)
The right one is a lot easier to draw and looks cleaner, which is cool about axonometric perspective too :)
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 27, 2015, 06:21:56 pm
Great job - awesome drawing skills ;)

Btw: Some pages ago, I read that you want to update all systems at once without calling each system individually. As I remember you had not base class for your systems, so a common collection like std::vector<std::unique_ptr<BaseSystem>> systems isn't possible.

Have you solved the problem yet without introducing a base class?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 27, 2015, 11:24:24 pm
Great job - awesome drawing skills ;)
Thanks!

Btw: Some pages ago, I read that you want to update all systems at once without calling each system individually. As I remember you had not base class for your systems, so a common collection like std::vector<std::unique_ptr<BaseSystem>> systems isn't possible.

Have you solved the problem yet without introducing a base class?
Right now I have base class IEntitySystem and template class
template <typename ComponentType>
class EntitySystem {
    ...
    std::vector<ComponentType*> components;
}

So I can store systems like this:
std::vector<std::unique_ptr<IEntitySystem>>
Works quite well! (No casts needed, because IEntitySystem has such virtual methods as update and process)
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 28, 2015, 08:08:17 am
Works quite well! (No casts needed, because IEntitySystem has such virtual methods as update and process)

Ah cool! :) I just found another solution without a base class - but with some heavy template meta-programming using C++11 parameter packs.
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on September 28, 2015, 06:56:27 pm
I prefer the newer perspective and the artwork is - unbelievably - still improving!
Title: Re:creation - a top down action rpg about undeads
Post by: Mörkö on September 29, 2015, 07:39:39 am
The new style looks much better.

Seeing all four walls of a room doesn't make any sense when the objects in the room are shown only from one side.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 29, 2015, 03:29:06 pm
Ah cool! :) I just found another solution without a base class - but with some heavy template meta-programming using C++11 parameter packs.
Neat. How can you access a particular system in your engine?

I prefer the newer perspective and the artwork is - unbelievably - still improving!
Thanks a lot!

The new style looks much better.

Seeing all four walls of a room doesn't make any sense when the objects in the room are shown only from one side.
Thanks. I agree, though some games used weird perspectives pretty good, I'm not able to pull it off, so using a more convenient one is better.
Title: Re:creation - a top down action rpg about undeads
Post by: Nexus on September 29, 2015, 10:21:09 pm
I think the problem with the previous perspective was still what I mentioned earlier (http://en.sfml-dev.org/forums/index.php?topic=18062.msg134432#msg134432): mixing perspective and parallel projection.

Games with an actual top view (not a front-top angle) such as GTA2 are usually rendered with perspective, even if it may be faked implementation-wise. There are games that mix both successfully (e.g. Binding Of Isaac), but it works because the game focuses much more on action/enemies than on scenery and art.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on September 30, 2015, 12:26:35 am
So, do you like the new perspective? :D
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on September 30, 2015, 08:36:53 am
Ah cool! :) I just found another solution without a base class - but with some heavy template meta-programming using C++11 parameter packs.
Neat. How can you access a particular system in your engine?

In a nutshell:
int main() {
        SystemA a;
        SystemB b;
        SystemC c;
        SystemD d;
       
        EntityUpdater<SystemA, SystemD, SystemB, SystemC> updater{a, d, b, c};
        updater.update(sf::milliseconds(20));
        updater.update(sf::milliseconds(19));
        updater.update(sf::milliseconds(23));
        updater.update(sf::milliseconds(30));
        updater.update(sf::milliseconds(12));
        updater.update(sf::milliseconds(20));
       
        std::cout << "Total time for System A: " << updater.getTotal<SystemA>().asMilliseconds() << "ms\n";
        std::cout << "Total time for System B: " << updater.getTotal<SystemB>().asMilliseconds() << "ms\n";
        std::cout << "Total time for System C: " << updater.getTotal<SystemC>().asMilliseconds() << "ms\n";
        std::cout << "Total time for System D: " << updater.getTotal<SystemD>().asMilliseconds() << "ms\n";
}

But providing something like
template <typename... Args>
struct EntityUpdater
        : MultiUpdater<Args...> {
       
        EntityUpdater(Args& ...args)
                : MultiUpdater<Args...>{std::forward<Args&>(args)...} {
        }
       
        // should also be possible
        template <typename T>
        T& getSystem() {
                return SingleUpdater<T>::system;
        }
};

In more detail:
(click to show/hide)
(Source linked)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 02, 2015, 07:47:06 am
Glocke, that's a cool implementation. But yeah, looks like it may cause increased compilation time. Especially if you have lots of systems. And doesn't this approach creates a high compilation dependency between systems? By changing one system, you may cause lots of unnecessary recompilation.

Base class approach is working good, because most of the time you don't really care about what components this system works with. You just call update() and process() and you're done.
But, in case I need to get a particular system, I can do it by dynamic_cast. :)

Progress update
Can't really show much at the moment. Working on the cool fog system which I hope to show off soon. It's not just overlay sprites, clouds can actually be of any height and interact with objects they collide with!
I'm also prototyping some stuff. I've understood that this is absolutely neccessary.
This is something which I need to be used to. Drawing raw, unpolished sprites, making levels without lots of details, etc.
If I make a level with some detail (even not a lot of it), changing stuff becomes harder. So, raw prototyping helps here. Just draw some boxes, throw them on the map and change them to get a good level. And then I can start with details. But it's actually pretty hard, because I want the game to look good all the time, but I have to overcome this thing. Does anyone feel that about their games? :D
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on October 02, 2015, 01:19:51 pm
Glocke, that's a cool implementation.

Thanks :)
And doesn't this approach creates a high compilation dependency between systems? By changing one system, you may cause lots of unnecessary recompilation.

Yes it does. But I'd recomment to use such an approach at the very high end of the module stack - e.g. right before the actual game's mainloop (e.g. at the game state if you're using something like a state machine to switch between different states like menus).

But, yes: The approach using a common interface (which virtually provides update etc.) is better for decoupling, because the Headerfile (where you declare the systems vector) only depends on the interface declaration and the cpp-File includes everything else. So everything that depends on the header (which provides the systems vector) doesn't need to be recompiled when a system is added (only the corresponding cpp-File which depends on the systems is needed).

About your dynamic casts: Personally, I could think of something like
class ECS {
    private:
        std::vector<std::unique_ptr<BaseSystem>> systems;

    public:
        // create system
        template <typename T, typename ...Args>
        std::size_t create(Args&& ...args) {
            // emplace system and return index
        }
       
        // query existing system
        template <typename T>
        T& operator[](std::size_t index) {
            return *systems[index].get();
        }
        // + const overload
};
plus some is_base_of etc.
But at the moment I use
// session.hpp
struct Session {
    MovementManager& movement;
    CollisionManager& collision;
    // ...

    // + ctor that initializes the references
};

// ecs.hpp
struct ECS {
    MovementSystem movement;
    CollisionSystem collision;
    // ...

    Session session;
    std::vector<Updateable*> updateables;

    // + ctor that initializes all systems, the session and the updateables
};
FooManager is the pure FooComponent container, FooSystem is based on FooManager and has update logic etc. (which is implemented for the Updateable interface). So I can pass that Session reference where ever I those component managers (e.g. to a factory that creates complete objects). So the factory depends on the Component definition (+ their manager definition which is very simple) but not on the actual system.

Well this isn't perfect either^^

About your progress update: Can you tell us more about your fog system? Personally, I'm using a simple lightingsystem in my game, which produces dynamic shadows. What's the idea of your (upcomming) fog system yet? :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 04, 2015, 10:24:37 am
About your dynamic casts: Personally, I could think of something like
*code*
Yep, that's how I currently do it. But this code won't work:

template <typename T>
T& operator[](std::size_t index) {
    return *systems[index].get();
}

Because you can't convert from BaseSystem to DerivedSystem
This is what I do:

template <typename T>
T& operator[](std::size_t index) {
    return *(std::dynamic_pointer_cast<T>(systems[index].get())); // systems are shared_ptr, can't do this with unique_ptr
}

But at the moment I use
It's okay when you have a small number of systems, but as it increases, this stuff becomes more difficult to work with.

About your progress update: Can you tell us more about your fog system? Personally, I'm using a simple lightingsystem in my game, which produces dynamic shadows. What's the idea of your (upcomming) fog system yet? :)
Something like this:
(http://i.imgur.com/CuN6YuP.png)
The height of the cloud can vary and the cloud can move, so I have to draw it differently depending on the object which are in it. I'll explain how I do it a bit later. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on October 04, 2015, 11:19:10 am
Something like this:
(http://i.imgur.com/CuN6YuP.png)
The height of the cloud can vary and the cloud can move, so I have to draw it differently depending on the object which are in it. I'll explain how I do it a bit later. :)
Looks very interesting. I'm curious about your explanation!
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 06, 2015, 01:33:42 pm
Okay, here's how the fog looks in the game
(http://i.imgur.com/3VYHeU2.gif)

Notice, that it's not just an overlay. It actually has some height and draws depending which objects are in it. Just a neat simple effect...

This wasn't easy to make, though. Here's how it works:
(http://i.imgur.com/FbNfLlU.png)
Suppose we have one object. First, we draw the part of the fog which is behind it. Then we draw the object itself. After that, we draw the rest of the fog sprite in front of the object.
It all depends on the line which divedes the front and the back.It's easy to get it by substracting fog height (in pixels) from lowest Y coordinate of the object.
So, I split one big sprite in smaller ones depending on objects around.

Stuff becomes a lot harder if there are several objects in fog. I won't explain how to deal with it, as it would take too much time, but stuff works mostly the same.
And by the way, the most interesting thing about it is that the fog sprites don't move. Only textures move on sprites. This is done to make tiling of fog easier. I don't have to create additional sprites to do this, sprites just follow the camera if it moves.

There are other stuff I can do with this system. Like simulating water (some stupid undead forgot to turn off the taps...)
(http://i.imgur.com/nW4m3cY.png)

Or deep snow...
(http://i.imgur.com/BwJY76t.png)
You get the idea. It's always cool to reuse stuff like that!
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on October 06, 2015, 05:25:33 pm
May I suggest that if you are going to do water effects or snow effects then use a texture. Before I read the whole post, the second and third images just looked like a sort of weird version of fog of different intensities. Either giving it a texture across the whole  thing, or by the edges would make it clearer what the effect is.
Title: Re:creation - a top down action rpg about undeads
Post by: select_this on October 06, 2015, 06:09:03 pm
I think it was more of a demonstration of the versatility of his solution rather than "this is how I want it to look", but I do agree that it does look rather odd to have flat colours - especially the snow one, due to the lack of translucency :)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 06, 2015, 08:30:57 pm
I think it was more of a demonstration of the versatility of his solution rather than "this is how I want it to look", but I do agree that it does look rather odd to have flat colours - especially the snow one, due to the lack of translucency :)
Yeah, that's just to show off that it's possible to use the solution in different ways . Of course, I'll add texture if I decide to use in in some level. Snow would have some footprints on it, some snowdrifts, etc.
Title: Re:creation - a top down action rpg about undeads
Post by: Nerevar on October 06, 2015, 08:38:13 pm
What size of sprites(objects,tiles,gui) you use in your game?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 06, 2015, 09:54:02 pm
What size of sprites(objects,tiles,gui) you use in your game?
Most of the gifs and screenshots I make are upscaled 2x. So, you can take any screenshot/gif and check it out for yourself. The original resolution is 256x240.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 09, 2015, 09:00:56 am
Fixed one big bug where hero's sprite was shaking during camera scrolling. Turns out, I was setting the updated camera view too late (somewhere in the rendering phase, he-he). This took me like 3-4 hours to find! I'm not a clever man, heh.

As for 256x240 resolution. I've chosen this resolution because of SNES (but actually SNES is 256x224!).
So, I'm thinking about changing resolution to either 256x244 or 320x240 (4:3!).
320x240 would actually be cool because it would give me more horizontal space.

16:9 ratio for resolution would be cool, but I think that this would make my game look weird and too much horizontal space is not needed anyway (it's better for platformers).
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on October 12, 2015, 04:53:58 pm
Your fog (/water/snow) effect looks pretty cool!

I noticed that they're all at the same height (from the ground) though. Is it possible in your system to adjust this height as required or is it hard-coded at that height?
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 12, 2015, 06:38:27 pm
Your fog (/water/snow) effect looks pretty cool!

I noticed that they're all at the same height (from the ground) though. Is it possible in your system to adjust this height as required or is it hard-coded at that height?
Thanks!
It's possible to adjust the height, but it's not currently possible to adjust height for individual clouds because the code becomes very complicated. But it's possible that I'll create "layers" of fog at different heights which may make the effect even cooler! :D
Title: Re:creation - a top down action rpg about undeads
Post by: Hapax on October 12, 2015, 06:41:46 pm
It's possible to adjust the height, but it's not currently possible to adjust height for individual clouds because the code becomes very complicated. But it's possible that I'll create "layers" of fog at different heights which may make the effect even cooler! :D
Sounds cool  :)

Can the height be dynamically altered, like a water level rising/falling, for example?  ;)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 12, 2015, 07:38:51 pm
Can the height be dynamically altered, like a water level rising/falling, for example?  ;)
Yeah, the height is just a variable which can be easily changed. :)
Title: Re:creation - a top down action rpg about undeads
Post by: Mario on October 13, 2015, 11:14:54 am
Not sure, but from your explanation the fog drawing sounds more complicated, especially if there are multiple things around close by.

Could think of two alternative approaches:

Or even easier when using a shader:

Of course the latter gets more complicated with multiple layers.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 14, 2015, 06:46:29 am
Mario, thanks for your suggestions. At first I thought I'd say "the first approach is cool, but I want it to be like this:

std::vector<sf::Sprite*> renderList;
... // form it from all entities on the screen
applyFog(renderList);
... // do other stuff
for(auto sPtr : renderList) {
    ... // render
}
"

But then I 've realized that this is possible to do with the first method, I just need to divide sprites in parts and then put sprite parts under the first layer of fog in the renderList, then add fog sprite of the first level, then add all sprite parts under the second layer of fog, etc.
So, I'll need to create sf::Sprite for parts of all entities in the fog, but I think it's okay and won't be a problem!

I can't really understand the second approach, though. Can you explain it more, please?
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on October 14, 2015, 08:28:37 am
Or even easier when using a shader:
  • Determine depth in the fog.
  • Mix textures depending on the depth.
I can't really understand the second approach, though. Can you explain it more, please?
Maybe:
(*) And let the shader manipulate all pixels that should be affected by the fog. So if your sprite has a height of 64px and the fog should have a height of 24px, the shader will leave all pixels with height 0-39 as they are, but change the pixels with height 40-63 to be "fogged". I could imagine of using a gradient here, too!

At least that's what I understood :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 14, 2015, 08:59:54 pm
Glocke, yep shaders might do the trick. But I've never worked with shaders before, so this may be quite a challenge for me... Which I'll try to beat a bit later. :D

Right now I'm working on refactoring and making the game more playable. There were some game breaking bugs which I was okay with. Not anymore. As I work toward playable build, I have to reduce the number of bugs. Hopefully, this won't take long as the game is mostly (sometimes surprisingly) stable.
Title: Re:creation - a top down action rpg about undeads
Post by: argh on October 14, 2015, 09:33:31 pm
Right now I'm working on refactoring and making the game more playable. There were some game breaking bugs which I was okay with. Not anymore. As I work toward playable build, I have to reduce the number of bugs. Hopefully, this won't take long as the game is mostly (sometimes surprisingly) stable.

Can't wait  8)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 14, 2015, 11:57:29 pm
Can't wait  8)
I can't really promise a lot. If I'm able to finish it this year, this is going to be a miracle, ha-ha.
There's just lots of content I have to make. I want to make a good first impression, so I want a polished and awesome demo.
Hobby game dev is a long process.  :-[
(Any tips on speeding it up everyone? :D)
Title: Re:creation - a top down action rpg about undeads
Post by: shadowmouse on October 15, 2015, 08:16:09 am
What sped up the development of my current project the most, was moving to using bitbucket and source tree. Once I got it I immediately stopped putting off doing big things in case they broke it, because I would be working on a different branch and could always switch back again, but it also seemed to increase my coding speed once I was confident that whatever I did, it wouldn't be irreversible.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 15, 2015, 10:24:53 am
What sped up the development of my current project the most, was moving to using bitbucket and source tree. Once I got it I immediately stopped putting off doing big things in case they broke it, because I would be working on a different branch and could always switch back again, but it also seemed to increase my coding speed once I was confident that whatever I did, it wouldn't be irreversible.
Currently using it! Can't really get into branching yet, because I can't work on the one independent part of the code. Most of the code I write affects other stuff, so I can't be sure that if I return there'll be no collisions. But this is just for now, because I work on the engine and fix lots of stuff. Separating systems by using events will help a lot too. :D
And when most of my job will be done by writing scripts... that's where real fun begins and stuff will go pretty fast! :D
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 15, 2015, 11:51:14 pm
Here's a summary of what I've made during the last five months.
https://eliasdaler.wordpress.com/2015/10/15/recreation-dev-log-june-october-2015-theres-a-lot-of-stuff-made/
It's so good to look back and see how much of the stuff changed and improved.
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on October 16, 2015, 09:02:54 am
Glocke, yep shaders might do the trick. But I've never worked with shaders before, so this may be quite a challenge for me... Which I'll try to beat a bit later. :D

Don't hesitate to work with shaders :) Once you're in, there are lots of possibilities. As an example: When I started working on my game's lighting implementation, I had never worked with shaders before. But the result is quite great!
(example image inside spoiler, because it's offtopic somehow ^^)
(click to show/hide)
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 16, 2015, 09:14:36 am
Don't hesitate to work with shaders :) Once you're in, there are lots of possibilities. As an example: When I started working on my game's lighting implementation, I had never worked with shaders before. But the result is quite great!
(example image inside spoiler, because it's offtopic somehow ^^)
(click to show/hide)
Okay, I'll try something out. Do you know any great tutorials on GLSL? :)
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on October 18, 2015, 09:44:16 am
Okay, I'll try something out. Do you know any great tutorials on GLSL? :)
Sorry, I don't :D

But here are my shaders for rendering a sprite with some brightness and saturation (I use it for blinking animations)
sprite_shader.loadFromMemory(
        "uniform float brightness, min_saturation, max_saturation;" \
        "uniform sampler2D texture;" \
        "void main() {" \
        "       vec4 pixel = gl_Color * texture2D(texture, gl_TexCoord[0].xy);" \
        "       pixel = vec4(clamp(pixel.rgb, min_saturation, max_saturation), pixel.a);" \
        "       gl_FragColor = vec4(pixel.rgb * brightness, pixel.a);" \
        "}",
        sf::Shader::Fragment
);
and for rendering a lighttexture (which is a major part of my lighting implementation).
light_shader.loadFromMemory(
        "uniform vec2 center;" \
        "uniform float radius;" \
        "uniform float intensity;" \
        "void main() {" \
        "       float dist = distance(gl_TexCoord[0].xy, center);" \
        "       float color = exp(-9.0*dist/radius);" \
        "       gl_FragColor = vec4(gl_Color.xyz * color, 1.0);" \
        "}",
        sf::Shader::Fragment
);
Setting up the sprite_shader before rendering looks like this:
sprite_shader.setParameter("brightness", brightness);
sprite_shader.setParameter("min_saturation", min_saturation);
sprite_shader.setParameter("max_saturation", max_saturation);
sprite_shader.setParameter("texture", sf::Shader::CurrentTexture);
Prerendering a light texture is shown here:
sf::RenderTexture buffer;
buffer.create(size, size);

// prepare shadeable object
sf::VertexArray array{sf::Quads, 4u};
array[0].position = {0.f, 0.f};
array[1].position = {size, 0.f};
array[2].position = {size, size};
array[3].position = {0.f, size};
for (std::size_t i = 0u; i < 4u; ++i) {
        array[i].texCoords = array[i].position;
        array[i].color = sf::Color::White;
}

// render lightmap
buffer.clear(sf::Color::Black);
light_shader.setParameter("radius", radius);
light_shader.setParameter("center", {size / 2.f, size / 2.f});
buffer.draw(array, &light_shader);
buffer.display();
Later the resulting texture is applied to the scene using a suitable blend mode. The lighting texture is attached (so you can see the result).

Maybe those shaders can help to when experimenting.
Title: Re:creation - a top down action rpg about undeads
Post by: Elias Daler on October 24, 2015, 07:34:30 am
Glocke, thanks for your code. :)
I think I'll need shaders to create cool effect when the player turns into a ghost. Still not sure how it will look like.

Progress update
So, I've been refactoring and improving the code this week. This actually feels very good, because I'm fixing a lot of bugs and improving the readability and structure a lot. I'll tell more about stuff I've been doing a bit later.

So, I have a question about one aspect of the code.

For a lot of time I could get components from entities with this function:
template <typename T>
T* Entity::get() {
    ...
    if(...) { // component found
        return componentPtr;
    }
   return nullptr; // component not found
}

And I could check if the component exists like this:
auto gc = entity->get<GraphicsComponent>();
if(gc) { // do stuff
     ...;
}

This is needed for two reasons:

1) Systems check if entities have components which they are interested in

2) C++ functions which can be called from Lua check this to send error messages if you call something like setAnimation(e, "anim") for entity which has no GraphicsComponent.

But what if I return the references instead?
template <typename T>
T& Entity::get() {
    ...
    if(...) { // component found
        return component;
    }

   ??? // component not found
}
 

The question is: what do I do in the situations where entities don't have the component? I think I can do it like this:
template <typename T>
T& Entity::get() {
    assert(...); // check if component is found
    ...
    return component;
}

And I'll have to check if entity has a particular component if I'm not sure if the components exist
if(e->hasComponent<GraphicsComponent>() {
    auto& gc = e->get<GraphicsComponent>();
} else {
    ... // do something else
}
 

So, I think this is better than getting nullptr errors where I don't check if component exists and it doesn't.
GraphicsComponent* gc = e->get<GraphicsComponent>(); // nullptr
gc->doSomething(); // crash!
vs
GraphicsComponent& gc = e->get<GraphicsComponent>(); // assert!
gc.doSomething() // component totally exists, because if assert aborted the program, we won't be there

Is this a good way to do things? Is there a better way to do it? Maybe returning the pointer to component is fine?
Title: Re:creation - a top down action rpg about undeads
Post by: Glocke on October 24, 2015, 11:06:56 am
Is this a good way to do things? Is there a better way to do it? Maybe returning the pointer to component is fine?
Personally, I'm using a pure get without extras! My getter returns a reference (or const reference if suitable), and I use a has()-Operation to query existence. Its great for readability: Prefering references over pointers (where pointers have to be non-null) is always good. So I always branche !has() to return early (e.g. no damage calculation if no health component) or do something alternative (e.g. writing to a log that the component is missing but shouldn't be ^^). Personally, I also use lots(!) of assertions, which help readability, "understandability" and "refactorability", as well as "debugability" ...
So the separation of has and get makes sense for my coding, because I'm asserting stuff anyway. But the separation can also be used without asking for the actual component, e.g. to check for logical paradox.. maybe an object has either a FooComponent or a BarComponent (not both, not none) ... this can be tested without asking for the actual components - if required.

So my code looks similar, like this:
assert(movesys.has(actor_id)); // ignored in production code
auto& movedat = movesys.get(actor_id); // safe in dev code
++movedat.pos.x; // etc.
or
if (!animationsys.has(actor_id)) { // also evaluated in production
    log << "Object << " << actor_id << " cannot be animated\n";
    return;
}
auto& anidata = animationsys.get(actor_id); // always safe
// do whatever

My getters have some assertions, too - to avoid memory violation. But they do not check anything in production code.. just deliver the component as fast as possible. If the code needs to change using existence, I use has additionally before querying a component.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on October 24, 2015, 11:34:07 am
Glocke, awesome, thanks for explanation. :D
I was using A LOT of pointers before and I think I need to refactor this a bit because sometimes references are much nicer, yeah. As for assertions... I've been using them from time to time, but I was using console output for errors mostly.  I think I need to use them more to make my game more stable and to prevent some stupid bugs in the future. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Glocke on October 26, 2015, 11:56:00 am
for assertions... I've been using them from time to time, but I was using console output for errors mostly. I think I need to use them more to make my game more stable and to prevent some stupid bugs in the future. :D

Personally, I prefer "testable" assertions (which to not abort while unit testing, but throw a specific exception that can be expected and caught) to guarantee (during unit testing) that specific conditions do not happen.

For error logging, I wrote a minimal wrapper using some operator<< and an assign() operation, which adds a logging target. So I can create a "Logger"-instance debug which can be used like
std::ofstream file{"debug.log"};
Logger debug;
debug.assign(file);
debug.assign(std::cout);
// ...
debug << "Position is " << myVector << "\n";
(with additional overloads for e.g. sf::Vector<> etc.) and write this to a specific log file and stdout. Both are some kind of basic output streams, so each call to debug's operator<< calls each assigned ostream's <<.

(My previous approach is part of my SfmlExt Lib, the new approach will be added as I have enough time to do it.)
Title: Re:creation - a top down action adventure about undeads
Post by: Tank on October 28, 2015, 09:29:38 pm
I was facing the get/has/etc "problem" before as well. Two options:

1) Like Glocke said, split get() up into get() and has(), where get() contains an assertion (reason: calling get() without making sure that the object exists via has() is a programming error, so report to developer only).
2) Rename get() into find(). Find operations, by definition, can either return a hit or nothing. The return type would be a pointer in this case, and I think it's perfectly legit.

Personally I use find() wherever I can, because it's less error-prone and avoids code duplication (both get() and has() will query the same thing).

Btw, I wrote some lines about that topic on my blog (http://www.optank.org/2013/10/11/game-development-design-4-errors/).
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on October 28, 2015, 10:10:35 pm
So my code looks similar, like this:
assert(movesys.has(actor_id)); // ignored in production code
auto& movedat = movesys.get(actor_id); // safe in dev code
Why not embed the assertion into get()? Makes code safer and more readable on call site.

You mention that you do it sometimes later, why not always? Getting something non-existing is always a mistake, as Tank pointed out.

1) Like Glocke said, split get() up into get() and has(), where get() contains an assertion (reason: calling get() without making sure that the object exists via has() is a programming error, so report to developer only).
Yes, exactly.

However, has() is an explicit case differentiation which may often be solved more elegantly using different design. If you end up having a lot of code such as:
if (e.has(thisComponent))
   doThis();
if (e.has(otherComponent))
   doSomethingElse();
...
you should think about restructuring the systems, so that code paths are selected depending on the available components a priori and implicitly.
Title: Re:creation - a top down action adventure about undeads
Post by: Glocke on October 29, 2015, 08:17:38 am
Why not embed the assertion into get()? Makes code safer and more readable on call site.
I placed an assert into both: get() and call site. This is because I faced problems while unit testing. My assertion macro expands to throwing a special exception in case of building the unit tests. Unfortunately I didn't get the configurations for boost test right (I'm not quite sure whether they even exist) to produce a call stack when an untested exception was thrown. So I get something like `AssertionFailed` thrown in component.hpp at line XY (that's the file which defines an abstract component system), which doesn't help my to find the right spot where I accessed an invalid object. When I move that assertion into the actual function (which is directly called by the corresponding unit test, so I don't need a callstack here), I'm able to figure out where my precondition has failed.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on October 29, 2015, 03:55:30 pm
Thanks for bringing up some awesome points, guys. I especially agree on using find() vs get() with Tank. Tank's article is also very awesome. :D
I didn't know about _ASSERTE. This works much better than assert from assert.h. Not only because it doesn't execute functions in release build, but because it actually lets you see the call stack (with assert the call stack is just some random stuff). So, I guess I'll be using _ASSERTE in the future. :D

Progress update
I'm almost finished with refactoring. The structure of the engine is much better. I've also done some stuff like fixed-time step, better collision testing (spatial partitioning with grids) and some other stuff. I plan to write a blog post about the stuff I've done this Saturday or Sunday.

I also plan to finish demo prototype by the end of November. There will be some finished stuff and there'll be some placeholder art/NPCs/dialogue, etc.
The best case scenario is me finishing the demo by the end of this year, testing/polishing it for a month and then releasing somewhere by the end of January or somewhere near my birthday, ha-ha (which is on the 2nd of February).

And by the way, Re:creation is now 2 years old. Please, don't use this as a way to tell how much I have to work to finish the game. Now that I have a set of good tools and better experience with art, I'll be able to work much faster. Most of the work I've done during those two years was about creating the engine from almost a scratch. And I'm glad that I did, because now I know lots of stuff about game dev and have an awesome system which I'm quite proud of.
I'm almost done with the engine, there are some minor things I've yet to add, but they'll be implemented quite fast. Most of the game I have in mind can be implemented with the tools I already have. This makes me very happy.
So, the new era of Re:creation development will begin soon. Thank you for supporting me so far, I hope you'll get some cool stuff from my future work. :D

(http://i.imgur.com/Lc7zy11.png)
Title: Re:creation - a top down action adventure about undeads
Post by: SeriousITGuy on October 30, 2015, 11:03:04 am
Congrats on keeping up the work for two years, can't wait to get my hands a copy of your game.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on October 31, 2015, 10:52:35 pm
Congrats on keeping up the work for two years, can't wait to get my hands a copy of your game.
Thanks

Okay, here's what I've been doing today:
Lua enums
As you may know, Lua doesn't have enums. But sometimes I need to pass C++ enum value into Lua function and do something based on it.

Suppose I have this enum in C++

enum class Direction {
    Up,
    Down,
    Left,
    Right
};

Previously I converted enum values to strings (using std::map<Direction, std::string>) and then used it like this in Lua:

if(direction == "Up") then
    ... -- do something
end

This was alright for a while, but now I've realized that I can do something a lot better!
Here's what I can do now:

if(direction == Direction.Up) then
    ... -- do something
end

Direction is a const global Lua table which can be used similarly to C++ enum. And what's cool is that it has the same values as corresponding C++ enum! So I can do something like this and this will still work:

enum class SomeEnum {
     SomeValue1 = 1,
     SomeValue2 = 8,
     ... // etc
};

I'll tell the implementation details in some blog post later, there's too much to write about. :)

Event Manager
Let's talk about events.
Previously I had something callbacks like this:

void SomeClass::onHpChange(Event* e) {
    auto event = virtual_cast<HpEvent*>();
    int hp = event->hp;
    ...
}

So, basically I had a base Event class and lots of events which used it as a base class.
The only thing different about them were arguments.

Why virtual_cast? That's because implementing something like this:

void SomeClass::onHpChange(HpEvent* event) {
    int hp = event->hp;
    ...
}

Is much harder, because functions with different argument types have different types, so they can't be stored in the same array, so you have to use lots of template magic to make this work.
Another problem is that Lua/C++ event communication gets harder, because you have to register all those event classes in Lua or write function which create tables based on the event's data.
I also had pretty bad separation between Lua and C++ callbacks, so I created CppEventManager and LuaEventManager. They had lots of common stuff, so I created a base EventManager template class (I had to store different types of callbacks and listener id's). Stuff was very hard to manage.

So, what did I come up with? First of all, I created EventArg class which can hold some common types (int, float, bool, more about it later). Event has a std::map<std::string, EventArgs> args. (key is a name of the argument)

So, I can create events like this now:
Event e(EventType::HpChangedEvent);
e.setData("hp", 10);
eventManager.queueEvent(e);

and callbacks look like this:

void SomeClass::onHpChange(const Event& e) {
     int hp = e.getData<int>("hp");
     ...
}

EventManager can now easily hold both C++ and Lua callbacks, so communication between Lua and C++ is easy. Lua callback can look like this:

function callback(event)
    print("HP:" .. event.data.hp)
end

This works, because events can easily be converted to Lua tables with same data.

I have two things I want to discuss though...

1) EventType enum
This is a big enum of all types of events which is used to differ one type from another. Is this okay to use a enum like this or is there a better way? Creating new classes is not an option as I've shown above.
What makes me worry is that compilation times may become slow, because EventManager.h includes EventType.h, so each time I change EventType enum, EventManager.h is recompiled which may cause lots of additional recompilation, which sucks.

2) EventArg
So, what is EventArg? This is a class with union which can hold int, float or bool.
This is enough for most purposes (you may think that std::string is needed, but it isn't, because you most engines don't use std::string's at all and have string integer ids instead.)
But sometimes this is not enough. Sometimes it's good for event to hold sf::Vector2f or sf::FloatRect.
This will probably work with unrestricted unions, but they're not currently supported in VS2013, so I can't use them. (They're supported in VS2015, anyone tried it?)

So, this is how things work now. What do you think about it?
(When I get some time, I'll write more about stuff I've improved in my code in a big blog post :D)
Title: Re:creation - a top down action adventure about undeads
Post by: JLM on November 11, 2015, 10:51:40 pm
I have a question for you. How do you make objects like Arrows spawn?

Let's say I've got a EntityManager class which contains all of the Entities (Entities are ints).
And Systems (Singletons) which contain all Components (map<Enity id, Component>...).

So how do I allow a Component like PlayerInputController to add new Entity to EntityManager?
I can't just #include EntityManager to System becouse EnityManager #includes all The systems already.

I was wondering how you solved that problem.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 12, 2015, 02:30:28 pm
Well, here's how it works in my game.
1) Each item has ItemComponent with a reference to Lua script function called use
2) When the player or AI uses the item, this function is called.

It looks like this:
function use(this, owner) -- this - a pointer to item entity, owner - a pointer to owner entity
    local arrow = createEntity("arrow")
    setPosition(arrow, getPosition(owner))
end

createEntity is a global C++ function which can be called from Lua and it looks like this:
Entity* createEntity(const std::string& name) {
    auto entity = entityManager.create(name);
    return entity;
}

If you don't use scripts, you can use events and send event like "EntityCreateEvent" with a name of entity which needs to be created to the entity manager. (But implementing events is a bit harder, yeah)
Another way is to store a pointer to EntityManager in your system (this is not very good, because of coupling, but this works). You can prevent cyclic dependencies by using forward declarations.

Progress Update coming soon!
I've remade lots of script and engine stuff and this is very cool and will improve my perfomance a lot. More details today or tomorrow!
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 22, 2015, 09:48:58 pm
Progress update
Sorry for a huge delay with a progress update, I've been very busy, mostly finishing the refactoring stuff and making new things!. And now I can say that for the most part it's complete.
Here's how much stuff I've changed last month!
(http://i.imgur.com/LtVfLgI.png)
Yep. That's a lot. This includes new stuff I've made this month, so maybe I wrote lots of negative code.
This was the biggest refactoring and engine improvement I've done ever. I'm very glad I did this, because now I can make stuff faster, easier and there'll be a lot less bugs in the future. Some people prefer to create workarounds for the problems they have, but if I did this, the game would be buggy, the engine would be a pain to work with and my creativity would be very limited by the stuff I coudn't implement because of the engine structure. So, I'm satisfied with most of the stuff I've remade and now I'm working on the game itself most of the time.

What about the game?
Here's a gif to get you interested. Not much have changed, but here you can see, that I've created bigger rooms for buildings, made scrolling a lot smoother etc.. The talking animation also stops when the character finishes the part he's talking.
(http://i.imgur.com/Diuvc9A.gif)

This post will give a brief overview about what I've done and I'll write a more detailed post later.

Separating drawing, input, event handling
This started when I tried to implement fixed time step. I've realized, that in my game input, drawing and other stuff wasn't separated well enough, so implementing fixed time step wasn't really possible. "SFML Game Development" book gave me some awesome ideas about this and stack of game states, so I did it mostly as described there. This also helped me get rid of lots of global variables. For example, window was a global variable, but now I can pass it in draw function as an argument from the main loop. The main loop looks like this now:
void Game::mainLoop() {
    sf::Time delta = mainClock.restart();
    timeSinceLastUpdate += delta;
    while (timeSinceLastUpdate > TimePerFrame) {
        timeSinceLastUpdate -= TimePerFrame;
        processEvents();
        update(TimePerFrame);
    }
    draw(window);
}
This is as simple as it can get and it feels great. :D
Using stack of GameStates helped me fix some bugs and improve code readability a lot.

EventManager
I've talked about this one before, but let's look at it again. Now I can send events like this:
Event event("HpChangedEvent");
event.setData("hp", healthComponent->getHp());
eventManager.queueEvent(event);

Subscribing to events looks like this:
eventManager.addListener(this, "HpChangedEvent", &GUIPlayingState::onHpChanged);
In this example, GUIPlayingState wants to know when player's hp changed, but other entities can send this event too, so GUIPlayingState can subscribe to the player entity only:
eventManager.addSubjectToListener(this, "HpChangedEvent", playerEntity);

Now, when the HpChangedEvent is triggered, onHpChanged callback is called by EventManager. It looks like this:
void GUIPlayingState::onHpChanged(const Event& event) {
    playerHp = event.getData<int>("hp");
    ... // update GUI!
}
I can also send events from Lua scripts!
event = {}
event.hp = entity:getHp()
event.type = "HpChangedEvent"
queueEvent(event)
Event Lua table is converted to C++ event and then is queued in EventManager. The most cool part is that no matter what sends the event, Lua or C++, both Lua and C++ listeners' callbacks will be called! When the Lua callback is called, I can do stuff like this:
someLuaCallback = function(event)
    print("Hp changed to " .. event.data.hp)
end
I previously used EventType enum for event types, but I now use string hash ids, so I don't have to recompile a lot of stuff when I add a new event. But this raises another question: what if I mistype something? Like this:
Event event("HpChangeEvent"); // should be HpChangedEvent
No problem, I will check the string hash and if it wasn't registered before (all event types are registered during EventManager initialization) nice little assert will tell me about this (crashing my game which is good, because I'd have to fix the error immediately!). (I would love to have some static_assert for checking this, but is this even possible?)

Event class is not a base class for all event types and it's great. It looks like this:
class Event {
    ...
    std::map<std::string, EventArg> args;
}

What is EventArg? It's a cool class which has an unrestricted union which may contain everything that I need for events: bool, int, float, string, etc. I can easily cast it to the needed type like this:
auto someInt = eventArg.cast<int>();

args map is easily converted to Lua table and vice versa, which is what makes using events easy with Lua. I'm very satisfied with the event system now.

C++11/14 stuff
C++11 makes your code much better. Back when I started making Re:creation, some C++11 features were not known to me or the Visual Studio version I was using didn't support these features. Now I've moved to VS2015 and now most of the cool stuff is available to me. Let's talk about the stuff which is available for most people first:

* Pointers
Mostly I was using shared_ptrs everywhere, but then I've realized that I was thinking about smart pointers wrong. Using raw pointers is okay as long as they are non-owning! So, it's better to pass a raw pointer to a function which does something with this pointer, than to pass unique/shared_ptr. So, I do it like this:
void someFunc(SomeClass* ptr) {...}
...
std::unique_ptr<SomeClass> ptr;
...
someFunc(ptr.get());

And using unique_ptr is better than using shared_ptr most of the time. And it's best to not use pointers at all, so I tried to reduce the number of pointers to minimum and use unique_ptr where it's needed.
There were some problems with forward declaration, though. This will produce an error:
// A.h
...
class B;
class A {
     ...
     std::unique_ptr<B> ptr;
};
Why? That's because the compiler creates default destructor in the A.h and B is not available yet, so the compiler tells you that it can't know how to delete B!
Here's an easy way to fix this:
// A.h
...
class B;
class A {
public:
     ~A();
private:
     ...
     std::unique_ptr<B> ptr;
};

// A.cpp
#include "B.h"
A::~A() = default;
...
Good! But this creates another problem when you need move ctor/operator=.
Defining a constructor will prevent move ctor/operator from generation, so you have to declare them for yourself. You can use =default for them, but VS2013 can't do that (but VS2015 can!)

* auto
There's no need to explain how cool auto is. It helped me refactor stuff a lot, because I was using it a lot before, so I didn't have to manually replace a lot of code.

* for-ranged loop
Instead of writing stuff like this:
for(auto it = someStuff.begin(); it != som
eStuff.end(); ++it) {
    auto& something = *it;
    ...
}
I can now write this:
for(auto& something : someStuff) {
    ...
}
Saves a lot of typing and this is easier to write. Now I wish that stuff like this was possible (it will be possible in C++17, most likely!):
for({someKey, someValue} : someMap) { ... }

* STL algoritms + lambdas
I didn't use algorithms much before, because writing functions and then passing them to another function wasn't fast. Lambdas make it a lot better. Suppose you have to find something which matches some condition. You can do it like this:
auto foundIt = someVector.end();
for(auto it = someVector.begin(); it != someVector.end(); ++it) {
     auto& elem = *it;
     if(.../*condition*/) {
          foundIt = it;
     }
}

Or like this:
auto it = std::find_if(someVector.begin(), someVector.end(), [](const SomeClass& elem) { return ...; /*condition*/ });
This is especially awesome when you need to erase something. Previously I had to do it like this:
auto it = someVector.begin();
while(it != someVector.end()) {
     if(... /*condition*/) {
         it = someVector.erase(it);
    } else {
        ++it;
    }
}
 
You can't just do it in for loop, because erasing something will invalidate some iterators.
But now I can do it like this!
std::erase(std::remove_if(someVector.begin(), someVector.end(),
     [](const SomeClass& elem) { return ...; /*condition*/}), someVector.end());
Much better.

One more thing, when you stuff with maps or vectors which store objects with long class names, lambdas can be pretty painful to write, because you have to do stuff like this:
[](const std::pair<KeyClass, ValueClass>& elem) { ... }
Generic lambdas (supported in VS2015 now!) make it a lot easier:
[](const auto& elem) { ...}
Awesome. If you can't use generic lambdas, the best thing I can come up with is this:
[](const decltype(someMap)::value_type& elem) { ... }
Not pretty, but works.
// end of C++11/14 stuff

Const correctness
Not too much to write about this, but I've improved const correctness a lot and this helped me fix a bunch of subtle bugs and will probably save me a lot in the future!

What, there's more?
Yeah, I have lots of stuff to write about (mostly about Lua). Lua enums, new cool LuaScriptManager, removing header dependencies (a.k.a. how LuaBridge caused compiler to recompile everything all the time), improving scripts and more! Stay tuned.

I would love to hear your thought about the stuff I've done and the stuff which you do to improve the quality of your code.
Title: Re:creation - a top down action adventure about undeads
Post by: Ungod on November 26, 2015, 10:20:01 pm
I'm following your project for some time now and i finally manged to register here. Your game and engine were a nice source of inspiration for me.

I really like your modding philosophy and your lua-scripting and editor tools related to that. Until now, I just hardcoded stuff, but I tried scripting in the past a few times. (I can remember that I tried lua for an afternoon, but I had some problems with the setup)

I think you have to consider carefully when using scripts, because they can really slow down the game if used for too basic procedures. Where do you use them? Just everytime you want to implement gameplay behavior, thats unique to certain object and will not occur regular in the game?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 26, 2015, 10:35:18 pm
Ungod, thanks a lot! Glad you find my articles/dev logs useful! :)

Yes, you have to use scripts for stuff that isn't computationally expensive and doesn't happen very often. For example, collision checking and resolution should be done in C++. But reaction to collision may be scripted, because collisions don't happen all the time and you're pretty safe. There are two things that should take most of the time if you're doing stuff right: collision, AI and rendering. Rendering and collision is done in C++. Some of the AI should be done in C++ (finding the shortest path, A*, etc.) and some can be scripted (going from one AI state to another, deciding what to do next, etc.). I don't optimize my script usage for now and I didn't notice any perfomance problems with Lua.

Progress update
Today I've tried to see how the prison/dungeon would look like if drawn in the new perspective. And the results are pretty cool. I'll show them when I implement them in the game! (It's mostly a sketch now)

And today's Pixel Dailies (https://twitter.com/Pixel_Dailies) theme is Bard, so I've drawn Undead Bard who is a cool character which you see from time to time on screenshots :)
(http://i.imgur.com/wrjbCbE.png)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 28, 2015, 11:49:10 am
I created pretty cool shadow system
(http://i.imgur.com/g7rRMWm.png)

Previously shadows were drawn by hand, but I realized that this is pretty boring to do, so I created a simple shadow system. Here's how it works:

(http://i.imgur.com/ZiNro6P.png)
First, I apply a simple fragment shader to the object's silhouette.
Here it is:
uniform sampler2D texture;

void main()
{
    float alpha = texture2D(texture, gl_TexCoord[0].xy).a;
    if(alpha < 0.1) {
        discard;
    }
    vec4 color = vec4(0.098, 0.098, 0.098, 0.5);
    gl_FragColor = color;      
}
 
So, I just set all non-transparent pixels to one color.
(http://i.imgur.com/GegiKPJ.png)
Then I skew the silhouette using sf::VertexArray (this is done by simply moving two top verticles (marked as 0 and 1)  like this:
(https://i.imgur.com/WPhqio0.png)

and then I draw the original sprite on top of the shadow. That's it! I still don't know how much I have to skew each shadow to get the best looking shadows (anyone has ideas?). Maybe there are ways to make this even cooler? (I don't want to make anything complex, there won't be "true" lightning system in my game, no directed lights, etc.)

Another aspect of shadows is interaction with other objects and I'll write about it when I implement it (basically it's per-pixel collision test with shadow and object's collision rect)
Title: Re:creation - a top down action adventure about undeads
Post by: shadowmouse on November 28, 2015, 12:22:46 pm
How about making a day and night system and having the shadows gradually move from left to right? I think you'll have to rotate the top edge a bit to stop it looking weird though, but I might be wrong as I've never tried it myself.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 28, 2015, 12:28:02 pm
How about making a day and night system and having the shadows gradually move from left to right? I think you'll have to rotate the top edge a bit to stop it looking weird though, but I might be wrong as I've never tried it myself.
Yeah, I thought about that, changing a pallete a bit by using different shaders would also work pretty good with this (changing brightness + hue). I think that I may make day/night system where day and night wouldn't change gradually, but during some events (you go inside the dungeon, it's day outside, you go out - night already!) :D
Title: Re:creation - a top down action adventure about undeads
Post by: lezebulon on November 28, 2015, 02:06:34 pm
Hi!
from experience, when you do shadows this way you really cannot skew them that much without it looking really bad
the reason is simply that the shadow should be the projection of the outline of the 3D object, and with a 2D sprite you only know the outline of the object when you see it from the camera point of view.

This can work fine in any direction as long as the original 3D object has a circulat symmetry (like a pine tree), where the outline from all angles is the same. But basically if you want the shadow to be drawn on the upper-right of the object, the shape of the shadow should be the outline of the object seen from the lower-left... there is no way to tell what it should be just based on the sprite since it's just a view of the object from the top
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 28, 2015, 09:19:30 pm
Hi! That's a valid concern, but I'll try not to skew them too much. Most of the shadow is overlapped by the object itself, shadows are low-res/not to big, so I don't think that this will be too obvious if you don't try to think about it. Even if I drew shadows myself, I wouldn't be able to imagine how the other side of the object would look! But if some objects (especially bigger once) have really bad shadows, I can still draw them by hand to make them look better.

So, I'm okay with not perfect shadows :)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 29, 2015, 08:54:57 am
Okay, it's time to write another part about the refactoring I've done. It's also contains the hardest part of the refactoring!
Here's some small stuff I've done:

1. Lua enums. I've written about those already (http://en.sfml-dev.org/forums/index.php?topic=18062.msg139016#msg139016). They work pretty good
2. LuaEntityHandle. Read more about this technique here (https://eliasdaler.wordpress.com/2013/11/30/lua_and_cpp_pt3/).
This thing allows me to write stuff like this:
entity:setAnimation("walk")
instead of
setAnimation(this, talk)
A minor change, but the one I like very much, because it makes scripts easier to read
3. Lua/C++ events. Written about it here (http://en.sfml-dev.org/forums/index.php?topic=18062.msg139773#msg139773).
4. And now for the hardest part. I didn't really think too much about header dependencies because I try to not include stuff in headers, use forward declaration as possible, try to decouple classes, etc. But changes in some classes caused lots of recompile for no reason. You now, like file changing A.h caused B.cpp which didn't include A.h in any way to recompile. I've searched for hours for the root of the problem. I've created a big graph of includes in my code but found no reason for this thing. And here comes the worst part: when I created new functions and registered them in LuaBridge, this caused almost full recompilation of the whole project (which took 4-5 minutes!). This was not acceptable. This would limit me a lot, because I wouldn't want to add C++ functions which can be called for Lua or change some classes which caused a lot.

And then I found it. It was LuaBridge.h. I created a quick project to test things out. So, suppose you have two classes A and B which are not related in any way. You register A class in A.cpp and do some stuff with LuaBridge in B.cpp. So, A.cpp and B.cpp have LuaBridge.h included in them. And now suppose you make some changes in class A and compile. B.cpp compiles too! What? This is what LuaBridge does. I think that compiler generates some weird template code again which causes LuaBridge.h to recompile causing ALL files which include LuaBridge.h to recompile.

As you may imagine, lots of files in my project included LuaBridge.h. This is what caused the problem! And I've found the solution. It was to make LuaScriptManager which included LuaBridge.h in LuaScriptManager.cpp but not in LuaScriptManager.h, so if you change some stuff and LuaBridge.h needs to recompile, only LuaScriptManager.cpp is recompiles, but all the files which use LuaScriptManager.h are not recompiled!
But making good interface for LuaScriptManager was a big challenge. There were two problems:

Problem A. I needed to make some templated functions which used LuaRef in them (like T getData<T>). This meant that I needed to include LuaBridge.h in LuaScriptManager.h which would cause the same problems again!

Here's how I solved it:
You can declare a template function in .h but define it in C++ if you do template specialization. But this proved to be bad, because a lot of the code had mostly common stuff in it and I didn't want to just copy-paste stuff. And then I've found out about one of the coolest template features ever. It's called explicit template instantiation. So, all you have to do is to define the template function in .cpp and then put explicit instantiations in .cpp for all the types you want this function to use with. This limits you to only those types, but I was okay with that, because getData was used with only a number of classes like int, float, bool, etc.
So, here's how the code looks:
// LuaScriptManager.h
class LuaScriptManager {
    ...
    template <typename T>
    T getData<T>(...);
    ...
};

// LuaScriptManager.cpp
...
template <typename T>
T LuaScriptManager::getData<T>(...) {
    // template code
}

// explicit instantiations
template bool LuaScriptManager<bool> getData(...);
template int LuaScriptManager<int> getData(...);
... // etc.
So, this causes compiler to generate all this functions in .cpp file, so you don't have to have template function definition in your .h file which enables you to not put code into headers.

Problem B. I needed to find some wrapper around LuaRef which could act like LuaRef, but didn't require files where it's used to include LuaBridge.h. This one was easy, I just created class like this:
namespace luabridge {
    class LuaRef;
} // forward declaration

class LuaRefWrapper {
    template <class T>
    T cast() const;
    ...
    std::unique_ptr<luabridge::LuaRef> refPtr;
};
This also allowed me to get rid of some explicit template instantiations in LuaScriptManager which made code a lot better. I can just use LuaRefWrapper.h in LuaScriptManager.h without including LuaBridge.h! So, I got rid of the dependency, but I also got a few good things out of LuaScriptManager too, of course.

1) Hiding stuff/error checking inside the scripts
Suppose I have entity definition that looks like this:
someEntity = {
    ...,
    GraphicsComponent = {
        filename = "res/images/someEntity.png",
        ...
    }
}
Suppose I want to get someEntity.CollisionComponent.collide. Here's what I had to do previously:
auto entityTable = luabridge::getGlobal(L, "someEntity");
auto componentTable = entityTable["GraphicsComponent"];
auto filenameRef = componentTable["filename"];
std::string filename;
if(filenameRef.isString()) {
    filename = filenameRef.cast<std::string>();
} else {
    filename = "res/images/error.png";
}
There are lots of things that can go wrong. What if one of the tables is not found? Should add checks for this too?
Here's what I can do now:
auto componentTable = scriptManager.getTable("someEntity.GraphicsComponent");
auto filename = scriptManager.getData<std::string>("filename", "res/images/error.png", componentTable);
Much better! If one of the tables is not found, the program doesn't crash and LuaScriptManager tells me about the error. If the value is of the wrong type, the script manager tells me about this too. If there are some errors, getData returns the default value which I provided as the second argument.

2) Overwrite
One functionality I've implemented a long ago was entity "inheritance". Suppose I have one entity with lots of components. And now I decide to create almost the same entity, but with another sprite. Here's how I can do that:
base_entity = {
    ...
}

derived_entity = {
    template_init = function(this)
        this:copyEntity("base_entity") // copies everything from base_entity
    end,
    GraphicsComponent = {
        filename = "res/images/newSprite.png"
    }
}
The difference between default loading and this type of loading is that I don't care if the value is not found in derived entity. If this is a case, I just don't change the value. If the value is found, I replace it with a new one. And here's what I had to do previously:
auto entityTable = luabridge::getGlobal(L, "someEntity");
auto componentTable = entityTable["GraphicsComponent"];
auto filenameRef = componentTable["filename"];
if(!filenameRef.isNil()) {
    filename = filenameRef.cast<std::string>();
}
Notice how it's almost the same as the previous example. Can I implement it better with new scriptManager? Sure
auto componentTable = scriptManager.getTable("someEntity.GraphicsComponent");
auto filenameRef = scriptManager.getRef("filename", componentTable);
if(filenameRef.isNil()) {
    filename = filenameRef.cast<std::string>();
}
This almost looks like LuaBridge code above! So I came up with a better solution, now I can do stuff like this:
scriptManager.getData(filename, "res/images/error.png", "filename", componentTable, isOverwrite);
Here's what's going on. Fist of all, notice that I don't have to specify template argument because of the type deduction which happens because I pass the first argument.
If isOverwrite == false, this works as getData<std::string> that I showed above. If isOverwrite == true, then I rewrite the value only if it's found. But I don't write about errors that some tables or values are not wrong, because some values may be missing in derived entities and that's fine.
So, this one line works for two cases: loading value expecting to find it and trying to overwrite value only if the value is found.

So, all this stuff lead me to great simplification of script loading code, allowed me not to worry about the errors in scripts and reduced a lot of header dependencies. This also allows me to replace LuaBridge with some other library in the future only by changing LuaScriptManager and not bothering about other code which is very good.

I'm very glad I did this epic refactoring/engine improvement. Now I'm a lot more confident in the engine and I'm already making some progress about the game. :)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on November 30, 2015, 10:31:39 pm
Today I've integrated new shadow system in the game (previously I used it in a test project). Here's how it looks!
(http://i.imgur.com/DOlQtfI.gif)
Notice, that I don't draw shadows when I turn on the fog.

There's a lot of stuff to improve, of course. Here's one of such improvements:
(http://i.imgur.com/Uzc5ft4.png)
The shadow on the left doesn't look as it should because the dirt/grass and tombstone were one sprite, so shadow system used all that sprite to create a shadow. But if I separate them and tell the system to generate a shadow only from the tombstone, it all becomes much better! (The shadow must be smaller though, but it's easy to change!)

Here's another screenshot for fun. There are still lots of things I have to make better (like don't skew shadows very much in some objects and there's other stuff) but I'm very satisfied with the result. The game looks more alive now!
(http://i.imgur.com/3RqbSBc.png)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on November 30, 2015, 11:39:58 pm
This is looking better and better every time. Good work!

Notice, that I don't draw shadows when I turn on the fog.
The absence of the 'dynamic' shadows makes the presence of the hand-animated shadows look odd (at the bottom of the lamps).
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 01, 2015, 06:10:52 am
Thanks a lot!

Oh, I completely forgot about those. They are drawn directly with the sprite itself, I guess I have to separate them  and draw shadow and torch sprites separately :D
Or I can use a shader which will remove "shadow" pixels from the texture (this is even easier, ha-ha!)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 01, 2015, 01:47:47 pm
If you love Re:creation, please vote for it, so maybe it wins Indie of The Year indiedb award!  ;D
Vote now! (http://www.indiedb.com/games/recreation)
Do it, so you can spend more time talking with this cat in the future
(http://i.imgur.com/EF18sUv.png)
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 01, 2015, 06:21:29 pm
Voted. You and your awesome game deserve it :-)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 01, 2015, 06:34:25 pm
Thanks a lot, Jesper!  ;D
Title: Re:creation - a top down action adventure about undeads
Post by: shadowmouse on December 01, 2015, 07:01:12 pm
Same. I think I'm possibly anticipating this more than any professionally made game at the moment.
Title: Re:creation - a top down action adventure about undeads
Post by: Mortal on December 01, 2015, 07:03:48 pm
Voted, here  ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 01, 2015, 07:13:27 pm
I think I'm possibly anticipating this more than any professionally made game at the moment.
I know what you mean. All the cool screenshots, details about implementation, etc etc, has built up a huge amount of suspense.
I want to play this now! ;-) (for Linux, please).
Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on December 01, 2015, 08:18:20 pm
Voted from work pc and home pc ;D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 01, 2015, 11:00:54 pm
Thanks you very much, everyone! Your support means a lot to me. I'm very glad that you find the game and the dev process interesting. Sometimes I have doubts about my skills, but hearing such kind words makes me confident and motivated to work more and more. :)

Jesper Juhl, Linux demo is totally coming when Windows version will be out. Though, I haven't compiled on Linux since March... hope most of the code works and there'll be no need to fix a lot of stuff. :D

(Btw, I'm working on wall shadows, they're pretty tricky to make)
(https://pbs.twimg.com/media/CVK7kgSVAAEsfqb.jpg)
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 02, 2015, 04:36:54 pm
Jesper Juhl, Linux demo is totally coming when Windows version will be out. Though, I haven't compiled on Linux since March... hope most of the code works and there'll be no need to fix a lot of stuff. :D
Why don't you set up a CI system like Jenkins or BuildBot to build every commit on all of your target platforms and then run your tests?

That way you'll instantly know if you caused a target to fail to build or a test to fail and you'll also know which exact commit broke it.

And you can use both physical machines and virtual ones (or a mix) as your build slaves.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 02, 2015, 06:31:56 pm
Yeah, I really need to do it some day. Any good articles about setting it all up? :D
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 02, 2015, 06:50:00 pm
Not really. But I've set up both BuildBot and Jenkins a few times, both at home and at a couple of employers - just using the official docs. It's really not that hard.  Set aside a day and read up on it in the morning and set it up in the afternoon. By evening you'll have a working setup and it'll be a day well spent going forward :-)

And your second step (when you have another day to burn) should then be to get your CI system to generate installation packages every night for all your target platforms. So that every morning you'll have a fresh set of MSI's, RPM's, DEB's, etc etc, ready to deploy to your customers.
And if you don't already have the generation of such packages/installers automated; well, pull out one more day from the calender and do that. That's also a day well spent (IMHO) - you really don't want to constantly have to do that crap by hand - a computer can do it better (every night).
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 03, 2015, 08:40:16 am
Thanks for advice. I'll try something out very soon. :D

By the way, can someone give me advice about how to make this stuff better?
So, I load components from scripts like this:
void AIComponent::loadFromScript(const std::string& entityName, const LuaRefWrapper& componentTable,
    bool overwrite)
{
    scriptManager.getData(viewSize, "viewSize", componentTable, overwrite);
    scriptManager.getData(type, "type", componentTable, overwrite);
    ...
}
So, the first argument is the variable in which the value from the script is written. The second argument is the name of the value in the script, the third argument is the component table in the script and the fourth argument is the script manager mode (doesn't really matter that much, it's just a bool).

So, for example I have something like this in the script:
enemy = {
    AIComponent = {
        type = "chaser",
        ...
    }
}
So, the componentTable is enemy.AIComponent

As you can see, always passing the third and the fourth argument is getting pretty annoying. Is the some good way to make this code better? Something like this:
void AIComponent::loadFromScript(const std::string& entityName, const LuaRefWrapper& componentTable,
    bool overwrite)
{
    ... // temporally set componentTable and overwrite mode in ScriptManager
    scriptManager.getData(viewSize, "viewSize");
    scriptManager.getData(type, "type");
    ... // automatically unset this, so the next time I use scriptManager, it works as usual
}
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 03, 2015, 10:04:43 am
Why not just make a simple wrapper?

void AIComponent::loadFromScript(const std::string& entityName, const LuaRefWrapper& componentTable,
    bool overwrite)
{
    ScriptDataLoader loader(scriptManager, componentTable, overwrite);
    loader.get(viewSize, "viewSize");
    loader.get(type, "type");
}
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 03, 2015, 01:50:11 pm
Why not just make a simple wrapper?

void AIComponent::loadFromScript(const std::string& entityName, const LuaRefWrapper& componentTable,
    bool overwrite)
{
    ScriptDataLoader loader(scriptManager, componentTable, overwrite);
    loader.get(viewSize, "viewSize");
    loader.get(type, "type");
}
Yeah, that's a good idea, thanks! Would make the code so much cleaner and easier to write. :D
(Btw, I was wondering, what is the name of this pattern? It kinda looks familiar)
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 03, 2015, 02:41:33 pm
I don't know if it's a known pattern ; maybe an adapter? Anyway, to me it's just "putting redundant stuff into a common place" ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 03, 2015, 02:53:49 pm
I don't know if it's a known pattern ; maybe an adapter? Anyway, to me it's just "putting redundant stuff into a common place" ;)
Yeah, looks like it. I did it, btw. Looks so much better!

(http://i.imgur.com/pZlKYhE.png)

I kinda want to write a macro like this:
#define GET_SCRIPT_DATA(loader, x) loader.get(x, #x)
so I could do this:
GET_SCRIPT_DATA(loader, chargeAnimationName);
// expands to loader.get(chargeAnimationName, "chargeAnimationName");
But that may be too extreme and silly. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 05, 2015, 10:14:21 pm
(http://i.imgur.com/hXo02P5.png)
QtCreator + CMake + GCC 5.2.1 + Xubuntu VM. Works pretty well, as you can see. Still have to fix some stuff, but I didn't have to change much to compile/run my game on Linux which is a very good sign! :D
The biggest fails were because of differences in newline characters. "\n" vs "\r\n". Any good way to deal with them? Remove them after each getline? Any other ways? :D
Title: Re:creation - a top down action adventure about undeads
Post by: dabbertorres on December 05, 2015, 11:54:14 pm
I just always use '\n'. Everything I've used except Notepad (which no one in their right mind uses for programming) parses it just fine.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 06, 2015, 08:06:27 am
I just always use '\n'. Everything I've used except Notepad (which no one in their right mind uses for programming) parses it just fine.
So, should I change line endings to Linux-style in every editor I use? :D
Btw, strangely enough:
getline(file, line); // this line is "SCRIPTS_BEGIN" in file
if(line == "SCRIPTS_BEGIN") { // true on Windows, false on Linux!
    ...
}
So I need to remove \r\n or just \n to get the expected results. This is because I read files with windows endings on Linux. Is there a better solution to the problem?

Question to those, who use CMake with large projects: do you use glob or do you specify source files by hand? I have 135 .cpp files and lots of sub-directories, so I'm afraid that specifying them by hand would take a long, but is it worth it?
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 06, 2015, 01:36:46 pm
If you don't open files with the std::ios::binary flag, newlines should be treated correctly by the stream, independantly of the platform.

I never use glob with CMake. Since I never add 150 files at once to the project, this is not really a problem ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 06, 2015, 02:34:15 pm
If you don't open files with the std::ios::binary flag, newlines should be treated correctly by the stream, independantly of the platform.
The problem is that I open files (which were created in Windows) in Linux, so getline produces different results on Windows and Linux. I'd probably write a function which will just remove line endings from strings. :D

I never use glob with CMake. Since I never add 150 files at once to the project, this is not really a problem ;)
Maybe I should devote some hours to it and just do it. :D
Btw, what is the correct way to manage subfolders? I know that I must add CMakeLists to each subfolder, but what should those files contain? I see that SFML sets SRC variable, but does it actually append to SRC? Can I use this method to do this in the main CMakeLists?
add_executable(game ${SRC})
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 06, 2015, 03:07:34 pm
You don't need to create CMakeLists.txt files in every sub-folder. If they just contain source files and headers, you can reference them from the main CMakeLists.txt with their relative path.
Title: Re:creation - a top down action adventure about undeads
Post by: shadowmouse on December 06, 2015, 03:53:39 pm
Just out of interest, why do you have so many files? How much do you put in each? That might well be the reason for your compile time taking minutes unlike the usual few seconds.
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 06, 2015, 04:12:05 pm
Just out of interest, why do you have so many files? How much do you put in each? That might well be the reason for your compile time taking minutes unlike the usual few seconds.
I would expect to opposite.
With many individual files the amount of code that needs to be recompiled when you change something is likely to be less than if you had a few monster files that are all impacted by every little change.

My personal rule of thumb is one class per .h/.cc file.
Title: Re:creation - a top down action adventure about undeads
Post by: shadowmouse on December 06, 2015, 04:21:31 pm
That's my rule as well (except with .hpp and .cpp), I just thought that once you had split stuff up that much, the shear amount of files that would have to be compiled, especially if a header file was changed could be what's taking ages. I just remember Elias saying something about it taking at least 2 minutes to compile, which is weird because in my experience things take 15 seconds tops, usually closer to 2 seconds to compile unless you're doing a full rebuild.
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 06, 2015, 04:43:19 pm
With many individual files the amount of code that needs to be recompiled when you change something is likely to be less than if you had a few monster files that are all impacted by every little change.
This is definitely true, and a good reason to keep dependencies between different modules low, for example by:
However, having many files comes with the problem that often-used external code in headers (from standard and other libraries) must be included in many more files, and recompiled again and again in each of them.

The effect of this depends strongly on the compilers' capabilities to cache code that doesn't change (which is not always trivial, since single declarations or macros can change the behavior of everything that follows). Good compiler toolchains therefore offer an explicit option to precompile headers. Furthermore, with the number of files increasing, the effort for the linker increases as well, thus the linking step may take longer.
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 06, 2015, 04:51:55 pm
@Nexus : What you say is true of course. And one should always try to only include what one uses and no more and always use forward declarations where possible etc. On top of that I'd recommend using ccache (https://ccache.samba.org/). It can really speed up your recompiles when most files can just be taken from the cache rather than re-running the compiler.
Ohh and using a fast compiler like clang (http://clang.llvm.org/) can also help a lot.
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 06, 2015, 09:10:17 pm
I just remember Elias saying something about it taking at least 2 minutes to compile, which is weird because in my experience things take 15 seconds tops, usually closer to 2 seconds to compile unless you're doing a full rebuild.
That very much depends on the size and complexity of the code you are working on.
Sure, for many personal hobby projects sub-minute build times are probably the norm. But projects grow...
The code base I work on at work is ~60000 files and takes about 30min to rebuild from scratch on a modern 8core machine. With ccache it can then usually be re-built in a few minutes (0.5-3.0) if you only make small local changes..
Also, have you tried building something like Qt5 from scratch? On my (8core) laptop it takes >4hrs.
Title: Re:creation - a top down action adventure about undeads
Post by: shadowmouse on December 06, 2015, 09:20:14 pm
No I'll be honest I haven't tried stuff like that. I was merely guessing at the amount of code that goes into something like this because it's similar to an unfinished old project of mine which I used to be able to compile in 10 seconds.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 06, 2015, 10:53:24 pm
You don't need to create CMakeLists.txt files in every sub-folder. If they just contain source files and headers, you can reference them from the main CMakeLists.txt with their relative path.
Yeah, but why do most people put them in every sub-folder anyway? Even SFML does it! :D

Just out of interest, why do you have so many files? How much do you put in each? That might well be the reason for your compile time taking minutes unlike the usual few seconds.
I have so many files, because I have lots of code! ~16k lines of code in .cpp and most of the files are 100-200 lines long. Most of the time compilation is pretty fast. Compilation times are bigger when I change some base files like Entity.h or Component.h. But mostly, they're pretty okay. I forward-declare as much as possible and  ECS makes me not make large inheritance trees, so dependencies are minimal.
And btw, my laptop is not very good, so this adds to compilation time. Full recompilation takes around 4-6 minutes.

The biggest problems with compilation times were caused by LuaBridge, but I've already fixed that :)
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 06, 2015, 10:59:21 pm
Quote
Yeah, but why do most people put them in every sub-folder anyway? Even SFML does it!
There's a CMakeLists.txt file where there is a new binary to configure. There are plenty of sub-folders in SFML that don't have this file, because they exist only to organize source code (the whole headers hierarchy, or the various platform folders in System and Window, for example).
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 06, 2015, 11:03:56 pm
There's a CMakeLists.txt file where there is a new binary to configure. There are plenty of sub-folders in SFML that don't have this file, because they exist only to organize source code (the whole headers hierarchy, or the various platform folders in System and Window, for example).
Oh, okay, this makes sense. Hmm, seems like using GLOB doesn't change anything in my case (except that I need to run CMake each time I add/remove file) :D
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 07, 2015, 08:54:59 am
The biggest problems with compilation times were caused by LuaBridge, but I've already fixed that :)
May I ask how you did that? :)
Title: Re:creation - a top down action adventure about undeads
Post by: eXpl0it3r on December 07, 2015, 09:00:59 am


May I ask how you did that? :)
See here: http://en.sfml-dev.org/forums/index.php?topic=18062.msg139957.msg#139957
Title: Re:creation - a top down action adventure about undeads
Post by: Jabberwocky on December 09, 2015, 01:42:18 am
Voted!
Looking great, Elias.  :)

This is definitely true, and a good reason to keep dependencies between different modules low, for example by:
  • Having classes with small APIs and let each reference only a few "neighbors" that logically relate
  • Avoiding central manager- and singleton-style classes used everywhere
  • Using forward declarations or even the PImpl idiom where appropriate
  • Including only the necessary specific headers and no mass includes like <SFML/Graphics.hpp>

All good suggestions, except for the singleton-style critique.  There's nothing inherent about a singleton that makes it any better or worse than a non-singleton for dependencies.  Sure, you can design a singleton poorly, but you can design a non-singleton poorly as well.

Singleton talk is one of those "holy war" type coder conversations.  If anyone wants to debate them further (as if everything hasn't already been debated 1000x over ;)) I'd suggest we start a new thread on it.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 09, 2015, 01:04:25 pm
Thanks, Jabberwocky!

Yeah, let's not discuss singletones. :)
Here's a thing I want to discuss: Manager classes.
There are some useful managers in my game: ResourceManager, LogManager, LuaScriptManager, etc.

I store pointers to them in a global structure named engine_system.
struct EngineSystem {
     LogManager* log;
     ... // etc.
}
To write something in log, I need to do it like this:
engine_system.log->write("Something happened");
This allows me to do some cool stuff, like making FileLogManager and ConsoleLogManager and then replace simple LogManager with FileLogManager which writes to file. Or, I can create NullLog which will ignore all the messages.
This is a Service Locator pattern. So, here are the things I want to discuss

1) How do I make a better interface to this? Maybe I should do something like this?
engine_system.getLog()->write(...);
Or maybe there are better alternatives?

2) Avoiding usage of global engine_system.
Sometimes I can pass needed managers to functions, like this:
void handleInput(const InputManager& inputManager);
But sometimes there's no such possibility, because it's hard to predict which managers will be needed (especially hard with virtual functions!)
So, what are your tips on dealing with this?
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 09, 2015, 01:31:32 pm
Quote
How do I make a better interface to this?
In the end it will always be a global access to some variable. So whether it is behind a function, a parent structure, or whatever, won't make much difference. Some will say that using a getter function is more flexible, since you can change the implementation without impacting the API. In real life, I can hardly see what you would change in a function that just returns an object.

Quote
Avoiding usage of global engine_system.
It is a fact that global access to some objects is the best design sometimes. There's no need to try to avoid it at all costs, if it's the best solution for you. What's important is to avoid global lifetimes whenever possible, because this is what causes problems: construction before main() and destruction after main(). But to me, global access is fine for objects that are used everywhere, and not really tied to what a function does (it would be silly to pass a log manager argument to every function that may log something).

A design that I often use is a globally accessible Application class (*), instanciated in main(), and which takes care of construction and destruction of all other "global" objects, as well as giving access to them. This way you avoid lots of global objects scattered all over the code, and you have fine control over order of construction, dependencies between them, etc. And you only have a single true global object to deal with, in case one day you decide that this is not a good design anymore.

(*) in a Qt application it is kind of mandatory anyway, because that's already how Qt works -- and I work with Qt ;D
Title: Re:creation - a top down action adventure about undeads
Post by: Jabberwocky on December 09, 2015, 08:42:03 pm
What's important is to avoid global lifetimes whenever possible, because this is what causes problems: construction before main() and destruction after main(). But to me, global access is fine for objects that are used everywhere, and not really tied to what a function does (it would be silly to pass a log manager argument to every function that may log something)

Good approach, Laurent.
I agree, and bolded what I consider the most important part for emphasis.

Title: Re:creation - a top down action adventure about undeads
Post by: Ricky on December 10, 2015, 01:22:31 am
What Laurent Said

All of this and also I understand where you are coming from Elias. The problem is that sometimes OOP is NOT the best solution to the problem but we have been sort of indoctrinated into this OOP religion where all the problems we have we think we can solve with OOP and UML charts.

I recommend watching this http://www.twitch.tv/handmade_hero/v/28507308 (http://www.twitch.tv/handmade_hero/v/28507308) recent talk at Handmade Con 2015. Very eye opening. Being dogmatic about programming is counter productive. If what you need is a global then do it. I also use a global for logging. I'm also considering a simpler design using a global gCurrActor and gCurrScene and then just have functions that operate on them. This is to simplify the process of Lua binding.

--Edit: Here is a link to the Logger I'm using https://github.com/ricanteja/MoonySpriteBatch/blob/master/include/Log.h (https://github.com/ricanteja/MoonySpriteBatch/blob/master/include/Log.h)
Title: Re:creation - a top down action adventure about undeads
Post by: SeriousITGuy on December 10, 2015, 07:59:02 am
I also use one global data structure which holds (non-owning) pointers to all engine subsystems (which are owned by the main application class), like renderer, audio, logger (even a blackboard for simple data exchange between different game states). In my opinion it is a simple and at the same time elegant solution to this problem. So everthing I do is to pass this global object to all gamestates, and from there every state has access to all engine subsystems.
I think in the book SFML Game Development the same concept is used, and it worked perfectly.
Title: Re:creation - a top down action adventure about undeads
Post by: eXpl0it3r on December 10, 2015, 08:30:40 am
(it would be silly to pass a log manager argument to every function that may log something).
Not according to my prof. :P
We're only allowed to use std::cin/std::cout in the main file and otherwise have to pass around the streams. But it does make sense to some extend, because that way we can easily test all classes and functions.
Then again a log class maybe a slightly different topic. Point being that in general globally accessible objects create side effects which are often nearly impossible to test against. ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 10, 2015, 02:21:47 pm
But to me, global access is fine for objects that are used everywhere, and not really tied to what a function does (it would be silly to pass a log manager argument to every function that may log something).
Yep, agreed. Thanks for making me stop doubting this stuff :D

(*) in a Qt application it is kind of mandatory anyway, because that's already how Qt works -- and I work with Qt ;D

Didn't really think about this before, that's a good analogy :D

Ricky, I'm currently watching Handmade Con and it's one of the best stuff to happen ever, haha. Lots of cool stories from awesome guys! :D

SeriousITGuy, yeah I mostly use this approach too (try to avoid using the global engine_system as possible), but sometimes the object is not really connected to game states and still needs to log stuff, that's where global engine_system is useful.

eXpl0it3r, yeah, sometimes it makes sense to pass a stream, but only when you know that this function will write some stuff most of the time. Passing it "just in case" may be poor design in some cases, IMHO.

After all, I think that some managers are almost like free functions which perform stuff without changing lots of stuff. They have their own members sometimes, but they don't change that much, so this is not a big deal. If I had some global stuff which was used everywhere and could change in some places, that would be another problem! :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 12, 2015, 12:06:25 pm
I'm starting to write a small animation tool for my game in Qt, so I don't have to modify JSON by hand. Why don't I just use JSON editor? That's because I'll add animation preview window soon.

I would like to ask: what's the current status on Qt + SFML? Do they work together? Are there many problems? :D

I would like to have a widget which would render stuff in SFML and I'll use Qt for GUI (possibly I'll create GUI for level editor using Qt if it all works all right, this would save me so much time!)

Progress update
Got some basic stuff working
(http://i.imgur.com/Ks5H7Qt.png)
The coolest thing about it is that it's much more readable than JSON because I can display better variable names. Here's how this animation looks in JSON:

{
    "directions" : null,
    "frame" :
    [
        0,
        64,
        32,
        32
    ],
    "frameTime" : 100,
    "isLooped" : false,
    "name" : "die",
    "numOfFrames" : 13,
    "offset" :
    [
        2,
        -2
    ]
},
 

I think I'll move most of the entity stuff (data) in JSON and use Lua for functions for the rest, so I may create Entity Creation Tool which will work the same way as Animation Tool and if I integrate it with my engine, I'll be able to see how entity would look like as I create it. Isn't it awesome? :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 13, 2015, 09:00:50 am
(http://i.imgur.com/hz42v6W.png)
It's happening! This is Qt with SFML drawing! :D
Animations are not yet implemented, but as you can see Qt and SFML work very well together! Integrating them was very easy, here's what I did. Feel free to give me some tips on how to make stuff better and tell me your experience with Qt + SFML :D

SFMLWidget.h
#ifndef SFMLWIDGET
#define SFMLWIDGET

#include <QWidget>
#include <SFML/Graphics/RenderWindow.hpp>

class SFMLWidget : public QWidget
{
public:
    SFMLWidget(QWidget* parent = nullptr);

    void processEvents();
    void processInput(int dt);
    void update (int dt);
    void draw();
private:
    QPaintEngine *paintEngine() const;
    void enterEvent(QEvent *) override;
    void paintEvent(QPaintEvent*) override;

    sf::RenderWindow window;
    sf::View view;
};

#endif // SFMLWIDGET
 

SFMLWidget.cpp

#include "sfmlwidget.h"
#include <SFML/Window/Event.hpp>

SFMLWidget::SFMLWidget(QWidget *parent) :
    QWidget(parent),
    view(sf::FloatRect(0.f, 0.f, 128.f, 120.f))
{
    //Setup some states to allow direct rendering into the widget.
    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_NoSystemBackground);
    setAttribute(Qt::WA_PaintUnclipped);

    //Set strong focus to enable keyboard events to be received.
    setFocusPolicy(Qt::StrongFocus);

    //Under X11, we need to flush the commands sent to the server to ensure that
    //SFML will get an updated view of the windows
#ifdef Q_WS_X11
    XFlush(QX11Info::display());
#endif

    window.create((HWND)winId()); //Create the SFML window with the widget handle
    window.setView(view);
}

QPaintEngine* SFMLWidget::paintEngine() const
{
    //We make the paintEvent function return a null paint engine. This functions works together with
    //the WA_PaintOnScreen flag to tell Qt that we're not using any of its built-in paint engines.
    return nullptr;
}

void SFMLWidget::enterEvent(QEvent *)
{
    setFocus();
}

void SFMLWidget::paintEvent(QPaintEvent *event)
{
    draw();
}

void SFMLWidget::processEvents()
{
    sf::Event event;
    while(window.pollEvent(event)) {
        ... // process events
    }
}

void SFMLWidget::processInput(int dt)
{
    ... // process input
}

void SFMLWidget::update(int dt)
{
    ... // update stuff
}

void SFMLWidget::draw()
{
    window.clear();
    ... // draw
    window.display();
}

And then you can use SFMLWidget as QWidget without any problems!
And now I need to figure out how to do game loop inside this stuff and I'll try to use it with my engine if this works out well :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 13, 2015, 10:42:17 am
I'm writing a lot today :D
Managed to get a basic loop working.
(http://i.imgur.com/5SjFPaR.gif)

Code:

#include "mainwindow.h"
#include "sfmlwidget.h"

#include <QApplication>
#include <QTime>

int main(int argv, char *args[])
{
    QApplication app(argv, args);
    MainWindow window;
    window.show();

    SFMLWidget* sfmlWidget = window.getSFMLWidget();

    int timeSinceLastUpdate = 0;
    int TimePerFrame = 16;

    QTime mainClock = QTime::currentTime();

    while(window.isVisible()) {
        app.processEvents();

        int delta = mainClock.restart(); // just like in SFML, lol
        timeSinceLastUpdate += delta;

        while (timeSinceLastUpdate > TimePerFrame) {
            timeSinceLastUpdate -= TimePerFrame;
            sfmlWidget->processEvents();
            sfmlWidget->update(TimePerFrame);
        }
        sfmlWidget->draw();

        // add small sleep time, so we don't get delta == 0
        QTime dieTime= QTime::currentTime().addMSecs(1);
        while (QTime::currentTime() < dieTime) { } // wait until time passes
    }

    app.exit();

    return 0;
}

So, fixed-delta, pretty cool. But I have to add small sleep period (1 ms), or else delta will be 0 most of the time (Qt's timer is not very precise). Is it the best way to deal with this problem?
(And I need to figure out how to process SFML events for keyboard input, and then most of the work is done! :D)

Update: SFML events work well, I can easily get sf::Event::MouseEntered/Left to capture input
sf::Keyboard::isPressed works too! :D
Title: Re:creation - a top down action adventure about undeads
Post by: eXpl0it3r on December 13, 2015, 08:28:59 pm
Oh nice! :)

I've often thought about playing around with SFML and Qt, but never got around to it. Also nice to see that events are working, some threads about SFML and Qt had issues with event processing.

What exactly do you need the Qt timer for? C++11 introduces <chrono> which also has some highprecision timer (iirc).
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 13, 2015, 08:49:32 pm
Or sf::Clock, or QElapsedTimer. But please don't use QTime as a timer :P

And simply use sf::sleep or QThread::msleep if you want to pause the execution.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 13, 2015, 09:36:25 pm
Oh nice! :)

I've often thought about playing around with SFML and Qt, but never got around to it. Also nice to see that events are working, some threads about SFML and Qt had issues with event processing.
Yeah, this was a pleasant surprise for me, much easier than I expected.
Well, I didn't test all events, but MouseEntered/MouseLeft work well, and that's pretty much all I need for now. :D

What exactly do you need the Qt timer for? C++11 introduces <chrono> which also has some highprecision timer (iirc).
No need for it, yeah. I just saw people doing stuff with Qt timer and now I realize that I can just use sf::Clock, ha-ha :D
(Hmm, I wonder what's better: <chrono> or sf::Timer?)

Or sf::Clock, or QElapsedTimer. But please don't use QTime as a timer :P

And simply use sf::sleep or QThread::msleep if you want to pause the execution.
Okay, thanks :D
So, should I use sleep to wait for some time if the delta was too low to not waste lots of resources, updating events all the time?

Starting to think about how I should map components to JSON objects, this will be very interesting to solve...
Basically I want to change some value in JSON object and automatically change corresponding value in the object without tons of if/else stuff.
I also wonder how to decouple editor from game. I guess I should have some game.dll and Qt application will call some functions from it... I've never done stuff like this before, this will be something new :D

Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 13, 2015, 10:29:05 pm
(Hmm, I wonder what's better: <chrono> or sf::Timer?)
In general, you should prefer the standard library where possible. However, in this particular case your code will be more portable with sf::Clock, because some standard library implementations (e.g. those of Visual Studio) were known to not use high-precision timers in Chrono until a few years ago.

Starting to think about how I should map components to JSON objects, this will be very interesting to solve...
Basically I want to change some value in JSON object and automatically change corresponding value in the object without tons of if/else stuff.
You should work with a C++ data structure that represents the JSON tree layout (which is very simple: arrays and objects=maps). I'm pretty sure good JSON libraries already come with that.

I also wonder how to decouple editor from game. I guess I should have some game.dll and Qt application will call some functions from it... I've never done stuff like this before, this will be something new :D
I wouldn't stick to one dynamic library format (DLL) unless you actually need it. There are various options for inter-process communication, see here (http://www.boost.org/doc/libs/1_59_0/doc/html/interprocess.html#interprocess.intro) for a list of common ones. Network sockets are also a possibility.

But are game and editor actually running in parallel, in two applications, and they need to know each other?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 13, 2015, 10:52:41 pm
In general, you should prefer the standard library where possible. However, in this particular case your code will be more portable with sf::Clock, because some standard library implementations (e.g. those of Visual Studio) were known to not use high-precision timers in Chrono until a few years ago.
Alright, thanks. Less differences between game and level editor code, yay! :D

You should work with a C++ data structure that represents the JSON tree layout (which is very simple: arrays and objects=maps). I'm pretty sure good JSON libraries already come with that.
I use jsoncpp which has that, but I want to do this.
Suppose I have a class like this in C++
class Animation {
     int frameTime;
     int frameCount;
     ...
};
which looks like this in JSON:
{
     "frameTime" : 100,
     "frameCount" : 10
}
I output Json table (Json::Value in C++) to Qt table which then maps every field to Json::Value object, so when I change table value, corresponding Json::Value changes. But I also need to update corresponding C++ value. So I have to map Json::Value object to pointer to corresponding value, so when Json::Value changes, the variable value changes automatically. I already have some ideas how to implement this, but maybe there are easy ways to do this stuff.

I wouldn't stick to one dynamic library format (DLL) unless you actually need it. There are various options for inter-process communication, see here (http://www.boost.org/doc/libs/1_59_0/doc/html/interprocess.html#interprocess.intro) for a list of common ones. Network sockets are also a possibility.

But are game and editor actually running in parallel, in two applications, and they need to know each other?
Thanks, I'll check this out.
I want to have an instance of game running in Qt application. I can use code directly from my game project and then call functions from it, but I feel like this is a bad idea.
So, I need some other way to link editor and game engine code.
They, of course, need to communicate somehow. Suppose I click on some object. Level editor calls some function from game engine like this:
Entity* findEntity(sf::Vector& mousePos);
and now I get a pointer to entity and level editor can do pretty much everything with it, so if I decide to delete it, it does calls function from Game:
removeEntity(selectedEntity);
This would be trivial if I just #included some stuff from main code base, but I feel like game engine and level editor need to be separate somehow. (Hell, some devs write their editors in C# while the game engine is in C++, you can't do #include's in C# for code in C++, so you can't call it directly)
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 13, 2015, 11:25:33 pm
I already have some ideas how to implement this, but maybe there are easy ways to do this stuff.
MVC is a common pattern. Your C++ Json::Value class would then be the model, and the Qt table (or even the JSON file) the view. Changes in one will notify and update the other. Have a look at the Qt documentation to see how it provides such functionality.

I can use code directly from my game project and then call functions from it, but I feel like this is a bad idea.
So, I need some other way to link editor and game engine code.
If we're only talking about code, and not actual concurrent processes at runtime, why don't you simply outsource the shared code into a library?

This would be trivial if I just #included some stuff from main code base, but I feel like game engine and level editor need to be separate somehow.
Don't make your life overly complicated because you feel something. You know, keeping things simple is a skill.
A library is the straightforward approach here.

(Hell, some devs write their editors in C# while the game engine is in C++, you can't do #include's in C# for code in C++, so you can't call it directly)
There are well-established techniques for ports between languages (e.g. P/Invoke in this case). But you're dealing with a different problem ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 14, 2015, 07:01:07 am
MVC is a common pattern. Your C++ Json::Value class would then be the model, and the Qt table (or even the JSON file) the view. Changes in one will notify and update the other. Have a look at the Qt documentation to see how it provides such functionality.
I've already implemented a part of that. So, when the Qt table value changes, value in JSON changes automatically. But now I need to go further, I need to change C++ variable which corresponds to the changed JSON value, which is a harder problem, I think. :)

A library is the straightforward approach here.
Yeah, it seems like it.
I just have  no idea how they work because I never before had a need to do such code re-use. But I'll figure it out. (Btw, any good resources I can read about making libraries? Or is it so simple that I can't do wrong? :D)

There are well-established techniques for ports between languages (e.g. P/Invoke in this case). But you're dealing with a different problem ;)
Yep :D
Title: Re:creation - a top down action adventure about undeads
Post by: Jesper Juhl on December 14, 2015, 07:04:31 am
A library is the straightforward approach here.
Yeah, it seems like it.
I just have  no idea how they work because I never before had a need to do such code re-use. But I'll figure it out. (Btw, any good resources I can read about making libraries? Or is it so simple that I can't do wrong? :D)
This might be of use : http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 14, 2015, 07:45:31 am
If you only need the JSON <--> C++ mapping in the level editor, then you can use the Qt meta-object system, which allows class introspection.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 14, 2015, 07:59:03 am
This might be of use : http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Thanks!

If you only need the JSON <--> C++ mapping in the level editor, then you can use the Qt meta-object system, which allows class introspection.
I may be wrong, but doesn't it require me to inherit from QObject? I can't do this, because I don't want to change the existing classes from my game. Or maybe I can create some wrapper class which will inherit from QObject and use Qt's introspection? Something like:
class AnimationWrapper : public QObject {
    Q_OBJECT
   
public:
    AnimationWrapper(Animation& animation) :
        frameCount(animation.frameCount),
        frameTime(animation.frameTime),
        ...
    {}
   
private:
    int& frameCount;
    int& frameTime;
    ... // etc.
   
};
and then later...
Q_PROPERTY(int& frameCount READ frameCount)
so when the JSON value changes I can do something like this:
animWraper.setProperty(changedValueName, newValue); // both are taken from Json::Value which just changed

Btw, animations are working now :D
(http://i.imgur.com/ufJxIIu.gif)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 14, 2015, 04:26:37 pm
(http://i.imgur.com/apwae3f.gif)
Okay, got some basic introspection working. Here's how the wrapper looks.

class AnimationWrapper : public QObject {
    Q_OBJECT
    Q_PROPERTY(bool looped READ isLooped WRITE setLooped)
    Q_PROPERTY(int frameCount READ getFrameCount WRITE setFrameCount)
    Q_PROPERTY(int frameTime READ getFrameTime WRITE setFrameTime)

public:
    AnimationWrapper(Animation* anim) :
        anim(anim)
    { }

    // is looped
    bool isLooped() const {
        return anim->isLooped();
    }

    void setLooped(bool b) const {
        anim->setLooped(b);
    }

    // frame count
    int getFrameCount() const {
        return anim->getFrameCount();
    }

    void setFrameCount(int fc) {
        anim->setFrameCount(fc);
    }

    // frame time
    int getFrameTime() const {
        return anim->getFrameTime().asMilliseconds();
    }

    void setFrameTime(int frameTime) {
        anim->setFrameTime(sf::milliseconds(frameTime));
    }
private:
    Animation* anim;
};
That's not the coolest thing, yeah, but now I can do this:
animationWrapper->setProperty("frameCount", 10); // same as calling animation->setFrameCount(10);
So, when some value changes, I find corresponding animation wrapper, and then I can change animation parameters using this wrapper.

Update: but then I realized that this system kinda sucks and I shoudn't really use QObject, because some introspection will be useful when loading components in the game from Json in the future...
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 14, 2015, 05:47:27 pm
Don't you already have a Lua binding of all your classes and objects? Can't you use it for introspection?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 14, 2015, 06:00:34 pm
Don't you already have a Lua binding of all your classes and objects? Can't you use it for introspection?
I have one way binding like this:
void SomeComponent::loadFromScript()
{
     someVar = scriptManager.getData<SomeVarClass>(entityName + ".someVar");
     ...
}
So it's one way only. I can't set variables by name. I could change the value in Lua table and call loadFromScript again... but that's just silly.
And I think about moving most data stuff to JSON in near future.

Right now I think about implementing meta stuff like this:
void SomeComponent::SomeComponent()
{
     meta_register<SomeVarClass>("someVar", this, getSomeVar, setSomeVar); // getSomeVar/setSomeVar are get/set functions
     ...
}
and then I'll be able to do this:
someComponent->setProperty("someVar", newValue);
and this:
auto value = someComponent->getProperty("someVar");
So, it's basically like QObject meta stuff works, but without moc_....cpp and macros.

I can use it for
1) Loading from JSON (no need to write it by hand)
2) Saving to JSON
3) Displaying/changing component variables with Qt
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 15, 2015, 08:19:24 am
Okay, so I got some basic meta-property system working which lets me do this:
class Animation : public MetaObject
{
public:
    Animation()
    {
        meta_register("name", name);
        meta_register("isLooped", isLooped);
        meta_register("frameCount", frameCount);
    }
private:
    std::string name;
    bool isLooped;
    int frameCount;
};

int main()
{
    Animation a;
    a.setProperty("name", std::string("walk"));
    a.setProperty("isLooped", true);
    a.setProperty("frameCount", 100);

    std::cout << "Name = "  << a.getProperty<std::string>("name") << std::endl;
    std::cout << "isLooped = "  << a.getProperty<bool>("isLooped") << std::endl;
    std::cout << "frameCount = " << a.getProperty<int>("frameCount") << std::endl;
}
Pretty neat! This will allow me to serialize to JSON /deserialize from JSON without any effort. One more thing I need to add is support for get/set member functions, but that's pretty easy to do, I just wanted to keep the code which I show brief.

Here's the source code:
http://pastebin.com/54ATGH9X
There's almost no error checking to keep the example brief.
Any suggestions to improve this are welcome! Maybe there's a better way do to it than to use dynamic_cast :P
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 15, 2015, 08:58:19 am
The "problem" here is that each instance of the class will register and store the (same) meta-properties, but properties should be attached to the class, not to its instances. Moreover, I think inheritance is too strong: almost every instance of your engine will be a meta-object, whereas they should have one (shared by all instances).

So I would rather do something along the lines of:

MetaObject meta("Animation");
meta.addProperty("name", &Animation::name); // or get/set functions
...
xxx.registerMetaObject<Animation>(meta);

auto meta = xxx.findMetaObject(a);
meta.setProperty(a, ...);
meta.getProperty(a, ...);

That's just for the idea. You can add a lot of syntactic sugar on top of that, and you can also find a smarter way of managing registration and ownership of meta-objects.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 15, 2015, 09:27:06 am
I agree with all your points, Laurent. Version 2.0 coming soon! :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 15, 2015, 09:43:38 am
Okay, it was a bit harder to implement, but it's so much cooler!
http://pastebin.com/SgAr78X3

it works like this:
class Animation
{
public:
    static void registerClass(MetaObject<Animation>& metaA)
    {
        metaA.addProperty("name", &Animation::name);
        metaA.addProperty("isLooped", &Animation::isLooped);
        metaA.addProperty("frameCount", &Animation::frameCount);
    }
   
private:
    std::string name;
    bool isLooped;
    int frameCount;
    FloatRect frame;
};

int main()
{
    MetaObject<Animation> metaA;
    Animation::registerClass(metaA);

    Animation a;
    metaA.setProperty(a, "name", std::string("walk"));
    metaA.setProperty(a, "isLooped", false);
    metaA.setProperty(a, "frameCount", 10);

    std::cout << "Name = " << metaA.getProperty<std::string>(a, "name") << std::endl;
    std::cout << "isLooped = " << metaA.getProperty<bool>(a, "isLooped") << std::endl;
    std::cout << "frameCount = " << metaA.getProperty<int>(a, "frameCount") << std::endl;
}
Of course, I'll need to have some MetaManager which will allow me to get Meta<Class> objects like this:
auto& meta = metaManager.get<Animation>();
I'll implement it soon.
Is it better now, Laurent? :D

P.S. a small improvement:
template <typename Class>
MetaObject::MetaObject()
{
     Class::registerClass(*this);
}

So now creating MetaObject<Animation> will automatically call Animation::registerClass
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 15, 2015, 09:50:42 am
Yes, much better, but let's see once you've completed the implementation ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 15, 2015, 09:53:59 am
Yes, much better, but let's see once you've completed the implementation ;)
Nice. :)
I guess I'll just make std::unordered_map<std::type_index, std::unique_ptr<IMetaObject>> metaObjects and then I'll use dynamic_cast just as I did with properties. But yeah, I'll post the source code once this is implemented :D

... or maybe I can should just store static MetaObject<SomeClass> meta inside SomeClass? No need for MetaManager then. And then I'll just do this:
Animation::meta.setProperty(a, ...);

Update: ...and done
Animation a;
auto& metaA = Animation::meta;
metaA.setProperty(a, "name", std::string("walk"));
metaA.setProperty(a, "isLooped", false);
metaA.setProperty(a, "frameCount", 10);

std::cout << "Name = " << metaA.getProperty<std::string>(a, "name") << std::endl;
std::cout << "isLooped = " << metaA.getProperty<bool>(a, "isLooped") << std::endl;
std::cout << "frameCount = " << metaA.getProperty<int>(a, "frameCount") << std::endl;

And now I'll add JSON serialization/deserialization. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 15, 2015, 10:23:51 am
I don't like this approach because:
- it is intrusive
- you can't control the lifetime of meta-objects, they all live in the global scope
- there's still a lof of static types involved

... however, it's good because you kept it simple and it really sticks to your needs. So I'd say leave it as it is, unless you think that one of the points above may be a problem in the future.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 15, 2015, 10:34:16 am
Alright. :)
I think that meta-objects don't need to have their lifetime, because information about the class is compile-time (if only we had better constexpr, I'd like to generate all this stuff at compile time, hehe). So it's fine unless I would want to add/remove meta objects in runtime, but I don't see why I would need that. (or if one meta-object would depend on the other, but I think this will be pretty bad).
Global scope is not a problem too, because &SomeClass::SomeVar is global too (though it can be private, but SomeClass::meta can too) ;)

So yeah, I'll see if there are some problems with this approach.
I just don't want to search for meta-object in the map every time I need to access meta-info which is almost here, if you have SomeClass instance. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 16, 2015, 10:45:51 pm
Okay, I'm almost done with this meta-system. I decided to go with the static approach (it's even more static that I originally thought to make!)
Animation class:
class Animation
{
public:
    // main stuff here
    int getFrameCount() const;
    void setFrameCount(const int& fc);
    // meta
    static void registerClass();
private:
    std::string name;
    bool isLooped;
    int frameCount;
    FloatRect frame;
};
As you can see, no static MetaObject involved.

First of all, let's look at what I can do now:
Let's look at the code:
// need to call this before using Meta<Animation>
Meta<Animation>::init();

// let's create a simple animation
Animation a;

// and set some properties using meta stuff
Meta<Animation>::setProperty(a, "name", std::string("walk"));
Meta<Animation>::setProperty(a, "isLooped", false);
Meta<Animation>::setProperty(a, "frameCount", 10);
Meta<Animation>::setProperty(a, "frame", FloatRect(10, 20, 32, 32));

// let's serialize it to JSON!
Json::Value root = Meta<Animation>::serialize(a);

// now we can save it to file, but we'll input it to console
std::cout << "Animation a in JSON:" << std::endl;
std::cout << root << std::endl;

Animation b;
Meta<Animation>::deserialize(b, root); // get info from JSON

std::cout << "____________________" << std::endl;
std::cout << "Let's look at Animation b now:" << std::endl;
std::cout << "Name = " << Meta<Animation>::getProperty<std::string>(b, "name") << std::endl;
std::cout << "isLooped = " << Meta<Animation>::getProperty<bool>(b, "isLooped") << std::endl;
std::cout << "frameCount = " << Meta<Animation>::getProperty<int>(b, "frameCount") << std::endl;
std::cout << "frame = " << Meta<Animation>::getProperty<FloatRect>(b, "frame") << std::endl;

Output:
(http://i.imgur.com/n5fgMew.png)

Cool!
So, Meta<Animation> (it's Meta now instead of MetaObject) stores a static map of properties. I thought that classes won't need to have different meta presentations, so now I can just use Meta<Animation> to do all the stuff!

Let's look how I can add properties:
void Animation::registerClass()
{
    Meta<Animation>::addProperty("name", &Animation::name);
    Meta<Animation>::addProperty("isLooped", &Animation::isLooped);
    Meta<Animation>::addProperty("frameCount", &Animation::frameCount,
        &Animation::getFrameCount, &Animation::setFrameCount);
    Meta<Animation>::addProperty("frame", &Animation::frame, &serializeRect, &deserializeRect);
}
So, I can set custom getters and setters which will be called each time getProperty or setProperty are called for the property who set them.
I can also add serialization/deserialization which allow me to convert from Json::Value to T and from T to Json::Value.
I don't need these functions for int, float, bool, etc., because I can just do this (jsoncpp provides this functions):
int i = intValue.asInt();
bool b = boolValue.asBool();
... // etc
But I can't convert from T to Json::Value if T is custom class.
So I can provide functions like this which allow me to do serialization/deserialization for custom classes:
Json::Value serializeRect(const FloatRect& rect)
{
    Json::Value v;
    v[0] = rect.x;
    v[1] = rect.y;
    v[2] = rect.w;
    v[3] = rect.h;
    return v;
}

void deserializeRect(FloatRect& rect, const Json::Value& value)
{
    rect.x = value[0].asFloat();
    rect.y = value[1].asFloat();
    rect.w = value[2].asFloat();
    rect.h = value[3].asFloat();
}

So, this allows me to do some great stuff, for example I can save and load components from JSON files without writing additional code for serialization/deserializaition! I can also use all this info about objects to display their properties on the screen while the game is running. How cool is that?

Ask me any questions if you're interested in knowing some other details. I won't post code until it becomes better, it has grown a lot in size, so I have to make a lot of work documenting and cleaning up stuff.
Title: Re:creation - a top down action adventure about undeads
Post by: Jabberwocky on December 17, 2015, 12:02:34 am
No doubt, decent tools can make or break a game, especially content heavy games like an RPG or action adventure.  I've enjoyed watching you hammer out your approach with the editor, Elias.  And the JSON <-> C++ serialization.

One thought - you may also want to be thinking about saving and loading functionality while you're at it.  Like, the "save game" and "load game" buttons.  It's very much the same kind of serialization/deserialization type of problem.  I'm personally a big fan of having a human-readable save file format (like XML or JSON), as this can help immensely during development and debugging.  As opposed to a binary format.

So, maybe you can use the C++ <-> JSON serialization for saving and loading the game, just like you do in your editor for authoring animations and other game content.
Title: Re:creation - a top down action adventure about undeads
Post by: dabbertorres on December 17, 2015, 04:29:30 am
^

Can even take it a step further and make a "game save editor" of sorts. That can help with debugging as well. Set the game to be at a certain level of completion or whatnot, and make sure the game loads and starts/runs fine, etc.

(Though, depending on game format, may be as simple as a bunch of checkboxes!)
Title: Re:creation - a top down action adventure about undeads
Post by: dwarfman78 on December 17, 2015, 07:05:26 am
your test is invalid because you print a's properties instead of b's.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 17, 2015, 07:43:21 am
Jabberwocky, dabbertorres, I'll think about it. There's just so many stuff I don't have to save to the save file, for example, component's default values which are stored in entity definition files. I only have to save stuff which is unique for entity: it's position, current state, HP, inventory, etc.
But, there's sometimes no need to save  HP or current position which most games don't do and they're fine. So, as for now, I'll be writing game saving/loading code by hand by thinking carefully about what I have to save and what I don't.

dwarfman78, ha-ha, right, I've changed the code.
I just checked b's values in debugger and thought:"Alright, this works, output is expected, let's post! :D"
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 17, 2015, 08:35:01 am
Just two comments about your implementation:

- Why do you need to pass the direct pointer to member when you also pass the getter and setter functions, when you register the property?

- Why do you pass the serialization functions explicitely when you register a property? You should rather use a single known function (like jsonSerialize / jsonDeserialize) for which you add overloads when you need to handle new types. The compiler will then choose the right overload for you. This is similar to what standard streams do with operators << and >>.

And if you're tired of writing all this stuff, you can add a wrapper that makes it a little funnier to write:
auto meta = getMeta(a); // returns a MetaWrapper<T>, which stores the T instance and invokes Meta<T>:: functions
meta.set("frameCount", 10);
auto count = meta.get<int>("frameCount");

And... this is also mostly for fun, but if you want to make the whole system safer, and disallow calling Meta<T>::addProperty from anywhere, you can do something like this:
void Animation::registerClass(MetaBuilder<Animation>& builder)
{
    builder.add("name", &Animation::name);
    builder.add("isLooped", &Animation::isLooped);
    ...
}

By restricting construction of MetaBuilder<T> and access to Meta<T>::addProperty, you can make sure by design that:
- Meta<T> can only be populated in T::registerClass, so the whole initialization of meta stuff is kept under control
- the rest of the code only has access to Meta<T>::get/set
- ... and if you use the MetaWrapper, you don't even need a visible Meta<T> class anymore, you can keep everything hidden and only expose construction with MetaBuilder and access with MetaWrapper.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 17, 2015, 01:14:14 pm
Thanks, Laurent, there are fantastic suggestions! I've implemented everything that you've proposed.
Once I finish cleaning everything up, I'll create a github repository, so maybe someone will help improve it even further :D

Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 17, 2015, 02:54:21 pm
I've tried out more complex classes and here are the results.
Animation class stays the same, let's add GraphicsComponent class:
class GraphicsComponent {
public:
    GraphicsComponent();

    Json::Value serializeAnimations() const;
    void deserializeAnimations(const Json::Value& root);

    static void registerClass(MetaBuilder<GraphicsComponent>& builder);
private:
    std::string filename;
    std::map<std::string, Animation> animations;
    Animation specialAnimation;
};

Here's how register function looks:
void GraphicsComponent::registerClass(MetaBuilder<GraphicsComponent>& builder)
{
    builder.add("filename", &GraphicsComponent::filename);

    builder.add<decltype(animations)>("animations");

    auto& animationsProperty = builder.get<decltype(animations)>("animations");
    animationsProperty.setMemberSerializer(&GraphicsComponent::serializeAnimations);
    animationsProperty.setMemberDeserializer(&GraphicsComponent::deserializeAnimations);

    builder.add("specialAnimation", &GraphicsComponent::specialAnimation);
}

Here's how JSON file for this class looks (all I have to do to get this is call Meta<GraphicsComponent>::serialize) :
{
        "animations" :
        [
                {
                        "frame" : [ 0, 32, 32, 32 ],
                        "frameCount" : 30,
                        "isLooped" : true,
                        "name" : "idle"
                },
        ...
        ],
        "filename" : "res/hero.png",
        "specialAnimation" :
        {
                "frame" : [ 0, 64, 32, 32 ],
                "frameCount" : 20,
                "isLooped" : false,
                "name" : "megaAttack"
        }
}

Serializing/deserializing map of animations is tricky, because it's array in JSON and we want to use animation names as map keys in C++. So, let's add functions which will be called each time Meta<GraphicsComponent> tries to serialize/deserialize animations map:
Json::Value GraphicsComponent::serializeAnimations() const
{
    Json::Value animationsArray;
    for (const auto& animationPair : animations) {
        auto& animation = animationPair.second;
        animationsArray.append(Meta<Animation>::serialize(animation));
    }
    return animationsArray;
}

void GraphicsComponent::deserializeAnimations(const Json::Value& root)
{
    for (int i = 0; i < root.size(); ++i) {
        Animation a;
        Meta<Animation>::deserialize(a, root[i]);
        animations[a.getName()] = a;
    }
}

Great! What about Animation specialAnimation? If no functions are provided, Meta<T>::serialize / Meta<T>::deserialize get called. If the meta class was not explicitly created for the T (using T::registerClass function) , it will have no properties, so the first function will return Json::nullValue and the second function will return T().

As for MetaWrapper object, here's how useful it is:
auto metaGc = Meta<GraphicsComponent>::getMeta(gc);
metaGc.set("filename", std::string("res/test.png"));
int frameCount = metaGc.get<int>("frameCount");
The code is much cleaner and easier to read!

Oh, and as Laurent suggested, doing this is possible:
builder.add<int>("frameCount");
auto& frameCountProperty = builder.get<int>("frameCount");
frameCountProperty.setGetter(&Animation::getFrameCount);
frameCountProperty.setSetter(&Animation::setFrameCount);
As you can see, there's no need to provide &Animation::frameCount for this property. What happens if I don't provide setter and try to call set for this property? (Or try to get some property without getter?) Assertion tell me about it ("Forgot to add setter/getter!"), and everything is alright :D (if I don't use assertions, C++ silently writes to nullptr and the stack gets corrupted!)

And now I'm getting back to work on Animation tool... which will later become Entity Creation Tool!
But I'll have to rewrite a lot of stuff to store all component data in JSON instead, so this will take a while. I'll try not to stop working on the game and will draw art and think about levels/mechanics in parallel.
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 17, 2015, 06:21:30 pm
Quote
auto metaGc = Meta<GraphicsComponent>::getMeta(gc);
The purpose of using a function was mainly to benefit from type deduction, so that you never have to write any template parameter. Just make getMeta a free function, and you can remove the "Meta<GraphicsComponent>::" part.

Quote
Oh, and as Laurent suggested, doing this is possible
I don't remember suggesting that ;D
What I previously said is that:
- there were useless arguments in your calls (pointer to member in addition to getter/setter)
- using an overload of a single function for serialize/deserialize would be better than explicitly passing the functions when you register the property
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 17, 2015, 08:29:23 pm
The purpose of using a function was mainly to benefit from type deduction, so that you never have to write any template parameter. Just make getMeta a free function, and you can remove the "Meta<GraphicsComponent>::" part.
Ohhh, yeah, I'll make that :D

Quote
Oh, and as Laurent suggested, doing this is possible
I don't remember suggesting that ;D
What I previously said is that:
- there were useless arguments in your calls (pointer to member in addition to getter/setter)
Well, as I've shown you can either pass just pointer to member ot getter + setter. How is this useless? You either access the member directly or use getter + setter to do this.

- using an overload of a single function for serialize/deserialize would be better than explicitly passing the functions when you register the property
Can you please explain more? I have no idea how to do this. :D

And... I've encountered the first huge problem.
What I need is to have Property::serialize function which does this:
1) Calls serializer member function if it exists
2) If it doesn't exist:
     a) Returns Json::Value(T&) for these types: bool, string, float, int.
     b) Tries to call Meta<T>::serialize for other types
This is easily done with template specializations...
3) If everything else fails, returns empty Json::Value() (null value)

Here's the problem: suppose I try to serialize size_t. Template specialization for size_t doesn't exist, so Meta<size_t>::serialize gets called. But this will fail to sompile, because size_t doesn't have registerClass function which is required for all types which use Meta<T>.
Even if I call it only with "good" types, this introduces another problem: circular dependencies. Meta<T>::serialize calls Property::serialize for each property of T, some of which may call Meta<U>::serialize, etc.
This introduces circular header dependencies and other headaches... So, I feel like I'm doing this wrong. Any suggestions? :D
I feel there's much easier solution...
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 17, 2015, 09:00:43 pm
Quote
Well, as I've shown you can either pass just pointer to member ot getter + setter.
I was referring to this:
Meta<Animation>::addProperty("frameCount", &Animation::frameCount,
        &Animation::getFrameCount, &Animation::setFrameCount);
If you have a getter and a setter you obviously don't need direct access to the member ;)

Quote
You either access the member directly or use getter + setter to do this.
If now it's one or the other, it's fine.

By the way, what do you gain by allowing to set the meta-property's properties (;D) after constructing it, rather than passing all you need directly to the add function?

Quote
Can you please explain more? I have no idea how to do this.
Sure.
Json::Value json::serialize(int x) {...}
void json::deserialize(const Json::Value& root, int& x) {...}

Json::Value json::serialize(std::string s) {...}
void json::deserialize(const Json::Value& root, std::string& s) {...}

Json::Value json::serialize(sf::FloatRect rect) {...}
void json::deserialize(const Json::Value& root, sf::FloatRect& rect) {...}

Json::Value json::serialize(sf::IntRect rect) {...}
void json::deserialize(const Json::Value& root, sf::IntRect& rect) {...}

...

auto value = json::serialize(v);

If an overload exists for the type of v, the compiler will automatically choose it. If it doesn't, the compiler will complain. The point is, the serialization code remains generic, it only has to call json::serialize and the compiler does the rest, as long as a compatible overload exists.

Quote
And... I've encountered the first huge problem.
What I explained may solve it as well. If not, I'll try to come up with a proper solution later ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 17, 2015, 10:48:25 pm
I was referring to this:
Meta<Animation>::addProperty("frameCount", &Animation::frameCount,
        &Animation::getFrameCount, &Animation::setFrameCount);
If you have a getter and a setter you obviously don't need direct access to the member ;)
Look at the code I've posted previously:
builder.add<int>("frameCount");
auto& frameCountProperty = builder.get<int>("frameCount");
frameCountProperty.setGetter(&Animation::getFrameCount);
frameCountProperty.setSetter(&Animation::setFrameCount);
Just pointers to get/set functions, no direct access! :D

By the way, what do you gain by allowing to set the meta-property's properties (;D) after constructing it, rather than passing all you need directly to the add function?
That's because I was tired of having lots of constructor overloads
1) No pointers passed
2) Just pointer to member
3) Getter + Setter
4) Getter + Setter + Serializer/Deserializer
5) Pointer to member + Serializer / Deserializer
Setting particular functions makes the code easier to read and write, imo. But maybe I should come back to having 3 (or 4?) overloads, I don't know :D

Sure.
Json::Value json::serialize(int x) {...}
void json::deserialize(const Json::Value& root, int& x) {...}

Json::Value json::serialize(std::string s) {...}
void json::deserialize(const Json::Value& root, std::string& s) {...}

Json::Value json::serialize(sf::FloatRect rect) {...}
void json::deserialize(const Json::Value& root, sf::FloatRect& rect) {...}

Json::Value json::serialize(sf::IntRect rect) {...}
void json::deserialize(const Json::Value& root, sf::IntRect& rect) {...}

...

auto value = json::serialize(v);
Yeah, this is something I previously did, though I tried to make the function generic and failed! :D
You see, I just wanted to have function like this:
template <typename T>
Json::Value cast(const T& obj) {
     return Meta<T>::serialize(obj);
}
and having a bunch of template specializations for other specializations. But this introduces cyclic dependency between Meta -> Property -> cast -> Meta which I couldn't resolve. Once again, the cyclic dependency is caused by these things I have to do:
Meta<T>::serialize calls Property<U>::serialize for some property with type U, which then either calls template specialization (for simple types) or Meta<U>::serialize and so on. And I can't even forward declare all this stuff :D

This is what made it possible to simply create JSON in the GraphicsAnimation class. Meta<GraphicsAnimation> iterated over all the properties, it did this:
1) Called template specialization for std::string
2) Called serialization function for std::map<...> which I've provided
3) Called template function Json::cast<Animation> which then called Meta<Animation>::serialize

This worked in MSVC, but GCC fails to compile this code because of the cycle. So, this is my problem now. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 17, 2015, 11:06:20 pm
Would you mind sharing your code for Meta and Property, so that I can have a look?
Title: Re:creation - a top down action adventure about undeads
Post by: Jabberwocky on December 17, 2015, 11:12:58 pm
If an overload exists for the type of v, the compiler will automatically choose it. If it doesn't, the compiler will complain. The point is, the serialization code remains generic, it only has to call json::serialize and the compiler does the rest, as long as a compatible overload exists.

This is pretty close to how I've implemented XML serialization in my game.

You've given a lot of fantastic advice in this thread Laurent, and it's cool seeing the SFML devs so involved in these devlog threads.

Jabberwocky, dabbertorres, I'll think about it. There's just so many stuff I don't have to save to the save file, for example, component's default values which are stored in entity definition files. I only have to save stuff which is unique for entity: it's position, current state, HP, inventory, etc.
But, there's sometimes no need to save  HP or current position which most games don't do and they're fine. So, as for now, I'll be writing game saving/loading code by hand by thinking carefully about what I have to save and what I don't.

Absolutely.  You don't save the same data to a savegame file as you would to an entity definition file.  It should only be "dynamic state" stuff, like position and inventory, as you mention.

What I am saying is that in both cases (editing, saving) you need to serialize and deserialize data to a file.  And that it's useful to be able to open and read your savegame files (in a non-binary format).  So JSON may be an ideal format for both.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 17, 2015, 11:23:26 pm
Would you mind sharing your code for Meta and Property, so that I can have a look?
Sure, here:
https://bitbucket.org/edaler/meta-stuff/src
Check out include/JsonCast.h. It includes Meta.h which causes the problem according to GCC. It compiles with MSVC, huh. Also, Property.inl and Meta.inl have some very important code
And yeah, I'm sorry that some code may be bad, this is very WIP, so I still have some stuff to improve. ;D

You've given a lot of fantastic advice in this thread Laurent, and it's cool seeing the SFML devs so involved in these devlog threads.
Ha-ha, yeah, I'm very glad that so many awesome people read my dev logs and help me make the game! :D

Absolutely.  You don't save the same data to a savegame file as you would to an entity definition file.  It should only be "dynamic state" stuff, like position and inventory, as you mention.

What I am saying is that in both cases (editing, saving) you need to serialize and deserialize data to a file.  And that it's useful to be able to open and read your savegame files (in a non-binary format).  So JSON may be an ideal format for both.
Yup, it's quite good, working with it was a pleasure. Easy to read, easy to make, easy to parse. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 18, 2015, 10:07:48 pm
Okay, aside from the circular dependencies problems, I think about easier ways to solve the problem.
So, I think it would be good to make Json::toValue(T& obj) return null value for ALL non-standard types. What about the classes which can be serialized? Well, I think that it would be good for classes to provide serialization function to all members with non-standard types which have to be serialized. So, the Meta<T>::serialize will work like this:
1) Call toValue(T& obj) for all properties which have simple types (int, bool, string, etc.)
2) Ignore other properties and just call T::serialize

So, for GraphicsComponent this function will look like this:
void GraphicsComponent::serialize(Json::Value& root)
{
    root["specialAnimation"] = Meta<Animation>::serialize(specialAnimation);
    ... // serialize other stuff
}
So, it would just "append" all non-standard properties to existing Json::Value and the problem is solved.
The stuff I wanted to make previously is much more compilcated and isn't necessary as you can see (though it has some downsides, but they are okay!)

Update: so, I've made the changes, cast<T> function in Json::cast may seem silly, but this is one of the ways to be sure not change properties with non-default types. If I just returned T() for all non-standard classes, there's no way I could tell that this is T() for non-default value or some standard-type property is really T() (0, 0.0f, "", etc.)
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on December 21, 2015, 05:35:26 am
This thread kept popping up non stop last week in recent posts so I looked through the screens and I noticed in one of the gif screens you use a small console/prompt in your game to enter Lua code.
I don't know how much code you enter by hand into game itself vs. code in files but I decided to shameless promote myself a little anyway. :P
I happen to have a Lua SFML console/terminal lib for 5.1 and 5.2 (I'd not mind adding 5.3 if that's what you're using now, but it came after you started and there is little benefit in upgrading 5.1 to 5.2 to 5.3 for gamedev purposes so I'm guessing it's not).
It's a Slavic product too. ;D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 25, 2015, 08:53:50 am
I don't know how much code you enter by hand into game itself vs. code in files
Not much, it's mostly for testing purposes. The code is not saved, this console just calls some C++ functions if I need to call them.

I happen to have a Lua SFML console/terminal lib for 5.1 and 5.2 (I'd not mind adding 5.3 if that's what you're using now, but it came after you started and there is little benefit in upgrading 5.1 to 5.2 to 5.3 for gamedev purposes so I'm guessing it's not).
How does it work? Does it integrate into C++ program and then calls Lua/SFML bindings?

Progress update
I've passed lots of exams in my university, so the week was very busy and I didn't have any time to work on the game! But I'll be mostly free for the next month, so I'll work on the game a lot.
I'll write a big blog post about the stuff I've done this year later. :)
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on December 25, 2015, 10:48:21 am
Quote
How does it work? Does it integrate into C++ program and then calls Lua/SFML bindings?
It's a Lua console so it's like the 'lua' command line program except in your game.
You type Lua code into it and it'll evaluate it for you (plus extras like completion, history, etc.).
Anything you exposed to Lua is available, you're basically doing luaL_dostring at runtime in a super fancy way.

It's a C++ lib which depends only on Lua, C++98 and SFML and is meant to be easy to use:
1. You create the view, input and model class and give input the model ptr (and set font and history if you don't want to use default ones from default paths) and give L pointer to the model.
2. You call  input.handleEvent(eve) to filter your events through the console in your pollEvent loop.
3. You call view.geoRebuild(&model) and then draw the view (it's SFML drawable) when you want to render it.

There is an example here of minimal program that has just a console in it, with default everything: https://github.com/FRex/LuaConsole/blob/master/examples/main.cpp
It shouldn't take more than 30 minutes to get into an app and I tried to make it well configurable and so on but with sane defaults.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 25, 2015, 10:00:21 pm
Heh, this is basically what I do with my console. Everything I write after "lua" is passed to luaL_dostring.
But I have other functions as well. Like if I write "open res/levels/someLevel.txt", it opens level, if I write "info 45", it prints info about entity with id=45, etc.
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on December 25, 2015, 11:50:54 pm
I do just Lua code, so everything I want to use there must be exposed to Lua for my apps, but then I get history, completion, incomplete chunks, colors, ect. and I like working with Lua so it's worth it to me. I was thinking about a simplified bash-like input without braces and commas or about adding moonscript or typedscript input (or even some user provided input handler via callback instead of making all go through Lua) but didn't try to do any of that yet.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 27, 2015, 04:27:41 pm
I do just Lua code, so everything I want to use there must be exposed to Lua for my apps, but then I get history, completion, incomplete chunks, colors, ect. and I like working with Lua so it's worth it to me. I was thinking about a simplified bash-like input without braces and commas or about adding moonscript or typedscript input (or even some user provided input handler via callback instead of making all go through Lua) but didn't try to do any of that yet.
That's pretty cool. I'll check out your project. :D

Progress update
Okay, I'm almost done with Animation Tool. Here's how it looks now:
(http://i.imgur.com/0iPWhEs.gif)
This gif actually uses Meta system I've been working on for so long. Previous gifs just used JSON and reloaded animation when something changed. This one changes C++ value, so when I change "frameTime", corresponding C++ variable changes!

Stuff I've also added:
Stuff I need to add:
Later I'll use this project to make entity editor. It will work by the same principle. What's cool is that most of the members in component classes are of these types: bool, int, float, size_t, std::string, sf::Vector2i, sf::Vector2f, sf::IntRect, sf::FloatRect which are supported by my meta system very well.

One current problem I have which someone may help me solve is this. Suppose I want to do this:
std::cout << meta.get("someProperty");
This isn't going to work, because I need to do this:
std::cout << meta.get<int>("someProperty");  // if someProperty is int
Why do I need to specify the type? I need this type to convert from IProperty<Class> to Property<T, Class> inside get function!  (where T is type of property, Class is class to which this property belongs)

Property<T, Class>  has T Property<T, Class>::get() function which returns value of the property, but IProperty can't have it as virtual, because it's a base class which I use to store all properties in one map.
When I store Property<T, Class> as IProperty<Class> pointer I lose type of the property. I've solved this by storing type_index of T inside IProperty, so I can later get it to identify which type Property has.

So I can do this:
if(meta.getPropertyType("someProperty") == typeid(int)) {
    std::cout << meta.get<int>("someProperty");
} else if(meta.getPropertyType("someProperty") == typeid(double)) {
    std::cout << meta.get<double>("someProperty");
} ...
but those if/else things are pretty awful to write! (but they work, he-he)
Are there any other solutions?
What I want to do is do is call template function by getting the type out of type_index. Any way to do it without if/else?
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 27, 2015, 07:17:11 pm
virtual std::ostream& IProperty::print(std::ostream& stream) = 0;

Again, you can then add some syntactic suger on top of that to make it look funnier.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 27, 2015, 09:21:34 pm
virtual std::ostream& IProperty::print(std::ostream& stream) = 0;

Again, you can then add some syntactic suger on top of that to make it look funnier.
At first I wanted to say "I've oversimplified the problem, in MY case I can't use virtual functions!" but then I thought "oh wait... what if...?" and turns out I can use them! :D
So, I've just replaced lots of awful code with one line(!) which looks like this:
meta.setData(name, value); // where value is QVariant.
This call IProperty<Class>::setData which calls Property<T, Class>::setData and there I have something like this:
T v;
castFromQVariant<T>(v, value);
set(obj, v);
Virtual function saves the day!
(http://i.imgur.com/wRbTMXi.png)

P.S. and I just want to show this gif. I've realized how many cool animations I have drawn and it made me happy :D
(http://i.imgur.com/UPw7S6i.gif)
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 27, 2015, 09:45:09 pm
Nice! And this looks like a really versatile tool to tweak the animations :)

The presence of explicit case differentiations based on any kind of type identifier (dynamic_cast, typeid, a type enum, ...) is usually a strong indicator of bad abstraction. Very often, a form of polymorphism can help in these cases. See also my reply here (http://en.sfml-dev.org/forums/index.php?topic=7023.msg69437#msg69437).
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 27, 2015, 10:23:53 pm
Nice! And this looks like a really versatile tool to tweak the animations :)
Thanks! And it'll be a lot more versatile once I move all entity data to JSON and then I'll be able to do same stuff with most entity parameters.

The presence of explicit case differentiations based on any kind of type identifier (dynamic_cast, typeid, a type enum, ...) is usually a strong indicator of bad abstraction. Very often, a form of polymorphism can help in these cases. See also my reply here (http://en.sfml-dev.org/forums/index.php?topic=7023.msg69437#msg69437).
Wow, this looks really interesting, I'll think about it. The only place I have dynamic_cast now is get/set functions for properties. So, if I call this:
auto value = meta.get<int>("someIntProperty");
IProperty<Class> is cast to Property<T, Class> inside the get function, so I can call
T Property<T, Class>::get()
{
    ...
}

this function cannot be virtual, because of different return types for each property type.
But maybe I can do some trickery with templates and virtual functions which will allow me to get needed type from IProperty*... :D
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 27, 2015, 11:01:56 pm
Do you need dynamic_cast for error checking? Otherwise, you can as well downcast with static_cast.

Or even better, combine the advantages of both. I've written a downcast function template (http://www.bromeon.ch/libraries/aurora/v1.0/doc/_downcast_8hpp.html) that checks the type in Debug mode, but is fast in Release mode. It's a drop-in replacement for static_cast:
Base& base = ...;
auto& derived = aurora::downcast<Derived&>(base);
auto* derived = aurora::downcast<Derived*>(&base);

By the way, the Aurora library is header-only and very lightweight, so it can be used very easily within any project (without configuration, building or linking).
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 28, 2015, 09:35:34 am
Oh... if you use QVariant then it's a totally different thing. It does all the crappy things for you (type abstraction, checking, conversion, JSON serialization, ...). But I thought that you wanted to stay away from Qt specific stuff for this part of the code.

So now, may I ask why you still need this IProperty class with typed derived classes?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 28, 2015, 09:40:11 am
Do you need dynamic_cast for error checking? Otherwise, you can as well downcast with static_cast.
Yeah, I think that dynamic_cast is not really necessary, but I think that assert which checks that cast succeeded will be nice. Are there any speed diferences between static_cast and dynamic_cast?

Or even better, combine the advantages of both. I've written a downcast function template (http://www.bromeon.ch/libraries/aurora/v1.0/doc/_downcast_8hpp.html) that checks the type in Debug mode, but is fast in Release mode. It's a drop-in replacement for static_cast:
Base& base = ...;
auto& derived = aurora::downcast<Derived&>(base);
auto* derived = aurora::downcast<Derived*>(&base);
Good idea.

By the way, the Aurora library is header-only and very lightweight, so it can be used very easily within any project (without configuration, building or linking).
I think I'll implement my template stuff first (this is so useful to learn template trickery!) and then I'll try to use your library to gain some perfomance, because I think that your code may be better :D
Title: Re:creation - a top down action adventure about undeads
Post by: Nexus on December 28, 2015, 11:04:03 am
Yeah, I think that dynamic_cast is not really necessary, but I think that assert which checks that cast succeeded will be nice. Are there any speed diferences between static_cast and dynamic_cast?
Yes, of course. As implied by the name, static_cast is resolved at compile time (the compiler computes the new start address of the class, which is more or less an addition at runtime), while dynamic_cast is a runtime operation that looks up the RTTI of the involved classes and checks their inheritance relation. But in any case, performance should not be the decisive factor here.

You can only use static_cast when you're sure about the conversion, and it's more limited (regarding cross-casts or casts through virtual inheritance). But the use of dynamic_cast should be questioned; often, a design with virtual functions can replace it.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 28, 2015, 11:51:06 am
Yeah, I think that dynamic_cast is not really necessary, but I think that assert which checks that cast succeeded will be nice. Are there any speed diferences between static_cast and dynamic_cast?
Yes, of course. As implied by the name, static_cast is resolved at compile time (the compiler computes the new start address of the class, which is more or less an addition at runtime), while dynamic_cast is a runtime operation that looks up the RTTI of the involved classes and checks their inheritance relation. But in any case, performance should not be the decisive factor here.
Good to know, thanks.

You can only use static_cast when you're sure about the conversion, and it's more limited (regarding cross-casts or casts through virtual inheritance).
After some thinking, I think that I need to do dynamic_cast, because I can't be sure about some stuff. Like if I have some property Property<T, Class> which is stored as IProperty<Class>* and then if I call
int i = meta.get<int>("someProperty")
I assume that T is int, so this needs an assert.

But the use of dynamic_cast should be questioned; often, a design with virtual functions can replace it.
Yeah, I'll try to think about improving my design, but right now it works pretty okay :D

And here's another screenshot of the animation tool. Almost done!
(http://i.imgur.com/zil8Lsk.png)
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 28, 2015, 02:40:25 pm
I posted while you were replying to Nexus, so you may have missed it:

Quote
Oh... if you use QVariant then it's a totally different thing. It does all the crappy things for you (type abstraction, checking, conversion, JSON serialization, ...). But I thought that you wanted to stay away from Qt specific stuff for this part of the code.

So now, may I ask why you still need this IProperty class with typed derived classes?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 28, 2015, 05:34:53 pm
I posted while you were replying to Nexus, so you may have missed it:

Quote
Oh... if you use QVariant then it's a totally different thing. It does all the crappy things for you (type abstraction, checking, conversion, JSON serialization, ...). But I thought that you wanted to stay away from Qt specific stuff for this part of the code.

So now, may I ask why you still need this IProperty class with typed derived classes?
Yeah, I've missed it, sorry. :D
So, I need to cast from QVariant to T and back to be able to edit/display properties with QTreeView. It passes QVariant to setData in my model (which is inherited from QAbstractItemModel) and then I need to cast it to the correct type and set it to property. But... I think that the QVariant passed by QTreeView can be converted to QString and then to std::string, so I can basically make this get/set functions which convert std::string to needed value. (instead of making virtual functions which operate on QVariant)
So, when I type "56" it's treated as int, when I type "32, 32" it's treated as sf::Vector2i, etc.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 29, 2015, 10:54:31 pm
So, implementing toString and getValueFromString methods totally solved the problem with having QVariant near animation classes. QTreeView uses QString for data manipulation, so when you input something, you get QVariant which contains QString with stuff you just wrote. This is converted to std::string and passed to virtual function in IProperty<Class> which then calls function in Property<T, Class> which then converts from std::string to T.

One interesting problem to solve was checking the input data. That's because if you do this:
auto i = std::stoi("bla-bla");
you get an exception. So, I created a quick function which checks if the string contains data which can be converted to following types: bool, int, float, string (he-he), etc.
And if you input wrong stuff, you get a nice error message instead of program crash. :)
(http://i.imgur.com/TTxb2Zb.png)

I've also worked on the game itself (finally!). I connected meta stuff to main project and quickly thrown away old JSON loading code in favor of meta-deserialization! It worked pretty well. I'm now very glad that I did all that stuff instead of sticking to the easiest solution.
Now only animations use JSON but I'll start to convert most of the component data from Lua to JSON. What's interesting is that I can do it gradually (converting component data to JSON one by one), so I won't stop working on other stuff in meanwhile!

I've also came up with a bunch of cool ideas which will be easy to implement (mostly dialogues and cutscenes) and I won't spoil anything. Oh, and I'll soon start working on cutscene system, so expect some silly test cutscenes soon.

And by the way, I have question about reusing your own code in your projects. How do you do it?
Often I feel that I need to use LogManager, ResourceManager or Meta stuff in other quick/test projects and I end up just copying the code from main project so I don't break some stuff in it accidentally (by changing code shared among different projects). This approach is obviously not the right way to do stuff... So, what's your approach? Where do you store your code which you reuse in different projects? Do you just include them in all your projects or do you make shared libs?
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 30, 2015, 09:40:08 am
Quote
So, I created a quick function which checks if the string contains data which can be converted to following types: bool, int, float, string (he-he), etc.
I still don't get why you're writing all that stuff when QVariant can already do it.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 30, 2015, 03:08:31 pm
Quote
So, I created a quick function which checks if the string contains data which can be converted to following types: bool, int, float, string (he-he), etc.
I still don't get why you're writing all that stuff when QVariant can already do it.
That's because I have to handle types like sf::Int/FloatRect, sf::Vector2i/f, etc. (they're not stored inside QVariant! Only strings like "54, 20, 32, 32" are stored, so I need to manually convert them.)
 
And I also want to make meta stuff independent from Qt. If I use QVariant inside the Property class, I can't use this code inside my game which doesn't use Qt.
Title: Re:creation - a top down action adventure about undeads
Post by: Laurent on December 30, 2015, 06:03:33 pm
Good points ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 30, 2015, 10:06:48 pm
Nothing special, just repaired Lua callbacks and I think that this area looks neat with fog in it. :D (Though there are lots of tiles I' have to draw!)
(http://i.imgur.com/9o5dRqb.gif)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on December 31, 2015, 03:51:16 pm
I've written a big blog post about the stuff I've done this year. Lots of gifs, pictures and info. If you've followed this thread, you may have already seen this stuff, but it's always too look back and remember how much the game improved. :D
Read it here (https://eliasdaler.wordpress.com/2015/12/31/recreation-2015/)
(http://i.imgur.com/3eR8O5K.png)
Thanks again, everyone. And Happy New Year!
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 03, 2016, 10:29:50 pm
My short holiday rest is almost finished, I'll soon be resuming the development. ;D
I want to hear what you think of the progress I've made this year. (check the post above)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on January 03, 2016, 11:44:24 pm
I had a look through it and it's as I remember it: impressive!  :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 04, 2016, 09:17:15 am
I had a look through it and it's as I remember it: impressive!  :D
Thank you! :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 05, 2016, 09:23:22 am
I'm back working on the game! Right now I'm working on moving entity data to JSON from Lua, but I've done it in such way that it can be loaded from Lua and JSON at the same time, so I won't need to provide Meta stuff for each component and the game will still work, so I'll work on the other stuff in parallel.
I'll also try to measure how faster the loading from JSON would be (I hope it would be faster, ha-ha!)
JSON will look like this:
(https://i.imgur.com/opYtN6l.png)

And a strange thing happened. I randomly visited daily discussion thread on /r/gamedev and came upon this post (https://np.reddit.com/r/gamedev/comments/3zdy6p/its_the_rgamedev_daily_random_discussion_thread/cyldjg8).
My first reaction was this:"Huh, someone posted a screenshot of my game...? Cool. Oh wait..."

Compare for yourselves.
(https://i.imgur.com/TEoUKae.png)
Right top corner part is my game with some color adjusted.

Generally I'm okay with people copying stuff from other people, but it should be subtle and you should add something to the original. I'm taking huge inspiration from Zelda, yeah, but it's not that obvious.
What will I do? Nothing. I've already called out the person on twitter and reddit and they said that they'll redo the graphics (while saying it's just a "coincidence").
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on January 05, 2016, 02:26:21 pm
It's possible that it really is a co-incidence. Creative people that have never seen each others' work come up with the same thing all the time.

Still, I don't buy it.

It's a shame they didn't post their character design  ;D

However, their version doesn't stick to the pixelation very well. The flowers, for example, are obviously scaled down from wherever they stole them from  ::)

On top of everything, though, the best part is that his Reddit account has been deleted.
Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on January 05, 2016, 02:51:28 pm
For me there is too much similarity to call that coincidence. Everything except for the lamps looks almost identical.

Quote
Actually, the project is inspired by A Link to the Past and Dark Souls. Thus the Zelda vibe combined with the darker and gloomier atmosphere.
Sure... I was really hoping to see one of "his" main gameplay mechanics. Let's make an elaborated guess: Taking over dead enemies/npcs to get their abilities?

Well, like hapax said his account is deleted, so we most probably won't see anything from him anytime soon.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 05, 2016, 11:10:41 pm
He-he, thanks for support, guys. :D

Okay, soon I'll start working on cutscenes. Imagine the following cutscene

We see a person sleeping and then old warrior goes near the bed and tells him to wake up. He gets up and asks:"What happened"?
This cutscene will look something like this in the Lua script:
sleepCutscene = function()
    local warrior = getEntityByTag("OLD_WARRIOR")
    local sleepyDude = getEntityByTag("SLEEPY_DUDE")
   
    cutscene = {
        init = function()
            sleepyDude:setAnimation("sleeping")
        end,
        {
            type = "WalkTo",
            f = function()
                warrior:setDestination(getEntityPosition("POINT_NEAR_BED"))
            end
        },
        {
            type = "Dialogue",
            f = function()
                warrior:sayTalk("WAKE_UP")
            end
        },
        {
            type = "Animation",
            f = function()
                sleepyDude:setAnimation("getting_up_from_bed")
            end
        },
        {
            type = "Dialogue",
            f = function()
                sleepyDude:sayTalk("WHAT_HAPPENED")
            end
        }
        ... // etc.
    }
   
    return cutscene
end

So, when cutscene is launched, init function is called, but then things get a bit difficult.
I can't just call functions one after another, because sometimes next action must wait until the current action is finished. So, there are two things each type of actions needs to have: functions which is called in the beginning and functions which will test if the current action is finished

Let's look at the actions and their finish conditions. (These will be hardcoded in C++, because they are very common)
1) "WalkTo" - wait until npc reaches destination
2) "Dialogue" - wait until the player reads all the lines of dialogue and presses *ACTION_BUTTON*
3) "Animation" - wait until the animation is finished
Etc.

There are a lot of other common actions which I'll add as I need them. I can also add a function which will be called repeatedly for the current action, so I can specify finishing conditions in scripts.

Any thoughts? Maybe I can do this better? :D
Title: Re:creation - a top down action adventure about undeads
Post by: dabbertorres on January 06, 2016, 03:28:16 am
Some sort of event/trigger system is the most reusable method I've seen for something like this.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 06, 2016, 07:22:32 am
Some sort of event/trigger system is the most reusable method I've seen for something like this.
Yeah, previously I've used event/trigger system to do cutscenes, but then I've realized that I have to do too much stuff and want to keep everything in one place. I had to subscribe to events, create lots of callback function, create lots of triggers on the map, etc.

But maybe I can do it automatically? So, when I'll write this:
{
            type = "Animation",
            f = function()
                sleepyDude:setAnimation("getting_up_from_bed")
            end
}
This action will subscribe to AnimationFinishedEvent
And when I do this:
{
    type = "WalkTo",
    f = function()
         warrior:setDestination(getEntityPosition("POINT_NEAR_BED"))
    end
}

I'll subscribe to the CollisionEvent between warrior and POINT_NEAR_BED. Notice that the POINT_NEAR_BED acts like a trigger in this case. I can't just hardcode variables, so I have to use trigger's position as a destination. (because then I'll forget to change them when the bed is moved, for example).

Previously all that trigger stuff was very confusing, because it was all over the place and you coudn't read cutscene from start to finish. So, it would be like this:

cutscene_near_bed_trigger = {
    TriggerComponent = {
        onTrigger = function(first, second)
            if(isCutscene("cutscene1")) then
                if(second:getName() == "old_warrior) then
                    ... -- do next stuff
                end
            end
        end,
        ...
    },
    ...
}

Keep in mind that this will be in a separate file, so you'd have to look at several files to see what's going on. Pure mess! So, I kinda like what I came up with.
Title: Re:creation - a top down action adventure about undeads
Post by: Mario on January 06, 2016, 10:46:42 pm
While this sounds like a good idea, you're somehow duplicating code/data.

In your example, your action type already is "Animation". Why would you have to call "setAnimation()" in addition?

Instead, this could be 100% data driven without code:

{
    type = 'Animation',
    target = 'sleepyDude',
    animation = 'getting_up_from_bed'
}

Or how about multiple actors doing the same?

{
    type = 'Animation',
    target = {'leftGuard', 'rightGuard'},
    animation = 'salute'
}

For more complex stuff:
{
    type = 'Serial', -- alternative 'Parallel'
    actions = {
        {
            type = 'Animation',
            target = 'leftGuard',
            animation = 'salute'
        },
        {
            type = 'Animation',
            target = 'rightGuard',
            animation = 'salute'
        },
    }
}

A "Serial" or "Parallel" action would only return/continue once all children have been completed.

Of course there could still be an action "script" or "complex", that would call actual code.

But also keep content creators in mind who might not be programmers. They might have a far easier time to toy around with data in a tree that's displayed in a treeview control or something similar (think of the trigger editors for Blizzard's RTS games, like StarCraft  (2)).
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 06, 2016, 11:24:47 pm
Yeah, I was just giving a simpler examples of functions which can be called. But sometimes you won't have enough of predefined actions. So custom functions for them will be useful.

I like your ideas, thanks! Animation actions can be also used like this:
{
    type = 'Animation',
    target = 'sleepyDude',
    animation = 'getting_up_from_bed',
    waitUntilAnimationFinish = true
}
So the next action can immediately begin after the animation is set or wait until the animation finishes depending on waitUntilAnimationFinish value.

Here's an example of a cutscene I've already done. This is very simple, and of course I could create "Print" action or something, but I'll just show the general principle.
local cutscene =  {
    {
        f = function()
            print("Hello")
        end
    },
    {
        type = CutsceneActionType.Delay,
        finishTime = 1000
    },
    {
        f = function()
            print("World")
        end
    },
}

This cutscene prints "Hello", then waits for one second and then prints "World".
I have Cutscene class which has vector of pointers to CutsceneAction
I inherit from CutsceneAction to create DelayCutsceneAction which works the same as other actions which follow this principle at the moment:
    1) Call currentAction's function
    2) If currentAction->isFinished() then we can move on to another action
    3) Else we update the currentAction, just passing delta time to its execute function

At this point it's easy to came up with idea how to implement DelayCutsceneAction, so I won't post its code here.

I think this explanation may be a bit too short for such complex topic and I think I'll write an article about it once I have more experience with it (once I create complex cutscenes some things will change for sure)

But also keep content creators in mind who might not be programmers. They might have a far easier time to toy around with data in a tree that's displayed in a treeview control or something similar (think of the trigger editors for Blizzard's RTS games, like StarCraft  (2)).

Good idea, maybe I'll make a GUI for cutscene editing at some point and then it will be easier to implement! :D
(And I also need to check out how cutscene creation works in Starcraft)
Title: Re:creation - a top down action adventure about undeads
Post by: ZackTheHuman on January 07, 2016, 07:17:55 pm
One thing that may be interesting to use for implementing cutscenes would be Behavior Trees. I just recently wrote a simple behavior tree implementation to control entity behavior, but the basic set of behavior tree components (Sequence, Selector, Repeat, etc.) could easily be used to do the kind of thing you're describing.

As to whether it's easier for content authors to write cutscenes using behavior trees is another story, but you could possibly carry over some of the ideas behind behavior trees and use them in your own way.

There are a few good articles about them on Gamasutra:

http://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php
http://gamasutra.com/blogs/BenWeber/20120308/165151/ABL_versus_Behavior_Trees.php

Another thing that could be interesting since you're using Lua would be to use coroutines to implement those "keep doing this until some condition is met" kind of things. Coroutines are an awesome feature of Lua, but you would have to wrap them up to make them nicer to use for content authors/modders.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 07, 2016, 09:57:20 pm
ZackTheHuman, thanks, I'll check the articles. Can't really talk about what I think about behavious trees for cutscenes at the moment, because I'm not experienced with them. :D


I wrote an article about global vs local variables in scripts. It only took me two years to realize the stuff I've been doing wrong ;D
https://eliasdaler.wordpress.com/2016/01/07/using-lua-with-c-in-practice-part4/
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on January 07, 2016, 11:13:58 pm
There is a function in 5.1 called setfenv that you can use to set the global environment of a function so all global variables go into that table instead of going into the real global one. Here's an example:
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

int main(void)
{
    lua_State * L = luaL_newstate();
    lua_newtable(L);
    luaL_loadfile(L, "vars.lua");
    lua_pushvalue(L, -2);
    lua_setfenv(L, -2);
    lua_pcall(L, 0, 0, 0);

    lua_getfield(L, -1, "a");
    printf("a = %f\n", lua_tonumber(L, -1));
    lua_pop(L, 1);

    lua_getfield(L, -1, "a");
    printf("b = %f\n", lua_tonumber(L, -1));
    lua_pop(L, 1);

    lua_getfield(L, -1, "c");
    printf("c = %s\n", lua_tostring(L, -1));
    lua_pop(L, 1);

    lua_close(L);
    return 0;
}
a = 10
b = 20
c = "sto"
In 5.2 this function was removed and environment is upvalue _ENV or something like that instead.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 08, 2016, 07:45:11 am
That's good to know, thanks. But how is this better than using local tables?
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on January 08, 2016, 02:26:35 pm
It's not better or worse, just a bit different and on about same level of complexity to do. I personally like it because it allows not having a table in the file and just writing 'variable = value' lines like in an .ini file or something. To me it's more intuitive without the local table. But there's nothing wrong with local tables.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 09, 2016, 08:27:16 am
I think it's a bit worse: you have to manage lifetime of stuff you load to this table. Yes, scoping problem is solved, but you have to keep track of variables you still need to have and ones you don't. If you load too many script files, your lua_State may become pretty big.

If you use local tables which are assigned to LuaRef, once the reference count for the table is 0, it's gone forever.
So, you can do something like this:
void loadData() {
    ... // load stuff
    auto ref = luabridge::LuaRef::fromStack(L, -1);
    ... // get data
    lua_settop(L, 0); // clean stack
} // ref is removed, so when you call garbage collector, local table will be removed
So, you can control Lua variables lifetimes just as you do with C++ unique/shared_ptr which is very good.

As for simplicity... You can do this:
local settings = {
a = 10,
b = 20,
c = "sto",
}

return settings
Not much different from .ini and easy to read and modify.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 10, 2016, 11:03:50 pm
I was making pickable items and remaking item menus and I decided to make something a bit silly
(http://i.imgur.com/d2nMzh1.gif)

Right now I'm working on a cutscene system and it's working pretty well. Here's an example of a simple cutscene. Nothing special, but I'm very glad to see the characters come into life. Now I need to draw some animations :D
(http://i.imgur.com/DNOfv8m.gif)

local cutscene =  {
    {
        type = ActionType.Dialogue,
        entityTag = "MASTER",
        talkTag = "GREETINGS"
    },
    {
        type = ActionType.GoTo,
        entityTag = "MASTER",
        destinationEntityTag = "BUTTON_BRIDGE_MASTER"
    },
    {
        type = ActionType.Event,
        eventType = EventType.TriggerEnteredEvent,
        subjectTag = "TRIGGER_CROSSED_BRIDGE"
    },
    {
        type = ActionType.GoTo,
        entityTag = "MASTER",
        destinationEntityTag = "TRIGGER_GO_TO_HOUSE"
    },
    {
        type = ActionType.Dialogue,
        entityTag = "MASTER",
        talkTag = "COME_IN"
    }
}
It's easy to read and modify which is great. I especially like "Event" action which waits until the particular event is triggered (in this example it's when the player walks across the bridge and collides with invisible trigger)
I'll continue to work on cutscenes (which are more like a scriptable events which will happen in-game and are very important!) and finally draw some new art.  :D
Title: Re:creation - a top down action adventure about undeads
Post by: Ironbell on January 14, 2016, 10:47:44 pm
That's pretty awesome and inspiring stuff you're developing here. I didn't manage yet to read this entire thread, but I'm impressed by what I've seen (I also took a glimpse into your dev blog :P).

I'm also developing a game at the moment but at the time when I thought it would be a good idea to have an Entity Component System, 30k lines of code were written and it was just.. nah. So I'm still using the straight forward, ugly, OO approach but I'll be sure to come back and look at your tutorials when starting my next game.

I also know what it feels to be a student that's developing a game and using nearly every free minute for it. And doing art AND code. Fortunately, I'm not a solo dev, I have a fellow student who's helping me with design decisions and sometimes even a bit programming and art  ;D. This is also what helps me staying motivated, having someone to talk and share, which is important when the project takes a long time (say, more than a year) to finish. So it's even more amazing that you are able to develop it entirely on your own.

I'll certainly be following your future progress and I'm quite excited about what it will be like to play when it's finished (supposed it will be finished at some time? You'll never know.)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 15, 2016, 11:12:38 pm
Thank you! I'm very glad that my progress inspires you!

It's hard to "get" ECS the first time you do it. It took me two or three times to get the design I've felt quite good (still, I think it's not the most efficient, but at least it works well :D)

And that's pretty cool to have something you work with. For me, my gf's support helps a lot (I talk a lot about the game with her). I also have a lot of stuff going on there, on reddit and on twitter, so people's feedback helps a lot too! :D

The game is surely being finished. Maybe it seems like I'm taking forever to make progress, but that's just because I didn't draw much art in the last months. It'll get faster, I promise :)
Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on January 16, 2016, 10:14:53 am
Well you did much groundwork and I think that your devspeed might skyrocket now :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 18, 2016, 08:44:07 am
Well you did much groundwork and I think that your devspeed might skyrocket now :D
Yeah, it really seems so.

For example, I was able to do lots of stuff with Cutscene system I've made recently. It's more like "scripted sequence of events", not just for cutscenes. It would take me so long to make the same without it (I previously made short cutscenes with triggers all around the map and different callbacks between entities which was pretty painful).
I'll make cool cutscene soon and I'll be able to show it's full strength. :)

I've spend lots of time drawing stuff in axonometric perspective and giving more volume to stuff.
(http://i.imgur.com/wwyQfao.png)
Here's an old screenshot for comparison:
(http://i.imgur.com/9sOqc3Y.png)

You may notice that I made a lot of changes in Master's sprite. One big change was making it more 3d by using colors better (I'm still not very good at this, but at least the sprite doesn't look as flat as it did before!)
(http://i.imgur.com/IzCnOC7.png)

I don't have much time to work on the game now, because of the exams but they'll soon be over and I'll spend lots of time making the game. :)
Title: Re:creation - a top down action adventure about undeads
Post by: dwarfman78 on January 18, 2016, 09:19:47 am
Hi,

the hat's shadow is on a different side on the thumbnail !!!!  :'(

I prefer the old style bed, it goes better with the style of an old hermit master.

keep up with the good work !
Title: Re:creation - a top down action adventure about undeads
Post by: Ungod on January 19, 2016, 09:26:22 am
The new style looks much better and seems to be easier to draw too. There is actually a big improvement from old to new.

How do you did the shadow of the closet on the northern wall? They seem to fall out of the regular procedure.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 19, 2016, 04:36:42 pm
Hi,
the hat's shadow is on a different side on the thumbnail !!!!  :'(
I prefer the old style bed, it goes better with the style of an old hermit master.
keep up with the good work !
Yeah, I'll fix it :)
Old style bed fits better, but I how new one looks. Maybe I'll make another bed for Master and use this somewhere else.
And thanks, I will :D

The new style looks much better and seems to be easier to draw too. There is actually a big improvement from old to new.

How do you did the shadow of the closet on the northern wall? They seem to fall out of the regular procedure.
Thanks! Yeah, it's a lot easier to draw in this perspective. :)

This and other shadows which don't look like other shadows are drawn manually, since they look the best if I do this instead of relying on algorithm which only works for objects which cast their shadow on a flat surface.
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on January 19, 2016, 04:43:22 pm
I prefer the new projection but that's just a personal preference  :)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 20, 2016, 02:29:26 pm
I prefer the new projection but that's just a personal preference  :)
Thanks. :D

Today I've figured out a way to make multi-branch scripted sequences which will allow me to change stuff based on player's actions/dialogue responses in easy way. Details will come once I implement it and make a cutscene for you to enjoy. :)
Title: Re:creation - a top down action adventure about undeads
Post by: icecat on January 22, 2016, 10:00:20 pm
hey i tried to improve your straw hat guy:

(http://i.imgur.com/F7DwV7i.png?1)
- his hat seems less of a hat and more of a spike (http://i.imgur.com/yUbhAmz.png)
- the sword on his back doesn't really add much to his character so i just removed it
- notice the feet? thats because in most asian cultures its mandatory to take off your shoes when indoors so i took that into consideration

(http://i.imgur.com/Pw9sFlm.png)
- those 2 fire pillars should have shadows
- if this character still needs a sword, you could just make it walk towards the sword on the wall prehaps
- the dialogue says "show no empathy" but i think "show no mercy" would make more sense

anyway i attached my variation of the hat guy with this post. feel free to use it as you wish.
(might need to login to see attachments)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on January 23, 2016, 01:18:17 am
hey i tried to improve your chinese hat guy
Unfortunately, your version looks like it is looking upwards, weirdly towards the high camera!

his hat seems less of a hat and more of a spike (http://i.imgur.com/yUbhAmz.png)
It seems to be correctly "pointed". However, it maybe should be wider and less high. For example:
(https://farm4.staticflickr.com/3036/2955093140_8a6a7a8bf4_z.jpg?zz=1)
(maybe not this big!)

the dialogue says "show no empathy" but i think "show no mercy" would make more sense
Technically, neither makes sense since the words relate to actual people but mercy does make more sense than empathy so I agree with you here.
Title: Re:creation - a top down action adventure about undeads
Post by: icecat on January 23, 2016, 06:42:21 am
Unfortunately, your version looks like it is looking upwards, weirdly towards the high camera!

It seems to be correctly "pointed". However, it maybe should be wider and less high.

(http://i.imgur.com/g2PiaRC.png?1)
- attempted to fix the camera angle
- added a slight cut on the hat to make it more interesting
- used the exact same colors for outline and mustashe that Elias used
- trimmed the arms to make him appear less intimidating and static
- hat got slightly bigger

(http://i.imgur.com/5a5BQEA.png)

attached the 2nd attempt of straw hat guy. feel free to use as you wish.
(login for attachments)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 23, 2016, 10:54:53 am
Thanks for feedback, guys.
I agree with Hapax, that icecat's version had wrong angle, but the last one is better. I'll take some notes into consideration when I try to improve the sprite again, but I won't do it exactly as you did, icecat. That's because I don't think that your interpretation fits my art style very well and the character looks a bit different from what I imagine him to be.

Meanwhile I've been redrawing stuff in Undead Cafe.
Here's how it looks now:
(http://i.imgur.com/n3eUCxD.png)
Old screenshot for comparison:
(http://i.imgur.com/6hqLHuZ.png)

It feels great to redraw characters with more shading and better use of colors. Stuff looks more polished and professional. And it has more depth.  ;D
(http://i.imgur.com/KU1Rd35.png)

My exams are almost over (The last one is on 25th). After that I'll rest a little and begin to work on a simple multi-branch cutscene which I'll show to you. (Multi-branch system already works well, I just need to make some art and animations for the cutscene)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on January 23, 2016, 02:25:47 pm
Icecat, your new version looks better but you made the head bigger to match the hat and it looks wrong  :P

Elias, seeing your improvement in the cafe makes me wonder why we didn't notice how short the walls were before!
How did the cat get even cuter?  >:(
Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on January 23, 2016, 06:18:38 pm
I don't know why, but the cat is cuter eventhough I think it would be even cuter with the legs stretched like before.
Right now it looks more like a person.
The old one gave a "mew mew" feeling :D
Title: Re:creation - a top down action adventure about undeads
Post by: icecat on January 23, 2016, 06:55:20 pm
Icecat, your new version looks better but you made the head bigger to match the hat and it looks wrong  :P

(http://i.imgur.com/wMZEKC3.png?2)
- smaller head
- tried to mimic Elias's style for shading
- robe got curvier from the bottom

(http://i.imgur.com/cxArLjh.png?1)

attached attempt 3. feel free to use.
(login for attachments)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on January 23, 2016, 07:03:00 pm
I don't know why, but the cat is cuter eventhough I think it would be even cuter with the legs stretched like before.
Right now it looks more like a person.
The old one gave a "mew mew" feeling :D
It's weird but now that I've seen the two together, the older one looks like it's stood on the table!
Title: Re:creation - a top down action adventure about undeads
Post by: icecat on January 23, 2016, 07:57:03 pm
Meanwhile I've been redrawing stuff in Undead Cafe.
Here's how it looks now:
(http://i.imgur.com/n3eUCxD.png)

i have some suggestions for the cafe:

(http://i.imgur.com/NwGjJNZ.png?1)
- give this guy an animation doing something casual like cleaning glasses

(http://i.imgur.com/Ev6H3vT.png?1)
- instead of square stools maybe you should have bar stools here (picture for reference below)
(http://i.imgur.com/Bw4A8vY.jpg?1)

(http://i.imgur.com/k03i3rs.jpg?2)(http://i.imgur.com/7kzvu7O.png?1)
- instead of pillars maybe use hanging lamps/lanterns for light?

(http://i.imgur.com/JHi8Kcj.png?1)(http://orig13.deviantart.net/3e72/f/2010/100/5/5/554857f7dbf6ffb18264957cfe033f60.png)
- maybe some jars/glasses/cups on the tables

(http://i.imgur.com/iBo5kmy.jpg?2)
- local sign, could maybe say "undead cafe" on it

(http://i.imgur.com/d3CPiHb.jpg?1)
- would be funny to see some cats waitering, highly unnecessary though
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 23, 2016, 10:14:19 pm
Elias, seeing your improvement in the cafe makes me wonder why we didn't notice how short the walls were before!
How did the cat get even cuter?  >:(
I think you didn't notice it, because when I've made the changes in perspective, the walls stayed at the same height. So you imagined that you looked at the old angle at them. But not long ago I've realized that if I make walls higher, the angle would fit the style and perspective better. And it worked! :D
And I think the cat got cuter because of longer ears and better head shape. :D

Specter, as for his pose, just imagine that he sits like this... it makes the whole thing better ;D
(http://www.zakstudio.com/wp-content/uploads/2013/06/chaton-gris-parquet-.jpg)

icecap, not to sound rude, but while some of your suggestions are good, I think that you're giving too many suggestions instead of feedback... I can't add that much stuff based on your vision of my game.
Title: Re:creation - a top down action adventure about undeads
Post by: icecat on January 23, 2016, 11:12:56 pm
I can't add that much stuff based on your vision of my game.

understood
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 30, 2016, 09:31:43 am
So, I'm done with the exams and I have more time to do stuff. I'm working on scripted sequences now. I've implemented multiple choice inside dialogs and tagged actions.
(http://i.imgur.com/yB0Hw90.gif)
Here's how this looks in Lua:
local cat = getEntityByTag("CAT")

local cutscene =  {
    {
        type = ActionType.Dialogue,
        dialogue = {
            {
                entity = cat,
                text = { "meow_meow_pop_quiz", "pop_quiz" },
                choices = {
                    {
                        text = "yes",
                        f = function()
                            cutsceneGoTo("ANSWERED_YES")
                        end
                    },
                    {
                        text = "no",
                        f = function()
                            cutsceneGoTo("ANSWERED_NO")
                        end
                    }
                }
            }
        }
    },
    {
        tag = "ANSWERED_YES",
        type = ActionType.Dialogue,
        dialogue = {
            {
                entity = cat,
                text = { "incorrect" },
            }
        }
    },
    {
        tag = "ANSWERED_NO",
        type = ActionType.Dialogue,
        dialogue = {
            {
                entity = cat,
                text = { "i_thought_you_would" },
                portraitName = "sad"
            },
            {
                entity = cat,
                text = { "silly_me" },
                portraitName = "shrug"
            }
        }
    }
}

return cutscene
Pretty easy to follow, but maybe there's some stuff I can improve? :D
As you can see, some actions are tagged, and I can go to them with cutsceneGoTo function. There's a lot more I can do with this stuff and I'll make another, more complex cutscene to show it off soon!
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on January 31, 2016, 04:33:28 pm
Made a quick and easy system to draw overlays on sprites which let me minimize copy-paste between human and zombie sprite sheets. Previously I had to make human sprite sheet and then copy-paste it and redraw face, hair and hands. This was obviously a pretty silly thing to do.
But now I do things a lot better. I have separate sprite sheets for body and face + hair + hands and just draw one sprite on top of another. So, I get something like this:

(http://i.imgur.com/TdmknN0.png)

(http://i.imgur.com/zP59uzw.png)

Right now face, hair and arms are at the same positions in sprite sheet as they are in original one, so I set same textureRect for both main and overlay sprite without having to deal with different coordinates. I don't waste much space by having huge empty spaces in .png.

This will also allow me to make different faces for NPC with same bodies to make reusing art easier!

My plans for the next week is to work on the battle system, puzzles and awesome boss battle which I won't spoil for you. :D
Title: Re:creation - a top down action adventure about undeads
Post by: ZackTheHuman on January 31, 2016, 07:53:15 pm
Looks really good. Reminds me of how the sprites in Mega Man worked. I'd love to hear more about how you specify this kind of layering/compositing in your data files. I want to do something similar in the game I'm working on.

I don't waste much space by having huge empty spaces in .png.

Nitpick: this is true for the .png file on disk, but not really true once the image is in memory.
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on February 01, 2016, 12:21:12 am
"InferXX"
"Can you fill in the blanks?"
(Yes/No)
"No"
"I thought you would help."

Made me laugh although sad cat's face also made me sad.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 02, 2016, 08:39:04 am
Looks really good. Reminds me of how the sprites in Mega Man worked. I'd love to hear more about how you specify this kind of layering/compositing in your data files. I want to do something similar in the game I'm working on.
Right now it's pretty simple, I just have this table in Lua:
overlays = {
    default  = "res/images/enemy_human_skin.jpg",
    zombie = "res/imaged/enemey_human_zombie_skin.jpg"
}
And overlay textures are stored in std::map<std::string, sf::Texture*>. So I can easily do this:
entity->get<GraphicsComponent>()->setOverlay("zombie");
so the "zombie" texture gets set to sf::Sprite overlaySprite and it's drawn on top of main sprite.

Nitpick: this is true for the .png file on disk, but not really true once the image is in memory.
Yeah, that's true. But after all the size if not the main issue, because the sprites are really small. Not having to copy-paste stuff is what makes it cool (because if I change some stuff in "human" sprite, I could have forgotten to change it in "zombie" sprite. But that's not a problem anymore)

Made me laugh although sad cat's face also made me sad.
Ha-ha, this is now one of my favorite comments about my game of all time. I want to make the game which will be called "roller coaster of emotions". ;D

Btw, I'm currently working on the first boss which will be much cooler than I've thought before and fit "prison" theme better. I'll fully redesign him later and make a lot of changes to boss battle. I'll probably show as much as possible because I don't want to spoil anything for you. :D
This boss is very complex and has a lot of different states and reactions to the stuff you do. It would have been pretty hard to make it with script state machines, so cutscene/scripted sequence helps a lot. It becomes more and more complex and lets me do stuff I never imagined to do before. For example, now I can easily track how many times one or another action happened (for example, how many times someone said something to you), so I can make NPCs react in another way if you do something twice. That's pretty cool, but also very hard to make good. So I'm trying out different approaches and maybe I'll write an article about that later.

So, I have a question: what are some good editors in games (AAA or not, doesn't matter) which let you do cutscenes in games? It would be pretty good to see how other games do it.
Title: Re:creation - a top down action adventure about undeads
Post by: Dark2Dragon on February 02, 2016, 12:50:41 pm
Quote
Btw, I'm currently working on the first boss which will be much cooler than I've thought before and fit "prison" theme better. I'll fully redesign him later and make a lot of changes to boss battle. I'll probably show as much as possible because I don't want to spoil anything for you. :D
This boss is very complex and has a lot of different states and reactions to the stuff you do. It would have been pretty hard to make it with script state machines, so cutscene/scripted sequence helps a lot. It becomes more and more complex and lets me do stuff I never imagined to do before. For example, now I can easily track how many times one or another action happened (for example, how many times someone said something to you), so I can make NPCs react in another way if you do something twice. That's pretty cool, but also very hard to make good. So I'm trying out different approaches and maybe I'll write an article about that later.
I hope you doesn´t make it too complex - because then i think u can´t finish this game (alone).
You make it better and better, but not only the engine have to run, also the story must be implemented.
Your work and this game is really great, but it would be a shame when it never comes out.  :'(
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 03, 2016, 08:51:57 am
I hope you doesn´t make it too complex - because then i think u can´t finish this game (alone).
You make it better and better, but not only the engine have to run, also the story must be implemented.
Your work and this game is really great, but it would be a shame when it never comes out.  :'(
Thank you! I completely understand your concerns. I'll try not to make it all overly complex, I don't want to make simple game, but it won't be a game with 10+ hours of gameplay with tons of NPCs (I plan to have something like 6-8 hours). The engine work is almost done and it feels really great. I've spend only 2 days making a boss behaviour which would take me like a week before. This will be even faster in the future, because these two days weren't just about scripts, I had to add some stuff to script system which was missing. But as I add these features, I need to do it less and less.
I've yet to learn how to develop faster and be more pragmatic, but I think I'm getting better at that. :D

Just a quick note: I now realize even more stuff which script sequence system help me to solve and it leads to removal of lots of C++ code and less hardcoding. Feels really great. :D

I've also made CameraGoToAction which lets me scroll camera to specified entity. This works pretty funny: I create an invisible entity which camera follows just as it follows the player. Then I add AIComponent to it and set AISeekState which sets entity to go to another entity. But because the first entity is invisible, it looks like camera scrolls to the entity I specified.
This is a cool example of reusing my code without simple copy-paste. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Ungod on February 03, 2016, 11:21:55 pm
How is the boss-progress going? Would like to see some gameplay. :)

Do you currently work full-time on your game?
Title: Re:creation - a top down action adventure about undeads
Post by: etiennebp on February 04, 2016, 05:25:35 am
Just wanted to say that I'm looking forward to playing this game. What you got going on is really cool and it has inspired me to build my own ECS engine. Cheers!
Title: Re:creation - a top down action adventure about undeads
Post by: Tukimitzu on February 05, 2016, 06:36:03 am
Hey, dude, nice work!

I also share your love for ECS. And it's interesting to see a implementation different from mine.
I have 2 questions about your implementation:

1) Do you have/need communication between systems?

2) How do you handle events?

Thanks!
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 05, 2016, 09:13:01 am
How is the boss-progress going? Would like to see some gameplay. :)

Do you currently work full-time on your game?
The boss development is doing great. I'm almost finished with it, just need to redraw everything, make some more states for the battle and make sure that the battle doesn't have bugs in it.
As for gameplay: I won't show boss battle to not spoil it. But I plan to make some new puzzles soon which I'll show (and also I'll maybe show improved battle system when I'll make it)

I don't work full-time on the game, because I have to do some other stuff (study math, read, spend time with family, etc.), but I'm getting much more time to work on the game than I normally do which is great.

Just wanted to say that I'm looking forward to playing this game. What you got going on is really cool and it has inspired me to build my own ECS engine. Cheers!
Thank you! Glad that it inspires you. This is turn inspires me. :)

Hey, dude, nice work!

I also share your love for ECS. And it's interesting to see a implementation different from mine.
I have 2 questions about your implementation:

1) Do you have/need communication between systems?

2) How do you handle events?

Thanks!
Thanks!

1) Yeah, I have some communication between them, but it's pretty minimal and is done with events. So, systems just send events to which everything (including other systems) may subscribe to and then handle as needed.

2) There's some info here: http://en.sfml-dev.org/forums/index.php?topic=18062.msg139016#msg139016
But feel free to ask more questions if you feel that this is not enough to see the whole picture. :)
Title: Re:creation - a top down action adventure about undeads
Post by: Ungod on February 05, 2016, 10:45:12 am
Its your decision, but many games chose a boss to include it in teaser-gameplay (e.g. see Dark Souls 3).

I don't want to make simple game, but it won't be a game with 10+ hours of gameplay with tons of NPCs (I plan to have something like 6-8 hours).

Just wondering about that. While 6-8 sounds enough for a 1-man-game, i would say that the time to create gameplay content (if the required tools are developed), is small in proportion to the overall dev-time. Your data-driven-philosophy should go hand in hand with that anyway.

You seem to be at a point in dev where you might want to plan the next years instead of a few month so how are your future plans? I could imagine some kind of episode-format?
Title: Re:creation - a top down action adventure about undeads
Post by: Tukimitzu on February 05, 2016, 05:30:45 pm
1) Yeah, I have some communication between them, but it's pretty minimal and is done with events. So, systems just send events to which everything (including other systems) may subscribe to and then handle as needed.

2) There's some info here: http://en.sfml-dev.org/forums/index.php?topic=18062.msg139016#msg139016
But feel free to ask more questions if you feel that this is not enough to see the whole picture. :)

I see, the communication between my systems happens through events as well. As you said, it is minimal, but don't you think it is a big deal? I sure do. Maybe it's because I'm working on a turn-based strategy game, where events are essential.

I have another question, I don't know if you talked about it already somewhere: how about GUI? Are buttons and other GUI elements Entities as well?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 06, 2016, 09:15:19 am
Its your decision, but many games chose a boss to include it in teaser-gameplay (e.g. see Dark Souls 3).
Dark Souls has much more stuff than my game, so showing off one or two bosses out of 20-30 is not that big deal.  :)

Just wondering about that. While 6-8 sounds enough for a 1-man-game, i would say that the time to create gameplay content (if the required tools are developed), is small in proportion to the overall dev-time. Your data-driven-philosophy should go hand in hand with that anyway.

You seem to be at a point in dev where you might want to plan the next years instead of a few month so how are your future plans? I could imagine some kind of episode-format?
I currently focus on making a demo which will later show me what stuff I need to focus on. Feedback from people would be very useful and then I'll continue to work on the rest of the game.
The scope of the game is almost defined and I see how much stuff I want to make but it's hard to plan how much it would take me to do it. Cutscene system, for example, saved me a great bunch of time already. Who knows how much time I can save in the future by making new tools and systems.
So, my main plan is simple for now: fully playable demo with 30min-1hour of gameplay.
As for episode-format... No. The game should be fully complete and I won't make it early access before launch.

I see, the communication between my systems happens through events as well. As you said, it is minimal, but don't you think it is a big deal? I sure do. Maybe it's because I'm working on a turn-based strategy game, where events are essential.
The less communication there is between the systems, the better it is for you game, I think. You get less coupling and less dependencies between systems. They each do some stuff and don't share much information between each other.

I have another question, I don't know if you talked about it already somewhere: how about GUI? Are buttons and other GUI elements Entities as well?
GUI elements are not entities, they have their own classes (but I don't have much GUI, but your game may have classes like Button, ScrollBar, etc. Or you can use some SFML GUI libraries instead of writing your own) and right now they're had coded but I'll later store their properties in Lua.
Entities are objects in the game world. Using ECS doesn't mean that everything should be an entity. :)
Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on February 06, 2016, 03:22:36 pm
Quote
Thank you! Glad that it inspires you. This is turn inspires me. :)
Seeing encouraging posts about your game fills you with Determination.

Sorry could not resist :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 10, 2016, 09:19:47 am
Quote
Thank you! Glad that it inspires you. This is turn inspires me. :)
Seeing encouraging posts about your game fills you with Determination.

Sorry could not resist :D
Ha-ha, that's right! :D

Okay, some progress update.
I'm determined to finish the demo's prototype by the end of the month or a bit later. I won't post much screenshots, because it will be a raw prototype which means shitty graphics, shitty dialogue and some bugs. But this just gets stuff moving faster which I've realized when I made pretty cool boss battle in just 3 days.
How long will I polish what I do? I have no idea.  8)

Scripted action sequence (previously cutscene system) goes pretty well and I'm adding new stuff I can do with it.
Sorry for broken tiles/stuff, this is just a test level!
(http://i.imgur.com/jsaCz3U.gif)

It's not even a sequence anymore, as I can go from any action to another depending on some conditions. So, it's more like a state machine now.

For example, I made a script named house_enter.lua which scripts door behaviour and stuff when you enter the house.
Here it is: http://pastebin.com/GMcqUQwE

First of all, it has a function named makeCutscene which returns array of actions which are then later used to make a C++ vector of Actions which are then executed mostly in C++, but they also call to Lua functions (for example, f function defined in lots of actions in the script)
It could have been just a vector of references to Lua functions, but some tasks are pretty complex, so I've made some shortcuts for myself which are coded in C++.

I can pass table named args to cutscene, which is used to get different parameters.
For example, when I call door's interact function, it looks like this:
interact = function(this) -- "this" is a LuaEntityHandle of door entity
    playCutscene("house_enter",  { door = this, key = "GOLDEN_KEY" } )
end
So I can later get stuff which I need like this:
local door = args.door
Some actions have tags, so I can go to them by calling goTo function.
Actions which have nextTag property are calling goTo(nextTag) after they're finished. "EXIT_REQUEST_TAG" is a special tag which just stops cutscene from playing.
When I go to the "ENTER" action, following actions don't have tags, so they're executed one after another.

(I'm also thinking about how to do State machines in Lua better and I'll write some stuff about it later when I test some things. I'll also most likely use Behavior Trees for AI, because they're awesome, though this will be the first time I implement them and I'll try to make them data-driven, of course.)

So, that's how it works. What do you think about this system? Any stuff I can improve? :D
Title: Re:creation - a top down action adventure about undeads
Post by: Jabberwocky on February 10, 2016, 01:39:00 pm
I won't comment on the lua scripting system, I've not much experience with it since I don't use one myself.  But the game looks to be coming along really nicely, Elias!  Agreed, setting some milestones for yourself (the demo) is a great idea.  Sometimes we programmers like to disappear down rabbit holes for a long time without such milestones.  ;)
Title: Re:creation - a top down action adventure about undeads
Post by: Mörkö on February 10, 2016, 02:54:47 pm
Hi.

As I understand you are using an entity component system in your engine right? Could you please summarize how it works, just the broad strokes, most important aspects, etc. What I'm mostly interested in is, for example, does the components have logic or just data? Is there a container `entity` object or are they just connected by ID? How is message passing done? Things like that.

I'm interested in this because I'm currently considering trying ecs for an engine I'm planning, so I'm gathering data on successful implementations of the concept. I could read the whole thread instead of asking but it's very long and thus difficult to get a good overview ^^ thanks.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 11, 2016, 05:29:31 am
I won't comment on the lua scripting system, I've not much experience with it since I don't use one myself.  But the game looks to be coming along really nicely, Elias!  Agreed, setting some milestones for yourself (the demo) is a great idea.  Sometimes we programmers like to disappear down rabbit holes for a long time without such milestones.  ;)
But how does the script itself look? I think it looks pretty readable even if you have almost no experience with Lua :D
And thanks for support :)

Hi.

As I understand you are using an entity component system in your engine right? Could you please summarize how it works, just the broad strokes, most important aspects, etc. What I'm mostly interested in is, for example, does the components have logic or just data? Is there a container `entity` object or are they just connected by ID? How is message passing done? Things like that.

I'm interested in this because I'm currently considering trying ecs for an engine I'm planning, so I'm gathering data on successful implementations of the concept. I could read the whole thread instead of asking but it's very long and thus difficult to get a good overview ^^ thanks.
Hello. :D
There' some stuff about my view of ECS here (http://en.sfml-dev.org/forums/index.php?topic=18062.msg129804#msg129804).
Stuff about Event handling is here (http://en.sfml-dev.org/forums/index.php?topic=18062.msg139016#msg139016).
You can also check out my Using Lua with C++ series (https://eliasdaler.wordpress.com/2015/08/10/using-lua-and-cpp-in-practice/) which show how I implement stuff (though it's simplified there, of  course).
Title: Re:creation - a top down action adventure about undeads
Post by: grok on February 11, 2016, 07:17:49 am
Hi there.
I've been following this topic for a long time. What I can say - you do an amazing job!

One question regarding ECS engine - how  do you process, say 'GraphicsComponents' in the specified order?
For example, let's suppose we have tilemap (i.e. the 'background' layer), then we have HUDS tilemap on top of that, and finally we have our entities like main hero, enemies, whatever. Obviously, during the render we must process them in the specified order: 1) tilemap; 2) HUDS tilemap; 3) enemies and main hero.

Or, suppose, we need to render GUI elements on top of all rendered stuff.

If we just say to our Render system: "hey, take all graphics components and draw them", it will be a mess.

How do you do that? Thank you.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 12, 2016, 05:48:32 pm
Hi there.
I've been following this topic for a long time. What I can say - you do an amazing job!
Hello! Thank you :)

One question regarding ECS engine - how  do you process, say 'GraphicsComponents' in the specified order?
For example, let's suppose we have tilemap (i.e. the 'background' layer), then we have HUDS tilemap on top of that, and finally we have our entities like main hero, enemies, whatever. Obviously, during the render we must process them in the specified order: 1) tilemap; 2) HUDS tilemap; 3) enemies and main hero.

Or, suppose, we need to render GUI elements on top of all rendered stuff.

If we just say to our Render system: "hey, take all graphics components and draw them", it will be a mess.

How do you do that? Thank you.
I have two GameStates in stack of states, so PlayingState calls renderingSystem.process() (which draws tilemap and entities) and GUIPlayingState calls state->draw() which just draws stuff on top of everything. That's all there it to it. :)
ECS doesn't mean that everything has to be part of ECS system. GUI is separate, but still can access events and info from entities. But it's drawing is fully separate and I'm okay with that. :D
Title: Re:creation - a top down action adventure about undeads
Post by: totoo on February 24, 2016, 05:27:29 pm
hi Elias ! first of all I'd say what you made till now is great, just keep going, can't wait to play your game!

Actually I'm making my own game too (what a surprise!), and reading yours made me want to use Lua too for scripting. So I'm currently reading your articles in order to learn (which are great btw), and I found a better way than yours to get a table keys (https://eliasdaler.wordpress.com/2013/10/20/lua_and_cpp_pt2/), I don't know if you still use the same code but on your article you're making a string which contains lua code to execute it in a C++ program... definitely not the best way   ;)

So there's mine:

std::vector<std::string> LuaScript::getTableKeys(const std::string& tableName)
{
    std::vector<std::string> strings;

    if(!lua_gettostack(tableName)){
        return strings;
    }

    for(lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)){
        strings.push_back(lua_tostring(L, -2));
    }

    cleanStack();
    return strings;
}

In fact, when using lua_next(), the value is located at the bottom of the stack, whereas the key is located one upper. So getting the value of the key is as easy as that.
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on February 24, 2016, 06:25:19 pm
You might accidentally call lua_tostring on a non string key, which will break lua_next.
Quote
While traversing a table, do not call lua_tolstring directly on a key, unless you know that the key is actually a string. Recall that lua_tolstring may change the value at the given index; this confuses the next call to lua_next.
Title: Re:creation - a top down action adventure about undeads
Post by: totoo on February 24, 2016, 07:43:04 pm
indeed, but in my case (and in his too I guess) the keys I'll catch like this will always have no space, or if there are, I simply need to add brackets and double quotes. If the name has no spaces then it is automatically converted into a string, for example:

player = {
        AnimationComponent = {
               
                animations = {
                        idle = {
                       
                        },
                       
                        moving = {
                       
                        },
                       
                        attacking = {
                       
                        }
                }
        }
}
 

if I catch the keys of the animations table, like this:

std::vector<std::string> vec = script.getTableKeys("player.AnimationComponent.animations");

for(unsigned int i = 0; i != vec.size(); ++i){
    std::cout << vec[i] << std::endl;;
}

this will output this:
idle
moving
attacking
(the order is variable but it does not matter)

and if you want to use spaces in your key name :

player = {

        AnimationComponent = {
               
                animations = {
                        ["moving right"] = {
                       
                        }
                }      
        }
}
 

this will output the correct name, with the spaces  ;)
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on February 24, 2016, 09:44:24 pm
If there is a number in one of the tables then it'll raise an error. If that error is not in a protected environment (pcall) then it'll call the default panic function and call abort.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 24, 2016, 10:34:44 pm
Hello, totoo
Thanks for you kind words. Really appreciate that.
I recently wrote an article about the problem. Here: https://eliasdaler.wordpress.com/2016/02/16/using-lua-with-c-iterating-over-lua-tables/
So, it's almost the same as getting all keys in table. But it does more, it gets keys and puts values in LuaRef's which is a lot better, because then you can easily iterate over the table just as you would do in Lua with pairs function! That's because most of the time you don't need a list of keys, you need values too. So this function proves to be pretty useful.
As for the non-string keys... My function checks if the key is string, so there's no problems with that. Most of the time I don't care about non-string keys.

Progress update?
It's been a while since I've posted anything new. So you might be thinking that there's not much to write about. But this is false, I'm working very hard on the game and it's actually what I do most of the time for the last few weeks.
It feels like a completion of the base engine so I can focus more on the content once it's done.
I've done a lot of stuff and there are some pretty neat stuff I want to show and I'll do it as soon as I can!
Don't expect new amazing screenshots and gifs, though (sorry). Some of the coolest stuff I've done is pretty spoiler-heavy and isn't polish because I started to prototype a lot of stuff because making shitty art and doing gameplay stuff makes progress go a lot faster than usual.

One awesome thing I want to share right now is this:
I'm porting a lot of code to Lua. This goes quite well because it makes things faster (Calling Lua from C++ is expensive! More about this later), it make my code easier to modify and expand and it makes me write less code. I feel like I'm changing my philosophy about Lua scripting. :D
For example, I rewrote entity state machine in Lua yesterday. -387 lines of C++. +95 lines of Lua. :D
Once I finish some of the stuff I've already started, I'll share a lot of details and hopefully it will inspire other devs and some will help me improve my design.
Title: Re:creation - a top down action adventure about undeads
Post by: totoo on February 26, 2016, 03:18:01 pm
great!
as you're becoming a Lua pro, I'd like to ask you something. as I said previously I'm currently implementing Lua Scripting, what I made till now is being able to build an entity template with its components from the lua script, that works great. but what I want to do now is calling C++ functions from Lua. I read a lot about registering functions, I've made it work (in both senses) but, there's something I'm thinking about.
in every Lua function found in any script, we must be able to do everything that is possible (get the current animation frame, get the current speed, get the health... everything) so lots of functions have to be registered. But the thing is, everytime we open a new script file, everything about the previous one is deleted, including the registered functions.
Is there any way not to need to register every function (registered with lua_pushcfunction() and lua_setglobal()) each time I open a new script file ? (I'm not using LuaBridge or anything else and I'd like not to for the moment)

thanks.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on February 26, 2016, 09:52:50 pm
You should just use the same Lua state for everything. This way you register all the functions once and then load as many script files as you want. Don't forget to check out this article: https://eliasdaler.wordpress.com/2016/01/07/using-lua-with-c-in-practice-part4/

Btw, feel free to ask me any questions about all the programming stuff by sending me emails: eliasdaler@yandex.ru or posting questions on my blog.
This is a dev log about the game in the first place, so I don't want it to be filled with questions which have no relation to the game or it's engine. People interested in the game would find it pretty hard to navigate in the thread.
Title: Re:creation - a top down action adventure about undeads
Post by: jamesL on March 06, 2016, 04:45:41 am
just saw somebody streaming a game called
Stardew Valley 

and it reminded me of the game in this thread

here is Stardew Valley 
go here and watch the video from 1:58 to about 2:25
http://store.steampowered.com/app/413150/

Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on March 06, 2016, 12:23:03 pm
Stardew Valley is a completely different game ???
Title: Re:creation - a top down action adventure about undeads
Post by: jamesL on March 06, 2016, 09:00:32 pm
Stardew Valley is a completely different game ???

duh, obviously

but the video portion I mentioned made me think of the screenshorts posted on page 33
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 06, 2016, 09:28:58 pm
Well, to be fair, the only similarities I see is the same perspective and some colors... But that's a bit of a stretch :)

New dev log. January-February 2016.
Here's a new dev log (https://eliasdaler.wordpress.com/2016/03/06/recreation-dev-log-january-february-2016/)! It talks about the stuff that I did in the last two months.
Some of the stuff I've already posted there, but there's also new stuff!
Here's one of the new screenshots which I haven't posted before.
(http://i.imgur.com/sZAi57L.png)
I'm pretty satisfied about the progress in the last few months. It may not seem that big from the outside, but the changes and improvements I make are making my engine and game a lot better.
There's also a lot of unfinished / spoiler-y stuff I've yet to show.
What do you think about my progress? :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 08, 2016, 09:13:01 am
I'm working on depth and height in the levels and the progress is great so far.
Check out how one of the sides of the platform is not seen when it reaches the lowest point.
(http://i.imgur.com/uN45czv.gif)
I've tested some of the stuff in lots of SNES top down games and it seems like they use the same method that I use: some tiles are just drawn on top of other tiles. The rules of this are not trivial, so I'll probably write an article about it later. More height updates soon!

Btw, here's an awesome chibi Renatus which my GF drawn. It's the first fan art for my game ever. So cool :D
(http://i.imgur.com/aPZ6ivb.jpg)

And I've just realized that I forgot to tell you that the protagonist has a name, Renatus! So, here it is :D
The name will be customizable for laughs.
Title: Re:creation - a top down action adventure about undeads
Post by: Rhimlock on March 08, 2016, 09:20:42 am
Really great project you have here.

I'm just wondering about your depth-rules.
Shouldn't it be enough for a top down 2d-game to sort the draw-order by Y-coordinate?
Things at the top get drawn before things at the bottom.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 08, 2016, 09:34:05 am
Thank you!

No, that's not enough. First of all, if you have flying objects or objects on the ground, you need to introduce z coordinate. Then you'll have to sort by Y and Z at the same time.
And this method only works for sprites, it's different for tiles. Especially considering that I draw tiles using VertexArrays and don't want to render each tile individually, so I have to keep "layers" of tiles which gets complicated pretty quickly. I'll explain more a bit later. :)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on March 08, 2016, 04:49:09 pm
I'm working on depth and height in the levels and the progress is great so far.
Check out how one of the sides of the platform is not seen when it reaches the lowest point.
(click to show/hide)
Even though, technically, it's perfect, it doesn't actually look like that platform is lowering. It looks like it's sliding from one side of the gap to the other.
If it's lowering, it really should have some suggestions of that. Shadows (cast onto the platform and/or cast by the platform) are the best but possibly most complicated solutions. However, perceived occlusion (just darkening it as it's lower) can help. Darkening something makes it appear smaller, further away, more occulded and/or less-significant.

I love this project. It's really progressing and I like reading about it.
I don't think it would actually be the type of game that I would play but I'd love to have the entire story to read (along with images and the humour!) ;D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 08, 2016, 05:21:56 pm
Even though, technically, it's perfect, it doesn't actually look like that platform is lowering. It looks like it's sliding from one side of the gap to the other.
It's moving in Y axis, so yeah, it is sliding from on side of the gap to the other. I'll make it more explicit a bit later (by making the gap wider and drawing better vertical tiles).
Thanks for the suggestions, though! I'll totally have it in mind once I'll start implementing platforms which move up and down. :D

I love this project. It's really progressing and I like reading about it.
I don't think it would actually be the type of game that I would play but I'd love to have the entire story to read (along with images and the humour!) ;D
Thank you!
Well, maybe someone will make a playthrough or "story-only" video for you to enjoy. Though I'll go by the Earthbound route and put some funny stuff in random interactions and dialogue even with unsignificant NPCs :D

Progress update
And here's what I did with tiles... Now the height totally works! I'm very excited about it because I couldn't figure out the way to do this stuff for two days. And there weren't any articles which could help.
(http://i.imgur.com/ypgVCuN.gif)
I still need to add shadows to make it look more cool, but you get the idea. I'll also add jumping down (and falling!) later.
I'll also write an article about how to do this stuff. It's pretty complicated, so it's worth talking about it in depth. :)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on March 08, 2016, 09:37:46 pm
It's moving in Y axis, so yeah, it is sliding from on side of the gap to the other. I'll make it more explicit a bit later (by making the gap wider and drawing better vertical tiles).
Oh, I'm sorry! The irony of me thinking that it did something but did not look like it because it looked like it did something that I thought that it did not look like!  :-X
So, it's travelling from one side of the gap to the other? What would it look like if it was lowering?  ;)

Progress update
That height stuff is a massive step. Good work!
Be aware, though, that obscuring the character is a bad thing. Displaying it through the obstructions (walls etc.) as a transparent or outlined "ghost" sprite is a common solution for this.
Title: Re:creation - a top down action adventure about undeads
Post by: Ethan.Calabria on March 09, 2016, 05:23:16 am
Looks pretty cool!  Some of your marketing efforts must be working too as I see screens of your game re-tweeted from time to time.

I didn't go through the entire thread, but I saw mostly questions / updates about the game mechanics / programming.  How is the story / writing progressing?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 10, 2016, 07:56:20 am
Oh, I'm sorry! The irony of me thinking that it did something but did not look like it because it looked like it did something that I thought that it did not look like!  :-X
Ha-ha, no problem! I realize that this was kinda confused and I'll fix it

So, it's travelling from one side of the gap to the other? What would it look like if it was lowering?  ;)
I don't know, I'll try to make this effect soon and then I'll show it to you :)

That height stuff is a massive step. Good work!
Be aware, though, that obscuring the character is a bad thing. Displaying it through the obstructions (walls etc.) as a transparent or outlined "ghost" sprite is a common solution for this.
Thank you! Btw, the stuff in that gif was fake depth done with some overlays. But now I've made a system which will allow all tiles and entities to have true height as I've found how to draw them properly!
Be aware, though, that obscuring the character is a bad thing. Displaying it through the obstructions (walls etc.) as a transparent or outlined "ghost" sprite is a common solution for this.
Yeah, having an outline will certainly help, though some games are okay with player hinding behind walls and stuff... Well, I'll see, it's not that hard to implement with a simple shader. :D

Looks pretty cool!  Some of your marketing efforts must be working too as I see screens of your game re-tweeted from time to time.
Thank you. Glad to hear that. I didn't do marketing much though, only dev logs and gifs. Once the game is more playable, I'll focus on it more, I'll mail some journalists, make some videos, trailers, Steam Greenlight, etc.! :D

I didn't go through the entire thread, but I saw mostly questions / updates about the game mechanics / programming.  How is the story / writing progressing?
It's progressing quite great! The more I think about the story and characters, the more it makes sense to me. I want to make a connected world, not just a randomly connected sequence of events.
Lots of stuff I develop in the story now is pretty spoiler-y, so I don't talk about it. :D
Non spoiler stuff is not being made yet, because I'm making some stuff which will allow me to do cutscenes / dialogues pretty quickly. So far, the progress is pretty good in this direction. I can make dialogues and cutscenes pretty quickly. I'm also working on all stuff in the gameplay and the engine, so it takes a bit of time.

I plan to focus more on the story stuff a bit later, so maybe you'll see more details about it a bit later. :)
It's certainly richer and deeper than simple "humans fight undeads and they fight back" plot.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 10, 2016, 12:22:13 pm
3d stuff update! I can now make levels with height in my level editor!
(http://i.imgur.com/2GeanAx.gif)

The gif that was posted previously wasn't using "true" height, the height was emulated by drawing some tiles above everything with less Z. But now I've realized that I can make levels with "cubic" tiles, which kinda work like voxels. It makes collision detection and height stuff much easier.
I'll write about how drawing algorithm works a bit later, because there's so much more stuff I have yet to do and improve. Hopefully, it doesn't suck in the end. :)

(Btw, the tiles don't look very well without outlines and shadows and that's something I'll work on in the future)
Title: Re:creation - a top down action adventure about undeads
Post by: SpeCter on March 10, 2016, 02:04:44 pm
So basically your tiles have a real z-position now instead of emulating this behaviour with x/y offsets?

Looks pretty neat btw :D
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on March 10, 2016, 07:22:46 pm
Can your editor hide certain things? I'd suggest a modifiable height limit. If you build a wall like the one in your example above, you still might need to change the floor behind it that is obscured (or build a smaller wall behind it).

If you're feeling adventurous, the editor could now be fully 3D... hehe  ;D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 10, 2016, 10:28:50 pm
So basically your tiles have a real z-position now instead of emulating this behaviour with x/y offsets?
Yep. Not only tiles, but objects have real z position too!

Looks pretty neat btw :D
Thank you :)

Can your editor hide certain things? I'd suggest a modifiable height limit. If you build a wall like the one in your example above, you still might need to change the floor behind it that is obscured (or build a smaller wall behind it).
Not yet, but I think I'll add a feature which will let me see vertical slice of the level, so I can see each row individually. This may help. Not sure what's the best interface for it would be, though. I'll see.

If you're feeling adventurous, the editor could now be fully 3D... hehe  ;D
Hehe, I've thought about that. Too much work for little profit. I'll mostly make stuff which isn't obscured behind objects in front of them so 3d is not needed. (Because this will also be a poor level design as the player can't see what's behind the walls!)
Title: Re:creation - a top down action adventure about undeads
Post by: bitano on March 10, 2016, 10:40:31 pm
Hehe, I've thought about that. Too much work for little profit. I'll mostly make stuff which isn't obscured behind objects in front of them so 3d is not needed. (Because this will also be a poor level design as the player can't see what's behind the walls!)
You're flaming so many nintendo games here among which many super mario games (lol). Obscured places were the most rewarding ones! :D

Also: Nice work! The Z implementation looks awesome. Can you also go downwards, or does the level editor start from the base allowing you to only build upwards?
Title: Re:creation - a top down action adventure about undeads
Post by: Tukimitzu on March 10, 2016, 10:54:33 pm
(Because this will also be a poor level design as the player can't see what's behind the walls!)

I'm with you on that.
*caham* chrono trigger *coff coff*
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 11, 2016, 07:02:57 am
You're flaming so many nintendo games here among which many super mario games (lol). Obscured places were the most rewarding ones! :D
Ha-ha. Well, I think it's okay to have secrets in obscured places, but it's not a good idea to put stuff you can't see but have to interact with. :D

Also: Nice work! The Z implementation looks awesome. Can you also go downwards, or does the level editor start from the base allowing you to only build upwards?
Thank you! For now, it's limited to tiles with z = 0. But there's nothing preventing me from doing tiles with lesser z, so I'll make it. For example, I can build gaps like one I've showed previously where the platform was.

I'm with you on that.
*caham* chrono trigger *coff coff*
Ha-ha. Did Chrono Trigger really do this a lot? I don't remember such stuff here. :D
Title: Re:creation - a top down action adventure about undeads
Post by: bitano on March 11, 2016, 11:14:23 am
Ha-ha. Well, I think it's okay to have secrets in obscured places, but it's not a good idea to put stuff you can't see but have to interact with. :D
Very true! I was just messing :P

Thank you! For now, it's limited to tiles with z = 0. But there's nothing preventing me from doing tiles with lesser z, so I'll make it. For example, I can build gaps like one I've showed previously where the platform was.
That would be cool. Again obscuring areas would be tricky to prevent i suppose. Unless you make it so that higher Z objects are hidden / transparent when you move behind them (or hide the entire Z layer)...Tricky stuff.

Also i was wondering - How are you dealing with the drawing of higher structures which have a base outside the viewport? If the base tile (Z=0) is culled, isn't the entire structure above the base tile culled as well (Z=1/2/3/4/etc)?

I'm interested in this as i'm working on something somewhat similar.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 13, 2016, 08:51:22 pm
Thank you! For now, it's limited to tiles with z = 0. But there's nothing preventing me from doing tiles with lesser z, so I'll make it. For example, I can build gaps like one I've showed previously where the platform was.
That would be cool. Again obscuring areas would be tricky to prevent i suppose. Unless you make it so that higher Z objects are hidden / transparent when you move behind them (or hide the entire Z layer)...Tricky stuff.
I think that I'll just draw outline as Hapax suggested so there'll be no problems with this.

Also i was wondering - How are you dealing with the drawing of higher structures which have a base outside the viewport? If the base tile (Z=0) is culled, isn't the entire structure above the base tile culled as well (Z=1/2/3/4/etc)?
I have no idea how to solve this yet. For now all I can really think about is this: 1) find the biggest z on the map 2) Write z rows below just in case every time.
Yeah, really stupid, but this may do the job if you don't have much height variation (and when z is not very high!)

My drawing algorithm currently works like this:
prevZ = -100
(for each visible tile row) {
   (for each z in row's zs(height variation in row)) {
        draw sprites which lowest Y point is on the row and which have z between prevZ and current Z
        draw tiles with current Z
        prevZ = current Z
    }
}
This gives me correct Z order for everything.
The problem I currently have is that drawing tiles individually is quite slow and I can't really use VertexArray in this case it seems (unless I have VertexArray for each row and z... don't think it will help much). So, does anyone have any ideas how I can improve this?

And by the way, I've been checking out Dear Imgui (https://github.com/ocornut/imgui) which is a very nice immediate mode GUI library which lets me write GUIs for debugging and level editor very easily. I just started using it and implemented my old level editor interface in 1-2 hours! (And improved it a lot in the process, the old one didn't have as many cool things!)
(http://i.imgur.com/jDlAoQg.gif)
I'll write more about experiences with it later, but currently all I can say is this:
Here's all what I have to do to add working checkbox to the window:
ImGui::Checkbox("Show grid", &showGrid); // showGrid is bool
Isn't it cool? :D
Title: AW: Re:creation - a top down action adventure about undeads
Post by: eXpl0it3r on March 14, 2016, 08:10:53 am
Do you use your own Dear ImGui SFML integration?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 14, 2016, 08:12:15 am
Do you use your own Dear ImGui SFML integration?
Nope, I use this one (https://github.com/Mischa-Alff/imgui-backends/tree/master/SFML) by Mischa Alff

bitano, I've created a thread about the problem, so maybe someone will come up with some ideas
http://en.sfml-dev.org/forums/index.php?topic=19971.0

(http://i.imgur.com/4IZROA6.png)
The explanation how I store maps may help everyone visualize everything. I don't just store heights, I store tile Ids for each "z" in the column though.
But still, is there any way to speed up this row by row drawing? Maybe I should still try to create VertexArrays for each row if it possible? (Sometimes it makes no sense, because tiles may have different tilesets or there may be just one or two tiles for given z...)

P.S. Unless there's a way to do proper z-ordering by drawing each "z" tile layer one by one which I can't figure out... :D
Title: Re:creation - a top down action adventure about undeads
Post by: bitano on March 14, 2016, 09:19:20 am
Woa! Thanks for the detailed answer and great idea to dedicate a thread to the issue. Let's see where that leads.
In the meantime, I'll do some puzzling myself :D

Also, that ImGUI looks good. I'm gonna have to borrow that as well. That saves so much work  :o
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 14, 2016, 07:13:43 pm
You're welcome!

Right now I'm having a problem of dealing with all this stuff. Can't decide which way is better, "flat" or "3d" one, so I want to discuss it with everyone. I don't really know about all SNES games, but it seems like most of them store tile data as in "flat" approach with some tiles being able to be written above everything. Do you think it's really so?
It seems like "3d" way has more disadvantages then advantages...
Title: Re:creation - a top down action adventure about undeads
Post by: bitano on March 14, 2016, 07:51:38 pm
Right now I'm having a problem of dealing with all this stuff. Can't decide which way is better, "flat" or "3d" one, so I want to discuss it with everyone. I don't really know about all SNES games, but it seems like most of them store tile data as in "flat" approach with some tiles being able to be written above everything. Do you think it's really so?
It seems like "3d" way has more disadvantages then advantages...
I share the dilemma :P. Personally i decided to work on a system that supports the Z index as i'm sure i'll miss it at some point if I don't (when designing creative encounters).

Unless they tricked it somehow, I think Zelda - a link to the past was in fact 3d, as you were able to move over and under bridges, etc (similar to your last demo GIF).
Having said that, from the top of my head i can't think of any situation where the 3D aspect added a whole lot to the player experience... Grrr i'm gonna have to watch a Zelda gameplay vid on youtube now to make sure :-)

[UPDATE]
Check the following example: https://www.youtube.com/watch?v=xf2IO7P5DVA&feature=youtu.be&t=3h15m16s (https://www.youtube.com/watch?v=xf2IO7P5DVA&feature=youtu.be&t=3h15m16s)
The next couple of rooms have some Z-layer mechanics. There are more rooms like this in Zelda where you see both an upper and a lower area that overlap, but most of the game seems pretty flat. I don't think leaving out the overlapping bits would've broken the game :P
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 14, 2016, 08:39:56 pm
Well, you see, you can have some sort of Z coordinate which will determine some stuff, like entities not seeing/colliding other entities if they have different Z coords or which entities should be drawn under some tiles and which ones should be drawn above the same tiles.
So, for example, suppose you have a bridge which is a bit higher than most of the ground. You can have it with Z = 1 and all entities on the ground will have Z = 0. So, only entities which have Z = 1 or higher will be drawn above the bridge, so you can be under or above the bridge.
The dilemma is: do I store bridge tiles like I do in "3d" version of tile map or in "flat" version... Uhhh... :D
Title: Re:creation - a top down action adventure about undeads
Post by: bitano on March 14, 2016, 09:06:19 pm
Well, you see, you can have some sort of Z coordinate which will determine some stuff, like entities not seeing/colliding other entities if they have different Z coords or which entities should be drawn under some tiles and which ones should be drawn above the same tiles.
Of course! A character-bound Z index. That makes sense as you always have to go up/down stairs (Z trigger object) to get onto an overlaying tile. So it's probably flat. But enough about Zelda!

The dilemma is: do I store bridge tiles like I do in "3d" version of tile map or in "flat" version... Uhhh... :D
Shouldn't you take a step back, look at what you want to achieve with the game and go from there? You started with a really cool idea and have a lot of functionality in place. You probably want/need to develop some more mechanics for interesting enemies and items. Possibly add level/world-altering effects. You'd have a storyline you want to implement. Would leaving out the 3D stuff in any way impair your game?

Looking at what you shared so far i'd think not, but my knowledge of your game / concept is very limited :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 26, 2016, 03:33:07 pm
I'm back! I've done lots of studying stuff I had to do, so I'm mostly free again and I'm starting working on the game again.

I've managed to improve the graphics a lot for a last few weeks and I'll show a screenshot once I polish everything. It's a pretty big step forward!

Let's talk about tiles and 3/4 perspective though. This is a problem which haunted me for a long time...
As I've said previously, there are two ways I could store tile info:
(http://i.imgur.com/4IZROA6.png)
"3d" approach was the thing I've experimented with. I could set x, y and z coordinates for each tile to be able to handle different heights easily.
While the "3d" approach makes sense, it's pretty hard to work with, because it's very hard to place tiles and think about all the different heights. It totally makes sense in isometric games. 3/4? Not much.
My game isn't going to be very "height based" after all. 3/4 perspective is not very suitable for such gameplay.

There are number of things I want to discuss with everyone because there are lots of ways to manage height in 3/4 perspective and some downsides to a method I'm going to implement (maybe someone will give me some good ideas!)

Suppose I have a tile map like this:
(http://i.imgur.com/T5N7HYf.png)
It's possible to walk under the bridge and on the bridge. There can also be a situation like this:
(http://i.imgur.com/9s15MsY.png)
So, there's a need to establish proper drawing order of tiles and objects. Right now I can think of a simple solution: entities and tiles will have z coordinate. For example if the entity is standing on the grass, its z is 0 and if it's higher, it's z = 1 (or more).

Tiles in the red rectangle will have z = 1:
(http://i.imgur.com/Lk9ONVG.png)
Here's how renderer will draw stuff:
draw tiles with z = 0
draw entities with z = 0
draw tiles with z = 1
draw entities with z = 1
etc...

This is probably how most SNES games did it. Here's a screenshot from The Legend of Zelda: A Link to The Past where layers are clearly visible!
(http://i.imgur.com/2HD36Nn.png)

And this approach works okay in most of the cases... unless there are characters which are more than two tiles high (or some animations like the one on the previous screenshot).  They'll be drawn incorrectly, for example in situations like this:
(http://i.imgur.com/DKJopD1.png)
I don't have a solution to this problem and unless I came up with something, I'll just prevent these situations from happening by not placing entities at such places.

And now for collision. It may vary from one z level to another. For example, for entities which have z = 0 it'll look like this:
(http://i.imgur.com/EI0if8w.png)
(If tile is unmarked, it means that it's walkable, if it's marked by X, it means that tile is completely unwalkable)
When the player starts to climb the ladder, entity's z changes from 0 to 1 and another collision rules work for it, they look like this:
(http://i.imgur.com/umMhe9V.png)
Here arrows show directions in which entity can move while standing on the tile. Red lines show "walls" with which entity will collide, so it'll work as needed. (I've got this idea from various posts on RPG Maker forums, he-he)

So, maybe there are other ways to do similar stuff? Or is my way of doing things alright? What do you think? :D
Title: Re:creation - a top down action adventure about undeads
Post by: Tukimitzu on March 27, 2016, 05:07:28 am
Damn scarecrow, always causing trouble, so many places for it to be, but noo, slightly below the platform is the best spot.

Also, what if I want to jump from the second to the first floor with the character (while performing a double front flip, of course) and want the impact to cause an earthquake that destroys the platform I was on? I think you should handle this situation as well.

I hope you find my criticism helpful.

Cheers!  :)
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on March 27, 2016, 09:40:02 am
Damn scarecrow, always causing trouble, so many places for it to be, but noo, slightly below the platform is the best spot.
Ha-ha :D

Also, what if I want to jump from the second to the first floor with the character (while performing a double front flip, of course) and want the impact to cause an earthquake that destroys the platform I was on? I think you should handle this situation as well.
I don't think I'll add jumping. It's pretty hard to implement and make levels having that in mind :)
Title: Re:creation - a top down action adventure about undeads
Post by: Hyden on March 27, 2016, 05:06:23 pm
Love the art style.
Title: Re:creation - a top down action adventure about undeads
Post by: bitano on March 27, 2016, 10:18:34 pm
Looking at your (once again thorough) explanation including visuals, I wanted to reply with something quite profound....but couldn't think of anything. Mainly because i'm thinking you've investigated quite a few options yourself and therefore are well-informed on the pros and cons of each existing method.

I don't think I'll add jumping. It's pretty hard to implement and make levels having that in mind :)
Just wanted to add the question: Does this mean you also don't want to add falling from platforms and/or hovering off of them (or from one to the other) in ghost form?

Also you mentioned preventing placement of entities larger than 2 tiles in those zones, but what if you have a scenario with a 3 tile high moving entity?
Maybe an entity / mob would have a tile-height to check against (and simply cannot move underneath when tile-height > Z)?

Keep up the good work! :D
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on April 12, 2016, 11:56:25 am
Also you mentioned preventing placement of entities larger than 2 tiles in those zones, but what if you have a scenario with a 3 tile high moving entity?
Maybe an entity / mob would have a tile-height to check against (and simply cannot move underneath when tile-height > Z)?
I will just keep large entities (mostly bosses) in isolated areas, so they shouldn't be a problem. :)
The problem is not with collision, it's with drawing order, so I just have to prevent large entities from appearing near bridges and stuff like that.

Progress update
Studying continues...

Not a lot of time to work on the game, but I managed to work on level editor for some time and implement some cool stuff with ImGui:
(http://i.imgur.com/iQibpSk.gif)
There's a room for improvement, of course! For example, adding a small preview for each entity in Entity Creation tab.
I've also drawn some new cool stuff but I'll show it once everything is completed.

I've also made a repository (https://github.com/EliasD/imgui-sfml) which contains the code which I use for ImGui. The related discussion about it will be here:
http://en.sfml-dev.org/forums/index.php?topic=20137.0
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on May 07, 2016, 02:48:34 pm
I'm back again! While I was busy studying I've had some time devoted to the game and I'll have more of it in the next months, so the progress will be faster hopefully. :)

Here's the latest screenshot from the game!
(http://i.imgur.com/I2yn8X4.png)
As you can see, there are some new graphics there. Houses were previously just sprites, but now they're created out of tiles which makes creating new variations of houses much easier! Their proportions changed too.

I've also redrawn main character sprite which is more undead-y and has a lot more detail in it!
(http://i.imgur.com/XQTlPUD.png)
I've also worked on the level editor a lot. (click or zoom in to view in better resolution)
(http://i.imgur.com/2qM27HY.gif) (http://i.imgur.com/2qM27HY.gif)
Now I can add tile overlays which makes creating combinations of tiles easier and lets me greatly reduce the number of tiles in tilesets. This makes creating more interesting levels and changing/reusing graphics much easier!
I can also set z-levels for tiles now which determines drawing order (for example, if the tile has z = 1 then all entities with z less than 1 will be drawn below the tile).

One interesting change in code I've done was using std::stringstream to parse bitmap font config files (BMFont format) and level files which reduced loading times a lot (not like it was very high, hehe).  Previously I had a function which worked like this:
auto tokens = splitString("firstToken,secondToken,thirdToken", ',');
// returns std::vector<std::string> with "firstToken", "secondToken" and "thirdToken" in it
for(auto& token : tokens) {
   ... // do something
}
 
This function used stringstream internally but it was still much slower than this code:
std::stringstream ss(str);
std::string token;
while(std::getline(ss, token, ',')) {
    ... // do something
}
There were thousands of splitString calls during level/bitmap font loading, so replacing it with a better solution improved perfomance a lot.
Title: Re:creation - a top down action adventure about undeads
Post by: Mr_Blame on May 07, 2016, 09:04:24 pm
Very cool GUI!
Did you use premade lib or made one yourself?

EDIT:

Found it as your project, and I like it.
Title: Re:creation - a top down action adventure about undeads
Post by: FRex on May 07, 2016, 09:08:22 pm
It's ImGui:
https://github.com/EliasD/imgui-sfml
https://github.com/ocornut/imgui
Title: Re:creation - a top down action adventure about undeads
Post by: TheGuerilla on May 09, 2016, 01:30:19 am
Game looks pretty damn good. Any vague idea when a release will be availible?
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on May 09, 2016, 09:37:51 am
Mr_Blame, thanks!
TheGuerilla, thank you. To be fair, I don't have any idea about the release sadly. Hard to predict how much I'll be working in the next months and how much time some stuff is going to take. My aim for now is a demo which is still not near horizon sadly but I'll try to finish it this year.
Right now I have 2-4 hours per day to work on the game. This isn't much to be fair so even little things take a lot of time considering I have to do everything in those 2-4 hours: programming, art, level design, etc.
Title: Re:creation - a top down action adventure about undeads
Post by: Mr_Blame on May 09, 2016, 10:10:08 am
My aim for now is a demo which is still not near horizon sadly but I'll try to finish it this year.
Welp, will check this thread as rapidly as I can to not miss the demo release :)

EDIT:

Download you SFML version of imGui, this lib will definitely go to my SFML-app-making-lib-collection(or just SFMLamlc).
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on May 09, 2016, 09:55:06 pm
Implemented much better zoom in. This one responds to where the mouse points and is much smoother than the previous one (the previous one was jitterry because of rounding errors!)
This was made with the help from this tutorial (https://github.com/SFML/SFML/wiki/Source:-Zoom-View-At-(specified-pixel)) by Hapax!
(http://i.imgur.com/yE5lKzX.gif)

As I made some work with sf::Views I've realized that the way I was doing things was quite awkward. To be fair, I have global pointers to the views as I sometimes need to switch some view, draw something, switch to another view, etc. This leads to some confusion and globals feel just very wrong.

Here are the views I have in my engine:
1) Game camera view
2) Game camera view with rounded position for pixel-perfect rendering
3) GUI view
4) Level editor view

So, where can I store sf::Views to get easy access to them? How do I make sure that stuff gets drawn correctly? Should I keep putting window.setView in the beginning of each render() function call? (There're several of them, so there may be bugs because some previous function changed the view and the next one assumed that window has another view...) I can't just pass sf::View* to each render() function, because one render function may use several views at one (for example, GUI can be drawn in GUI view and some stuff may be drawn with game camera view, for example when drawing some GUI stuff relative to game entities)
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on May 10, 2016, 01:53:40 am
You could set the view at the beginning of each render function. It's a tiny thing to do. How many render functions do you have?
If you want to definitely avoid setting them unless they've changed, another option could be to store flags that keep track of if a view has been altered and set the view depending on the flag.
That said, what difference is it making? Are you altering the views in the rendering functions? It may be better to set up each of the views that are needed before any rendering occurs and then just switch amongst them during rendering. Should the views really be altered by the rendering process?

p.s. glad you found the view zooming code useful :)
Depending on how you want the interface to be, you may want to zoom out (only out!) from the opposite pixel (window size - mouse position in window). Try both ways and see what works best for you!
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on May 10, 2016, 09:21:50 am
You could set the view at the beginning of each render function. It's a tiny thing to do. How many render functions do you have?

Not much, in the game it's just two render functions: for the game and for the GUI. But level editor is much more complex: some GUI is drawn with window default view, some GUI is drawn in the world itself (stuff like bounding boxes). So at least two views are needed. Probably the level editor instance will store them as others won't need it.

If you want to definitely avoid setting them unless they've changed, another option could be to store flags that keep track of if a view has been altered and set the view depending on the flag.
That said, what difference is it making? Are you altering the views in the rendering functions? It may be better to set up each of the views that are needed before any rendering occurs and then just switch amongst them during rendering. Should the views really be altered by the rendering process?
Views won't be altered during the rendering. I just don't know what is the best way to access them from rendering functions without using globals. Well, maybe I can add them to Context struct which can be accessed from GameStates, so I can do something like this:
auto& view = *getContext()->gameView;
But PlayingState::render calls RenderingSystem::render so RenderingSystem doesn't have access to Context. So, I should probably pass needed views to the RenderingSystem::render function?
Or maybe I should just do this in PlayingState::render:
window.setView(gameView);
renderingSystem.render(window);
and hope that I won't ever need to draw anything in GUI view from renderingSystem function. :D

EDIT: After a lot of refactoring I've managed to manage views pretty nicely by putting them into Context struct which can be used from GameStates. So the problem is no longer relevant, unless someone has a better approach!

p.s. glad you found the view zooming code useful :)
Depending on how you want the interface to be, you may want to zoom out (only out!) from the opposite pixel (window size - mouse position in window). Try both ways and see what works best for you!
Tried zooming out with the opposite pixel - felt really weird, so I'm going to go with original version. :D
Title: Re:creation - a top down action adventure about undeads
Post by: Carlos Augusto Br Cpp on May 12, 2016, 07:07:13 pm
Hey man...I'm your biggest fan..and I will realy apreciate if you support me..
I have some questions:
1) You use a game engine?If yes tell me what..
2) Where you learn your C++ skills...If you learn at your own tell me why and what material you use?
3) The same question as above but changed to Lua Language...
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on May 12, 2016, 11:20:44 pm
Hey man...I'm your biggest fan..and I will realy apreciate if you support me..
I have some questions:
1) You use a game engine?If yes tell me what..
2) Where you learn your C++ skills...If you learn at your own tell me why and what material you use?
3) The same question as above but changed to Lua Language...
Hey! Glad to hear that, thank you!

1) I'm writing my own engine with the help of SFML. SFML is used for rendering, window creation, input and audio. This is just a basics upon which you can build a game engine which I'm doing right now. You should read this thread and my blog more, there's a lot of info about my engine. 
2) My C++ skills come from lots of books which I've read and lots of time spent programming in C++ (I've been developing in C++ for almost 7 years now!). I'm learning on my own, though there's a lot of help coming from more experienced people telling me what I'm doing right or wrong and telling about best practices.

I should probably write a recommended reading list on my blog, but I'll probably do it later. Okay, let's go!

C++
As far as the learning books go, I can't recommend C++ Primer (5th edition) by Stanley B. Lippman enough (not to be confused with C++ Primer Plus!).
Read it if you're not very confident in your C++ skills and want to learn it more.
As for more advanced/in-depth books (don't be afraid to read them, they're mostly not hard, they're just not tutorial books like C++ Primer)

Resources:

Lua
There's probably only one book I can recommend: Programming in Lua by Roberto Ierusalimschy. Very well written and covers everything you'll need to know about Lua. Can be used for learning from scratch but provides a lot about more difficult concepts.

Resources:
http://lua-users.org/wiki/ - lots of tutorials, sample code, libraries and bindings.

If anyone has anything nice to add, feel free to do so.
Title: Re:creation - a top down action adventure about undeads
Post by: Hapax on May 12, 2016, 11:32:01 pm
I've managed to manage views pretty nicely by putting them into Context struct which can be used from GameStates. So the problem is no longer relevant, unless someone has a better approach
Seems like you've managed to simplify passing the views to the rendering system so sounds like a good design. Nice work.

Tried zooming out with the opposite pixel - felt really weird, so I'm going to go with original version. :D
I expected as much. It's just that I've experienced some interfaces where they would zoom in the alternate way and you can get used to it for that software so you may have had a preference to that style.
Title: Re:creation - a top down action adventure about undeads
Post by: Elias Daler on May 12, 2016, 11:52:59 pm
Seems like you've managed to simplify passing the views to the rendering system so sounds like a good design. Nice work.
Thanks. :D
Yeah, it's pretty simple now. Here's how the code looks in PlayingState::draw now:
if (!game.isEditingLevel()) {
    gameCamera.activate(window);
} else {
    levelEditorCamera.activate(window)</