Komodo
Komodo was spawned out of a desire to learn popular game engine design, like composition over inheritance and ECS. Komodo is an attempt at making an engine that places the developer first, providing simple control over 2D and 3D game development.
Install / Use
/learn @exokomodo/KomodoREADME
Komodo
Komodo was spawned out of a desire to learn popular game engine design, like composition over inheritance and ECS. Komodo is an attempt at making an engine that places the developer first, providing simple control over 2D and 3D game development.
Links
Usage
The recommended way to start with Komodo is by using a project template found in the Komodo.Templates package.
The project layout generally consists of two or more projects.
- One or multiple
<Platform>projects (such asDesktopGL) which consists of platform-specific and creation of starting entities. Commonproject where all major game logic should reside.
Content Pipeline
A Komodo project also will need a Content directory in the top-level directory of the project for placing assets and the MonoGame mgcb file. Komodo users will need to use the MonoGame Content Pipeline for compiling assets. Releases can be found here and a tutorial can be found here. Ignore the sections detailing the code needed to load in the asset files, as Komodo will do this for you given a path to an applicable asset for SpriteComponent, TextComponent, Drawable3DComponent, and SoundComponent.
Platform Project
In each platform project, a Game instance needs to be created. Once Game.Run() is called, control will not come back to the Startup class, so make sure at least one Entity with a BehaviorComponent.
A suggested pattern involves creating a Game instance, setting up platform-specific default inputs, and creating a root Entity with a root BehaviorComponent that will generate all the starting entities and their components.
using DesktopGL.Behaviors;
using Komodo.Core;
using Komodo.Core.ECS.Entities;
using Komodo.Core.Engine.Input;
namespace DesktopGL
{
public static class Startup
{
public static Game Game { get; private set; }
[STAThread]
static void Main()
{
using (Game = new Game()) {
SetupInputs();
var rootEntity = new Entity(Game);
rootEntity.AddComponent(new StartupBehaviorComponent());
Game.Run();
}
}
private static void SetupInputs()
{
InputManager.AddInputMapping("left", Inputs.KeyLeft, 0);
InputManager.AddInputMapping("right", Inputs.KeyRight, 0);
InputManager.AddInputMapping("up", Inputs.KeyUp, 0);
InputManager.AddInputMapping("down", Inputs.KeyDown, 0);
InputManager.AddInputMapping("quit", Inputs.KeyEscape, 0);
}
}
}
If a Common project is being used, the <Platform> project should rarely be more complicated than this. Consider including graphics configuration code to the <Platform> project, selecting a resolution, whether or not to display fullscreen, etc.
Common Project
The Common project is where the majority of the game will be created through BehaviorComponents.
BehaviorComponents generally will initialize the content for an Entity, loading the content from disk or generating the assets programatically.
Once initialized, a BehaviorComponents will continue to receive Update(GameTime gametime) calls unless disabled, allowing the BehaviorComponent to continue interacting with other entities and components.
Here is an example BehaviorComponent which creates an FPS counter as a TextComponent. This example assumes a CameraComponent and a Render2DSystem are also a part of the parent Entity of the FPSCounterBehavior.
using Komodo.Core.ECS.Components;
using Komodo.Lib.Math;
using System;
using Color = Microsoft.Xna.Framework.Color;
using GameTime = Microsoft.Xna.Framework.GameTime;
namespace Common.Behaviors
{
public class FPSCounterBehavior : BehaviorComponent
{
public TextComponent CounterText { get; set; }
public override void Initialize()
{
base.Initialize();
CounterText = new TextComponent(
"fonts/font",
Color.Black,
Game.DefaultSpriteShader,
""
)
{
Position = Vector3.Zero
};
Parent.AddComponent(CounterText);
}
public override void Update(GameTime gameTime)
{
CounterText.Text = $"{Math.Round(Game.FramesPerSecond)} FPS";
}
}
}
Cameras and Render Systems
All Entity objects which have components which can be rendered must have either a Render2DSystem or Render3DSystem referenced by them.
- Render2DSystem is necessary for rendering all Drawable2DComponent objects: SpriteComponent and TextComponent
- Render3DSystem is necessary for rendering all Drawable3DComponent objects.
If an Entity will have a TextComponent, it will also need a Render2DSystem.
If an Entity will have a Drawable3DComponent, it will also need a Render3DSystem.
If an Entity has both a TextComponent and a Drawable3DComponent, it would need both a Render2DSystem and a Render3DSystem.
Each [Render2
