Loki
Hello again! In the last post I talked mostly about my past engine, Marauder, and the projects I made with it. This post just going to be some of the goals and features I want to accomplish with Loki.
Goal #1: Ease of use
I want Loki to be as designer friendly as possible, which means that I want to limit the amount of code one needs to write when they eventually need to change something in their game. I want just about everything exposed through the editor’s GUI in some way.
Looking back at Marauder, I encountered problems stemming from not having a proper editor; That coupled with not having predefined workflows set up to edit entities or systems led to games that were frustrating to develop. The workflows that were present looked something like the following:
Find entity's value -> Change Value -> Recompile -> Repeat
This is fine every once in a while, but usually I find myself making systems-driven games and I often find myself doing that hundreds of time in a row for multiple values. Needless to say, the process could be a tad bit more friendlier.
Find entity -> Change value slider
Goal #2: Data Oriented Entity Composition
Since the first game created with Marauder was meant to be mostly procedurally generated, I didn’t really focus all too much on data serialization (ya’ know, like an idiot). So when the time came for me to make an editor I had to build serialization on top of an architecture that didn’t really support it, which is one of the major reasons why it failed. This also meant that all entities were created in C# and only could be created in C#. But this time I’m focusing on serialization first, and it’s already a lot better for it. Below are the differences between entity creation between Marauder and Loki.
Marauder
public class Queelaag: Entity
{
public Queelaag() :base()
{
AddComponent<TransformComponent>(new TransformComponent(new Vector2(0,0)));
AddComponent<PhysicsComponent>(new PhysicsComponent(10.0, 5));
AddComponent<RenderComponent>(new RenderComponent("Chaos_Witch_Quelaag.png"));
}
}
And thats it. If I wanted to make a change to this entity I could only do so through the source code.
Loki
public class Smough: Entity
{
public Smough() :base()
{
AddComponent<TransformComponent>(new TransformComponent(new Vector2(10,50)));
AddComponent<PhysicsComponent>(new PhysicsComponent(10.0, 5));
AddComponent<RenderComponent>(new RenderComponent("Executioner_Smough.png"));
}
}
OR
{
"Name": "Smough",
"EntityType": "Loki.Core.GameObject.Entity",
"Components":
[
{
"Position": "0, 0",
"ComponentType": "Loki2D.Core.Component.TransformComponent"
},
{
"RenderLayer": 0,
"TextureName": "Executioner_Smough.png",
"Scale": 1.0,
"Rotation": 0.0,
"ComponentType": "Loki2D.Core.Component.RenderComponent"
},
{
"Mass": 110.0,
"ComponentType": "Loki2D.Core.Component.PhysicsComponent"
}
]
}
So, in Loki one can create their entities in C# or JSON. A few things I want to point out that I find pretty cool… In JSON if you look at the EntityType property you can see that it has the base type “Entity”. But know that if I wanted to I could create an entity in C# then call that type in the JSON.
{
"Name": "Smough",
"EntityType": "Darksouls.Smough",
"Components": []
}
“David why is this cool?” Well that means in the editor, I can create an entity editor that creates a blank entity and then give the user a list of components to choose from. Meaning that they would not have to touch any source code to create a player, monster, or scenery. This helps to satisfy goal #1!
The only time someone would have to touch code is when adding game logic to an entity. Now, there are two ways of accomplishing this. They could either:
-
Create their Entity in C# and then program all logic there. It would still serialize properly and expose itself in the editor, so no worries there.
-
Add a Script Component which allows the user to select the path for a Lua file to supply the logic for it. (Lua scripting could be an entire separate blog post so I’ll leave it at that.)
The downsides to adding game logic in a C# class is that you’d have to create your entity in C# as well which kinda goes against the first goal. But since I’m already using reflection to load the game project I could maybe allow the script component to take the path of a C# class then reflect that to the entity being loaded. That way everything can be done from the editor. Still deciding if its worth the effort though.
Goal #3: Learning
The last goal is to simply understand why game engines like Unity or Unreal chose the workflows they did. Since I’m not really focusing on making a game right now, I can really focus on designing something to allow creators to make a variety of 2D games.
Here are some screen grabs of the editor so far. Be warned…its not much.
Loading a .loki file.
Editing a scene and messing around with grid snapping.