Bevy All-in-One Documentation
A powerful 3D/2.5D game controller plugin for Bevy Engine.
Project maintained by yaskhan
Hosted on GitHub Pages — Theme by mattgraham
Bevy Tutorial System Documentation
Table of Contents
Overview
System Purpose and Philosophy
The Bevy Tutorial System provides a comprehensive framework for creating, managing, and presenting interactive tutorial sequences within Bevy-based games. Designed with player experience as the primary focus, this system enables developers to craft educational content that seamlessly integrates with gameplay without disrupting immersion or flow. The architecture emphasizes flexibility, allowing tutorials to range from simple one-panel hints to complex multi-stage learning experiences with sophisticated game state management.
At its core, the system operates on a panel-based sequencing model where each tutorial consists of one or more informational panels presented in sequence. This approach provides natural breakpoints for player comprehension while maintaining a consistent interaction pattern (next/previous navigation). The system deliberately separates tutorial content definition from presentation logic, enabling content designers to focus on educational material while programmers handle integration concerns.
The philosophy driving this implementation centers on three key principles: non-intrusiveness (tutorials should enhance rather than interrupt gameplay), persistence (player progress through tutorials should be remembered across sessions), and configurability (developers should have fine-grained control over how tutorials affect game state). These principles manifest in features like optional single-play enforcement, cursor unlocking, input pausing, and time scale manipulation—all configurable per tutorial rather than globally enforced.
Key Features
The tutorial system delivers a robust set of capabilities designed to handle diverse educational scenarios within games:
Panel-Based Sequencing: Tutorials are constructed from sequential panels, each containing a title, descriptive text, and optional visual asset. This structure supports progressive disclosure of information, allowing complex mechanics to be broken into digestible segments. Panel navigation follows intuitive patterns (next/previous buttons) with automatic closure upon sequence completion.
Persistent Progress Tracking: Through the TutorialLog component attached to player entities, the system maintains a record of completed tutorials across game sessions. This enables sophisticated behaviors like preventing redundant tutorials for experienced players while ensuring newcomers receive necessary guidance. The persistence mechanism uses efficient HashSet storage for O(1) lookup performance.
Configurable Game State Management: Each tutorial definition includes boolean flags controlling four critical aspects of game interaction during presentation:
play_only_once: Prevents re-display of completed tutorials
unlock_cursor: Releases cursor confinement for UI interaction
pause_input: Disables standard gameplay input processing
set_custom_time_scale: Modifies game time progression (including full pause)
These flags operate independently, allowing precise control over player experience. For example, a combat tutorial might pause input and slow time without unlocking the cursor, while a menu navigation tutorial would unlock the cursor without affecting time scale.
Event-Driven Architecture: Tutorial lifecycle management occurs through a dedicated event system (TutorialEvent) with explicit lifecycle events (Open, NextPanel, PreviousPanel, Close). This decouples tutorial triggering from presentation logic, enabling tutorials to be initiated from diverse game contexts (collision detection, UI interactions, quest progression) without tight coupling.
Automatic UI Management: The system handles complete UI lifecycle management—creation, content population, state updates, and cleanup—without developer intervention beyond initial tutorial definition. UI elements automatically appear when tutorials activate and cleanly despawn upon completion, preventing entity leakage or visual artifacts.
Serialization Support: All core data structures implement Serde’s Serialize and Deserialize traits alongside Bevy’s Reflect derive macro, enabling seamless persistence to disk and editor integration. This facilitates save game compatibility and potential future tooling support.
Customizable Visual Presentation: While providing a functional default UI implementation, the system exposes component markers (TutorialRoot, TutorialTitleText, etc.) that enable complete visual customization through additional systems without modifying core logic.
Design Principles
The tutorial system architecture adheres to several foundational design principles that ensure maintainability, extensibility, and developer ergonomics:
Separation of Concerns: Content definition (Tutorial/TutorialPanel structs) remains completely separate from runtime state management (TutorialManager resource) and presentation logic (UI systems). This separation enables content designers to work with data structures without understanding runtime mechanics, while systems programmers can optimize presentation without affecting content pipelines.
Explicit State Transitions: All tutorial state changes occur through explicit events rather than implicit conditions. This design choice enhances debuggability and predictability—developers can trace tutorial progression through event logs rather than deciphering complex conditional logic scattered across systems.
Resource-Based Global State: The TutorialManager resource maintains global tutorial state (active tutorial ID, current panel index) rather than distributing this information across components. This centralization simplifies state reasoning and prevents synchronization issues that could arise from distributed state management.
Component-Based Player Tracking: While global state resides in a resource, player-specific progress tracking uses components (TutorialLog) attached to player entities. This hybrid approach correctly models the domain: tutorial progress is player-specific (hence component-based), while active presentation state is globally singular (hence resource-based).
Defensive Programming Practices: Systems implement robust error handling including tutorial ID validation before activation, bounds checking during panel navigation, and cleanup operations that handle edge cases (e.g., despawning UI when none exists). These practices prevent common runtime errors in tutorial sequences.
Performance-Conscious Implementation: The system minimizes runtime overhead through techniques like event queue batching (processing all pending events in a single pass), UI existence checking before updates (avoiding unnecessary queries), and efficient data structures (HashSet for played tutorials).
Extensibility by Design: Extension points are deliberately exposed through component markers and configurable flags rather than hard-coded behaviors. Developers can attach additional systems to TutorialRoot entities for custom animations, extend TutorialPanel with additional fields through composition, or implement alternative navigation schemes alongside the default button system.
Integration Capabilities
The tutorial system integrates seamlessly with common game architecture patterns and complementary systems:
Input System Coordination: Through configurable input pausing, the tutorial system cooperates with custom input state management systems. The manage_tutorial_game_state system interacts with an optional InputState resource, demonstrating a non-invasive integration pattern that respects game-specific input architectures.
Time Management Integration: Time scale manipulation occurs through Bevy’s standard Time resource, ensuring compatibility with physics systems, animation timelines, and other time-dependent game mechanics. The system carefully preserves and restores the previous time scale upon tutorial completion to prevent state leakage.
UI System Compatibility: The tutorial UI implementation uses standard Bevy UI primitives (Node, Text, Button components) without custom render pipelines, ensuring compatibility with existing UI theming systems, resolution scaling solutions, and accessibility features.
Persistence Ecosystem: Serialization support enables integration with save game systems. TutorialLog components can be included in player entity serialization without special handling, while TutorialManager state (being transient presentation state) appropriately excludes itself from persistence.
Event System Interoperability: TutorialEvent operates within Bevy’s standard event ecosystem, allowing other systems to react to tutorial lifecycle events. For example, an analytics system could listen for TutorialEvent::Close to record completion metrics, or a sound system could trigger audio cues on panel transitions.
Modular Plugin Architecture: Implemented as a standard Bevy Plugin (TutorialPlugin), the system registers its resources, components, and systems through the conventional plugin interface. This enables straightforward integration into existing application builders with predictable initialization ordering.
Core Concepts
Tutorial Architecture
The tutorial system employs a layered architecture with three distinct layers that communicate through well-defined interfaces:
Content Layer: This layer consists of pure data structures (Tutorial and TutorialPanel) that define tutorial content independent of runtime concerns. Tutorials are stored in a HashMap within the TutorialManager resource, indexed by unique numeric identifiers. This layer focuses exclusively on “what” content exists without addressing “when” or “how” it appears.
State Management Layer: The TutorialManager resource serves as the central coordinator, maintaining active tutorial state (currently displayed tutorial ID and panel index) alongside the complete tutorial catalog. This layer handles state transitions triggered by events, enforces business rules (like single-play restrictions), and coordinates with game systems (time, input) based on tutorial configuration.
Presentation Layer: Multiple systems collaborate to transform state into visual representation. The update_tutorial_ui system manages UI entity lifecycle and content population, handle_tutorial_buttons processes player interactions with navigation controls, and manage_tutorial_game_state adjusts global game parameters (time scale, input state) according to tutorial requirements.
These layers communicate through unidirectional data flow: Content Layer → State Management Layer (via TutorialEvent) → Presentation Layer (via TutorialManager resource queries). This architecture prevents circular dependencies and simplifies debugging—state changes always originate from events, propagate through the manager, and manifest in UI updates.
Data Flow
Tutorial system data flow follows a precise sequence during each operational phase:
Initialization Phase:
- TutorialPlugin registers required resources (TutorialManager, TutorialEventQueue) and components during app construction
- Game code populates TutorialManager.tutorials HashMap with defined tutorial content
- Player entities receive TutorialLog components tracking completion history
- Systems register with Bevy’s scheduler for execution during Update stage
Activation Phase:
- Game logic emits TutorialEvent::Open(id) through TutorialEventQueue resource
- handle_tutorial_events system processes the event during its scheduled execution
- System validates tutorial existence and checks TutorialLog for play restrictions
- Upon validation, TutorialManager.active_tutorial_id and current_panel_index are set
- TutorialLog is updated to record tutorial initiation (for single-play enforcement)
- manage_tutorial_game_state system detects state change and applies configured game modifications (input pause, time scale)
- update_tutorial_ui system detects active tutorial and either creates new UI or updates existing UI content
Navigation Phase:
- Player interacts with UI buttons, triggering Interaction::Pressed events on Button entities
- handle_tutorial_buttons system detects interactions and emits corresponding TutorialEvents (NextPanel/PreviousPanel)
- handle_tutorial_events processes navigation events, updating current_panel_index with bounds checking
- update_tutorial_ui detects panel index change and refreshes UI content to match new panel data
- For NextPanel events reaching sequence end, active_tutorial_id is cleared, triggering cleanup phase
Deactivation Phase:
- Tutorial completion (final panel navigation) or explicit closure (Close button) clears active_tutorial_id
- manage_tutorial_game_state detects cleared state and restores original game parameters (input enabled, time scale reset)
- update_tutorial_ui detects cleared state and despawns entire UI hierarchy rooted at TutorialRoot entities
- System returns to idle state awaiting next TutorialEvent::Open
This data flow ensures deterministic behavior with clear cause-and-effect relationships between player actions and system responses. Each phase completes fully within a single frame update cycle, preventing partial state transitions that could cause visual glitches or input handling errors.
State Management
State management in the tutorial system distinguishes between persistent state (surviving across game sessions) and transient state (relevant only during active presentation):
Persistent State:
- Stored in TutorialLog components attached to player entities
- Contains HashSet of tutorial IDs already completed by the player
- Serialized to disk as part of player entity persistence
- Consulted during tutorial activation to enforce play_only_once restrictions
- Updated immediately upon tutorial initiation (not completion) to prevent duplicate triggers during same session
Transient Presentation State:
- Stored in TutorialManager resource with three critical fields:
- tutorials: Complete catalog of defined tutorial content (HashMap<u32, Tutorial>)
- active_tutorial_id: Option indicating currently displayed tutorial (None when inactive)
- current_panel_index: usize tracking position within active tutorial’s panel sequence
- Not serialized to disk—reconstructed on each game launch from content definitions
- Drives UI presentation and game state modifications while active
- Reset to default state (None active tutorial) upon sequence completion or explicit closure
Game State Modifications:
- Time scale adjustments tracked through previous_time_scale field in TutorialManager
- Input state modifications coordinated through optional InputState resource integration
- Cursor state modifications implied through unlock_cursor flag (requires external cursor management system)
- All modifications automatically reversed when active_tutorial_id becomes None
This state separation ensures that tutorial progress survives game restarts while presentation state remains ephemeral. The design prevents common bugs where transient UI state accidentally persists across level loads or game sessions.
Event-Driven Control
The tutorial system implements a hybrid event processing model combining Bevy’s native event system with a custom queue resource to overcome event reader limitations in certain Bevy versions:
Event Types:
- TutorialEvent::Open(u32): Initiates tutorial sequence with specified ID
- TutorialEvent::NextPanel: Advances to subsequent panel in sequence
- TutorialEvent::PreviousPanel: Returns to preceding panel in sequence
- TutorialEvent::Close: Immediately terminates active tutorial regardless of position
Event Processing Flow:
- Systems or game logic push TutorialEvent variants into TutorialEventQueue.0 vector
- handle_tutorial_events system drains the entire queue at the start of its execution
- Events are processed in FIFO order within a single frame
- Queue is emptied completely each frame to prevent event accumulation
- No events persist beyond the frame they were emitted
Advantages of Queue Approach:
- Guarantees all events emitted during a frame are processed in that same frame
- Prevents event loss that can occur with Bevy’s default event reader mechanics under certain conditions
- Enables multiple tutorial-related events within a single frame (e.g., Open followed immediately by NextPanel)
- Simplifies debugging through deterministic event processing order
- Avoids complex event reader state management across system execution order
Event Safety Guarantees:
- Open events validate tutorial existence before state modification
- Navigation events perform bounds checking against panel sequence length
- Close events safely handle null state (no active tutorial)
- All events processed atomically within single system execution to prevent partial state transitions
This event model provides reliable, predictable control over tutorial progression while remaining compatible with Bevy’s broader event ecosystem for analytics, logging, or system coordination purposes.
UI Lifecycle
The tutorial UI follows a strict lifecycle managed entirely by the update_tutorial_ui system without developer intervention:
Creation Phase:
- Triggered when active_tutorial_id becomes Some(id) AND no TutorialRoot entities exist
- setup_tutorial_ui function constructs complete UI hierarchy:
- Root overlay node (full-screen semi-transparent background)
- Container node (centered panel with padding and border)
- Title text node with TutorialTitleText marker
- Image placeholder node with TutorialPanelImage marker
- Description text node with TutorialDescriptionText marker
- Button container with three navigation buttons (Prev/Next/Close)
- Each interactive button receives TutorialButton component storing associated TutorialEvent
- UI uses absolute positioning to overlay all other game content
- Visual styling provides sufficient contrast for readability over varied game backgrounds
Update Phase:
- Triggered when active_tutorial_id exists AND UI entities already present
- Title text content replaced with current panel’s title field
- Description text content replaced with current panel’s description field
- Image asset reloaded only when panel specifies image_path (avoids unnecessary asset server queries)
- Button states automatically managed by separate handle_tutorial_buttons system
- UI structure remains constant; only content values change between panels
Navigation Handling:
- Prev button disabled at first panel (index 0) through interaction filtering
- Next button transitions to subsequent panel or closes tutorial at sequence end
- Close button immediately terminates tutorial regardless of position
- Button visual feedback provided through background color changes on hover/press
Cleanup Phase:
- Triggered when active_tutorial_id becomes None
- Entire UI hierarchy despawned recursively starting from TutorialRoot entities
- Complete cleanup prevents entity accumulation across multiple tutorial sessions
- No residual UI elements remain after tutorial completion
- Memory released back to Bevy’s entity storage pool immediately
This lifecycle management ensures tutorials never leave visual artifacts or orphaned entities, critical for games with frequent tutorial triggers. The system’s self-contained nature means developers never manually create, update, or destroy tutorial UI entities—only triggering events and defining content.
Component Reference
TutorialPanel
TutorialPanel represents a single informational unit within a tutorial sequence, designed to convey one coherent concept or instruction set. Each panel functions as an atomic learning moment with consistent presentation structure.
Structural Composition:
- name field provides machine-readable identifier for panel within its tutorial sequence. This field supports internal referencing, analytics tagging, or conditional logic extensions without affecting player-facing content. Names should follow consistent naming conventions (e.g., “movement_basics_1”, “combat_intro_panel2”) for maintainability.
- title field contains concise heading text displayed prominently at panel top. Effective titles summarize panel content in 3-7 words, using active voice and concrete terminology (“Jumping Mechanics” rather than “About Jumping”). Titles appear in larger font size with high contrast against background.
- description field holds primary instructional content as multi-sentence explanatory text. Descriptions should follow progressive disclosure principles—starting with core concept, followed by contextual details, ending with practical application tips. Optimal length ranges from 2-5 sentences to maintain player attention without overwhelming cognitive load.
- image_path field provides optional visual reinforcement through asset reference. When specified, system loads image asset and displays within dedicated panel region. Images should illustrate concepts described in text rather than merely decorating UI. Supported formats depend on Bevy asset configuration (typically PNG, JPEG, WebP). Absence of image_path results in empty image region maintaining layout consistency.
Design Considerations:
- Panel content should be self-contained yet sequenced—each panel must make sense in isolation while building toward comprehensive understanding across the sequence
- Text content should avoid pronouns with ambiguous antecedents since panels may be reviewed individually through PreviousPanel navigation
- Visual hierarchy should guide player attention: title → image → description → navigation controls
- Panel complexity should increase gradually across sequences, starting with foundational concepts before introducing nuanced mechanics
- Each panel should focus on single learning objective to prevent cognitive overload
Content Guidelines:
- Titles: Maximum 60 characters to prevent text wrapping at standard resolutions
- Descriptions: Maximum 300 characters for comfortable reading without scrolling
- Images: Recommended 800x400 pixel aspect ratio matching default UI container proportions
- Language: Active voice, second-person perspective (“You can jump by pressing Space”) preferred over passive constructions
- Terminology: Consistent vocabulary across panels within same tutorial sequence
Extension Points:
- Additional fields can be added through composition with custom components attached to TutorialRoot entities
- Panel sequencing logic can be extended beyond linear progression through custom event handling systems
- Visual presentation can be customized by systems querying TutorialTitleText/TutorialDescriptionText markers
Tutorial
Tutorial aggregates multiple TutorialPanel instances into cohesive learning sequences with configurable runtime behaviors. Each tutorial represents a complete instructional unit covering related game mechanics or concepts.
Structural Composition:
- id field provides unique numeric identifier for tutorial within global catalog. IDs should be assigned sequentially during development with reserved ranges for different tutorial categories (e.g., 1000-1999 for movement tutorials, 2000-2999 for combat). Uniqueness is enforced at runtime through HashMap storage—duplicate IDs silently overwrite previous entries.
- name field supplies human-readable tutorial identifier for logging and debugging purposes. Names should clearly describe tutorial content (“Basic Movement Controls”, “Advanced Combat Combos”) without marketing fluff. This field does not appear in player-facing UI unless explicitly used by custom systems.
- panels field contains ordered Vec defining sequence presentation order. Panel order should follow pedagogical best practices: concrete before abstract, simple before complex, isolated mechanics before integrated applications. Minimum one panel required; empty sequences automatically close upon activation.
- play_only_once flag determines whether tutorial can be replayed after initial completion. When true, TutorialLog tracking prevents reactivation even if TutorialEvent::Open is emitted. When false, tutorial can be triggered repeatedly—useful for reference materials or optional hints. Default behavior should favor true for onboarding tutorials, false for reference content.
- unlock_cursor flag signals whether cursor confinement should be released during tutorial presentation. Critical for tutorials requiring mouse interaction with UI elements. Actual cursor unlocking requires integration with game-specific cursor management system—the tutorial system only provides the signal through this flag.
- pause_input flag controls whether standard gameplay input processing should be suspended. When true, manage_tutorial_game_state system interacts with InputState resource to disable input processing. Essential for preventing unintended player actions during instructional moments. Should be true for mechanics tutorials, false for passive informational sequences.
- set_custom_time_scale flag enables time manipulation during tutorial presentation. Works in conjunction with custom_time_scale field to create slow-motion demonstrations or complete pauses. Particularly valuable for complex mechanic demonstrations where normal game speed obscures critical details.
- custom_time_scale field specifies target time scale value when set_custom_time_scale is true. Value of 1.0 represents normal speed, 0.0 represents complete pause, values between 0.0-1.0 create slow motion, values above 1.0 accelerate time. Recommended values: 0.3 for slow-motion demonstrations, 0.0 for complete pauses during critical instructions.
Behavioral Semantics:
- Tutorial activation automatically records completion in TutorialLog when play_only_once is true, preventing redundant presentations
- Panel navigation respects sequence boundaries—PreviousPanel at first panel has no effect, NextPanel at final panel triggers automatic closure
- Game state modifications (input pause, time scale) apply immediately upon activation and persist until tutorial closure
- All configuration flags operate independently—developers can mix behaviors (e.g., pause input without time scaling)
- Tutorial definitions are immutable at runtime—content changes require manager reinitialization
Content Strategy:
- Optimal tutorial length: 3-7 panels balancing completeness against attention span
- Panel sequencing should follow “show, explain, practice” pedagogical pattern where feasible
- Complex mechanics should be decomposed across multiple focused tutorials rather than single overwhelming sequence
- Tutorials should reference previously learned concepts to reinforce knowledge retention
- Final panel should summarize key takeaways and provide clear transition back to gameplay
Performance Characteristics:
- Tutorial catalog storage scales linearly with number of defined tutorials
- HashMap lookup provides O(1) access to tutorial content by ID
- Panel sequences stored as contiguous vectors enabling cache-friendly iteration
- Configuration flags evaluated only during state transitions, not per-frame
TutorialLog
TutorialLog tracks player-specific tutorial completion history as a component attached to player entities. This component enables personalized tutorial experiences based on player progression and prior knowledge.
Structural Composition:
- played_tutorials field maintains HashSet of tutorial IDs previously completed by the player. HashSet provides O(1) lookup performance critical for frequent play_only_once checks during gameplay triggers. The set grows monotonically—tutorials are added upon initiation but never removed, reflecting permanent knowledge acquisition.
Lifecycle Management:
- Component should be attached to primary player entity during character creation or load operations
- Multiple TutorialLog components across different entities are supported but typically unnecessary—tutorial progress is usually player-specific rather than character-specific
- Component persists across game sessions when player entity serialization includes components
- Default initialization creates empty HashSet ready for first tutorial completion
Usage Patterns:
- Systems triggering tutorials should query TutorialLog before emitting Open events to avoid unnecessary activations
- Analytics systems can query played_tutorials to measure tutorial engagement metrics
- Optional tutorials can use TutorialLog state to offer “Show Again” options only for previously completed sequences
- Achievement systems might track completion of tutorial sets through TutorialLog inspection
Design Rationale:
- Component-based storage (rather than resource) correctly models player-specific state
- HashSet chosen over Vec for completion checks due to frequent membership testing
- u32 tutorial IDs provide compact storage with sufficient namespace for typical games
- Absence of timestamps or completion order tracking keeps component lightweight—these features can be added through extension components if needed
Integration Considerations:
- Games with multiple save slots require separate TutorialLog per save file
- Multiplayer games may need distinct TutorialLog per player entity with server-authoritative validation
- Tutorial reset functionality (e.g., for “New Game+” modes) requires explicit HashSet clearing
- Cloud save systems must include TutorialLog in synchronized entity data
Performance Characteristics:
- HashSet memory footprint scales linearly with number of completed tutorials
- Typical games with 20-50 tutorials consume negligible memory (<1KB)
- Lookup operations occur only during tutorial trigger attempts, not per-frame
- Serialization size minimal due to compact integer storage
TutorialRoot
TutorialRoot serves as marker component identifying the root entity of the tutorial UI hierarchy. This component enables reliable identification and manipulation of the entire tutorial interface through Bevy’s entity query system.
Architectural Role:
- Applied exclusively to the top-level overlay node entity created during UI setup
- Enables single-query identification of entire tutorial UI for existence checks and cleanup operations
- Provides anchor point for recursive despawn operations that cleanly remove entire UI hierarchy
- Serves as extension point for systems wanting to attach behaviors to tutorial UI container
Query Patterns:
- Existence checks: Query<Entity, With> determines if tutorial UI currently displayed
- Cleanup operations: Iterating TutorialRoot entities enables complete UI removal on tutorial closure
- Visual effects: Systems can attach particle effects or animations to TutorialRoot entity for presentation enhancements
- Layout adjustments: Systems can modify TutorialRoot node properties for resolution adaptation or theming
Lifecycle Characteristics:
- Component exists only while tutorial actively displayed
- Automatically added during UI creation phase of tutorial activation
- Automatically removed when entire UI hierarchy despawned during cleanup phase
- Never persists beyond single tutorial presentation session
Design Intent:
- Marker components preferred over bundle checks for performance and clarity
- Single root entity simplifies hierarchy management versus distributed markers
- Absence of data fields keeps component lightweight and focused on identification purpose
- Distinct from TutorialTitleText/TutorialDescriptionText which mark specific content regions
Extension Opportunities:
- Animation systems can query TutorialRoot to apply entrance/exit transitions
- Theming systems can modify TutorialRoot background color for visual consistency
- Accessibility systems can attach focus management behaviors to root entity
- Analytics systems can timestamp TutorialRoot creation for engagement metrics
TutorialTitleText
TutorialTitleText marks the Text component entity displaying current panel’s title content. This marker enables targeted content updates and visual customization without affecting other UI text elements.
Architectural Role:
- Applied to entity containing Text component for panel title display
- Enables precise content replacement during panel transitions without rebuilding UI hierarchy
- Provides styling hook for title-specific visual treatments (font, size, color variations)
- Separates title semantics from description text for accessibility and localization systems
Update Mechanics:
- During panel transitions, systems query entities with TutorialTitleText marker
- Text content replaced by assigning new string value to Text component’s sections
- Styling properties (font size, color) remain constant unless explicitly modified by external systems
- Multiple title entities theoretically possible but default UI creates exactly one instance
Visual Design Intent:
- Titles should command visual hierarchy through size (30px default), weight, and color contrast
- Positioning at top of panel container establishes natural reading flow
- Sufficient vertical spacing separates title from subsequent image region
- Text wrapping handled automatically by Bevy UI text layout system
Customization Points:
- Font selection can be modified by systems querying TutorialTitleText marker
- Color schemes can vary based on tutorial category through conditional styling systems
- Animation effects (fade, slide) can target title text for emphasis during transitions
- Localization systems can replace content while preserving styling through marker queries
Accessibility Considerations:
- Title text should be concise enough for screen reader efficiency
- Semantic separation from description aids navigation for assistive technologies
- Color contrast must meet WCAG AA standards against background (4.5:1 minimum)
- Text size should remain legible at minimum supported resolution
TutorialDescriptionText
TutorialDescriptionText identifies the Text component entity presenting panel’s instructional content. This marker enables dynamic content updates while maintaining consistent visual treatment across panel transitions.
Architectural Role:
- Applied to entity containing primary instructional text content
- Enables content replacement without UI hierarchy reconstruction during navigation
- Provides styling hook for description-specific typographic treatments
- Separates body content semantics from title and button text elements
Content Characteristics:
- Holds multi-sentence explanatory text requiring greater reading time than titles
- Typically displayed in smaller font size (20px default) with lighter color for visual hierarchy
- Positioned below image region to maintain natural top-to-bottom reading flow
- Text wrapping and overflow handled automatically by Bevy UI layout constraints
Update Mechanics:
- Panel transitions trigger content replacement through direct Text component mutation
- Systems query entities with TutorialDescriptionText marker to locate update targets
- Default UI creates single description entity per tutorial instance
- Content updates occur every panel transition regardless of actual content changes
Styling Guidelines:
- Font size should balance readability against panel real estate constraints
- Line height should provide comfortable reading rhythm (1.4-1.6x font size recommended)
- Text color should provide sufficient contrast while maintaining visual hierarchy below title
- Maximum width constraints prevent excessively long line lengths that impair readability
Content Best Practices:
- Descriptions should expand upon title’s promise with concrete details
- Active voice and second-person perspective enhance engagement (“Press Space to jump”)
- Concrete examples anchor abstract concepts in player experience
- Progressive complexity: simple statement → elaboration → practical application
- Avoid pronoun ambiguity since panels may be reviewed non-sequentially
Localization Support:
- Text content should be externalized to localization files rather than hardcoded
- Marker component enables runtime text replacement without UI restructuring
- Line length variations across languages require flexible container sizing
- Right-to-left language support requires additional layout considerations
TutorialPanelImage
TutorialPanelImage marks the UI node entity designated for visual asset display within tutorial panels. This component enables dynamic image loading and presentation without rebuilding UI structure during panel navigation.
Architectural Role:
- Applied to ImageNode entity within tutorial UI hierarchy
- Provides target for asset loading operations when panels specify image_path
- Enables visual consistency through persistent node structure even when images change
- Serves as placeholder region when panels omit image_path specification
Visual Presentation:
- Default implementation provides 500px width × 200px height container matching tutorial panel proportions
- Positioned between title and description to maintain visual flow hierarchy
- Background remains transparent when no image loaded, showing underlying container styling
- Image scaling handled automatically by Bevy’s UI image rendering system
Asset Loading Behavior:
- Images loaded only when panel specifies non-None image_path value
- AssetServer.load() called with provided path string triggering asynchronous loading
- Loading state not explicitly handled—blank region displayed during asset load
- Previously loaded images remain visible until explicitly replaced by new panel content
- No caching layer beyond Bevy’s standard asset management—repeated paths reload assets
Content Guidelines:
- Images should illustrate concepts described in accompanying text rather than decorative elements
- Diagrams and annotated screenshots often more effective than pure photography
- Consistent visual style across tutorial images enhances professional presentation
- Critical information should never appear exclusively in images (accessibility requirement)
- Recommended aspect ratio 2.5:1 (500×200) matching default container dimensions
Performance Considerations:
- Large image assets increase memory footprint and loading times
- Texture atlasing not automatically applied—individual assets loaded separately
- GPU memory consumption scales with number of simultaneously loaded tutorial images
- Asset unloading occurs through Bevy’s standard reference counting when UI despawned
Extension Opportunities:
- Animation systems could replace static images with sprite animations for dynamic demonstrations
- Systems could attach particle effects to image node for emphasis on critical visuals
- Conditional image selection based on player settings (e.g., colorblind-friendly variants)
- Progressive image loading with placeholders during asset retrieval
TutorialButton associates navigation actions with UI button entities through encapsulated TutorialEvent variants. This component bridges player interactions with tutorial state transitions without hard-coded button behaviors.
Structural Composition:
- Single field stores cloned TutorialEvent variant corresponding to button’s intended action
- Event variants supported: PreviousPanel, NextPanel, Close (Open not used for buttons)
- Component attached to Button entity along with standard UI interaction components
- Enables generic button handling system without per-button special casing
Interaction Flow:
- Player clicks button entity with TutorialButton component
- Bevy’s UI system updates Interaction component to Pressed state
- handle_tutorial_buttons system detects Changed on marked entities
- System pushes TutorialButton’s stored event into TutorialEventQueue
- handle_tutorial_events processes event during next system execution
- Tutorial state updates according to event semantics
Visual Feedback System:
- handle_tutorial_buttons simultaneously manages button appearance states:
- Pressed: Darker background (0.4,0.4,0.4) providing tactile feedback
- Hovered: Medium background (0.3,0.3,0.3) indicating interactivity
- Normal: Base background (0.2,0.2,0.2) for visual consistency
- Color transitions occur immediately with interaction state changes
- Visual feedback independent of event emission—provides responsive UI even with frame delay before state update
Button Configuration:
- Default UI creates three buttons with fixed labels: “Prev”, “Next”, “Close”
- Button width (80px) and height (40px) provide adequate touch targets
- Horizontal arrangement with space-between justification creates balanced layout
- “Prev” button implicitly disabled at first panel through interaction filtering (no visual disable state)
- Button order follows Western reading convention (left to right: previous, next, close)
Customization Points:
- Button labels can be modified by systems querying child Text entities of TutorialButton parents
- Visual styling can be overridden through additional systems modifying BackgroundColor
- Additional buttons can be added alongside defaults with custom TutorialEvent variants
- Layout arrangement can be reconfigured by modifying parent container node properties
Accessibility Considerations:
- Button size meets minimum touch target recommendations (44px minimum)
- Color contrast between text and background exceeds WCAG AA requirements
- Visual feedback states provide non-color cues for interaction status
- Semantic labeling should be enhanced for screen readers through ARIA attributes (requires Bevy UI extension)
Resource Reference
TutorialManager
TutorialManager serves as the central coordination resource maintaining global tutorial state and content catalog. This resource embodies the system’s state management layer, bridging content definitions with runtime presentation logic.
Structural Composition:
- tutorials field stores complete catalog of defined Tutorial instances in HashMap<u32, Tutorial> structure. HashMap provides O(1) lookup by tutorial ID critical for activation performance. Population occurs during game initialization—typically through direct insertion or asset loading systems. Catalog remains immutable during gameplay; dynamic tutorial creation requires manager access and explicit insertion.
- active_tutorial_id field tracks currently displayed tutorial as Option. None indicates no active tutorial (system idle state). Some(id) triggers UI presentation and game state modifications. This field represents the primary state transition point—changes here drive all subsequent system behaviors.
- current_panel_index field maintains zero-based position within active tutorial’s panel sequence. Always valid when active_tutorial_id is Some—systems guarantee index remains within bounds through careful update logic. Reset to zero upon each new tutorial activation.
- previous_time_scale field caches original game time scale before tutorial modifications. Critical for accurate restoration when tutorials close. Captured during manage_tutorial_game_state execution when time scale modification first applied. Not used when set_custom_time_scale flag is false.
Lifecycle Management:
- Resource initialized through Default implementation during Plugin::build registration
- Tutorials catalog populated after resource initialization but before first gameplay frame
- Active state fields (active_tutorial_id, current_panel_index) transition during gameplay based on events
- Resource persists for entire application lifetime—never despawned or reinitialized
- Not serialized to disk by default since presentation state is transient (content catalog typically loaded from assets each session)
State Transition Semantics:
- Activation: active_tutorial_id transitions None → Some(id), current_panel_index set to 0
- Navigation: current_panel_index increments/decrements within valid panel range
- Completion: active_tutorial_id transitions Some(id) → None when NextPanel exceeds sequence bounds
- Cancellation: active_tutorial_id transitions Some(id) → None immediately on Close event
- All transitions atomic within single system execution to prevent partial state exposure
Concurrency Considerations:
- Resource accessed mutably by handle_tutorial_events system (state transitions)
- Resource accessed immutably by update_tutorial_ui and manage_tutorial_game_state systems (state reading)
- Bevy’s system scheduler guarantees exclusive mutable access during system execution
- No explicit synchronization primitives required due to single-threaded update stage execution
- Event queue pattern prevents concurrent modification issues from multiple event sources
Extension Patterns:
- Additional fields can track analytics data (time spent per tutorial) without affecting core logic
- Tutorial categorization metadata could enable filtered queries or progression gating
- Tutorial dependency tracking could enforce prerequisite completion before activation
- All extensions should maintain resource’s single-responsibility principle for state coordination
Performance Characteristics:
- HashMap storage provides constant-time tutorial lookup critical for frequent activation checks
- Active state fields consume negligible memory (Option + usize + f32)
- No per-frame processing overhead beyond system queries—state only evaluated when relevant
- Cache-friendly layout due to small, fixed-size fields minimizing memory footprint
Debugging Support:
- Resource fields visible through Bevy Inspector or custom debug UI systems
- State transitions logged at info level for activation/completion events
- Invalid tutorial ID attempts logged at warn level with diagnostic information
- Resource implements Debug trait for println! diagnostics during development
TutorialEventQueue
TutorialEventQueue implements a custom event buffering mechanism addressing limitations in Bevy’s native event system for certain version ranges. This resource provides reliable, frame-accurate event delivery critical for tutorial state consistency.
Structural Composition:
- Single field (0) stores Vec accumulating events emitted during current frame
- Vector grows dynamically to accommodate arbitrary event quantities per frame
- Events processed in strict FIFO order preserving emission sequence semantics
- Queue completely drained each frame—no events persist beyond emission frame
Processing Mechanics:
- Systems emit events by pushing TutorialEvent variants into queue.0 vector
- handle_tutorial_events system executes early in Update stage
- System drains entire vector into local collection before processing
- Events processed sequentially in drained order within single execution
- Queue remains empty after processing until next frame’s emissions
Advantages Over Native Events:
- Guarantees all frame-emitted events processed within same frame
- Prevents event loss from reader/ writer timing mismatches in Bevy 0.18
- Enables multiple related events per frame (e.g., Open followed by NextPanel)
- Simplifies debugging through deterministic processing order
- Eliminates complex event reader state management across system ordering
Usage Patterns:
- Systems should push events directly to queue rather than using Bevy Events
- No need for event reader management or manual clearing
- Multiple systems can safely push to queue concurrently within same frame
- Event emission has zero runtime cost beyond vector push operation
Memory Management:
- Vector capacity may grow with high-frequency event emission patterns
- No explicit capacity management—relies on Rust’s vector amortized growth
- Typical usage involves 0-3 events per frame, keeping allocations minimal
- Vector never holds events across frames, preventing unbounded growth
Thread Safety:
- Resource accessed exclusively during single-threaded Update stage
- No synchronization primitives required for safe concurrent pushes within frame
- Bevy’s system scheduler guarantees no concurrent mutable access across systems
- Not designed for multi-threaded access—would require Mutex/RwLock protection
Migration Path:
- Implementation designed as temporary workaround for specific Bevy version limitations
- Future versions may revert to native Events when reliable
- Abstraction layer (queue resource) minimizes migration impact on dependent systems
- Interface remains consistent regardless of underlying event delivery mechanism
Debugging Considerations:
- Event queue contents visible through resource inspection for diagnostic purposes
- Event processing order matches emission order—critical for sequence-dependent operations
- No event deduplication—duplicate events processed as emitted (intentional behavior)
- Systems should avoid emitting redundant events to prevent unnecessary processing
Event Reference
TutorialEvent::Open
TutorialEvent::Open(u32) initiates tutorial presentation sequence for specified tutorial ID. This event represents the primary entry point for tutorial system interaction, triggering complete activation pipeline including validation, state setup, UI creation, and game state modifications.
Activation Pipeline:
- Event received by handle_tutorial_events system during processing phase
- System validates tutorial existence by querying TutorialManager.tutorials HashMap
- When tutorial found, system checks TutorialLog components on player entities for play restrictions
- play_only_once enforcement: if tutorial marked single-play AND ID exists in played_tutorials, activation aborted with warning log
- Upon successful validation:
- TutorialManager.active_tutorial_id set to Some(id)
- TutorialManager.current_panel_index reset to 0
- TutorialLog.played_tutorials updated with tutorial ID (immediate tracking prevents duplicate triggers within session)
- Info log emitted recording tutorial name for diagnostics
- Subsequent systems detect state change and apply presentation/game modifications
Validation Semantics:
- Tutorial ID validation occurs before any state modification—invalid IDs produce no side effects beyond warning log
- play_only_once enforcement occurs after ID validation but before state modification
- TutorialLog update occurs immediately upon validation success, not after completion—prevents rapid duplicate triggers
- Multiple player entities with TutorialLog components all updated simultaneously (typical games have single player entity)
Usage Patterns:
- Triggered by gameplay events: player entering tutorial zone, first interaction with game mechanic, quest progression milestone
- Can be emitted proactively by systems monitoring player behavior (e.g., repeated failure at task)
- Should include validation checks before emission to avoid unnecessary event processing
- Tutorial ID constants should be defined centrally to prevent magic number usage
Edge Cases:
- Emitted while tutorial already active: previous tutorial immediately replaced without cleanup sequence
- Emitted for completed single-play tutorial: silently ignored with warning log
- Emitted with invalid ID: silently ignored with warning log—no state modification occurs
- Emitted rapidly in succession: last valid tutorial ID wins due to immediate state replacement
Performance Characteristics:
- HashMap lookup provides O(1) validation performance
- TutorialLog update involves HashSet insertion (amortized O(1))
- Entire activation pipeline completes within single frame
- No asset loading occurs during activation—deferred to UI update phase
Best Practices:
- Always validate tutorial eligibility before emitting Open event
- Use descriptive tutorial IDs with category prefixes for maintainability
- Consider player context before triggering—avoid interrupting critical gameplay moments
- Provide visual/audio cues preceding tutorial activation for player preparation
- Log tutorial triggers for analytics to measure engagement patterns
TutorialEvent::NextPanel
TutorialEvent::NextPanel advances tutorial presentation to subsequent panel within active sequence. This event drives forward progression through tutorial content, implementing boundary-aware navigation with automatic sequence completion.
Navigation Semantics:
- Event processed only when TutorialManager.active_tutorial_id is Some(id)
- System retrieves Tutorial instance via ID lookup in tutorials catalog
- Boundary check: if current_panel_index + 1 < panels.len(), increment index
- Boundary exceeded: current_panel_index at final panel (index == len() - 1)
- TutorialManager.active_tutorial_id set to None
- Tutorial automatically closed without requiring explicit Close event
- UI cleanup and game state restoration triggered in subsequent systems
- No effect when no active tutorial—event silently ignored
Progression Characteristics:
- Linear forward navigation only—no branching or non-sequential jumps
- Panel index increments by exactly one per event—no skipping multiple panels
- Automatic closure at sequence end provides seamless transition back to gameplay
- No validation of panel content—assumes panels vector contains valid TutorialPanel instances
Usage Patterns:
- Primarily triggered by player interaction with “Next” UI button
- Can be emitted programmatically for automated tutorial progression (e.g., timed demonstrations)
- May be combined with TutorialEvent::Open in same frame for non-zero starting panels
- Systems monitoring player actions could emit after successful mechanic demonstration
Edge Cases:
- Emitted with single-panel tutorial: immediately closes tutorial after one NextPanel event
- Rapid successive emissions: each processed individually with bounds checking per event
- Emitted during panel transition animation: processed immediately—animation systems must handle rapid state changes
- Emitted when UI not yet created: state updates immediately; UI reflects new state during next update cycle
Performance Characteristics:
- Single bounds check and potential index increment per event
- O(1) panel access via vector indexing
- No memory allocations during normal navigation
- Automatic closure triggers UI despawn with associated entity cleanup costs
Design Rationale:
- Automatic closure at sequence end reduces required player actions
- Strict linear progression simplifies content authoring and player expectations
- Boundary checking prevents panic conditions from invalid navigation
- No visual indication of final panel—players discover completion through UI disappearance
Best Practices:
- Panel content should prepare players for sequence completion on final panel
- Consider adding summary or encouragement text on final panel before closure
- Avoid placing critical information exclusively on final panel that players might miss during rapid navigation
- Analytics systems should track panel progression to identify content abandonment points
TutorialEvent::PreviousPanel
TutorialEvent::PreviousPanel enables backward navigation within active tutorial sequence, allowing players to review previously displayed content. This event implements boundary-constrained reverse progression maintaining intuitive navigation semantics.
Navigation Semantics:
- Event processed only when TutorialManager.active_tutorial_id is Some(id)
- Boundary check: if current_panel_index > 0, decrement index by one
- Boundary enforced: at first panel (index == 0), event has no effect—index remains zero
- No automatic closure or special behaviors on reverse navigation
- Silently ignored when no active tutorial exists
Progression Characteristics:
- Linear backward navigation only—moves exactly one panel toward sequence start
- Minimum index enforced at zero—no negative index states possible
- No content validation during navigation—assumes panels vector integrity maintained
- Reverse navigation does not affect TutorialLog tracking or completion status
Usage Patterns:
- Primarily triggered by player interaction with “Prev” UI button
- Enables content review for complex instructions requiring multiple exposures
- Supports player-paced learning without time pressure
- Particularly valuable for text-heavy panels or complex visual demonstrations
Edge Cases:
- Emitted at first panel: silently ignored without visual feedback in default implementation
- Rapid successive emissions: each processed individually with bounds checking
- Combined with NextPanel in same frame: last processed event determines final index
- No visual disable state for “Prev” button at first panel—relies on interaction filtering
Performance Characteristics:
- Single comparison and potential decrement operation per event
- O(1) panel access via vector indexing after state update
- No memory allocations or asset operations during navigation
- Minimal computational overhead—suitable for high-frequency emission
Design Rationale:
- Boundary enforcement prevents invalid state transitions without explicit error conditions
- Silent ignore at boundary provides graceful degradation versus error states
- Reverse navigation support acknowledges varied player comprehension speeds
- No completion tracking impact maintains consistent progress semantics regardless of navigation path
Best Practices:
- Panel content should be self-contained to support non-sequential review
- Avoid pronouns with ambiguous antecedents that assume sequential reading
- Consider visual indicators showing panel position within sequence (e.g., “2 of 5”)
- Analytics systems should track reverse navigation frequency to identify confusing content sections
- UI should provide subtle visual feedback when Prev button inactive at first panel
TutorialEvent::Close
TutorialEvent::Close terminates active tutorial presentation immediately regardless of current panel position. This event provides explicit cancellation pathway complementing automatic closure at sequence end, returning game to normal state without completing tutorial sequence.
Termination Pipeline:
- Event received by handle_tutorial_events system during processing phase
- TutorialManager.active_tutorial_id set to None unconditionally
- current_panel_index value discarded—no preservation for potential resumption
- Info log emitted recording tutorial closure for diagnostics
- Subsequent systems detect state change:
- manage_tutorial_game_state restores input state and time scale
- update_tutorial_ui despawns entire UI hierarchy
- Game returns to normal interaction state within same frame
State Restoration:
- Input state: InputState resource re-enabled if integration configured
- Time scale: Restored to value cached in TutorialManager.previous_time_scale
- Cursor state: External systems responsible for re-confinement if previously unlocked
- UI state: Complete removal of tutorial interface entities
- No partial state restoration—transition atomic from tutorial to normal state
Usage Patterns:
- Primarily triggered by player interaction with “Close” UI button
- Can be emitted programmatically to interrupt tutorials based on game events (e.g., enemy encounter during tutorial)
- Systems monitoring player frustration signals might trigger closure to prevent negative experience
- Optional tutorials might auto-close after timeout period if player inactive
Edge Cases:
- Emitted with no active tutorial: silently ignored without side effects
- Emitted simultaneously with navigation events: closure takes precedence due to state replacement
- Rapid closure/reopen sequences: each processed independently with full state transitions
- Closure during asset loading: UI despawn cancels pending image loads through entity removal
Progress Tracking Semantics:
- Tutorial marked as “played” in TutorialLog regardless of completion status
- play_only_once enforcement prevents future activations even after premature closure
- No distinction between completed and cancelled tutorials in tracking system
- Design decision favors simplicity over granular completion metrics
Performance Characteristics:
- O(1) state update operation (Option set to None)
- UI cleanup involves recursive entity despawn proportional to UI complexity
- Time scale restoration single assignment operation
- Input state restoration single method call if integration configured
Design Rationale:
- Immediate closure prioritizes player agency over forced completion
- No resumption capability simplifies state management—tutorials designed for single-session completion
- Consistent tracking behavior (mark played on initiation) prevents exploitation of closure mechanism
- Atomic state transition prevents partial cleanup states that could cause visual artifacts
Best Practices:
- Clearly label Close button to set player expectations about progress loss
- Consider confirmation dialog for critical tutorials if premature closure problematic
- Analytics systems should distinguish between natural completion and premature closure
- Game design should minimize situations where players feel compelled to close tutorials
- Provide alternative access to tutorial content for players who close prematurely
System Reference
handle_tutorial_events
handle_tutorial_events system serves as the central state transition engine for the tutorial system, processing queued events and updating TutorialManager state with strict validation and boundary enforcement. This system executes early in the Update schedule to ensure state changes propagate to dependent systems within the same frame.
Execution Timing:
- Registered in Update schedule alongside other tutorial systems
- Executes before update_tutorial_ui and manage_tutorial_game_state to enable same-frame state propagation
- Processes all pending events in single execution pass—no partial processing across frames
- Event processing completes before any UI or game state modifications occur
Event Processing Algorithm:
- Drain TutorialEventQueue.0 vector into local Vec collection
- Iterate drained events in FIFO order preserving emission sequence
- For each event, match variant and execute corresponding state transition logic:
- Open(id): Validate existence → check play restrictions → update state → record completion
- NextPanel: Bounds check → increment index or close tutorial
- PreviousPanel: Bounds check → decrement index if not at start
- Close: Clear active tutorial state unconditionally
- Each event processed atomically—partial failures do not affect subsequent events
- All state modifications occur through exclusive mutable access to TutorialManager resource
Validation Logic:
- Tutorial existence verified via HashMap.contains_key() before any state modification
- play_only_once enforcement checks TutorialLog components on all player entities
- Panel navigation bounds verified against actual panel count before index modification
- Invalid operations silently ignored with diagnostic logging—never panic or corrupt state
- Validation occurs per-event rather than pre-processing entire queue
State Transition Guarantees:
- Atomic transitions: each event produces complete valid state or no change
- No intermediate invalid states exposed to other systems
- State changes immediately visible to subsequently executing systems in same frame
- Previous time scale captured before modification for accurate restoration
Error Handling:
- Invalid tutorial IDs: warning log with ID value, no state modification
- Completed single-play tutorials: debug log noting prevention, no state modification
- Events during invalid states (e.g., navigation without active tutorial): silently ignored
- All errors non-fatal—system continues processing subsequent events
- Comprehensive logging enables diagnostic tracing without performance impact in release builds
Performance Characteristics:
- Event processing time linear with queue size—typically 1-3 events per activation
- HashMap lookups O(1) for tutorial validation
- HashSet operations O(1) for play restriction checks
- No heap allocations during normal operation beyond initial queue drain
- Cache-friendly access patterns due to sequential event processing
Concurrency Safety:
- Exclusive mutable access to TutorialManager guaranteed by Bevy scheduler
- TutorialEventQueue resource accessed mutably only by this system
- Player entity queries use immutable access during validation phase
- TutorialLog updates use mutable queries but occur after validation to minimize lock duration
- No race conditions possible within single-threaded update stage
Debugging Support:
- Info-level logs for successful tutorial openings and closures
- Warn-level logs for invalid tutorial IDs
- Debug-level logs for play restriction enforcement
- Event processing order preserved in logs for sequence diagnostics
- All logs include tutorial names (not just IDs) for human readability
Extension Points:
- Additional event variants can be added through enum expansion
- Validation logic can be extended with custom business rules
- Analytics integration can record event processing metrics
- Conditional event suppression based on game state (e.g., prevent during cutscenes)
update_tutorial_ui
update_tutorial_ui system manages complete lifecycle of tutorial user interface including creation, content population, state updates, and cleanup. This system transforms TutorialManager state into visual representation through Bevy UI entity manipulation without developer intervention.
Execution Timing:
- Registered in Update schedule after handle_tutorial_events to react to state changes
- Executes before handle_tutorial_buttons to ensure UI exists before interaction processing
- Runs every frame regardless of tutorial state—minimal overhead when inactive
- UI updates occur within single frame of state changes for responsive presentation
State Detection Logic:
- Query TutorialManager resource for active_tutorial_id state
- Branch execution based on state:
- Some(id): Active tutorial requires UI presentation
- None: Inactive state requires UI cleanup if entities exist
- Active state further validated by checking tutorials catalog for ID existence
- Panel index bounds verified before content access to prevent panic conditions
UI Creation Pathway:
- Query TutorialRoot entities to determine UI existence
- If no TutorialRoot entities found AND active tutorial exists:
- Invoke setup_tutorial_ui helper function
- Construct complete UI hierarchy with parent-child relationships
- Apply marker components to relevant entities for future queries
- Populate initial content from current panel data
- Entire hierarchy created within single commands scope for atomic appearance
- Creation occurs only once per tutorial activation—subsequent frames update existing UI
UI Update Pathway:
- When UI exists AND active tutorial state valid:
- Query TutorialTitleText entities → update Text content with panel title
- Query TutorialDescriptionText entities → update Text content with panel description
- Query TutorialPanelImage entities → reload image asset if panel specifies image_path
- Content updates occur through direct component mutation without hierarchy reconstruction
- Image updates conditional on path presence to avoid unnecessary asset server queries
- Text updates occur unconditionally—minimal cost compared to hierarchy rebuild
UI Cleanup Pathway:
- When active_tutorial_id is None AND TutorialRoot entities exist:
- Iterate all TutorialRoot entities
- Despawn each with recursive children removal
- Complete cleanup prevents entity leakage across tutorial sessions
- Cleanup occurs immediately upon state transition—no delayed removal
- Despawn operations batched within single commands scope for efficiency
Performance Optimizations:
- Existence checks prevent unnecessary queries when UI state matches manager state
- Conditional image updates avoid redundant asset loading operations
- Direct component mutation avoids costly UI hierarchy reconstruction
- Single-frame lifecycle transitions prevent visual flickering or partial states
- Queries filtered by marker components for precise target identification
Error Resilience:
- Missing tutorial content handled gracefully—UI not created if catalog lookup fails
- Partial UI hierarchies (e.g., missing title entity) handled through query iteration without panic
- Asset loading failures result in blank image region—no system crash
- Entity despawn operations safe even if entities already removed externally
Visual Consistency Guarantees:
- UI always reflects current TutorialManager state—no stale content display
- Panel transitions produce immediate visual updates within same frame
- Cleanup operations complete before next tutorial activation possible
- Default styling provides readable presentation across varied game backgrounds
Extension Opportunities:
- Additional systems can attach animations to TutorialRoot entities for entrance/exit effects
- Theming systems can modify styling properties through marker component queries
- Localization systems can intercept content updates for runtime text replacement
- Analytics systems can timestamp UI creation for engagement duration metrics
handle_tutorial_buttons system processes player interactions with tutorial navigation controls, translating UI interaction states into TutorialEvent emissions for state management. This system provides responsive visual feedback while maintaining clean separation between presentation and state logic.
Interaction Detection:
- Query entities with three constraints:
- Interaction component (Bevy UI standard interaction state)
- TutorialButton component (custom marker with associated event)
- Changed filter (process only entities with state changes this frame)
- Changed filter critical for performance—avoids processing static buttons every frame
- Query returns tuples of (Interaction, TutorialButton, BackgroundColor) for simultaneous state reading and visual feedback
State Transition Handling:
For each matching entity, system evaluates current Interaction state:
- Interaction::Pressed:
- Push TutorialButton’s stored event into TutorialEventQueue
- Update BackgroundColor to darker shade (0.4,0.4,0.4) for press feedback
- Interaction::Hovered:
- Update BackgroundColor to medium shade (0.3,0.3,0.3) for hover indication
- Interaction::None:
- Update BackgroundColor to base shade (0.2,0.2,0.2) for default state
Visual Feedback Characteristics:
- Color transitions immediate with interaction state changes—no animation delay
- Three distinct visual states provide clear interaction affordances
- Color values chosen for sufficient contrast against dark panel background
- Feedback occurs independently of event emission—responsive even with frame delay before state update
- No sound effects or haptic feedback in default implementation—requires external integration
Performance Characteristics:
- Changed filter reduces query processing to only interactive frames
- Typical interaction rate 1-2 state changes per button press cycle
- Color updates occur through direct component mutation—minimal overhead
- Event emission involves single vector push operation
- No heap allocations during normal operation
Button State Management:
- No explicit disable state for “Prev” button at first panel
- Interaction filtering implicitly prevents navigation beyond boundaries
- Visual appearance remains consistent regardless of navigational validity
- Alternative implementations could add explicit disable styling through additional systems
Concurrency Safety:
- TutorialEventQueue accessed mutably but system executes single-threaded in Update stage
- BackgroundColor components accessed mutably with exclusive access guaranteed by scheduler
- No race conditions between visual feedback and event emission—both occur in single system execution
- Interaction component accessed immutably during state evaluation
Extension Points:
- Additional interaction states could trigger custom behaviors (e.g., long-press for skip)
- Visual feedback could extend beyond color to scale/opacity animations
- Sound effect systems could listen for Interaction::Pressed on TutorialButton entities
- Haptic feedback systems could integrate with button press events
- Accessibility systems could enhance feedback for assistive technologies
Design Rationale:
- Decoupled interaction handling separates presentation concerns from state logic
- Visual feedback immediate even with event processing delay in subsequent systems
- Minimalist implementation focuses on core functionality—extensions through composition
- Changed filter essential for performance with potentially numerous UI entities
manage_tutorial_game_state
manage_tutorial_game_state system coordinates global game parameters during tutorial presentation, applying configured modifications to time scale and input state while ensuring proper restoration upon completion. This system acts as integration layer between tutorial system and core game mechanics.
State Detection:
- Query TutorialManager resource for active_tutorial_id state
- Branch execution based on presence of active tutorial:
- Some(id): Apply tutorial-specific game state modifications
- None: Restore default game state parameters
- Tutorial catalog lookup validates configuration flags before applying modifications
- System designed to be non-invasive—only modifies state when explicitly configured
Input State Management:
- Conditional integration with optional InputState resource through Option<ResMut> parameter
- When tutorial.pause_input is true AND InputState resource exists:
- Call input.set_input_enabled(false) to disable standard gameplay input processing
- When no active tutorial AND InputState resource exists:
- Call input.set_input_enabled(true) to restore normal input processing
- InputState integration optional—games without this pattern simply omit the resource
- No assumptions about InputState internal implementation—relies on standardized interface
Time Scale Management:
- When tutorial.set_custom_time_scale is true:
- Capture current time scale into TutorialManager.previous_time_scale if not already stored
- Apply tutorial.custom_time_scale via time.set_relative_speed()
- When no active tutorial:
- Restore time scale to TutorialManager.previous_time_scale value
- Default restoration to 1.0 if previous value unavailable (defensive programming)
- Time scale modifications affect entire game uniformly—physics, animations, scripts
- Restoration occurs unconditionally on tutorial closure regardless of modification history
Cursor State Considerations:
- unlock_cursor flag present in Tutorial struct but no direct implementation
- Flag serves as signal for external cursor management systems
- Tutorial system does not directly control cursor confinement state
- Integration requires separate system observing TutorialManager state and unlock_cursor flag
- Design decision maintains separation of concerns—tutorial system focuses on educational content
State Restoration Guarantees:
- Input state always restored to enabled when tutorial closes
- Time scale always restored to pre-tutorial value or 1.0 default
- Restoration occurs even after abnormal termination (e.g., Close event)
- No persistent state leakage between tutorial sessions
- Atomic transitions prevent partial restoration states
Performance Characteristics:
- Minimal per-frame overhead—single resource query and conditional branches
- No heap allocations during normal operation
- Time scale operations involve single float assignment
- Input state operations involve single method call if integration configured
- Efficient even with frequent tutorial activations/deactivations
Error Resilience:
- Missing InputState resource handled gracefully—no panic or error logs
- Invalid time scale values (negative) permitted but may cause unexpected game behavior
- Restoration to 1.0 default prevents stuck time states if previous value lost
- No assumptions about game architecture beyond standard Bevy resources
Integration Patterns:
- InputState resource should implement set_input_enabled(bool) method for compatibility
- Cursor management systems should query TutorialManager and unlock_cursor flag
- Additional game systems can observe TutorialManager state for custom behaviors
- Systems should avoid tight coupling—prefer observation over direct tutorial system dependencies
Design Philosophy:
- Minimalist integration approach—tutorial system signals intentions without enforcing implementations
- Configurable per-tutorial rather than global settings enable precise control
- Restoration guarantees prevent common bugs in tutorial-heavy games
- Separation of concerns maintains system modularity and testability
Advanced Features
Single-Play Tutorials
The play_only_once feature provides sophisticated control over tutorial repetition, enabling personalized learning experiences that respect player expertise while ensuring newcomers receive necessary guidance. This feature operates through coordinated interaction between Tutorial definitions, TutorialLog components, and event processing logic.
Implementation Mechanics:
- Tutorial struct includes boolean play_only_once field set during content definition
- During TutorialEvent::Open processing, system checks this flag before state modification
- When true, system queries all TutorialLog components on player entities
- HashSet in TutorialLog checked for tutorial ID membership before activation
- If ID found in set AND play_only_once true, activation aborted with diagnostic log
- TutorialLog updated immediately upon successful validation—not after completion
- Update occurs before UI creation to prevent rapid duplicate triggers within single session
Player Experience Design:
- Prevents frustration from redundant tutorials for experienced players
- Ensures critical onboarding content presented to new players exactly once
- Immediate tracking (on initiation vs completion) prevents exploitation through premature closure
- No distinction between completed and cancelled tutorials—both count as “played”
- Design decision favors simplicity and exploit prevention over granular completion tracking
Content Strategy Implications:
- Core mechanics tutorials should typically enable play_only_once
- Reference materials and optional hints should typically disable play_only_once
- Contextual help systems benefit from repeatable access to relevant information
- Games with significant mechanical depth may segment tutorials into progressive tiers
- Each tier can use play_only_once while allowing access to prior tier content
Edge Case Handling:
- Multiple player entities: all TutorialLog components updated simultaneously
- Tutorial definition changes: existing TutorialLog entries remain valid—ID-based tracking
- Tutorial removal: orphaned IDs in TutorialLog harmless but consume minimal storage
- New Game+ scenarios: require explicit TutorialLog reset through game design systems
- Multiplayer sessions: server should validate tutorial eligibility to prevent cheating
Performance Characteristics:
- HashSet lookup provides O(1) validation performance critical for frequent checks
- Typical games with 20-50 tutorials maintain negligible memory footprint (<1KB)
- Validation occurs only during activation attempts—not per-frame overhead
- Serialization size minimal due to compact integer storage in save games
Analytics Integration:
- TutorialLog state provides completion metrics without additional tracking
- Systems can query played_tutorials for engagement analytics
- Time-to-completion metrics require additional timestamp tracking component
- Abandonment analysis possible by comparing TutorialLog state with gameplay progression
Customization Opportunities:
- Tiered completion tracking: extend TutorialLog with completion quality metrics
- Conditional replay: systems could offer “Show Again” options for completed tutorials
- Progressive disclosure: subsequent tutorials could adapt content based on prior completion
- Achievement integration: tutorial completion could trigger achievement unlocks
Cursor Management
Cursor management during tutorials addresses the fundamental tension between gameplay interaction models and UI navigation requirements. While the tutorial system provides the unlock_cursor configuration flag, actual cursor state control requires integration with game-specific cursor management systems due to Bevy’s lack of standardized cursor API.
Architectural Approach:
- Tutorial struct includes unlock_cursor boolean flag for configuration
- Flag serves as signal rather than direct control mechanism
- Tutorial system does not directly manipulate cursor state—maintains separation of concerns
- Integration requires separate system observing TutorialManager state and unlock_cursor flag
- System should handle both activation (unlock) and deactivation (relock) transitions
Integration Pattern:
- Create cursor management system with appropriate access to window/input resources
- System queries TutorialManager resource each frame
- When active_tutorial_id becomes Some(id):
- Retrieve tutorial configuration
- If unlock_cursor true, release cursor confinement
- When active_tutorial_id becomes None:
- Restore previous cursor confinement state
- System should cache previous state for accurate restoration
Cursor State Transitions:
- Unlock operations should occur before UI creation to ensure immediate interactivity
- Relock operations should occur after UI cleanup to prevent interaction with disappearing elements
- Transition timing critical for seamless player experience—frame-accurate coordination preferred
- Visual cursor changes (e.g., icon updates) should accompany state transitions for feedback
Gameplay Considerations:
- First-person games typically confine cursor during gameplay—tutorials require temporary release
- Strategy games may already have free cursor—unlock_cursor flag may be irrelevant
- Games with mixed interaction models need sophisticated cursor state management
- Tutorial navigation should never require cursor actions conflicting with gameplay inputs
Technical Implementation Options:
- Bevy window cursor grab mode manipulation via primary window resource
- Custom cursor visibility/state management systems
- Input mapping systems that reinterpret mouse movements during tutorials
- Hybrid approaches combining multiple techniques for robust behavior
Edge Cases:
- Rapid tutorial activation/deactivation sequences require state caching to prevent oscillation
- Multiple overlapping UI systems may conflict over cursor control—coordination required
- Platform-specific cursor behaviors (mobile touch vs desktop mouse) require abstraction
- Accessibility settings may override standard cursor behaviors—respect user preferences
Best Practices:
- Always restore original cursor state upon tutorial completion
- Provide visual feedback for cursor state changes (icon updates, border highlights)
- Test cursor behavior across all tutorial entry/exit scenarios including interruptions
- Consider player expectations—sudden cursor confinement changes can disorient
- Document cursor requirements clearly for tutorial content designers
Input pausing provides critical isolation between tutorial presentation and gameplay mechanics, preventing unintended player actions that could disrupt instructional moments or create negative experiences. This feature operates through configurable integration with game-specific input state management systems.
Implementation Architecture:
- Tutorial struct includes pause_input boolean flag for per-tutorial configuration
- manage_tutorial_game_state system conditionally interacts with optional InputState resource
- Integration requires InputState resource to implement set_input_enabled(bool) method
- When flag true AND resource exists, input disabled during tutorial activation
- Input automatically re-enabled when tutorial closes regardless of closure method
- Restoration occurs even after abnormal termination (Close event, sequence completion)
Input State Semantics:
- “Paused” input means gameplay actions disabled—not UI navigation
- Tutorial UI buttons remain fully interactive during input pause
- Input pause should not affect system-level inputs (pause menu, volume controls)
- Distinction between gameplay input and UI input critical for proper implementation
- InputState resource should maintain this distinction internally
Integration Requirements:
- Games must implement InputState resource with standardized interface
- Resource must track previous enabled state for accurate restoration
- Input processing systems should query InputState before handling gameplay actions
- UI interaction systems should bypass InputState checks for tutorial navigation
- No assumptions about input implementation—works with action states, direct polling, or event systems
Player Experience Considerations:
- Input pause essential for tutorials demonstrating complex mechanics
- Prevents player frustration from accidental actions during instruction moments
- Should be used judiciously—excessive pausing breaks gameplay flow
- Visual or audio cues should indicate input pause state to player
- Duration should be minimized—only during critical instructional moments
Configuration Strategy:
- Movement tutorials: typically require input pause to prevent wandering
- Combat tutorials: often require input pause during demonstration phases
- Menu/navigation tutorials: typically do not require input pause
- Contextual hints: rarely require input pause—designed for minimal disruption
- Progressive complexity: early tutorials may pause input, later reference materials may not
Edge Case Handling:
- InputState resource missing: system silently continues without error—non-invasive design
- Multiple input systems: all should respect InputState enabled flag
- Input re-enabled before UI cleanup: prevents interaction with disappearing elements
- Rapid activation/deactivation: state restoration must handle nested transitions correctly
- Emergency inputs: consider allowing critical actions (pause menu) even during input pause
Performance Characteristics:
- Single boolean check per frame when tutorial active
- Method call overhead negligible compared to input processing costs
- No per-frame overhead when no active tutorial
- Cache-friendly access pattern due to single resource query
Testing Recommendations:
- Verify input truly disabled during tutorial presentation
- Confirm input restored after all closure methods (NextPanel completion, Close button)
- Test rapid tutorial activation/deactivation sequences
- Validate emergency inputs (pause menu) still functional if desired
- Check input state after game interruptions (alt-tab, focus loss)
Time Scale Control
Time scale manipulation enables sophisticated tutorial presentations including slow-motion demonstrations and complete pauses, providing players optimal conditions for observing complex mechanics. This feature leverages Bevy’s standard time management system for seamless integration with physics, animation, and gameplay systems.
Implementation Mechanics:
- Tutorial struct includes two related fields:
- set_custom_time_scale: boolean flag enabling time modification
- custom_time_scale: f32 value specifying target time scale (0.0 = pause, 1.0 = normal)
- manage_tutorial_game_state system handles time scale transitions
- Previous time scale cached in TutorialManager.previous_time_scale before modification
- Restoration occurs unconditionally when tutorial closes—prevents stuck time states
- Default restoration to 1.0 if cached value unavailable (defensive programming)
Time Scale Semantics:
- Value 1.0: Normal game speed—baseline for all mechanics
- Value 0.0: Complete pause—physics, animations, scripts all suspended
- Values 0.0-1.0: Slow motion—proportional reduction in all time-dependent systems
- Values >1.0: Accelerated time—rarely used for tutorials but technically supported
- Affects all Bevy time-dependent systems uniformly—no selective application
Pedagogical Applications:
- Complex combat combos: slow motion (0.3) reveals timing nuances
- Physics interactions: pause (0.0) allows examination of spatial relationships
- Rapid sequences: slow motion makes fleeting moments observable
- Environmental hazards: pause enables safe observation of danger patterns
- Multi-step processes: controlled pacing guides attention through sequence
Configuration Guidelines:
- Demonstration panels: typically use slow motion (0.2-0.4) for observation
- Instructional panels: typically use pause (0.0) for undivided attention
- Practice panels: typically use normal speed (1.0) for authentic application
- Transition panels: gradual time scale changes can smooth pacing shifts
- Avoid extreme values (<0.1 or >2.0) that distort player perception
Integration Considerations:
- Physics systems automatically respect time scale—no special handling required
- Animation systems should use Time::delta() for frame-independent updates
- Scripts using fixed timestep may require additional consideration
- Audio pitch typically unaffected—may require separate pitch scaling for realism
- Networked games must handle time scale carefully to avoid desynchronization
Edge Case Handling:
- Nested tutorials: time scale restoration must handle multiple layers correctly
- Rapid activation/deactivation: cached previous value prevents drift
- Missing cache value: defensive restoration to 1.0 prevents stuck states
- Conflicting time modifications: tutorial system assumes ownership during active state
- Time scale during loading transitions: may require special handling
Performance Characteristics:
- Time scale modification involves single float assignment—negligible cost
- No per-frame overhead beyond standard time query operations
- Physics systems may reduce computation during slow motion—potential performance gain
- Complete pause may allow aggressive frame skipping optimizations
Player Experience Best Practices:
- Always provide visual indicator of non-normal time scale (slow-motion effect, pause icon)
- Avoid prolonged slow motion that frustrates player agency
- Use time scale changes deliberately—not as gimmick but pedagogical tool
- Restore normal speed before player practice opportunities
- Consider motion blur or other visual effects to enhance slow-motion perception
Visual Customization
Visual customization enables tutorial presentation to match game aesthetic and branding requirements while maintaining functional integrity. The system provides multiple extension points for styling modifications without requiring core system changes.
Customization Layers:
- Root styling: TutorialRoot entity background color and overlay properties
- Container styling: Panel container border, padding, and background treatments
- Typography: Title and description text fonts, sizes, colors, and alignment
- Imagery: Panel image presentation including sizing, borders, and effects
- Navigation controls: Button styling, layout arrangement, and visual feedback states
- Animations: Entrance/exit transitions and panel change effects
Extension Mechanisms:
- Marker components (TutorialRoot, TutorialTitleText, etc.) enable precise targeting
- Additional systems can query these markers to apply styling modifications
- Systems should execute after update_tutorial_ui to override default styling
- No modification of core tutorial systems required for visual customization
- Complete UI replacement possible by despawning default UI and creating custom alternative
Styling Best Practices:
- Maintain sufficient text contrast against backgrounds (WCAG AA minimum 4.5:1)
- Ensure button targets meet minimum touch size requirements (44px recommended)
- Preserve visual hierarchy: title > image > description > buttons
- Consistent styling across all tutorials establishes professional presentation
- Consider colorblind-friendly palettes for critical information presentation
- Test readability across target display resolutions and lighting conditions
Theming System Integration:
- Central theme resource can store tutorial-specific styling parameters
- Theming systems apply styles by querying tutorial marker components
- Runtime theme switching requires reapplying styles to existing UI entities
- Theme parameters should include: colors, font selections, spacing values, border radii
- Consider separate themes for light/dark mode or accessibility requirements
Animation Integration:
- Entrance animations: fade/slide effects when tutorial activates
- Exit animations: reverse entrance effects when tutorial closes
- Panel transitions: subtle animations during NextPanel/PreviousPanel navigation
- Button feedback: hover/press animations enhancing interactivity perception
- Performance consideration: avoid heavy animations during time-scaled tutorials
Localization Adaptations:
- Text container sizing should accommodate language expansion (up to 40% longer than English)
- Right-to-left language support requires layout mirroring capabilities
- Font selections must support required character sets for target languages
- Icon-based navigation aids comprehension across language barriers
Accessibility Enhancements:
- Text scaling support for vision-impaired players
- High-contrast mode with simplified color schemes
- Screen reader compatibility through semantic markup (requires Bevy UI extensions)
- Reduced motion options for players sensitive to animations
- Keyboard navigation support for tutorial controls
Panel Sequencing
Panel sequencing forms the pedagogical backbone of tutorial design, structuring information delivery to maximize comprehension and retention. The system’s linear sequencing model provides predictable navigation while supporting sophisticated content strategies through panel composition and ordering.
Sequencing Patterns:
- Linear progression: Simple A→B→C sequence for straightforward concepts
- Demonstration cycles: Show mechanic → Explain concept → Provide practice opportunity
- Complexity gradients: Simple isolated mechanic → Combined applications → Edge cases
- Problem-solution pairs: Present challenge → Reveal solution technique
- Contextual layering: Core mechanic → Environmental interactions → Advanced variations
Panel Composition Guidelines:
- Single concept focus: Each panel should convey one primary learning objective
- Progressive disclosure: Reveal complexity gradually across sequence
- Concrete before abstract: Start with observable actions before theoretical explanations
- Self-contained units: Panels should make sense when reviewed non-sequentially
- Consistent terminology: Maintain vocabulary across panels within sequence
Navigation Semantics:
- NextPanel advances linearly—no branching or conditional paths
- PreviousPanel enables review without penalty or tracking complications
- Automatic closure at sequence end provides seamless gameplay transition
- No resumption capability—tutorials designed for single-session completion
- Navigation speed controlled by player—supports varied comprehension rates
Content Density Management:
- Optimal panel count: 3-7 panels balancing completeness against attention span
- Text length: 2-5 sentences per panel maintaining scannability
- Visual reinforcement: Images should illustrate rather than decorate content
- White space: Sufficient padding prevents cognitive overload from dense layouts
- Pacing variation: Mix text-heavy and visual panels to maintain engagement
Pedagogical Effectiveness:
- Cognitive load theory: Limit novel information per panel to working memory capacity
- Dual coding: Combine verbal and visual information channels for enhanced retention
- Spacing effect: Distribute related concepts across multiple panels rather than single dense panel
- Retrieval practice: Final panels should prompt mental rehearsal of key concepts
- Emotional tone: Encouraging language enhances motivation and reduces frustration
Analytics Integration:
- Panel progression tracking identifies abandonment points requiring content refinement
- Time-per-panel metrics reveal comprehension difficulty variations
- Reverse navigation frequency indicates confusing or complex content sections
- Completion rates across tutorial sequences inform onboarding effectiveness
- Correlation with subsequent gameplay performance validates tutorial efficacy
Advanced Sequencing Techniques:
- Embedded micro-interactions: Simple player actions within tutorial context
- Progressive disclosure controls: Optional “Show More” expansions for detailed explanations
- Contextual branching: External systems trigger different tutorials based on player state
- Adaptive sequencing: Panel order adjusted based on prior player performance (requires extension)
- Multi-modal presentation: Combine text, images, and audio cues within single panel
Persistent Progress Tracking
Persistent progress tracking ensures tutorial experiences adapt to individual player journeys across game sessions, preventing redundant presentations while maintaining accessibility for reference purposes. This feature leverages Bevy’s component serialization capabilities for seamless save game integration.
Tracking Architecture:
- TutorialLog component attached to player entities stores completion history
- HashSet provides efficient O(1) lookup for play restriction enforcement
- Tracking occurs at initiation rather than completion to prevent session exploitation
- Serialization through Serde traits enables automatic save game persistence
- Component lifetime tied to player entity—persists across level transitions and game sessions
Persistence Mechanics:
- TutorialLog included in player entity serialization automatically when components serialized
- No special handling required beyond standard entity persistence setup
- Deserialization reconstructs exact completion state from save data
- New tutorials added post-save appear as unplayed to existing players
- Tutorial ID reuse should be avoided to prevent completion state corruption
Player Journey Considerations:
- New players receive complete onboarding sequence exactly once
- Returning players skip completed tutorials but retain access to reference materials
- Multiple save slots maintain independent completion states per slot
- Cloud saves synchronize tutorial progress across devices seamlessly
- New Game+ modes may optionally reset TutorialLog for fresh experience
Edge Case Handling:
- Corrupted save data: TutorialLog deserialization failures should not prevent game load
- Tutorial removal: orphaned IDs in HashSet harmless but consume minimal storage
- ID reassignment: dangerous practice—could grant unintended completion status
- Multiplayer sessions: server-authoritative validation prevents client-side manipulation
- Demo/full game transitions: completion state may transfer if designed appropriately
Privacy and Analytics:
- Completion data remains on player device unless explicitly transmitted
- Analytics systems can query TutorialLog for engagement metrics with player consent
- Aggregated completion statistics inform tutorial effectiveness without individual tracking
- Opt-out mechanisms should be provided for analytics participation
- Compliance with regional data protection regulations (GDPR, CCPA) required for transmission
Advanced Tracking Extensions:
- Completion timestamps enable time-to-learn analytics
- Panel-level tracking identifies specific comprehension challenges
- Attempt counters distinguish between successful completion and abandonment
- Quality metrics capture player performance during tutorial practice segments
- Contextual tags associate completions with gameplay circumstances (location, level, etc.)
Performance Characteristics:
- HashSet memory footprint scales linearly with completed tutorials (<1KB typical)
- Lookup operations occur only during activation attempts—not per-frame overhead
- Serialization size minimal due to compact integer storage
- Deserialization time negligible compared to asset loading operations
Design Philosophy:
- Player respect: tracking prevents redundant experiences without locking content
- Simplicity: binary played/unplayed model avoids complex state management
- Transparency: players should understand when content is being skipped due to prior completion
- Accessibility: reference materials should remain accessible regardless of completion status
- Extensibility: foundation supports richer tracking models through component extensions
Integration Guide
Plugin Registration
Plugin registration establishes the tutorial system within your Bevy application’s architecture, initializing required resources and registering systems with the scheduler. Proper registration ensures seamless integration with existing game systems and correct initialization ordering.
Basic Registration:
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(TutorialPlugin)
// ... other plugins and systems
.run();
Initialization Order Considerations:
- TutorialPlugin should register after core plugins (DefaultPlugins) providing UI and asset systems
- Register before systems that might emit TutorialEvent variants to ensure event queue exists
- InputState resource integration requires InputState registration before TutorialPlugin if dependency exists
- Serialization support requires ReflectPlugin registration before TutorialPlugin for proper type registration
Custom Initialization Patterns:
- Games with complex initialization may need to populate TutorialManager after plugin registration:
app.add_plugins(TutorialPlugin);
let mut manager = app.world.resource_mut::<TutorialManager>();
manager.tutorials.insert(1000, movement_tutorial());
manager.tutorials.insert(1001, combat_tutorial());
- Asset-based tutorial loading requires asset system readiness before population:
// In asset loading completion system:
let mut manager = world.resource_mut::<TutorialManager>();
manager.tutorials.extend(loaded_tutorials);
Plugin Configuration Options:
- Current implementation provides no configuration parameters—designed for zero-configuration usage
- Future extensions may support configuration struct for default styling or behavior overrides
- Customization achieved through additional systems rather than plugin parameters
- Resource pre-initialization enables configuration before first frame
System Execution Ordering:
- Tutorial systems register in Update schedule without explicit ordering constraints
- Implicit ordering: handle_tutorial_events → update_tutorial_ui → handle_tutorial_buttons → manage_tutorial_game_state
- Custom systems interacting with tutorial state should consider this ordering:
- Emit events before handle_tutorial_events execution
- Read UI state after update_tutorial_ui execution
- Modify game state considering manage_tutorial_game_state effects
Testing Integration:
- Unit tests can construct App with TutorialPlugin for integration testing
- Test harnesses should initialize TutorialManager with test-specific tutorials
- Player entities require TutorialLog components for complete behavior simulation
- Event emission should use TutorialEventQueue resource rather than Bevy Events for reliability
Migration from Prior Versions:
- Plugin interface stable across minor versions—no registration changes expected
- Major version upgrades may require resource/component type updates
- Serialization format changes may require migration logic for save compatibility
- Always review changelog before upgrading tutorial system version
Tutorial Definition
Tutorial definition transforms educational content into structured data the system can present, requiring careful attention to pedagogical design alongside technical specification. Well-constructed tutorials balance informational density with player comprehension capacity.
Content Structure:
- Tutorial ID: Unique u32 identifier with semantic meaning (e.g., 1000s for movement, 2000s for combat)
- Tutorial name: Human-readable identifier for logging/debugging (not player-facing)
- Panel sequence: Ordered Vec with 3-7 panels optimal for engagement
- Configuration flags: play_only_once, unlock_cursor, pause_input, time scale settings per tutorial needs
Panel Authoring Guidelines:
- Title field: 3-7 word concise summary using active voice (“Jumping Mechanics” not “About Jumping”)
- Description field: 2-5 sentence explanatory text following concrete → abstract progression
- Image path: Optional visual reinforcement illustrating concepts described in text
- Panel sequencing: Each panel should build upon prior knowledge while remaining self-contained
Configuration Strategy:
- play_only_once: Enable for core mechanics tutorials, disable for reference materials
- unlock_cursor: Enable when tutorial requires mouse interaction with UI elements
- pause_input: Enable for demonstration panels, disable for practice opportunities
- time scale: Set 0.3 for slow-motion demonstrations, 0.0 for complete pauses during critical instructions
Content Creation Workflow:
- Identify learning objective for tutorial sequence
- Decompose objective into 3-7 atomic concepts for individual panels
- Author panel content following progressive disclosure principles
- Select appropriate configuration flags based on interaction requirements
- Assign unique ID within semantic namespace
- Register tutorial with TutorialManager during initialization
- Test tutorial flow with target audience for comprehension validation
Localization Preparation:
- Externalize all text content to localization files rather than hardcoded strings
- Reserve space for text expansion (up to 40% longer than English equivalents)
- Avoid text embedded in images—use separate image assets with localization variants
- Consider cultural appropriateness of visual examples across target markets
Asset Management:
- Image assets should follow consistent naming convention tied to tutorial IDs
- Recommended resolution 800×400 pixels matching default UI container proportions
- Texture formats should match project standards (typically PNG for UI elements)
- Asset loading occurs asynchronously—design for graceful degradation during load
Validation Practices:
- Verify all tutorial IDs unique within catalog before registration
- Confirm panel sequences contain at least one panel to prevent immediate closure
- Validate image paths resolve to existing assets during build process
- Test tutorial flow with play_only_once enabled to verify completion tracking
- Review configuration flags against actual tutorial interaction requirements
Version Control Considerations:
- Tutorial content should reside in version-controlled data files separate from code
- Semantic versioning for tutorial content enables compatibility tracking
- Change history should document pedagogical rationale for content modifications
- A/B testing frameworks may require multiple tutorial variants under same ID namespace
Player Entity Setup
Player entity setup establishes the per-player state tracking required for personalized tutorial experiences, ensuring completion history persists across game sessions and adapts to individual player journeys.
Component Attachment:
- TutorialLog component must be attached to primary player entity during creation
- Default initialization creates empty HashSet ready for first completion
- Component should persist for entity lifetime—never removed or replaced
- Multiple player entities (multiplayer) each require independent TutorialLog components
Entity Query Patterns:
- Systems triggering tutorials should query TutorialLog before emitting Open events:
// Example validation before tutorial trigger
if let Ok(log) = player_entity.get::<TutorialLog>() {
if !log.played_tutorials.contains(&tutorial_id) {
event_queue.0.push(TutorialEvent::Open(tutorial_id));
}
}
- Analytics systems can query TutorialLog for completion metrics
- Optional tutorial systems can offer “Show Again” based on TutorialLog state
Persistence Integration:
- TutorialLog automatically included in entity serialization when components serialized
- No special handling required beyond standard save game implementation
- Deserialization reconstructs exact completion state from save data
- New game sessions should create fresh TutorialLog with empty HashSet
Multiplayer Considerations:
- Each player entity maintains independent TutorialLog state
- Server-authoritative validation prevents client-side manipulation of completion state
- Tutorial triggers should originate from server to prevent cheating
- Synchronization of TutorialLog across clients typically unnecessary—local state sufficient
New Game+ Implementation:
- Resetting tutorial progress requires explicit TutorialLog modification:
// In New Game+ initialization system
for mut log in &mut tutorial_logs {
log.played_tutorials.clear();
}
- Selective reset possible by removing specific tutorial IDs from HashSet
- Consider player expectations—some may want to retain reference material access
- Analytics should track New Game+ starts separately from initial playthroughs
Edge Case Handling:
- Missing TutorialLog component: tutorials always trigger (no play restriction enforcement)
- Corrupted serialization: implement defensive deserialization with fallback to empty set
- Entity recreation: ensure TutorialLog preserved during player entity transformations
- Save migration: handle TutorialLog format changes during version upgrades
Performance Characteristics:
- HashSet memory footprint negligible (<1KB for 50 tutorials)
- Lookup operations infrequent—only during tutorial trigger attempts
- Serialization size minimal due to compact integer storage
- No per-frame overhead from TutorialLog presence alone
Testing Recommendations:
- Verify TutorialLog attached during all player creation paths (new game, load, respawn)
- Test completion tracking across save/load cycles
- Validate play restriction enforcement with play_only_once tutorials
- Confirm New Game+ reset functionality operates correctly
- Test multiplayer scenarios with independent player completion states
Triggering Tutorials
Tutorial triggering bridges game events with educational content delivery, requiring thoughtful integration to provide timely guidance without disrupting gameplay flow. Effective triggering balances player need with contextual appropriateness.
Trigger Sources:
- Spatial triggers: Player entering designated tutorial zones in game world
- Interaction triggers: First interaction with game mechanic or object type
- Progression triggers: Quest milestones, level completion, achievement unlocks
- Behavioral triggers: Systems detecting player struggle patterns (repeated failures)
- Explicit triggers: Player-initiated help requests through menu systems
- Temporal triggers: Time-based reminders after extended gameplay without mechanic usage
Trigger Implementation Patterns:
- Spatial trigger example:
// System detecting player in tutorial zone
fn movement_tutorial_trigger(
player_query: Query<&Transform, With<Player>>,
tutorial_zones: Query<(&Transform, &TutorialZone)>,
mut event_queue: ResMut<TutorialEventQueue>,
tutorial_logs: Query<&TutorialLog>,
) {
for (player_transform, (zone_transform, zone)) in
player_query.iter().zip(tutorial_zones.iter()) {
if player_transform.translation.distance(zone_transform.translation) < zone.radius {
if !has_completed(&tutorial_logs, zone.tutorial_id) {
event_queue.0.push(TutorialEvent::Open(zone.tutorial_id));
}
}
}
}
- Interaction trigger example:
// System detecting first weapon pickup
fn weapon_tutorial_trigger(
mut pickup_events: EventReader<WeaponPickupEvent>,
mut event_queue: ResMut<TutorialEventQueue>,
tutorial_logs: Query<&TutorialLog>,
) {
for event in pickup_events.read() {
if event.is_first_weapon && !has_completed(&tutorial_logs, 2000) {
event_queue.0.push(TutorialEvent::Open(2000));
}
}
}
Contextual Appropriateness:
- Avoid triggering during combat or other high-intensity gameplay moments
- Provide brief visual/audio cue before tutorial activation for player preparation
- Consider player velocity/momentum—trigger when player relatively stationary
- Respect player intent—avoid interrupting deliberate actions in progress
- Allow player to defer tutorials with “Remind Me Later” option for non-critical content
Trigger Validation:
- Always check TutorialLog before emitting Open events to prevent redundant triggers
- Validate tutorial existence in catalog to avoid invalid ID errors
- Consider game state—avoid triggers during cutscenes, loading transitions, or menus
- Implement cooldown periods between non-critical tutorial triggers to prevent spam
- Prioritize triggers—resolve conflicts when multiple tutorials eligible simultaneously
Progressive Triggering:
- Sequence tutorials based on player progression through game mechanics
- Gate advanced tutorials behind completion of prerequisite tutorials
- Adjust trigger sensitivity based on player performance (more hints for struggling players)
- Reduce trigger frequency for players demonstrating mechanic proficiency
- Maintain trigger eligibility for optional tutorials regardless of progression
Analytics Integration:
- Log all trigger attempts with context (location, game state, player stats)
- Track trigger-to-completion conversion rates to identify ineffective triggers
- Monitor time between trigger and player action to measure receptiveness
- Correlate trigger timing with subsequent gameplay performance improvements
- Identify over-triggering patterns causing player frustration or tutorial avoidance
Edge Case Handling:
- Rapid successive triggers: implement queuing or prioritization to prevent overlap
- Tutorial interruption: handle game events requiring immediate attention during tutorial
- Trigger during tutorial: defer or cancel based on priority assessment
- Multi-trigger conflicts: establish clear priority hierarchy for resolution
- Network latency: server-authoritative triggers require client prediction handling
Best Practices:
- Trigger tutorials at natural gameplay pauses rather than interrupting flow
- Provide clear visual indication of trigger source (highlighted object, zone boundary)
- Allow players to disable non-critical tutorial triggers through settings menu
- Design triggers to feel organic rather than artificial interruptions
- Test trigger placement extensively with target audience to validate timing appropriateness
Custom UI Integration
Custom UI integration enables tutorial presentation to match game aesthetic and functional requirements beyond default implementation, leveraging marker components and system composition for non-invasive customization.
Customization Approaches:
- Styling override: Modify visual properties of existing UI through additional systems
- Component extension: Attach additional components to tutorial UI entities for enhanced behaviors
- Complete replacement: Despawn default UI and construct custom alternative hierarchy
- Hybrid approach: Retain default structure with selective replacements for specific elements
Styling Override Pattern:
// System applying custom theme to tutorial UI
fn apply_tutorial_theme(
root_query: Query<Entity, With<TutorialRoot>>,
mut background_query: Query<&mut BackgroundColor, With<TutorialRoot>>,
theme: Res<GameTheme>,
) {
for (entity, mut bg) in root_query.iter().zip(background_query.iter_mut()) {
bg.0 = theme.tutorial_background_color;
// Additional styling queries for title, description, buttons...
}
}
Complete Replacement Pattern:
- Register system after update_tutorial_ui with #[system(order = 2)]
- Query TutorialRoot entities created by default system
- Despawn entire hierarchy recursively
- Construct custom UI hierarchy with equivalent functionality
- Maintain TutorialButton components on navigation controls for event integration
Extension Component Pattern:
// Custom component for tutorial-specific animations
#[derive(Component)]
struct TutorialEntranceAnimation {
elapsed: f32,
duration: f32,
}
// System adding animation component to new tutorial UI
fn add_tutorial_animations(
mut commands: Commands,
new_roots: Query<Entity, (With<TutorialRoot>, Added<TutorialRoot>)>,
) {
for entity in new_roots.iter() {
commands.entity(entity).insert(TutorialEntranceAnimation {
elapsed: 0.0,
duration: 0.3,
});
}
}
Layout Customization:
- Modify Node properties on TutorialRoot for positioning adjustments
- Adjust container dimensions to accommodate game-specific aspect ratios
- Implement responsive layout adapting to screen resolution changes
- Support multiple display orientations (landscape/portrait) for mobile targets
- Consider safe area insets for notched displays on mobile platforms
Theming System Integration:
- Central Theme resource stores tutorial-specific styling parameters
- Theming system queries tutorial marker components to apply styles
- Runtime theme switching requires reapplying styles to existing UI entities
- Support light/dark mode variants through theme parameterization
- Accessibility themes provide high-contrast alternatives for vision-impaired players
Animation Integration:
- Entrance animations: fade/slide effects when tutorial activates
- Exit animations: reverse entrance effects with cleanup after completion
- Panel transitions: subtle animations during navigation enhancing flow perception
- Button feedback: hover/press animations improving interactivity perception
- Performance consideration: avoid heavy animations during time-scaled tutorials
Localization Adaptations:
- Text container sizing accommodates language expansion (up to 40% longer)
- Right-to-left language support requires layout mirroring capabilities
- Font selections must support required character sets for target languages
- Icon-based navigation aids comprehension across language barriers
- Text scaling options for vision-impaired players
Accessibility Enhancements:
- Screen reader compatibility through semantic markup (requires Bevy UI extensions)
- Keyboard navigation support for tutorial controls (Tab/Arrow key navigation)
- Reduced motion options for players sensitive to animations
- Text scaling preserving layout integrity at enlarged sizes
- Colorblind-friendly palette options with pattern differentiation
Performance Considerations:
- Custom UI should maintain efficient entity/component structure
- Avoid excessive nesting depth in UI hierarchy impacting layout performance
- Texture atlas usage for button assets reduces draw calls
- Animation systems should skip updates when animations complete
- Profiling recommended to validate performance impact of customizations
Game State Coordination
Game state coordination ensures tutorial presentation harmonizes with broader game systems, preventing conflicts and maintaining coherent player experience during educational moments. This coordination spans input handling, time management, physics simulation, and audio presentation.
Input System Integration:
- Implement InputState resource with set_input_enabled(bool) method for tutorial integration
- Input processing systems should query InputState before handling gameplay actions
- UI interaction systems should bypass InputState checks for tutorial navigation controls
- Emergency inputs (pause menu, volume controls) should remain functional during input pause
- Input buffering during tutorial may enhance experience when returning to gameplay
Time Management Coordination:
- Physics systems automatically respect time scale modifications through Bevy’s Time resource
- Animation systems should use Time::delta() for frame-independent updates
- Fixed timestep systems may require special consideration during time scale changes
- Audio pitch typically unaffected by time scale—consider separate pitch scaling for realism
- Networked games must handle time scale carefully to avoid desynchronization
Physics Simulation Considerations:
- Time scale changes affect physics uniformly—no selective application possible
- Paused physics may require special handling for player collision volumes
- Slow-motion physics may reveal simulation artifacts normally imperceptible
- Tutorial demonstrations should account for physics determinism requirements
- Reset physics state after tutorial if simulation diverged significantly during pause
Audio System Coordination:
- Background music may continue during tutorials or fade appropriately
- Tutorial-specific audio cues enhance engagement and information retention
- Voice-over narration requires synchronization with panel transitions
- Audio ducking reduces background volume during critical instructions
- Spatial audio considerations for 3D game environments during tutorial presentation
Camera System Integration:
- Camera may require repositioning to frame tutorial demonstration effectively
- Smooth camera transitions enhance presentation professionalism
- Camera constraints may need temporary relaxation during tutorial sequences
- Multiple camera angles could illustrate mechanics from optimal perspectives
- Return camera to player control smoothly after tutorial completion
AI System Coordination:
- Enemy AI may require pausing or simplified behavior during tutorials
- Friendly NPCs could participate in tutorial demonstrations
- AI perception systems might ignore player during tutorial sequences
- Tutorial-specific AI behaviors enhance contextual learning opportunities
- Restore normal AI behavior immediately after tutorial completion
State Restoration Guarantees:
- All modified game states must restore to pre-tutorial values upon completion
- Restoration should occur even after abnormal termination (Close event)
- Defensive programming: cache original values before modification when possible
- Validation systems should verify restoration completeness
- Logging restoration operations aids debugging state leakage issues
Coordination System Pattern:
// Example coordination system for camera handling
fn tutorial_camera_coordinator(
manager: Res<TutorialManager>,
mut cameras: Query<&mut Transform, With<Camera3d>>,
mut state: Local<Option<OriginalCameraState>>,
) {
if let Some(id) = manager.active_tutorial_id {
if let Some(tutorial) = manager.tutorials.get(&id) {
if tutorial.requires_camera_adjustment && state.is_none() {
// Cache original state
if let Ok(mut transform) = cameras.get_single_mut() {
*state = Some(OriginalCameraState {
position: transform.translation,
rotation: transform.rotation
});
// Apply tutorial camera position
transform.translation = tutorial.camera_position;
}
}
}
} else if let Some(original) = state.take() {
// Restore original state
if let Ok(mut transform) = cameras.get_single_mut() {
transform.translation = original.position;
transform.rotation = original.rotation;
}
}
}
Testing Recommendations:
- Verify all game systems restore state correctly after tutorial completion
- Test rapid tutorial activation/deactivation sequences for state leakage
- Validate behavior during tutorial interruption by high-priority game events
- Confirm multiplayer synchronization remains intact during tutorial sequences
- Profile performance impact of state modifications during tutorial presentation
Serialization Setup
Serialization setup enables tutorial progress tracking to persist across game sessions, leveraging Bevy’s Reflect and Serde integration for seamless save game compatibility. Proper configuration ensures player completion history survives application restarts without manual intervention.
Reflect Registration:
- TutorialPlugin automatically registers required types with TypeRegistry during build
- Types registered: Tutorial, TutorialPanel, TutorialLog, TutorialEvent
- Registration enables editor tooling support and runtime type inspection
- Custom components extending tutorial system should also register with TypeRegistry
- Verify registration completeness through debug inspection of TypeRegistry resource
Serde Integration:
- All core types implement Serialize and Deserialize traits from Serde crate
- Derive macros handle standard field serialization automatically
- Optional fields (image_path) serialize as null when absent
- HashSet in TutorialLog serializes efficiently as array of integers
- HashMap<u32, Tutorial> in TutorialManager typically excluded from persistence (content catalog reloads each session)
Save Game Integration:
- TutorialLog components automatically included when serializing player entities
- No special handling required beyond standard entity serialization setup
- Deserialization reconstructs exact completion state from save data
- New tutorials added post-save appear as unplayed to existing players
- Tutorial ID reuse should be avoided to prevent completion state corruption
Serialization Format Considerations:
- JSON format human-readable for debugging but verbose for production
- Bincode format compact and fast—recommended for production saves
- Format choice should match broader save game strategy
- Versioning strategy essential for handling tutorial content changes across game updates
- Migration logic may be required when tutorial ID assignments change between versions
Version Migration Strategy:
// Example migration system for tutorial ID changes
fn migrate_tutorial_logs(
mut logs: Query<&mut TutorialLog>,
version: Res<SaveVersion>,
) {
if version.0 < 12 {
// Tutorial ID 1000 renamed to 1100 in version 12
for mut log in logs.iter_mut() {
if log.played_tutorials.remove(&1000) {
log.played_tutorials.insert(1100);
}
}
}
}
Security Considerations:
- Deserialize with validation to prevent malicious save file manipulation
- Limit tutorial ID values to expected ranges during deserialization
- Reject save files with implausibly large TutorialLog sets (>1000 entries)
- Cryptographic signing of save files prevents unauthorized modification
- Server-authoritative validation for multiplayer tutorial progress
Performance Characteristics:
- Serialization time negligible compared to asset loading operations
- Deserialization reconstructs HashSet in linear time with number of completed tutorials
- Typical games with 20-50 tutorials add <1KB to save file size
- No runtime overhead from serialization traits when not actively saving/loading
Testing Recommendations:
- Verify TutorialLog serializes correctly with varying completion states
- Test deserialization of saves from prior game versions with migration logic
- Validate behavior when loading saves with orphaned tutorial IDs (removed content)
- Confirm new game sessions create fresh TutorialLog with empty HashSet
- Test cloud save synchronization with tutorial progress data
Debugging Support:
- Implement debug display for TutorialLog showing completed tutorial IDs
- Log serialization/deserialization operations at trace level for diagnostics
- Provide developer console commands to inspect/modify TutorialLog state
- Visual debug UI overlay showing current tutorial completion status
Usage Patterns
First-Time Player Onboarding
First-time player onboarding represents the most critical application of tutorial systems, establishing foundational mechanics understanding that shapes entire player experience. Effective onboarding balances comprehensive instruction with engagement preservation, avoiding overwhelming newcomers while ensuring essential competence.
Onboarding Sequence Design:
- Progressive complexity: Start with absolute fundamentals (movement) before introducing interactions
- Spaced repetition: Revisit core mechanics in increasingly complex contexts across early gameplay
- Contextual relevance: Introduce mechanics immediately before required for progression
- Achievement pacing: Alternate tutorials with genuine gameplay accomplishments to maintain motivation
- Escape valves: Provide clear paths to skip or defer non-critical tutorials for experienced players
Tutorial Structure for Onboarding:
- Movement tutorial (ID 1000): Basic locomotion, jumping, camera control—play_only_once enabled
- Interaction tutorial (ID 1001): Object interaction, pickup mechanics—play_only_once enabled
- Combat fundamentals (ID 2000): Attack inputs, blocking, basic combos—play_only_once enabled
- Inventory management (ID 3000): Item organization, equipment—play_only_once enabled
- Advanced mechanics (ID 4000+): Optional deep dives for players seeking mastery—play_only_once disabled
Trigger Strategy:
- Spatial triggers in dedicated tutorial area before main game access
- Mandatory completion gating progression until core mechanics demonstrated
- Soft triggers for advanced mechanics appearing contextually during early gameplay
- Behavioral triggers detecting struggle patterns offering optional remedial tutorials
- Explicit access points in pause menu for players wanting to review fundamentals
Player State Considerations:
- Track onboarding completion separately from individual tutorials for progression gating
- Allow partial completion resumption after game interruption
- Provide visual progress indicator for multi-tutorial onboarding sequences
- Celebrate onboarding completion with meaningful reward or narrative moment
- Transition smoothly from structured tutorials to organic gameplay learning
Analytics Integration:
- Track time-to-competence metrics correlating tutorial completion with gameplay performance
- Monitor abandonment points within onboarding sequence for content refinement
- Measure correlation between onboarding quality and long-term player retention
- A/B test tutorial variations to optimize comprehension and engagement
- Segment analytics by player demographics to identify accessibility gaps
Edge Case Handling:
- Handle game interruption during onboarding (alt-tab, phone call) with graceful resumption
- Support controller disconnect/reconnect during input-focused tutorials
- Accommodate accessibility settings activation mid-onboarding
- Provide language change capability without losing progress
- Validate save state integrity after onboarding completion
Best Practices:
- Limit mandatory onboarding to absolute essentials—5-10 minutes maximum
- Design onboarding area as genuine gameplay space, not artificial training ground
- Integrate narrative elements to maintain engagement during instructional moments
- Provide immediate application opportunities after each tutorial segment
- Respect player intelligence—avoid over-explaining obvious mechanics
Contextual Help Systems
Contextual help systems provide just-in-time guidance triggered by player behavior or environmental context, offering targeted assistance without disrupting gameplay flow. These systems complement mandatory onboarding with adaptive support responsive to individual player needs.
Trigger Mechanisms:
- Behavioral analysis: Detect repeated failure patterns at specific challenges
- Idle detection: Offer hints after extended player inactivity at puzzle elements
- Proximity triggers: Activate when player approaches complex mechanics areas
- Explicit requests: Player-initiated help through button press or menu selection
- Progression gating: Trigger when player attempts action without required mechanic knowledge
Help Content Strategy:
- Micro-tutorials: 1-2 panel sequences focused on single specific challenge
- Reference cards: Static informational panels players can review at own pace
- Demonstration loops: Short repeating animations showing solution technique
- Progressive hints: Multiple hint tiers revealing increasing solution detail
- Optional depth: Core hint always available, expanded explanation accessible optionally
Player Agency Preservation:
- Always provide clear opt-out mechanism for contextual help
- Respect player choices—suppress similar triggers after explicit dismissal
- Avoid interrupting high-engagement moments (combat, platforming sequences)
- Provide visual/audio cue before help activation for player preparation
- Allow help deferral with “Remind Me Later” option for non-critical situations
Implementation Pattern:
// Behavioral trigger detecting repeated jump failures
fn jump_hint_trigger(
mut failure_streak: Local<u32>,
mut last_failure_time: Local<f32>,
jump_events: EventReader<JumpFailedEvent>,
time: Res<Time>,
mut event_queue: ResMut<TutorialEventQueue>,
tutorial_logs: Query<&TutorialLog>,
) {
for _ in jump_events.read() {
if time.elapsed_seconds() - *last_failure_time < 2.0 {
*failure_streak += 1;
} else {
*failure_streak = 1;
}
*last_failure_time = time.elapsed_seconds();
if *failure_streak >= 3 && !has_completed(&tutorial_logs, 1005) {
event_queue.0.push(TutorialEvent::Open(1005)); // Jump timing hint
*failure_streak = 0; // Reset after trigger
}
}
}
Adaptive Difficulty Integration:
- Correlate hint frequency with dynamic difficulty adjustments
- Reduce challenge parameters after multiple hint requests for same mechanic
- Increase challenge after successful mechanic demonstration without hints
- Maintain player dignity—avoid obvious difficulty manipulation visible to player
- Preserve sense of accomplishment despite adaptive support
Analytics for Optimization:
- Track hint request frequency per mechanic to identify design pain points
- Measure time-between-hint and subsequent success rate for efficacy validation
- Correlate hint usage patterns with player retention metrics
- Identify over-triggering scenarios causing player annoyance
- Segment hint effectiveness by player skill tier and demographics
Multiplayer Considerations:
- Individualized hint delivery avoiding disruption to other players
- Coordinated hints for team-based mechanics requiring group understanding
- Spectator mode hints for observing players learning team strategies
- Competitive integrity preservation—no hints providing unfair advantage
- Social learning opportunities through shared hint experiences
Accessibility Integration:
- Enhanced hint systems for players with cognitive or motor accessibility needs
- Customizable hint frequency and intrusiveness through accessibility settings
- Alternative presentation formats (audio descriptions, haptic cues) for diverse needs
- Extended time allowances integrated with hint systems for time-sensitive challenges
- Progressive disclosure respecting individual learning pace preferences
Feature Introduction Sequences
Feature introduction sequences gradually unveil game systems as players progress, preventing cognitive overload while maintaining discovery excitement. These sequences strategically time mechanic reveals to match player readiness and narrative context.
Progressive Unveiling Strategy:
- Core loop first: Establish fundamental gameplay cycle before adding complexity
- Vertical slice approach: Fully develop small feature set before expanding breadth
- Narrative integration: Tie mechanic unlocks to story progression for meaningful context
- Environmental teaching: Design spaces that naturally encourage mechanic experimentation
- Mastery gating: Require demonstrated competence before introducing dependent mechanics
Tutorial Sequencing Example:
- Session 1 (First 15 minutes):
- Movement and camera control (Tutorial 1000)
- Basic interaction and object manipulation (Tutorial 1001)
- Core combat loop: attack, block, dodge (Tutorial 2000)
- Session 2 (First level completion):
- Special ability acquisition and basic usage (Tutorial 2100)
- Environmental interaction: levers, doors, platforms (Tutorial 1100)
- Inventory management fundamentals (Tutorial 3000)
- Session 3 (Mid-game progression):
- Advanced combat: combos, counters, special moves (Tutorial 2200)
- Crafting system introduction (Tutorial 4000)
- Character progression systems (Tutorial 5000)
- Late game (Mastery phase):
- Expert techniques and optimization strategies (Tutorial 2300)
- System interactions and emergent gameplay (Tutorial 6000)
- Speedrun techniques and advanced challenges (Tutorial 7000)
Contextual Integration Patterns:
- Environmental storytelling: Spaces designed to teach through exploration
- NPC demonstrations: Characters modeling mechanic usage before player access
- Gradual constraint removal: Early levels restrict mechanics, later levels unlock
- Failure-driven learning: Safe failure opportunities teaching mechanic boundaries
- Reward reinforcement: Successful mechanic usage immediately rewarded
Player Readiness Assessment:
- Track demonstrated competence through gameplay metrics before introducing complexity
- Monitor engagement levels—introduce new mechanics during high-engagement periods
- Assess cognitive load through performance metrics on existing mechanics
- Consider narrative emotional state—avoid complex introductions during intense moments
- Respect player pacing preferences through optional depth layers
Analytics-Driven Refinement:
- Correlate feature introduction timing with subsequent usage frequency
- Identify features introduced too early (abandoned) or too late (missed opportunities)
- Measure learning curve steepness through performance progression metrics
- Track feature combination usage to validate introduction sequencing
- A/B test introduction timings for optimal engagement and retention
Edge Case Handling:
- Handle player discovering mechanics before formal introduction gracefully
- Support players skipping content and encountering mechanics out of sequence
- Provide catch-up tutorials when players return after extended absence
- Accommodate different play styles requiring alternative introduction sequences
- Validate introduction sequencing across difficulty settings
Best Practices:
- Never introduce more than one major mechanic per gameplay session
- Always provide immediate meaningful application after mechanic introduction
- Design introduction sequences as genuine gameplay, not artificial training
- Maintain consistent visual language for mechanic affordances across introductions
- Celebrate mastery moments with meaningful rewards reinforcing learning
Progressive Complexity Tutorials
Progressive complexity tutorials structure learning experiences to gradually increase cognitive demand, respecting cognitive load theory while building comprehensive mechanic understanding. These tutorials decompose complex systems into sequenced learning moments that scaffold player competence.
Cognitive Load Management:
- Intrinsic load: Break complex mechanics into atomic components taught separately
- Germane load: Design panels encouraging schema construction through examples
- Extraneous load: Eliminate decorative elements competing for attention with core concepts
- Worked examples: Provide complete solutions before expecting independent application
- Completion problems: Gradually fade support from full solution to blank challenge
Tutorial Structure Example - Advanced Combat:
Panel 1 (Foundation):
- Title: “Combo Fundamentals”
- Description: “Press attack buttons in sequence to chain strikes. Timing windows are generous for beginners.”
- Image: Character performing basic 3-hit combo with button prompts overlaid
- Configuration: pause_input=true, time_scale=0.5 for observation
Panel 2 (Variation):
- Title: “Directional Combos”
- Description: “Incorporate movement directions between attacks to change combo paths. Try forward + attack after first hit.”
- Image: Same combo with directional input visualized
- Configuration: pause_input=false, time_scale=1.0 for immediate practice
Panel 3 (Application):
- Title: “Enemy-Specific Combos”
- Description: “Some enemies have vulnerability windows after blocking. Watch for stagger animations to extend combos.”
- Image: Combo against specific enemy type with vulnerability window highlighted
- Configuration: pause_input=true, time_scale=0.3 for precise observation
Panel 4 (Integration):
- Title: “Combo Mastery”
- Description: “Combine directional inputs, enemy knowledge, and timing for maximum damage. Experiment with different sequences!”
- Image: Extended combo demonstration with damage numbers
- Configuration: pause_input=false, time_scale=1.0 for free practice
Scaffolding Techniques:
- Faded worked examples: Progress from fully demonstrated → partially completed → blank challenge
- Goal specification: Clear success criteria for each learning segment
- Self-explanation prompts: Encourage mental rehearsal through reflective questions
- Error-driven learning: Safe opportunities to experience and correct common mistakes
- Spaced repetition: Revisit concepts in new contexts to strengthen retention
Adaptive Sequencing:
- Performance-based branching: Adjust panel sequence based on player success/failure
- Optional depth layers: Core panels mandatory, advanced panels accessible optionally
- Remedial pathways: Automatic insertion of foundational panels when struggle detected
- Accelerated paths: Skip panels when player demonstrates prior competence
- Player-controlled pacing: Explicit controls for review and advancement speed
Assessment Integration:
- Embedded assessments: Mini-challenges verifying comprehension before progression
- Stealth assessment: Analyze natural gameplay for competence demonstration
- Formative feedback: Immediate specific guidance on performance errors
- Summative validation: Clear success indicators confirming mastery
- Growth mindset framing: Emphasize improvement over absolute performance
Analytics for Optimization:
- Panel abandonment rates identifying confusing content sections
- Time-per-panel metrics revealing comprehension difficulty variations
- Success rates on embedded assessments validating instructional effectiveness
- Correlation between tutorial completion quality and subsequent gameplay performance
- Longitudinal tracking of skill retention weeks after tutorial completion
Edge Case Handling:
- Player mastery exceeding tutorial pacing—provide acceleration options
- Player struggle requiring additional support beyond standard sequence
- Interruption during tutorial requiring state preservation and resumption
- Multi-mechanic interactions requiring coordinated introduction sequencing
- Platform-specific constraints affecting complexity presentation (mobile touch limitations)
Best Practices:
- Never introduce multiple novel concepts within single panel
- Always provide concrete application opportunity immediately after conceptual explanation
- Design struggle moments as learning opportunities rather than frustration sources
- Maintain consistent terminology and visual language across complexity levels
- Celebrate progression through complexity tiers with meaningful feedback
Checkpoint-Based Guidance
Checkpoint-based guidance delivers targeted tutorials at natural progression points, aligning educational moments with gameplay structure to minimize disruption while maximizing relevance. This approach leverages level design and progression systems as tutorial delivery framework.
Checkpoint Identification:
- Level transitions: Natural breaks between gameplay segments
- Boss encounters: Preparation moments before significant challenges
- Ability unlocks: Introduction points for new mechanic capabilities
- Environmental shifts: New areas introducing novel interaction possibilities
- Narrative milestones: Story moments providing context for mechanic significance
- Failure recovery: After repeated deaths at specific challenges
Guidance Delivery Patterns:
- Pre-challenge briefings: Short tutorials immediately before significant obstacles
- Post-failure analysis: Targeted hints after player death at specific mechanics
- Success celebration: Reinforcement tutorials after overcoming difficult challenges
- Environmental priming: Subtle environmental cues teaching before explicit instruction
- Optional deep dives: Accessible reference materials at safe checkpoint locations
Implementation Example - Boss Preparation:
// System triggering boss preparation tutorial
fn boss_prep_tutorial(
player_query: Query<&LevelProgress>,
mut event_queue: ResMut<TutorialEventQueue>,
tutorial_logs: Query<&TutorialLog>,
) {
for progress in player_query.iter() {
if progress.next_boss == BossType::Minotaur
&& progress.boss_attempts == 0
&& !has_completed(&tutorial_logs, 2500) {
// Trigger minotaur-specific preparation tutorial
event_queue.0.push(TutorialEvent::Open(2500));
}
}
}
Tutorial Content Strategy:
- Challenge analysis: Break down upcoming obstacle into manageable components
- Strategy suggestions: Multiple viable approaches respecting player style preferences
- Weakness highlighting: Clear indicators of enemy/environment vulnerabilities
- Resource management: Guidance on optimal consumable usage for challenge
- Escape options: Legitimate retreat paths preserving player agency
Player Agency Preservation:
- Always provide explicit skip option for experienced players
- Respect player choices—suppress similar guidance after explicit dismissal
- Avoid interrupting player momentum during high-engagement sequences
- Provide visual/audio cue before guidance activation for preparation
- Allow guidance deferral with “Remind Me Later” for non-critical situations
Analytics Integration:
- Track guidance acceptance/skip rates to calibrate intrusiveness
- Measure correlation between guidance consumption and challenge success rates
- Identify guidance timing issues through player frustration metrics
- Segment guidance effectiveness by player skill tier and play style
- A/B test guidance content variations for optimal efficacy
Multiplayer Considerations:
- Individualized guidance delivery avoiding disruption to team coordination
- Coordinated guidance for team-based challenges requiring group understanding
- Leader/player role-specific guidance respecting responsibility differences
- Competitive integrity preservation—no guidance providing unfair advantage
- Social learning opportunities through shared guidance experiences
Progressive Disclosure:
- Tier 1: Core strategy essentials (always shown)
- Tier 2: Advanced technique options (accessible optionally)
- Tier 3: Expert optimization strategies (hidden behind explicit request)
- Tier 4: Community-discovered techniques (external resource links)
- Respects player expertise while providing depth for those seeking it
Edge Case Handling:
- Rapid successive checkpoint triggers requiring queuing/prioritization
- Guidance interruption by high-priority game events (emergency situations)
- Multi-checkpoint proximity requiring trigger consolidation
- Player backtracking triggering guidance repeatedly—implement cooldowns
- Network latency affecting checkpoint detection timing in multiplayer
Best Practices:
- Limit guidance duration to 30-60 seconds maximum to preserve challenge integrity
- Design guidance content as genuine strategic insight, not hand-holding
- Maintain consistent visual language for guidance elements across game
- Provide immediate application opportunity after guidance completion
- Celebrate successful challenge completion with meaningful rewards
Optional Tutorial Access
Optional tutorial access empowers players to seek guidance on demand, respecting player agency while providing safety net for confusion or forgotten mechanics. This approach transforms tutorials from interruptions into player-controlled resources enhancing autonomy and reducing frustration.
Access Mechanisms:
- Pause menu integration: Dedicated “Tutorials” section with categorized content library
- Contextual help button: Dedicated input (e.g., Select/Back button) triggering relevant help
- NPC knowledge vendors: In-world characters providing tutorial access for immersion
- Environmental help points: Interactive objects offering mechanic reminders
- Gesture-based access: Platform-specific gestures (touchscreen swipes, motion controls)
Content Organization Strategy:
- Categorical grouping: Movement, Combat, Exploration, Systems menus
- Search functionality: Text search across tutorial content for specific queries
- Progress tracking: Visual indicators showing completed vs available tutorials
- Relevance sorting: Prioritize tutorials related to current game context
- Favorites system: Player-curated collection of frequently referenced tutorials
Implementation Pattern - Pause Menu:
// System handling tutorial selection from pause menu
fn pause_menu_tutorial_selection(
interaction_query: Query<(&Interaction, &TutorialSelection), Changed<Interaction>>,
mut event_queue: ResMut<TutorialEventQueue>,
) {
for (interaction, selection) in interaction_query.iter() {
if *interaction == Interaction::Pressed {
// Optional tutorials never enforce play_only_once restrictions
event_queue.0.push(TutorialEvent::Open(selection.tutorial_id));
}
}
}
Player Experience Design:
- Zero friction access: Maximum two interactions to reach desired tutorial content
- Context preservation: Return player to exact pre-access state after tutorial completion
- Bookmarking capability: Save position in multi-panel tutorials for later resumption
- Cross-referencing: Links between related tutorials enabling knowledge exploration
- Offline availability: All tutorial content accessible without network connection
Content Strategy for Optional Tutorials:
- Reference materials: Comprehensive mechanic documentation beyond initial introduction
- Advanced techniques: Expert strategies not covered in mandatory onboarding
- System interactions: Emergent gameplay possibilities from mechanic combinations
- Speedrun techniques: Optimization strategies for experienced players
- Accessibility guides: Platform-specific control schemes and assistance options
Analytics Integration:
- Track most-accessed tutorials to identify confusing mechanics requiring design refinement
- Measure time-between-access patterns revealing knowledge retention issues
- Correlate tutorial access with subsequent gameplay performance improvements
- Identify content gaps where players seek help but no tutorial exists
- Segment access patterns by player demographics and skill tiers
Progressive Disclosure:
- Basic overview: Single panel summary for quick reminders
- Standard depth: Complete multi-panel explanation matching initial tutorial
- Expert depth: Advanced applications and optimization strategies
- Community knowledge: Curated player-discovered techniques and strategies
- Video demonstrations: Optional video content for complex spatial mechanics
Edge Case Handling:
- Tutorial access during cutscenes or non-interactive sequences—defer until appropriate moment
- Multiplayer session tutorial access—provide individual UI without disrupting others
- Controller reconfiguration during tutorial access—maintain input mapping consistency
- Language change during tutorial access—preserve position while updating content
- System resource constraints—prioritize tutorial content loading appropriately
Best Practices:
- Never gate critical progression behind optional tutorials—core mechanics always taught mandatorily
- Design optional tutorials as genuine value-adds players want to access, not remedial content
- Maintain consistent visual language between mandatory and optional tutorial presentations
- Provide clear visual distinction between completed and unviewed optional content
- Celebrate knowledge acquisition through optional tutorials with subtle positive reinforcement
Multi-Stage Learning Paths
Multi-stage learning paths structure extended skill development across multiple gameplay sessions, recognizing that complex mechanic mastery requires distributed practice rather than single-session instruction. These paths transform tutorials from isolated moments into cohesive learning journeys.
Learning Path Architecture:
- Foundation stage: Core mechanic introduction and basic competence (Session 1)
- Application stage: Mechanic usage in varied contexts reinforcing understanding (Sessions 2-3)
- Integration stage: Combining mechanic with other systems for emergent gameplay (Sessions 4-5)
- Mastery stage: Advanced techniques and optimization strategies (Sessions 6+)
- Expert stage: Community-discovered techniques and creative applications (Ongoing)
Progress Tracking System:
- TutorialLog extended with stage completion tracking per mechanic
- Performance metrics capturing demonstrated competence beyond simple completion
- Milestone achievements celebrating progression through learning stages
- Personalized recommendations for next learning opportunities based on play patterns
- Visual progress indicators showing current stage and available advancement paths
Implementation Example - Combat Learning Path:
Stage 1 (Foundation - Tutorial 2000):
- Basic attack inputs, blocking, dodging
- Trigger: First enemy encounter
- Completion: Defeat 5 basic enemies using taught mechanics
Stage 2 (Application - Tutorial 2100):
- Combos, directional attacks, enemy-specific strategies
- Trigger: After 30 minutes gameplay post Stage 1 completion
- Completion: Defeat mini-boss using combo techniques
Stage 3 (Integration - Tutorial 2200):
- Combining combat with movement, environment, special abilities
- Trigger: Unlocking second special ability
- Completion: Defeat enemy group using integrated mechanics
Stage 4 (Mastery - Tutorial 2300):
- Advanced timing, parries, counter-attacks, resource management
- Trigger: Player achieving S-rank on 3 combat challenges
- Completion: Defeat boss without taking damage using advanced techniques
Stage 5 (Expert - Tutorial 2400):
- Speedrun techniques, glitch exploitation (intentional), style optimization
- Trigger: Player completing game under threshold time
- Completion: Community submission of novel technique demonstration
Adaptive Progression:
- Performance-based advancement: Accelerate players demonstrating rapid mastery
- Remedial insertion: Automatically insert additional practice stages when struggle detected
- Branching paths: Different advancement routes respecting play style preferences
- Player-directed pacing: Explicit controls for requesting advancement or additional practice
- Contextual opportunities: Natural gameplay moments serving as stage transition points
Analytics Integration:
- Longitudinal tracking of skill development across gameplay sessions
- Correlation between learning path progression and overall game engagement
- Identification of stage transition friction points requiring design refinement
- Segmentation of learning patterns by player demographics and prior experience
- A/B testing of stage content variations for optimal learning outcomes
Motivation Systems:
- Achievement unlocks tied to stage completion providing tangible rewards
- Visual customization options unlocked through learning progression
- Narrative revelations tied to mechanic mastery enhancing story integration
- Social sharing capabilities for milestone achievements
- Growth mindset framing emphasizing improvement over absolute performance
Edge Case Handling:
- Player skipping content and encountering advanced stages prematurely
- Extended play breaks requiring refresher content before stage advancement
- Platform switching (console to PC) requiring control scheme adaptation within path
- Multiplayer coordination where players at different learning stages cooperate
- Content updates introducing new stages to existing player learning paths
Best Practices:
- Never force players to remain at stage until arbitrary time requirements met
- Always provide clear advancement criteria and progress toward completion
- Design stage transitions as genuine gameplay moments, not artificial gates
- Maintain consistent visual language for learning path indicators across game
- Celebrate stage completion with meaningful rewards reinforcing continued engagement
Best Practices
Content Design
Content design forms the pedagogical foundation of effective tutorials, transforming mechanical explanations into engaging learning experiences that respect player intelligence while ensuring comprehension. Superior content design balances informational density with cognitive load management.
Cognitive Load Theory Application:
- Segment complex mechanics into atomic concepts taught individually before integration
- Eliminate extraneous elements competing for attention with core instructional content
- Use dual coding principles combining verbal explanations with visual demonstrations
- Provide worked examples before expecting independent application
- Implement completion problems gradually fading support from full solution to blank challenge
Text Content Guidelines:
- Title field: Maximum 60 characters preventing text wrapping at standard resolutions
- Description field: 2-5 sentences optimal for comprehension without cognitive overload
- Active voice preferred: “Press Space to jump” versus passive “Jumping is performed by pressing Space”
- Second-person perspective enhances engagement and direct applicability
- Concrete terminology over abstract concepts: “double jump” versus “vertical mobility enhancement”
- Avoid pronoun ambiguity since panels may be reviewed non-sequentially
Visual Content Strategy:
- Images should illustrate concepts described in text rather than merely decorating UI
- Diagrams and annotated screenshots often more effective than pure photography
- Consistent visual style across tutorial images enhances professional presentation
- Critical information must never appear exclusively in images (accessibility requirement)
- Recommended aspect ratio 2.5:1 (500×200) matching default container dimensions
- Color coding should align with broader game visual language for consistency
Sequencing Principles:
- Concrete before abstract: Observable actions before theoretical explanations
- Simple before complex: Isolated mechanics before integrated applications
- Known before unknown: Build upon established concepts when introducing novelty
- Whole-part-whole: Demonstrate complete mechanic, decompose components, reassemble application
- Spaced repetition: Revisit core concepts in increasingly complex contexts across sequences
Progressive Disclosure Implementation:
- Panel 1: Core concept with minimal supporting details
- Panel 2: Contextual application expanding on core concept
- Panel 3: Variation or edge case demonstrating concept boundaries
- Panel 4: Integration with related mechanics showing emergent possibilities
- Panel 5: Mastery application synthesizing multiple concepts cohesively
Content Validation Process:
- Playtest with target audience having no prior game exposure
- Measure time-to-comprehension for each panel through observation
- Identify confusion points through player verbalization during playtests
- Validate knowledge retention through delayed recall testing (24 hours later)
- Iterate content based on empirical comprehension metrics rather than designer assumptions
Localization Preparation:
- Externalize all text content to localization files rather than hardcoded strings
- Reserve 40% additional space for text expansion in non-English languages
- Avoid text embedded in images—use separate image assets with localization variants
- Consider cultural appropriateness of visual examples across target markets
- Test right-to-left language support requiring layout mirroring capabilities
Accessibility Integration:
- Provide text alternatives for all visual instructional content
- Ensure sufficient color contrast (WCAG AA minimum 4.5:1) for text readability
- Avoid color-only information encoding—supplement with patterns or labels
- Design for screen reader compatibility through semantic content structure
- Support text scaling up to 200% without layout breakage or content loss
Content Freshness Maintenance:
- Schedule periodic review of tutorial content against actual game mechanics
- Establish clear ownership for tutorial content updates when mechanics change
- Implement version tracking linking tutorial content to game mechanic versions
- Create automated tests verifying tutorial accuracy against live game systems
- Document pedagogical rationale for content decisions enabling informed updates
Player Experience
Player experience design ensures tutorials enhance rather than disrupt gameplay flow, respecting player agency while providing necessary guidance. Exceptional tutorial experiences feel like natural extensions of gameplay rather than artificial interruptions.
Flow State Preservation:
- Trigger tutorials during natural gameplay pauses rather than interrupting momentum
- Limit mandatory tutorial duration to 60 seconds maximum per sequence
- Provide immediate application opportunities after instructional moments
- Design tutorial spaces as genuine gameplay environments, not artificial training grounds
- Maintain consistent visual and audio language between tutorials and core gameplay
Player Agency Respect:
- Always provide explicit skip options for non-critical tutorials
- Remember player choices—suppress similar tutorials after explicit dismissal
- Allow tutorial deferral with “Remind Me Later” options for contextually inappropriate moments
- Never gate critical progression behind optional tutorial consumption
- Design struggle moments as learning opportunities rather than frustration sources
Pacing Optimization:
- Space mandatory tutorials at least 5 minutes apart during initial onboarding
- Increase spacing between tutorials as player demonstrates competence
- Provide optional depth layers allowing players to control information density
- Accelerate tutorial sequences for players demonstrating rapid mastery
- Insert remedial content automatically when struggle patterns detected
Emotional Design Considerations:
- Frame challenges positively: “Master this technique” versus “Don’t fail this challenge”
- Celebrate small victories during tutorial sequences to maintain motivation
- Avoid shaming language for mistakes—frame errors as learning opportunities
- Match tutorial tone to broader game narrative voice for consistency
- Provide encouraging feedback reinforcing player progress and competence
Contextual Appropriateness:
- Avoid tutorial triggers during high-intensity gameplay moments (combat, platforming sequences)
- Consider player emotional state—avoid complex introductions during narrative intensity peaks
- Respect physical context—mobile tutorials should accommodate interruption patterns
- Adapt tutorial length to platform expectations (shorter for mobile, longer for PC/console)
- Provide visual/audio cues before tutorial activation allowing player preparation
Feedback Loop Design:
- Provide immediate specific feedback on player actions during tutorial practice segments
- Visual indicators confirming successful mechanic execution
- Audio cues reinforcing correct timing and execution
- Gradual difficulty scaling within tutorials matching player demonstrated competence
- Clear success criteria with unambiguous completion indicators
Frustration Prevention:
- Implement generous timing windows during initial mechanic introductions
- Provide multiple solution paths respecting different play styles
- Include explicit failure recovery paths preventing soft-locks
- Design safe failure states allowing experimentation without severe penalties
- Monitor player behavior for frustration signals (rapid button mashing, inactivity) triggering assistance
Retention Optimization:
- Correlate tutorial quality metrics with long-term player retention data
- Identify tutorial sequences preceding drop-off points for refinement
- Balance challenge and skill development maintaining engagement curve
- Provide meaningful rewards for tutorial completion enhancing motivation
- Design tutorials as genuine value-adds players want to experience, not obstacles to skip
Analytics-Driven Refinement:
- Track tutorial completion rates identifying abandonment points
- Measure time-to-completion revealing comprehension difficulty variations
- Correlate tutorial consumption with subsequent gameplay performance improvements
- Segment effectiveness by player demographics and prior experience levels
- A/B test tutorial variations optimizing for comprehension and engagement metrics
Best Practices Checklist:
Performance optimization ensures tutorial systems operate efficiently without impacting frame rate or memory usage, critical for maintaining smooth gameplay during educational moments. Well-optimized tutorials deliver seamless experiences indistinguishable from core gameplay performance.
UI Entity Management:
- Minimize UI entity count through efficient hierarchy design—target under 20 entities per tutorial
- Avoid unnecessary component attachments on UI entities increasing query complexity
- Reuse UI entities across tutorial sequences rather than rebuilding hierarchy each activation
- Implement object pooling for tutorial UI entities eliminating allocation costs during activation
- Despawn UI entities immediately upon tutorial completion preventing entity accumulation
Asset Loading Strategy:
- Preload tutorial image assets during level loading phases avoiding runtime stalls
- Implement texture atlasing for tutorial button assets reducing draw calls
- Cache frequently used tutorial images in memory avoiding redundant loads
- Provide low-resolution fallbacks for memory-constrained platforms
- Stream tutorial assets asynchronously with placeholder content during load
System Execution Efficiency:
- Leverage Changed filters in button handling systems reducing per-frame processing
- Implement early-exit conditions in systems when tutorial inactive minimizing overhead
- Batch entity operations within single commands scope reducing scheduler overhead
- Avoid nested queries—flatten query structures for cache-friendly access patterns
- Profile system execution times identifying optimization opportunities through Bevy diagnostics
Memory Footprint Management:
- HashSet in TutorialLog provides compact storage—typical games under 1KB total
- Avoid storing redundant data in tutorial definitions—reference shared assets externally
- Implement asset reference counting ensuring tutorial images unloaded when no longer needed
- Monitor memory usage patterns across tutorial activation/deactivation cycles
- Establish memory budgets for tutorial content with enforcement through asset pipeline
Time Scale Considerations:
- Physics systems automatically reduce computation during slow-motion tutorials—potential performance gain
- Complete pause (time_scale=0.0) may enable aggressive frame skipping optimizations
- Animation systems should skip updates during complete pause reducing CPU load
- Audio systems may reduce mixing complexity during tutorial sequences
- Network systems should maintain synchronization despite local time scale modifications
Platform-Specific Optimizations:
- Mobile platforms: Reduce tutorial UI complexity accommodating lower GPU capabilities
- Console platforms: Leverage platform-specific memory management for asset streaming
- VR platforms: Minimize UI movement reducing motion sickness potential during tutorials
- Cloud gaming: Optimize asset sizes reducing streaming bandwidth requirements
- Low-end PCs: Provide scalable UI quality settings tied to global graphics options
Profiling Methodology:
- Establish performance baselines measuring frame time with/without active tutorials
- Profile tutorial activation sequence identifying initialization bottlenecks
- Measure memory allocation patterns during tutorial lifecycle transitions
- Test worst-case scenarios: rapid successive activations, maximum panel count sequences
- Validate performance across target hardware spectrum including minimum specifications
Optimization Priorities:
- Eliminate frame rate drops during tutorial activation/deactivation transitions
- Minimize memory footprint of inactive tutorial systems (should be near zero)
- Reduce asset loading stalls through preloading and asynchronous strategies
- Optimize UI entity count and component complexity for efficient queries
- Implement platform-specific adaptations respecting hardware constraints
Common Performance Pitfalls:
- Rebuilding entire UI hierarchy on each panel transition rather than updating content
- Unnecessary asset reloads when panel image paths unchanged between transitions
- Missing Changed filters causing systems to process static UI entities every frame
- Excessive entity nesting depth impacting Bevy UI layout performance
- Unbounded TutorialEventQueue growth from unprocessed events
Testing Recommendations:
- Profile tutorial sequences on minimum specification target hardware
- Test rapid activation/deactivation cycles simulating player experimentation
- Validate performance with maximum simultaneous UI elements (tutorial + game UI)
- Measure memory usage before/after tutorial sequences identifying leaks
- Test asset loading performance on slow storage media (HDD, network drives)
State Management
State management ensures tutorial systems maintain consistent, predictable behavior across complex gameplay scenarios including interruptions, edge cases, and system interactions. Robust state management prevents visual artifacts, input handling errors, and progression corruption.
State Separation Principles:
- Persistent state (TutorialLog) stored in components attached to player entities
- Transient state (TutorialManager) stored in resource with ephemeral presentation data
- Game state modifications (time scale, input) tracked separately with restoration guarantees
- Clear ownership boundaries preventing state duplication or conflicting modifications
- Unidirectional data flow from events → manager → presentation systems
State Transition Safety:
- Atomic transitions: Each event produces complete valid state or no change
- Boundary enforcement: Navigation events checked against panel sequence bounds
- Validation before modification: Tutorial existence verified before state changes
- Defensive programming: Default restoration values prevent stuck states (time_scale=1.0)
- Comprehensive logging enabling diagnostic tracing of state transitions
Restoration Guarantees:
- Input state always restored to enabled when tutorial closes
- Time scale always restored to pre-tutorial value or 1.0 default
- Cursor state restoration coordinated through external systems observing unlock_cursor flag
- UI entities completely despawned preventing visual artifacts or input conflicts
- Restoration occurs even after abnormal termination (Close event, sequence completion)
Interruption Handling:
- Game interruptions (alt-tab, focus loss) should preserve tutorial state for resumption
- High-priority game events (enemy ambush, environmental hazard) may cancel tutorials gracefully
- Tutorial cancellation should restore game state before handling interruption event
- Player death during tutorial should complete tutorial closure before respawn sequence
- Network disconnections during multiplayer tutorials require server-authoritative state resolution
Multi-System Coordination:
- Establish clear ownership of shared state (time scale, input state)
- Implement state change notifications enabling coordinated transitions
- Avoid tight coupling between tutorial system and game systems—prefer observation patterns
- Document state modification contracts enabling safe system composition
- Validate state consistency through periodic integrity checks during development
Serialization Safety:
- TutorialLog serialization includes only completion history—not transient presentation state
- Deserialization validates tutorial ID ranges preventing malicious save manipulation
- Version migration handles tutorial ID reassignments between game updates
- Orphaned tutorial IDs (removed content) handled gracefully without crashing
- Cryptographic signing prevents unauthorized modification of completion data
Edge Case Coverage:
- Rapid successive tutorial activations testing state transition robustness
- Tutorial activation during asset loading phases testing asynchronous safety
- UI interaction during state transitions testing input handling consistency
- Resource exhaustion scenarios (memory, file handles) testing graceful degradation
- Platform-specific edge cases (controller disconnect, display rotation)
Debugging Support:
- Implement debug visualization of current tutorial state (active ID, panel index)
- Log all state transitions with timestamps enabling sequence reconstruction
- Provide developer console commands for manual state manipulation during testing
- Visual debug overlays showing TutorialLog completion status
- Automated state consistency checks running during development builds
Testing Strategy:
- Unit tests validating state transition logic for all event types
- Integration tests verifying restoration guarantees after abnormal termination
- Stress tests with rapid state transitions identifying race conditions
- Persistence tests validating save/load cycles across game versions
- Multiplayer tests verifying server/client state synchronization
Common State Management Bugs:
- Time scale not restored after tutorial closure causing permanently slowed game
- Input state stuck disabled after tutorial interruption
- UI entities not despawned causing visual artifacts or input conflicts
- TutorialLog not updated causing redundant tutorial triggers
- Panel index exceeding bounds causing panic during navigation
Best Practices Checklist:
UI/UX Guidelines
UI/UX guidelines ensure tutorial interfaces provide intuitive, accessible interactions that enhance learning without introducing friction or cognitive overhead. Exceptional tutorial UI feels like natural extension of game interface rather than disconnected overlay.
Visual Hierarchy Principles:
- Title text commands attention through size (30px), weight, and contrast against background
- Image region provides visual anchor between title and description text
- Description text supports title with smaller size (20px) and reduced contrast
- Navigation buttons positioned consistently at panel bottom with clear visual separation
- Sufficient spacing between elements preventing visual crowding (minimum 20px padding)
Color Theory Application:
- Background overlay semi-transparent (0.7 alpha) obscuring game content without complete obscuration
- Panel container dark background (0.1,0.1,0.1) providing contrast for light text content
- Border/outlines (0.3,0.3,0.3) creating visual separation from overlay background
- Button states use three distinct shades (0.2/0.3/0.4) providing clear interaction feedback
- Color choices maintain sufficient contrast (WCAG AA minimum 4.5:1) for text readability
Typography Guidelines:
- Title font size minimum 24px for readability at standard viewing distances
- Description font size minimum 16px preventing eye strain during extended reading
- Line height 1.4-1.6x font size providing comfortable reading rhythm
- Maximum line length 60-80 characters preventing excessive horizontal eye movement
- Font selection consistent with broader game UI establishing visual cohesion
Interaction Design:
- Button targets minimum 44px×44px meeting touch interface accessibility standards
- Visual feedback immediate on interaction state changes (hover/press)
- Navigation semantics intuitive: left=previous, right=next, prominent=close
- Disabled states visually distinct when navigation options unavailable
- Focus management supporting keyboard navigation for accessibility
Layout Responsiveness:
- Container width maximum 80% of screen preventing edge proximity issues
- Vertical centering maintaining comfortable reading position across resolutions
- Padding scales proportionally with screen size maintaining visual