From 85980939f59ced6c3d141b9a89099bf368091dfd Mon Sep 17 00:00:00 2001 From: Sam Sung <51686767+samwhosung@users.noreply.github.com> Date: Tue, 6 Oct 2026 09:12:02 +0700 Subject: [PATCH] A crate on top finds its own benilla-config/ through config_dir (#809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- crates/benilla-app/examples/extended_launcher.rs | 11 ++++++++--- crates/benilla-app/src/lib.rs | 9 +++++++++ docs/CONTRIBUTING.md | 10 ++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/crates/benilla-app/examples/extended_launcher.rs b/crates/benilla-app/examples/extended_launcher.rs index 8c44196c..f8c38021 100644 --- a/crates/benilla-app/examples/extended_launcher.rs +++ b/crates/benilla-app/examples/extended_launcher.rs @@ -6,7 +6,8 @@ //! cargo run -p benilla-app --example extended_launcher //! ``` //! -//! The banner reads `benilla build … · extended`, and the plugin logs one line at `Startup`. +//! 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` @@ -55,12 +56,16 @@ use benilla_app::{AppExit, BuildId}; use bevy::prelude::*; -/// The crate's own plugin: one line at `Startup`, to show it runs inside the client. +/// 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, || info!("a plugin on top of benilla is running")); + 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:?}"); + }); } } diff --git a/crates/benilla-app/src/lib.rs b/crates/benilla-app/src/lib.rs index b6eeee9f..1a0e200b 100644 --- a/crates/benilla-app/src/lib.rs +++ b/crates/benilla-app/src/lib.rs @@ -215,6 +215,15 @@ pub fn run_with(build: BuildId, extend: impl FnOnce(&mut App)) -> AppExit { launch(build, Some(Box::new(extend))) } +/// The state folder, `benilla-config/`, where a crate on top keeps its own files: an addon it ships +/// goes in its `AddOns/`, where benilla finds addons and their art and fonts. `None` when +/// persistence is off (a capture run, or no executable path), and it may not exist yet. A dev +/// build resolves it from the launcher's folder, which [`run_with`] sets, so ask from `extend` or +/// a system, never before. +pub fn config_dir() -> Option { + local_state::home() +} + /// What a crate on top of benilla adds to the built app ([`run_with`]). type Extension<'a> = Box; diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index bf071393..735a1dfb 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -40,11 +40,13 @@ A feature 1.12.1 does not have lives in a crate of its own that adds its Bevy pl `benilla_app::run_with`, as `crates/benilla-app/examples/extended_launcher.rs` shows, or in a fork. A client started through `run_with` says `extended` in its build line, so its reports read apart from stock benilla's. The crate keeps its own settings, never rows in benilla's CVar table, -which every addon reads. +which every addon reads, and its files go under `benilla_app::config_dir()`, its own +`benilla-config/`: an addon it ships is written into that folder's `AddOns/` and loads as any +addon does. -benilla opens a piece of itself to such a crate only when its own 1.12.1 work creates that piece, -never for the crate alone, and promises no stable API: a crate pins the benilla revision it -builds on. What a crate cannot reach stays a fork's. +Past `run_with` and that folder, benilla opens a piece of itself to such a crate only when its own +1.12.1 work creates that piece, never for the crate alone, and promises no stable API: a crate +pins the benilla revision it builds on. What a crate cannot reach stays a fork's. ## How a change is judged