---
title: "2D physics in C#"
url: https://recursiveai.org/onephysics/cookbook/2d-physics/
description: "2D physics in C#: create a world, add a ground, a stack of boxes and a bouncing ball, step it at 60 Hz and read positions back, with results that are the same bits on every machine. Runnable code, with OnePhysics (preview)."
version: "0.4.0-preview.1"
---

# 2D physics in C#

Create a `PhysicsWorld2D`, add bodies with one call each, and call `Step` once per frame with a fixed time step. The program below builds a stack of five crates, knocks it down with a rubber ball, and prints where everything is after each simulated second.

```shell
dotnet new console -o Physics2D && cd Physics2D
dotnet add package RecursiveAI.OnePhysics --version 0.4.0-preview.1
```

Put this in `Program.cs` and run `dotnet run`:

```csharp
using RecursiveAI.OneMath;               // Vector2F, Vector2D
using RecursiveAI.OnePhysics;            // BodyType
using RecursiveAI.OnePhysics.Physics2D;  // PhysicsWorld2D, Body, Material2D

var world = new PhysicsWorld2D();        // gravity -9.81 m/s² along y

// The ground: a static 40 m x 1 m box whose top is at y = 0.
world.AddBox(new Vector2F(40, 1), at: new Vector2D(0, -0.5), type: BodyType.Static);

// Five 1 m crates stacked at x = 5.
var crates = new List<Body>();
for (int i = 0; i < 5; i++)
    crates.Add(world.AddBox(new Vector2F(1, 1), at: new Vector2D(5, 0.5 + i)));

// A rubber ball thrown from the left at 25 m/s.
Body ball = world.AddCircle(0.5f, at: new Vector2D(-5, 2),
                            material: Material2D.Rubber);
ball.SetLinearVelocity(new Vector2F(25, 1));

const float dt = 1f / 60;                // one fixed step per frame
for (int frame = 1; frame <= 240; frame++)
{
    world.Step(dt);
    if (frame % 60 != 0) continue;
    Vector2D b = ball.Position, top = crates[4].Position;
    Console.WriteLine($"t={frame / 60}s ball ({b.X:F2}, {b.Y:F2})  "
        + $"top crate ({top.X:F2}, {top.Y:F2})");
}
Console.WriteLine($"world hash {world.ComputeHash():X16}");
```

```text
t=1s ball (0.96, 2.01)  top crate (4.71, 4.77)
t=2s ball (-4.46, 1.27)  top crate (3.71, 1.37)
t=3s ball (-9.84, 1.11)  top crate (3.30, 0.50)
t=4s ball (-15.26, 0.60)  top crate (3.30, 0.50)
world hash 691636F9904A86B1
```

The ball hits the stack, knocks the top crate off and bounces back to the left; by t=3s the crate lies on the ground (y = 0.5, its half height). Sizes are full extents in meters, positions are `double` (`Vector2D`) and everything else is `float`. Bodies are dynamic unless you pass `BodyType.Static` or `Kinematic`, and they fall asleep when they come to rest. Draw each body at its `Position` and `Angle` after every `Step`.

The world hash is the point of OnePhysics: run the same steps on another OS, CPU or in the browser and it prints the same hash, so a lockstep or rollback game stays in sync. See [Rollback physics in C#](https://recursiveai.org/onephysics/cookbook/rollback/).

## What else is there

- **Shapes:** `AddCircle`, `AddBox`, `AddCapsule`, `AddPolygon`, `AddSegment` and `AddChain` for terrain.
- **Materials:** `Material2D.Rubber`, `Ice`, `Metal` and `Wood`, or `new Material2D(friction, restitution, rollingResistance)`.
- **Forces:** `ApplyForce`, `ApplyImpulse`, `ApplyTorque`, `SetLinearVelocity`.
- **Collisions:** events such as `OnCollisionEnter` ([events and sensors](https://recursiveai.org/onephysics/cookbook/events-and-sensors/)), raycasts and overlap tests ([Raycasts in 2D physics](https://recursiveai.org/onephysics/cookbook/queries-and-layers/)), and joints ([Joints](https://recursiveai.org/onephysics/cookbook/joints/)).
- **Characters:** `AddCharacter` gives a character mover that walks, stands on slopes and resolves its own contacts: see [getting started](https://recursiveai.org/onephysics/docs/getting-started/).

## Limits

- **OnePhysics is a preview** (0.4.0-preview.1, .NET 10) and is paused for now. The API and results may change between previews, and a snapshot or replay from one preview doesn’t load in the next.
- **One fixed time step.** Use one `dt` for the whole session; a variable frame time changes the results.
- **2D is the supported engine.** The 3D engine is a preview inside the preview: see [the 3D preview](https://recursiveai.org/onephysics/cookbook/3d-preview/).
