75 models (5 KenneyNL starter kits, .glb, pinned commits + sha256, 2.8MB)
and 556 sounds (7 packs via kenney.nl content-hashed URLs, each zip
sha256-verified, 13MB). Nothing large enters git: dirs are gitignored, only
CREDITS.toml and .gitignore files are tracked.
The index is the point — an AI cannot use a library it can't name:
- id is kenney/racing/vehicle-truck-yellow, anchored to where the file
LIVES, not its category, so retuning the category tree never invalidates
a saved game
- Filename tokens are the floor; the value is two hand-curated alias tables
(76 model rows, 116 audio FAMILY rows — Kenney's footstep_wood_000..004
collapse to one family, so 556 files stay maintainable) spanning
synonyms, kid vocabulary and misspellings (vehical, hosue, motercycle),
function over identity ("something to hide behind"), colour/size/
material, and theme, plus ~190 query-time synonym expansions
- AssetKind model/sound/music so a 30-second track can't be returned as a
hit sound; GLB probe reads skins -> rigged, animations -> animated
- FIND_MODEL tool descriptor (provider-neutral plain data) + compact
results; library_summary() is 469 chars for 632 entries and provably
doesn't grow with the catalogue; resolve_or_explain() rejects
hallucinated ids with near-misses; local_spawn() gives the local
librarian a best match plus a confidence blending strength with margin
HONEST GAP: every Kenney audio pack is Ogg Vorbis only — no WAV exists
upstream — and this tree has no vorbis decoder. Sounds are indexed and
searchable but NOT playable: entries carry decodable:false, the agent JSON
emits playable:false so a game cannot fire a silent sound, and
--transcode converts via ffmpeg when present. A real decoder is the fix.
Three bugs found by testing, all fixed: sci-fi-sounds.zip ships a directory
with no owner-write bit so that pack alone silently extracted 0 of 73 files;
prepositions matched phrase aliases ("...at the roadworks" hit "something to
shoot at"), so function words must be dropped, not down-weighted; and exact
names lost to incidental aliases (a coin SOUND outranked the coin MODEL).
Miss list left visible at 2/52 rather than tuned away — both are defensible
answers against over-narrow expectations.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
17 lines
1.2 KiB
Rust
17 lines
1.2 KiB
Rust
use makepad_game_assets::{agent, AssetIndex};
|
|
fn main() {
|
|
let idx = AssetIndex::build(std::path::Path::new("apps/arcade/resources"));
|
|
println!("index: {} entries ({} models, {} sounds, {} music)\n",
|
|
idx.len(),
|
|
idx.count_of(makepad_game_assets::AssetKind::Model),
|
|
idx.count_of(makepad_game_assets::AssetKind::Sound),
|
|
idx.count_of(makepad_game_assets::AssetKind::Music));
|
|
println!("--- prompt summary ({} chars) ---\n{}\n", agent::library_summary(&idx).len(), agent::library_summary(&idx));
|
|
for q in ["i want a lorry", "a big scary monster", "something to hide behind",
|
|
"sound when you crash into a wall", "happy win music", "a digger like at the roadworks"] {
|
|
let r = agent::execute(&idx, &agent::FindParams::new(q));
|
|
let top: Vec<String> = r.iter().take(3).map(|x| format!("{} ({})", x.id, x.name)).collect();
|
|
println!("{:38} -> {}", format!("\"{q}\""), if top.is_empty() { "(no hits)".into() } else { top.join("\n ") });
|
|
}
|
|
println!("\n--- compact JSON handed to the model ---\n{}", agent::results_to_json(&agent::execute(&idx, &agent::FindParams::new("red truck"))));
|
|
}
|