Import Oxide engine (Stages 0–10) under MIT license

Full project snapshot migrated to new Gitea remote without history:
engine, editor, physics, script, examples, tests, docs, and assets.
Relicensed from GPLv3 to MIT and updated repo URLs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Homer Simpson
2026-07-05 20:41:02 +02:00
parent 2afb56b329
commit 9eead719b0
157 changed files with 47270 additions and 2 deletions
+82
View File
@@ -0,0 +1,82 @@
//! The [`ScriptModule`] — the Stage-10 entry point that wires scripting into an
//! [`App`].
//!
//! Following the engine's module convention, everything the scripting layer
//! contributes is registered here so it can be enabled, disabled, or removed as
//! a unit (and so an exported game that uses no scripts never compiles them in).
//! This first piece registers the [`Script`] component *type* for reflection
//! (making it dual-editable and captured by the play-mode snapshot), installs
//! the `.rhai` [`ScriptLoader`], and inserts the shared [`ScriptEngine`]. The
//! lifecycle system that compiles and runs scripts each frame is added in a
//! later piece.
use oxide_engine::app::{App, Module, Schedule};
use crate::host::run_scripts;
use crate::{Script, ScriptHost, ScriptLoader};
/// The scripting module. Add it after [`DefaultModules`] to give an app a
/// `rhai`-backed scripting layer.
///
/// [`DefaultModules`]: oxide_engine::app::DefaultModules
///
/// ```
/// use oxide_engine::app::App;
/// use oxide_script::ScriptModule;
///
/// let mut app = App::new();
/// app.add_module(ScriptModule);
/// assert!(app.has_module("script"));
/// assert!(app.types.is_registered("Script"));
/// ```
pub struct ScriptModule;
impl Module for ScriptModule {
fn name(&self) -> &'static str {
"script"
}
fn build(&self, app: &mut App) {
// Register the component type for reflection so it round-trips through
// RON (scripts/AI/inspector) and is captured by the play-mode snapshot.
app.register_type::<Script>("Script");
// Teach the asset server to load `.rhai` files as `ScriptAsset`s.
app.add_loader(ScriptLoader);
// The runtime that compiles and runs each entity's script, driven on
// `Update` (after `FixedUpdate`, so scripts observe post-physics poses).
app.insert_resource(ScriptHost::new());
app.add_system(Schedule::Update, run_scripts);
}
}
#[cfg(test)]
mod tests {
use super::*;
use oxide_engine::app::DefaultModules;
#[test]
fn module_registers_its_type_loader_and_host() {
let mut app = App::new();
app.add_modules(DefaultModules);
app.add_module(ScriptModule);
assert!(app.has_module("script"));
assert!(app.types.is_registered("Script"));
assert!(app.has_resource::<ScriptHost>());
// The per-frame run_scripts system was registered.
assert!(app.system_count() >= 1);
}
#[test]
fn removing_the_module_drops_its_type() {
let mut app = App::new();
app.add_module(ScriptModule);
assert!(app.types.is_registered("Script"));
assert!(app.remove_module("script"));
assert!(!app.has_module("script"));
assert!(!app.types.is_registered("Script"));
}
}