@origingame/create-game 0.0.0-stage → 0.1.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.
- package/README.md +57 -2
- package/archetypes/README.md +99 -0
- package/archetypes/idle/.origin/setup +14 -0
- package/archetypes/idle/LICENSES.md +12 -0
- package/archetypes/idle/README.md +234 -0
- package/archetypes/idle/assets/audio/buy.wav +0 -0
- package/archetypes/idle/assets/audio/milestone.wav +0 -0
- package/archetypes/idle/assets/audio/nova.wav +0 -0
- package/archetypes/idle/assets/audio/orbit.wav +0 -0
- package/archetypes/idle/assets/audio/tap.wav +0 -0
- package/archetypes/idle/assets/audio/ui-close.ogt +9 -0
- package/archetypes/idle/assets/audio/ui-error.ogt +9 -0
- package/archetypes/idle/assets/audio/ui-open.ogt +9 -0
- package/archetypes/idle/assets/audio/ui-press.ogt +9 -0
- package/archetypes/idle/assets/audio/ui-success.ogt +9 -0
- package/archetypes/idle/assets/fonts/NotoSansSC-subset.ttf +0 -0
- package/archetypes/idle/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
- package/archetypes/idle/assets/fonts/OFL.txt +93 -0
- package/archetypes/idle/assets/fx/drift.ogt +21 -0
- package/archetypes/idle/assets/fx/milestone.ogt +21 -0
- package/archetypes/idle/assets/fx/nova.ogt +22 -0
- package/archetypes/idle/assets/fx/stars.ogt +20 -0
- package/archetypes/idle/assets/fx/tap.ogt +23 -0
- package/archetypes/idle/assets/looks/idle.ogt +17 -0
- package/archetypes/idle/assets/skins/sparkorb/ChakraPetch-BoldItalic.ttf +0 -0
- package/archetypes/idle/assets/skins/sparkorb/ChakraPetch-BoldItalic.ttf.ogt +9 -0
- package/archetypes/idle/assets/skins/sparkorb/LICENSES.md +19 -0
- package/archetypes/idle/assets/skins/sparkorb/OFL.txt +95 -0
- package/archetypes/idle/assets/skins/sparkorb/Orbitron-Medium.ttf +0 -0
- package/archetypes/idle/assets/skins/sparkorb/Orbitron-Medium.ttf.ogt +9 -0
- package/archetypes/idle/assets/skins/sparkorb/Rajdhani-Bold.ttf +0 -0
- package/archetypes/idle/assets/skins/sparkorb/Rajdhani-Bold.ttf.ogt +9 -0
- package/archetypes/idle/assets/skins/sparkorb/atlas.png +0 -0
- package/archetypes/idle/assets/skins/sparkorb/atlas.png.ogt +7 -0
- package/archetypes/idle/assets/skins/sparkorb/icons.png +0 -0
- package/archetypes/idle/assets/skins/sparkorb/icons.png.ogt +7 -0
- package/archetypes/idle/assets/skins/sparkorb/skin.ogt +113 -0
- package/archetypes/idle/assets/sprites/glow.png +0 -0
- package/archetypes/idle/assets/sprites/glow.png.ogt +8 -0
- package/archetypes/idle/assets/sprites/mote-crystal.png +0 -0
- package/archetypes/idle/assets/sprites/mote-crystal.png.ogt +7 -0
- package/archetypes/idle/assets/sprites/mote-ember.png +0 -0
- package/archetypes/idle/assets/sprites/mote-ember.png.ogt +7 -0
- package/archetypes/idle/assets/sprites/mote-star.png +0 -0
- package/archetypes/idle/assets/sprites/mote-star.png.ogt +7 -0
- package/archetypes/idle/assets/sprites/mote-storm.png +0 -0
- package/archetypes/idle/assets/sprites/mote-storm.png.ogt +7 -0
- package/archetypes/idle/assets/sprites/orb.png +0 -0
- package/archetypes/idle/assets/sprites/orb.png.ogt +7 -0
- package/archetypes/idle/assets/sprites/spark.png +0 -0
- package/archetypes/idle/assets/sprites/spark.png.ogt +7 -0
- package/archetypes/idle/assets/strings/en.ogt +62 -0
- package/archetypes/idle/assets/strings/zh-CN.ogt +62 -0
- package/archetypes/idle/gitattributes +22 -0
- package/archetypes/idle/host.d.ts +46 -0
- package/archetypes/idle/package.json +18 -0
- package/archetypes/idle/project.ogt +14 -0
- package/archetypes/idle/references/metal/card.png +0 -0
- package/archetypes/idle/references/metal/orbit.png +0 -0
- package/archetypes/idle/references/metal/title.png +0 -0
- package/archetypes/idle/src/components.ts +139 -0
- package/archetypes/idle/src/main.ts +247 -0
- package/archetypes/idle/src/numbers.ts +126 -0
- package/archetypes/idle/src/systems.ts +340 -0
- package/archetypes/idle/src/ui.ts +412 -0
- package/archetypes/idle/tests/away.og.ts +42 -0
- package/archetypes/idle/tests/flow.og.ts +57 -0
- package/archetypes/idle/tests/frames.og.ts +33 -0
- package/archetypes/idle/tests/frames.ts +134 -0
- package/archetypes/idle/tests/lib.ts +74 -0
- package/archetypes/idle/tests/milestone.og.ts +32 -0
- package/archetypes/idle/tests/nova.og.ts +52 -0
- package/archetypes/idle/tests/offline.og.ts +60 -0
- package/archetypes/idle/tests/pad.og.ts +55 -0
- package/archetypes/idle/tests/pause.og.ts +68 -0
- package/archetypes/idle/tests/phone.og.ts +50 -0
- package/archetypes/idle/tests/replay.og.ts +28 -0
- package/archetypes/idle/tools/make-assets.py +448 -0
- package/archetypes/idle/tools/oglite.py +285 -0
- package/archetypes/idle/tsconfig.json +17 -0
- package/archetypes/match3/.origin/setup +14 -0
- package/archetypes/match3/LICENSES.md +7 -0
- package/archetypes/match3/README.md +205 -0
- package/archetypes/match3/assets/audio/cascade.wav +0 -0
- package/archetypes/match3/assets/audio/clear.wav +0 -0
- package/archetypes/match3/assets/audio/lost.wav +0 -0
- package/archetypes/match3/assets/audio/refused.wav +0 -0
- package/archetypes/match3/assets/audio/select.wav +0 -0
- package/archetypes/match3/assets/audio/swap.wav +0 -0
- package/archetypes/match3/assets/audio/won.wav +0 -0
- package/archetypes/match3/assets/fonts/OFL.txt +93 -0
- package/archetypes/match3/assets/fonts/ui.ttf +0 -0
- package/archetypes/match3/assets/fonts/ui.ttf.ogt +11 -0
- package/archetypes/match3/assets/scenes/main.ogt +24 -0
- package/archetypes/match3/assets/sprites/backdrop.png +0 -0
- package/archetypes/match3/assets/sprites/board.ogt +21 -0
- package/archetypes/match3/assets/sprites/cells.ogt +7 -0
- package/archetypes/match3/assets/sprites/cells.png +0 -0
- package/archetypes/match3/assets/sprites/cells.png.ogt +7 -0
- package/archetypes/match3/assets/sprites/gems.ogt +75 -0
- package/archetypes/match3/assets/sprites/gems.png +0 -0
- package/archetypes/match3/assets/sprites/panel.png +0 -0
- package/archetypes/match3/assets/sprites/ring.png +0 -0
- package/archetypes/match3/gitattributes +22 -0
- package/archetypes/match3/host.d.ts +46 -0
- package/archetypes/match3/package.json +18 -0
- package/archetypes/match3/project.ogt +18 -0
- package/archetypes/match3/references/metal/cascade.png +0 -0
- package/archetypes/match3/references/metal/clearing.png +0 -0
- package/archetypes/match3/references/metal/dealt.png +0 -0
- package/archetypes/match3/src/art.ts +54 -0
- package/archetypes/match3/src/board.ts +112 -0
- package/archetypes/match3/src/components.ts +95 -0
- package/archetypes/match3/src/layout.ts +25 -0
- package/archetypes/match3/src/main.ts +199 -0
- package/archetypes/match3/src/systems.ts +631 -0
- package/archetypes/match3/tests/drag.og.ts +31 -0
- package/archetypes/match3/tests/endings.og.ts +40 -0
- package/archetypes/match3/tests/frames.og.ts +49 -0
- package/archetypes/match3/tests/frames.ts +134 -0
- package/archetypes/match3/tests/hidpi.og.ts +41 -0
- package/archetypes/match3/tests/lib.ts +64 -0
- package/archetypes/match3/tests/replay.og.ts +28 -0
- package/archetypes/match3/tests/sounds.og.ts +50 -0
- package/archetypes/match3/tests/swap.og.ts +67 -0
- package/archetypes/match3/tools/make-assets.py +404 -0
- package/archetypes/match3/tools/oglite.py +285 -0
- package/archetypes/match3/tsconfig.json +17 -0
- package/archetypes/rhythm/.origin/setup +14 -0
- package/archetypes/rhythm/LICENSES.md +13 -0
- package/archetypes/rhythm/README.md +235 -0
- package/archetypes/rhythm/assets/audio/bass0.wav +0 -0
- package/archetypes/rhythm/assets/audio/bass1.wav +0 -0
- package/archetypes/rhythm/assets/audio/bass2.wav +0 -0
- package/archetypes/rhythm/assets/audio/bass3.wav +0 -0
- package/archetypes/rhythm/assets/audio/chords0.wav +0 -0
- package/archetypes/rhythm/assets/audio/chords1.wav +0 -0
- package/archetypes/rhythm/assets/audio/chords2.wav +0 -0
- package/archetypes/rhythm/assets/audio/chords3.wav +0 -0
- package/archetypes/rhythm/assets/audio/clear.wav +0 -0
- package/archetypes/rhythm/assets/audio/click.wav +0 -0
- package/archetypes/rhythm/assets/audio/drums.wav +0 -0
- package/archetypes/rhythm/assets/audio/fail.wav +0 -0
- package/archetypes/rhythm/assets/audio/leadA.wav +0 -0
- package/archetypes/rhythm/assets/audio/leadB.wav +0 -0
- package/archetypes/rhythm/assets/audio/miss.wav +0 -0
- package/archetypes/rhythm/assets/audio/tap0.wav +0 -0
- package/archetypes/rhythm/assets/audio/tap1.wav +0 -0
- package/archetypes/rhythm/assets/audio/tap2.wav +0 -0
- package/archetypes/rhythm/assets/audio/ui-close.ogt +9 -0
- package/archetypes/rhythm/assets/audio/ui-error.ogt +9 -0
- package/archetypes/rhythm/assets/audio/ui-open.ogt +9 -0
- package/archetypes/rhythm/assets/audio/ui-press.ogt +9 -0
- package/archetypes/rhythm/assets/audio/ui-success.ogt +9 -0
- package/archetypes/rhythm/assets/charts/neon-pulse.ogt +919 -0
- package/archetypes/rhythm/assets/fonts/NotoSansSC-subset.ttf +0 -0
- package/archetypes/rhythm/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
- package/archetypes/rhythm/assets/fonts/OFL.txt +93 -0
- package/archetypes/rhythm/assets/fx/hit.ogt +22 -0
- package/archetypes/rhythm/assets/skins/lanebeat/ChakraPetch-Medium.ttf +0 -0
- package/archetypes/rhythm/assets/skins/lanebeat/ChakraPetch-Medium.ttf.ogt +9 -0
- package/archetypes/rhythm/assets/skins/lanebeat/JetBrainsMono-Regular.ttf +0 -0
- package/archetypes/rhythm/assets/skins/lanebeat/JetBrainsMono-Regular.ttf.ogt +9 -0
- package/archetypes/rhythm/assets/skins/lanebeat/LICENSES.md +17 -0
- package/archetypes/rhythm/assets/skins/lanebeat/OFL.txt +95 -0
- package/archetypes/rhythm/assets/skins/lanebeat/Orbitron-Bold.ttf +0 -0
- package/archetypes/rhythm/assets/skins/lanebeat/Orbitron-Bold.ttf.ogt +9 -0
- package/archetypes/rhythm/assets/skins/lanebeat/atlas.png +0 -0
- package/archetypes/rhythm/assets/skins/lanebeat/atlas.png.ogt +7 -0
- package/archetypes/rhythm/assets/skins/lanebeat/icons.png +0 -0
- package/archetypes/rhythm/assets/skins/lanebeat/icons.png.ogt +7 -0
- package/archetypes/rhythm/assets/skins/lanebeat/skin.ogt +110 -0
- package/archetypes/rhythm/assets/sprites/lane.png +0 -0
- package/archetypes/rhythm/assets/sprites/lane.png.ogt +7 -0
- package/archetypes/rhythm/assets/sprites/note.png +0 -0
- package/archetypes/rhythm/assets/sprites/note.png.ogt +7 -0
- package/archetypes/rhythm/assets/sprites/ring.png +0 -0
- package/archetypes/rhythm/assets/sprites/ring.png.ogt +7 -0
- package/archetypes/rhythm/assets/sprites/spark.png +0 -0
- package/archetypes/rhythm/assets/sprites/spark.png.ogt +7 -0
- package/archetypes/rhythm/assets/strings/en.ogt +61 -0
- package/archetypes/rhythm/assets/strings/zh-CN.ogt +61 -0
- package/archetypes/rhythm/gitattributes +22 -0
- package/archetypes/rhythm/host.d.ts +46 -0
- package/archetypes/rhythm/package.json +18 -0
- package/archetypes/rhythm/project.ogt +14 -0
- package/archetypes/rhythm/references/metal/highway.png +0 -0
- package/archetypes/rhythm/references/metal/results.png +0 -0
- package/archetypes/rhythm/references/metal/title.png +0 -0
- package/archetypes/rhythm/src/components.ts +147 -0
- package/archetypes/rhythm/src/main.ts +202 -0
- package/archetypes/rhythm/src/systems.ts +490 -0
- package/archetypes/rhythm/src/ui.ts +421 -0
- package/archetypes/rhythm/tests/band.og.ts +45 -0
- package/archetypes/rhythm/tests/calibrate.og.ts +49 -0
- package/archetypes/rhythm/tests/clear.og.ts +51 -0
- package/archetypes/rhythm/tests/fail.og.ts +40 -0
- package/archetypes/rhythm/tests/flow.og.ts +54 -0
- package/archetypes/rhythm/tests/frames.og.ts +35 -0
- package/archetypes/rhythm/tests/frames.ts +134 -0
- package/archetypes/rhythm/tests/lib.ts +123 -0
- package/archetypes/rhythm/tests/pad.og.ts +41 -0
- package/archetypes/rhythm/tests/pause.og.ts +77 -0
- package/archetypes/rhythm/tests/phone.og.ts +44 -0
- package/archetypes/rhythm/tests/replay.og.ts +27 -0
- package/archetypes/rhythm/tests/timing.og.ts +37 -0
- package/archetypes/rhythm/tools/make-assets.py +383 -0
- package/archetypes/rhythm/tools/oglite.py +285 -0
- package/archetypes/rhythm/tsconfig.json +17 -0
- package/archetypes/roguelike/.origin/setup +14 -0
- package/archetypes/roguelike/LICENSES.md +14 -0
- package/archetypes/roguelike/README.md +256 -0
- package/archetypes/roguelike/assets/ai/foe.ogt +28 -0
- package/archetypes/roguelike/assets/ai/guardian.ogt +26 -0
- package/archetypes/roguelike/assets/audio/bump.wav +0 -0
- package/archetypes/roguelike/assets/audio/drink.wav +0 -0
- package/archetypes/roguelike/assets/audio/fall.wav +0 -0
- package/archetypes/roguelike/assets/audio/hit.wav +0 -0
- package/archetypes/roguelike/assets/audio/hurt.wav +0 -0
- package/archetypes/roguelike/assets/audio/item.wav +0 -0
- package/archetypes/roguelike/assets/audio/kill.wav +0 -0
- package/archetypes/roguelike/assets/audio/pickup.wav +0 -0
- package/archetypes/roguelike/assets/audio/roar.wav +0 -0
- package/archetypes/roguelike/assets/audio/stairs.wav +0 -0
- package/archetypes/roguelike/assets/audio/step.ogt +9 -0
- package/archetypes/roguelike/assets/audio/telegraph.wav +0 -0
- package/archetypes/roguelike/assets/audio/tomb.wav +0 -0
- package/archetypes/roguelike/assets/audio/ui-close.ogt +9 -0
- package/archetypes/roguelike/assets/audio/ui-error.ogt +9 -0
- package/archetypes/roguelike/assets/audio/ui-open.ogt +9 -0
- package/archetypes/roguelike/assets/audio/ui-press.ogt +9 -0
- package/archetypes/roguelike/assets/audio/ui-success.ogt +9 -0
- package/archetypes/roguelike/assets/audio/won.wav +0 -0
- package/archetypes/roguelike/assets/fonts/NotoSansSC-subset.ttf +0 -0
- package/archetypes/roguelike/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
- package/archetypes/roguelike/assets/fonts/OFL.txt +93 -0
- package/archetypes/roguelike/assets/maps/dive.ogt +106 -0
- package/archetypes/roguelike/assets/skins/lampdive/DotGothic16-Regular.ttf +0 -0
- package/archetypes/roguelike/assets/skins/lampdive/DotGothic16-Regular.ttf.ogt +9 -0
- package/archetypes/roguelike/assets/skins/lampdive/LICENSES.md +16 -0
- package/archetypes/roguelike/assets/skins/lampdive/OFL.txt +93 -0
- package/archetypes/roguelike/assets/skins/lampdive/atlas.png +0 -0
- package/archetypes/roguelike/assets/skins/lampdive/atlas.png.ogt +7 -0
- package/archetypes/roguelike/assets/skins/lampdive/icons.png +0 -0
- package/archetypes/roguelike/assets/skins/lampdive/icons.png.ogt +7 -0
- package/archetypes/roguelike/assets/skins/lampdive/skin.ogt +115 -0
- package/archetypes/roguelike/assets/sprites/dive.ogt +50 -0
- package/archetypes/roguelike/assets/sprites/dive.png +0 -0
- package/archetypes/roguelike/assets/sprites/dive.png.ogt +7 -0
- package/archetypes/roguelike/assets/sprites/glow.png +0 -0
- package/archetypes/roguelike/assets/sprites/glow.png.ogt +7 -0
- package/archetypes/roguelike/assets/strings/en.ogt +57 -0
- package/archetypes/roguelike/assets/strings/zh-CN.ogt +57 -0
- package/archetypes/roguelike/assets/tiles/tomb.ogt +31 -0
- package/archetypes/roguelike/assets/tiles/tomb.png +0 -0
- package/archetypes/roguelike/assets/tiles/tomb.png.ogt +7 -0
- package/archetypes/roguelike/gitattributes +22 -0
- package/archetypes/roguelike/host.d.ts +46 -0
- package/archetypes/roguelike/package.json +18 -0
- package/archetypes/roguelike/project.ogt +14 -0
- package/archetypes/roguelike/references/metal/dive.png +0 -0
- package/archetypes/roguelike/references/metal/over.png +0 -0
- package/archetypes/roguelike/references/metal/title.png +0 -0
- package/archetypes/roguelike/src/art.ts +23 -0
- package/archetypes/roguelike/src/components.ts +169 -0
- package/archetypes/roguelike/src/dive.ts +144 -0
- package/archetypes/roguelike/src/foes.ts +174 -0
- package/archetypes/roguelike/src/main.ts +258 -0
- package/archetypes/roguelike/src/systems.ts +620 -0
- package/archetypes/roguelike/src/ui.ts +350 -0
- package/archetypes/roguelike/tests/flow.og.ts +54 -0
- package/archetypes/roguelike/tests/foes.og.ts +45 -0
- package/archetypes/roguelike/tests/frames.og.ts +32 -0
- package/archetypes/roguelike/tests/frames.ts +134 -0
- package/archetypes/roguelike/tests/lib.ts +83 -0
- package/archetypes/roguelike/tests/lose.og.ts +44 -0
- package/archetypes/roguelike/tests/pad.og.ts +54 -0
- package/archetypes/roguelike/tests/pause.og.ts +59 -0
- package/archetypes/roguelike/tests/phone.og.ts +54 -0
- package/archetypes/roguelike/tests/replay.og.ts +24 -0
- package/archetypes/roguelike/tests/win.og.ts +60 -0
- package/archetypes/roguelike/tools/make-assets.py +518 -0
- package/archetypes/roguelike/tools/oglite.py +285 -0
- package/archetypes/roguelike/tsconfig.json +17 -0
- package/archetypes/runner/.origin/setup +14 -0
- package/archetypes/runner/LICENSES.md +10 -0
- package/archetypes/runner/README.md +225 -0
- package/archetypes/runner/assets/audio/coin.wav +0 -0
- package/archetypes/runner/assets/audio/crash.wav +0 -0
- package/archetypes/runner/assets/audio/hold.ogt +9 -0
- package/archetypes/runner/assets/audio/jump.wav +0 -0
- package/archetypes/runner/assets/audio/start.wav +0 -0
- package/archetypes/runner/assets/fonts/OFL.txt +93 -0
- package/archetypes/runner/assets/fonts/ui.ttf +0 -0
- package/archetypes/runner/assets/fonts/ui.ttf.ogt +11 -0
- package/archetypes/runner/assets/maps/far.ogt +25 -0
- package/archetypes/runner/assets/maps/near.ogt +25 -0
- package/archetypes/runner/assets/maps/roofs.ogt +19 -0
- package/archetypes/runner/assets/scenes/main.ogt +35 -0
- package/archetypes/runner/assets/sprites/coin.ogt +11 -0
- package/archetypes/runner/assets/sprites/coin.png +0 -0
- package/archetypes/runner/assets/sprites/coin.png.ogt +7 -0
- package/archetypes/runner/assets/sprites/courier.ogt +32 -0
- package/archetypes/runner/assets/sprites/courier.png +0 -0
- package/archetypes/runner/assets/sprites/courier.png.ogt +7 -0
- package/archetypes/runner/assets/sprites/props.ogt +21 -0
- package/archetypes/runner/assets/sprites/props.png +0 -0
- package/archetypes/runner/assets/sprites/props.png.ogt +7 -0
- package/archetypes/runner/assets/sprites/sky.png +0 -0
- package/archetypes/runner/assets/sprites/sky.png.ogt +7 -0
- package/archetypes/runner/assets/tiles/city.ogt +18 -0
- package/archetypes/runner/assets/tiles/city.png +0 -0
- package/archetypes/runner/assets/tiles/city.png.ogt +7 -0
- package/archetypes/runner/gitattributes +22 -0
- package/archetypes/runner/host.d.ts +46 -0
- package/archetypes/runner/package.json +18 -0
- package/archetypes/runner/project.ogt +18 -0
- package/archetypes/runner/references/metal/frames-coin.png +0 -0
- package/archetypes/runner/references/metal/frames-crash.png +0 -0
- package/archetypes/runner/references/metal/frames-title.png +0 -0
- package/archetypes/runner/src/art.ts +57 -0
- package/archetypes/runner/src/components.ts +94 -0
- package/archetypes/runner/src/main.ts +241 -0
- package/archetypes/runner/src/systems.ts +553 -0
- package/archetypes/runner/tests/coins.og.ts +30 -0
- package/archetypes/runner/tests/flow.og.ts +72 -0
- package/archetypes/runner/tests/frames.og.ts +37 -0
- package/archetypes/runner/tests/frames.ts +134 -0
- package/archetypes/runner/tests/jump.og.ts +44 -0
- package/archetypes/runner/tests/lib.ts +42 -0
- package/archetypes/runner/tests/records.og.ts +43 -0
- package/archetypes/runner/tests/replay.og.ts +36 -0
- package/archetypes/runner/tests/sounds.og.ts +43 -0
- package/archetypes/runner/tests/tune.og.ts +36 -0
- package/archetypes/runner/tools/make-assets.py +603 -0
- package/archetypes/runner/tools/oglite.py +285 -0
- package/archetypes/runner/tsconfig.json +17 -0
- package/archetypes/third-person/.origin/setup +14 -0
- package/archetypes/third-person/LICENSES.md +23 -0
- package/archetypes/third-person/README.md +249 -0
- package/archetypes/third-person/assets/ai/sentinel-east.ogt +69 -0
- package/archetypes/third-person/assets/ai/sentinel-north.ogt +69 -0
- package/archetypes/third-person/assets/ai/sentinel-west.ogt +69 -0
- package/archetypes/third-person/assets/anims/humanoid-clips.glb +0 -0
- package/archetypes/third-person/assets/audio/alarm.wav +0 -0
- package/archetypes/third-person/assets/audio/dawn.wav +0 -0
- package/archetypes/third-person/assets/audio/grab.wav +0 -0
- package/archetypes/third-person/assets/audio/ignite.wav +0 -0
- package/archetypes/third-person/assets/audio/jump.wav +0 -0
- package/archetypes/third-person/assets/audio/night.wav +0 -0
- package/archetypes/third-person/assets/audio/splash.wav +0 -0
- package/archetypes/third-person/assets/audio/step.ogt +9 -0
- package/archetypes/third-person/assets/audio/ui-close.ogt +9 -0
- package/archetypes/third-person/assets/audio/ui-error.ogt +9 -0
- package/archetypes/third-person/assets/audio/ui-open.ogt +9 -0
- package/archetypes/third-person/assets/audio/ui-press.ogt +9 -0
- package/archetypes/third-person/assets/audio/ui-success.ogt +9 -0
- package/archetypes/third-person/assets/audio/vale.wav +0 -0
- package/archetypes/third-person/assets/fonts/NotoSansSC-subset.ttf +0 -0
- package/archetypes/third-person/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
- package/archetypes/third-person/assets/fonts/OFL.txt +93 -0
- package/archetypes/third-person/assets/fx/burst.ogt +25 -0
- package/archetypes/third-person/assets/fx/fire.ogt +24 -0
- package/archetypes/third-person/assets/fx/smoke.ogt +24 -0
- package/archetypes/third-person/assets/fx/splash.ogt +24 -0
- package/archetypes/third-person/assets/luts/teal-orange.cube +4917 -0
- package/archetypes/third-person/assets/models/stout.glb +0 -0
- package/archetypes/third-person/assets/models/strider.glb +0 -0
- package/archetypes/third-person/assets/models/strider.glb.ogt +9 -0
- package/archetypes/third-person/assets/nav/vale.ogt +43 -0
- package/archetypes/third-person/assets/rigs/strider.ogt +6 -0
- package/archetypes/third-person/assets/skins/ember/Cinzel-Bold.ttf +0 -0
- package/archetypes/third-person/assets/skins/ember/Cinzel-Bold.ttf.ogt +9 -0
- package/archetypes/third-person/assets/skins/ember/LICENSES.md +13 -0
- package/archetypes/third-person/assets/skins/ember/Newsreader-Medium.ttf +0 -0
- package/archetypes/third-person/assets/skins/ember/Newsreader-Medium.ttf.ogt +9 -0
- package/archetypes/third-person/assets/skins/ember/OFL.txt +94 -0
- package/archetypes/third-person/assets/skins/ember/atlas.png +0 -0
- package/archetypes/third-person/assets/skins/ember/atlas.png.ogt +7 -0
- package/archetypes/third-person/assets/skins/ember/icons.png +0 -0
- package/archetypes/third-person/assets/skins/ember/icons.png.ogt +7 -0
- package/archetypes/third-person/assets/skins/ember/skin.ogt +109 -0
- package/archetypes/third-person/assets/strings/en.ogt +47 -0
- package/archetypes/third-person/assets/strings/zh-CN.ogt +47 -0
- package/archetypes/third-person/assets/terrain/vale-control.png +0 -0
- package/archetypes/third-person/assets/terrain/vale.ogt +42 -0
- package/archetypes/third-person/assets/terrain/vale.png +0 -0
- package/archetypes/third-person/assets/textures/decals.png +0 -0
- package/archetypes/third-person/assets/textures/flame.png +0 -0
- package/archetypes/third-person/assets/textures/smoke.png +0 -0
- package/archetypes/third-person/assets/textures/spark.png +0 -0
- package/archetypes/third-person/assets/textures/terrain-grass.png +0 -0
- package/archetypes/third-person/assets/textures/terrain-path.png +0 -0
- package/archetypes/third-person/assets/textures/terrain-rock.png +0 -0
- package/archetypes/third-person/assets/textures/terrain-sand.png +0 -0
- package/archetypes/third-person/gitattributes +22 -0
- package/archetypes/third-person/host.d.ts +46 -0
- package/archetypes/third-person/package.json +18 -0
- package/archetypes/third-person/project.ogt +14 -0
- package/archetypes/third-person/references/metal/beacon.png +0 -0
- package/archetypes/third-person/references/metal/dawn.png +0 -0
- package/archetypes/third-person/references/metal/title.png +0 -0
- package/archetypes/third-person/references/webgl2/beacon.png +0 -0
- package/archetypes/third-person/src/anim.ts +87 -0
- package/archetypes/third-person/src/beacons.ts +80 -0
- package/archetypes/third-person/src/components.ts +148 -0
- package/archetypes/third-person/src/hero.ts +293 -0
- package/archetypes/third-person/src/main.ts +164 -0
- package/archetypes/third-person/src/sentinels.ts +159 -0
- package/archetypes/third-person/src/sound.ts +66 -0
- package/archetypes/third-person/src/ui.ts +451 -0
- package/archetypes/third-person/src/world.ts +212 -0
- package/archetypes/third-person/tests/flow.og.ts +70 -0
- package/archetypes/third-person/tests/frames.og.ts +35 -0
- package/archetypes/third-person/tests/frames.ts +134 -0
- package/archetypes/third-person/tests/hitstop.og.ts +26 -0
- package/archetypes/third-person/tests/lib.ts +87 -0
- package/archetypes/third-person/tests/lose.og.ts +44 -0
- package/archetypes/third-person/tests/pause.og.ts +64 -0
- package/archetypes/third-person/tests/phone.og.ts +65 -0
- package/archetypes/third-person/tests/replay.og.ts +32 -0
- package/archetypes/third-person/tests/restart.og.ts +28 -0
- package/archetypes/third-person/tests/sentinels.og.ts +48 -0
- package/archetypes/third-person/tests/win.og.ts +62 -0
- package/archetypes/third-person/tools/make-assets.py +353 -0
- package/archetypes/third-person/tools/oglite.py +285 -0
- package/archetypes/third-person/tsconfig.json +17 -0
- package/archetypes/topdown/.origin/setup +14 -0
- package/archetypes/topdown/LICENSES.md +10 -0
- package/archetypes/topdown/README.md +235 -0
- package/archetypes/topdown/assets/ai/slime.ogt +49 -0
- package/archetypes/topdown/assets/audio/coin.wav +0 -0
- package/archetypes/topdown/assets/audio/door.wav +0 -0
- package/archetypes/topdown/assets/audio/hit.wav +0 -0
- package/archetypes/topdown/assets/audio/hurt.wav +0 -0
- package/archetypes/topdown/assets/audio/key.wav +0 -0
- package/archetypes/topdown/assets/audio/step.ogt +9 -0
- package/archetypes/topdown/assets/fonts/OFL.txt +93 -0
- package/archetypes/topdown/assets/fonts/ui.ttf +0 -0
- package/archetypes/topdown/assets/fonts/ui.ttf.ogt +9 -0
- package/archetypes/topdown/assets/maps/tomb.tmj +2183 -0
- package/archetypes/topdown/assets/sprites/hero.ogt +58 -0
- package/archetypes/topdown/assets/sprites/hero.png +0 -0
- package/archetypes/topdown/assets/sprites/hero.png.ogt +7 -0
- package/archetypes/topdown/assets/sprites/items.ogt +15 -0
- package/archetypes/topdown/assets/sprites/items.png +0 -0
- package/archetypes/topdown/assets/sprites/items.png.ogt +7 -0
- package/archetypes/topdown/assets/sprites/slime.ogt +17 -0
- package/archetypes/topdown/assets/sprites/slime.png +0 -0
- package/archetypes/topdown/assets/sprites/slime.png.ogt +7 -0
- package/archetypes/topdown/assets/tiles/dungeon.ogt +65 -0
- package/archetypes/topdown/assets/tiles/dungeon.png +0 -0
- package/archetypes/topdown/assets/tiles/dungeon.png.ogt +7 -0
- package/archetypes/topdown/gitattributes +22 -0
- package/archetypes/topdown/host.d.ts +46 -0
- package/archetypes/topdown/package.json +18 -0
- package/archetypes/topdown/project.ogt +14 -0
- package/archetypes/topdown/references/metal/crit.png +0 -0
- package/archetypes/topdown/references/metal/dash.png +0 -0
- package/archetypes/topdown/references/metal/east.png +0 -0
- package/archetypes/topdown/references/metal/start.png +0 -0
- package/archetypes/topdown/src/art.ts +48 -0
- package/archetypes/topdown/src/components.ts +128 -0
- package/archetypes/topdown/src/main.ts +275 -0
- package/archetypes/topdown/src/systems.ts +503 -0
- package/archetypes/topdown/tests/ai.og.ts +64 -0
- package/archetypes/topdown/tests/combat.og.ts +72 -0
- package/archetypes/topdown/tests/door.og.ts +62 -0
- package/archetypes/topdown/tests/flee.og.ts +49 -0
- package/archetypes/topdown/tests/frames.og.ts +45 -0
- package/archetypes/topdown/tests/frames.ts +134 -0
- package/archetypes/topdown/tests/lib.ts +71 -0
- package/archetypes/topdown/tests/replay.og.ts +40 -0
- package/archetypes/topdown/tests/walk.og.ts +46 -0
- package/archetypes/topdown/tools/make-assets.py +623 -0
- package/archetypes/topdown/tools/oglite.py +285 -0
- package/archetypes/topdown/tsconfig.json +17 -0
- package/archetypes/tower-defense/.origin/setup +14 -0
- package/archetypes/tower-defense/LICENSES.md +15 -0
- package/archetypes/tower-defense/README.md +240 -0
- package/archetypes/tower-defense/assets/ai/plant.ogt +16 -0
- package/archetypes/tower-defense/assets/audio/clear.wav +0 -0
- package/archetypes/tower-defense/assets/audio/frost.wav +0 -0
- package/archetypes/tower-defense/assets/audio/leak.wav +0 -0
- package/archetypes/tower-defense/assets/audio/lost.wav +0 -0
- package/archetypes/tower-defense/assets/audio/night.wav +0 -0
- package/archetypes/tower-defense/assets/audio/plant.wav +0 -0
- package/archetypes/tower-defense/assets/audio/pop.wav +0 -0
- package/archetypes/tower-defense/assets/audio/thorn.wav +0 -0
- package/archetypes/tower-defense/assets/audio/ui-close.ogt +9 -0
- package/archetypes/tower-defense/assets/audio/ui-error.ogt +9 -0
- package/archetypes/tower-defense/assets/audio/ui-open.ogt +9 -0
- package/archetypes/tower-defense/assets/audio/ui-press.ogt +9 -0
- package/archetypes/tower-defense/assets/audio/ui-success.ogt +9 -0
- package/archetypes/tower-defense/assets/audio/wave.wav +0 -0
- package/archetypes/tower-defense/assets/audio/won.wav +0 -0
- package/archetypes/tower-defense/assets/fonts/NotoSansSC-subset.ttf +0 -0
- package/archetypes/tower-defense/assets/fonts/NotoSansSC-subset.ttf.ogt +10 -0
- package/archetypes/tower-defense/assets/fonts/OFL.txt +93 -0
- package/archetypes/tower-defense/assets/fx/fireflies.ogt +21 -0
- package/archetypes/tower-defense/assets/fx/pop.ogt +21 -0
- package/archetypes/tower-defense/assets/maps/garden.ogt +91 -0
- package/archetypes/tower-defense/assets/skins/pathguard/Fredoka-SemiBold.ttf +0 -0
- package/archetypes/tower-defense/assets/skins/pathguard/Fredoka-SemiBold.ttf.ogt +9 -0
- package/archetypes/tower-defense/assets/skins/pathguard/LICENSES.md +13 -0
- package/archetypes/tower-defense/assets/skins/pathguard/LilitaOne-Regular.ttf +0 -0
- package/archetypes/tower-defense/assets/skins/pathguard/LilitaOne-Regular.ttf.ogt +9 -0
- package/archetypes/tower-defense/assets/skins/pathguard/OFL.txt +94 -0
- package/archetypes/tower-defense/assets/skins/pathguard/atlas.png +0 -0
- package/archetypes/tower-defense/assets/skins/pathguard/atlas.png.ogt +7 -0
- package/archetypes/tower-defense/assets/skins/pathguard/icons.png +0 -0
- package/archetypes/tower-defense/assets/skins/pathguard/icons.png.ogt +7 -0
- package/archetypes/tower-defense/assets/skins/pathguard/skin.ogt +111 -0
- package/archetypes/tower-defense/assets/sprites/garden.ogt +66 -0
- package/archetypes/tower-defense/assets/sprites/garden.png +0 -0
- package/archetypes/tower-defense/assets/sprites/garden.png.ogt +7 -0
- package/archetypes/tower-defense/assets/sprites/glow.png +0 -0
- package/archetypes/tower-defense/assets/sprites/glow.png.ogt +7 -0
- package/archetypes/tower-defense/assets/sprites/ring.png +0 -0
- package/archetypes/tower-defense/assets/sprites/ring.png.ogt +7 -0
- package/archetypes/tower-defense/assets/sprites/spark.png +0 -0
- package/archetypes/tower-defense/assets/sprites/spark.png.ogt +7 -0
- package/archetypes/tower-defense/assets/strings/en.ogt +47 -0
- package/archetypes/tower-defense/assets/strings/zh-CN.ogt +47 -0
- package/archetypes/tower-defense/assets/tiles/garden.ogt +10 -0
- package/archetypes/tower-defense/assets/tiles/garden.png +0 -0
- package/archetypes/tower-defense/assets/tiles/garden.png.ogt +7 -0
- package/archetypes/tower-defense/gitattributes +22 -0
- package/archetypes/tower-defense/host.d.ts +46 -0
- package/archetypes/tower-defense/package.json +18 -0
- package/archetypes/tower-defense/project.ogt +14 -0
- package/archetypes/tower-defense/references/metal/end.png +0 -0
- package/archetypes/tower-defense/references/metal/title.png +0 -0
- package/archetypes/tower-defense/references/metal/wave.png +0 -0
- package/archetypes/tower-defense/src/art.ts +24 -0
- package/archetypes/tower-defense/src/components.ts +156 -0
- package/archetypes/tower-defense/src/main.ts +253 -0
- package/archetypes/tower-defense/src/systems.ts +658 -0
- package/archetypes/tower-defense/src/ui.ts +382 -0
- package/archetypes/tower-defense/tests/flow.og.ts +56 -0
- package/archetypes/tower-defense/tests/frames.og.ts +31 -0
- package/archetypes/tower-defense/tests/frames.ts +134 -0
- package/archetypes/tower-defense/tests/lib.ts +81 -0
- package/archetypes/tower-defense/tests/lose.og.ts +40 -0
- package/archetypes/tower-defense/tests/maze.og.ts +53 -0
- package/archetypes/tower-defense/tests/pad.og.ts +41 -0
- package/archetypes/tower-defense/tests/pause.og.ts +59 -0
- package/archetypes/tower-defense/tests/phone.og.ts +49 -0
- package/archetypes/tower-defense/tests/replay.og.ts +28 -0
- package/archetypes/tower-defense/tests/win.og.ts +58 -0
- package/archetypes/tower-defense/tools/make-assets.py +640 -0
- package/archetypes/tower-defense/tools/oglite.py +285 -0
- package/archetypes/tower-defense/tsconfig.json +17 -0
- package/bin/create.ts +496 -0
- package/looks/catalogue.json +1871 -0
- package/package.json +31 -4
- package/template/.origin/setup +14 -0
- package/template/LICENSES.md +23 -0
- package/template/README.md +37 -0
- package/template/assets/ai/guard.ogt +48 -0
- package/template/assets/audio/blip.wav +0 -0
- package/template/assets/audio/click.ogt +9 -0
- package/template/assets/fonts/NotoSansSC-Regular-subset.ttf +0 -0
- package/template/assets/fonts/NotoSansSC-Regular-subset.ttf.ogt +12 -0
- package/template/assets/fonts/OFL.txt +93 -0
- package/template/assets/looks/origin-game.ogt +12 -0
- package/template/assets/models/dropship.glb +0 -0
- package/template/assets/models/walker.glb +0 -0
- package/template/assets/nav/yard.ogt +27 -0
- package/template/assets/scenes/main.ogt +34 -0
- package/template/assets/strings/en.ogt +14 -0
- package/template/assets/textures/stone.png +0 -0
- package/template/assets/textures/stone_n.png +0 -0
- package/template/assets/textures/stone_n.png.ogt +7 -0
- package/template/gitattributes +22 -0
- package/template/package.json +18 -0
- package/template/project.ogt +25 -0
- package/template/src/main.ts +246 -0
- package/template/tests/guard.og.ts +67 -0
- package/template/tests/smoke.og.ts +43 -0
- package/template/tsconfig.json +17 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Shared readers for Path Guard's playtests. `get:Game:<file>` writes the
|
|
2
|
+
// round's resource, the state the game's `facts` (src/main.ts) report to the
|
|
3
|
+
// probe; `dump_entity:<name>:<file>` one row; `dump_platform` the calls to
|
|
4
|
+
// og.platform.
|
|
5
|
+
import type { PlaytestRun } from "@origingame/engine/playtest";
|
|
6
|
+
|
|
7
|
+
export interface Game {
|
|
8
|
+
phase: number;
|
|
9
|
+
paused: boolean;
|
|
10
|
+
settingsOpen: boolean;
|
|
11
|
+
won: boolean;
|
|
12
|
+
rounds: number;
|
|
13
|
+
lives: number;
|
|
14
|
+
gold: number;
|
|
15
|
+
wave: number;
|
|
16
|
+
inWave: boolean;
|
|
17
|
+
walking: number;
|
|
18
|
+
kills: number;
|
|
19
|
+
leaks: number;
|
|
20
|
+
placed: number;
|
|
21
|
+
refused: number;
|
|
22
|
+
refusal: number;
|
|
23
|
+
shots: number;
|
|
24
|
+
selected: number;
|
|
25
|
+
cursorX: number;
|
|
26
|
+
cursorY: number;
|
|
27
|
+
score: number;
|
|
28
|
+
best: number;
|
|
29
|
+
newBest: boolean;
|
|
30
|
+
bestRevision: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Phase.* and Refusal.* of src/components.ts. */
|
|
34
|
+
export const TITLE = 0;
|
|
35
|
+
export const PLAY = 1;
|
|
36
|
+
export const OVER = 2;
|
|
37
|
+
export const POOR = 1;
|
|
38
|
+
export const BLOCKED = 2;
|
|
39
|
+
export const TAKEN = 3;
|
|
40
|
+
|
|
41
|
+
/** The Game resource from a `get:Game:<file>` step. */
|
|
42
|
+
export function game(run: PlaytestRun, file: string): Game {
|
|
43
|
+
return run.json<{ value: Game }>(file).value;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** One component of a dumped entity. */
|
|
47
|
+
export function component<T>(run: PlaytestRun, file: string, name: string): T {
|
|
48
|
+
const c = run.json<{ components: Record<string, unknown> }>(file).components[name];
|
|
49
|
+
if (!c) throw new Error(`${file} has no ${name}`);
|
|
50
|
+
return c as T;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface PlatformDump {
|
|
54
|
+
host: string;
|
|
55
|
+
calls: Array<{ method: string; args: Record<string, unknown>; tick: number; state: string; result?: { ok: boolean; data: Record<string, unknown> } }>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** A key pressed at t (down, then up two ticks later). */
|
|
59
|
+
export const press = (key: string, t: number) => `${t}:key_down:${key};${(t + 0.034).toFixed(3)}:key_up:${key}`;
|
|
60
|
+
|
|
61
|
+
/** A tap on a UI element by its id path (pressed, released a tick later). */
|
|
62
|
+
export const tap = (id: string, t: number) => `${t}:touch_move_to:${id};${(t + 0.017).toFixed(3)}:touch_start;${(t + 0.05).toFixed(3)}:touch_end`;
|
|
63
|
+
|
|
64
|
+
/** Play on the title: the round starts on the release. */
|
|
65
|
+
export const play = (t: number) => tap("play", t);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A cell's centre in CSS pixels on the 1280×720 desktop surface: src/ui.ts
|
|
69
|
+
* frames the 9 × 13 field in the room the HUD leaves (76 px above, 24
|
|
70
|
+
* below, 200 each side), 46.27 px a cell.
|
|
71
|
+
*/
|
|
72
|
+
export function cellPx(x: number, y: number): string {
|
|
73
|
+
const scale = Math.min(880 / 9.4, 620 / 13.4);
|
|
74
|
+
const camY = 6.5 + (386 - 360) / scale;
|
|
75
|
+
const sx = 640 + (x + 0.5 - 4.5) * scale;
|
|
76
|
+
const sy = 360 - (12.5 - y - camY) * scale;
|
|
77
|
+
return `${sx.toFixed(1)},${sy.toFixed(1)}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A tap on a lawn cell (desktop). */
|
|
81
|
+
export const tapCell = (x: number, y: number, t: number) => `${t}:touch_move:${cellPx(x, y)};${(t + 0.017).toFixed(3)}:touch_start;${(t + 0.05).toFixed(3)}:touch_end`;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// The failure path: no plants, the light set to two. The first visitors
|
|
2
|
+
// walk the open lawn to the doorstep; each takes its light with a shake, a
|
|
3
|
+
// hit stop and a red number; the light at 0 ends the round on the end card
|
|
4
|
+
// ("The lantern went out"), and Play again starts a fresh round.
|
|
5
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
6
|
+
import { game, OVER, PLAY, play, tap } from "./lib.ts";
|
|
7
|
+
|
|
8
|
+
export default playtest({
|
|
9
|
+
name: "unguarded, visitors reach the doorstep, the lantern goes out, the end card offers another round",
|
|
10
|
+
commands: [
|
|
11
|
+
"0.1:set:Tuning.startLives=2",
|
|
12
|
+
play(0.3),
|
|
13
|
+
"1.0:get:Game:start.json",
|
|
14
|
+
"15.0:get:Game:over.json",
|
|
15
|
+
"15.0:get:og.TimeScale:time.json",
|
|
16
|
+
"16.6:screenshot:lost.png",
|
|
17
|
+
tap("Retry", 17.0),
|
|
18
|
+
"17.8:get:Game:again.json",
|
|
19
|
+
"17.9:quit",
|
|
20
|
+
].join(";"),
|
|
21
|
+
check(run, t) {
|
|
22
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
23
|
+
const start = game(run, "start.json");
|
|
24
|
+
t.equal(start.phase, PLAY, "the round started");
|
|
25
|
+
t.equal(start.lives, 2, "with the tuned light");
|
|
26
|
+
const over = game(run, "over.json");
|
|
27
|
+
t.equal(over.phase, OVER, "the light ran out: the round is over");
|
|
28
|
+
t.equal(over.won, false, "lost");
|
|
29
|
+
t.equal(over.lives, 0, "no light left");
|
|
30
|
+
t.ok(over.leaks >= 2, `${over.leaks} visitors reached the doorstep`);
|
|
31
|
+
t.equal(over.kills, 0, "nothing was turned away");
|
|
32
|
+
t.equal(run.json<{ value: { scale: number } }>("time.json").value.scale, 1, "the end card leaves the time scale at 1");
|
|
33
|
+
t.frame("lost.png", () => t.equal(run.png("lost.png").width, 1280, "the end card was captured"));
|
|
34
|
+
const again = game(run, "again.json");
|
|
35
|
+
t.equal(again.phase, PLAY, "Play again started another round");
|
|
36
|
+
t.equal(again.rounds, 2, "the second round");
|
|
37
|
+
t.equal(again.lives, 2, "with the light back");
|
|
38
|
+
t.equal(again.leaks, 0, "and the count cleared");
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// The maze and its refusals: a row of hedges across the lawn leaves one
|
|
2
|
+
// gap, and the flow field takes the visitors through it; a hedge in the gap
|
|
3
|
+
// would close the path, so it is refused and costs nothing; so are a plant
|
|
4
|
+
// on a stone or on another plant, and one the purse cannot pay for.
|
|
5
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
6
|
+
import { BLOCKED, game, POOR, TAKEN } from "./lib.ts";
|
|
7
|
+
|
|
8
|
+
const ROW = [1, 2, 3, 4, 5, 6].map((x) => `0.5:plant:hedge:${x}:2`).join(";");
|
|
9
|
+
// The first visitor's position, every tenth of a second while it crosses the hedge row.
|
|
10
|
+
const SAMPLES = Array.from({ length: 40 }, (_, k) => +(4.0 + k * 0.1).toFixed(1));
|
|
11
|
+
|
|
12
|
+
export default playtest({
|
|
13
|
+
name: "hedges route the visitors through the gap; a closed path, a stone, a taken cell and an empty purse are refused",
|
|
14
|
+
commands: [
|
|
15
|
+
"0.3:begin",
|
|
16
|
+
"0.4:gold:200",
|
|
17
|
+
ROW,
|
|
18
|
+
"0.6:get:Game:row.json",
|
|
19
|
+
"0.7:plant:hedge:7:2",
|
|
20
|
+
"0.8:get:Game:closed.json",
|
|
21
|
+
"0.9:plant:thorn:2:3",
|
|
22
|
+
"1.0:get:Game:stone.json",
|
|
23
|
+
"1.1:plant:thorn:3:2",
|
|
24
|
+
"1.2:get:Game:taken.json",
|
|
25
|
+
"1.3:gold:20",
|
|
26
|
+
"1.4:plant:frost:5:6",
|
|
27
|
+
"1.5:get:Game:poor.json",
|
|
28
|
+
"1.6:screenshot:maze.png",
|
|
29
|
+
...SAMPLES.map((t, k) => `${t}:get:visitor-0.og.Transform.position:p${k}.json`),
|
|
30
|
+
"8.1:quit",
|
|
31
|
+
].join(";"),
|
|
32
|
+
check(run, t) {
|
|
33
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
34
|
+
const row = game(run, "row.json");
|
|
35
|
+
t.equal(row.placed, 6, "six hedges across row 2, the gap at column 7");
|
|
36
|
+
t.equal(row.gold, 200 - 60, "ten coins each");
|
|
37
|
+
const closed = game(run, "closed.json");
|
|
38
|
+
t.equal(closed.refusal, BLOCKED, "a hedge in the gap would close the path: refused");
|
|
39
|
+
t.equal(closed.placed, 6, "and not set");
|
|
40
|
+
t.equal(closed.gold, row.gold, "and not paid for");
|
|
41
|
+
t.equal(game(run, "stone.json").refusal, TAKEN, "a stone takes no plant");
|
|
42
|
+
t.equal(game(run, "taken.json").refusal, TAKEN, "a hedge's cell takes no other plant");
|
|
43
|
+
const poor = game(run, "poor.json");
|
|
44
|
+
t.equal(poor.refusal, POOR, "twenty coins do not buy a frost lily");
|
|
45
|
+
t.equal(poor.refused, 4, "four refusals in all");
|
|
46
|
+
// Row 2 spans y 9.5–10.5 in the world; the gap is column 7 (x 7–8).
|
|
47
|
+
const at = SAMPLES.map((_, k) => run.json<{ value: number[] }>(`p${k}.json`).value);
|
|
48
|
+
const crossing = at.filter((p) => p[1]! > 9.6 && p[1]! < 10.4);
|
|
49
|
+
t.ok(crossing.length > 0, `the first visitor crossed the hedge row (${crossing.length} samples on it)`);
|
|
50
|
+
t.ok(crossing.every((p) => p[0]! > 6.8), `through the gap only (x ${crossing.map((p) => p[0]!.toFixed(2)).join(", ")})`);
|
|
51
|
+
t.ok(at.at(-1)![1]! < 9.5, `and walked on below it (y ${at.at(-1)![1]!.toFixed(2)})`);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// A gamepad alone: the d-pad and A start from the title, the d-pad walks
|
|
2
|
+
// the cursor, A sets a plant, X picks the next plant, Y calls the wave,
|
|
3
|
+
// Start pauses and B resumes.
|
|
4
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
5
|
+
import { game, PLAY } from "./lib.ts";
|
|
6
|
+
|
|
7
|
+
export default playtest({
|
|
8
|
+
name: "the d-pad, A, X, Y, Start and B play a round",
|
|
9
|
+
commands: [
|
|
10
|
+
// The title's first item holds the focus when the menu opens (og-ui §4): A plays at once.
|
|
11
|
+
"0.4:gamepad:a",
|
|
12
|
+
"1.2:get:Game:started.json",
|
|
13
|
+
"1.3:gamepad:up",
|
|
14
|
+
"1.4:gamepad:left",
|
|
15
|
+
"1.5:gamepad:a",
|
|
16
|
+
"1.6:gamepad:x",
|
|
17
|
+
"1.7:gamepad:right",
|
|
18
|
+
"1.8:gamepad:a",
|
|
19
|
+
"1.9:get:Game:planted.json",
|
|
20
|
+
"2.0:gamepad:y",
|
|
21
|
+
"2.2:get:Game:called.json",
|
|
22
|
+
"2.3:gamepad:start",
|
|
23
|
+
"2.5:get:Game:paused.json",
|
|
24
|
+
"2.6:gamepad:b",
|
|
25
|
+
"2.9:get:Game:resumed.json",
|
|
26
|
+
"3.0:gamepad:off",
|
|
27
|
+
"3.1:quit",
|
|
28
|
+
].join(";"),
|
|
29
|
+
check(run, t) {
|
|
30
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
31
|
+
t.equal(game(run, "started.json").phase, PLAY, "the pad started a round from the title");
|
|
32
|
+
const planted = game(run, "planted.json");
|
|
33
|
+
t.equal(planted.placed, 2, "A set two plants");
|
|
34
|
+
t.equal(planted.selected, 1, "X picked the frost lily");
|
|
35
|
+
t.ok(planted.cursorX === 4 && planted.cursorY === 8, `the d-pad walked the cursor to (4, 8) (${planted.cursorX}, ${planted.cursorY})`);
|
|
36
|
+
t.equal(planted.gold, 150 - 50 - 70, "a thorn and a frost lily paid for");
|
|
37
|
+
t.equal(game(run, "called.json").wave, 1, "Y called the first wave");
|
|
38
|
+
t.equal(game(run, "paused.json").paused, true, "Start paused");
|
|
39
|
+
t.equal(game(run, "resumed.json").paused, false, "B resumed");
|
|
40
|
+
},
|
|
41
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Pause and settings: Escape holds the garden (time scale 0, the visitors
|
|
2
|
+
// stop), the pause menu opens Settings, 简体中文 switches every string, the
|
|
3
|
+
// music slider moves, Done saves the settings through og.platform, and
|
|
4
|
+
// Resume lets the garden go again in the chosen language.
|
|
5
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
6
|
+
import { component, game, type PlatformDump, play, press, tap } from "./lib.ts";
|
|
7
|
+
|
|
8
|
+
export default playtest({
|
|
9
|
+
name: "Escape pauses, settings switch the language and save, Resume runs the garden again",
|
|
10
|
+
commands: [
|
|
11
|
+
play(0.3),
|
|
12
|
+
"4.4:dump_entity:visitor-0:moving.json",
|
|
13
|
+
press("Escape", 4.5),
|
|
14
|
+
"4.7:get:Game:paused.json",
|
|
15
|
+
"4.7:get:og.TimeScale.scale:scale.json",
|
|
16
|
+
"4.7:dump_entity:visitor-0:held-a.json",
|
|
17
|
+
"5.2:dump_entity:visitor-0:held-b.json",
|
|
18
|
+
"5.3:screenshot:pause.png",
|
|
19
|
+
tap("settings", 5.4),
|
|
20
|
+
"6.0:move_to_text:简体中文",
|
|
21
|
+
"6.02:touch_start",
|
|
22
|
+
"6.05:touch_end",
|
|
23
|
+
"6.3:touch_move_to:Music/Slider",
|
|
24
|
+
"6.32:touch_start",
|
|
25
|
+
"6.35:touch_end",
|
|
26
|
+
"6.8:screenshot:settings-zh.png",
|
|
27
|
+
tap("Done", 7.0),
|
|
28
|
+
"7.5:get:Prefs:prefs.json",
|
|
29
|
+
"7.5:dump_platform:platform.json",
|
|
30
|
+
"7.6:screenshot:pause-zh.png",
|
|
31
|
+
tap("resume", 7.8),
|
|
32
|
+
"8.4:get:Game:resumed.json",
|
|
33
|
+
"8.4:dump_entity:visitor-0:again-a.json",
|
|
34
|
+
"8.6:dump_entity:visitor-0:again-b.json",
|
|
35
|
+
"8.7:screenshot:play-zh.png",
|
|
36
|
+
"8.8:quit",
|
|
37
|
+
].join(";"),
|
|
38
|
+
check(run, t) {
|
|
39
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
40
|
+
const pos = (f: string) => component<{ position: number[] }>(run, f, "og.Transform").position;
|
|
41
|
+
t.equal(game(run, "paused.json").paused, true, "Escape paused the round");
|
|
42
|
+
t.equal(run.json<{ value: number }>("scale.json").value, 0, "the garden holds: time scale 0");
|
|
43
|
+
t.equal(pos("held-b.json")[1], pos("held-a.json")[1], "the visitor stands still while paused");
|
|
44
|
+
const prefs = run.json<{ value: { language: number; music: number; saves: number } }>("prefs.json").value;
|
|
45
|
+
t.equal(prefs.language, 1, "简体中文 was chosen");
|
|
46
|
+
t.ok(prefs.music < 0.7, `the music slider moved (${prefs.music.toFixed(2)})`);
|
|
47
|
+
t.equal(prefs.saves, 1, "Done saved once");
|
|
48
|
+
const p = run.json<PlatformDump>("platform.json");
|
|
49
|
+
const saved = p.calls.find((c) => c.method === "store.set" && c.args["key"] === "og.settings");
|
|
50
|
+
t.equal((saved?.args["value"] as { language?: string } | undefined)?.language, "zh-CN", "the settings went to og.platform with the language");
|
|
51
|
+
const resumed = game(run, "resumed.json");
|
|
52
|
+
t.equal(resumed.paused, false, "Resume closed the pause menu");
|
|
53
|
+
t.ok(pos("again-b.json")[1]! < pos("again-a.json")[1]!, "the visitor walks again");
|
|
54
|
+
t.frame(["pause.png", "settings-zh.png", "pause-zh.png", "play-zh.png"], () => {
|
|
55
|
+
for (const f of ["pause.png", "settings-zh.png", "pause-zh.png", "play-zh.png"]) t.equal(run.png(f).width, 1280, `${f} captured`);
|
|
56
|
+
});
|
|
57
|
+
t.ok(pos("moving.json")[1]! < 12.5, "a visitor was on the lawn before the pause");
|
|
58
|
+
},
|
|
59
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// A phone in portrait (390 × 844 CSS px at 3×, a notch and a home
|
|
2
|
+
// indicator): the title and the HUD lay out for it, the tray runs along
|
|
3
|
+
// the bottom inside the safe area with touch-sized buttons, and a tap on
|
|
4
|
+
// a tray button picks its plant.
|
|
5
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
6
|
+
import { game, PLAY, play, tap } from "./lib.ts";
|
|
7
|
+
|
|
8
|
+
interface Ui {
|
|
9
|
+
surface: { width: number; height: number; dpr: number } | null;
|
|
10
|
+
elements: Array<{ id: string; parent: string; kind?: string; text: string; x: number; y: number; width: number; height: number }>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default playtest({
|
|
14
|
+
name: "the phone layout: title, HUD and a bottom tray of touch-sized buttons inside the safe area",
|
|
15
|
+
size: "1170x2532",
|
|
16
|
+
commands: [
|
|
17
|
+
"0.05:viewport:phone",
|
|
18
|
+
"0.4:screenshot:title.png",
|
|
19
|
+
play(0.5),
|
|
20
|
+
"1.3:plant:thorn:3:5",
|
|
21
|
+
tap("Plant#2/Pick", 1.4),
|
|
22
|
+
// A finger lifts away: nothing hovers on a touch screen.
|
|
23
|
+
"1.5:touch_move:195,400",
|
|
24
|
+
"1.7:get:Game:picked.json",
|
|
25
|
+
"1.8:screenshot:play.png",
|
|
26
|
+
"1.8:dump_ui:ui.json",
|
|
27
|
+
"1.9:quit",
|
|
28
|
+
].join(";"),
|
|
29
|
+
check(run, t) {
|
|
30
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
31
|
+
const picked = game(run, "picked.json");
|
|
32
|
+
t.equal(picked.phase, PLAY, "a tap on Play started the round");
|
|
33
|
+
t.equal(picked.selected, 2, "a tap on the tray picked the hedge");
|
|
34
|
+
const ui = run.json<Ui>("ui.json");
|
|
35
|
+
t.equal(ui.surface?.width, 390, "the UI lays out at 390 CSS px");
|
|
36
|
+
const picks = ui.elements.filter((e) => e.id === "Pick");
|
|
37
|
+
t.equal(picks.length, 3, "three tray buttons");
|
|
38
|
+
for (const p of picks) {
|
|
39
|
+
t.ok(p.height >= 44, `${p.text}: ${p.height} px tall, a touch target`);
|
|
40
|
+
t.ok(p.y + p.height <= 844 - 34, `${p.text} sits above the home indicator`);
|
|
41
|
+
t.ok(p.y > 844 / 2, `${p.text} is in the bottom half, the thumb's`);
|
|
42
|
+
}
|
|
43
|
+
const pause = ui.elements.find((e) => e.id === "Pause");
|
|
44
|
+
t.ok(pause !== undefined && pause.y >= 47, "the pause button sits below the notch");
|
|
45
|
+
t.frame(["title.png", "play.png"], () => {
|
|
46
|
+
for (const f of ["title.png", "play.png"]) t.equal(run.png(f).height, 2532, `${f} is a phone frame`);
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Determinism: a round with plants by tap and keys, two waves called early,
|
|
2
|
+
// shots, frost, pops and a leak, run twice in fresh processes, ends on the
|
|
3
|
+
// same world hash.
|
|
4
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
5
|
+
import { game, play, press, tapCell } from "./lib.ts";
|
|
6
|
+
|
|
7
|
+
export default playtest({
|
|
8
|
+
name: "a round with plants, shots, pops and frost replays to the same hash",
|
|
9
|
+
runs: 2,
|
|
10
|
+
commands: [
|
|
11
|
+
play(0.3),
|
|
12
|
+
tapCell(3, 4, 1.2),
|
|
13
|
+
press("Digit2", 1.4),
|
|
14
|
+
press("ArrowRight", 1.5),
|
|
15
|
+
press("ArrowRight", 1.6),
|
|
16
|
+
press("Space", 1.7),
|
|
17
|
+
press("KeyN", 1.9),
|
|
18
|
+
"9.0:get:Game:end.json",
|
|
19
|
+
"9.1:quit",
|
|
20
|
+
].join(";"),
|
|
21
|
+
check(run, t) {
|
|
22
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
23
|
+
t.equal(run.hashes.length, 2, "two runs");
|
|
24
|
+
t.equal(run.hashes[1], run.hashes[0], `both runs end on hash ${run.hashes[0]}`);
|
|
25
|
+
const end = game(run, "end.json");
|
|
26
|
+
t.ok(end.shots > 0 && end.kills > 0, `the round had shots (${end.shots}) and pops (${end.kills})`);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// The round held to the end: a stand of thorns and frost lilies at the
|
|
2
|
+
// gate, the last wave called early with N (its bonus paid), every visitor
|
|
3
|
+
// turned away; the end card lands with its stars and score, the score is
|
|
4
|
+
// saved as the best (a store write at the revision read on tick 0,
|
|
5
|
+
// whose answer moves the revision on for the next one),
|
|
6
|
+
// submitted to the board and filed as telemetry; Title goes back.
|
|
7
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
8
|
+
import { game, OVER, type PlatformDump, press, tap, TITLE } from "./lib.ts";
|
|
9
|
+
|
|
10
|
+
const STAND = ["thorn:3:2", "thorn:5:2", "frost:4:3", "thorn:2:4", "thorn:6:4", "frost:3:5", "frost:5:5", "thorn:4:7", "thorn:2:7", "thorn:6:7"].map((p) => `0.5:plant:${p}`).join(";");
|
|
11
|
+
|
|
12
|
+
export default playtest({
|
|
13
|
+
name: "a strong stand holds the last wave, the end card shows the win, the best is saved and submitted",
|
|
14
|
+
commands: [
|
|
15
|
+
"0.1:set:Tuning.spawnGap=0.5",
|
|
16
|
+
"0.3:begin",
|
|
17
|
+
"0.4:gold:2000",
|
|
18
|
+
STAND,
|
|
19
|
+
"0.6:wave:5",
|
|
20
|
+
"0.7:get:Game:before.json",
|
|
21
|
+
press("KeyN", 1.0),
|
|
22
|
+
"1.2:get:Game:called.json",
|
|
23
|
+
"22.0:get:Game:won.json",
|
|
24
|
+
"23.0:screenshot:won.png",
|
|
25
|
+
"23.1:dump_platform:platform.json",
|
|
26
|
+
tap("Menu", 23.5),
|
|
27
|
+
"24.4:get:Game:title.json",
|
|
28
|
+
"24.5:quit",
|
|
29
|
+
].join(";"),
|
|
30
|
+
check(run, t) {
|
|
31
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
32
|
+
const before = game(run, "before.json");
|
|
33
|
+
t.equal(before.placed, 10, "ten plants in the stand");
|
|
34
|
+
const called = game(run, "called.json");
|
|
35
|
+
t.equal(called.wave, 5, "N called the last wave at once");
|
|
36
|
+
t.ok(called.inWave, "and it is under way");
|
|
37
|
+
const won = game(run, "won.json");
|
|
38
|
+
t.equal(won.phase, OVER, "the round is over");
|
|
39
|
+
t.equal(won.won, true, "won");
|
|
40
|
+
t.equal(won.leaks, 0, "nobody reached the doorstep");
|
|
41
|
+
t.equal(won.kills, 18, "all eighteen visitors of the last wave turned away");
|
|
42
|
+
t.equal(won.score, won.kills * 10 + won.lives * 50 + won.gold, "the score: kills × 10 + light × 50 + coins");
|
|
43
|
+
t.ok(won.newBest && won.best === won.score, "a new best");
|
|
44
|
+
const p = run.json<PlatformDump>("platform.json");
|
|
45
|
+
const of = (m: string) => p.calls.filter((c) => c.method === m);
|
|
46
|
+
const read = of("store.get").find((c) => c.args["key"] === "best");
|
|
47
|
+
t.ok(read?.tick === 0 && read.result?.data["value"] === null, "tick 0 read `best` from the store (never written)");
|
|
48
|
+
const set = of("store.set")[0];
|
|
49
|
+
t.equal(set?.args["value"], won.score, "the best was written");
|
|
50
|
+
t.equal(set?.args["revision"], 0, "at the revision read (never written before)");
|
|
51
|
+
t.equal(set?.result?.data["revision"], 1, "its first revision");
|
|
52
|
+
t.equal(of("leaderboard.submit")[0]?.args["score"], won.score, "the score went to the board");
|
|
53
|
+
t.equal(of("telemetry")[0]?.args["name"], "round.over", "a round.over event was filed");
|
|
54
|
+
const title = game(run, "title.json");
|
|
55
|
+
t.equal(title.phase, TITLE, "Title went back to the title");
|
|
56
|
+
t.equal(title.bestRevision, 1, "the write's answer moved the revision on, so the next best is written at 1 and not refused as stale");
|
|
57
|
+
},
|
|
58
|
+
});
|