ViewCullingSystem class

Opt-in view culling — tracks which entities are near the camera and marks them accordingly on their CullStateComponent.

Two separate radii are used rather than one shared threshold:

  • renderRadiusMultiplier (default 1.2) — a tight radius matching what's actually on screen. An entity outside it is hidden: ViewCullingSystem sets its RenderableComponent.renderable.visible to false, so RenderSystem skips drawing it — no extra wiring needed.
  • activeRadiusMultiplier (default 2.0) — a larger radius used for simulation. This engine's MovementSystem/PhysicsSystem skip any entity whose CullStateComponent.isActive is false, and game-specific systems (AI, etc.) should check the same flag. The gap between the two radii means entities approaching the screen are already moving by the time they scroll into view, instead of snapping to life at the edge.

Who owns visible

The game does; the culler only borrows it. It writes visible when an entity crosses the render edge and at no other time: on the way out it hides the entity — if it was showing — and remembers doing so (CullStateComponent.hidesRenderable); on the way back in it shows again only what it hid. So a game can hide a culled entity on screen and it stays hidden however often it scrolls away and back.

One case cannot be told apart: while an entity is culled its visible is already false, so the game setting it false then changes nothing, and the culler shows the entity when it comes back into view. To hide an entity that may be off screen, clear CullStateComponent.hidesRenderable as well.

Bounds

An entity's extent is its renderable's bounds, scaled and turned with its transform — the bounding box of the turned rectangle, so a turned entity is never culled while a corner still shows. A negative scale (a flipped sprite) is fine. Without bounds it is a 1×1 box at its position.

Entities must explicitly carry a CullStateComponent to participate — nothing else is affected. The hysteresisMargin avoids visibility flicker for entities sitting right on the render boundary (e.g. during camera spring micro-movement): once visible, an entity needs to cross slightly further out before it's culled back out.

world.addSystem(ViewCullingSystem(camera: engine.cameraSystem.mainCamera));
enemy.addComponent(CullStateComponent()); // opt in — the player shouldn't get one
Inheritance

Constructors

ViewCullingSystem({required GameCamera camera, double renderRadiusMultiplier = 1.2, double activeRadiusMultiplier = 2.0, double hysteresisMargin = 24.0, @Deprecated('Unused: culling tests every opted-in entity directly, which is ' 'cheaper than keeping a grid in step. Will be removed in 3.0.') double gridCellSize = 256.0})
A culler for camera with a render area 1.2× the view, an active area 2× it and a 24-unit hysteresis margin, unless told otherwise. gridCellSize is ignored.

Properties

activeDistance ↔ double
For a camera in space (not GameCamera.isPlanar): how far from the camera, in world units, an entity out of view stays active. Inside the frustum an entity is always active.
getter/setter pair
activeRadiusMultiplier → double
Size of the active (simulated) area, as a multiple of the visible bounds' width and height about their centre.
final
camera → GameCamera
The camera whose visible bounds, read each update, everything is measured against.
final
entities → Iterable<Entity>
Get all entities that match this system's requirements
no setterinherited
hashCode → int
The hash code for this object.
no setterinherited
hysteresisMargin → double
World units added to every side of the render area for an entity that is already visible, before it is culled again.
final
isActive ↔ bool
Whether this system is active
getter/setter pairinherited
priority ↔ int
Priority for system execution order (higher = earlier). Systems of the same priority run in the order they were added.
getter/setter pairinherited-setteroverride-getter
profileName → String
What World.stats files this system's time under (systemTimesMs).
no setterinherited
renderRadiusMultiplier → double
Size of the render area as a multiple of the visible bounds' width and height, about their centre: 1 is exactly the view, 1.2 a tenth of it spare on each side.
final
requiredComponents → List<Type>
Required component types for this system
no setteroverride
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
world ↔ World
World this system belongs to
getter/setter pairinherited

Methods

dispose() → void
Dispose system resources
inherited
forEach(void action(Entity entity)) → void
Execute a function for each matching entity
inherited
initialize() → void
Initialize the system
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onAddedToWorld() → void
Called when system is added to world
inherited
onRemovedFromWorld() → void
Called when system is removed from world
inherited
render(Canvas canvas, Size size) → void
Render the system (optional)
inherited
toString() → String
A string representation of this object.
inherited
update(double deltaTime) → void
Update the system
override

Operators

operator ==(Object other) → bool
The equality operator.
inherited