agentleFS
chrisgliddonchrisgliddon/bevy-skills/skills/bevy-a11y/SKILL.md

bevy-a11y

Skill29 starsChanged 11 days agoMITView on GitHub

Use when designing or auditing high-standard video-game accessibility in Bevy 0.20, integrating screen readers and focus navigation, supporting adaptive controllers and complete remapping, implementing captions or audio description, checking contrast and motion safety, or building disabled-player test evidence.

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 5 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use all four layers:

    line 20
  2. Distinctive:

    Every gameplay and UI action is device-neutral, remappable, conflict-checked, persistable, and available through menus without a pointer.

    line 35
  3. Distinctive:

    Test keyboard, D-pad/stick, switch-style scanning, touch, pointer, and a real screen reader.

    line 94
  4. Distinctive:

    Read visual, cognitive, and motion and captions, audio, and communication.

    line 133
  5. Very specific:

    Run scripts/audit_input_map.py on the action manifest before input freezes.

    line 138
  6. Very specific:

    Run scripts/check_contrast.py on every theme/state pair.

    line 139
  7. Very specific:

    Run scripts/validate_captions.py on source and localized VTT/SRT files.

    line 141
  8. Distinctive:

    Do not advertise accessibility feature tags until the shipping build and supported input/platform combinations have been verified.

    line 143

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Bevy 0.20 — game accessibility

Accessibility is a cross-cutting product requirement. Start during input, UI, audio, camera, narrative, multiplayer, and save-system design; retrofitting only labels and captions will not solve inaccessible game mechanics.

Standard of work

Use all four layers:

  1. Xbox Accessibility Guidelines as the public game-specific engineering baseline.
  2. WCAG 2.2 criteria, aiming at AAA where they transfer meaningfully to game UI/content.
  3. Platform-holder requirements and certification guidance for every shipping target.
  4. Usability testing with disabled players using their own assistive technology.

WCAG AAA is not a universal native-game certification, and automated checks do not establish conformance. Record scope, exceptions, devices, test builds, findings, and remediation evidence. See requirements.

Ship these foundations first

  • Every gameplay and UI action is device-neutral, remappable, conflict-checked, persistable, and available through menus without a pointer.
  • Input supports hotplug, simultaneous devices, multiple controllers per player, unknown controls, adjustable deadzones/sensitivity, and digital analog alternatives.
  • Holds, repeated presses, chords, rapid timing, and precision input have toggle, timing, or assist alternatives.
  • UI has deterministic focus order, visible focus, semantic roles/names/states, scalable text/layout, adequate contrast, and no information conveyed only by colour.
  • Dialogue and meaningful audio have synchronized closed captions; meaningful visual events have narration/audio-description or equivalent cues.
  • Camera shake, motion blur, flashes, auto-motion, and other vestibular/photosensitive effects have safe defaults or independent controls.
  • Accessibility settings are available before first gameplay and remain usable after rebinding, language changes, disconnects, and save migration.

Bevy UI semantics and focus

DefaultPlugins includes InputFocusPlugin. Add navigation plugins explicitly and put the accessible name on the same entity as the interactive control:

use bevy::{
    input_focus::{
        directional_navigation::DirectionalNavigationPlugin,
        tab_navigation::TabNavigationPlugin,
    },
    picking::hover::Hovered,
    prelude::*,
    ui::auto_directional_navigation::AutoDirectionalNavigation,
    ui_widgets::Button,
};

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            TabNavigationPlugin,
            DirectionalNavigationPlugin,
        ))
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d);
    commands.spawn((
        Button,
        Hovered::default(),
        AccessibleLabel::new("Start game"),
        AutoDirectionalNavigation::default(),
        children![Text::new("Start game")],
    ));
}

ui_widgets::Button requires an AccessKit Role::Button node. Read interaction state as (&Hovered, Has<Pressed>); ui::Interaction and ui::prelude::Button are deprecated.

Focus, hover, pointer capture, and screen-reader focus are related but not identical. Test keyboard, D-pad/stick, switch-style scanning, touch, pointer, and a real screen reader. Use AccessKit nodes for custom widgets and expose changing value/state—not only a static label. See screen readers and navigation.

Adaptive and accessibility controllers

Adaptive controllers normally arrive through standard gamepad/HID mappings. Do not gate features on a brand, vendor ID, or a particular device name. Treat every Gamepad entity as capabilities and bindings:

use bevy::prelude::*;

fn read_gamepads(gamepads: Query<(Entity, &Gamepad)>) {
    for (entity, gamepad) in &gamepads {
        let move_axis = gamepad.left_stick();
        let activate = gamepad.just_pressed(GamepadButton::South);
        let extra = gamepad.just_pressed(GamepadButton::Other(0));
        let _sample = (entity, move_axis, activate, extra);
    }
}

With default-features = false, native discovery requires Bevy's bevy_gilrs feature, not only gamepad. leafwing-input-manager 0.22 is a compatible optional action layer, but it does not create accessible settings, UI, persistence, or mechanic alternatives for you. See input and adaptive controllers.

Requirements by access need

AreaNon-negotiable implementation
Blind/low visionsemantic UI, full non-pointer navigation, narration/audio description, text scale, strong focus/contrast, non-colour cues
Deaf/hard of hearingclosed captions with speaker and meaningful sound cues, visual/haptic equivalents, independent mix controls
Motorfull remapping, simultaneous devices, no mandatory holds/mashing/chords, timing/aim/movement assists, pauseability where possible
Cognitive/learningconsistent navigation, plain language, objective history, tutorials, adjustable pacing/difficulty, low-distraction modes
Speech/communicationno voice-only requirement, accessible text chat, speech-to-text/text-to-speech where communication is core
Photosensitive/vestibularflash safety, reduced motion, shake/FOV/blur controls, no essential parallax/auto-motion

Read visual, cognitive, and motion and captions, audio, and communication.

Implementation gates

  • Run scripts/audit_input_map.py on the action manifest before input freezes.
  • Run scripts/check_contrast.py on every theme/state pair; sample image/video backgrounds separately.
  • Run scripts/validate_captions.py on source and localized VTT/SRT files.
  • Execute the manual matrix in testing and evidence.
  • Do not advertise accessibility feature tags until the shipping build and supported input/platform combinations have been verified.

Script formats and CI examples are in tooling.

Gotchas

  • 0.20: ui::prelude::Button and ui::Interaction are deprecated. Spawn bevy::ui_widgets::Button and read (&Hovered, Has<Pressed>). Stale output queries Changed<Interaction>.
  • 0.20: FocusCause gained Auto (focus granted by AutoFocus). An exhaustive match on Navigated | Pressed no longer compiles.
  • 0.20: Escape in a focused EditableText clears InputFocus and keeps bubbling. A dialog cancel observer fires on the same press; test original_event_target() for two-step behaviour. EditableText needs a sibling TextInput to be a widget.
  • 0.20: pointer events are flat: On<PointerClick>, not On<Pointer<Click>>; the position is event.pointer.position.
  • 0.20: GamepadButton::Other(u32) and GamepadAxis::Other(u32) (were u8).
  • 0.20: TextFont::default() size is FontSize::Rem(1.); Val::Rem sizes scale with the RemSize resource, which is the hook for a user text-scale setting.
  • 0.19: InputFocus fields are private; use set(entity, cause), get(), clear(). UiWidgetsPlugins ships in DefaultPlugins; tab/directional plugins stay explicit.
  • 0.19: bevy_input_focus is no longer implied by the picking feature; ui pulls it in.

See also

  • bevy-input-actions — logical actions, remapping, device hot-plug, Steam Deck, and adaptive-controller integration.
  • bevy-audio — captions/cue boundary, category mixes, spatial limitations, and browser audio startup.
  • bevy-ui — layout, text, interaction, and focus APIs.
  • bevy-cargo-features — controller and UI backends.
  • bevy-fluent — localized text and captions.
  • bevy-cameras — shake, FOV, and viewport controls.
  • bevy-physics — accessible character movement, aim, and timing mechanics built over physics.
  • bevy-testing — deterministic checks and capture evidence.
  • bevy-core-concepts — schedule architecture.
  • bevy-migration-0-19-to-0-20 — deprecated Button/Interaction, flat pointer events, FocusCause::Auto.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.