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
+157
View File
@@ -0,0 +1,157 @@
# Architecture
This document explains how Oxide is structured and the principles that govern how
it is built. For per-system detail, see the topic documents (e.g. [math.md](math.md)).
## Goals
Oxide is a general-purpose 3D game engine written in Rust, built to make **any**
3D game — scaling from stylized low-poly to realistic graphics — and to **ship
only what each game uses**. It is built in two phases: a **general-purpose engine**
(Phase 1, scene graph, render pass pipeline, input, UI, physics, scripting,
animation, particles, shaders, audio, content kit, and game export) and a set of
optional, feature-gated **built-in modules** (Phase 2: ray-traced sound, developer
console, procedural toolkit, terrain, open world, pathfinding/AI, water). The
guiding idea is **build tools, not games**, all driven through a first-class
**in-engine editor**. See [`PLAN.md`](../PLAN.md) for the staged roadmap.
## Design philosophy
These principles are non-negotiable and shape every decision:
1. **Build in stages.** Each stage produces a usable, standalone artifact and
must be fully tested and stable before the next begins. See
[development.md](development.md) and [`PLAN.md`](../PLAN.md).
2. **Composability.** Every system should be usable independently of the others.
You should be able to pull in the math module, or the scene graph, without
dragging in the renderer.
3. **Correctness and clarity over premature optimization.** Optimize when a
benchmark says to, not before.
4. **Minimal public surface.** Internal complexity is fine; the external API
should be small and clean. Modules expose a curated set of types through
`pub use`, not their whole internal structure.
5. **No feature creep between stages.** New ideas go to the backlog, not into the
current stage.
6. **The editor grows with the engine.** `oxide-editor` is a first-class
deliverable, gaining panels and tools as each stage adds systems.
7. **Build tools, not games.** Ship composable building blocks; genre-specific
behavior belongs in game code or optional modules.
8. **Ship only what's used.** Subsystems are feature-gated **modules** (from
Stage 5); an exported game compiles in only the modules it registers.
9. **Scalable fidelity.** A data-driven render pass pipeline lets a project run
anything from a flat low-poly/stylized look to a full realistic stack, paying
only for the passes it enables.
10. **Modules are the primary extension point.** A module registers engine logic
*and* editor UI *and* its own settings through one documented API; anyone —
including AI agents — can write one.
## Workspace layout
Oxide is a single Cargo workspace. Crates share version, edition, license, and
dependency versions through `[workspace.package]` and `[workspace.dependencies]`
in the root `Cargo.toml`.
```
Oxide/
├── engine/ # oxide-engine — the core library (all engine systems)
├── editor/ # oxide-editor — the in-engine editor binary
├── examples/ # oxide-examples — runnable examples, one+ per stage
├── tests/ # oxide-tests — integration / end-to-end test harness
├── docs/ # this documentation
├── assets/ # logos and shared assets
├── install.sh # release build + system install
├── PLAN.md # authoritative staged roadmap
├── README.md # short project overview
└── CLAUDE.md # rules and context for AI-assisted development
```
### Crate responsibilities
- **`oxide-engine`** — the library that contains every engine system. It is
organized as one module per system (`math`, and later `scene`, `render`,
`physics`, …). Each module is independently usable and re-exports its public
types. A `prelude` module collects the most common imports.
- **`oxide-editor`** — the binary users run. It depends on `oxide-engine` and
builds a UI on top of engine systems (its own window with a placeholder
viewport since Stage 2; egui panels from Stage 3). It never contains engine
logic itself; it is a consumer of the engine.
- **`oxide-examples`** — small, focused programs that each demonstrate one
stage's capabilities. They double as manual-review artifacts and as living
documentation. `publish = false`; they are never installed.
- **`oxide-tests`** — integration tests that exercise the engine the way a real
consumer would, including cross-module scenarios and fuzz/property tests.
## Engine module structure
Inside `oxide-engine`, each system is a module under `engine/src/`. The pattern,
established by the math module, is:
```
engine/src/
├── lib.rs # declares modules, defines the prelude
├── math/
│ ├── mod.rs # module docs + curated `pub use` re-exports
│ ├── transform.rs # one type/concept per file, with its own tests
│ ├── aabb.rs
│ └── ...
├── render/ # Stage 2: GPU acquisition + surface clear loop
│ ├── mod.rs # RenderError, clear_view, re-exports
│ ├── gpu.rs # Gpu (instance/adapter/device/queue)
│ └── context.rs # RenderContext (surface, resize, render_frame)
└── window/ # Stage 2: window + event loop + App trait
├── mod.rs # WindowConfig, `event` re-export module
├── app.rs # App trait, AppCtx
└── runner.rs # winit ApplicationHandler internals
```
Rules of thumb:
- **One concept per file.** Prefer many small focused files over a few large
ones.
- **Tests live with the code.** Each file has a `#[cfg(test)] mod tests` block
covering core behavior and edge cases.
- **The module root curates the API.** `mod.rs` decides what is public via
`pub use`; submodules are private (`mod foo;`, not `pub mod foo;`) unless there
is a reason to expose the path.
- **The prelude is the front door.** `oxide_engine::prelude::*` brings in the
types a typical consumer needs, including re-exported third-party math types so
downstream code needs only one dependency for everyday work.
## Key dependencies
Chosen for portability and a lightweight footprint:
| Concern | Crate | Notes |
|---------|-------|-------|
| Math | [`glam`](https://docs.rs/glam) | SIMD-friendly vectors/quats/matrices; `serde` feature enabled |
| Graphics | [`wgpu`](https://docs.rs/wgpu) | Portable across Vulkan/Metal/DX12 (since Stage 2; re-exported as `oxide_engine::wgpu`) |
| Windowing | [`winit`](https://docs.rs/winit) | Cross-platform windows and events (since Stage 2; re-exported as `oxide_engine::winit`) |
| ECS | [`hecs`](https://docs.rs/hecs) | Lightweight archetypal ECS (Stage 3+) |
| Physics | [`rapier3d`](https://docs.rs/rapier3d) | Rigid bodies and collision (Stage 6+) |
| Editor UI | [`egui`](https://docs.rs/egui) | Immediate-mode UI (Stage 3+) |
| Logging | `log` + `env_logger` | Facade + env-driven backend |
| Errors | `anyhow` + `thiserror` | Application vs. library error handling |
| Serialization | `serde` + `ron` | Scene/asset (de)serialization (Stage 3+) |
## Error handling and logging
- **Libraries (`oxide-engine`)** define their own error types with `thiserror`
so callers can match on failure modes.
- **Binaries (`oxide-editor`, examples)** use `anyhow` for ergonomic error
propagation at the top level.
- **Logging** uses the `log` facade throughout the engine; binaries initialize a
backend (`env_logger`). Control verbosity with `RUST_LOG`, e.g.
`RUST_LOG=oxide_engine=debug cargo run -p oxide-examples --bin math_demo`.
## Installability
Oxide must remain installable as a Linux package at all times. `install.sh`
builds in release mode and installs the `oxide-editor` binary and assets under a
prefix (`/usr/local` by default, overridable with `PREFIX`). Any new installed
binary or asset must be reflected in `install.sh` in the same change.
## See also
- [conventions.md](conventions.md) — coordinate system, units, color space
- [development.md](development.md) — workflow, testing, and how stages progress
- [`PLAN.md`](../PLAN.md) — the full staged roadmap