ShelterLab Mechanics is a 2-D physics lab. Build a scene by placing bodies, joining them with pin or weld connectors, attaching springs, strings, or chains, and dropping them into static surfaces (the ground, ramps, tables, bowls). Press Run to watch it play out.
Mechanics is the first of a planned ShelterLab family — Thermo and Fluids will follow as separate labs.
All lengths are in metres, masses in kg,
forces in N. Default gravity is 9.8 m/s²
downward. One second of simulation matches one second of clock time at 60 fps.
Resetting returns every body to the position and velocity it had at t=0, so
any run is reproducible from the same starting scene.
| Control | Purpose |
|---|---|
| ▶ Run / ⏸ Pause | Start or pause. Keyboard: Space |
| ↺ Reset | Return every body to its initial state. Keyboard: R |
| ◀ Step back / ▶ Step | Rewind or advance by n frames. Keyboard: , / . |
| n fr | Number of frames per step (one frame = 1/120 s). |
| ↖ Select | Default tool — click and drag objects. Keyboard: 1 |
| ⚙ World | Open World settings: gravity, ground, damping, presets. |
| ⬡ Body | Open the body sub-panel for placing blocks, disks, springs, carts, etc. |
| ⊕ Anchor | Place a fixed world point. Keyboard: 3 |
| ◫ Constraint | Open the constraint (surface) sub-panel. |
| ↑ Forces | Open the forces sub-panel: thruster, drag, profile force, winch. |
| 💾 Save | Save the scene to the database (login required). |
| 📂 Load | Load a saved scene. Browsing is open; rename and delete need login. |
| ⬇ Export / ⬆ Import | Save / load a .physics file on your computer. |
Click ⚙ Settings to open scene-wide controls. The panel is split into Basic Settings at the top and Advanced Settings at the bottom, with sections for Default Contact Properties, Trails, and Custom Contact Properties in between. Most rows are pinnable to the cockpit — click the 📌 Pin button at the top of the panel to reveal the pin gutters.
| Setting | Description |
|---|---|
| Preset | Pick a predefined world (Lab Station, Earth, Moon, Mars, Jupiter, deep space, air table, large-scale variants). |
| Grid scale | Zoom in or out. Same as the keyboard zoom shortcuts. |
| New object scale | Multiplier applied to default sizes and force/stiffness magnitudes when placing new objects. 1 = demo scale; 0.125 = lab-table scale (the Lab Station preset). |
| Gravity (m/s²) | Gravitational acceleration. Takes effect immediately, even while running. |
| Ideal pulleys | When on, pulleys are massless with one uniform tension per rope (textbook). Off = pulleys have inertia and rope tension can differ across each pulley. |
| Ground | Toggle the solid floor on or off. |
| Labels | Show object labels (Block 1, Disk 2, etc.) on the canvas. |
| Telemetry | Show or hide the live telemetry strip below the toolbar. |
| Default μ static / kinetic | Friction defaults applied to any contact pair without a custom value. |
| Default elasticity | Bounciness default for any contact pair without a custom value. |
| Damping (1/s) (Advanced) | Global per-body velocity decay, like air resistance applied to every object regardless of contact. Higher = bodies coast to a stop sooner. 0 = ideal (no decay). |
| No rotation (Advanced) | Zeroes every body's angular velocity each step — bodies translate but don't spin. A blunt stability tool useful while diagnosing other problems. |
| Lock object drag in embed (Advanced) | When this model is loaded in embed.php, viewers cannot drag bodies; they can still adjust pinned cockpit parameters. |
| Substep rate (Hz) (Advanced) | How many physics substeps run per simulated second. Higher = more stable contacts and welds; defaults to 120. |
| Constraint iters (Advanced) | Solver iterations per substep. Higher = stiffer welds and less drift at increased CPU cost; defaults to 10. |
| Solver mode (Advanced) | Dynamic (default) or Static. See the next subsection. |
Two different solvers live behind the same Run button.
The solver-mode picker is pinnable to the cockpit dashboard so a single classroom model can be flipped between motion and statics views without opening Settings.
After computing the reactions, the solver validates them physically and surfaces any failures in the Status panel:
The static solver handles gravity, pin and weld connectors, rod endpoint attachments, body↔constraint surface contacts, constant thruster forces, spring/bungee forces evaluated at the current geometry, and direct (no-pulley) strings between bodies/anchors. A string's tension is shown as a "T = … N" label at its midpoint; a negative T means the configuration would require the string to push, which is reported as an error.
Models that contain chains, motors (winch or piston), profile forces, drag forces, rotation axes, or turntables are not yet supported — switching to Static with any of these present produces a "feature unsupported" diagnostic and the solver refuses. Strings routed through pulleys are also skipped (with an info note, not a refusal). Use Dynamic for those.
Live readouts for every body (and selected motors, springs, strings, etc.): position, displacement, velocity, speed, velocity angle, acceleration, angular velocity, angular acceleration. Y is positive upward in displayed values. Toggle the strip from the World panel.
Shows body and connector counts, plus transient confirmation messages.
When a saved scene loads, its name appears centred above the canvas. The first edit appends “ - Revised” in amber so you can see at a glance whether the on-screen scene matches the saved version. Saving (or pressing ↻ Reload) clears the flag.
Click ⬡ Body to open the body sub-panel, choose a type, then click the canvas to place it. Some types (rod, pole, pulley, bungee, string, chain) place by dragging to set their endpoints. The simulation pauses automatically while you're placing. After placing, the tool reverts to Select.
Hold Option while placing or dragging to snap to the grid. Hold Ctrl to suppress all snaps.
A solid rectangle. Default 2 × 1 m, 1 kg.
Three round bodies that share a circular footprint but differ in how their mass is distributed (which affects how much they resist spinning).
A long thin rigid bar (rectangle plus rounded end caps). Useful as a structural rail or attachment member. Drag from one endpoint to the other to place. Width is derived from length (length / 20).
A round body with a hub-and-spoke look, optimised for rolling. Default radius 1 m, 1 kg. Placing a wheel on top of a block automatically pins it to that block.
A linear spring–damper with two endpoints. Pulls back toward its rest length and resists rapid stretching.
A one-sided elastic — pulls when stretched but goes slack and exerts no force when shorter than its rest length. Place by selecting Bungee from the body sub-panel, then click two endpoints (body, anchor, or anywhere in space). Drawn as an amber coil that droops when slack.
A small point body that serves as a junction for tying strings, bungees, chains, and connectors together. Drawn as a brown dot. Knots have no extent, no surface contact, and no body-body collision — they're pure attachment points that move under the net force of whatever pulls on them.
A rigid bar that maintains a fixed length. Drag to set its endpoints. With zero mass, a rod acts as an ideal inextensible link between two bodies; with mass, it's a full rigid bar that collides with disks and blocks.
A block-shaped frame for compound assemblies. Default 4 × 2 m, 1 kg. Drawn as a rounded grey-brown rectangle with a dashed inner outline.
A pre-assembled vehicle: chassis (2.4 × 0.6 m, 5 kg) with two pinned wheels (radius 0.35 m, 1.2 kg each). Placed and selected as a single unit.
A two-DOF body: a cylindrical casing with a piston head that slides inside. The head carries a wrist pin at the open face for connecting a rod.
A spring launcher. Three-sided tube (closed at the back) with a sleeved spring and a sphere. Pre-runtime, drag the sphere toward the closed end (or type a Cock distance) to load the spring. On Run the spring releases and pushes the sphere out the open end.
A first-class open container — three rigid walls with no top. Drop other bodies in; tip it over to dump them out. Resizable on the canvas.
A block-shaped body with a live signed-force readout displayed alongside it on the canvas. Useful for measuring contact loads, pull-tests, or any force passing through it.
A spring with a calibrated dial. Shows the deflection as a signed force reading. Drop a body onto it for a weight readout, or pull through a string for a tension readout.
A measurement annotation between two world points. Click once to set the first endpoint, click again to set the second; the live distance label appears at the midpoint and updates whenever either endpoint moves.
A flexible chain of equal-length links. Drapes over surfaces, slides under gravity, can be pinned at either or both ends. Place by selecting ⛓ Chain and clicking the canvas.
When a chain is selected, three handles appear on the canvas:
| Handle | Action |
|---|---|
| Blue ring at each free endpoint | Drag to resize that leg; bend and the opposite endpoint stay fixed. |
| Amber diamond at chain centre | Drag to bend the chain; both endpoints stay fixed. |
| Blue dot above centroid | Drag to rotate the whole chain (only when both endpoints are free). |
Chains collide with constraint surfaces (and the ground). Chain ↔ constraint friction is per-pair: select a chain and a constraint together to expose μstatic / μkinetic / Elasticity sliders. Chains pass through bodies; chain ↔ body collision is not currently implemented.
Pulleys redirect strings; strings are inextensible ropes. Together they model rope-and-pulley systems with mechanical advantage.
A wheel that redirects a string. Click to place. A pulley can be mounted to a body or anchor (it tracks that object's motion) or left free in space.
An inextensible rope between two endpoints, optionally routed through any number of pulleys.
Constraints are static surfaces — they don't move under physics. Click ◫ Constraint to open the sub-panel.
The solid floor at the base of the world. Toggle from the World panel; not placed from this sub-panel. There is at most one ground per scene.
A solid rectangular block. Default 10 × 1.5 m.
A flat top with two legs (inverted U). Default 6 × 2 m. Top and leg thickness stay constant (~0.3 m) regardless of overall dimensions, so resizing changes the spans without changing how chunky the structure looks.
A right-triangle slope with a smooth curve at the base where slope meets horizontal. Default 10 × 5 m, slope facing right. Click to place the top-left corner.
Rectangular outer profile with a semicircular inner cavity — a half-pipe open at the top. Disks and wheels engage the curved inner arc smoothly; blocks and poles bounce off the rectangular outer walls only.
A vertical loop-the-loop, drawn as a full circle with short flat tangent stubs at the entry and exit. The loop emulates a real-world helical track where the on-ramp and off-ramp are at different depths.
Hollow containers — bodies placed inside stay contained by the inward-facing walls. The box version is a closed rectangle; the circle version is a closed ring. Unlike a bowl, the entire perimeter is walled.
Freehand polygon. Click to add vertices, then either:
After drawing, select the constraint to flip it horizontally or vertically. Drawn polygons can't be resized — redraw if you need different dimensions.
Connectors join two bodies (or a body and an anchor) at a shared point.
Bodies share a position but rotate freely relative to each other (a revolute joint).
Position and relative angle are both locked. The two bodies move as a rigid unit.
Click a connector glyph to select it; Remove connector deletes it. Drag the glyph to reposition the joint along either body — the cursor snaps to disk centres, pole / rod end caps, and pole / rod centrelines, with free placement otherwise. Both endpoints update so the joint references the same world location on each body.
External forces act on a target body without any visible coupling. Click ↑ Forces to open the sub-panel.
A constant force at a fixed angle. An arrow on the body shows direction and magnitude. Click a body to attach.
Speed-dependent retarding force, opposite to velocity. Useful for modelling air or fluid resistance.
F = b·v).F = c·v²).A force whose magnitude is a tabulated function of time. Click a body to attach, then use the Edit profile button in the sidebar to open a small canvas where you click to add control points.
A motor that reels a string in or out. Click to place; attach a string to the winch using the String tool.
Two world-level objects let you study problems with circular motion. Open the Objects panel and look for the World section. Only one of the two may exist in a model at a time — pick the view that fits the problem.
Use this for banked turns, swing-ride pendulums, and any setup where you want to see the equilibrium pose of an object in a rotating system. The view is a side-on cross-section: the axis appears as a vertical dashed line on the canvas, and gravity acts downward as usual. The ⊙ / ⊗ markers on either side show which way material is moving in three dimensions (out of / into the page) for the chosen ω. Two short "sticks" attached to the rotating frame swing into view at the upper and lower thirds of the canvas; their length and the depth-shaded end dot indicate the rate and direction of rotation.
Alongside the cross-section, a top-down companion view renders the same scene as seen from directly above. By default it sits to the right of the axis with the axis-projection at its centre. Each mass-carrying body traces its circular orbit at radius |b.x − axis.x| from the axis. Blocks, disks, spheres, and rings render as full silhouettes that rotate with the frame; other body types (springs, rods, poles, buckets, etc.) appear as thin dashed trajectory rings plus a small body-coloured dot at the current phase. Anchors, pulleys, and strings project too — threaded strings show their full routed path from above. Trails enabled in the side view automatically appear in the top view with the same colour and number label; one Erase clears both.
In the side-view cross-section, the third dimension (the actual direction of circular motion) is perpendicular to the canvas, so the Coriolis effect is invisible in the side panel — a body in equilibrium just sits at its banked-turn angle. The top-view companion makes the circular motion visible, and trails reveal the orbital path. For pure Coriolis demonstrations with a body sliding on a rotating surface (top-down only, no banked-turn cross-section), use the turntable instead.
A kinematic rotating disk seen from directly above. Place bodies (block, disk, sphere) on top of it; they experience friction against the moving surface and get carried along, deflect into curved paths, or spiral outward — depending on ω, the friction coefficients, and where the body starts.
A body cannot be placed such that its footprint covers the turntable's centre. This avoids a configuration where the friction model would otherwise produce visibly wrong results.
Click any object to see its editable properties. Fields update the simulation immediately; dimension fields enforce physical limits (minimum side lengths, maximum aspect ratios).
Shift-click a second object to show contact properties for the pair:
| Property | Description |
|---|---|
| μ static | Static friction coefficient. Default 0 (frictionless). |
| μ kinetic | Kinetic friction coefficient. Default 0. |
| Elasticity (0–1) | Bounciness of collisions. 0 = perfectly inelastic, 1 = perfectly elastic. |
| Sticky | Available for body–body pairs (block–block, disk–disk). When on, the two bodies stick on first contact and behave as a single rigid unit while in contact. |
| Apply to all | Applies any change to every pair involving the same body type. For constraints, applies to all constraints regardless of type. |
Contact properties are stored per pair and saved with the scene. Friction and elasticity are pair properties only — they're never inferred from a body's individual settings.
Chain ↔ constraint pairs are configurable here too: select a chain plus a constraint to set per-pair friction and elasticity. Friction is applied per node, so total drag scales naturally with how much of the chain is in contact with the surface.
Select a cart and a constraint together to open Wheel Contact Properties. Changes apply to both wheels simultaneously.
A summary count of bodies, compound bodies, constraints, and anchors. Drag any selected object to move the whole group.
| Handle | Appears on | Action |
|---|---|---|
| Diamond above | Blocks, tables, ramps, drawn constraints | Drag to rotate. Option snaps to 15° steps. |
| ↔ (right edge) | Blocks, tables, ramps | Drag to resize width. |
| ↕ (bottom edge) | Blocks, tables, ramps | Drag to resize height. |
| Circle (right of centre) | Disks, wheels, pulleys | Drag to resize radius. |
| Endpoint circles | Springs (free endpoints) | Drag to reposition. Rest length updates on release. |
| Bounding box circle / diamond | Cart, plunger | Rotate (circle) or scale (diamond) the whole compound. |
| Chain handles | Chain | Resize a leg, bend the chain, or rotate it. See the Chain section. |
The Cockpit is a panel of cards exposing runtime controls — sliders, toggles, dropdowns — for selected fields, so you can adjust them while a simulation is running. Cockpit exposure is fully opt-in: a fresh body shows no cockpit content until you pin something.
Every editable property row in the sidebar has a small pin gutter to its left. By default the pin gutters are hidden — click the 📌 Pin button at the top of the Properties panel (or the matching button at the top of the Settings panel) to reveal them across the page. Click a gutter dot to pin that row for the cockpit; click again to unpin. Pinned rows show a subtle accent so you can see at a glance which fields are exposed.
When at least one row is pinned on an entity, a card titled with the entity (e.g. Cart (ID=4)) appears in the cockpit, with one widget per pinned field. All widgets are live — changes take effect immediately during a run, no Reset required.
World-level Settings rows — gravity, damping, ground, ideal pulleys, default contact properties, substep rate, etc. — are pinnable too. The pinned values appear in a World card in the cockpit. Changes flow both ways: editing the cockpit slider updates the Settings panel, and editing in Settings updates the cockpit.
The Show in cockpit checkbox in each property panel hides or shows the entity's whole card without unpinning anything. Useful for temporarily decluttering during a long run.
Disks, spheres, and rings can leave a trail of their past positions on the canvas. The fastest way to turn one on is the Show trail checkbox in the disk's property panel — checking it also surfaces the body in the cockpit's shared Trails card, which has a per-body motion-trail toggle, per-body Erase, and an Erase-all button. If a rotation axis is present, trails automatically project to the top-view companion as well, with the same colour and number label; erasing clears both views in one click.
Strings have their own bespoke cockpit card with Detach end 1, Detach end 2, and Detach both buttons — useful for triggering releases mid-simulation. Enable from the string's property panel.
The telemetry strip can chart any numeric channel in real time. Beyond the standard body channels (position, velocity, acceleration, ω, α, mass) the system exposes:
A status pill near the step controls (● Status) shows whether the simulation is in good shape, has warnings, or has had to halt because numerical results stopped being trustworthy. Click the pill to open the Health panel.
| Indicator | Meaning |
|---|---|
| Green dot | Healthy. No advisories. |
| Amber dot | Advisory — the model has a configuration that can lead to soft or jittery results (e.g. a very heavy block on a very light support). Sim continues. |
| Red dot | Halted. The simulation stopped because results were no longer reliable. Open the panel to see why. |
The Health panel lists active warnings and which entities are involved. Most advisories trace back to a wide spread of masses (light supports under heavy loads), or a spring tuned much stiffer than its load can stably bear. See Stability tips for the knobs that usually fix these.
Real-time playback (1 s sim ≈ 1 s clock at 60 fps). The scene cannot be edited while running — pause first.
Returns every body to its initial position, angle, and velocity. Elapsed time resets to zero. Constraints, anchors, connectors, and strings are unaffected.
Each press advances or rewinds by n frames, where n is set in the field next to the step buttons. One frame = 1/120 s. History is recorded automatically during running and during manual stepping; the buffer holds about 20 seconds of running history.
Right-click any object and choose Duplicate, or select an object and use the keyboard tool. A copy follows the cursor; click to drop. All properties — including initial velocities, contact pairs, and pin attachments — are preserved.
Save records the complete scene to the server database; saving requires a login. Load opens the list of saved scenes; browsing and loading are open to all users. Logged-in users can rename and delete entries.
Export and Import let you save and load
scenes as .physics files on your computer, independent of the
server.
With one or more bodies selected, the arrow keys move them by exactly one minor-grid cell at the current zoom. Shift+arrow nudges by 10 cells (≈ one major cell); Ctrl+arrow nudges by one screen pixel for fine positioning.
Right-click an object and choose Delete, or select and press Del / Backspace. Right-clicking a cart selects the whole compound body for deletion.
Right-click any object for duplicate, delete, and (for bodies) front-to-back layering:
Z-order also drives click-to-select: clicking a body that's drawn in front selects it even when overlapping others. Affects body-vs-body layering only.
Most stability problems trace back to two situations: very light bodies carrying very heavy loads, and contact between bodies whose mass difference is large. The knobs below are the usual fixes — try them in order.
When the mass ratio between two interacting bodies grows past a few dozen to one, joints can flex visibly under load and contacts can jitter. The Health monitor flags large mass spreads and tells you which bodies are involved. Two practical fixes:
The Damping knob in the World panel applies a gentle decay to every body's velocity each step. A small value (0.1–0.5) helps lab-bench scenes coast to rest cleanly without affecting the dynamics meaningfully. Higher values (1–5) are useful for diagnosing — if a buggy oscillation disappears with damping turned up, you know you're chasing an oscillation problem rather than a contact problem.
The No rotation toggle zeroes every body's spin each step. Useful as a temporary check — if a model misbehaves only when bodies are free to rotate, the problem is rotational. Wheel and pulley motors don't drive their loads while this is on.
For block–block or disk–disk pairs that should never come apart in your scene (e.g. a stack rigidly carried as cargo), enable Sticky in the contact properties. The pair locks together on first contact and behaves as one rigid object. Faster and more stable than relying on friction.
| Key | Action |
|---|---|
| Space | Run / Pause |
| R | Reset |
| . | Step forward n frames |
| , | Step back n frames |
| 1 | Select tool |
| 2 | Block tool |
| 3 | Anchor tool |
| 4 | Delete tool |
| 5 | Rectangle constraint |
| 6 | Thruster |
| + / = | Zoom in |
| − | Zoom out |
| Del / Backspace | Remove selected object(s) |
| Option (hold) | Snap to grid while placing, dragging, rotating |
| Ctrl (hold) | Suppress all snaps during placement and drag |
| Shift+click | Toggle an object in or out of the selection |
| Arrow keys | Nudge selected bodies by one minor grid cell |
| Shift+arrows | Nudge by 10 minor cells (≈ one major cell) |
| Ctrl+arrows | Nudge by one screen pixel |
| Esc | Cancel freehand drawing |
| Cmd/Ctrl+Z | Undo |