Files
benilla-octo/crates/benilla-app/examples/extended_launcher.rs
T
Sam SungandClaude Opus 5.5 85980939f5 A crate on top finds its own benilla-config/ through config_dir (#809)
A crate built on benilla through `run_with` has its own `benilla-config/`, but could not ask where it is: `local_state::home` is crate-private. A crate that ships an addon has to write it into that folder's `AddOns/`, where benilla discovers addons and resolves their art and fonts, so without the path it needed a fork.

- `benilla_app::config_dir()` answers `local_state::home()`, asked from `run_with` on, since a dev build resolves it from the launcher's folder set there.
- CONTRIBUTING's "Building on top" says a crate's files and addons go there, and names `run_with` and this folder as the two seams opened for crates alone.
- The example launcher logs its `AddOns/` folder through it, so the example, which clippy and the tests build, is the outside caller that keeps it public.

No 1.12.1 behaviour changes.

Fixes #807

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 09:12:02 +07:00

88 lines
3.2 KiB
Rust

//! `extended_launcher`: the client with a plugin of its own on top, started through
//! [`benilla_app::run_with`] as a crate built on benilla starts it. A feature 1.12.1 does not have
//! lives in a crate like this one, never in benilla.
//!
//! ```text
//! cargo run -p benilla-app --example extended_launcher
//! ```
//!
//! The banner reads `benilla build … · extended`, and the plugin logs one line at `Startup`: the
//! `AddOns/` folder in [`benilla_app::config_dir`], where an addon the crate ships is written.
//!
//! A crate of its own copies the `benilla` launcher (`crates/benilla`): a build script that stamps
//! its commit, a `main` like this one that reads the stamp back as `crates/benilla/src/main.rs`
//! does, and a manifest that takes benilla as the workspace does:
//!
//! ```toml
//! [features]
//! default = ["dev"]
//! # The instruments; the player build is `--no-default-features`.
//! dev = ["benilla-app/dev"]
//!
//! [dependencies]
//! # `default-features = false`, or `--no-default-features` still builds benilla-app with `dev`.
//! benilla-app = { git = "https://github.com/samwhosung/benilla", default-features = false }
//! # benilla's version, adding no features: bevy's defaults bring its audio stack back.
//! bevy = { version = "0.18.1", default-features = false }
//!
//! [build-dependencies]
//! benilla-buildstamp = { git = "https://github.com/samwhosung/benilla" }
//!
//! # Cargo reads `[patch]` and `[profile]` from the root manifest only, so benilla's are repeated:
//! # without the patches the addon Lua and the mixer are not benilla's.
//! [patch.crates-io]
//! lua-src = { git = "https://github.com/samwhosung/benilla" }
//! kira = { git = "https://github.com/samwhosung/benilla" }
//!
//! [profile.dev]
//! opt-level = 1
//!
//! [profile.dev.package."*"]
//! opt-level = 3
//! ```
//!
//! ```text
//! // build.rs
//! fn main() {
//! benilla_buildstamp::emit();
//! }
//! ```
//!
//! Its `Cargo.lock` starts as a copy of benilla's: cargo reads only the root's lockfile too, and
//! without it resolves every crate to its newest compatible version, not the one benilla is built
//! with. A dev build keeps its `WoW` link, `benilla-config/` and `.probe-identity` in its own
//! folder, beside that `Cargo.lock`, as benilla's does.
use benilla_app::{AppExit, BuildId};
use bevy::prelude::*;
/// The crate's own plugin: one line at `Startup`, to show it runs inside the client and where its
/// addons go.
struct HelloPlugin;
impl Plugin for HelloPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, || {
let addons = benilla_app::config_dir().map(|dir| dir.join("AddOns"));
info!("a plugin on top of benilla is running; its addons go in {addons:?}");
});
}
}
fn main() -> AppExit {
// A launcher of its own passes the stamp its build script made; an example has no build
// script, so this names the version and profile alone.
let build = BuildId {
version: env!("CARGO_PKG_VERSION"),
profile: if cfg!(debug_assertions) {
"debug"
} else {
"release"
},
..Default::default()
};
benilla_app::run_with(build, |app| {
app.add_plugins(HelloPlugin);
})
}