oriverse-engine 0.1.8 → 0.1.9
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.
- package/LICENSE.md +30 -30
- package/README.md +7 -7
- package/dist/CODEX_PROMPT.md +9 -9
- package/dist/GAME_AUTHORING.md +24 -15
- package/dist/examples/coin_collector.weave +73 -70
- package/dist/examples/dodge_blocks.weave +73 -70
- package/dist/examples/target_range.weave +85 -82
- package/dist/ktx_bridge.js +130 -121
- package/dist/oriverse_wgpu.d.ts +38 -36
- package/dist/oriverse_wgpu.js +173 -118
- package/dist/oriverse_wgpu_bg.wasm +0 -0
- package/dist/oriverse_wgpu_bg.wasm.d.ts +38 -36
- package/dist/shader_prewarm_manifest.json +1 -1
- package/dist/snippets/oriverse_market_client-0cd3013288f3c49c/inline0.js +2 -34
- package/dist/snippets/oriverse_market_client-0cd3013288f3c49c/inline2.js +36 -0
- package/dist/snippets/oriverse_networking_shared-e43478064e11e46c/inline1.js +2 -1
- package/dist/snippets/oriverse_wgpu-255445ce6d9a0851/inline1.js +26 -58
- package/dist/snippets/oriverse_wgpu-255445ce6d9a0851/inline2.js +58 -26
- package/dist/starter/AGENTS.md +2 -2
- package/dist/starter/CLAUDE.md +2 -2
- package/dist/starter/game.html +6 -6
- package/dist/templates/game_cdn.html +6 -6
- package/dist/weave_documentation.txt +510 -190
- package/package.json +6 -1
package/LICENSE.md
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
# Oriverse Artifact Bundle License
|
|
2
|
-
|
|
3
|
-
> PLACEHOLDER — review with legal counsel before the first `npm publish`.
|
|
4
|
-
|
|
5
|
-
Copyright (c) 2026 Oriverse. All rights reserved.
|
|
6
|
-
|
|
7
|
-
This package contains a compiled, proprietary build of the Oriverse engine
|
|
8
|
-
("the Bundle"). No source code is included or licensed.
|
|
9
|
-
|
|
10
|
-
Permission is hereby granted, free of charge and royalty-free, to any person
|
|
11
|
-
obtaining a copy of the Bundle to:
|
|
12
|
-
|
|
13
|
-
1. Use the Bundle to run and serve games and applications, commercial or
|
|
14
|
-
non-commercial.
|
|
15
|
-
2. Redistribute the Bundle **unmodified** (including via CDNs such as unpkg,
|
|
16
|
-
bundlers, or by copying the `dist/` files alongside your game), provided this
|
|
17
|
-
license file accompanies any standalone redistribution of the Bundle.
|
|
18
|
-
|
|
19
|
-
The following are NOT permitted:
|
|
20
|
-
|
|
21
|
-
- Modifying, decompiling, disassembling, or reverse-engineering the Bundle,
|
|
22
|
-
except to the extent such restriction is prohibited by applicable law.
|
|
23
|
-
- Redistributing modified versions of the Bundle.
|
|
24
|
-
- Representing the Bundle as your own work or removing copyright notices.
|
|
25
|
-
|
|
26
|
-
THE BUNDLE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
27
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
28
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
29
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
30
|
-
LIABILITY ARISING FROM THE USE OF THE BUNDLE.
|
|
1
|
+
# Oriverse Artifact Bundle License
|
|
2
|
+
|
|
3
|
+
> PLACEHOLDER — review with legal counsel before the first `npm publish`.
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026 Oriverse. All rights reserved.
|
|
6
|
+
|
|
7
|
+
This package contains a compiled, proprietary build of the Oriverse engine
|
|
8
|
+
("the Bundle"). No source code is included or licensed.
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge and royalty-free, to any person
|
|
11
|
+
obtaining a copy of the Bundle to:
|
|
12
|
+
|
|
13
|
+
1. Use the Bundle to run and serve games and applications, commercial or
|
|
14
|
+
non-commercial.
|
|
15
|
+
2. Redistribute the Bundle **unmodified** (including via CDNs such as unpkg,
|
|
16
|
+
bundlers, or by copying the `dist/` files alongside your game), provided this
|
|
17
|
+
license file accompanies any standalone redistribution of the Bundle.
|
|
18
|
+
|
|
19
|
+
The following are NOT permitted:
|
|
20
|
+
|
|
21
|
+
- Modifying, decompiling, disassembling, or reverse-engineering the Bundle,
|
|
22
|
+
except to the extent such restriction is prohibited by applicable law.
|
|
23
|
+
- Redistributing modified versions of the Bundle.
|
|
24
|
+
- Representing the Bundle as your own work or removing copyright notices.
|
|
25
|
+
|
|
26
|
+
THE BUNDLE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
27
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
28
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
29
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
30
|
+
LIABILITY ARISING FROM THE USE OF THE BUNDLE.
|
package/README.md
CHANGED
|
@@ -29,11 +29,11 @@ object Box { model = "cube" position = (0, 300, 100) size = (100, 100, 100) colo
|
|
|
29
29
|
</script>
|
|
30
30
|
|
|
31
31
|
<!-- Pinned engine version: bump @0.1.2 together on new releases -->
|
|
32
|
-
<script src="https://unpkg.com/oriverse-engine@0.1.
|
|
33
|
-
<script src="https://unpkg.com/oriverse-engine@0.1.
|
|
32
|
+
<script src="https://unpkg.com/oriverse-engine@0.1.9/dist/ktx_lib.js"></script>
|
|
33
|
+
<script src="https://unpkg.com/oriverse-engine@0.1.9/dist/ktx_bridge.js"></script>
|
|
34
34
|
<script type="module">
|
|
35
|
-
import initOriverse from "https://unpkg.com/oriverse-engine@0.1.
|
|
36
|
-
await initOriverse({ module_or_path: "https://unpkg.com/oriverse-engine@0.1.
|
|
35
|
+
import initOriverse from "https://unpkg.com/oriverse-engine@0.1.9/dist/oriverse_wgpu.js";
|
|
36
|
+
await initOriverse({ module_or_path: "https://unpkg.com/oriverse-engine@0.1.9/dist/oriverse_wgpu_bg.wasm" });
|
|
37
37
|
</script>
|
|
38
38
|
</body>
|
|
39
39
|
</html>
|
|
@@ -49,8 +49,8 @@ The engine auto-boots from the `#oriverse-weave` tag. To boot programmatically
|
|
|
49
49
|
instead, omit the tag and call the typed export once after init:
|
|
50
50
|
|
|
51
51
|
```js
|
|
52
|
-
import initOriverse, { bootOriverseArtifact } from "https://unpkg.com/oriverse-engine@0.1.
|
|
53
|
-
await initOriverse({ module_or_path: "https://unpkg.com/oriverse-engine@0.1.
|
|
52
|
+
import initOriverse, { bootOriverseArtifact } from "https://unpkg.com/oriverse-engine@0.1.9/dist/oriverse_wgpu.js";
|
|
53
|
+
await initOriverse({ module_or_path: "https://unpkg.com/oriverse-engine@0.1.9/dist/oriverse_wgpu_bg.wasm" });
|
|
54
54
|
await bootOriverseArtifact(weaveSource);
|
|
55
55
|
```
|
|
56
56
|
|
|
@@ -69,7 +69,7 @@ point an agent at it, and say "make a game".
|
|
|
69
69
|
- Content must be fully procedural: primitive models, `#mesh`, `#texture`,
|
|
70
70
|
`#particles`. Market/network assets are unavailable and hard-error.
|
|
71
71
|
- Weave language + API reference: `dist/weave_documentation.txt`
|
|
72
|
-
(also at `https://unpkg.com/oriverse-engine@0.1.
|
|
72
|
+
(also at `https://unpkg.com/oriverse-engine@0.1.9/dist/weave_documentation.txt`).
|
|
73
73
|
- Package/runtime onboarding: `dist/AGENT_ONBOARDING.md`.
|
|
74
74
|
- Copy-paste prompt for AI coding agents: `dist/CODEX_PROMPT.md`.
|
|
75
75
|
|
package/dist/CODEX_PROMPT.md
CHANGED
|
@@ -53,15 +53,15 @@ object BlueCube {
|
|
|
53
53
|
</script>
|
|
54
54
|
<!-- ==== END OF EDITABLE BLOCK ==== -->
|
|
55
55
|
|
|
56
|
-
<script src="https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
57
|
-
<script src="https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
56
|
+
<script src="https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/ktx_lib.js"></script>
|
|
57
|
+
<script src="https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/ktx_bridge.js"></script>
|
|
58
58
|
<script type="module">
|
|
59
|
-
import initOriverse from "https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
59
|
+
import initOriverse from "https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/oriverse_wgpu.js";
|
|
60
60
|
const setBoot = (t) => { const b = document.getElementById('oriverse-status-banner'); if (b) b.textContent = t; };
|
|
61
61
|
(async () => {
|
|
62
62
|
try {
|
|
63
63
|
setBoot('starting engine…');
|
|
64
|
-
await initOriverse({ module_or_path: "https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
64
|
+
await initOriverse({ module_or_path: "https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/oriverse_wgpu_bg.wasm" });
|
|
65
65
|
} catch (e) {
|
|
66
66
|
setBoot('WASM init failed:\n' + ((e && e.stack) ? e.stack : String(e)));
|
|
67
67
|
console.error('[wasm_boot] initOriverse failed:', e);
|
|
@@ -90,15 +90,15 @@ Rules — the engine hard-errors if you break the first two:
|
|
|
90
90
|
- `color = (r, g, b)` uses 0-1 floats (or `#RRGGBB`). 0-255 values clamp to WHITE.
|
|
91
91
|
- The game boots straight into play mode. WASD + mouse + Space jump already work via a
|
|
92
92
|
default player controller; define `#class player ... #end` only for custom movement.
|
|
93
|
-
- Give the world a ground object, a HUD (`screenCanvas`), a win or lose condition, and
|
|
94
|
-
`
|
|
93
|
+
- Give the world a ground object, a HUD (`screenCanvas`), a win or lose condition, and a
|
|
94
|
+
Restart `button` whose `ClickButton` handler calls `RestartGame()` to replay.
|
|
95
95
|
|
|
96
96
|
Authoritative references, served next to the engine (fetch if you can — the authoring
|
|
97
97
|
guide contains three complete tested example games to pattern-match from):
|
|
98
98
|
|
|
99
|
-
- https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
100
|
-
- https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
101
|
-
- https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.
|
|
99
|
+
- https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/GAME_AUTHORING.md <- game patterns + 3 full example games
|
|
100
|
+
- https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/weave_documentation.txt <- full language + API reference
|
|
101
|
+
- https://cdn.jsdelivr.net/npm/oriverse-engine@0.1.9/dist/examples/coin_collector.weave (also dodge_blocks / target_range)
|
|
102
102
|
|
|
103
103
|
## Step 3: test
|
|
104
104
|
|
package/dist/GAME_AUTHORING.md
CHANGED
|
@@ -72,8 +72,8 @@ event OnSpawned { // main entry; runs once when the object spawns
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
event
|
|
76
|
-
RestartGame()
|
|
75
|
+
event ClickButton { // any player clicked any UI button
|
|
76
|
+
if Event.ClickedButton == ResolveObjectByNameOnce("RestartBtn") { RestartGame() }
|
|
77
77
|
}
|
|
78
78
|
#end
|
|
79
79
|
```
|
|
@@ -206,7 +206,7 @@ The manager pattern (used by all three examples):
|
|
|
206
206
|
- Keep `var GameOver = false` (or `RoundOver`) on the tagged manager.
|
|
207
207
|
- Losing conditions write it cross-object: `NearestObjectWithTag(Tag.Manager).GameOver = true`.
|
|
208
208
|
- The manager's `forever` loop shows the banner and freezes scoring when set.
|
|
209
|
-
- `
|
|
209
|
+
- Replay: a Restart `button` shown at game over; its `ClickButton` handler calls `RestartGame()`.
|
|
210
210
|
|
|
211
211
|
## 9. Procedural textures and meshes (quickstarts)
|
|
212
212
|
|
|
@@ -269,7 +269,7 @@ Collect 10 spinning coins; HUD counter; win banner + R to restart. Demonstrates:
|
|
|
269
269
|
objects + runtime spawning, tags, proximity pickup, default player controller.
|
|
270
270
|
|
|
271
271
|
```text
|
|
272
|
-
// Coin Collector — walk into the 10 spinning coins to collect them all.
|
|
272
|
+
// Coin Collector — walk into the 10 spinning coins to collect them all. Click Restart to replay.
|
|
273
273
|
// Demonstrates: saved objects + runtime spawning, tags, proximity pickup, HUD score text,
|
|
274
274
|
// win + restart flow. Movement uses the engine's default player controller (no #class player).
|
|
275
275
|
|
|
@@ -299,6 +299,7 @@ event OnSpawned {
|
|
|
299
299
|
}
|
|
300
300
|
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
301
301
|
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
302
|
+
var restartBtn = ResolveObjectByNameOnce("RestartBtn")
|
|
302
303
|
forever {
|
|
303
304
|
// Spawned coins register their tag on the next tick, so wait until the census
|
|
304
305
|
// has seen at least one coin before treating "0 left" as a win.
|
|
@@ -306,7 +307,8 @@ event OnSpawned {
|
|
|
306
307
|
var collected = TotalCoins - left
|
|
307
308
|
scoreLabel.SetText("Coins: " + collected + " / " + TotalCoins)
|
|
308
309
|
if left == 0 and collected == TotalCoins and SeenCoins {
|
|
309
|
-
midLabel.SetText("YOU WIN!
|
|
310
|
+
midLabel.SetText("YOU WIN!")
|
|
311
|
+
restartBtn.SetVisible(true)
|
|
310
312
|
} else {
|
|
311
313
|
midLabel.SetText("")
|
|
312
314
|
}
|
|
@@ -315,8 +317,8 @@ event OnSpawned {
|
|
|
315
317
|
}
|
|
316
318
|
}
|
|
317
319
|
}
|
|
318
|
-
event
|
|
319
|
-
RestartGame()
|
|
320
|
+
event ClickButton {
|
|
321
|
+
if Event.ClickedButton == ResolveObjectByNameOnce("RestartBtn") { RestartGame() }
|
|
320
322
|
}
|
|
321
323
|
#end
|
|
322
324
|
|
|
@@ -338,6 +340,7 @@ display manager : GameManager { visible = false }
|
|
|
338
340
|
screenCanvas HUD {
|
|
339
341
|
textLabel ScoreText { offset = (20, 20) text = "Coins: 0 / 10" color = (1, 1, 0.85) }
|
|
340
342
|
textLabel MidText { align = (center, center) text = "" color = (1, 1, 0.3) }
|
|
343
|
+
button RestartBtn { anchor = (center, center) offset = (0, 70) size = (220, 52) text = "Restart" corner_radius = 8 color = #B98A20 visible = false }
|
|
341
344
|
}
|
|
342
345
|
```
|
|
343
346
|
|
|
@@ -348,7 +351,7 @@ Demonstrates: timed spawner, dynamic physics objects, cross-object state writes,
|
|
|
348
351
|
lose + restart flow.
|
|
349
352
|
|
|
350
353
|
```text
|
|
351
|
-
// Dodge the Falling Blocks — red cubes rain down; touching one ends the run.
|
|
354
|
+
// Dodge the Falling Blocks — red cubes rain down; touching one ends the run. Click Restart to retry.
|
|
352
355
|
// Demonstrates: a hidden manager object, timed spawning with Timer, dynamic physics objects,
|
|
353
356
|
// cross-object variable writes (block -> manager), survival-seconds score, lose + restart flow.
|
|
354
357
|
// Movement uses the engine's default player controller (no #class player).
|
|
@@ -380,9 +383,11 @@ event OnSpawned {
|
|
|
380
383
|
var dropTmr = Timer()
|
|
381
384
|
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
382
385
|
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
386
|
+
var restartBtn = ResolveObjectByNameOnce("RestartBtn")
|
|
383
387
|
forever {
|
|
384
388
|
if GameOver {
|
|
385
|
-
midLabel.SetText("GAME OVER — survived " + Score + " s
|
|
389
|
+
midLabel.SetText("GAME OVER — survived " + Score + " s")
|
|
390
|
+
restartBtn.SetVisible(true)
|
|
386
391
|
continue
|
|
387
392
|
}
|
|
388
393
|
if secondTmr.IsDone() {
|
|
@@ -397,8 +402,8 @@ event OnSpawned {
|
|
|
397
402
|
}
|
|
398
403
|
}
|
|
399
404
|
}
|
|
400
|
-
event
|
|
401
|
-
RestartGame()
|
|
405
|
+
event ClickButton {
|
|
406
|
+
if Event.ClickedButton == ResolveObjectByNameOnce("RestartBtn") { RestartGame() }
|
|
402
407
|
}
|
|
403
408
|
#end
|
|
404
409
|
|
|
@@ -417,6 +422,7 @@ display manager : GameManager { visible = false }
|
|
|
417
422
|
screenCanvas HUD {
|
|
418
423
|
textLabel ScoreText { offset = (20, 20) text = "Survived: 0 s" color = (1, 1, 1) }
|
|
419
424
|
textLabel MidText { align = (center, center) text = "" color = (1, 0.45, 0.35) }
|
|
425
|
+
button RestartBtn { anchor = (center, center) offset = (0, 70) size = (220, 52) text = "Restart" corner_radius = 8 color = #B03A2E visible = false }
|
|
420
426
|
}
|
|
421
427
|
```
|
|
422
428
|
|
|
@@ -427,7 +433,7 @@ Click the floating spheres through the crosshair; 30-second round. Demonstrates:
|
|
|
427
433
|
called cross-object, TeleportTo respawn, countdown timer.
|
|
428
434
|
|
|
429
435
|
```text
|
|
430
|
-
// Target Range — aim at the floating spheres and left-click to score. 30-second round,
|
|
436
|
+
// Target Range — aim at the floating spheres and left-click to score. 30-second round, click Restart to replay.
|
|
431
437
|
// Demonstrates: a custom #class player (movement + jump + click-to-shoot with the crosshair ray),
|
|
432
438
|
// user-defined funcs called cross-object, TeleportTo respawn, countdown round timer, HUD score.
|
|
433
439
|
|
|
@@ -474,6 +480,7 @@ event OnSpawned {
|
|
|
474
480
|
secondTmr.StartCountDown(1)
|
|
475
481
|
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
476
482
|
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
483
|
+
var restartBtn = ResolveObjectByNameOnce("RestartBtn")
|
|
477
484
|
forever {
|
|
478
485
|
scoreLabel.SetText("Hits: " + Hits + " Time: " + TimeLeft)
|
|
479
486
|
if RoundOver {
|
|
@@ -484,13 +491,14 @@ event OnSpawned {
|
|
|
484
491
|
TimeLeft -= 1
|
|
485
492
|
if TimeLeft <= 0 {
|
|
486
493
|
RoundOver = true
|
|
487
|
-
midLabel.SetText("TIME! Final score: " + Hits
|
|
494
|
+
midLabel.SetText("TIME! Final score: " + Hits)
|
|
495
|
+
restartBtn.SetVisible(true)
|
|
488
496
|
}
|
|
489
497
|
}
|
|
490
498
|
}
|
|
491
499
|
}
|
|
492
|
-
event
|
|
493
|
-
RestartGame()
|
|
500
|
+
event ClickButton {
|
|
501
|
+
if Event.ClickedButton == ResolveObjectByNameOnce("RestartBtn") { RestartGame() }
|
|
494
502
|
}
|
|
495
503
|
#end
|
|
496
504
|
|
|
@@ -508,5 +516,6 @@ display manager : GameManager { visible = false }
|
|
|
508
516
|
screenCanvas HUD {
|
|
509
517
|
textLabel ScoreText { offset = (20, 20) text = "Hits: 0 Time: 30" color = (1, 1, 0.85) }
|
|
510
518
|
textLabel MidText { align = (center, center) text = "" color = (0.4, 1, 0.5) }
|
|
519
|
+
button RestartBtn { anchor = (center, center) offset = (0, 70) size = (220, 52) text = "Restart" corner_radius = 8 color = #2E8B57 visible = false }
|
|
511
520
|
}
|
|
512
521
|
```
|
|
@@ -1,70 +1,73 @@
|
|
|
1
|
-
// Coin Collector — walk into the 10 spinning coins to collect them all.
|
|
2
|
-
// Demonstrates: saved objects + runtime spawning, tags, proximity pickup, HUD score text,
|
|
3
|
-
// win + restart flow. Movement uses the engine's default player controller (no #class player).
|
|
4
|
-
|
|
5
|
-
#class Coin
|
|
6
|
-
event OnPreSpawn {
|
|
7
|
-
AddTag(Tag.Coin)
|
|
8
|
-
}
|
|
9
|
-
event OnSpawned {
|
|
10
|
-
forever {
|
|
11
|
-
RotateLeftInstantly(4)
|
|
12
|
-
var p = NearestPlayer()
|
|
13
|
-
if p.Exists() and SurfaceGapTo(p) < 70 {
|
|
14
|
-
p.SpawnFloatingText("+1", Vector(1, 0.9, 0.2))
|
|
15
|
-
Destroy()
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
#end
|
|
20
|
-
|
|
21
|
-
#class GameManager
|
|
22
|
-
var TotalCoins = 10
|
|
23
|
-
var SeenCoins = false
|
|
24
|
-
event OnSpawned {
|
|
25
|
-
for i in 0..TotalCoins {
|
|
26
|
-
var pos = Position(RandomNumber(-1400, 1400), RandomNumber(-1400, 1400), 80)
|
|
27
|
-
SpawnObject(SavedObject.coin, pos)
|
|
28
|
-
}
|
|
29
|
-
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
30
|
-
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
object
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
1
|
+
// Coin Collector — walk into the 10 spinning coins to collect them all. Click Restart to replay.
|
|
2
|
+
// Demonstrates: saved objects + runtime spawning, tags, proximity pickup, HUD score text,
|
|
3
|
+
// win + restart flow. Movement uses the engine's default player controller (no #class player).
|
|
4
|
+
|
|
5
|
+
#class Coin
|
|
6
|
+
event OnPreSpawn {
|
|
7
|
+
AddTag(Tag.Coin)
|
|
8
|
+
}
|
|
9
|
+
event OnSpawned {
|
|
10
|
+
forever {
|
|
11
|
+
RotateLeftInstantly(4)
|
|
12
|
+
var p = NearestPlayer()
|
|
13
|
+
if p.Exists() and SurfaceGapTo(p) < 70 {
|
|
14
|
+
p.SpawnFloatingText("+1", Vector(1, 0.9, 0.2))
|
|
15
|
+
Destroy()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
#end
|
|
20
|
+
|
|
21
|
+
#class GameManager
|
|
22
|
+
var TotalCoins = 10
|
|
23
|
+
var SeenCoins = false
|
|
24
|
+
event OnSpawned {
|
|
25
|
+
for i in 0..TotalCoins {
|
|
26
|
+
var pos = Position(RandomNumber(-1400, 1400), RandomNumber(-1400, 1400), 80)
|
|
27
|
+
SpawnObject(SavedObject.coin, pos)
|
|
28
|
+
}
|
|
29
|
+
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
30
|
+
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
31
|
+
var restartBtn = ResolveObjectByNameOnce("RestartBtn")
|
|
32
|
+
forever {
|
|
33
|
+
// Spawned coins register their tag on the next tick, so wait until the census
|
|
34
|
+
// has seen at least one coin before treating "0 left" as a win.
|
|
35
|
+
var left = GetAllObjectsWithTag(Tag.Coin).Count()
|
|
36
|
+
var collected = TotalCoins - left
|
|
37
|
+
scoreLabel.SetText("Coins: " + collected + " / " + TotalCoins)
|
|
38
|
+
if left == 0 and collected == TotalCoins and SeenCoins {
|
|
39
|
+
midLabel.SetText("YOU WIN!")
|
|
40
|
+
restartBtn.SetVisible(true)
|
|
41
|
+
} else {
|
|
42
|
+
midLabel.SetText("")
|
|
43
|
+
}
|
|
44
|
+
if left > 0 {
|
|
45
|
+
SeenCoins = true
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
event ClickButton {
|
|
50
|
+
if Event.ClickedButton == ResolveObjectByNameOnce("RestartBtn") { RestartGame() }
|
|
51
|
+
}
|
|
52
|
+
#end
|
|
53
|
+
|
|
54
|
+
saved coin {
|
|
55
|
+
display coin : Coin { model = "cylinder" size = (60, 60, 12) rotation = (90, 0, 0) color = (1, 0.85, 0.2) }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
object Ground {
|
|
59
|
+
model = "cube"
|
|
60
|
+
position = (0, 0, -50)
|
|
61
|
+
size = (4000, 4000, 100)
|
|
62
|
+
color = (0.32, 0.5, 0.34)
|
|
63
|
+
}
|
|
64
|
+
object PillarA { position = (400, 400, 150) size = (100, 100, 300) color = (0.62, 0.58, 0.52) }
|
|
65
|
+
object PillarB { position = (-600, 300, 150) size = (100, 100, 300) color = (0.62, 0.58, 0.52) }
|
|
66
|
+
object PillarC { position = (200, -700, 150) size = (100, 100, 300) color = (0.62, 0.58, 0.52) }
|
|
67
|
+
display manager : GameManager { visible = false }
|
|
68
|
+
|
|
69
|
+
screenCanvas HUD {
|
|
70
|
+
textLabel ScoreText { offset = (20, 20) text = "Coins: 0 / 10" color = (1, 1, 0.85) }
|
|
71
|
+
textLabel MidText { align = (center, center) text = "" color = (1, 1, 0.3) }
|
|
72
|
+
button RestartBtn { anchor = (center, center) offset = (0, 70) size = (220, 52) text = "Restart" corner_radius = 8 color = #B98A20 visible = false }
|
|
73
|
+
}
|
|
@@ -1,70 +1,73 @@
|
|
|
1
|
-
// Dodge the Falling Blocks — red cubes rain down; touching one ends the run.
|
|
2
|
-
// Demonstrates: a hidden manager object, timed spawning with Timer, dynamic physics objects,
|
|
3
|
-
// cross-object variable writes (block -> manager), survival-seconds score, lose + restart flow.
|
|
4
|
-
// Movement uses the engine's default player controller (no #class player).
|
|
5
|
-
|
|
6
|
-
#class FallingBlock
|
|
7
|
-
var LifeTmr : Timer
|
|
8
|
-
event OnSpawned {
|
|
9
|
-
LifeTmr.StartCountDown(8) // despawn landed blocks so the arena stays playable
|
|
10
|
-
forever {
|
|
11
|
-
if LifeTmr.IsDone() {
|
|
12
|
-
Destroy()
|
|
13
|
-
}
|
|
14
|
-
var p = NearestPlayer()
|
|
15
|
-
if p.Exists() and SurfaceGapTo(p) < 5 {
|
|
16
|
-
NearestObjectWithTag(Tag.Manager).GameOver = true
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
#end
|
|
21
|
-
|
|
22
|
-
#class GameManager
|
|
23
|
-
var GameOver = false
|
|
24
|
-
var Score = 0
|
|
25
|
-
event OnPreSpawn {
|
|
26
|
-
AddTag(Tag.Manager)
|
|
27
|
-
}
|
|
28
|
-
event OnSpawned {
|
|
29
|
-
var secondTmr = Timer()
|
|
30
|
-
var dropTmr = Timer()
|
|
31
|
-
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
32
|
-
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
1
|
+
// Dodge the Falling Blocks — red cubes rain down; touching one ends the run. Click Restart to retry.
|
|
2
|
+
// Demonstrates: a hidden manager object, timed spawning with Timer, dynamic physics objects,
|
|
3
|
+
// cross-object variable writes (block -> manager), survival-seconds score, lose + restart flow.
|
|
4
|
+
// Movement uses the engine's default player controller (no #class player).
|
|
5
|
+
|
|
6
|
+
#class FallingBlock
|
|
7
|
+
var LifeTmr : Timer
|
|
8
|
+
event OnSpawned {
|
|
9
|
+
LifeTmr.StartCountDown(8) // despawn landed blocks so the arena stays playable
|
|
10
|
+
forever {
|
|
11
|
+
if LifeTmr.IsDone() {
|
|
12
|
+
Destroy()
|
|
13
|
+
}
|
|
14
|
+
var p = NearestPlayer()
|
|
15
|
+
if p.Exists() and SurfaceGapTo(p) < 5 {
|
|
16
|
+
NearestObjectWithTag(Tag.Manager).GameOver = true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
#end
|
|
21
|
+
|
|
22
|
+
#class GameManager
|
|
23
|
+
var GameOver = false
|
|
24
|
+
var Score = 0
|
|
25
|
+
event OnPreSpawn {
|
|
26
|
+
AddTag(Tag.Manager)
|
|
27
|
+
}
|
|
28
|
+
event OnSpawned {
|
|
29
|
+
var secondTmr = Timer()
|
|
30
|
+
var dropTmr = Timer()
|
|
31
|
+
var scoreLabel = ResolveObjectByNameOnce("ScoreText")
|
|
32
|
+
var midLabel = ResolveObjectByNameOnce("MidText")
|
|
33
|
+
var restartBtn = ResolveObjectByNameOnce("RestartBtn")
|
|
34
|
+
forever {
|
|
35
|
+
if GameOver {
|
|
36
|
+
midLabel.SetText("GAME OVER — survived " + Score + " s")
|
|
37
|
+
restartBtn.SetVisible(true)
|
|
38
|
+
continue
|
|
39
|
+
}
|
|
40
|
+
if secondTmr.IsDone() {
|
|
41
|
+
secondTmr.StartCountDown(1)
|
|
42
|
+
Score += 1
|
|
43
|
+
scoreLabel.SetText("Survived: " + Score + " s")
|
|
44
|
+
}
|
|
45
|
+
if dropTmr.IsDone() {
|
|
46
|
+
dropTmr.StartCountDown(0.35)
|
|
47
|
+
var pos = Position(RandomNumber(-900, 900), RandomNumber(-900, 900), 1300)
|
|
48
|
+
SpawnObject(SavedObject.block, pos)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
event ClickButton {
|
|
53
|
+
if Event.ClickedButton == ResolveObjectByNameOnce("RestartBtn") { RestartGame() }
|
|
54
|
+
}
|
|
55
|
+
#end
|
|
56
|
+
|
|
57
|
+
saved block {
|
|
58
|
+
physics block : FallingBlock { model = "cube" size = (120, 120, 120) color = (0.85, 0.25, 0.2) }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
object Ground {
|
|
62
|
+
model = "cube"
|
|
63
|
+
position = (0, 0, -50)
|
|
64
|
+
size = (2200, 2200, 100)
|
|
65
|
+
color = (0.4, 0.42, 0.5)
|
|
66
|
+
}
|
|
67
|
+
display manager : GameManager { visible = false }
|
|
68
|
+
|
|
69
|
+
screenCanvas HUD {
|
|
70
|
+
textLabel ScoreText { offset = (20, 20) text = "Survived: 0 s" color = (1, 1, 1) }
|
|
71
|
+
textLabel MidText { align = (center, center) text = "" color = (1, 0.45, 0.35) }
|
|
72
|
+
button RestartBtn { anchor = (center, center) offset = (0, 70) size = (220, 52) text = "Restart" corner_radius = 8 color = #B03A2E visible = false }
|
|
73
|
+
}
|