docs/style.md, docs/glossary.md, style checks DOC010–DOC023 and docs report; the site in a light theme; the Editor, Aego Script, Gameplay, Physics, Scenes, Rendering, Tools and Reference sections rewritten.
13 KiB
id, try, try_select, icon, group, group_title, group_icon, group_order, title, order
| id | try | try_select | icon | group | group_title | group_icon | group_order | title | order |
|---|---|---|---|---|---|---|---|---|---|
| physics | try/Body2D.aescene | physics.Body2D | cat.physics | physics | Physics 2D | cat.physics | 50 | Physics 2D | 1 |
Physics 2D
Aego simulates 2D rigid bodies with its own solver. A body is a node with Rigid Body 2D; colliders on that node and its children give it a shape. Scripts react to contacts and query the world.
Physics runs during Play and in aego run. In edit mode nothing moves, and the Scene View shows collider outlines and their problems.
To try it:
- Create → Physics → Rigid Body gives a falling box.
- Create → Physics → Static Collider gives a floor for it.
- Press Play.
id: physics/units icon: view.grid parent: physics order: 1 title: Units and axes
Units and axes
Physics works in world units. One unit is whatever size you choose for your game; shapes between 0.1 and 10 units behave best. render.pixelsPerUnit in project.aego is used only for the default size of imported sprites, the default Camera2D.Zoom and Snap to Sprite; physics never reads it, so changing it does not change how anything falls.
Axes follow the 2D scene: +X right, +Y down, positive angles turn clockwise. Default gravity is (0, 9.81), pointing down the screen. Normals and velocities in events and queries use the same axes, so a floor under a body has a normal with a negative Y.
id: physics/components try: try/CircleCollider2D.aescene try_select: physics.CircleCollider2D icon: comp.rigidbody parent: physics order: 2 title: Components
Components
These components make a node part of the simulation. Each has its own page in the reference with every field.
| Component | Purpose |
|---|---|
| Rigid Body 2D | makes the node a body: static, kinematic or dynamic |
| Box, Circle, Capsule, Polygon and Edge Collider 2D | shapes |
| Distance Joint 2D | keeps a distance to the Target body, rigid or springy |
| Revolute Joint 2D | pins to the Target body at Anchor, with an optional limit and motor |
Every collider has Offset, IsTrigger, Friction, Restitution and Density.
- Capsules lie along the node's local X axis.
Lengthincludes the caps. - Polygons are convex, with 3 to 8 points.
- Edge colliders are polylines for level geometry.
Loopcloses them.OneSidedmakes them solid only from the side the points wind towards: points from left to right are solid from above.
A body's Type decides how it moves: static never moves, kinematic moves by its velocity and ignores forces, dynamic reacts to forces and contacts. Its velocity and whether it is awake are runtime state, listed on the Rigid Body 2D page.
id: physics/hierarchy icon: panel.hierarchy parent: physics order: 3 title: Bodies and hierarchy
Bodies and hierarchy
A collider belongs to the nearest node at or above it that has a Rigid Body 2D. One body can therefore be built from several child nodes, each with its own collider; mass, centre of mass and inertia come from all of them. A collider with no body above it becomes a static body of its own.
The collider's position, rotation and uniform scale relative to its body are baked into the shape. Boxes and polygons also take non-uniform scale; circles and capsules need a uniform one and report PHY001 otherwise. Nodes under a 3D parent are not simulated (PHY005).
The transform of a moving body belongs to physics. Write it from FixedUpdate or through Teleport and it is applied as a teleport at the next step, keeping the velocity. A write from Update is reported once per body (PHY007) and applied at the next step. Static and kinematic bodies follow their node every step. Reparenting a moving body during Play recreates it with the same world pose and velocity (PHY006).
id: physics/layers icon: view.overlays parent: physics order: 4 title: Layers
Layers
Up to 32 named layers and the pairs that collide are declared in project.aego or in Project Settings → Physics:
physics {
layers=[Default, Ground, Player, Enemy]
collide {
Player=[Ground, Enemy]
Enemy=[Ground, Player]
}
}
The matrix is symmetric: Player=[Enemy] also lets enemies hit players. Without a collide block every layer collides with every other. An unknown layer name in collide is a load error.
A body stores its layer as an index, so renaming a layer keeps every body on it; clearing a name keeps the index. Two shapes collide when both bodies' Mask accept the other's layer and the matrix allows the pair. Changing a layer or mask during Play ends the contacts it forbids in the next step.
id: physics/events icon: panel.events parent: physics order: 5 title: Events
Events
Declare a method with one of these names in any script on the body node or on the collider node:
func OnCollisionEnter(other NodeRef, c physics.Contact)
func OnCollisionStay(other NodeRef, c physics.Contact)
func OnCollisionExit(other NodeRef, c physics.Contact)
func OnTriggerEnter(other NodeRef)
func OnTriggerExit(other NodeRef)
Both participants get the event, each from its own side. other is the other body's node; c.Normal points from the other body into the receiver, so a floor under you reports c.Normal.Y < 0. c.SelfCollider and c.OtherCollider name the collider nodes. Events run after the physics step, before script.events_fixed ends the fixed tick.
OnCollisionStay runs every step while two bodies touch, and only when some script handles it; prefer Enter/Exit counters. Exit also comes when a body is destroyed or disabled; other.IsAlive() is then false.
Destroying nodes inside a handler is safe: the removal happens after all handlers ran.
id: physics/scripting icon: file.script parent: physics order: 6 title: Scripting
Scripting
Scripts move bodies through the Rigid Body 2D component and ask the world what is where through aego/physics.
body := node.Get<Body2D>()
v := body.Velocity
body.SetVelocity(Vec2{x * Speed, v.Y})
body.ApplyImpulse(JumpImpulse)
Moving a body
- Forces and torque act during the next physics step. Call
ApplyForceandApplyTorquefromFixedUpdate. - Impulses change the velocity at once, scaled by mass. They suit jumps and hits.
MoveTodrives a kinematic body to a pose by the end of the next step.Teleportmoves a body without sweeping and keeps its velocity.
Every method is listed on the Rigid Body 2D page.
Queries
Raycasts, line casts and overlap tests ignore the caller's own body and skip triggers. They work only during Play. Functions that fill an out slice write at most len(out) entries, so size the slice once with append and reuse it.
Every function is listed on the aego/physics page.
id: physics/settings icon: panel.settings parent: physics order: 7 title: Settings
Settings
Project Settings → Physics edits the physics block of project.aego: gravity, substeps, iterations, contact stiffness, sleep thresholds, layers and the matrix. An empty or zero field takes the engine default, shown greyed out. Substeps and both iteration counts accept 1 to 64. Changes apply at the next Play.
Tall free-standing stacks and fast motors need the stiff profile: substeps=8 and contactHertz=60, at about twice the solver cost. At the default 30 Hz with 4 substeps a free column stands up to about twelve boxes; bonded brick layers stand much higher.
id: physics/editor try: try/EdgeCollider2D.aescene try_select: physics.EdgeCollider2D icon: tool.move parent: physics order: 8 title: Editor tools
Editor tools
The editor draws colliders, contacts and forces and lets you shape colliders with handles. These tools work in the Scene View, and some of them over the running game.
Handles
Select a node with a collider to drag its sides, radius, length or vertices. Double-click an edge of a polygon to add a vertex; Alt-click a vertex to remove it. Joints show anchors on both bodies. Every drag is one Undo step.
Snap to Sprite in the Inspector of box, circle and capsule colliders fits the shape to the node's sprite.
Overlays
- The Physics menu turns on the debug overlay: shapes, contacts, bounding boxes, joints, islands and the broadphase tree. In edit mode only shapes are drawn.
- Vectors (
Vin the Scene View) draws velocity, angular velocity, forces, contact impulses, gravity and script fields with@export(gizmo="vector"). Drag the tip of a field arrow to change the value. - Game View → Overlays draws the same layers over the running game, with the game camera.
Problems and profiling
- Problems lists collider and joint errors with a link to the node. Broken geometry blocks Play.
- Profiler → Physics shows bodies, pairs, islands and the time of each stage during Play.
id: physics/lifecycle icon: panel.history parent: physics order: 9 title: Lifecycle
Lifecycle
What happens to bodies, shapes and contact events when the scene changes during Play.
| Action during Play | Result |
|---|---|
| Destroy a body node | its shapes leave the world at the next step, Exit events in the same step |
| Destroy a collider child | the shape is removed, mass and inertia recomputed |
| Disable a node | all shapes below it switch off with Exit events; enabling brings Enter at the next step |
| Remove Rigid Body 2D | child colliders become static bodies |
| Remove a collider | the shape is removed with Exit |
| Change layer or mask | forbidden pairs end in the same step |
| Change a trigger flag or the geometry | contacts of the shape end, new ones begin at the next step |
| Add a body or collider | picked up at the next step, starting at rest |
| Reparent a moving body | recreated with world pose and velocity, PHY006 |
| Script hot reload | the world keeps running, handlers are rebound by name |
| Native rebuild | the play world is recreated with the editor |
| Stop | the world is destroyed without Exit events |
id: physics/world icon: vec.gravity parent: physics order: 10 title: World
World
The physics world steps all bodies together at the fixed rate, 60 times a second by default, never with the frame time. This page describes how it moves bodies and what the material values mean.
Steps
Each step finds contacts once, then solves in substeps, 4 by default. A substep applies gravity, pushes overlapping shapes apart, moves the bodies and settles the push so it does not turn into a bounce. More substeps give stiffer contacts; see Settings.
A body moves at most a set distance and angle per step. Small fast bodies should set Bullet: their contacts look ahead by the distance they travel in one step.
Every body and shape is checked when it is made. Invalid numbers, negative sizes, concave polygons and zero-length segments are rejected with an error, and the world stays as it was.
Materials
| Material | Meaning | When two shapes touch |
|---|---|---|
Friction |
0 is ice, 1 is rubber | sqrt(a·b) |
Restitution |
0 stops, 1 bounces back at full speed | max(a, b) |
Density |
mass per square unit | — |
Very slow bounces are not restituted, so resting bodies stay at rest.
Sleep
A group of touching bodies falls asleep when all of them have moved slowly for a while. A contact with an awake body, a force, an impulse, a teleport or a new joint wakes the group.
Determinism
The same game on the same CPU with the same input gives the same result every time. Rewinding Play in the editor relies on this.
id: physics/pitfalls icon: status.warning parent: physics order: 11 title: Common mistakes
Common mistakes
These are the mistakes that most often make physics feel wrong. Each one names what you see and what to change.
A dynamic body jitters when moved
Moving a dynamic body with SetPosition from Update fights the solver. Use SetVelocity, forces or Teleport from FixedUpdate.
A jump is sometimes missed
input.Pressed is true for one frame, and a frame may have zero or two fixed steps. Read it in Update and act in FixedUpdate, or use input.Down.
A circle collider reports a problem
Circles and capsules need a uniform scale. Change the collider's fields instead of stretching the node.
Objects fall through thin floors
Mark small fast bodies as Bullet, or make the floor thicker.
Tall towers wobble
Use the stiff profile in Settings, stagger the boxes like bricks, or build the tower as one body.
Nothing collides
Check both bodies' masks and the layer matrix, and that the node is 2D and not under a 3D parent.
Motion feels floaty
Gravity 9.81 assumes a unit is about a metre. A 64-pixel sprite at zoom 64 is one unit.

