summer-engine 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +72 -8
  2. package/dist/bin/postinstall.d.ts +2 -0
  3. package/dist/bin/postinstall.js +3 -0
  4. package/dist/bin/summer.d.ts +2 -0
  5. package/dist/bin/summer.js +34 -0
  6. package/dist/commands/create.d.ts +2 -0
  7. package/dist/commands/create.js +99 -0
  8. package/dist/commands/install.d.ts +2 -0
  9. package/dist/commands/install.js +135 -0
  10. package/dist/commands/list.d.ts +2 -0
  11. package/dist/commands/list.js +48 -0
  12. package/dist/commands/login.d.ts +2 -0
  13. package/dist/commands/login.js +75 -0
  14. package/dist/commands/logout.d.ts +2 -0
  15. package/dist/commands/logout.js +26 -0
  16. package/dist/commands/mcp.d.ts +2 -0
  17. package/dist/commands/mcp.js +7 -0
  18. package/dist/commands/open.d.ts +2 -0
  19. package/dist/commands/open.js +32 -0
  20. package/dist/commands/run.d.ts +2 -0
  21. package/dist/commands/run.js +69 -0
  22. package/dist/commands/skills.d.ts +2 -0
  23. package/dist/commands/skills.js +187 -0
  24. package/dist/commands/status.d.ts +2 -0
  25. package/dist/commands/status.js +43 -0
  26. package/dist/lib/api-client.d.ts +17 -0
  27. package/dist/lib/api-client.js +69 -0
  28. package/dist/lib/auth.d.ts +13 -0
  29. package/dist/lib/auth.js +39 -0
  30. package/dist/lib/banner.d.ts +4 -0
  31. package/dist/lib/banner.js +122 -0
  32. package/dist/lib/engine.d.ts +12 -0
  33. package/dist/lib/engine.js +36 -0
  34. package/dist/mcp/server.d.ts +4 -0
  35. package/dist/mcp/server.js +40 -0
  36. package/dist/mcp/tools/asset-tools.d.ts +2 -0
  37. package/dist/mcp/tools/asset-tools.js +247 -0
  38. package/dist/mcp/tools/debug-tools.d.ts +2 -0
  39. package/dist/mcp/tools/debug-tools.js +49 -0
  40. package/dist/mcp/tools/project-tools.d.ts +2 -0
  41. package/dist/mcp/tools/project-tools.js +55 -0
  42. package/dist/mcp/tools/scene-tools.d.ts +2 -0
  43. package/dist/mcp/tools/scene-tools.js +139 -0
  44. package/dist/mcp/tools/with-engine.d.ts +10 -0
  45. package/dist/mcp/tools/with-engine.js +65 -0
  46. package/package.json +22 -5
  47. package/skills/3d-lighting/SKILL.md +103 -0
  48. package/skills/fps-controller/SKILL.md +131 -0
  49. package/skills/gdscript-patterns/SKILL.md +96 -0
  50. package/skills/gdscript-patterns/reference.md +55 -0
  51. package/skills/scene-composition/SKILL.md +108 -0
  52. package/skills/ui-basics/SKILL.md +121 -0
  53. package/bin/summer.js +0 -3
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: 3d-lighting
3
+ description: Lighting setup, environment, sky, and shadows for 3D scenes. Use when setting up a 3D scene, adding lights, configuring WorldEnvironment, or adjusting shadows.
4
+ license: MIT
5
+ compatibility:
6
+ - Cursor
7
+ - Claude Code
8
+ - Windsurf
9
+ ---
10
+
11
+ # 3D Lighting for Summer Engine
12
+
13
+ Set up lighting and environment for 3D scenes. Follow these patterns for outdoor and indoor setups.
14
+
15
+ ## Light Types
16
+
17
+ | Type | Use case |
18
+ |------|----------|
19
+ | DirectionalLight3D | Sun, moon, outdoor primary light |
20
+ | OmniLight3D | Point lights (lamps, torches) |
21
+ | SpotLight3D | Flashlights, stage lights |
22
+
23
+ ## Basic Outdoor Setup
24
+
25
+ ### 1. Directional Light (Sun)
26
+
27
+ ```
28
+ summer_add_node(parent="./World", type="DirectionalLight3D", name="Sun")
29
+ summer_set_prop(path="./World/Sun", key="rotation_degrees", value="Vector3(-45, 30, 0)")
30
+ summer_set_prop(path="./World/Sun", key="light_energy", value="1.0")
31
+ summer_set_prop(path="./World/Sun", key="shadow_enabled", value="true")
32
+ summer_set_prop(path="./World/Sun", key="light_color", value="Color(1, 0.95, 0.9, 1)")
33
+ ```
34
+
35
+ Warm sunlight: `Color(1, 0.95, 0.9, 1)`. Cool moonlight: `Color(0.8, 0.85, 1, 1)`.
36
+
37
+ ### 2. WorldEnvironment (Sky + Ambient)
38
+
39
+ ```
40
+ summer_add_node(parent="./World", type="WorldEnvironment", name="WorldEnvironment")
41
+ summer_set_prop(path="./World/WorldEnvironment", key="environment", value="Environment")
42
+ ```
43
+
44
+ Then configure the Environment's sub-properties. The Environment resource has:
45
+ - `background_mode` — 2 for sky, 1 for color, 3 for canvas
46
+ - `sky` — Sky resource (ProceduralSkyMaterial or PhysicalSkyMaterial)
47
+ - `ambient_light_source` — AMBIENT_SOURCE_SKY or AMBIENT_SOURCE_COLOR
48
+ - `ambient_light_color`
49
+ - `tonemap_mode`
50
+
51
+ For a simple procedural sky:
52
+
53
+ ```
54
+ summer_set_resource_property(nodePath="./World/WorldEnvironment", resourceProperty="environment", subProperty="background_mode", value="2")
55
+ ```
56
+
57
+ You may need to create a Sky resource and assign it. In the editor this is done via the inspector; via MCP, SetResourceProperty on nested resources may require the resource to exist first. If `environment` is "Environment", the engine creates a default. For `sky`, you might set `sky` to "ProceduralSkyMaterial" or similar—check Godot docs for the exact property chain.
58
+
59
+ **Simpler path:** Use the 3d-basic template which already has a sky. Copy that structure.
60
+
61
+ ### 3. Fill Light (Optional)
62
+
63
+ A second, weaker directional or omni for shadow fill:
64
+
65
+ ```
66
+ summer_add_node(parent="./World", type="DirectionalLight3D", name="FillLight")
67
+ summer_set_prop(path="./World/FillLight", key="rotation_degrees", value="Vector3(-30, -120, 0)")
68
+ summer_set_prop(path="./World/FillLight", key="light_energy", value="0.3")
69
+ summer_set_prop(path="./World/FillLight", key="shadow_enabled", value="false")
70
+ summer_set_prop(path="./World/FillLight", key="light_color", value="Color(0.7, 0.8, 1, 1)")
71
+ ```
72
+
73
+ ## Indoor / Point Lights
74
+
75
+ ```
76
+ summer_add_node(parent="./World", type="OmniLight3D", name="Lamp")
77
+ summer_set_prop(path="./World/Lamp", key="position", value="Vector3(2, 3, 2)")
78
+ summer_set_prop(path="./World/Lamp", key="light_energy", value="0.8")
79
+ summer_set_prop(path="./World/Lamp", key="light_color", value="Color(1, 0.9, 0.7, 1)")
80
+ summer_set_prop(path="./World/Lamp", key="omni_range", value="8")
81
+ ```
82
+
83
+ ## Property Reference
84
+
85
+ | Property | Type | Example |
86
+ |----------|------|---------|
87
+ | light_energy | float | `1.0`, `1.5` |
88
+ | light_color | Color | `"Color(1, 0.95, 0.9, 1)"` |
89
+ | shadow_enabled | bool | `true` |
90
+ | rotation_degrees | Vector3 | `"Vector3(-45, 30, 0)"` |
91
+ | position | Vector3 | `"Vector3(0, 10, 0)"` |
92
+ | omni_range | float | `10` (OmniLight3D) |
93
+ | spot_range | float | `10` (SpotLight3D) |
94
+ | spot_angle | float | `45` (degrees, SpotLight3D) |
95
+
96
+ ## Color Format
97
+
98
+ Always use `Color(r, g, b, a)` with values 0.0–1.0:
99
+
100
+ - Warm white: `Color(1, 0.95, 0.9, 1)`
101
+ - Cool white: `Color(0.9, 0.95, 1, 1)`
102
+ - Orange (torch): `Color(1, 0.6, 0.2, 1)`
103
+ - Green (alien): `Color(0.5, 1, 0.5, 1)`
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: fps-controller
3
+ description: First-person character controller with movement, camera, and physics. Use when building an FPS game, first-person movement, or a 3D character that moves with WASD and looks with mouse.
4
+ license: MIT
5
+ compatibility:
6
+ - Cursor
7
+ - Claude Code
8
+ - Windsurf
9
+ ---
10
+
11
+ # FPS Controller for Summer Engine
12
+
13
+ Build a first-person character controller using CharacterBody3D, Camera3D, and proper collision. Follow this structure for reliable movement and camera behavior.
14
+
15
+ ## Scene Structure
16
+
17
+ ```
18
+ Player (CharacterBody3D)
19
+ ├── CollisionShape3D # Capsule for body
20
+ ├── Camera3D # At head height
21
+ └── RayCast3D # Optional: ground detection
22
+ ```
23
+
24
+ ## Step-by-Step Setup via MCP
25
+
26
+ ### 1. Add the Player Root
27
+
28
+ ```
29
+ summer_add_node(parent="./World", type="CharacterBody3D", name="Player")
30
+ summer_set_prop(path="./World/Player", key="position", value="Vector3(0, 1, 0)")
31
+ ```
32
+
33
+ ### 2. Add Collision Shape
34
+
35
+ ```
36
+ summer_add_node(parent="./World/Player", type="CollisionShape3D", name="CollisionShape3D")
37
+ summer_set_prop(path="./World/Player/CollisionShape3D", key="shape", value="CapsuleShape3D")
38
+ ```
39
+
40
+ Configure capsule size (radius ~0.4, height ~1.6 for typical human):
41
+
42
+ ```
43
+ summer_set_resource_property(nodePath="./World/Player/CollisionShape3D", resourceProperty="shape", subProperty="radius", value="0.4")
44
+ summer_set_resource_property(nodePath="./World/Player/CollisionShape3D", resourceProperty="shape", subProperty="height", value="1.6")
45
+ ```
46
+
47
+ ### 3. Add Camera
48
+
49
+ ```
50
+ summer_add_node(parent="./World/Player", type="Camera3D", name="Camera3D")
51
+ summer_set_prop(path="./World/Player/Camera3D", key="position", value="Vector3(0, 1.6, 0)")
52
+ ```
53
+
54
+ Camera at y=1.6 puts the view at roughly eye level (capsule center is at 0.8, so 0.8 + 0.8 = 1.6 for eyes).
55
+
56
+ ### 4. InputMap Actions
57
+
58
+ Create movement and look actions:
59
+
60
+ ```
61
+ summer_input_map_bind(name="move_forward", events=[{type:"key", key:"W"}])
62
+ summer_input_map_bind(name="move_back", events=[{type:"key", key:"S"}])
63
+ summer_input_map_bind(name="move_left", events=[{type:"key", key:"A"}])
64
+ summer_input_map_bind(name="move_right", events=[{type:"key", key:"D"}])
65
+ summer_input_map_bind(name="jump", events=[{type:"key", key:"Space"}])
66
+ ```
67
+
68
+ For mouse look, you need a script. The script will use `Input.get_vector` for movement and `InputEventMouseMotion` for look. Attach a script and implement:
69
+
70
+ ### 5. GDScript Pattern
71
+
72
+ ```gdscript
73
+ extends CharacterBody3D
74
+
75
+ @export var move_speed: float = 5.0
76
+ @export var jump_velocity: float = 4.5
77
+ @export var mouse_sensitivity: float = 0.002
78
+
79
+ func _physics_process(_delta: float) -> void:
80
+ # Movement
81
+ var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
82
+ var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
83
+ if direction:
84
+ velocity.x = direction.x * move_speed
85
+ velocity.z = direction.z * move_speed
86
+ else:
87
+ velocity.x = move_toward(velocity.x, 0, move_speed)
88
+ velocity.z = move_toward(velocity.z, 0, move_speed)
89
+
90
+ # Jump
91
+ if is_on_floor() and Input.is_action_just_pressed("jump"):
92
+ velocity.y = jump_velocity
93
+
94
+ # Gravity
95
+ if not is_on_floor():
96
+ velocity.y -= 9.8 * _delta
97
+
98
+ move_and_slide()
99
+ ```
100
+
101
+ For mouse look, add to a script attached to the Player or Camera:
102
+
103
+ ```gdscript
104
+ func _input(event: InputEvent) -> void:
105
+ if event is InputEventMouseMotion:
106
+ rotate_y(-event.relative.x * mouse_sensitivity)
107
+ $Camera3D.rotate_x(-event.relative.y * mouse_sensitivity)
108
+ $Camera3D.rotation.x = clamp($Camera3D.rotation.x, -1.2, 1.2)
109
+ ```
110
+
111
+ ## Property Values (Godot Format)
112
+
113
+ When using `summer_set_prop`, use these string formats:
114
+
115
+ | Property | Value |
116
+ |----------|-------|
117
+ | position | `"Vector3(0, 1, 0)"` |
118
+ | rotation_degrees | `"Vector3(0, 0, 0)"` |
119
+ | shape | `"CapsuleShape3D"` |
120
+
121
+ For `summer_set_resource_property` on CapsuleShape3D:
122
+ | subProperty | value |
123
+ |-------------|-------|
124
+ | radius | `"0.4"` |
125
+ | height | `"1.6"` |
126
+
127
+ ## Common Issues
128
+
129
+ - **Falling through floor:** Ensure the floor has a StaticBody3D or similar with a CollisionShape3D
130
+ - **Camera clipping:** If the camera goes inside geometry, enable `near` on the Camera3D or add collision exception
131
+ - **Mouse capture:** For FPS, you typically need `Input.mouse_mode = Input.MOUSE_MODE_CAPTURED` in `_ready()` and a way to release (e.g., Escape)
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: gdscript-patterns
3
+ description: Common GDScript idioms, signals, exports, and type hints. Use when writing GDScript, attaching scripts to nodes, connecting signals, or defining exported variables.
4
+ license: MIT
5
+ compatibility:
6
+ - Cursor
7
+ - Claude Code
8
+ - Windsurf
9
+ ---
10
+
11
+ # GDScript Patterns for Summer Engine
12
+
13
+ When writing GDScript for Summer Engine projects, follow these patterns. They align with Godot 4.x conventions and work well with MCP scene operations.
14
+
15
+ ## Type Hints
16
+
17
+ Always use type hints for clarity and editor support:
18
+
19
+ ```gdscript
20
+ var health: int = 100
21
+ var speed: float = 5.0
22
+ var player_name: String = ""
23
+ var velocity: Vector3 = Vector3.ZERO
24
+ var is_alive: bool = true
25
+ ```
26
+
27
+ For nodes, use typed references:
28
+
29
+ ```gdscript
30
+ @onready var collision_shape: CollisionShape3D = $CollisionShape3D
31
+ @onready var camera: Camera3D = $Camera3D
32
+ ```
33
+
34
+ ## Signals
35
+
36
+ Define signals at the top of the script, then emit them:
37
+
38
+ ```gdscript
39
+ signal died
40
+ signal health_changed(new_health: int)
41
+ signal item_collected(item_name: String)
42
+
43
+ func take_damage(amount: int) -> void:
44
+ health -= amount
45
+ health_changed.emit(health)
46
+ if health <= 0:
47
+ died.emit()
48
+ ```
49
+
50
+ When connecting via MCP, use `summer_connect_signal` with the emitter path, signal name, receiver path, and method name. The receiver script must have the method defined.
51
+
52
+ ## Exports
53
+
54
+ Use `@export` for inspector-editable properties:
55
+
56
+ ```gdscript
57
+ @export var move_speed: float = 5.0
58
+ @export var jump_force: float = 10.0
59
+ @export var max_health: int = 100
60
+ @export var can_double_jump: bool = false
61
+ ```
62
+
63
+ Exports appear in the inspector. MCP can set initial values via `summer_set_prop` after the node exists, but exports are best for values the designer tweaks.
64
+
65
+ ## Lifecycle Methods
66
+
67
+ | Method | When it runs | Use for |
68
+ |--------|--------------|---------|
69
+ | `_ready()` | Once when node enters tree | Initialization, getting node references |
70
+ | `_process(delta: float)` | Every frame | UI, non-physics logic |
71
+ | `_physics_process(delta: float)` | Every physics frame (fixed) | Movement, physics, collision |
72
+
73
+ For character movement, use `_physics_process` and `move_and_slide()`.
74
+
75
+ ## Node Access
76
+
77
+ ```gdscript
78
+ # Prefer $ for direct children
79
+ var camera = $Camera3D
80
+
81
+ # get_node() for dynamic paths
82
+ var target = get_node("../Enemy/HealthBar")
83
+
84
+ # get_parent() / get_children() when needed
85
+ var siblings = get_parent().get_children()
86
+ ```
87
+
88
+ ## Common Patterns
89
+
90
+ For health systems, input handling, and state machines, see [reference.md](reference.md).
91
+
92
+ ## MCP Integration
93
+
94
+ When the AI adds a script via `summer_add_node` and attaches a script, the script path is set via `summer_set_prop(path, "script", "res://path/to/script.gd")`. The script file must exist—use `summer_write_file` to create it first.
95
+
96
+ For signal connections, the receiver must have the handler method. Create the script with the method stub before calling `summer_connect_signal`.
@@ -0,0 +1,55 @@
1
+ # GDScript Patterns — Reference
2
+
3
+ Detailed patterns for common game systems. Load this when implementing health, input, or state logic.
4
+
5
+ ## Health System
6
+
7
+ ```gdscript
8
+ signal died
9
+
10
+ var health: int = 100
11
+ var max_health: int = 100
12
+
13
+ func take_damage(amount: int) -> void:
14
+ health = maxi(0, health - amount)
15
+ if health <= 0:
16
+ died.emit()
17
+
18
+ func heal(amount: int) -> void:
19
+ health = mini(max_health, health + amount)
20
+ ```
21
+
22
+ ## Input Handling
23
+
24
+ Use `Input.get_axis()` for movement, `Input.is_action_just_pressed()` for discrete actions:
25
+
26
+ ```gdscript
27
+ func _physics_process(_delta: float) -> void:
28
+ var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
29
+ velocity.x = input_dir.x * move_speed
30
+ velocity.z = input_dir.y * move_speed
31
+
32
+ if Input.is_action_just_pressed("jump"):
33
+ velocity.y = jump_force
34
+
35
+ move_and_slide()
36
+ ```
37
+
38
+ Ensure InputMap actions exist via `summer_input_map_bind` before the game runs.
39
+
40
+ ## State Machine (Simple)
41
+
42
+ ```gdscript
43
+ enum State { IDLE, WALKING, JUMPING, FALLING }
44
+ var current_state: State = State.IDLE
45
+
46
+ func _physics_process(delta: float) -> void:
47
+ match current_state:
48
+ State.IDLE:
49
+ if Input.is_action_just_pressed("jump"):
50
+ current_state = State.JUMPING
51
+ elif input_dir != Vector2.ZERO:
52
+ current_state = State.WALKING
53
+ State.WALKING:
54
+ # ...
55
+ ```
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: scene-composition
3
+ description: How to structure scenes, when to use sub-scenes, and node hierarchy conventions. Use when building scenes, organizing nodes, or creating reusable prefabs.
4
+ license: MIT
5
+ compatibility:
6
+ - Cursor
7
+ - Claude Code
8
+ - Windsurf
9
+ ---
10
+
11
+ # Scene Composition for Summer Engine
12
+
13
+ Organize scenes for clarity, reuse, and MCP compatibility. Follow these conventions when building levels, characters, and UI.
14
+
15
+ ## Node Hierarchy Conventions
16
+
17
+ ### 3D Scenes
18
+
19
+ ```
20
+ World (Node3D) # Root or main container
21
+ ├── Camera3D # Main camera
22
+ ├── DirectionalLight3D # Sun / primary light
23
+ ├── WorldEnvironment # Sky, ambient, fog
24
+ ├── Level (Node3D) # Level geometry
25
+ │ ├── Ground
26
+ │ ├── Walls
27
+ │ └── Platforms
28
+ ├── Props (Node3D) # Placed objects (trees, crates)
29
+ ├── Enemies (Node3D) # Enemy instances
30
+ └── Player # Player instance (or instantiated)
31
+ ```
32
+
33
+ ### 2D Scenes
34
+
35
+ ```
36
+ Level (Node2D)
37
+ ├── TileMapLayer # Or TileMap
38
+ ├── Characters
39
+ ├── Props
40
+ └── Effects
41
+ ```
42
+
43
+ ### UI Scenes
44
+
45
+ ```
46
+ CanvasLayer or Control
47
+ ├── MarginContainer
48
+ │ ├── VBoxContainer
49
+ │ │ ├── Label
50
+ │ │ ├── Button
51
+ │ │ └── Button
52
+ ```
53
+
54
+ ## Parent Paths for MCP
55
+
56
+ Use `./` for paths relative to the scene root:
57
+
58
+ | Path | Meaning |
59
+ |------|---------|
60
+ | `./` | Scene root |
61
+ | `./World` | Child named "World" of root |
62
+ | `./World/Player` | Player under World |
63
+ | `./World/Props/Tree1` | Tree1 under Props under World |
64
+
65
+ **Never use** `/World` (absolute) or `World` (missing `./`). The engine expects `./` prefix.
66
+
67
+ ## When to Use Sub-Scenes
68
+
69
+ **Use sub-scenes (separate .tscn files) when:**
70
+ - The same setup appears in multiple places (player, enemy, pickup)
71
+ - The setup has many nodes and would clutter the main scene
72
+ - You want to edit a prefab in isolation
73
+
74
+ **Use inline nodes when:**
75
+ - The node is unique to this scene (main camera, level-specific light)
76
+ - It's a simple one-off (single MeshInstance3D)
77
+
78
+ ### Creating a Sub-Scene
79
+
80
+ 1. Build the hierarchy in the main scene
81
+ 2. Select the root of what you want to extract
82
+ 3. Save as scene: `summer_save_scene(path="res://scenes/player.tscn")` — but note: SaveScene saves the *current* scene. To save a branch, you typically save the open scene first, then in the editor you'd use "Save Branch as Scene." MCP doesn't have a direct "save branch" op—so for now, create the sub-scene as its own file via `summer_write_file` or build it in a separate scene and save.
83
+ 4. In the main scene, add it with `summer_instantiate_scene(parent="./World", scene="res://scenes/player.tscn", name="Player")`
84
+
85
+ **Practical approach:** Create reusable scenes (player.tscn, enemy.tscn) as separate scene files, then instantiate them into levels.
86
+
87
+ ## InstantiateScene vs AddNode
88
+
89
+ | Use | Tool | Example |
90
+ |-----|------|---------|
91
+ | Built-in mesh (Box, Sphere) | AddNode + SetProp | `summer_add_node` type=MeshInstance3D, then `summer_set_prop` mesh=BoxMesh |
92
+ | Existing .tscn prefab | InstantiateScene | `summer_instantiate_scene` scene=res://player.tscn |
93
+ | Imported .glb model | ImportFromUrl then InstantiateScene | Import first, then instantiate |
94
+
95
+ **Do not** use `summer_set_prop` with `mesh` for a .glb path. Use `summer_instantiate_scene` for .tscn and .glb files.
96
+
97
+ ## Save Conventions
98
+
99
+ - Always call `summer_save_scene` after changes you want to keep
100
+ - For new scenes: `summer_save_scene(path="res://scenes/level1.tscn")`
101
+ - For existing scenes: `summer_save_scene` (no path, uses current scene path)
102
+
103
+ ## Common Mistakes
104
+
105
+ 1. **Wrong parent path:** `./NonExistent` fails. Ensure the parent exists before adding children.
106
+ 2. **Unnamed scene:** Saving without a path fails if the scene was never saved. Use `path` for new scenes.
107
+ 3. **Duplicate names:** Godot auto-renames (Node, Node2, etc.). Use descriptive unique names.
108
+ 4. **Mixing 2D and 3D:** Don't put Node2D under Node3D or vice versa in the same hierarchy.
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: ui-basics
3
+ description: HUD, menus, health bars, and responsive UI layout. Use when building menus, HUDs, health bars, or Control-based UI in Summer Engine.
4
+ license: MIT
5
+ compatibility:
6
+ - Cursor
7
+ - Claude Code
8
+ - Windsurf
9
+ ---
10
+
11
+ # UI Basics for Summer Engine
12
+
13
+ Build menus and HUDs using Godot's Control nodes. Follow these patterns for layout, buttons, and responsive design.
14
+
15
+ ## Control Hierarchy
16
+
17
+ Use containers for layout, then add content nodes:
18
+
19
+ ```
20
+ Control or CanvasLayer (root)
21
+ └── MarginContainer
22
+ └── VBoxContainer (or HBoxContainer)
23
+ ├── Label
24
+ ├── Button
25
+ ├── Button
26
+ └── ProgressBar
27
+ ```
28
+
29
+ ## Common Containers
30
+
31
+ | Container | Use |
32
+ |-----------|-----|
33
+ | MarginContainer | Padding from edges |
34
+ | VBoxContainer | Stack vertically |
35
+ | HBoxContainer | Stack horizontally |
36
+ | CenterContainer | Center child |
37
+ | GridContainer | Grid layout |
38
+
39
+ ## Basic Menu
40
+
41
+ ```
42
+ summer_add_node(parent="./", type="Control", name="MainMenu")
43
+ summer_add_node(parent="./MainMenu", type="MarginContainer", name="Margin")
44
+ summer_set_prop(path="./MainMenu/Margin", key="anchors_preset", value="15") # Full rect
45
+ summer_set_prop(path="./MainMenu/Margin", key="theme_override_constants/margin_left", value="50")
46
+ summer_set_prop(path="./MainMenu/Margin", key="theme_override_constants/margin_right", value="50")
47
+ summer_set_prop(path="./MainMenu/Margin", key="theme_override_constants/margin_top", value="50")
48
+ summer_set_prop(path="./MainMenu/Margin", key="theme_override_constants/margin_bottom", value="50")
49
+
50
+ summer_add_node(parent="./MainMenu/Margin", type="VBoxContainer", name="VBox")
51
+ summer_add_node(parent="./MainMenu/Margin/VBox", type="Label", name="Title")
52
+ summer_set_prop(path="./MainMenu/Margin/VBox/Title", key="text", value="My Game")
53
+ summer_add_node(parent="./MainMenu/Margin/VBox", type="Button", name="StartButton")
54
+ summer_set_prop(path="./MainMenu/Margin/VBox/StartButton", key="text", value="Start Game")
55
+ summer_add_node(parent="./MainMenu/Margin/VBox", type="Button", name="QuitButton")
56
+ summer_set_prop(path="./MainMenu/Margin/VBox/QuitButton", key="text", value="Quit")
57
+ ```
58
+
59
+ For nested theme overrides, use `summer_set_resource_property` if the property is on a resource. For `theme_override_constants/margin_left`, it may be a direct node property—check Godot docs. Some constants are set via `add_theme_constant_override`. If `summer_set_prop` accepts `theme_override_constants/margin_left`, use it; otherwise the UI may need a script or theme resource.
60
+
61
+ ## HUD (Health Bar)
62
+
63
+ ```
64
+ summer_add_node(parent="./", type="CanvasLayer", name="HUD")
65
+ summer_add_node(parent="./HUD", type="MarginContainer", name="TopLeft")
66
+ summer_set_prop(path="./HUD/TopLeft", key="anchors_preset", value="1") # Top-left
67
+ summer_add_node(parent="./HUD/TopLeft", type="HBoxContainer", name="HealthContainer")
68
+ summer_add_node(parent="./HUD/TopLeft/HealthContainer", type="Label", name="HealthLabel")
69
+ summer_set_prop(path="./HUD/TopLeft/HealthContainer/HealthLabel", key="text", value="Health:")
70
+ summer_add_node(parent="./HUD/TopLeft/HealthContainer", type="ProgressBar", name="HealthBar")
71
+ summer_set_prop(path="./HUD/TopLeft/HealthContainer/HealthBar", key="max_value", value="100")
72
+ summer_set_prop(path="./HUD/TopLeft/HealthContainer/HealthBar", key="value", value="100")
73
+ summer_set_prop(path="./HUD/TopLeft/HealthContainer/HealthBar", key="size", value="Vector2(200, 20)")
74
+ ```
75
+
76
+ ProgressBar uses `value` and `max_value` for the fill. Update `value` from a script when health changes.
77
+
78
+ ## Anchors Preset
79
+
80
+ Common preset values (Godot 4):
81
+
82
+ | Preset | Value | Description |
83
+ |--------|-------|-------------|
84
+ | Top Left | 0 | Anchor to top-left |
85
+ | Top Right | 1 | Anchor to top-right |
86
+ | Bottom Left | 2 | Anchor to bottom-left |
87
+ | Bottom Right | 3 | Anchor to bottom-right |
88
+ | Full Rect | 15 | Stretch to fill parent |
89
+
90
+ Set via `summer_set_prop(path, key="anchors_preset", value="15")`.
91
+
92
+ ## Connecting Buttons
93
+
94
+ Wire the `pressed` signal to a handler:
95
+
96
+ ```
97
+ summer_connect_signal(emitter="./MainMenu/Margin/VBox/StartButton", signal="pressed", receiver="./MainMenu", method="_on_start_pressed")
98
+ ```
99
+
100
+ The receiver node must have a script with `func _on_start_pressed() -> void:`.
101
+
102
+ ## Property Reference
103
+
104
+ | Node | Property | Example |
105
+ |------|----------|---------|
106
+ | Label | text | `"Score: 0"` |
107
+ | Button | text | `"Start"` |
108
+ | ProgressBar | value | `75` |
109
+ | ProgressBar | max_value | `100` |
110
+ | Control | size | `"Vector2(200, 50)"` |
111
+ | Control | anchors_preset | `15` |
112
+ | Control | custom_minimum_size | `"Vector2(100, 30)"` |
113
+
114
+ ## Responsive Layout
115
+
116
+ For UI that scales with window size:
117
+ 1. Use `anchors_preset` to anchor to corners or edges
118
+ 2. Use `size_flags_horizontal` and `size_flags_vertical` on children (SIZE_EXPAND_FILL, etc.)
119
+ 3. MarginContainer with percentage-based margins (may need theme or script)
120
+
121
+ For simple cases, CenterContainer + fixed-size children works. For complex layouts, a Theme resource or script may be needed.
package/bin/summer.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- console.log("Summer Engine CLI is coming soon. Visit https://summerengine.com to get started.");
3
- process.exit(0);