Skip to content

MinimalPlugins + Window requires additional plugins (RenderPlugin) #21900

@martinstarkov

Description

@martinstarkov

Running Bevy 0.17.2 on Ubuntu 24.04.3 LTS with wayland

Was trying to run a minimal bevy app to get the maximum FPS of windowed vs headless when using MinimalPlugins.

According to:

https://docs.rs/bevy/latest/bevy/winit/struct.WinitPlugin.html

"When using eg. MinimalPlugins you can add this using WinitPlugin::<WakeUp>::default(), where WakeUp is the default event that bevy uses."

I had the following code:

use bevy::prelude::*;

fn main() {
    let mut app = App::new();
    app.add_plugins(MinimalPlugins);

    #[cfg(feature = "window")]
    {
        use bevy::window::PresentMode;
        use bevy::winit::{UpdateMode, WakeUp, WinitPlugin, WinitSettings};

        app.add_plugins(WindowPlugin {
            primary_window: Some(Window {
                present_mode: PresentMode::Mailbox,
                ..default()
            }),
            ..default()
        })
        .add_plugins(WinitPlugin::<WakeUp>::default())
        .insert_resource(WinitSettings {
            focused_mode: UpdateMode::Continuous,
            unfocused_mode: UpdateMode::Continuous,
        });
    }

    app.run();
}

With Cargo.toml (running with default features and profile):

[package]
name = "bevy_example"
version = "0.1.0"
edition = "2021"

[features]
default = ["window", "debug"]
debug = ["bevy/debug"]
window = ["bevy/bevy_winit", "bevy/wayland", "bevy/x11"]

[dependencies]
bevy = { version = "0.17.2", default-features = false, features = [] }

[profile.dev]
opt-level = 0         
debug = 0             
debug-assertions = true
overflow-checks = false
incremental = true
lto = false

[profile.release]
opt-level = 3
lto = "thin"
debug = false

And it crashed with:

thread 'main' (20503) panicked at /home/martin/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_ecs-0.17.3/src/system/system_param.rs:813:21:
Resource requested by (bevy_ecs::system::commands::Commands<'_, '_>, bevy_ecs::system::query::Query<'_, '_, (bevy_ecs::entity::Entity, &mut bevy_window::window::Window, &bevy_window::window::CursorOptions, core::option::Option<&bevy_window::raw_handle::RawHandleWrapperHolder>), bevy_ecs::query::filter::Added<bevy_window::window::Window>>, bevy_ecs::message::message_writer::MessageWriter<'_, bevy_window::event::WindowCreated>, bevy_ecs::change_detection::ResMut<'_, bevy_winit::accessibility::WinitActionRequestHandlers>, bevy_ecs::change_detection::Res<'_, bevy_a11y::AccessibilityRequested>, bevy_ecs::change_detection::Res<'_, bevy_winit::winit_monitors::WinitMonitors>) does not exist: bevy_a11y::AccessibilityRequested

Adding the bevy::a11y::AccessibilityPlugin changed the error to:

thread 'main' (20768) panicked at /home/martin/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_ecs-0.17.3/src/error/handler.rs:125:1:
Encountered an error in system `bevy_winit::system::check_keyboard_focus_lost`: Parameter `MessageWriter<'_, KeyboardFocusLost>::messages` failed validation: Message not initialized
If this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `If<T>` to skip the system when it happens.
   1: <bevy_ecs::system::system::RunSystemError as core::convert::From<E>>::from
   3: bevy_ecs::system::system::System::run_without_applying_deferred
note: Some "noisy" backtrace lines have been filtered out. Run with `BEVY_BACKTRACE=full` for a verbose backtrace.

Adding the bevy::input::InputPlugin made it run but without opening a window.

I then had to painstakingly enable/disable plugins inside DefaultPlugins until I discovered that the RenderPlugin (and all of the plugins it depends on) need to be enabled for a window to be opened.

Perhaps I was not looking in the right places, but I would say it isn't clear that disabling default features effectively makes DefaultPlugins act like MinimalPlugins (for the most part).

It would be nice if the official examples contained a default-features disabled example of a minimal app that can be toggled between headless and windowed mode that runs at max FPS, perhaps just a stress test of max FPS with an empty window with or without a renderer. When I disabled the Wgpu settings backend the window stopped opening.

This was for the specific use case of running a simulator within bevy as fast as possible without it being bottle necked by the renderer.

A couple of relevant issues I saw that solved this using a schedule:
#8539
#6648

No real "issue" here, just documentation improvement and perhaps this post can save time for someone running into the same situation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-DocsAn addition or correction to our documentationS-Needs-TriageThis issue needs to be labelled

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions