Your First Game
This walkthrough takes you from an empty project to a running game with a single entity on screen. It uses the Softfire editor’s New Project wizard, which handles the boilerplate so you can start writing logic immediately.
Choose a genre template
Genre templates are pre-configured starting points with the correct systems registered for a given style of game. Templates exist for all supported genres; for this walkthrough choose Platformer 2D. The template includes:
- A scene with a camera and ground tilemap
- The
PhysicsSystem,PlatformerMovementSystem, andCollisionSystemalready registered - A sample player entity with
TransformComponent,SpriteComponent, andPlatformerControllerComponent
To create the project: open the Softfire editor, click New Project, enter a name, choose Platformer 2D, and click Create. The wizard generates the solution structure described in the installation guide.
The basic game loop
Every Softfire game inherits from SoftfireGame, which itself inherits from MonoGame’s Game. The lifecycle is:
using Softfire.Engine.Core;
public class MyGame : SoftfireGame{ public MyGame() : base(new GameConfig { Title = "My Game" }) { }
protected override void Initialize() { // Register systems, load initial scene Systems.Register<PhysicsSystem>(); Systems.Register<SpriteRenderSystem>();
Scenes.Load("scenes/main.scene");
base.Initialize(); }
protected override void Update(GameTime gameTime) { // ECS systems run here automatically via Systems.Update() base.Update(gameTime); }
protected override void Draw(GameTime gameTime) { // ECS render systems run here automatically via Systems.Draw() base.Draw(gameTime); }}You rarely override Update or Draw directly. Instead you write ECS systems that run inside those calls. The base implementation drives the system scheduler and the scene manager.
Adding an entity with a sprite
You can create entities in C# or in the scene editor. Here is the code path, which is useful for understanding what the editor generates under the hood.
using Softfire.Engine.Core;using Softfire.Engine.Core.Components;
// Inside Initialize(), after Scenes.Load():var world = Scenes.Current.World;
EntityId player = world.CreateEntity();
world.Add(player, new TransformComponent{ Position = new Vector2(100, 200),});
world.Add(player, new SpriteComponent{ TextureKey = "player_idle", // Must match an MGCB content key Origin = new Vector2(0.5f, 1.0f),});
world.Add(player, new PlatformerControllerComponent{ MoveSpeed = 180f, JumpForce = 400f,});The TextureKey must match a texture registered in your MGCB .mgcb pipeline file. If you used the template, player_idle is already included as a placeholder 32×48 sprite sheet.
Running in play mode
In the editor, click the Play button (or press F5). The editor launches your game in a sandboxed play-mode window. Input is captured, systems run, and you can see real-time component values in the Inspector panel on the right. Press F5 again or click Stop to return to editor mode. Changes made to entity component values in the inspector during play mode are discarded when you stop — this is intentional.
Building and exporting
When you are ready to produce a distributable build, open the Build panel (View → Build). Select a target platform (Windows, Linux, macOS), choose Release configuration, and click Export. The output lands in bin/export/<platform>/. The export includes your compiled game binary, content files, and a minimal runtime bootstrap. It does not include the editor.
A minimal complete game class
For reference, here is the smallest valid Softfire game entry point — useful when you are not using a genre template and want to start entirely from scratch.
using Softfire.Engine.Core;
public static class Program{ public static void Main() { using var game = new MinimalGame(); game.Run(); }}
public class MinimalGame : SoftfireGame{ public MinimalGame() : base(new GameConfig { Title = "Minimal Game", WindowWidth = 1280, WindowHeight = 720, IsFixedTimeStep = true, TargetFrameRate = 60, }) { }
protected override void Initialize() { Systems.Register<SpriteRenderSystem>(); Scenes.LoadEmpty("main"); base.Initialize(); }}From here, consult the Entities and Components guide to build out your scene.