Architecture
Technical architecture of frond.
Layer Structure
frond/
├── core/ # Pure Rust, no engine deps
│ ├── frond-spatial/ # Quadtree, BVH, spatial hash
│ ├── frond-pathfinding/ # A*, flow fields, nav mesh
│ └── frond-math/ # Kinematic helpers, curves
│
├── bindings/ # Engine-specific adapters
│ ├── frond-godot/ # GDExtension
│ ├── frond-bevy/ # Bevy systems/components
│ ├── frond-unity/ # NativePlugin + C# wrapper
│ └── frond-love/ # Lua FFI for Love2D
│
├── scripting/ # Game logic in engine-native languages
│ ├── frond-gdscript/ # GDScript library
│ ├── frond-lua/ # Lua patterns (Love2D, etc.)
│ └── frond-csharp/ # C# patterns (Unity)
│
└── docs/ # Universal patterns, language-agnosticWhat Lives Where
| Layer | Contents | Why |
|---|---|---|
| core/ | Spatial, pathfinding, math | Perf-critical, complex algorithms, called 1000s/frame |
| bindings/ | Engine glue | Thin adapters to expose core to each engine |
| scripting/ | FSM, stats, inventory, timing, damage | Game logic, moddable, rapid iteration |
| docs/ | Camera, coyote time, patterns | Universal knowledge, any language |
Rule of thumb: If modders should be able to change it, it's scripting. If it needs to be fast, it's core.
Core Dependencies
glam- Math types (shared by Bevy, macroquad, rend3, others)serde- Serialization for config filesthiserror- Error handling
Engine Targets
| Engine | Binding | Scripting | Status |
|---|---|---|---|
| Godot | GDExtension | GDScript | First target |
| Bevy | bevy_ecs | (Rust) | Planned |
| Unity | NativePlugin | C# | Planned |
| Love2D | Lua FFI | Lua | Planned |
Godot Integration
GDScript (scripting/)
Game logic lives in GDScript for moddability:
gdscript
# FSM for movement states
extends Node
var fsm = preload("res://addons/frond/fsm.gd").new()
func _ready():
fsm.add_state("idle")
fsm.add_state("run")
fsm.set_initial("idle")GDExtension (bindings/)
Performance-critical code in Rust, exposed to GDScript:
rust
// bindings/frond-godot/src/lib.rs
use godot::prelude::*;
#[derive(GodotClass)]
#[class(base=Node)]
struct SpatialIndex { ... }
#[godot_api]
impl SpatialIndex {
#[func]
fn query_radius(&self, center: Vector2, radius: f32) -> Array<i64> { ... }
}Headless Testing
Test without the editor:
bash
godot --headless --script res://tests/test_fsm.gd --quitConfiguration
Tunable parameters live in asset files, not code.
ron
// movement.ron
MovementConfig(
jump_force: 15.0,
gravity: 40.0,
slide_decay: 0.95,
)Load via serde in Rust or ConfigFile in GDScript.