Files
kiln/kiln-core/src/builtin_scripts.rs
T

69 lines
3.0 KiB
Rust
Raw Normal View History

2026-06-16 14:34:42 -05:00
//! Built-in scripts: archetypes that are really scripted objects.
//!
//! Some archetypes (currently the `pusher_*` family) have behavior that an
//! ordinary scripted object can express exactly. Rather than special-case them in
//! the engine, the map loader *expands* such an archetype into an [`ObjectDef`]
//! carrying an embedded Rhai script (see [`ObjectDef::builtin_script`]) plus a
//! `BUILTIN_<archetype>` tag. The script reads that tag for any per-instance
//! parameter (the pusher reads it for its direction), and [`crate::map_file`]'s
//! save path uses the same tag to collapse the object back into its archetype
//! keyword so maps round-trip.
//!
//! This module is the single place to register a new script-backed archetype:
//! add an arm to [`archetype_script`].
use crate::archetype::Archetype;
/// Prefix for the tag that marks an object as an expanded built-in archetype and
/// names which archetype it came from (e.g. `"BUILTIN_pusher_east"`).
pub(crate) const BUILTIN_TAG_PREFIX: &str = "BUILTIN_";
/// The pusher behavior, embedded into the binary. Shared by every direction —
/// direction comes from the object's tag, so all pushers share one compiled AST.
const PUSHER: &str = include_str!("scripts/pusher.rhai");
2026-06-21 01:32:47 -05:00
/// The spinner behavior, embedded into the binary. Shared by both spin directions —
/// direction comes from the object's tag, so all spinners share one compiled AST.
const SPINNER: &str = include_str!("scripts/spinner.rhai");
2026-06-21 18:27:45 -05:00
/// The gem behavior, embedded into the binary: a `grab()` hook that adds a gem to
/// the player and removes the object.
const GEM: &str = include_str!("scripts/gem.rhai");
2026-06-16 14:34:42 -05:00
/// The tag identifying an object as the expanded form of `arch`, e.g.
/// `"BUILTIN_pusher_east"`.
pub(crate) fn builtin_tag(arch: Archetype) -> String {
format!("{BUILTIN_TAG_PREFIX}{}", arch.name())
}
/// Recovers the archetype a `BUILTIN_*` tag came from, or `None` if `tag` is not a
/// built-in tag naming a known archetype. Used by the save path to round-trip.
pub(crate) fn archetype_from_builtin_tag(tag: &str) -> Option<Archetype> {
let name = tag.strip_prefix(BUILTIN_TAG_PREFIX)?;
Archetype::try_from(name).ok()
}
/// Returns the embedded script implementing `arch` as an object, or `None` if the
/// archetype is a plain terrain cell. The one place script-backed archetypes are
/// declared.
pub(crate) fn archetype_script(arch: Archetype) -> Option<&'static str> {
match arch {
Archetype::Pusher(_) => Some(PUSHER),
2026-06-21 01:32:47 -05:00
Archetype::Spinner(_) => Some(SPINNER),
2026-06-21 18:27:45 -05:00
Archetype::Gem => Some(GEM),
_ => None,
}
}
/// Returns the embedded script implementing `arch` as an object, or `None` if the
/// archetype is a plain terrain cell. The one place script-backed archetypes are
/// declared.
pub(crate) fn archetype_script_key(arch: Archetype) -> Option<&'static str> {
match arch {
Archetype::Pusher(_) => Some("BUILTIN_pusher"),
Archetype::Spinner(_) => Some("BUILTIN_spinner"),
Archetype::Gem => Some("BUILTIN_gem"),
2026-06-16 14:34:42 -05:00
_ => None,
}
}