Appearance
Building Systems for Nexus Engine
A "System" in Nexus Engine is a standalone, decoupled feature (e.g., Pathfinding, Player Controllers, Phone UI) that users can purchase or install and drop into their 3D worlds.
System Anatomy
A complete system consists of two parts:
- The Runtime Component: A standard React component (2D or 3D via
@react-three/fiber) that executes the actual game logic. - The Editor Plugin Schema: A configuration object that tells the Visual Editor how to render the properties panel, spawn helpers, and handle configuration.
1. The Runtime Component
Runtime components receive position, rotation, scale, and all custom properties defined in your Editor schema as standard React props.
tsx
import React from 'react';
import { useGLTF } from '@react-three/drei';
import * as THREE from 'three';
export function MySystemRuntime({ position, rotation, speed, modelUrl }) {
const { scene } = useGLTF(modelUrl);
// Apply position to the scene if needed
React.useEffect(() => {
scene.position.set(position[0], position[1], position[2]);
}, [position]);
return <primitive object={scene} />;
}2. The Editor Schema
The schema object must implement the EditorPlugin interface from @neural-workspace/nexus-engine-core.
tsx
import { EditorPlugin } from '@neural-workspace/nexus-engine-core';
export const MySystemPlugin: EditorPlugin = {
id: "my-system",
name: "My Awesome System",
category: "Systems",
is3D: true, // True if the system renders inside the <Canvas>
iconSvg: '<svg>...</svg>', // Raw SVG string for the sidebar
// Optional: A URL to a 3D model used ONLY as a visual placeholder in the editor
viewportHelperModel: "/models/optimized/placeholder.glb",
// Optional: A custom React component for complex Editor viewport visualization
// (e.g., drawing grids, rings, or bounds). This overrides `viewportHelperModel`.
CustomViewportHelper: ({ node, onChange }) => {
// Render custom visualizers using standard Drei/Three tools
return <mesh><boxGeometry/></mesh>;
},
// Optional: A custom React component for the right sidebar properties panel.
// This allows complex UIs (like behavior graphs or script editors) beyond simple schemas.
CustomInspector: ({ node, onChange }) => {
// You can access built-in Editor UI components from window.NexusEnv.EditorUI!
const { BehaviorScriptEditor } = (window as any).NexusEnv.EditorUI;
return (
<BehaviorScriptEditor
script={node.properties.script || []}
onChange={(newScript) => onChange({ script: newScript })}
/>
);
},
defaultProps: {
speed: 5,
modelUrl: '/models/optimized/default.glb',
script: []
},
properties: [
{ id: 'speed', label: 'Speed', type: 'number', min: 1, max: 10, default: 5 },
{ id: 'modelUrl', label: 'Model', type: 'string', default: '/models/optimized/default.glb' },
// You can also use built-in complex property types directly in the schema:
{ id: 'script', label: 'Bot Script', type: 'behavior_script', options: ['move', 'wait', 'turn'] }
]
};Distributing Systems
Systems can be bundled into standalone ECMAScript modules (ESM) and served remotely.
To build systems for distribution, we use esbuild with a custom globalsPlugin that maps bare specifiers (like react, three) to window.NexusEnv. This ensures that dynamically loaded systems share the same React instance as the host engine.
See apps/backend/buildPlugins.js for the exact build pipeline.