A TypeScript-first game engine with visual scripting, real-time physics, and a fully dockable editor — running in the browser or as a native desktop app.
Feather Engine is a browser-native game engine and editor built entirely in TypeScript. It delivers a Unreal-inspired development experience — Blueprint visual scripting, dockable editor panels, real-time 3D physics, particle systems, AI controllers — all running in a Vite-powered web app or packaged as a native desktop app via Tauri.
You build your game in the editor. Visual node graphs compile down to executable JavaScript. Hit Play and your beginPlay, tick, and onDestroy lifecycles run immediately — no reload, no compile step, no waiting.
- Blueprint visual scripting — connect nodes in a Rete-powered graph editor; the engine compiles them to live JS closures at runtime
- Full 3D rendering — Three.js scene graph with cameras, lighting, meshes, sprite actors, and a custom render pipeline
- 2D + 3D physics — Rapier physics worlds for both dimensions; joints, character controllers, collision events
- Dockable editor UI — DockView-based layout with viewport, inspector, asset browser, blueprint editor, and widget editor panels
- Widget/UI blueprints — author in-game HUDs visually; rendered as a DOM overlay above the canvas at runtime
- AI & navigation — behaviour tree manager, AI controllers, and NavMesh pathfinding via Recast Navigation
- Desktop packaging — wrap the same web frontend in a Tauri Rust shell for a native Windows/macOS/Linux app with filesystem access
- Audio & particles — built-in audio system and particle system integrated into the engine lifecycle
| Layer | Technology |
|---|---|
| Language | TypeScript 5.9 |
| Renderer | Three.js r182 |
| Physics | Rapier 2D + 3D |
| Visual Scripting | Rete 2 + plugins |
| Editor Layout | DockView Core |
| UI Framework | React 19 |
| Build Tool | Vite 8 |
| Desktop Shell | Tauri v2 (Rust) |
| Navigation | Recast Navigation |
- Node.js 18+ recommended
- npm
- For desktop app mode: Rust toolchain + Tauri prerequisites for your OS
npm install
npm run devThen open: http://localhost:5173
npm run build
npm run previewnpm install
npm run tauri devTauri config points dev mode to Vite and production to dist output.
There are two frontend entry points configured by Vite:
index.html→src/main.ts(editor app)gameplay.html→src/gameplay.ts(gameplay/runtime page)
This is important: the repository supports both the editor runtime and a gameplay-oriented runtime entry.
Key modules include:
Engine.ts— main orchestrator (init, update loop, play start/stop lifecycle)Scene.ts— scene/game object ownershipPhysicsWorld.ts— physics stepping and world behaviorScriptComponent.ts— compiled script wrapper (beginPlay,tick,onDestroy)- controller systems:
PlayerController,AIController,SpectatorController- movement modules (
MovementComponent,CharacterMovementComponent,FloatingPawnMovement)
AnimationInstance.ts— runtime animation blueprint behaviorUIManager.ts— runtime widget blueprint system rendered as HTML overlay
Contains panels and tooling for:
- scene editing,
- blueprint editing (node editor),
- actor/component authoring,
- widget blueprint authoring,
- asset/project management,
- viewport tools and gizmos.
src/main.ts wires everything together by constructing engine/editor managers, connecting asset managers, and connecting runtime resolvers (e.g., widget blueprint resolver into UIManager).
The repo already documents this flow in detail (see docs/How-Nodes-Become-Runtime-Code.md). In practical terms:
- Graph changes detected (node add/remove, connection add/remove).
- Node editor debounces and calls compile pipeline.
- Generator emits JS with:
- variable preamble,
- generated functions/custom events,
- lifecycle sections for BeginPlay/Tick/OnDestroy.
ScriptComponentcompiles code (vianew Function) into callable handlers.- Engine calls handlers during Play lifecycle.
So visual graphs are effectively transformed into lifecycle JS closures with shared script state.
A useful mental model:
- Node definitions (
src/editor/nodes/**) describe editor-facing behavior. - Node editor panel (
NodeEditorPanel.tsx) handles context menus, graph state, and code generation. - Compiled source string is stored with actor/widget/blueprint asset data.
- At runtime,
ScriptComponentwraps the compiled functions. Engineprovides script context (gameObject,deltaTime,elapsedTime, print, physics/UI hooks) and runs script lifecycle.- For UI-specific scripts,
UIManagermanages widget instances and callable UI API.
Widget blueprints are authored in editor panels and executed at runtime by UIManager:
- widgets are turned into a runtime blueprint tree,
UIManagercreates a DOM overlay container above the Three.js canvas,- each widget instance tracks element maps (name/id lookup), state, handlers,
- blueprint-exposed API supports create/add/remove/set text/visibility/color/opacity/progress/slider/etc,
- widget animations and input mode/cursor visibility are also runtime-controlled.
The widget render pipeline includes image caching behavior (e.g., cached texture/image lookups), plus dirty/refresh flow for updates.
In short: widget rendering is optimized by reusing loaded images and re-rendering when needed rather than rebuilding everything every frame.
There are multiple "runtime" distinctions in this repo:
- Editor mode: manipulate scene/assets/blueprints; no gameplay lifecycle scripts ticking as in play.
- Play mode: engine calls script
beginPlay, per-frametick, andonDestroywhen stopping.
- Web runtime: pure Vite/browser execution.
- Desktop runtime: same frontend, hosted by Tauri, with Rust commands for filesystem/project operations.
Event BeginPlay: one-time startup behaviorEvent Tick: per-frame behaviorEvent OnDestroy: shutdown/cleanup behavior
The node system is modular and category-based. src/editor/nodes/index.ts serves as a barrel file that exports node classes and triggers registration into palette/menus.
This is the full list of node module files currently under
src/editor/nodes.
animation/AnimBPNodes.ts
casting/CastingNodes.ts
casting/GameInstanceNodes.ts
casting/InheritanceNodes.ts
character/AIControllerNodes.ts
character/CameraControlNodes.ts
character/CameraSpringArmNodes.ts
character/CharacterMovementNodes.ts
character/ControllerNodes.ts
character/PlayerControllerNodes.ts
collision/CollisionEventNodes.ts
collision/TraceNodes.ts
components/ComponentNodeRules.ts
components/LightComponentNodes.ts
components/MeshComponentNodes.ts
components/TriggerComponentNodes.ts
conversions/BoolToNumber.ts
conversions/BoolToString.ts
conversions/ColorToString.ts
conversions/NumberToBool.ts
conversions/NumberToString.ts
conversions/StringToBool.ts
conversions/StringToColor.ts
conversions/StringToNumber.ts
events/CustomEventNodes.ts
events/EventBeginPlayNode.ts
events/EventOnDestroyNode.ts
events/EventTickNode.ts
events/InputKeyNodes.ts
flow-control/BranchNode.ts
flow-control/DelayNode.ts
flow-control/DoNNode.ts
flow-control/DoOnceNode.ts
flow-control/FlipFlopNode.ts
flow-control/ForLoopNode.ts
flow-control/ForLoopWithBreakNode.ts
flow-control/GateNode.ts
flow-control/MultiGateNode.ts
flow-control/SequenceNode.ts
flow-control/SwitchOnIntNode.ts
flow-control/SwitchOnStringNode.ts
flow-control/WhileLoopNode.ts
functions/FunctionNodes.ts
math/AbsNode.ts
math/ClampNode.ts
math/CosineNode.ts
math/ExtendedMathNodes.ts
math/GreaterThanNode.ts
math/LerpNode.ts
math/MathAddNode.ts
math/MathDivideNode.ts
math/MathMultiplyNode.ts
math/MathSubtractNode.ts
math/SineNode.ts
physics/AddAngularImpulseNode.ts
physics/AddForceAtLocationNode.ts
physics/AddForceNode.ts
physics/AddImpulseAtLocationNode.ts
physics/AddImpulseNode.ts
physics/AddTorqueNode.ts
physics/ClampVelocityNode.ts
physics/CollisionQueryNodes.ts
physics/CollisionToggleNodes.ts
physics/GetAngularVelocityNode.ts
physics/GetBodyTypeNode.ts
physics/GetCenterOfMassNode.ts
physics/GetGravityScaleNode.ts
physics/GetMassNode.ts
physics/GetPhysicsMaterialNode.ts
physics/GetSpeedNode.ts
physics/GetVelocityAtPointNode.ts
physics/GetVelocityNode.ts
physics/GetWorldGravityNode.ts
physics/IsGravityEnabledNode.ts
physics/IsSimulatingPhysicsNode.ts
physics/PhysicsEventNodes.ts
physics/RadialForceNodes.ts
physics/ResetPhysicsNode.ts
physics/SetAngularDampingNode.ts
physics/SetAngularVelocityNode.ts
physics/SetBodyTypeNode.ts
physics/SetConstraintNode.ts
physics/SetGravityEnabledNode.ts
physics/SetGravityScaleNode.ts
physics/SetLinearDampingNode.ts
physics/SetLinearVelocityNode.ts
physics/SetMassNode.ts
physics/SetPhysicsMaterialNode.ts
physics/SetPhysicsTransformNode.ts
physics/SetSimulatePhysicsNode.ts
physics/SetVelocityNode.ts
physics/SetWorldGravityNode.ts
physics/SleepWakeNodes.ts
physics/TeleportPhysicsBodyNode.ts
player/PlayerControllerNodes.ts
player/WorldNodes.ts
spawning/SpawningNodes.ts
transform/ActorNodes.ts
transform/GetPositionNode.ts
transform/GetRotationNode.ts
transform/GetScaleNode.ts
transform/SetPositionNode.ts
transform/SetRotationNode.ts
transform/SetScaleNode.ts
ui/WidgetBlueprintNodes.ts
ui/WidgetEnhancedNodes.ts
ui/WidgetNodes.ts
utility/LoadSceneNode.ts
utility/OpenSceneNode.ts
utility/PrintStringNode.ts
utility/StringNodes.ts
utility/TimerNodes.ts
values/BooleanNode.ts
values/ColorNode.ts
values/DeltaTimeNode.ts
values/FloatNode.ts
values/StringLiteralNode.ts
values/TimeNode.ts
values/Vector3LiteralNode.ts
variables/StructNodes.ts
variables/VariableNodes.ts
src/engine→ runtime systems (render/physics/controllers/scripts/ui)src/editor→ all editor tools and panelssrc/editor/nodes→ Blueprint node declarations + category modulesdocs/→ implementation guides (node compilation, adding node types)src-tauri/→ desktop shell and filesystem commands
A practical first-read order:
src/main.ts(wiring and startup)src/engine/Engine.ts(play lifecycle/update loop)src/engine/ScriptComponent.ts(compiled script execution)docs/How-Nodes-Become-Runtime-Code.mdsrc/editor/NodeEditorPanel.tsxsrc/engine/UIManager.tsand widget editor files
This sequence gives you the full “authoring → compile → runtime execute” loop.
- The node inventory above is the module-level list (file modules), not a manually expanded list of every class symbol in each file.
- Some files (e.g.,
ExtendedMathNodes.ts, widget node files, controller node files) contain multiple node classes each. - For an exhaustive class-level node catalog, a small script can be added later to extract all exported
*Nodeclasses.
