@dcl-regenesislabs/opendcl 0.1.0-22234509684.commit-63dfd19

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 (54) hide show
  1. package/README.md +234 -0
  2. package/context/components-reference.md +113 -0
  3. package/context/open-source-3d-assets.md +705 -0
  4. package/context/sdk7-complete-reference.md +3684 -0
  5. package/context/sdk7-examples.md +1709 -0
  6. package/dist/index.d.ts +8 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +76 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/scene-context.d.ts +97 -0
  11. package/dist/scene-context.d.ts.map +1 -0
  12. package/dist/scene-context.js +203 -0
  13. package/dist/scene-context.js.map +1 -0
  14. package/dist/utils.d.ts +2 -0
  15. package/dist/utils.d.ts.map +1 -0
  16. package/dist/utils.js +4 -0
  17. package/dist/utils.js.map +1 -0
  18. package/extensions/dcl-context.ts +123 -0
  19. package/extensions/dcl-deploy.ts +89 -0
  20. package/extensions/dcl-header.ts +162 -0
  21. package/extensions/dcl-init.ts +62 -0
  22. package/extensions/dcl-preview.ts +144 -0
  23. package/extensions/dcl-setup-ollama.ts +312 -0
  24. package/extensions/dcl-setup.ts +96 -0
  25. package/extensions/dcl-status.ts +88 -0
  26. package/extensions/dcl-tasks.ts +102 -0
  27. package/extensions/dcl-update-check.ts +79 -0
  28. package/extensions/dcl-validate.ts +80 -0
  29. package/extensions/plan-mode/index.ts +340 -0
  30. package/extensions/plan-mode/utils.ts +168 -0
  31. package/extensions/process-registry.ts +25 -0
  32. package/extensions/scene-utils.ts +31 -0
  33. package/package.json +65 -0
  34. package/prompts/explain.md +16 -0
  35. package/prompts/review.md +19 -0
  36. package/prompts/system.md +126 -0
  37. package/skills/add-3d-models/SKILL.md +115 -0
  38. package/skills/add-interactivity/SKILL.md +176 -0
  39. package/skills/advanced-input/SKILL.md +238 -0
  40. package/skills/advanced-rendering/SKILL.md +235 -0
  41. package/skills/animations-tweens/SKILL.md +173 -0
  42. package/skills/audio-video/SKILL.md +167 -0
  43. package/skills/authoritative-server/SKILL.md +329 -0
  44. package/skills/build-ui/SKILL.md +231 -0
  45. package/skills/camera-control/SKILL.md +199 -0
  46. package/skills/create-scene/SKILL.md +67 -0
  47. package/skills/deploy-scene/SKILL.md +106 -0
  48. package/skills/deploy-worlds/SKILL.md +107 -0
  49. package/skills/lighting-environment/SKILL.md +216 -0
  50. package/skills/multiplayer-sync/SKILL.md +132 -0
  51. package/skills/nft-blockchain/SKILL.md +246 -0
  52. package/skills/optimize-scene/SKILL.md +160 -0
  53. package/skills/player-avatar/SKILL.md +239 -0
  54. package/skills/smart-items/SKILL.md +181 -0
@@ -0,0 +1,235 @@
1
+ ---
2
+ name: advanced-rendering
3
+ description: Advanced rendering features in Decentraland scenes. Use Billboard to make entities face the camera, TextShape for 3D text, advanced PBR material properties like metallic/roughness/transparency, GltfNodeModifiers for per-node visibility and material overrides in GLTF models, and VisibilityComponent to show/hide entities. Use when user wants billboards, 3D text, text labels, material effects, transparency, glow, or model node control.
4
+ ---
5
+
6
+ # Advanced Rendering in Decentraland
7
+
8
+ ## Billboard (Face the Camera)
9
+
10
+ Make entities always rotate to face the player's camera:
11
+
12
+ ```typescript
13
+ import { engine, Transform, Billboard, BillboardMode, MeshRenderer } from '@dcl/sdk/ecs'
14
+ import { Vector3 } from '@dcl/sdk/math'
15
+
16
+ const sign = engine.addEntity()
17
+ Transform.create(sign, { position: Vector3.create(8, 2, 8) })
18
+ MeshRenderer.setPlane(sign)
19
+
20
+ // Rotate only on Y axis (most common — stays upright)
21
+ Billboard.create(sign, {
22
+ billboardMode: BillboardMode.BM_Y
23
+ })
24
+ ```
25
+
26
+ ### Billboard Modes
27
+
28
+ ```typescript
29
+ BillboardMode.BM_Y // Rotate on Y axis only (stays upright) — most common
30
+ BillboardMode.BM_ALL // Rotate on all axes (fully faces camera)
31
+ BillboardMode.BM_X // Rotate on X axis only
32
+ BillboardMode.BM_Z // Rotate on Z axis only
33
+ BillboardMode.BM_NONE // No billboard rotation
34
+ ```
35
+
36
+ - Prefer `BM_Y` over `BM_ALL` for most use cases — it looks more natural and is cheaper to render.
37
+ - `BM_ALL` is useful for particles or effects that should always directly face the camera.
38
+
39
+ ## TextShape (3D Text)
40
+
41
+ Render text directly in 3D space:
42
+
43
+ ```typescript
44
+ import { engine, Transform, TextShape, TextAlignMode } from '@dcl/sdk/ecs'
45
+ import { Vector3, Color4 } from '@dcl/sdk/math'
46
+
47
+ const label = engine.addEntity()
48
+ Transform.create(label, { position: Vector3.create(8, 3, 8) })
49
+
50
+ TextShape.create(label, {
51
+ text: 'Hello World!',
52
+ fontSize: 24,
53
+ fontWeight: 'bold',
54
+ color: Color4.White(),
55
+ outlineColor: Color4.Black(),
56
+ outlineWidth: 0.1,
57
+ textAlign: TextAlignMode.TAM_MIDDLE_CENTER
58
+ })
59
+ ```
60
+
61
+ ### Text Alignment Options
62
+
63
+ ```typescript
64
+ TextAlignMode.TAM_TOP_LEFT
65
+ TextAlignMode.TAM_TOP_CENTER
66
+ TextAlignMode.TAM_TOP_RIGHT
67
+ TextAlignMode.TAM_MIDDLE_LEFT
68
+ TextAlignMode.TAM_MIDDLE_CENTER
69
+ TextAlignMode.TAM_MIDDLE_RIGHT
70
+ TextAlignMode.TAM_BOTTOM_LEFT
71
+ TextAlignMode.TAM_BOTTOM_CENTER
72
+ TextAlignMode.TAM_BOTTOM_RIGHT
73
+ ```
74
+
75
+ ### Floating Label (Billboard + TextShape)
76
+
77
+ Combine Billboard and TextShape to create labels that always face the player:
78
+
79
+ ```typescript
80
+ const floatingLabel = engine.addEntity()
81
+ Transform.create(floatingLabel, { position: Vector3.create(8, 4, 8) })
82
+
83
+ TextShape.create(floatingLabel, {
84
+ text: 'NPC Name',
85
+ fontSize: 16,
86
+ color: Color4.White(),
87
+ outlineColor: Color4.Black(),
88
+ outlineWidth: 0.08,
89
+ textAlign: TextAlignMode.TAM_BOTTOM_CENTER
90
+ })
91
+
92
+ Billboard.create(floatingLabel, {
93
+ billboardMode: BillboardMode.BM_Y
94
+ })
95
+ ```
96
+
97
+ ## Advanced PBR Materials
98
+
99
+ ### Metallic and Roughness
100
+
101
+ ```typescript
102
+ import { engine, Transform, MeshRenderer, Material, MaterialTransparencyMode } from '@dcl/sdk/ecs'
103
+ import { Color4, Color3 } from '@dcl/sdk/math'
104
+
105
+ // Shiny metal
106
+ Material.setPbrMaterial(entity, {
107
+ albedoColor: Color4.create(0.8, 0.8, 0.9, 1),
108
+ metallic: 1.0,
109
+ roughness: 0.1
110
+ })
111
+
112
+ // Rough stone
113
+ Material.setPbrMaterial(entity, {
114
+ albedoColor: Color4.create(0.5, 0.5, 0.5, 1),
115
+ metallic: 0.0,
116
+ roughness: 0.9
117
+ })
118
+ ```
119
+
120
+ ### Transparency
121
+
122
+ ```typescript
123
+ // Alpha blend — smooth transparency
124
+ Material.setPbrMaterial(entity, {
125
+ albedoColor: Color4.create(1, 0, 0, 0.5), // 50% transparent red
126
+ transparencyMode: MaterialTransparencyMode.MTM_ALPHA_BLEND
127
+ })
128
+
129
+ // Alpha test — cutout (binary visible/invisible based on threshold)
130
+ Material.setPbrMaterial(entity, {
131
+ texture: Material.Texture.Common({ src: 'assets/cutout.png' }),
132
+ transparencyMode: MaterialTransparencyMode.MTM_ALPHA_TEST,
133
+ alphaTest: 0.5
134
+ })
135
+ ```
136
+
137
+ ### Emissive (Glow Effects)
138
+
139
+ ```typescript
140
+ // Glowing material
141
+ Material.setPbrMaterial(entity, {
142
+ albedoColor: Color4.create(0, 0, 0, 1),
143
+ emissiveColor: Color4.create(0, 1, 0, 1), // Green glow
144
+ emissiveIntensity: 2.0
145
+ })
146
+
147
+ // Emissive with texture
148
+ Material.setPbrMaterial(entity, {
149
+ texture: Material.Texture.Common({ src: 'assets/diffuse.png' }),
150
+ emissiveTexture: Material.Texture.Common({ src: 'assets/emissive.png' }),
151
+ emissiveIntensity: 1.0,
152
+ emissiveColor: Color3.White()
153
+ })
154
+ ```
155
+
156
+ ### Texture Maps
157
+
158
+ ```typescript
159
+ Material.setPbrMaterial(entity, {
160
+ texture: Material.Texture.Common({ src: 'assets/diffuse.png' }),
161
+ bumpTexture: Material.Texture.Common({ src: 'assets/normal.png' }),
162
+ emissiveTexture: Material.Texture.Common({ src: 'assets/emissive.png' })
163
+ })
164
+ ```
165
+
166
+ ## GltfNodeModifiers
167
+
168
+ Override visibility or materials on specific nodes within a GLTF model:
169
+
170
+ ```typescript
171
+ import { engine, Transform, GltfContainer, GltfNodeModifiers, Material } from '@dcl/sdk/ecs'
172
+ import { Vector3, Color4 } from '@dcl/sdk/math'
173
+
174
+ const model = engine.addEntity()
175
+ GltfContainer.create(model, { src: 'models/myModel.glb' })
176
+ Transform.create(model, { position: Vector3.create(4, 0, 4) })
177
+
178
+ // Override material of the entire model (empty path = whole model)
179
+ GltfNodeModifiers.create(model, {
180
+ modifiers: [
181
+ {
182
+ path: '', // empty string = all nodes
183
+ materialOverride: Material.setPbrMaterial(model, {
184
+ albedoColor: Color4.Red()
185
+ })
186
+ }
187
+ ]
188
+ })
189
+ ```
190
+
191
+ Use node paths to target specific parts of a model for visibility or material changes.
192
+
193
+ ## VisibilityComponent
194
+
195
+ Show or hide entities without removing them:
196
+
197
+ ```typescript
198
+ import { engine, VisibilityComponent } from '@dcl/sdk/ecs'
199
+
200
+ // Hide an entity
201
+ VisibilityComponent.create(entity, { visible: false })
202
+
203
+ // Toggle visibility
204
+ const visibility = VisibilityComponent.getMutable(entity)
205
+ visibility.visible = !visibility.visible
206
+
207
+ // Useful for LOD (Level of Detail)
208
+ function lodSystem() {
209
+ const playerPos = Transform.get(engine.PlayerEntity).position
210
+
211
+ for (const [entity, transform] of engine.getEntitiesWith(Transform, MeshRenderer)) {
212
+ const distance = Vector3.distance(playerPos, transform.position)
213
+
214
+ if (distance > 30) {
215
+ VisibilityComponent.createOrReplace(entity, { visible: false })
216
+ } else {
217
+ VisibilityComponent.createOrReplace(entity, { visible: true })
218
+ }
219
+ }
220
+ }
221
+
222
+ engine.addSystem(lodSystem)
223
+ ```
224
+
225
+ ## Best Practices
226
+
227
+ - Use `BillboardMode.BM_Y` instead of `BM_ALL` — looks more natural and renders faster
228
+ - Keep `fontSize` readable (16-32 for in-world text)
229
+ - Add `outlineColor` and `outlineWidth` to TextShape for legibility against any background
230
+ - Use `emissiveColor` with a dark `albedoColor` for maximum glow visibility
231
+ - `MTM_ALPHA_TEST` is cheaper than `MTM_ALPHA_BLEND` — use cutout when smooth transparency isn't needed
232
+ - Combine Billboard + TextShape for floating name labels above NPCs or objects
233
+ - Use VisibilityComponent for LOD systems instead of removing/re-adding entities
234
+
235
+ For more component details, see `context/components-reference.md`.
@@ -0,0 +1,173 @@
1
+ ---
2
+ name: animations-tweens
3
+ description: Animate objects in Decentraland scenes using Animator (GLTF animations), Tween (move/rotate/scale over time), and TweenSequence (chain animations). Use when user wants to animate, move, rotate, spin, slide, or create motion effects.
4
+ ---
5
+
6
+ # Animations and Tweens in Decentraland
7
+
8
+ ## GLTF Animations (Animator)
9
+
10
+ Play animations embedded in .glb models:
11
+
12
+ ```typescript
13
+ import { engine, Transform, GltfContainer, Animator } from '@dcl/sdk/ecs'
14
+ import { Vector3 } from '@dcl/sdk/math'
15
+
16
+ const character = engine.addEntity()
17
+ Transform.create(character, { position: Vector3.create(8, 0, 8) })
18
+ GltfContainer.create(character, { src: 'models/character.glb' })
19
+
20
+ // Set up animation states
21
+ Animator.create(character, {
22
+ states: [
23
+ { clip: 'idle', playing: true, loop: true, speed: 1 },
24
+ { clip: 'walk', playing: false, loop: true, speed: 1 },
25
+ { clip: 'attack', playing: false, loop: false, speed: 1.5 }
26
+ ]
27
+ })
28
+
29
+ // Play a specific animation
30
+ Animator.playSingleAnimation(character, 'walk')
31
+
32
+ // Stop all animations
33
+ Animator.stopAllAnimations(character)
34
+ ```
35
+
36
+ ### Switching Animations
37
+ ```typescript
38
+ function playAnimation(entity: Entity, clipName: string) {
39
+ const animator = Animator.getMutable(entity)
40
+ // Stop all
41
+ for (const state of animator.states) {
42
+ state.playing = false
43
+ }
44
+ // Play the desired one
45
+ const state = animator.states.find(s => s.clip === clipName)
46
+ if (state) {
47
+ state.playing = true
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Tweens (Code-Based Animation)
53
+
54
+ Animate entity properties smoothly over time:
55
+
56
+ ### Move
57
+ ```typescript
58
+ import { engine, Transform, Tween, EasingFunction } from '@dcl/sdk/ecs'
59
+ import { Vector3 } from '@dcl/sdk/math'
60
+
61
+ const box = engine.addEntity()
62
+ Transform.create(box, { position: Vector3.create(2, 1, 8) })
63
+
64
+ Tween.create(box, {
65
+ mode: Tween.Mode.Move({
66
+ start: Vector3.create(2, 1, 8),
67
+ end: Vector3.create(14, 1, 8)
68
+ }),
69
+ duration: 2000, // milliseconds
70
+ easingFunction: EasingFunction.EF_EASEINOUTSINE
71
+ })
72
+ ```
73
+
74
+ ### Rotate
75
+ ```typescript
76
+ Tween.create(box, {
77
+ mode: Tween.Mode.Rotate({
78
+ start: Quaternion.fromEulerDegrees(0, 0, 0),
79
+ end: Quaternion.fromEulerDegrees(0, 360, 0)
80
+ }),
81
+ duration: 3000,
82
+ easingFunction: EasingFunction.EF_LINEAR
83
+ })
84
+ ```
85
+
86
+ ### Scale
87
+ ```typescript
88
+ Tween.create(box, {
89
+ mode: Tween.Mode.Scale({
90
+ start: Vector3.create(1, 1, 1),
91
+ end: Vector3.create(2, 2, 2)
92
+ }),
93
+ duration: 1000,
94
+ easingFunction: EasingFunction.EF_EASEOUTBOUNCE
95
+ })
96
+ ```
97
+
98
+ ## Tween Sequences (Chained Animations)
99
+
100
+ Chain multiple tweens to play one after another:
101
+
102
+ ```typescript
103
+ import { TweenSequence } from '@dcl/sdk/ecs'
104
+
105
+ // First tween
106
+ Tween.create(box, {
107
+ mode: Tween.Mode.Move({
108
+ start: Vector3.create(2, 1, 8),
109
+ end: Vector3.create(14, 1, 8)
110
+ }),
111
+ duration: 2000,
112
+ easingFunction: EasingFunction.EF_EASEINOUTSINE
113
+ })
114
+
115
+ // Chain sequence
116
+ TweenSequence.create(box, {
117
+ sequence: [
118
+ // Second: move back
119
+ {
120
+ mode: Tween.Mode.Move({
121
+ start: Vector3.create(14, 1, 8),
122
+ end: Vector3.create(2, 1, 8)
123
+ }),
124
+ duration: 2000,
125
+ easingFunction: EasingFunction.EF_EASEINOUTSINE
126
+ }
127
+ ],
128
+ loop: TweenLoop.TL_RESTART // Loop the entire sequence
129
+ })
130
+ ```
131
+
132
+ ## Easing Functions
133
+
134
+ Available easing functions from `EasingFunction`:
135
+ - `EF_LINEAR` — Constant speed
136
+ - `EF_EASEINQUAD` / `EF_EASEOUTQUAD` / `EF_EASEINOUTQUAD` — Quadratic
137
+ - `EF_EASEINSINE` / `EF_EASEOUTSINE` / `EF_EASEINOUTSINE` — Sinusoidal (smooth)
138
+ - `EF_EASEINEXPO` / `EF_EASEOUTEXPO` / `EF_EASEINOUTEXPO` — Exponential
139
+ - `EF_EASEINELASTIC` / `EF_EASEOUTELASTIC` / `EF_EASEINOUTELASTIC` — Elastic bounce
140
+ - `EF_EASEOUTBOUNCE` / `EF_EASEINBOUNCE` / `EF_EASEINOUTBOUNCE` — Bounce effect
141
+ - `EF_EASEINBACK` / `EF_EASEOUTBACK` / `EF_EASEINOUTBACK` — Overshoot
142
+
143
+ ## Custom Animation Systems
144
+
145
+ For complex animations, create a system:
146
+
147
+ ```typescript
148
+ // Continuous rotation system
149
+ function spinSystem(dt: number) {
150
+ for (const [entity] of engine.getEntitiesWith(Transform, Spinner)) {
151
+ const transform = Transform.getMutable(entity)
152
+ const spinner = Spinner.get(entity)
153
+ // Rotate around Y axis
154
+ const currentRotation = Quaternion.toEulerAngles(transform.rotation)
155
+ transform.rotation = Quaternion.fromEulerDegrees(
156
+ currentRotation.x,
157
+ currentRotation.y + spinner.speed * dt,
158
+ currentRotation.z
159
+ )
160
+ }
161
+ }
162
+
163
+ engine.addSystem(spinSystem)
164
+ ```
165
+
166
+ ## Best Practices
167
+
168
+ - Use Tweens for simple A-to-B animations (doors, platforms, UI elements)
169
+ - Use Animator for character/model animations baked into GLTF files
170
+ - Use Systems for continuous or physics-based animations
171
+ - Tween durations are in **milliseconds** (1000 = 1 second)
172
+ - Combine move + rotate tweens by applying them to parent/child entities
173
+ - For looping: use `TweenSequence` with `loop: TweenLoop.TL_RESTART`
@@ -0,0 +1,167 @@
1
+ ---
2
+ name: audio-video
3
+ description: Add audio sources, sound effects, music, audio streaming, and video players to Decentraland scenes. Use when user wants sound, music, audio, video screens, speakers, or media playback.
4
+ ---
5
+
6
+ # Audio and Video in Decentraland
7
+
8
+ ## Audio Source (Sound Effects & Music)
9
+
10
+ Play audio clips from files:
11
+
12
+ ```typescript
13
+ import { engine, Transform, AudioSource } from '@dcl/sdk/ecs'
14
+ import { Vector3 } from '@dcl/sdk/math'
15
+
16
+ const speaker = engine.addEntity()
17
+ Transform.create(speaker, { position: Vector3.create(8, 1, 8) })
18
+
19
+ AudioSource.create(speaker, {
20
+ audioClipUrl: 'sounds/music.mp3',
21
+ playing: true,
22
+ loop: true,
23
+ volume: 0.5, // 0 to 1
24
+ pitch: 1.0 // Playback speed (0.5 = half speed, 2.0 = double)
25
+ })
26
+ ```
27
+
28
+ ### Supported Formats
29
+ - `.mp3` (recommended)
30
+ - `.ogg`
31
+ - `.wav`
32
+
33
+ ### File Organization
34
+ ```
35
+ project/
36
+ ├── sounds/
37
+ │ ├── click.mp3
38
+ │ ├── background-music.mp3
39
+ │ └── explosion.ogg
40
+ ├── src/
41
+ │ └── index.ts
42
+ └── scene.json
43
+ ```
44
+
45
+ ### Play/Stop/Toggle
46
+ ```typescript
47
+ // Play
48
+ AudioSource.getMutable(speaker).playing = true
49
+
50
+ // Stop
51
+ AudioSource.getMutable(speaker).playing = false
52
+
53
+ // Toggle
54
+ const audio = AudioSource.getMutable(speaker)
55
+ audio.playing = !audio.playing
56
+ ```
57
+
58
+ ### Play on Click
59
+ ```typescript
60
+ import { pointerEventsSystem, InputAction } from '@dcl/sdk/ecs'
61
+
62
+ const button = engine.addEntity()
63
+ // ... set up transform and mesh ...
64
+
65
+ const audioEntity = engine.addEntity()
66
+ Transform.create(audioEntity, { position: Vector3.create(8, 1, 8) })
67
+ AudioSource.create(audioEntity, {
68
+ audioClipUrl: 'sounds/click.mp3',
69
+ playing: false,
70
+ loop: false,
71
+ volume: 0.8
72
+ })
73
+
74
+ pointerEventsSystem.onPointerDown(
75
+ { entity: button, opts: { button: InputAction.IA_POINTER, hoverText: 'Play sound' } },
76
+ () => {
77
+ // Reset and play
78
+ const audio = AudioSource.getMutable(audioEntity)
79
+ audio.playing = false
80
+ audio.playing = true
81
+ }
82
+ )
83
+ ```
84
+
85
+ ## Audio Streaming
86
+
87
+ Stream audio from a URL (radio, live streams):
88
+
89
+ ```typescript
90
+ import { engine, Transform, AudioStream } from '@dcl/sdk/ecs'
91
+ import { Vector3 } from '@dcl/sdk/math'
92
+
93
+ const radio = engine.addEntity()
94
+ Transform.create(radio, { position: Vector3.create(8, 1, 8) })
95
+
96
+ AudioStream.create(radio, {
97
+ url: 'https://example.com/stream.mp3',
98
+ playing: true,
99
+ volume: 0.3
100
+ })
101
+ ```
102
+
103
+ ## Video Player
104
+
105
+ Play video on a surface:
106
+
107
+ ```typescript
108
+ import { engine, Transform, VideoPlayer, Material, MeshRenderer } from '@dcl/sdk/ecs'
109
+ import { Vector3 } from '@dcl/sdk/math'
110
+
111
+ // Create a screen
112
+ const screen = engine.addEntity()
113
+ Transform.create(screen, {
114
+ position: Vector3.create(8, 3, 15.9),
115
+ scale: Vector3.create(8, 4.5, 1) // 16:9 ratio
116
+ })
117
+ MeshRenderer.setPlane(screen)
118
+
119
+ // Add video player
120
+ VideoPlayer.create(screen, {
121
+ src: 'https://example.com/video.mp4',
122
+ playing: true,
123
+ loop: true,
124
+ volume: 0.5,
125
+ playbackRate: 1.0
126
+ })
127
+
128
+ // Set material to show the video texture
129
+ Material.setPbrMaterial(screen, {
130
+ texture: Material.Texture.Video({ videoPlayerEntity: screen }),
131
+ roughness: 1,
132
+ emissiveColor: { r: 1, g: 1, b: 1 },
133
+ emissiveIntensity: 1,
134
+ emissiveTexture: Material.Texture.Video({ videoPlayerEntity: screen })
135
+ })
136
+ ```
137
+
138
+ ### Video Controls
139
+ ```typescript
140
+ // Play
141
+ VideoPlayer.getMutable(screen).playing = true
142
+
143
+ // Pause
144
+ VideoPlayer.getMutable(screen).playing = false
145
+
146
+ // Change volume
147
+ VideoPlayer.getMutable(screen).volume = 0.8
148
+
149
+ // Change source
150
+ VideoPlayer.getMutable(screen).src = 'https://example.com/other.mp4'
151
+ ```
152
+
153
+ ## Spatial Audio
154
+
155
+ Audio in Decentraland is **spatial by default** — it gets louder as the player approaches the audio source entity and quieter as they move away. The position is determined by the entity's `Transform`.
156
+
157
+ To make audio non-spatial (same volume everywhere), there's no built-in flag — keep the volume low and place the audio at the scene center.
158
+
159
+ ## Important Notes
160
+
161
+ - Audio files must be in the project's directory (relative paths from project root)
162
+ - Video requires HTTPS URLs — HTTP won't work
163
+ - Players must interact with the scene (click) before audio can play (browser autoplay policy)
164
+ - Keep audio files small — large files increase scene load time
165
+ - Use `.mp3` for music and `.ogg` for sound effects (smaller file sizes)
166
+ - Video playback requires the `ALLOW_MEDIA_HOSTNAMES` permission in scene.json for external URLs
167
+ - For live video streaming, use HLS (.m3u8) URLs when possible