agentsclimarketplace

Rust bevy standards

Skill kimgoetzke/coding-agent-configs/skills/rust-bevy-standards

My personal skills, agents, and other configuration files for agentic coding.

Install
npx -y skills add kimgoetzke/coding-agent-configs --skill rust-bevy-standards

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Write idiomatic Rust code for applications that use Bevy Engine. Augments rust-standards skill, does not replace it. Use when writing Rust code for a Bevy application.

SKILL.md

4.5 KB, as published. Nobody here has run it

⚠️ Bevy 0.17+ Breaking Changes

  • Material handles wrapped in MeshMaterial3d<T>, not Handle<T>

  • Observer pattern replaces event system (commands.trigger(), add_observer())

  • Event split into Message (buffered) and Event (observers)

  • EventWriter/EventReader replaced by MessageWriter/MessageReader (message.write() / messages.read())

  • Observer trigger API changed:

    // Old
    commands.add_observer(|trigger: Trigger<OnAdd, Player>| {
        info!("Spawned player {}", trigger.target());
    });
    
    // New
    commands.add_observer(|add: On<Add, Player>| {
        info!("Spawned player {}", add.entity);
    });
    
  • Color arithmetic removed; use component extraction instead

⚠️ Bevy 0.18+ Breaking Changes

  • RenderTarget is now a required component on Camera, not a Camera field:
    // Old
    Camera { target: RenderTarget::Image(handle.into()), ..default() }
    // New
    commands.spawn((Camera3d::default(), RenderTarget::Image(handle.into())));
    
  • BorderRadius is now a field on Node, not a component
  • LineHeight is now a required component on Text/Text2d/TextSpan; removed from TextFont
  • AmbientLight resource renamed to GlobalAmbientLight; AmbientLight is now a component on Camera
  • clear_childrendetach_all_children, remove_childrendetach_children, remove_childdetach_child (same on EntityCommands and EntityWorldMut)
  • AnimationTarget { id, player } replaced by separate AnimationTargetId(id) and AnimatedBy(player_entity) components
  • next_state.set(...) now always fires OnEnter/OnExit; use set_if_neq for the old behaviour
  • MaterialPlugin fields prepass_enabled/shadows_enabled replaced by Material trait methods enable_prepass()/enable_shadows()
  • SimpleExecutor removed; use SingleThreadedExecutor instead
  • #[reflect(...)] now only supports parentheses, not braces or brackets
  • AssetLoader, AssetSaver, AssetTransformer, Process now require #[derive(TypePath)]
  • ron no longer re-exported from bevy_scene or bevy_asset; add it as a direct dependency
  • Feature renames: animationgltf_animation, bevy_sprite_picking_backendsprite_picking, bevy_ui_picking_backendui_picking, bevy_mesh_picking_backendmesh_picking

General

  • Never delete target binaries — Bevy rebuilds take minutes

Footguns

  • despawn() orphans children, consider despawn_recursive() instead
  • Commands are deferred — world mutations apply at end of schedule; don't read back in the same system what you wrote via commands
  • Use Changed<T> and Added<T> query filters to skip unchanged components — omitting these is the most common Bevy performance mistake
  • Use observers (OnAdd, OnRemove) for component lifecycle reactions; don't poll for these in Update

Naming

  • No unnecessary abbreviations: position not pos
  • ECS systems: name ends in _system
  • Message handlers: name starts with handle_, ends in _message

ECS

  • Think in data (components) and transformations (systems), not objects and methods
  • Components = pure data, no logic
  • Systems = pure logic, operate on components
  • Events/Messages = communication between systems
  • Resources = global state; use sparingly
  • Keep components small and focused; one large component defeats ECS cache locality

System Design

Plugin structure

  • Break the app into discrete modules using plugins
  • All plugin structs must have a /// doc comment explaining their purpose and scope
/// Handles damage processing and death detection.
pub struct CombatPlugin;

impl Plugin for CombatPlugin {
    fn build(&self, app: &mut App) {
        app
            .add_event::<DamageEvent>()
            .add_systems(Update, (process_damage, check_death));
    }
}

System sets

  • Use run conditions (run_if(in_state(...))) to skip whole systems
  • Use OnEnter/OnExit schedules for state transitions, not flags checked in Update

System ordering

.add_systems(
    Update,
    (
        // 1. Input
        handle_input,

        // 2. State changes
        process_events,
        update_state,

        // 3. Derived values
        calculate_derived_values,

        // 4. Visuals
        update_materials,
        update_animations,

        // 5. UI (last)
        update_ui_displays,
    ),
)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.