MoonWorks-docs/content/Game/_index.md

3.5 KiB

title date weight
Game 2021-01-24T21:15:07-08:00 2

The Game class requires three main parts: initialization, update, and draw routines.

To create your Game class, extend the Game class:

namespace MyProject
{
    public class MyGame : Game
    {
        public MyGame(
            WindowCreateInfo windowCreateInfo,
            PresentMode presentMode
            int timestep,
            bool debugMode
        ) : base(windowCreateInfo, presentMode, timestep, debugMode)
        {
            // init code here
        }

        public override void Update(double dt)
        {
            // update code here
        }

        public override void Draw(double dt, double alpha)
        {
            // draw code here
        }
    }
}

Initialization

WindowCreateInfo is discussed in the Window section.

PresentMode refers to the way that your game's render is presented to the screen. The differences and trade-offs boil down to visible tearing vs latency.

The two modes that allow tearing are Immediate and FIFORelaxed.

Immediate means that the presentation system does not wait for vertical refresh to update the screen and presents the image as soon as possible.

FIFORelaxed means that the presentation system usually waits for vertical refresh to update the screen, but if a vertical refresh period has passed since the last screen update then the presentation system does not wait for a new one.

The two modes that do not allow tearing are Mailbox and FIFO.

Mailbox means that the presentation system waits for vertical refresh to update the screen. A queue is used to hold presentation requests, and if the queue is full, then an existing entry is replaced in the queue. This allows for low latency while still preventing tearing. The drawback is that this presentation mode is often not supported on non-Linux systems or older hardware.

FIFO means that the presentation system waits for vertical refresh to update the screen, and new requests are appended to the end of a queue. This mode is required to be supported by the device and prevents screen tearing, but the latency may be slightly worse than the alternatives.

timestep refers to units of frames-per-second. Passing a timestep of 60 means that your game's logic will always update with an exact timestep of (1/60).

debugMode does what it sounds like, enables or disabled debug mode. If debug mode is on then the system will yell at you for doing bad graphics things, for release this should obviously be turned off.

Update

MoonWorks automatically updates input and audio state before calling your game's Update method. dt will be filled in with the timestep. Put your game's update logic here.

Draw

Rendering code goes here. I recommend structuring your codebase so that your Game class doesn't just become a big mess of graphics resources.

You might be wondering what alpha refers to. What if you set your game to update at 60 frames per second but one of your users has, for example, a 144Hz monitor? This will result in ugly stuttering as the game logic and monitor update out-of-step with each other. alpha gets filled in with a value between 0 and 1 which refers to a blending factor between the previous game state and current game state. This will allow you to linearly interpolate your position and rotation values between the two states to eliminate this stuttering.

For a more in-depth explanation of this behavior, I recommend reading the Fix Your Timestep article.