AgentSkillsCN

Engine Scene

引擎场景

SKILL.md

Creating Scenes and Entities

This skill guides scene creation, entity management, and scene serialization for the engine.

Scene Structure

Scenes are JSON files that define entities with their components. Scenes live in assets/scenes/ directory.

json
{
  "version": 2,
  "entities": [
    {
      "id": 1001,
      "components": {
        "Name": { "Value": "Entity Name" },
        "Transform": { ... },
        "RenderMesh": { ... }
      }
    }
  ]
}

Scene Operations

Create a new scene file

Location: yourgame/assets/scenes/<name>.json

json
{
  "version": 2,
  "entities": []
}

Create entity programmatically

go
func (s *MySystem) SpawnPlayer(scene *scene.Scene, position math.Vector3) EntityId {
    entity := scene.CreateEntity("Player")
    
    scene.SetTransform(entity, component.TransformData{
        Position: position,
        Rotation: math.QuaternionIdentity(),
        Scale:    math.NewVector3(1, 1, 1),
    })
    
    scene.SetRenderMesh(entity, component.RenderMeshData{
        MeshId:     "player_model",
        MaterialId: "player_mat",
    })
    
    return entity
}

Common Entity Patterns

Basic Entity with Name and Transform

json
{
  "id": 1001,
  "components": {
    "Name": { "Value": "My Entity" },
    "Transform": {
      "Position": { "X": 0, "Y": 0, "Z": 0 },
      "Rotation": { "X": 0, "Y": 0, "Z": 0, "W": 1 },
      "Scale": { "X": 1, "Y": 1, "Z": 1 },
      "Debug": false,
      "Parent": 0
    }
  }
}

Entity with RenderMesh

json
{
  "id": 1002,
  "components": {
    "Name": { "Value": "Cube" },
    "RenderMesh": {
      "MeshId": "cube",
      "MaterialId": "red",
      "ShaderId": "",
      "IsTransparent": false
    },
    "Transform": {
      "Position": { "X": 5, "Y": 0, "Z": -5 },
      "Rotation": { "X": 0, "Y": 0, "Z": 0, "W": 1 },
      "Scale": { "X": 1, "Y": 1, "Z": 1 },
      "Debug": false,
      "Parent": 0
    }
  }
}

Entity with Camera

json
{
  "id": 1003,
  "components": {
    "Name": { "Value": "Main Camera" },
    "Camera": {
      "Fov": 45,
      "Near": 0.1,
      "Far": 1000,
      "Projection": 0,
      "Active": true,
      "Target": { "X": 0, "Y": 0, "Z": 0 }
    },
    "Transform": {
      "Position": { "X": 0, "Y": 20, "Z": 10 },
      "Rotation": { "X": 0, "Y": 0, "Z": 0, "W": 1 },
      "Scale": { "X": 1, "Y": 1, "Z": 1 },
      "Debug": false,
      "Parent": 0
    }
  }
}

Child Entity

json
{
  "id": 1004,
  "components": {
    "Name": { "Value": "Child Object" },
    "Transform": {
      "Position": { "X": 0, "Y": 2, "Z": 0 },
      "Rotation": { "X": 0, "Y": 0, "Z": 0, "W": 1 },
      "Scale": { "X": 0.5, "Y": 0.5, "Z": 0.5 },
      "Debug": false,
      "Parent": 1003
    }
  }
}

Scene API

go
// Create/destroy entities
CreateEntity(name string) EntityId
DestroyEntity(id EntityId) error

// Component access
HasTransform(id EntityId) bool
GetTransform(id EntityId) (*component.TransformData, error)
SetTransform(id EntityId, data component.TransformData) error

HasCamera(id EntityId) bool
GetCamera(id EntityId) (*component.CameraData, error)
SetCamera(id EntityId, data component.CameraData) error

HasRenderMesh(id EntityId) bool
GetRenderMesh(id EntityId) (*component.RenderMeshData, error)
SetRenderMesh(id EntityId, data component.RenderMeshData) error

HasName(id EntityId) bool
GetName(id EntityId) (string, error)
SetName(id EntityId, name string) error

// Hierarchy
SetParent(child EntityId, parent EntityId) error
GetParent(child EntityId) (EntityId, error)
GetChildren(parent EntityId) ([]EntityId, error)

// Position helpers
GetWorldPosition(id EntityId) (math.Vector3, error)

// Entity duplication
DuplicateEntity(id EntityId, registry *ComponentRegistry) (EntityId, error)

Loading Scenes

In your game's main.go:

go
eng.InitFunc = func() {
    RegisterComponents(eng)
    RegisterSystems(eng)
    
    eng.LoadOrCreateScene("scenes/default.json")
}

eng.Run()

Important Rules

  1. Entity IDs: Must be unique within a scene
  2. Parent references: Parent ID must reference an existing entity
  3. Component order: Name first, then other components, Transform last
  4. Version: Always use version 2 for new scenes
  5. Debug flag: Set to true to see debug visualization

Example: Complete RTS Scene

json
{
  "version": 2,
  "entities": [
    {
      "id": 1,
      "components": {
        "Name": { "Value": "Ground" },
        "RenderMesh": {
          "MeshId": "plane",
          "MaterialId": "default"
        },
        "Transform": {
          "Position": { "X": 0, "Y": -2, "Z": 0 },
          "Scale": { "X": 50, "Y": 1, "Z": 50 },
          "Parent": 0
        }
      }
    },
    {
      "id": 2,
      "components": {
        "Name": { "Value": "RTS Camera" },
        "Camera": {
          "Fov": 45,
          "Active": true,
          "Target": { "X": 0, "Y": 0, "Z": 0 }
        },
        "RTSCamera": {
          "PanSpeed": 20,
          "ZoomLevel": 20,
          "PitchAngle": 45
        },
        "Transform": {
          "Position": { "X": 0, "Y": 20, "Z": 10 },
          "Parent": 0
        }
      }
    },
    {
      "id": 3,
      "components": {
        "Name": { "Value": "Player Unit" },
        "RenderMesh": {
          "MeshId": "cube",
          "MaterialId": "blue"
        },
        "Transform": {
          "Position": { "X": 0, "Y": 0, "Z": 0 },
          "Parent": 0
        }
      }
    }
  ]
}

See Also

  • engine-component: For adding custom components to entities
  • engine-system: For processing entities in scenes