Skip to content

Tick Source should be able to tick more than once per frame #2094

Description

@jknightdoeswork

EDIT:

I've implemented this in a PR that adds a ecs_set_fixed_interval()

Describe the problem you are trying to solve.

I'm trying to use the flecs pipeline and system api to build a core loop that requires three distinct concepts to be expressed:

PreSimulation   (once per frame)
FixedSimulation (zero to N times per frame)
PostSimulation  (once per frame)

FixedSimulation runs core simulation logic at a fixed timestep (e.g. 1/60s) using a time accumulator. PreSimulation handles eg) input, and PostSimulation handles eg) rendering.

The key requirement is that the FixedSimulation must be able to tick multiple times in a single frame when the frame's delta time >= 2 * interval.

eg) Imagine a timer with interval 1.0 seconds, if you call ecs_progress with 10 seconds, the timer fires once with a delta time of 10, but I expect it to fire 10 times with a delta time of 1.0.

This is achievable today, but only by splitting the loop across three separate pipelines and implementing the fixed interval logic manually:

ecs_run_pipeline(world, PreSimulation, raw_delta_time);

const float fixed_dt = 1.0f / 60.0f;
accumulator += raw_delta_time;
while (accumulator >= fixed_dt) {
    ecs_run_pipeline(world, FixedSimulation, fixed_dt);
    accumulator -= fixed_dt;
}

ecs_run_pipeline(world, PostSimulation, raw_delta_time);

This works, but it bypasses ecs_progress entirely and requires the user to manually manage what should be expressible within a single pipeline using tick sources.

Describe the solution you'd like

The current tick_source / rate filter API only supports ticking a phase 0 or 1 times per ecs_progress call. If the frame's delta time is large enough to warrant multiple fixed-timestep iterations, the tick source will still only fire once, causing the simulation to fall behind.

I'd like tick_source to support ticking a phase 0 to N times per frame based on accumulated time, so that a single pipeline with phases like this would accurately simulate real time no matter what delta_time is passed into ecs_progress().

PreSimulation  (ticks once per frame)
FixedSimulation (fixed interval tick_source - may tick 0–N times)
PostSimulation (ticks once per frame)

This would eliminate the need for the three-pipeline workaround and let ecs_progress drive the entire core loop as intended.

I've implemented this in a PR that adds a ecs_set_fixed_interval() and changes TickSource.Tick from a bool to an int.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions