# Building a Simple Game with the SimVX Editor This tutorial walks through building a 2D game scene using the SimVX editor. Each step has been validated with automated tests to ensure the editor is functional. ## Prerequisites ```bash # Install in dev mode uv pip install -e packages/core -e packages/graphics -e packages/editor # Launch the editor python -m simvx.editor.main # Or: from simvx.editor.app import launch; launch() ``` ## Step-by-Step Tutorial ### Step 1: Launch the Editor **Action:** Run the editor. A window appears with: - **Menu bar** at top: File, Edit, Scene, View, Tools, Help - **Toolbar** below: Move/Rotate/Scale buttons, Play/Pause/Stop, 3D/2D toggle - **Scene Tree** panel (left): shows the node hierarchy with a "Root" node - **Viewport** (center): 3D preview area - **Inspector** panel (right): property editor (empty until a node is selected) - **Status bar** (bottom): mouse position and selection info - **Bottom tabs**: Console, Code, Files, Animation **Verify:** - [x] The editor window opens without errors - [x] All panels are visible and labeled - [x] The Scene Tree shows a single "Root" node - [x] The undo stack is empty - [x] The editor is not in play mode **Tests:** `TestStep1_LaunchEditor` (10 tests) --- ### Step 2: Add a Game Node **Action:** Click the **"+"** button in the Scene Tree header. The **Add Node** dialog appears. **In the dialog:** 1. You see a list of 12 node types (Node, Node2D, Node3D, Camera3D, etc.) 2. There's a filter text field at the top 3. Click **"Node2D"** in the list **Result:** A new Node2D appears under Root in the Scene Tree. **Verify:** - [x] Clicking "+" opens the Add Node dialog - [x] The dialog shows all 12 available types - [x] Clicking a type creates the node and closes the dialog - [x] The new node appears in the Scene Tree - [x] The new node gets selected after creation - [x] The operation is recorded in the undo stack **Tests:** `TestStep2_AddNodes` (8 tests), `TestAddNodeDialogInteraction` (3 tests) --- ### Step 3: Rename the Node **Action:** With the Node2D selected, press **F2** to open the rename overlay. 1. The rename field appears with the current name highlighted 2. Type **"Game"** 3. Press **Enter** to confirm **Result:** The node is renamed from "Node2D" to "Game" in the Scene Tree. **Verify:** - [x] F2 key opens the rename overlay - [x] Typing a name and pressing Enter renames the node - [x] The tree view updates to show the new name - [x] Renaming is undoable with Ctrl+Z **Tests:** `TestStep3_RenameNodes` (7 tests), `TestUndoRedoViaUI` (3 tests) --- ### Step 4: Add Child Nodes **Action:** With "Game" selected, click "+" again. 1. Select **"Node2D"** from the dialog 2. The new node appears **under** Game (as a child) 3. Press F2, type **"Player"**, press Enter 4. Select "Game" again in the tree 5. Click "+" and add another **"Node2D"** 6. Rename it to **"Enemy"** 7. Select "Game", add a **"Camera3D"** **Result:** Your scene tree looks like: ``` Root └─ Game (Node2D) ├─ Player (Node2D) ├─ Enemy (Node2D) └─ Camera3D ``` **Verify:** - [x] Nodes are added as children of the selected node - [x] If nothing is selected, nodes go under Root - [x] Multiple nodes can be added sequentially - [x] Each add is a separate undo operation **Tests:** `TestStep2_AddNodes::test_add_node_under_selected_parent` --- ### Step 5: Select a Node and View Properties **Action:** Click on **"Player"** in the Scene Tree. **Result:** The Inspector panel updates to show: - Type label: "Node2D" - Name field: "Player" - **Node** section: Visible checkbox - **Transform** section: Position (X, Y), Rotation, Scale (X, Y) **Verify:** - [x] Clicking a tree item updates the inspector - [x] Inspector shows the correct type name - [x] Inspector shows the correct node name - [x] Transform section appears for spatial nodes - [x] Node section appears with visibility toggle - [x] Switching selection updates the inspector **Tests:** `TestStep4_SelectionInspector` (9 tests) --- ### Step 6: Edit Transform Properties **Action:** In the Inspector, change the Player's position: 1. Click on the Position X spinbox 2. Type **100** or use the increment buttons 3. Change Position Y to **300** **Result:** The Player node's position updates to (100, 300). **Verify:** - [x] Position widgets exist for 2D nodes - [x] Initial values match the node's position (0, 0) - [x] Changing a value updates the node immediately - [x] Position changes are undoable with Ctrl+Z - [x] 3D transforms work similarly with X, Y, Z components - [x] Rotation and Scale can also be edited **Tests:** `TestStep5_EditTransforms` (7 tests), `TestSpinBoxInteraction` (2 tests) --- ### Step 7: Undo and Redo **Action:** Try the undo/redo system: 1. Press **Ctrl+Z** to undo the last position change 2. Press **Ctrl+Shift+Z** to redo it 3. Undo multiple times to step back through all changes 4. Redo to restore them **Verify:** - [x] Ctrl+Z undoes the last operation - [x] Ctrl+Shift+Z redoes an undone operation - [x] Multiple undos can be chained - [x] Undo works for: add node, rename, property change, delete, duplicate **Tests:** `TestStep6_UndoRedo` (6 tests), `TestKeyboardShortcuts` (5 tests) --- ### Step 8: Delete and Duplicate Nodes **Action:** 1. Select "Enemy" in the tree 2. Press **Delete** key — Enemy is removed 3. Press **Ctrl+Z** — Enemy is restored 4. Select "Player" 5. Use the context menu (right-click) → **Duplicate** — creates "Player_copy" 6. Select "Player_copy" and press Delete to remove it **Verify:** - [x] Delete key removes the selected node - [x] Cannot delete the root node - [x] Delete clears the selection - [x] Deleting is undoable - [x] Duplicate creates a copy with "_copy" suffix - [x] Duplicate is undoable - [x] Right-click context menu appears with all options **Tests:** `TestStep7_DeleteDuplicate` (7 tests), `TestContextMenu` (2 tests) --- ### Step 9: Copy and Paste **Action:** 1. Select "Player" 2. Right-click → **Copy** (or Ctrl+C) 3. Select "Game" 4. Right-click → **Paste** (or Ctrl+V) — creates "Player_paste" under Game **Verify:** - [x] Copy stores the node in the clipboard - [x] Paste creates a new node from the clipboard - [x] Pasted node gets "_paste" suffix - [x] Paste is undoable **Tests:** `TestStep8_CopyPaste` (3 tests) --- ### Step 10: Save the Scene **Action:** 1. Press **Ctrl+S** to save 2. If no path is set, the Save As dialog appears 3. Navigate to your project directory 4. Enter filename: **"game.json"** 5. Click Save **Result:** Scene is saved to disk as JSON. **Verify:** - [x] Save creates a JSON file on disk - [x] Save clears the "modified" flag - [x] Save remembers the path for future saves - [x] The path is stored in `current_scene_path` **Tests:** `TestStep9_SaveLoad` (6 tests) --- ### Step 11: Load a Scene **Action:** 1. Press **Ctrl+N** to create a new empty scene 2. Press **Ctrl+O** to open the file dialog 3. Navigate to and select **"game.json"** 4. Click Open **Result:** The saved scene is loaded with all nodes restored. **Verify:** - [x] New Scene clears everything (nodes, selection, undo) - [x] Open Scene loads nodes from the JSON file - [x] Loading clears the undo stack - [x] Loaded scene has all the original nodes **Tests:** `TestStep9_SaveLoad` (6 tests) --- ### Step 12: Custom Properties If you create a custom node class with `Property` descriptors: ```python from simvx.core import Node2D, Property class Player(Node2D): speed = Property(5.0, range=(0, 20)) health = Property(100, range=(0, 200)) name_tag = Property("hero") is_alive = Property(True) mode = Property("walk", enum=["walk", "run", "idle"]) ``` The Inspector will automatically create the right widget for each property: | Type | Widget | |------|--------| | `float` with `range` | Slider | | `int` / `float` without range | SpinBox | | `bool` | CheckBox | | `str` | TextEdit | | `str` with `enum` | DropDown | | Color tuple | ColorPicker | | `Vec2` / `Vec3` | Multi-SpinBox row | **Tests:** `TestStep12_CustomProperties` (5 tests) --- ### Step 13: Play Mode **Action:** 1. Press **F5** (or click Play) to enter play mode 2. Press **F7** (or click Pause) to toggle pause 3. Press **F6** (or click Stop) to exit play mode **Result:** The scene is serialized before play, and restored when stopped. **Verify:** - [x] Play enters play mode and emits signal - [x] Pause toggles the paused state - [x] Stop restores the scene to pre-play state - [x] Stop when not playing is a no-op **Tests:** `TestStep10_PlayMode` (5 tests) --- ### Step 14: Inspector Section Collapse **Action:** Click on a section header (e.g., "Transform") to collapse it. **Result:** The section rows hide. Click again to expand. **Tests:** `TestStep14_SectionCollapseExpand` (3 tests) --- ### Step 15: Gizmo and Viewport Mode **Action:** - Click **Move/Rotate/Scale** buttons in the toolbar to change gizmo mode - Press **Q** to cycle through modes - Click **3D/2D** buttons to switch viewport mode **Tests:** `TestStep15_GizmoMode` (3 tests), `TestStep16_ViewportMode` (3 tests)