Agent skill

Avian

by nolantait in nolantait/bevy-starter

Reference for Avian physics engine — rigid bodies, colliders, joints, spatial queries, collision events, character controllers, and debug rendering.

MITAuto-check passed

Install Avian

skills CLI
$ npx skills add nolantait/bevy-starter --skill avian -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install nolantait/bevy-starter avian --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/nolantait/bevy-starter.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/avian .claude/skills/avian && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
avian
GitHub stars
132
Token cost
~3k tokens
SKILL.md length
246 words
Files
1
Skills in repo
24
Repo updated
First seen
Licence
MIT

At a glance

Reference for Avian physics engine — rigid bodies, colliders, joints, spatial queries, collision events, character controllers, and debug rendering.

  • SKILL.md covers Setup, Rigid bodies, Position, Rotation, Transform and Velocity, plus 15 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Avian is an agent skill from nolantait/bevy-starter. Reference for Avian physics engine — rigid bodies, colliders, joints, spatial queries, collision events, character controllers, and debug rendering.

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The repository describes itself as: A minimalist starter for bevy and rust. The licence is MIT.

Example prompts

  • “/avian”

What it can do on your machine

Read from SKILL.md and the folder at commit dd6f56b. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are rust and toml).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Avian loads about 3k tokens when it runs. Until then it costs about 39 tokens; SKILL.md has 246 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~39
When it runs · the whole SKILL.md, loaded when a task matches
~3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from nolantait/bevy-starter at commit dd6f56b, republished under its MIT licence (© nolantait). 246 words, ~2,957 tokens.

Download SKILL.mdSave it as .claude/skills/avian/SKILL.md (or your agent's skills folder).
name
avian
description
Reference for Avian physics engine — rigid bodies, colliders, joints, spatial queries, collision events, character controllers, and debug rendering.
metadata.crate
avian3d
metadata.bevy
0.19

Setup

toml
[dependencies]
avian2d = "0.7"   # 2D
avian3d = "0.7"   # 3D
rust
use avian3d::prelude::*;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, PhysicsPlugins::default()))
        .run();
}

Rigid bodies

Three types: Dynamic (simulated), Kinematic (programmatic), Static (immovable).

rust
commands.spawn(RigidBody::Dynamic);
commands.spawn(RigidBody::Kinematic);
commands.spawn(RigidBody::Static);

Position, Rotation, Transform

Avian syncs Position and Rotation with Bevy's Transform automatically.

rust
fn move_things(mut q: Query<&mut Position>) {
    for mut pos in &mut q {
        pos.x += 1.0;
    }
}

fn rotate_things(mut q: Query<&mut Rotation>) {
    for mut rot in &mut q {
        *rot = rot.add_angle_fast(0.1);
    }
}

Velocity

rust
fn apply_velocity(mut q: Query<&mut LinearVelocity>) {
    for mut v in &mut q {
        v.x += 1.0;
    }
}

fn apply_angular_velocity(mut q: Query<&mut AngularVelocity>) {
    for mut av in &mut q {
        av.0 += 0.1;
    }
}

Forces, impulses, and torque

rust
use avian3d::dynamics::rigid_body::forces::*;

fn apply_forces(mut q: Query<(Entity, &mut ExternalForce, &mut ExternalTorque)>) {
    for (_, mut force, mut torque) in &mut q {
        force.apply_force(Vec3::Y * 10.0);
        torque.apply_torque(Vec3::Z * 2.0);
    }
}

fn apply_impulse(mut q: Query<&mut ExternalImpulse>) {
    for mut imp in &mut q {
        imp.apply_impulse(Vec3::Y * 5.0);
    }
}

Components: ExternalForce, ExternalTorque, ExternalImpulse, ExternalAngularImpulse.

Colliders

rust
commands.spawn((
    RigidBody::Dynamic,
    Collider::sphere(0.5),           // 3D sphere
    Collider::cuboid(1.0, 2.0, 1.0), // 3D box
    Collider::cylinder(0.5, 2.0),    // 3D cylinder
    Collider::capsule(0.5, 1.0),     // 3D capsule
    Collider::cone(0.5, 2.0),        // 3D cone
    Collider::halfspace(Vec3::Y),     // infinite plane
    Collider::compound(vec![]),      // compound of sub-shapes
));

2D colliders (avian2d): Collider::circle(0.5), Collider::rectangle(1.0, 2.0), etc.

Collider from mesh

Requires collider-from-mesh feature (enabled by default):

rust
Collider::from_bevy_mesh(&mesh, &ComputedTriangleMesh::default()).unwrap()
Collider density
rust
commands.spawn((RigidBody::Dynamic, Collider::sphere(0.5), ColliderDensity(1.0)));

Friction and restitution

rust
commands.spawn((
    RigidBody::Dynamic,
    Collider::sphere(0.5),
    Friction::new(0.3),
    Restitution::new(0.5),
));

Collision layers

rust
use avian3d::collision::CollisionLayer;

const PLAYER: CollisionLayer = CollisionLayer::from_bits(1 << 0);
const ENEMY: CollisionLayer = CollisionLayer::from_bits(1 << 1);
const WORLD: CollisionLayer = CollisionLayer::from_bits(1 << 2);

commands.spawn((
    RigidBody::Dynamic,
    Collider::sphere(0.5),
    CollisionLayers::new(PLAYER, WORLD | ENEMY), // member of PLAYER, collides with WORLD and ENEMY
));

Sensors

Colliders with Sensor detect overlap without physical response:

rust
commands.spawn((
    RigidBody::Dynamic,
    Collider::sphere(3.0),
    Sensor,
));

Mass properties

rust
commands.spawn((
    RigidBody::Dynamic,
    Collider::sphere(0.5),
    Mass(5.0),
    CenterOfMass::new(0.0, -0.5),
    LinearDamping(0.5),
    AngularDamping(0.5),
));

Locked axes

Prevent translation/rotation along specific axes:

rust
commands.spawn((
    RigidBody::Dynamic,
    LockedAxes::TRANSLATION_LOCKED_Y | LockedAxes::ROTATION_LOCKED_X,
));

Gravity

rust
fn zero_gravity(mut gravity: ResMut<Gravity>) {
    gravity.0 = Vec3::ZERO;
}

// Per-entity gravity scale:
commands.spawn((RigidBody::Dynamic, GravityScale(0.0))); // no gravity for this body

Continuous Collision Detection (CCD)

Prevents tunneling for fast-moving objects:

rust
use avian3d::dynamics::ccd::*;

commands.spawn((RigidBody::Dynamic, Ccd));

Sleeping (auto-deactivation)

Bodies deactivate when at rest. Configure globally or per-entity:

rust
// Disable sleeping for a specific body:
commands.spawn((RigidBody::Dynamic, SleepingDisabled));

// Default: bodies can sleep automatically.

Collision events

MessageReader (batch)
rust
fn handle_collisions(mut start: MessageReader<CollisionStart>, mut end: MessageReader<CollisionEnd>) {
    for event in start.read() {
        info!("Collision started: {:?} vs {:?}", event.entity, event.other_entity());
    }
    for event in end.read() {
        info!("Collision ended: {:?} vs {:?}", event.entity, event.other_entity());
    }
}

Entities must have CollisionEventsEnabled:

rust
commands.spawn((RigidBody::Dynamic, Collider::sphere(0.5), CollisionEventsEnabled));
Observers (entity-specific)
rust
commands
    .spawn((
        RigidBody::Dynamic,
        Collider::sphere(0.5),
        CollisionEventsEnabled,
    ))
    .observe(|_trigger: On<CollisionStart>| {
        info!("Collision started!");
    });
Accessing collision data
rust
fn read_collisions(mut collisions: Collisions) {
    for contacts in &mut collisions {
        info!("Contacts between {:?} and {:?}", contacts.entity1, contacts.entity2);
    }
}

Joints

Joints spawn as separate entities referencing two bodies:

rust
let body1 = commands.spawn(RigidBody::Dynamic).id();
let body2 = commands.spawn(RigidBody::Dynamic).id();

commands.spawn(FixedJoint::new(body1, body2));
commands.spawn(DistanceJoint::new(body1, body2));
commands.spawn(PrismaticJoint::new(body1, body2));
commands.spawn(RevoluteJoint::new(body1, body2));
commands.spawn(SphericalJoint::new(body1, body2));
Joint configuration
rust
commands.spawn((
    RevoluteJoint::new(body1, body2)
        .with_anchor(Vec3::new(5.0, 2.0, 0.0))
        .with_local_basis1(Quat::from_rotation_z(PI / 4.0)),
    JointDamping { linear: 0.1, angular: 0.1 },
));
Disable collision between joined bodies
rust
commands.spawn((FixedJoint::new(body1, body2), JointCollisionDisabled));
Breaking joints
rust
fn break_joints(query: Query<(Entity, &JointForces), Without<JointDisabled>>) {
    for (entity, forces) in &query {
        if forces.force().length() > 500.0 {
            commands.entity(entity).insert(JointDisabled);
        }
    }
}

Spatial queries

Raycasting
rust
// Component-based (every frame):
commands.spawn(RayCaster::new(Vec3::ZERO, Dir3::X));

fn print_hits(query: Query<(&RayCaster, &RayHits)>) {
    for (ray, hits) in &query {
        for hit in hits.iter_sorted() {
            info!("Hit {:?} at {}", hit.entity, ray.origin + *ray.direction * hit.distance);
        }
    }
}

// SystemParam (one-off):
fn cast_ray(spatial: SpatialQuery) {
    let hit = spatial.cast_ray(Vec3::ZERO, Dir3::X, 100.0, true, &SpatialQueryFilter::default());
    if let Some(hit) = hit {
        info!("Hit {:?} at distance {}", hit.entity, hit.distance);
    }
}
Shapecasting
rust
commands.spawn(ShapeCaster::new(
    Collider::sphere(0.5),
    Vec3::ZERO,
    Quat::default(),
    Dir3::X,
));

fn print_shape_hits(query: Query<(&ShapeCaster, &ShapeHits)>) {
    for (_, hits) in &query {
        for hit in hits.iter() {
            info!("Shape hit {:?}", hit.entity);
        }
    }
}
Spatial query filters
rust
SpatialQueryFilter::default()
    .with_mask(CollisionLayer::from_bits(0xFF))
    .without_entities(&[exclude_entity]);

Character controller

MoveAndSlide system parameter for kinematic character controllers:

rust
use avian3d::character_controller::move_and_slide::*;

fn move_player(mut q: Query<(&mut LinearVelocity, &mut Transform), With<Player>>, time: Res<Time>) {
    let (mut velocity, _transform) = q.single_mut();
    let mut direction = Vec3::ZERO;
    // ... read input to set direction ...
    velocity.0 = direction * 10.0;

    // MoveAndSlide is applied automatically by the plugin if Present is added:
    commands.entity(player).insert(MoveAndSlide::default());
}

Available physics-based third-party crates: bevy_ahoy (kinematic), bevy_tnua (dynamic).

Transform interpolation

Fixes choppy movement from fixed timestep physics:

rust
// Per-entity:
commands.spawn((RigidBody::Dynamic, TransformInterpolation));

// Global default (all rigid bodies interpolated):
fn main() {
    App::new()
        .add_plugins(PhysicsPlugins::default()
            .set(PhysicsInterpolationPlugin::interpolate_all()))
        .run();
}

Components: TransformInterpolation, TransformExtrapolation, TranslationInterpolation, RotationInterpolation, etc.

Debug rendering

rust
fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            PhysicsPlugins::default(),
            PhysicsDebugPlugin::default(),
        ))
        .run();
}

Requires the debug-plugin feature (enabled by default). Use DebugRender::default() to configure.

Physics configuration

rust
fn config(mut gravity: ResMut<Gravity>, mut substeps: ResMut<SubstepCount>) {
    gravity.0 = Vec3::new(0.0, -9.81, 0.0);
    substeps.0 = 10; // more substeps = more accurate but slower
}

Pausing / stepping physics

rust
fn pause(mut physics: ResMut<Physics>) {
    physics.paused = true;     // pause
    physics.paused = false;    // resume
    // Single-step while paused:
    if input.just_pressed(KeyCode::Space) {
        physics.schedule.stepped_state = StepState::StepOnce;
    }
}

Diagnostics

rust
use avian3d::diagnostics::*;

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            PhysicsPlugins::default(),
            PhysicsDiagnosticsPlugin, // requires bevy_diagnostic feature
        ))
        .run();
}

Collision hooks

Filter or modify contacts with CollisionHooks:

rust
use avian3d::collision::hooks::*;

#[derive(Resource)]
struct MyHooks;

impl CollisionHooks for MyHooks {
    fn filter_contact_pair(&self, _entities: (&Entity, &Entity)) -> Option<SolverFlags> {
        // return None to ignore, Some(...) to allow with flags
        Some(SolverFlags::default())
    }
    fn modify_contacts(&self, _contacts: &mut Vec<ContactData>, _entities: (&Entity, &Entity)) {}
}

fn main() {
    App::new()
        .add_plugins(PhysicsPluginsWithHooks::new(MyHooks))
        .run();
}

CCD and speculative collision

rust
commands.spawn((RigidBody::Dynamic, Ccd));

Collider disabled

Temporarily disable a collider without removal:

rust
commands.entity(entity).insert(ColliderDisabled);

Rigid body disabled

rust
commands.entity(entity).insert(RigidBodyDisabled);

Sleep

Bodies at rest auto-sleep. Query sleeping state:

rust
fn check_sleep(query: Query<&Sleeping>) {
    for sleeping in &query {
        info!("Entity is sleeping: {}", sleeping.is_sleeping());
    }
}

Colliding entities

Get entities currently touching a collider:

rust
fn check_touching(query: Query<&CollidingEntities>) {
    for colliding in &query {
        for entity in colliding.iter() {
            info!("Touching entity: {:?}", entity);
        }
    }
}

Physics schedule

Systems run in FixedPostUpdate by default. Order custom systems relative to physics:

rust
app.add_systems(FixedPostUpdate, my_system.after(PhysicsSystems::StepSimulation));

Available system sets: PhysicsSystems::StepSimulation, PhysicsSystems::BroadPhase, PhysicsSystems::NarrowPhase, PhysicsSystems::Solver, etc.

© nolantait, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/avian of nolantait/bevy-starter.

Open the folder on GitHubat commit dd6f56b

Compare with similar skills

Avian next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Avian compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Avian this skillnolantait/bevy-starter132—~3kAutomated safety check: PassMIT
Physical Addressthedaviddias/Front-End-Checklist74k—~574Automated safety check: PassMIT
Aria Hidden Bodythedaviddias/Front-End-Checklist74k—~444Automated safety check: PassMIT
Physics Systemjame581/GodotPrompter805—~3.6kAutomated safety check: PassMIT
Meta In Bodythedaviddias/Front-End-Checklist74k—~541Automated safety check: PassMIT
Pull Request Title and Body Writeropeninterpreter/openinterpreter69k2 repos~1.1kAutomated safety check: PassApache-2.0

Similar skills

  • Physical Address

    thedaviddias/Front-End-Checklist

    A skill your agent uses when auditing local business websites, e-commerce sites, or any site where a physical presence affects trust or local search visibility.

    74k GitHub stars~574 tokensUpdated 3 days ago
    Marketing & SEOAuto-check passed
  • Aria Hidden Body

    thedaviddias/Front-End-Checklist

    A skill your agent uses when reviewing rendered HTML, interactive components, or design-system patterns related to Do not use aria-hidden on the document body.

    74k GitHub stars~444 tokensUpdated 3 days ago
    Frontend & DesignAuto-check passed
  • Physics System

    jame581/GodotPrompter

    A skill your agent uses when working with physics bodies, collision shapes, raycasting, areas, rigid bodies, ragdolls, soft bodies, Jolt physics, and physics interpolation in Godot 4.3+

    805 GitHub stars~3.6k tokensUpdated today
    Game DevelopmentAuto-check passed
  • Meta In Body

    thedaviddias/Front-End-Checklist

    A skill your agent uses when auditing HTML document structure.

    74k GitHub stars~541 tokensUpdated 3 days ago
    Marketing & SEOAuto-check passed
  • Pull Request Title and Body Writer

    openinterpreter/openinterpreter

    Rewrites the title and body of one or more pull requests with gh, leading with why the change was made, then what changed, and describing only the net result.

    69k GitHub starsUsed in 2 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Unity Physics

    gamedev-skills/awesome-gamedev-agent-skills

    Set up 3D physics in Unity 6.3 LTS: Rigidbody movement and forces, colliders, triggers vs collisions, layer-based collision, raycasts, and joints.

    1.4k GitHub stars~2.1k tokensUpdated yesterday
    Game DevelopmentAuto-check passed

More from nolantait/bevy-starter

All 24 skills in this repo
  • Bevy Events

    nolantait/bevy-starter

    Reference for events, messages, and observers in Bevy — Message/MessageReader/MessageWriter, Event/EntityEvent, triggers, observers, and propagation.

    132 GitHub stars~867 tokensUpdated yesterday
    Auto-check passed
  • Bevy Assets

    nolantait/bevy-starter

    Reference for loading, managing, and tracking assets in Bevy — AssetServer, handles, loading states, events, custom loaders, and hot reloading.

    132 GitHub stars~871 tokensUpdated yesterday
    Auto-check passed
  • Bevy Audio

    nolantait/bevy-starter

    Reference for playing and controlling audio in Bevy — AudioPlayer, AudioSink, spatial audio, volume, and playback settings.

    132 GitHub stars~713 tokensUpdated yesterday
    Auto-check passed
  • Bevy Bsn

    nolantait/bevy-starter

    Reference for Bevy Scene Notation (BSN) — the bsn!. An agent skill from nolantait/bevy-starter.

    132 GitHub stars~1.1k tokensUpdated yesterday
    Auto-check passed
  • Bevy Cameras

    nolantait/bevy-starter

    Reference for cameras in Bevy — Camera2d, Camera3d, viewports, projection, render layers, mouse-to-world, and free camera controllers.

    132 GitHub stars~976 tokensUpdated yesterday
    Auto-check passed
  • Bevy Commands

    nolantait/bevy-starter

    Reference for Bevy Commands — spawning/despawning entities, inserting/removing components, custom commands, trait extensions, and testing.

    132 GitHub stars~783 tokensUpdated yesterday
    Auto-check passed

Questions about Avian

What does Avian do?

Reference for Avian physics engine — rigid bodies, colliders, joints, spatial queries, collision events, character controllers, and debug rendering. Avian is an agent skill from nolantait/bevy-starter. Reference for Avian physics engine — rigid bodies, colliders, joints, spatial queries, collision events, character controllers, and debug rendering.

How do I install Avian in Claude Code?

Run `npx skills add nolantait/bevy-starter --skill avian -a claude-code`. Or copy the skill folder (.agents/skills/avian in nolantait/bevy-starter) into .claude/skills/avian in your project. Claude Code loads it when a task matches its description.

How do I install Avian in Codex?

Run `npx skills add nolantait/bevy-starter --skill avian -a codex`. Or copy the skill folder (.agents/skills/avian in nolantait/bevy-starter) into .agents/skills/avian in your project. Codex loads it when a task matches its description.

Can I use Avian in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add nolantait/bevy-starter --skill avian -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/avian, .gemini/skills/avian, .github/skills/avian and .opencode/skills/avian in your project.

What does Avian need to run?

SKILL.md names no scripts, command-line tools or credentials: Avian is instructions for the agent only.

Does Avian access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Avian safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Avian use?

Avian is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Avian use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Avian?

Skills that share tags, products or a category with Avian: Physical Address (thedaviddias/Front-End-Checklist, 74k stars), Aria Hidden Body (thedaviddias/Front-End-Checklist, 74k stars), Physics System (jame581/GodotPrompter, 805 stars) and Meta In Body (thedaviddias/Front-End-Checklist, 74k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Avian?

nolantait (a GitHub user) maintains it in nolantait/bevy-starter, which has 132 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 8, 2026.

Source: nolantait/bevy-starter on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.