Objects

Objects are the primary way to store persistent, version-controlled state. Whether you are building a measurement tool or a volumetric editor, data that represents a part of a project (from a single point to a large mesh) should be defined as an Object.

Versioning with FseObject

This system is built on versioned objects. When you define a data structure and derive FseObject, the SDK manages it as a versioned entity. This provides several foundational features:

  • Local Undo/Redo: Every update is recorded in the session history, enabling undo/redo without custom logic.
  • Project Synchronization: In multi-user sessions, changes can be synchronized across connected clients.
  • Persistence: Objects are serialized and stored in the project database automatically.

Defining an Object

To create an object type, define a standard Rust struct and apply the necessary derives. This example shows how to combine coordinates with user-defined metadata:

use fdk::libs::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize, Deserialize, FseObject, PersistentObject)]
pub struct SurveyPoint {
    pub name: String,
    pub location: DVec3,
    pub classification: u8,
}

Managing State with the Facade

Object state is controlled by fse_state. To interact with objects, use the FseFacade. This interface allows you to create, update, and query project state, and is available when executing a Statement or a Tool.

For example, when a user clicks in the viewport, a tool can call fse.new_object to spawn an entity. The engine returns a unique FseId, which acts as a permanent, version-safe handle. The ID remains constant even as the object changes, allowing you to maintain stable relationships.

Hierarchy and Representations

Objects can be linked using relationships, such as ParentOf, to build a hierarchy. They can also be associated with Representations.

Representations are specialized objects, such as point clouds or triangle meshes, that the renderer can stream and display. Attaching a Representation to an Object defines how that data appears in the 3D viewport.

Bevy Autosync: Synchronizing State to the ECS

While fse_state is the authoritative source of truth, the Bevy Autosync system synchronizes that state into the engine’s Entity Component System (ECS).

When an object is created, modified, or restored during an undo/redo operation, the SDK triggers an autosync. This ensures that the visual representation in the scene matches the underlying versioned state. This centralized logic provides a predictable mechanism for deriving the rendered environment from the application state.

Composition over Inheritance

When extending the object model, prefer composition over inheritance. Each object should have a clear set of responsibilities and own a specific set of components on the ECS side.

Because multiple objects might contribute to a single entity, it is critical that their responsibilities do not overlap. Composition ensures that each object manages its own slice of the ECS state without conflict.