flutter3d_sim library

The simulation: everything a game does between one fixed step and the next, and nothing that draws it or reads a device.

Plain Dart, and that is the whole of why this package exists. It was flutter3d_game's inside — the loop, the entity store, the level format, the saves and replays, the world logic, the actors, the navigation, the camera rig, the maths — and none of it ever imported Flutter. The eight files that did are widgets, a MediaQuery read and one debugPrint, and they stayed behind with the devices they belong to.

What it buys

A server that verifies a submitted run has to replay it through the same simulation the player ran. Not an equivalent implementation and not a rules check: the moment a second copy of the game logic exists on the server, the verification stops proving anything about the first. That server is an ordinary Dart process in a container, and requiring a Flutter SDK there to advance a headless step is a blocker rather than an inconvenience.

It buys two more things that are not the reason and are worth having: a simulation that runs under dart test with no binding at all, and a boundary that a scan can enforce — tool/structure.dart reads this package's source and fails if anything in it names Flutter.

What is deliberately not here

Devices. A touch stick, a keyboard, a gamepad route and the widget that hosts them are flutter3d_game's, because they are Flutter. What crosses the boundary is InputState — intent, with the device forgotten — and InputTape, which is that intent written down per step and is therefore also the format a run is submitted to a server in.

The renderer. flutter3d_app is where a level meets something that draws it, and flutter3d_game is where a game's actors do; nothing here knows that anything does.

Classes

Activated
It did what it was asked.
Activation
Who is switching something on, and what they are carrying.
ActivationOutcome
What came of asking a mechanism to do something.
Actor
ActorDied
An actor's health reached zero this step.
ActorHurt
An actor took damage this step and survived it.
ActorSystem
AtLeastOne
There should be at least one of a type, or the level is missing something.
Automap
The level as the player has seen it, from above.
Body
The capsule that walks, slides along walls and falls off ledges.
Brain
Breaches
The holes a run has blown in its level, and the level with them in it.
Brush
One axis-aligned block of level geometry.
BrushGeometry
Turns a level's brushes into drawable triangles.
BrushSurface
The triangles of every brush sharing one material and one answer about shadows.
Button
A panel on a wall that fires its target when the player presses use.
ButtonKind
Kinds built on a trigger collider: a button, a trigger volume and an exit. Grouped because all three place a ColliderKind.trigger and drive a Signal or Exit from it, rather than a kinematic body.
CameraRig
The part of a chasing camera that every chasing camera has.
CatmullRom
A smooth curve through a list of control points, measured in metres.
CharacterController
Moves a box through a CollisionWorld the way a player expects.
ClothMesh
A grid of particles and the constraints between them, as flat arrays — the shape every hot loop in this package walks without an allocation.
ClothObstacle
One CollisionShape, positioned, for a cloth to push itself out of.
ClothSettings
How a ClothMesh moves, as values rather than as solver internals.
Collider
A shape, somewhere, that takes part in collision.
CollisionBox
An axis-aligned box: level geometry, and the player.
CollisionCapsule
An upright capsule: a segment of length 2 * halfHeight with radius around it.
CollisionHeightfield
Ground as a grid of sampled heights: the fifth shape, and the first one that is not convex.
CollisionLayers
What each collision bit means in a game of this shape.
CollisionListener
Told when colliders begin, continue and stop overlapping.
CollisionShape
A collision volume, positioned by whatever owns it.
CollisionSphere
A sphere: pickups, projectiles, blast radii.
CollisionWedge
A box with one edge cut away: a ramp.
CollisionWorld
Everything in the level that can be collided with, and the queries over it.
Contact
Two shapes, overlapping.
CorridorKit
A corridor, as a recipe.
Damageable
Something a rocket can hurt.
DataSourceRegistry
Every EduDataSource a level's bindings may name, by EntityDef.name.
DataSourceTrace
What every edu_data_source a run read gave, one fixed step at a time — edu-00 §9's "значение из источника... становится вводом для этого шага ленты", written down the same way InputTape writes down a controller: dense, one entry per step, so a replay reads the exact value a run saw rather than a value recomputed from a clock that has since moved on.
Demo
A run, as a file somebody can send: where it started and what they did.
Difficulty
How hard a game is being, as numbers a genre applies where it decides.
DigestTrace
The digest of a running simulation, taken every so many steps.
Divergence
Where two runs of the same tape parted company.
Door
Opens when somebody asks, waits, and closes itself.
DoorKind
Kinds that move a kinematic body along a fixed offset: a door, a lift and a platform. Grouped together because they share one mechanism — EntityKind.requireTravel, a kinematic collider and a speed/wait pair — and differ only in which Mover they hand it to.
Dynamics
EcsWorld
EduDataSource
A named stream of values, sampled once per fixed step — edu-00's edu_data_source (doc/edu-00-interactive-format.md §9), read from the side of a running simulation rather than from a controller.
EntityDef
Anything in the level that is not geometry: a spawn, a monster, a pickup, a door, a trigger, a note on the wall.
EntityKind
Everything one kind of level entity knows about itself.
EntityRegistry
The kinds a build knows about, by name.
EntityTypes
The names a level document uses.
ExactlyOne
There must be exactly this many of a type, no more and no fewer.
Exit
ExitKind
Facing
Which way it faces, how fast it comes round, and where its eye sits.
FixedStep
Turns the display's variable frame time into a simulation that always advances by the same amount.
Fixture
A piece of level geometry that an entity brought with it.
FlameFlicker
Fire.
FlowField
The distance to the goal from everywhere, and which way is downhill.
GameAction
Something the player can ask for, named by intent rather than by device.
GameEvent
Something a step did, told to whoever is watching.
GameEvents
What a step recorded, for the frame that is about to read it.
GameLoop
Ties the clock, the input and the simulation into one call per frame.
GameRandom
HeadlessGame
A game, as a tool that plays it blind needs one.
HeadlessRun
One run of a level, started by a HeadlessGame.
Health
How much punishment something can take.
Heightfield
Ground as a grid of sampled heights.
HeightfieldGeometry
Turns a field of heights into the triangles that draw it.
HeightfieldTiles
A field cut into tiles of tileCells cells a side, each buildable at any of levels resolutions.
InputFrame
One fixed step's worth of intent.
InputState
What the player is asking for, as one object that every input device writes into and the simulation alone reads.
InputTape
A run, as the inputs that produced it.
InputTapePlayback
Plays a tape back into an InputState, one step at a time.
InputTapeRecorder
Writes down what a player did, one entry per step.
InterpolatedAngle
An angle in radians that the simulation writes and the renderer reads.
InterpolatedVector3
A position the simulation writes at a fixed rate and the renderer reads at the display's rate.
One jump the grid allows: from a cell, to a cell, and what it costs a body.
JumpReach
How far a body can jump, from the three numbers that decide it.
KeyHolder
Something that might be carrying keys.
KeyRing
The keys one body is carrying, by colour.
Layers
The one layer constant that means the same thing in every game.
Level
Everything one playable space is made of.
LevelIssue
Something wrong with a level, and where to look for it.
LevelLight
A light placed by the level rather than by the renderer.
LevelMaterial
How a surface is shaded, named so brushes can share one.
LevelRecipe
A piece of a level written down as the instruction that builds it.
LevelRule
A whole-level rule a game brings with it.
LevelScope
What an entity can see of the level it sits in.
LevelSketch
Level geometry as the rows a document writes, before anything reads them.
LevelValidator
Reads a level and says what is wrong with it.
LevelVisibility
Which parts of a level can be seen from where, decided before the game runs.
Lift
Travels to the far end when called, and comes back.
LiftKind
LightBehaviour
How a light behaves over time.
LightFixture
Something in the level that gives off light and can be seen doing it.
LightFixtureKind
Anything that gives off light and can be seen doing it.
Lightmap
LightmapBaker
LightmapFace
One face's place in the atlas and its frame in the world.
LightmapLayout
The atlas: its size, its density, and every face's place in it.
Mechanism
Something in the level that can be switched on and that has a life of its own between switchings.
MechanismEvents
What the level's machinery did during one step.
MechanismWorld
Every mechanism in the level, and the wiring between them.
Mind
Everything a brain is allowed to know, and the few things it may do.
MovementTuning
Every number that decides how the player feels, in one place.
Mover
A block of level geometry that travels between two places.
MovingPlatform
Goes back and forth for ever, whether or not anyone is watching.
A lattice of standing places, and how much room each one has.
Somewhere to walk, and the way there.
Nearly
What "close enough" means in this package, once.
NothingToDo
There was nothing to do — already open, still moving, or no such name.
Pace
Whether the machine is keeping up, and what it cost when it did not.
Physical
A body the world pushes around: a crate, a barrel, anything with mass.
PlatformKind
Moves on its own timetable rather than waiting to be called.
Playback
Reads a recording back, smoothly.
PlayerSpawnKind
Portable
The transcendental functions, computed identically on every platform.
Pose
Where something was at one moment.
Powers
What is running on somebody, and for how much longer.
PulseLight
A slow swell, for something magical rather than burning.
RayHit
Where a ray met something.
Recorder
Writes down where something was, a few times a second.
ReflectionProbeKind
A point the room around it is reflected from.
Refused
It would not, and here is what to tell the player.
RewindBuffer
The last few seconds of a run, kept so they can be lived again.
RewindPoint
A moment in the recent past, and how to get there.
Rider
RigidBody
RigTuning
Where a chasing camera sits, and how fast it gets there.
RoomDoor
An opening in one of a room's walls.
RoomKit
A room, as a recipe.
RunStats
What a run came to, counted off the events it produced.
SamplerDataSource
A deterministic source, for demos and tests that must not depend on a broker being reachable.
ScatterKit
Copies of one thing, spread by the seed.
Scoring
Points, and the run of them a player is holding.
Signal
A mechanism that does nothing itself and switches something else on.
Snapshot
SpatialGrid
A uniform grid over the XZ plane, holding integer handles.
SpawnContext
What an entity is given when it is asked to become real.
StateDigest
Folds JSON-shaped values into one 32-bit number.
SteadyLight
Steady. A lamp, a stained window with daylight behind it.
StepContext
What a StepSystem is told about the step it is running inside.
StepPhase
A named point inside a fixed step, which a game announces as it reaches it.
StepSystems
Systems an application adds to a genre's step, by phase.
StepTimeTrace
How long each step of a run cost, keyed the same way DigestTrace keys a run's state — by the step number, not by wall-clock time.
SurfaceTable<T>
What this game thinks a level's surface words are worth.
SweepHit
Where a swept shape first touched something.
SweptContact
What a ContactFilter is told about the contact it is judging.
SystemRegistration
One registered system, and the handle that removes it.
Takeable
Something lying in the world that one toucher can take, once.
Tally
Things counted by name, and kept.
Tape
A recording: where something was, over and over.
Thinking
What decides where it is going.
TileLevelChooser
Which level each tile draws at, from how far it is — with hysteresis.
Tolerance
What "close enough" means in this package.
TriggerKind
TriggerVolume
A volume that fires its target when something walks into it.
Vitality
Health that can run out.
WindSettings
A uniform wind field, applied per triangle as drag along its own normal.
WorldStep
The order the world is stepped in, which three games had written out.

Enums

ColliderKind
How a collider takes part in the world.
LevelIssueSeverity
LevelLightType
MoverState
Where a mover is in its trip.
RunOutcome
How a run ended, or that it has not.
ShadowCasting
How a brush takes part in the shadow passes, as a document says it.
WedgeUphill
Which way a CollisionWedge climbs.

Extension Types

Entity

Extensions

JsonColorWriter on Vector4
JsonObjectReader on Map<String, Object?>
Reading a decoded JSON object, with the type checks in one place.
JsonValueReader on Object?
JsonVectorWriter on Vector3
LevelCollision on Level
Building the physical side of a level.
SnapshotFields on Map<String, Object?>
Reading and writing the handful of shapes a snapshot is made of.
StepEvents on List<GameEvent>
The question every reader of a drained step asks first.

Constants

levelKits → const Map<String, LevelKit>
The kits a document's recipes may name.

Functions

approach(double value, double target, double step) → double
Moves value towards target by at most step, never past it.
Finds every jump reach can make between cells of grid.
contactBetween(CollisionShape a, Vector3 aAt, CollisionShape b, Vector3 bAt, Contact out, {double margin = 0.02}) → void
Fills out when the two shapes overlap, and clears it when they do not.
contentDigestHex(Map<String, Object?> json) → String
A JSON document's content as an eight-digit hex digest — StateDigest over the document itself.
easeFactor(double rate, double dt) → double
How much of the way to a target one step of dt seconds should carry, for something that eases in at rate per second.
expandRecipes(Level level) → Level
level with every recipe turned into the rows it stands for.
pushOutsideObstacle(Vector3 point, ClothObstacle obstacle, double thickness, {double span = 0.0}) → bool
Pushes point outside obstacle by thickness.
pushParticleOutside(Float64List xyz, int i, ClothObstacle obstacle, double thickness, Float64List push, {double span = 0.0}) → bool
Pushes particle i of xyz outside obstacle by thickness, writing the push that was applied into push. Answers whether it moved.
readNumber(Object? value) → double
A number from a snapshot, or nought.
readVector(Object? value, Vector3 out) → bool
Reading a saved body back.
registerActorComponents(EcsWorld entities) → void
Teaches an EcsWorld how to write an actor down.
remapEntitySave(Map<String, Object?> saved, {required List<String?> oldNames, required List<String?> newNames, required List<int> newGenerations, required List<int> newFree}) → EntityRemap
Rewrites saved — an EcsWorld.save document — from the entity indices it was written at to the ones newNames hands out, matching by name.
resolveBindings(EntityDef step, int atStep, DataSourceRegistry sources) → Map<String, Object?>
One edu_step's worth of resolved bindings — target path to the value DataSourceRegistry held for it at step.
roundDecimal(double value, int digits) → double
value rounded to digits decimal places, ties to even, on its exact binary value.
roundedVector(Iterable<num> values) → List<double>
A vector at millimetre precision.
shadowKeys(String mode) → Map<String, Object?>
The keys a brush row writes to ask for the shadow mode, and nothing it need not.
shortestAngle(double from, double to) → double
The shortest way round from one angle to another, in radians.
shouldPause({required bool ready, required bool menuOpen, required bool pointerIsTheGate, required bool pointerHeld, required bool padConnected}) → bool
Whether the simulation should be standing still.
stepCloth(ClothMesh mesh, ClothSettings settings, double dt, {List<ClothObstacle> obstacles = const []}) → void
Advances mesh by dt seconds, in place.
subtractBox(Brush brush, Aabb3 hole) → List<Brush>
What is left of a brush when a box is taken out of it.
surfaceUnder(Collider? collider) → String?
What a body is standing on, as the word the level author wrote.
turnedTowards(double yaw, double wanted, double step) → double
yaw, turned towards wanted by at most step, the short way round.
vectorOf(Vector3 v) → List<double>
A vector as three numbers, which is what JSON has.

Typedefs

BrushFace = ({int brush, double centreX, double centreY, double centreZ, int face, double halfU, double halfV, Vector3 normal, Vector3 u, Vector3 v})
One visible block face: whose it is, which of the six, and its frame — the centre, the outward normal, the two axes across it and the half extents along them. What the geometry emits a quad from and what the lightmap plans a rectangle for, so the two agree about every face.
ContactFilter = bool Function(SweptContact contact)
Whether a contact counts, asked of the collider and the way it faces.
EntityRemap = ({List<String> dropped, Map<String, Object?> save})
The result of remapEntitySave: a document EcsWorld.restore can read, and the names it could not place.
LevelKit = void Function(LevelSketch sketch, LevelRecipe recipe)
A kit: reads a recipe's params and draws into a sketch.
StepSystem = void Function(StepContext step)
Work an application adds to a step it does not own.

Exceptions / Errors

DataSourceTraceFormatException
Thrown when a DataSourceTrace cannot be read back at all.
DemoFormatException
Thrown when a demo cannot be read at all.
DigestTraceFormatException
Thrown when a DigestTrace cannot be read back at all.
LevelFormatException
Raised when a document is not a level, or is one this build cannot read.
SnapshotFormatException
Thrown when a snapshot cannot be read at all.
StepTimeTraceFormatException
Thrown when a StepTimeTrace cannot be read back at all.
VisibilityFormatException
Thrown when a visibility table cannot be read at all.