@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,62 @@
|
|
|
1
|
+
// The win and the replay: the four beacons lit end the run at dawn; after
|
|
2
|
+
// a beat the summary says so with the time, the beacons and the best. Meanwhile
|
|
3
|
+
// another device wrote the record, so the end's write is refused as stale,
|
|
4
|
+
// read again and merged (the other device's runs, its wins plus this one,
|
|
5
|
+
// the better best) and written at the new revision; the end goes out as a
|
|
6
|
+
// `run.over` event. Again starts a second run from nothing: hearts full,
|
|
7
|
+
// the beacons dark, the clock back at half past three.
|
|
8
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
9
|
+
import { DAWN, game, OVER, PLAY, type PlatformDump, SUMMARY_READY, tap, texts, value } from "./lib.ts";
|
|
10
|
+
|
|
11
|
+
const OVER_AT = 2.1;
|
|
12
|
+
|
|
13
|
+
export default playtest({
|
|
14
|
+
name: "four beacons lit: dawn, a merged record, the summary, then Again from nothing",
|
|
15
|
+
commands: [
|
|
16
|
+
"0.3:run",
|
|
17
|
+
"0.6:stale_record",
|
|
18
|
+
"0.7:light:0",
|
|
19
|
+
"0.8:light:1",
|
|
20
|
+
"0.9:light:2",
|
|
21
|
+
"0.95:get:Game:three.json",
|
|
22
|
+
"1.0:light:3",
|
|
23
|
+
"1.05:get:Game:dawn.json",
|
|
24
|
+
`${OVER_AT + 0.6}:get:Game:over.json`,
|
|
25
|
+
`${OVER_AT + 0.6}:dump_platform:platform.json`,
|
|
26
|
+
`${OVER_AT + 1.2}:dump_ui:summary.json`,
|
|
27
|
+
tap("Again", OVER_AT + SUMMARY_READY + 0.1),
|
|
28
|
+
`${OVER_AT + SUMMARY_READY + 0.5}:get:Game:again.json`,
|
|
29
|
+
`${OVER_AT + SUMMARY_READY + 0.5}:get:beacon-2.Beacon:beacon.json`,
|
|
30
|
+
`${OVER_AT + SUMMARY_READY + 0.6}:quit`,
|
|
31
|
+
].join(";"),
|
|
32
|
+
check(run, t) {
|
|
33
|
+
t.equal(run.warnings.join("; "), "", "the script ran without warnings");
|
|
34
|
+
const three = game(run, "three.json");
|
|
35
|
+
t.ok(three.phase === PLAY && three.lit === 3, "three beacons lit, the run goes on");
|
|
36
|
+
const dawn = game(run, "dawn.json");
|
|
37
|
+
t.ok(dawn.lit === 4 && dawn.litMask === 15 && dawn.ending === DAWN, "the fourth brings the dawn");
|
|
38
|
+
t.equal(dawn.phase, PLAY, "the summary waits a beat");
|
|
39
|
+
const over = game(run, "over.json");
|
|
40
|
+
t.equal(over.phase, OVER, "then the run is over");
|
|
41
|
+
t.equal(over.recordConflicts, 1, "the record write was refused once as stale");
|
|
42
|
+
t.ok(over.runs === 9 && over.wins === 4, `and merged: the other device's 9 runs and 3 wins, plus this win (${over.runs}, ${over.wins})`);
|
|
43
|
+
t.ok(over.best > 0 && over.best < 2 && over.newBest, `this run's time is the best (${over.best.toFixed(2)} s, not the other device's 200 s)`);
|
|
44
|
+
const p = run.json<PlatformDump>("platform.json");
|
|
45
|
+
const writes = p.calls.filter((c) => c.method === "store.set" && c.args["key"] === "record");
|
|
46
|
+
const last = writes[writes.length - 1];
|
|
47
|
+
const merged = last?.args["value"] as { runs: number; wins: number; best: number } | undefined;
|
|
48
|
+
t.ok(merged?.runs === 9 && merged.wins === 4 && Math.abs(merged.best - over.best) < 1e-3, `the merge was written (${JSON.stringify(merged)})`);
|
|
49
|
+
t.equal(last?.result?.ok, true, "at the revision read again");
|
|
50
|
+
const event = p.calls.find((c) => c.method === "telemetry" && c.args["name"] === "run.over");
|
|
51
|
+
t.ok(event !== undefined, "the end went out as a run.over event");
|
|
52
|
+
const words = texts(run, "summary.json");
|
|
53
|
+
t.ok(words.includes("Dawn will find the vale lit"), "the summary shows the win");
|
|
54
|
+
t.ok(words.includes("4/4") && words.some((w) => w.endsWith(" ★")), "four beacons and a new best time");
|
|
55
|
+
t.ok(words.includes("Runs 9 · beacons all lit 4"), "and the merged record");
|
|
56
|
+
const again = game(run, "again.json");
|
|
57
|
+
t.equal(again.phase, PLAY, "Again started a run");
|
|
58
|
+
t.ok(again.runs === 10 && again.hearts === 3 && again.lit === 0 && again.ending === 0, "the tenth, from nothing: hearts full, no beacon lit");
|
|
59
|
+
t.ok(again.hour < 15.6, "the clock back at half past three");
|
|
60
|
+
t.equal(value<{ lit: boolean }>(run, "beacon.json").lit, false, "the beacons dark again");
|
|
61
|
+
},
|
|
62
|
+
});
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Regenerates Ember Vale's self-made assets (CC0), byte for byte:
|
|
3
|
+
|
|
4
|
+
python3 tools/make-assets.py # from the archetype directory
|
|
5
|
+
|
|
6
|
+
- assets/terrain/vale.png: a 129 x 129 16-bit grey heightmap of the 128 m
|
|
7
|
+
vale (one sample a metre; black -4 m, white 20 m, as terrain/vale.ogt
|
|
8
|
+
says): rolling meadow, a lake in the middle (og.Water at y 1 fills it),
|
|
9
|
+
a knoll under each of the four beacons and a ring of cliffs round it all.
|
|
10
|
+
- assets/terrain/vale-control.png: its 256 x 256 RGBA control map: grass in
|
|
11
|
+
R (except on the paths), the paths in G (a ring round the lake through the
|
|
12
|
+
four beacons and a spur from the south where the lamplighter starts), rock
|
|
13
|
+
in B and sand in A (both everywhere: their slope and altitude rules place
|
|
14
|
+
them).
|
|
15
|
+
- assets/audio/*.wav: the beacon's ignition, the sentinel's alarm and grab,
|
|
16
|
+
the splash, the dawn and the night stingers, and the vale's music loop;
|
|
17
|
+
assets/audio/*.ogt: og sfx presets for the interface and the footsteps.
|
|
18
|
+
- assets/fonts/NotoSansSC-subset.ttf + .ogt: Noto Sans SC subset to the
|
|
19
|
+
characters of assets/strings/zh-CN.ogt (needs fontTools and the project
|
|
20
|
+
template's font). When either is missing both stay as committed, and the
|
|
21
|
+
script fails naming any character of assets/strings/*.ogt the committed
|
|
22
|
+
font has no glyph for.
|
|
23
|
+
|
|
24
|
+
Standard library only except the font subset; deterministic.
|
|
25
|
+
"""
|
|
26
|
+
import math, os, struct, sys, zlib
|
|
27
|
+
|
|
28
|
+
here = os.path.dirname(os.path.abspath(__file__))
|
|
29
|
+
sys.path.insert(0, here)
|
|
30
|
+
from oglite import png_bytes, write_wav, tone, noise, mix, concat, subset_font # noqa: E402
|
|
31
|
+
|
|
32
|
+
root = os.path.dirname(here)
|
|
33
|
+
assets = os.path.join(root, "assets")
|
|
34
|
+
|
|
35
|
+
# The vale: keep these in step with src/world.ts (BEACONS, LAKE, WATER_Y, START).
|
|
36
|
+
LOW, HIGH = -4.0, 20.0
|
|
37
|
+
N = 129 # samples per side, one a metre
|
|
38
|
+
HALF = (N - 1) / 2
|
|
39
|
+
LAKE = (0.0, -6.0)
|
|
40
|
+
BEACONS = [(-34.0, -30.0), (34.0, -32.0), (36.0, 26.0), (-36.0, 24.0)]
|
|
41
|
+
RING = 31.0 # the path's radius round the lake's centre
|
|
42
|
+
START_Z = 36.0
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def write(path, data):
|
|
46
|
+
path = os.path.join(assets, path)
|
|
47
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
48
|
+
with open(path, "wb" if isinstance(data, bytes) else "w") as f:
|
|
49
|
+
f.write(data)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ── noise ──────────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
def hash01(x, y, s=0):
|
|
55
|
+
h = (x * 374761393 + y * 668265263 + s * 2147483647) & 0xFFFFFFFF
|
|
56
|
+
h = ((h ^ (h >> 13)) * 1274126177) & 0xFFFFFFFF
|
|
57
|
+
return (h ^ (h >> 16)) / 0xFFFFFFFF
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def smooth(t):
|
|
61
|
+
return t * t * (3 - 2 * t)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def value(x, y, s):
|
|
65
|
+
xi, yi = math.floor(x), math.floor(y)
|
|
66
|
+
fx, fy = smooth(x - xi), smooth(y - yi)
|
|
67
|
+
a, b = hash01(xi, yi, s), hash01(xi + 1, yi, s)
|
|
68
|
+
c, d = hash01(xi, yi + 1, s), hash01(xi + 1, yi + 1, s)
|
|
69
|
+
return a + (b - a) * fx + (c - a) * fy + (a - b - c + d) * fx * fy
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def fbm(x, y, s, octaves=4):
|
|
73
|
+
total, amp, norm = 0.0, 1.0, 0.0
|
|
74
|
+
for o in range(octaves):
|
|
75
|
+
total += amp * value(x * (1 << o), y * (1 << o), s + o * 17)
|
|
76
|
+
norm += amp
|
|
77
|
+
amp *= 0.5
|
|
78
|
+
return total / norm
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def gauss(x, z, cx, cz, r):
|
|
82
|
+
return math.exp(-((x - cx) ** 2 + (z - cz) ** 2) / (2 * r * r))
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def step(a, b, t):
|
|
86
|
+
return smooth(max(0.0, min(1.0, (t - a) / (b - a))))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# ── the terrain ────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
def height(x, z):
|
|
92
|
+
"""Metres at local (x, z), the terrain's centre at 0."""
|
|
93
|
+
h = 3.2 + 2.4 * (fbm(x / 40 + 3.1, z / 40 + 7.3, 1) - 0.5)
|
|
94
|
+
ridge = 1 - abs(2 * fbm(x / 18, z / 18, 5) - 1)
|
|
95
|
+
h += 15 * step(44, 62, max(abs(x), abs(z))) * (0.7 + 0.5 * ridge)
|
|
96
|
+
h -= 3.4 * gauss(x, z, LAKE[0], LAKE[1], 14)
|
|
97
|
+
for bx, bz in BEACONS:
|
|
98
|
+
h += 2.6 * gauss(x, z, bx, bz, 5)
|
|
99
|
+
return h
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def path(x, z):
|
|
103
|
+
"""How much of a path is at (x, z): the ring round the lake and the spur from the south."""
|
|
104
|
+
d = abs(math.hypot(x - LAKE[0], z - LAKE[1]) - RING)
|
|
105
|
+
ring = max(0.0, 1 - d / 1.4)
|
|
106
|
+
spur = max(0.0, 1 - abs(x - 1.5 * math.sin(z / 7)) / 1.2) * step(RING + LAKE[1] - 2, RING + LAKE[1] + 1, z) * (1 - step(START_Z + 2, START_Z + 5, z))
|
|
107
|
+
return max(ring, spur)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def png16_grey(w, h, rows):
|
|
111
|
+
raw = b"".join(b"\x00" + struct.pack(f">{w}H", *r) for r in rows)
|
|
112
|
+
|
|
113
|
+
def chunk(t, d):
|
|
114
|
+
return struct.pack(">I", len(d)) + t + d + struct.pack(">I", zlib.crc32(t + d) & 0xFFFFFFFF)
|
|
115
|
+
|
|
116
|
+
return (b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 16, 0, 0, 0, 0))
|
|
117
|
+
+ chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b""))
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def terrain():
|
|
121
|
+
rows = []
|
|
122
|
+
for r in range(N):
|
|
123
|
+
rows.append([max(0, min(65535, round((height(c - HALF, r - HALF) - LOW) / (HIGH - LOW) * 65535))) for c in range(N)])
|
|
124
|
+
write("terrain/vale.png", png16_grey(N, N, rows))
|
|
125
|
+
M = 256
|
|
126
|
+
rows = []
|
|
127
|
+
for r in range(M):
|
|
128
|
+
row = bytearray()
|
|
129
|
+
for c in range(M):
|
|
130
|
+
x = (c + 0.5) / M * (N - 1) - HALF
|
|
131
|
+
z = (r + 0.5) / M * (N - 1) - HALF
|
|
132
|
+
p = path(x, z)
|
|
133
|
+
row += bytes([round(255 * (1 - p)), round(255 * p), 255, 255])
|
|
134
|
+
rows.append(bytes(row))
|
|
135
|
+
write("terrain/vale-control.png", png_bytes(M, M, rows))
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# ── sounds ─────────────────────────────────────────────────────────────────
|
|
139
|
+
|
|
140
|
+
RATE = 22050
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def music():
|
|
144
|
+
"""Eight bars at 72 BPM in A minor: a soft drone, a plucked ostinato and a high answer, looped seamlessly."""
|
|
145
|
+
beat = 60 / 72
|
|
146
|
+
total = int(32 * beat * RATE)
|
|
147
|
+
out = [0.0] * total
|
|
148
|
+
for i in range(total):
|
|
149
|
+
t = i / RATE
|
|
150
|
+
swell = 0.6 + 0.4 * math.sin(2 * math.pi * t / (16 * beat))
|
|
151
|
+
out[i] += 0.045 * swell * (math.sin(2 * math.pi * 110.0 * t) + 0.5 * math.sin(2 * math.pi * 164.81 * t))
|
|
152
|
+
pluck = [220.0, 261.63, 329.63, 261.63, 196.0, 246.94, 293.66, 246.94]
|
|
153
|
+
for b in range(32):
|
|
154
|
+
f = pluck[b % 8]
|
|
155
|
+
s0 = int(b * beat * RATE)
|
|
156
|
+
for i in range(int(beat * RATE)):
|
|
157
|
+
t = i / RATE
|
|
158
|
+
out[(s0 + i) % total] += 0.05 * math.exp(-t / 0.25) * (math.sin(2 * math.pi * f * t) + 0.3 * math.sin(2 * math.pi * 2 * f * t))
|
|
159
|
+
answer = [(4, 659.25), (6, 587.33), (12, 523.25), (14, 493.88), (20, 659.25), (22, 783.99), (28, 659.25), (30, 587.33)]
|
|
160
|
+
for b, f in answer:
|
|
161
|
+
s0 = int(b * beat * RATE)
|
|
162
|
+
for i in range(int(2 * beat * RATE)):
|
|
163
|
+
t = i / RATE
|
|
164
|
+
out[(s0 + i) % total] += 0.05 * math.exp(-t / 0.9) * (math.sin(2 * math.pi * f * t) + 0.35 * math.sin(2 * math.pi * f * 2.76 * t))
|
|
165
|
+
return out
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def sounds():
|
|
169
|
+
a = os.path.join(assets, "audio")
|
|
170
|
+
os.makedirs(a, exist_ok=True)
|
|
171
|
+
w = lambda name, s: write_wav(os.path.join(a, name), s) # noqa: E731
|
|
172
|
+
w("ignite.wav", mix(noise(0.9, decay=0.35, gain=0.35, seed=7), tone(0.9, 180, 420, shape="tri", decay=0.4, gain=0.35)))
|
|
173
|
+
w("alarm.wav", concat(tone(0.12, 220, 330, shape="square", decay=0.08, gain=0.25), tone(0.3, 330, 165, shape="square", decay=0.15, gain=0.25)))
|
|
174
|
+
w("grab.wav", mix(tone(0.4, 140, 60, shape="square", decay=0.15, gain=0.35), noise(0.3, decay=0.08, gain=0.35, seed=11)))
|
|
175
|
+
w("splash.wav", mix(noise(0.5, decay=0.14, gain=0.4, seed=5), tone(0.2, 600, 200, shape="sine", decay=0.06, gain=0.15)))
|
|
176
|
+
w("jump.wav", tone(0.12, 300, 520, shape="tri", decay=0.06, gain=0.3))
|
|
177
|
+
w("dawn.wav", concat(*[tone(0.16, f, shape="tri", gain=0.4, decay=0.14) for f in (440.0, 523.25, 659.25, 783.99)], tone(0.9, 880.0, shape="tri", gain=0.4, decay=0.5)))
|
|
178
|
+
w("night.wav", concat(*[tone(0.3, f, shape="tri", gain=0.4, decay=0.22) for f in (329.63, 293.66, 246.94)], tone(1.0, 220.0, shape="tri", gain=0.4, decay=0.5)))
|
|
179
|
+
w("vale.wav", music())
|
|
180
|
+
presets = {"ui-press": "click", "ui-open": "select", "ui-close": "back", "ui-error": "error", "ui-success": "levelup", "step": "footstep"}
|
|
181
|
+
for name, preset in presets.items():
|
|
182
|
+
write(f"audio/{name}.ogt", f'type sfx\nversion 1\n---\n# og sfx\'s "{preset}" preset, synthesised by og cook.\npreset "{preset}"\nseed 0\npitch 1\nlength 1\nvolume 0.8\n')
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# ── the font ───────────────────────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
# ── the sentinels ──────────────────────────────────────────────────────────
|
|
188
|
+
|
|
189
|
+
# Each sentinel's patrol round the lake's path (keep in step with
|
|
190
|
+
# src/sentinels.ts SENTINELS, which spawns them at the first point).
|
|
191
|
+
ROUTES = {
|
|
192
|
+
"west": [(-27.0, 12.0), (-31.0, -6.0), (-27.0, -22.0)],
|
|
193
|
+
"north": [(-20.0, -31.0), (0.0, -37.0), (20.0, -31.0)],
|
|
194
|
+
"east": [(27.0, -22.0), (31.0, -6.0), (27.0, 12.0)],
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def behaviours():
|
|
199
|
+
for name, route in ROUTES.items():
|
|
200
|
+
points = "".join(f" point {x:g} {height(x, z):.2f} {z:g}\n" for x, z in route)
|
|
201
|
+
write(f"ai/sentinel-{name}.ogt", f"""type behaviour
|
|
202
|
+
version 1
|
|
203
|
+
---
|
|
204
|
+
# The {name} sentinel (og.ai; generated by tools/make-assets.py, which keeps
|
|
205
|
+
# the route on the terrain). It walks its round of the lake's path; when it
|
|
206
|
+
# sees the hero (og.Perception: within its sight, in its cone, not
|
|
207
|
+
# behind the terrain) it calls the alarm and chases, grabs within reach
|
|
208
|
+
# (the game's `grab` costs a heart and throws the hero back), stands
|
|
209
|
+
# stunned a moment, and searches where it last saw the hero before going
|
|
210
|
+
# back to its round. The hero wading in the lake is out of its reach: the
|
|
211
|
+
# navmesh stops at the shore.
|
|
212
|
+
name "sentinel-{name}"
|
|
213
|
+
route post {{
|
|
214
|
+
{points}}}
|
|
215
|
+
machine {{
|
|
216
|
+
initial patrol
|
|
217
|
+
state patrol {{
|
|
218
|
+
patrol post {{
|
|
219
|
+
wait 1.5
|
|
220
|
+
speed Tuning.patrolSpeed
|
|
221
|
+
}}
|
|
222
|
+
to alert {{
|
|
223
|
+
check sees
|
|
224
|
+
check Game.phase is 1
|
|
225
|
+
}}
|
|
226
|
+
}}
|
|
227
|
+
state alert {{
|
|
228
|
+
enter {{
|
|
229
|
+
command alarm
|
|
230
|
+
}}
|
|
231
|
+
chase {{
|
|
232
|
+
speed Tuning.chaseSpeed
|
|
233
|
+
reach 1.1
|
|
234
|
+
}}
|
|
235
|
+
to grab {{
|
|
236
|
+
check targetDistance below 1.5
|
|
237
|
+
}}
|
|
238
|
+
to search {{
|
|
239
|
+
check sees is false
|
|
240
|
+
}}
|
|
241
|
+
to patrol {{
|
|
242
|
+
check Game.phase not 1
|
|
243
|
+
}}
|
|
244
|
+
}}
|
|
245
|
+
state grab {{
|
|
246
|
+
enter {{
|
|
247
|
+
command grab
|
|
248
|
+
}}
|
|
249
|
+
stop
|
|
250
|
+
to search {{
|
|
251
|
+
after 1.6
|
|
252
|
+
}}
|
|
253
|
+
}}
|
|
254
|
+
state search {{
|
|
255
|
+
move_to lastSeen {{
|
|
256
|
+
speed Tuning.patrolSpeed
|
|
257
|
+
}}
|
|
258
|
+
to alert {{
|
|
259
|
+
check sees
|
|
260
|
+
check Game.phase is 1
|
|
261
|
+
}}
|
|
262
|
+
to patrol {{
|
|
263
|
+
after 4
|
|
264
|
+
}}
|
|
265
|
+
}}
|
|
266
|
+
}}
|
|
267
|
+
""")
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def cmap_chars(path):
|
|
271
|
+
"""The code points a TTF's cmap maps (formats 4 and 12; standard library only)."""
|
|
272
|
+
data = open(path, "rb").read()
|
|
273
|
+
tables = {}
|
|
274
|
+
for i in range(struct.unpack(">H", data[4:6])[0]):
|
|
275
|
+
tag, _, offset, _ = struct.unpack(">4sIII", data[12 + 16 * i:28 + 16 * i])
|
|
276
|
+
tables[tag] = offset
|
|
277
|
+
if b"cmap" not in tables:
|
|
278
|
+
sys.exit(f"{path} has no cmap table")
|
|
279
|
+
cmap = tables[b"cmap"]
|
|
280
|
+
found = set()
|
|
281
|
+
for i in range(struct.unpack(">H", data[cmap + 2:cmap + 4])[0]):
|
|
282
|
+
_, _, sub = struct.unpack(">HHI", data[cmap + 4 + 8 * i:cmap + 12 + 8 * i])
|
|
283
|
+
at = cmap + sub
|
|
284
|
+
fmt = struct.unpack(">H", data[at:at + 2])[0]
|
|
285
|
+
if fmt == 4:
|
|
286
|
+
segs = struct.unpack(">H", data[at + 6:at + 8])[0] // 2
|
|
287
|
+
ends = struct.unpack(f">{segs}H", data[at + 14:at + 14 + 2 * segs])
|
|
288
|
+
base = at + 16 + 2 * segs
|
|
289
|
+
starts = struct.unpack(f">{segs}H", data[base:base + 2 * segs])
|
|
290
|
+
deltas = struct.unpack(f">{segs}h", data[base + 2 * segs:base + 4 * segs])
|
|
291
|
+
ranges_at = base + 4 * segs
|
|
292
|
+
ranges = struct.unpack(f">{segs}H", data[ranges_at:ranges_at + 2 * segs])
|
|
293
|
+
for k in range(segs):
|
|
294
|
+
for c in range(starts[k], ends[k] + 1):
|
|
295
|
+
if c == 0xFFFF:
|
|
296
|
+
continue
|
|
297
|
+
if ranges[k] == 0:
|
|
298
|
+
glyph = (c + deltas[k]) & 0xFFFF
|
|
299
|
+
else:
|
|
300
|
+
g_at = ranges_at + 2 * k + ranges[k] + 2 * (c - starts[k])
|
|
301
|
+
glyph = struct.unpack(">H", data[g_at:g_at + 2])[0]
|
|
302
|
+
glyph = (glyph + deltas[k]) & 0xFFFF if glyph else 0
|
|
303
|
+
if glyph:
|
|
304
|
+
found.add(c)
|
|
305
|
+
elif fmt == 12:
|
|
306
|
+
groups = struct.unpack(">I", data[at + 12:at + 16])[0]
|
|
307
|
+
for k in range(groups):
|
|
308
|
+
first, last, glyph = struct.unpack(">III", data[at + 16 + 12 * k:at + 28 + 12 * k])
|
|
309
|
+
found.update(c for c in range(first, last + 1) if glyph + c - first)
|
|
310
|
+
return found
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def font():
|
|
314
|
+
text = open(os.path.join(assets, "strings", "zh-CN.ogt"), encoding="utf-8").read()
|
|
315
|
+
# And the star the summary draws after a new best (src/ui.ts), which the
|
|
316
|
+
# charset does not hold: it was a missing glyph until og-ui warned.
|
|
317
|
+
chars = "".join(sorted({ch for ch in text if ord(ch) > 0x2E7F} | {"★"}))
|
|
318
|
+
src = os.path.join(root, "..", "..", "game", "assets", "fonts", "NotoSansSC-Regular-subset.ttf")
|
|
319
|
+
dst = os.path.join(assets, "fonts", "NotoSansSC-subset.ttf")
|
|
320
|
+
try:
|
|
321
|
+
subset_font(src, dst, chars)
|
|
322
|
+
except ImportError:
|
|
323
|
+
print("font subset skipped: fontTools is not installed (pip install fonttools); checking the committed font")
|
|
324
|
+
except FileNotFoundError:
|
|
325
|
+
print(f"font subset skipped: no source font at {os.path.normpath(src)}; checking the committed font")
|
|
326
|
+
else:
|
|
327
|
+
write("fonts/NotoSansSC-subset.ttf.ogt", "type import\nversion 1\n---\n"
|
|
328
|
+
"# Latin-1, CJK punctuation and every character of assets/strings/zh-CN.ogt (tools/make-assets.py).\n"
|
|
329
|
+
f'font {{\n charset latin cjk-punct\n chars "{chars}"\n em_px 32\n px_range 4\n}}\n')
|
|
330
|
+
return
|
|
331
|
+
# Not subset: the committed font must already draw every CJK character the strings use.
|
|
332
|
+
strings = os.path.join(assets, "strings")
|
|
333
|
+
need = set()
|
|
334
|
+
for name in sorted(os.listdir(strings)):
|
|
335
|
+
if name.endswith(".ogt"):
|
|
336
|
+
need.update(ch for ch in open(os.path.join(strings, name), encoding="utf-8").read() if ord(ch) > 0x2E7F)
|
|
337
|
+
have = cmap_chars(dst)
|
|
338
|
+
missing = "".join(sorted(ch for ch in need if ord(ch) not in have))
|
|
339
|
+
if missing:
|
|
340
|
+
sys.exit(f"{os.path.relpath(dst, root)} has no glyph for {missing} (used in assets/strings); "
|
|
341
|
+
"install fontTools and the project template's font and run tools/make-assets.py again")
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def main():
|
|
345
|
+
terrain()
|
|
346
|
+
sounds()
|
|
347
|
+
behaviours()
|
|
348
|
+
if os.path.exists(os.path.join(assets, "strings", "zh-CN.ogt")):
|
|
349
|
+
font()
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
if __name__ == "__main__":
|
|
353
|
+
main()
|