reckfellENGINE

Pause: gameplay, interface and timers

ProcessMode, physics, signals and CreateTimer; working pause and resume buttons.

On this page

Run pause with a working interface

Add ProcessCounter2D.cs and PauseDemo2D.cs to a 1.0.0 C# project. Attach PauseDemo2D to an Entity2D in a separate level, set a 640×420 viewport, build and press F6. Pausable stops after Pause; Always and the status keep updating. Resume restores gameplay time.

The gameplay counter is stopped while the interface runs with Paused = true

ProcessCounter2D.cs
C#
using Reckfell;

public partial class ProcessCounter2D : Entity2D
{
    public double Elapsed { get; private set; }
    public int ProcessCalls { get; private set; }
    public int PhysicsCalls { get; private set; }

    public override void _Process(double delta) { Elapsed += delta; ProcessCalls++; QueueRedraw(); }
    public override void _PhysicsProcess(double delta) => PhysicsCalls++;
    public override void _Draw()
    {
        DrawCircle(Vector2.Zero, 36, new Color(.08f, .09f, .11f));
        DrawCircle(Vector2.FromAngle((float)Elapsed * 2) * 27, 8, new Color(.25f, .45f, 1));
        DrawString(ThemeDB.FallbackFont, new Vector2(-40, 64), Name.ToString(), fontSize: 17);
    }
}
PauseDemo2D.cs
C#
using Reckfell;

public partial class PauseDemo2D : Entity2D
{
    public ProcessCounter2D GameClock { get; private set; } = null!;
    public ProcessCounter2D UiClock { get; private set; } = null!;
    public Label Status { get; private set; } = null!;
    private bool _previousPause;

    public override void _EnterTree()
    {
        ProcessMode = ProcessModeEnum.Always;
        _previousPause = GetTree().Paused;
    }

    public override void _Ready()
    {
        bool ru = TranslationServer.GetLocale().StartsWith("ru");
        AddChild(new Label { Position = new Vector2(28, 24), Text = ru ? "Пауза: игровое время и интерфейс" : "Pause: game time and interface" });
        GameClock = new ProcessCounter2D { Name = "Pausable", Position = new Vector2(180, 225), ProcessMode = ProcessModeEnum.Pausable };
        UiClock = new ProcessCounter2D { Name = "Always", Position = new Vector2(440, 225), ProcessMode = ProcessModeEnum.Always };
        AddChild(GameClock);
        AddChild(UiClock);
        Status = new Label { Position = new Vector2(28, 340) };
        AddChild(Status);
        var pause = new Button { Position = new Vector2(28, 82), Text = ru ? "Пауза" : "Pause" };
        var resume = new Button { Position = new Vector2(160, 82), Text = ru ? "Продолжить" : "Resume" };
        pause.Pressed += () => GetTree().Paused = true;
        resume.Pressed += () => GetTree().Paused = false;
        AddChild(pause);
        AddChild(resume);
    }

    public override void _Process(double delta)
    {
        if (Status is not null) Status.Text = "Paused: " + GetTree().Paused + " | Pausable: " + GameClock.ProcessCalls + " | Always: " + UiClock.ProcessCalls;
    }

    public override void _ExitTree() => GetTree().Paused = _previousPause;
}

This demo owns global pause and restores the original state on exit. In a game choose one responsible controller; independent components changing one Paused flag can clear each other's pause.

Choose ProcessMode

Entity modeBehavior
InheritInherits through the Parent hierarchy
PausableProcesses while EntityTree.Paused = false
WhenPausedProcesses while Paused = true
AlwaysProcesses in both states
DisabledOrdinary processing is disabled; children with explicit modes can differ

Mode inheritance follows Parent rather than serialization Owner. IsProcessing reports an enabled callback without guaranteeing that pause and active-tree conditions currently allow it. CanProcess addresses those conditions. SetProcess(false) and ProcessMode solve related but different tasks.

The resume-button controller must process while paused: a Pausable interface can lose the input intended to resume it. Signals and direct calls, including CallGroup, do not stop merely because Paused is true. Losing _Process callbacks does not make an object inaccessible to other calls.

Physics and waits

EntityTree.Paused stops the 2D/3D physics servers in ordinary use. Always can continue _PhysicsProcess callbacks without restarting simulation. The fixture verifies an advancing Always counter alongside a stopped RigidBody2D. Running physics-step code and integrating a body are different operations.

WaitPause behavior
CreateTimer(seconds)Defaults to processAlways = true and keeps running
CreateTimer(seconds, processAlways: false)Stops until the game resumes
A Timer EntityFollows its ProcessMode and separate Timer properties
A signal subscription/awaitCan finish if its source emits during pause

Pause is neither Engine.TimeScale = 0 nor object deletion. Slow motion, ignoring time scale and physics-step timers need their own settings. Checks cover both EntityTreeTimer policies, Pausable/Always Timer entities, signals and resuming; application suspension and all platform events are not covered.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.