This checkout had no git history at all, so this one commit carries the whole
of the Everwood work as a single import on top of chairmanpow/benilla-octo's
`main` (706cd71). The two trees have genuinely diverged — each has files the
other does not — so this is a fork point, not a catch-up.
Today's work, which is the reason a baseline exists at all:
- Booth previews no longer cast world shadows (`NO_BOOTH_SHADOW`). Portrait
characters were entering the sun's shadow cascades, so every skinned-rig
shadow specialization compiled live mid-frame; the hitch detector logged
"main thread blocked 1316 ms" beside a `compiled LIVE` warning. This was
the Fashion/Tmog stutter.
- Per-pane dress-up: each `DressUpModel` pane assembles and stages its own
tried-on look instead of every pane mirroring the live player.
- Item template cache is append-only JSONL written on the IO pool, replacing
an 11.6 MB whole-map JSON rewrite on the main thread every 10 s.
- `WOW_SYSTEM_TIMING` rebuilt per-thread: it took 2 mutexes per system enter
and 4 per exit, costing 15 ms a frame (590 fps -> 60) and corrupting the
measurements it was taken to produce.
- The visibility-churn sweep moved to its own `WOW_FLASH_CHURN` switch, so a
frame-cost reading no longer pays 2.7 ms a frame for it.
Local state (`benilla-config/`, `logs/`, `target/`) is excluded by the
existing .gitignore; the account credential it holds is not in this commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
131 lines
4.6 KiB
Rust
131 lines
4.6 KiB
Rust
//! Which build is running: the release and the commit the binary was built from, stamped at
|
|
//! compile time by the launcher shims' build script (`benilla-buildstamp`) and passed to `run` as
|
|
//! the [`BuildId`] resource. It shows in the startup log line ([`banner`]), in crash reports and in
|
|
//! the debug panel's footer.
|
|
|
|
use bevy::prelude::*;
|
|
|
|
/// The launcher shim's compile-time stamp. The git fields are empty when the build had no
|
|
/// checkout or no `git` on `PATH`, which [`BuildId::summary`] reports as an unknown commit.
|
|
#[derive(Resource, Clone, Copy)]
|
|
pub struct BuildId {
|
|
/// The workspace version from `Cargo.toml`, which every release bumps.
|
|
pub version: &'static str,
|
|
/// `git describe --tags --long` against the nearest `v*` tag (`v0.2.0-12-gb17be27`); empty
|
|
/// when no release tag is in reach, as in a source archive or a shallow clone.
|
|
pub describe: &'static str,
|
|
/// The full sha, which the debug panel copies.
|
|
pub sha: &'static str,
|
|
/// Git's own abbreviation of [`sha`](Self::sha).
|
|
pub short: &'static str,
|
|
/// The commit date of [`sha`](Self::sha) (`YYYY-MM-DD`), not the build date.
|
|
pub date: &'static str,
|
|
/// The cargo profile directory: `debug`, `release` or `ship`.
|
|
pub profile: &'static str,
|
|
}
|
|
|
|
impl BuildId {
|
|
/// The release this build is: the version, and `+N` when the commit is N past that version's
|
|
/// tag. With no tag for this version in reach (none fetched, or the release commit before its
|
|
/// tag exists), the version alone.
|
|
pub fn release(&self) -> String {
|
|
match commits_past_tag(self.describe, self.version) {
|
|
Some(n) if n > 0 => format!("{}+{n}", self.version),
|
|
_ => self.version.to_owned(),
|
|
}
|
|
}
|
|
|
|
/// The one-line build id: release, short sha, commit date and profile.
|
|
pub fn summary(&self) -> String {
|
|
if self.short.is_empty() {
|
|
format!(
|
|
"{} · unknown commit (built without a git checkout) · {}",
|
|
self.release(),
|
|
self.profile
|
|
)
|
|
} else {
|
|
format!(
|
|
"{} · {} · {} · {}",
|
|
self.release(),
|
|
self.short,
|
|
self.date,
|
|
self.profile
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// How many commits past `v{version}` a `--long` describe (`<tag>-<n>-g<hash>`) is, or `None`
|
|
/// when the describe is empty, malformed or names another version's tag.
|
|
fn commits_past_tag(describe: &str, version: &str) -> Option<u32> {
|
|
let mut parts = describe.rsplitn(3, '-');
|
|
parts.next().filter(|hash| hash.starts_with('g'))?;
|
|
let n: u32 = parts.next()?.parse().ok()?;
|
|
let tag = parts.next()?;
|
|
(tag.strip_prefix('v')? == version).then_some(n)
|
|
}
|
|
|
|
/// Log the build id once at startup, not env-gated, so every pasted log carries it.
|
|
pub fn banner(build: Res<BuildId>) {
|
|
info!("benilla build {}", build.summary());
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
fn build(version: &'static str, describe: &'static str, short: &'static str) -> BuildId {
|
|
BuildId {
|
|
version,
|
|
describe,
|
|
sha: "",
|
|
short,
|
|
date: "2026-09-27",
|
|
profile: "release",
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn a_tagged_release_reads_as_its_version() {
|
|
let b = build("0.2.0", "v0.2.0-0-gb17be27", "b17be27");
|
|
assert_eq!(b.summary(), "0.2.0 · b17be27 · 2026-09-27 · release");
|
|
}
|
|
|
|
#[test]
|
|
fn a_commit_past_the_release_counts_its_distance() {
|
|
assert_eq!(
|
|
build("0.2.0", "v0.2.0-12-gb17be27", "b17be27").release(),
|
|
"0.2.0+12"
|
|
);
|
|
// A pre-release tag's own hyphens stay in the tag.
|
|
assert_eq!(
|
|
build("1.0.0-rc1", "v1.0.0-rc1-3-gabc1234", "abc1234").release(),
|
|
"1.0.0-rc1+3"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn another_versions_tag_or_none_reads_as_the_version_alone() {
|
|
// The release commit itself, before its tag exists: the nearest tag is the previous one.
|
|
assert_eq!(
|
|
build("0.2.0", "v0.1.0-450-gb17be27", "b17be27").release(),
|
|
"0.2.0"
|
|
);
|
|
// No release tag in reach: a source archive or a shallow clone.
|
|
assert_eq!(build("0.2.0", "", "b17be27").release(), "0.2.0");
|
|
assert_eq!(
|
|
build("0.2.0", "not-a-describe", "b17be27").release(),
|
|
"0.2.0"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn a_build_without_git_still_names_its_release() {
|
|
let b = build("0.2.0", "", "");
|
|
assert_eq!(
|
|
b.summary(),
|
|
"0.2.0 · unknown commit (built without a git checkout) · release"
|
|
);
|
|
}
|
|
}
|