Bundles carry pre-baked backgrounds (paintings survive filesystem-less boots)
RoomDoc gains baked_visual (quantized indices, exporter-written, skipped when empty); bake() falls back to it when pics/ can't load; --export-bundle folds every room's painting in via World::bake_backgrounds_for_bundle. A six-painting game bundles to 1.5MB. Tests green; alley renders from bundle alone with no pics/ on disk. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
8f98380261
commit
f706a9ce55
@ -76,7 +76,11 @@ fn main() {
|
||||
let mut gs = GameState::new(world);
|
||||
|
||||
if let Some(path) = get("--export-bundle") {
|
||||
let bundle = gs.world.to_bundle();
|
||||
let mut bundle = gs.world.to_bundle();
|
||||
// Paintings ride inside the bundle as pre-quantized indices, so the
|
||||
// wasm build (no filesystem) keeps its backgrounds.
|
||||
gs.world.bake_backgrounds_for_bundle(&mut bundle.rooms);
|
||||
let bundle = bundle;
|
||||
// Through Value first, so the output is byte-stable.
|
||||
//
|
||||
// A bundle is full of HashMaps — rooms, scripts, sprites, every
|
||||
|
||||
@ -154,6 +154,12 @@ pub struct RoomDoc {
|
||||
/// `<name>-ctl.png` companions). Applied before `ops`.
|
||||
#[serde(default)]
|
||||
pub background: String,
|
||||
/// The background pre-quantized to visual indices (PIC_W*PIC_H), written
|
||||
/// by the bundle exporter so filesystem-less builds (wasm) keep their
|
||||
/// paintings. Only consulted when the `pics/` file can't be loaded;
|
||||
/// travels with `palette`, which the exporter sets to the quantized one.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub baked_visual: Vec<u8>,
|
||||
/// Procedural paint ops (replayed after the background, if any).
|
||||
#[serde(default)]
|
||||
pub ops: Vec<PicOp>,
|
||||
@ -207,6 +213,7 @@ impl Default for RoomDoc {
|
||||
name: String::new(),
|
||||
enter_text: String::new(),
|
||||
background: String::new(),
|
||||
baked_visual: Vec::new(),
|
||||
ops: Vec::new(),
|
||||
palette: None,
|
||||
cycles: Vec::new(),
|
||||
@ -395,6 +402,10 @@ impl World {
|
||||
let dir = self.base.join("pics");
|
||||
if let Some(rgba) = assets::load_rgba_scaled(&dir.join(format!("{}.png", self.doc.background)), PIC_W, PIC_H) {
|
||||
assets::bake_background(&rgba, &mut self.palette, &mut self.screens);
|
||||
} else if self.doc.baked_visual.len() == PIC_W * PIC_H {
|
||||
// No filesystem (or the art moved): the exporter pre-baked
|
||||
// the painting into the doc. Palette came from doc.palette.
|
||||
self.screens.visual.copy_from_slice(&self.doc.baked_visual);
|
||||
}
|
||||
if let Some(rgba) = assets::load_rgba_scaled(&dir.join(format!("{}-pri.png", self.doc.background)), PIC_W, PIC_H) {
|
||||
assets::bake_pri_mask(&rgba, &mut self.screens);
|
||||
@ -518,6 +529,25 @@ impl World {
|
||||
WorldBundle { manifest: self.manifest.clone(), rooms, scripts, sprites }
|
||||
}
|
||||
|
||||
/// Fold each room's background painting into its doc (quantized indices
|
||||
/// + palette), so the bundle plays where there is no filesystem. The
|
||||
/// exporter calls this; docs already carrying a bake are left alone.
|
||||
pub fn bake_backgrounds_for_bundle(&self, rooms: &mut BTreeMap<u32, RoomDoc>) {
|
||||
for doc in rooms.values_mut() {
|
||||
if doc.background.is_empty() || doc.baked_visual.len() == PIC_W * PIC_H {
|
||||
continue;
|
||||
}
|
||||
let dir = self.base.join("pics");
|
||||
if let Some(rgba) = assets::load_rgba_scaled(&dir.join(format!("{}.png", doc.background)), PIC_W, PIC_H) {
|
||||
let mut pal = doc.palette.clone().unwrap_or_else(Palette::base);
|
||||
let mut probe = Screens::new();
|
||||
assets::bake_background(&rgba, &mut pal, &mut probe);
|
||||
doc.palette = Some(pal);
|
||||
doc.baked_visual = probe.visual;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the loaded world with a bundle. A bundle that carries
|
||||
/// sprites replaces the art wholesale (the wasm/bootstrap path); one
|
||||
/// that doesn't keeps whatever this World already loaded.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user