Skip to content

Application, Window and Log

The process itself, the window it draws into, and how to say something about it.

Application

Application.Quit()

Closes the game. Routes through the same shutdown path the OS window-close button uses, so teardown ordering is identical and there's no second exit path to keep in sync.

csharp
public class QuitButton : GameEntity
{
    protected override void OnClick() => Application.Quit();
}

In the editor this closes the editor

Called during Play mode in the editor, this closes the whole editor window — exactly as clicking its close button would. There's no "stop Play instead" special case. Its real target is a standalone build, where the ambiguity doesn't exist.

Application.IsFocused

Whether the OS currently gives the window input focus.

Not accurate on mobile in 0.1.0

No mobile app-lifecycle hook feeds this, so it reads true on Android and iOS regardless of whether the app is actually in the foreground. That's exactly the platform where "autosave when the app backgrounds" matters, so the obvious use of this property is the one that doesn't work yet. Use your own pause button as the trigger there.

csharp
// Reliable on desktop.
protected override void OnUpdate(float ts)
{
    if (!Application.IsFocused && !m_Paused)
        Pause();
}

Application.TargetFrameRate

A software frame-rate cap in frames per second, independent of VSync. <= 0 (the default) means uncapped — rely entirely on VSync and the OS compositor. Read and write.

csharp
Application.TargetFrameRate = 30;   // battery-saver mode on a phone

A soft cap, not a guarantee: a frame heavier than the budget still runs long.

Application.GameType

Whether the project was authored as 2D or 3D — GameType.TwoD or GameType.ThreeD. Read-only, set once at project creation.

csharp
if (Application.GameType == GameType.TwoD)
    UseOrthographicSetup();

Window

Window.FramebufferSize

The window's physical framebuffer size in pixels, as a (uint Width, uint Height) tuple. What you need to recompute screen-space bounds yourself.

csharp
(uint w, uint h) = Window.FramebufferSize;
float aspect = (float)w / h;

Physical pixels, not logical points

On a high-DPI display this is larger than the window's logical size. It matches what Input.GetMousePosition() and CameraComponent.WorldToScreen work in, so the three agree.

Log

Four levels, all taking a single string. Output appears in the editor's Log panel.

MethodUse for
Log.Trace(string message)Fine-grained detail you'd normally filter out
Log.Info(string message)Ordinary progress and state
Log.Warn(string message)Something looks wrong but the game continues
Log.Error(string message)Something is broken
csharp
Log.Info($"{Name} spawned at {Translation.X}, {Translation.Y}");
Log.Warn("No checkpoint found — starting from the top");
Log.Error("Save failed");

Each line is attributed automatically to the script file, line number and entity it came from — you never pass any of that. That's what makes double-clicking a log line open the script at that line.

Log calls in OnUpdate allocate

Log.Info($"...") builds a string every time it runs, and the interpolation happens before the call regardless of whether anything is listening. Fine on a state change, expensive at 60 fps. See Performance.

See also

  • Time — frame timing and pausing
  • Camera — screen space, in the same units as FramebufferSize
  • The Profiler — where log lines sit next to frame data
  • Saving and settings — autosaving when the player leaves