Table of Contents

Your first game

A first game: a window that draws a rectangle and closes on Escape.

Create the project

dotnet new console -n MyGame
cd MyGame
dotnet add package BSGameLib.Game --prerelease

BSGameLib targets .NET 10, so the project's TargetFramework is net10.0. The project setup guide covers the rest of the project file.

Write the game

A game derives from Game, overrides the steps it needs, and calls Run(). Replace Program.cs with:

using BSGameLib.Game;
using BSGameLib.Game.Drawing;
using BSGameLib.Game.Input;
using BSGameLib.Game.Rendering;

using var game = new MyGame();
game.Run();

public class MyGame : Game
{
  public MyGame() : base(new WindowOptions { Title = "My Game", Width = 1280, Height = 720 }) { }

  protected override void Update(IGameTime gameTime)
  {
    if (Keyboard.IsKeyDown(Key.Escape))
      Exit();
    base.Update(gameTime);
  }

  protected override void Draw(IGameTime gameTime)
  {
    using var encoder = Graphics2D.Begin();
    encoder.Clear(Color.CornflowerBlue);
    encoder.SubmitShape(ShapeDrawOptions.RectangleFilled(new Rectangle(20, 20, 220, 80), Color.White));
  }
}
dotnet run

What a game can override

Override When it runs
Configure(IServiceCollection) Once, before anything starts: register your services, and the packages' (AddUI(), AddShaderCompiler()).
Initialize() Once, after the window and the renderer exist.
Update(IGameTime) Every frame: input and game logic.
Draw(IGameTime) Every frame, inside the default render pass: drawing.
ConfigureRenderGraph(FrameGraphBuilder, IGameTime) Every frame, to build the frame's render passes. The default adds one pass, which calls Draw; override it to render in several passes.
EndFrame(IGameTime) Every frame, after rendering: a good place for Dear ImGui windows.

Services registered in Configure are available from GetService<T>(). The renderer is Vulkan unless the game picks another backend, as Setting up a project describes.

Content

ContentManager loads textures, texture atlases and fonts from a root folder:

protected override void Initialize()
{
  ContentManager.SetRootPath(Path.Combine(AppContext.BaseDirectory, "Content"));
  base.Initialize();
}

Copy the folder into the output in the project file:

<ItemGroup>
  <Content Include="Content\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Next