@origingame/create-game 0.2.0 → 0.3.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 +2 -2
- package/archetypes/README.md +1 -0
- package/archetypes/arena/.origin/setup +14 -0
- package/archetypes/arena/LICENSES.md +8 -0
- package/archetypes/arena/README.md +67 -0
- package/archetypes/arena/assets/audio/coin.ogt +9 -0
- package/archetypes/arena/assets/audio/dash.ogt +9 -0
- package/archetypes/arena/assets/audio/win.ogt +9 -0
- package/archetypes/arena/assets/fx/coin.ogt +20 -0
- package/archetypes/arena/assets/looks/arena.ogt +10 -0
- package/archetypes/arena/gitattributes +22 -0
- package/archetypes/arena/gitignore +8 -0
- package/archetypes/arena/host.d.ts +46 -0
- package/archetypes/arena/package.json +18 -0
- package/archetypes/arena/project.ogt +14 -0
- package/archetypes/arena/src/game.ts +314 -0
- package/archetypes/arena/src/main.ts +100 -0
- package/archetypes/arena/tests/duel.og.ts +32 -0
- package/archetypes/arena/tests/solo.og.ts +22 -0
- package/archetypes/arena/tsconfig.json +17 -0
- package/archetypes/idle/LICENSES.md +1 -1
- package/archetypes/idle/README.md +3 -3
- package/archetypes/idle/assets/looks/idle.ogt +1 -1
- package/archetypes/idle/assets/{skins → styles}/sparkorb/LICENSES.md +4 -4
- package/archetypes/idle/assets/{skins/sparkorb/skin.ogt → styles/sparkorb/style.ogt} +47 -47
- package/archetypes/idle/package.json +1 -1
- package/archetypes/idle/project.ogt +1 -1
- 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/main.ts +2 -2
- package/archetypes/idle/src/ui.ts +11 -11
- package/archetypes/idle/tools/make-assets.py +4 -4
- package/archetypes/match3/package.json +1 -1
- package/archetypes/match3/project.ogt +1 -1
- package/archetypes/rhythm/LICENSES.md +1 -1
- package/archetypes/rhythm/README.md +3 -3
- package/archetypes/rhythm/assets/{skins → styles}/lanebeat/LICENSES.md +4 -4
- package/archetypes/rhythm/assets/{skins/lanebeat/skin.ogt → styles/lanebeat/style.ogt} +45 -45
- package/archetypes/rhythm/package.json +1 -1
- package/archetypes/rhythm/project.ogt +1 -1
- package/archetypes/rhythm/references/metal/results.png +0 -0
- package/archetypes/rhythm/references/metal/title.png +0 -0
- package/archetypes/rhythm/src/main.ts +2 -2
- package/archetypes/rhythm/src/ui.ts +11 -11
- package/archetypes/roguelike/LICENSES.md +1 -1
- package/archetypes/roguelike/README.md +3 -3
- package/archetypes/roguelike/assets/{skins → styles}/lampdive/LICENSES.md +4 -4
- package/archetypes/roguelike/assets/{skins/lampdive/skin.ogt → styles/lampdive/style.ogt} +41 -41
- package/archetypes/roguelike/package.json +1 -1
- package/archetypes/roguelike/project.ogt +1 -1
- package/archetypes/roguelike/references/metal/over.png +0 -0
- package/archetypes/roguelike/references/metal/title.png +0 -0
- package/archetypes/roguelike/src/main.ts +2 -2
- package/archetypes/roguelike/src/ui.ts +7 -7
- package/archetypes/runner/package.json +1 -1
- package/archetypes/runner/project.ogt +1 -1
- package/archetypes/third-person/LICENSES.md +1 -1
- package/archetypes/third-person/README.md +3 -3
- package/archetypes/third-person/assets/{skins → styles}/ember/LICENSES.md +2 -2
- package/archetypes/third-person/assets/{skins/ember/skin.ogt → styles/ember/style.ogt} +40 -41
- package/archetypes/third-person/package.json +1 -1
- package/archetypes/third-person/project.ogt +1 -1
- 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/main.ts +2 -2
- package/archetypes/third-person/src/ui.ts +10 -10
- package/archetypes/topdown/package.json +1 -1
- package/archetypes/topdown/project.ogt +1 -1
- package/archetypes/tower-defense/LICENSES.md +1 -1
- package/archetypes/tower-defense/README.md +5 -5
- package/archetypes/tower-defense/assets/{skins → styles}/pathguard/LICENSES.md +4 -4
- package/archetypes/tower-defense/assets/styles/pathguard/atlas.png +0 -0
- package/archetypes/tower-defense/assets/styles/pathguard/style.ogt +111 -0
- package/archetypes/tower-defense/package.json +1 -1
- package/archetypes/tower-defense/project.ogt +1 -1
- 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/main.ts +2 -2
- package/archetypes/tower-defense/src/ui.ts +19 -17
- package/bin/create.ts +11 -8
- package/looks/catalogue.json +40 -40
- package/package.json +1 -1
- package/template/README.md +2 -1
- package/template/assets/audio/sting.ogt +10 -0
- package/template/assets/timelines/intro.ogt +101 -0
- package/template/assets/timelines/narration.srt +11 -0
- package/template/host.d.ts +46 -0
- package/template/package.json +1 -1
- package/template/project.ogt +1 -1
- package/template/references/metal/intro-4.png +0 -0
- package/template/references/metal/intro-8.png +0 -0
- package/template/src/main.ts +1 -1
- package/template/tests/frames.ts +134 -0
- package/template/tests/intro.og.ts +65 -0
- package/template/tests/smoke.og.ts +30 -36
- package/template/tsconfig.json +1 -1
- package/template-2d/LICENSES.md +1 -0
- package/template-2d/README.md +5 -2
- package/template-2d/assets/rigs/keeper.ogt +292 -0
- package/template-2d/assets/rigs/keeper.png +0 -0
- package/template-2d/assets/rigs/keeper.png.ogt +7 -0
- package/template-2d/package.json +1 -1
- package/template-2d/project.ogt +1 -1
- package/template-2d/src/main.ts +159 -4
- package/template-2d/tests/keeper.og.ts +93 -0
- package/archetypes/tower-defense/assets/skins/pathguard/atlas.png +0 -0
- package/archetypes/tower-defense/assets/skins/pathguard/skin.ogt +0 -111
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/ChakraPetch-BoldItalic.ttf +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/ChakraPetch-BoldItalic.ttf.ogt +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/OFL.txt +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/Orbitron-Medium.ttf +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/Orbitron-Medium.ttf.ogt +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/Rajdhani-Bold.ttf +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/Rajdhani-Bold.ttf.ogt +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/atlas.png +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/atlas.png.ogt +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/icons.png +0 -0
- /package/archetypes/idle/assets/{skins → styles}/sparkorb/icons.png.ogt +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/ChakraPetch-Medium.ttf +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/ChakraPetch-Medium.ttf.ogt +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/JetBrainsMono-Regular.ttf +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/JetBrainsMono-Regular.ttf.ogt +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/OFL.txt +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/Orbitron-Bold.ttf +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/Orbitron-Bold.ttf.ogt +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/atlas.png +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/atlas.png.ogt +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/icons.png +0 -0
- /package/archetypes/rhythm/assets/{skins → styles}/lanebeat/icons.png.ogt +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/DotGothic16-Regular.ttf +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/DotGothic16-Regular.ttf.ogt +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/OFL.txt +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/atlas.png +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/atlas.png.ogt +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/icons.png +0 -0
- /package/archetypes/roguelike/assets/{skins → styles}/lampdive/icons.png.ogt +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/Cinzel-Bold.ttf +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/Cinzel-Bold.ttf.ogt +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/Newsreader-Medium.ttf +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/Newsreader-Medium.ttf.ogt +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/OFL.txt +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/atlas.png +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/atlas.png.ogt +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/icons.png +0 -0
- /package/archetypes/third-person/assets/{skins → styles}/ember/icons.png.ogt +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/Fredoka-SemiBold.ttf +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/Fredoka-SemiBold.ttf.ogt +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/LilitaOne-Regular.ttf +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/LilitaOne-Regular.ttf.ogt +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/OFL.txt +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/atlas.png.ogt +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/icons.png +0 -0
- /package/archetypes/tower-defense/assets/{skins → styles}/pathguard/icons.png.ogt +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Coin Duel, the arena archetype (2D profile): two players on one floor run
|
|
2
|
+
// for one coin; each touch is a point and the coin jumps somewhere else,
|
|
3
|
+
// first to five wins the round. It plays alone (the local keys drive Red)
|
|
4
|
+
// and over a room in lockstep: `og relay` and two `og run . --room
|
|
5
|
+
// ws://127.0.0.1:47900/duel` processes (or two Play pages in one platform
|
|
6
|
+
// room) each run the whole world and exchange only their inputs and the
|
|
7
|
+
// world's hash (og.net, docs/design.md §2.10).
|
|
8
|
+
//
|
|
9
|
+
// start turns og.Lockstep on for two players and spawns the two fighters,
|
|
10
|
+
// each an og.PlayerInput whose `player` is its seat, and the coin. The
|
|
11
|
+
// systems are in src/game.ts: Submit hands this peer's keys to
|
|
12
|
+
// og.net.submit, Move and CoinDrop read og.PlayerInput and og.Rng only.
|
|
13
|
+
|
|
14
|
+
import { og } from "@origingame/engine";
|
|
15
|
+
import type { Entity, World } from "@origingame/engine";
|
|
16
|
+
import { Coin, COIN, CoinDrop, Duel, facts, Feedback, Fighter, FIGHTER, HEIGHT, Hud, Move, must, setBot, Sound, Sparks, Submit, Tuning, Voice, Voices, WIDTH } from "./game.ts";
|
|
17
|
+
|
|
18
|
+
/** The brand ink #14161b, linear, behind the floor. */
|
|
19
|
+
const INK = { r: 0.00699, g: 0.00802, b: 0.01096 };
|
|
20
|
+
const FLOOR = { r: 0.022, g: 0.026, b: 0.034 };
|
|
21
|
+
const LINE = { r: 0.06, g: 0.068, b: 0.085 };
|
|
22
|
+
/** Red and Blue, linear. */
|
|
23
|
+
const INKS = [
|
|
24
|
+
{ r: 0.9, g: 0.12, b: 0.1 },
|
|
25
|
+
{ r: 0.1, g: 0.38, b: 0.95 },
|
|
26
|
+
];
|
|
27
|
+
const GOLD = { r: 1, g: 0.62, b: 0.08 };
|
|
28
|
+
|
|
29
|
+
function rect(world: World, name: string, x: number, y: number, w: number, h: number, color: { r: number; g: number; b: number }, layer: number, glow = 0): Entity {
|
|
30
|
+
const e = must(world.spawn({ name, position: { x, y, z: 0 } }));
|
|
31
|
+
must(world.insert(e, og.Sprite, { width: w, height: h, color, layer, glow }));
|
|
32
|
+
return e;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function start(world: World): void {
|
|
36
|
+
// Lockstep for two: in a room the world waits for both seats' inputs each tick.
|
|
37
|
+
const lock = must(world.resource(og.Lockstep));
|
|
38
|
+
lock.enabled = true;
|
|
39
|
+
lock.players = 2;
|
|
40
|
+
lock.inputDelay = 2;
|
|
41
|
+
lock.hashEvery = 10;
|
|
42
|
+
|
|
43
|
+
const camera = must(world.resource(og.Camera));
|
|
44
|
+
camera.orthographic = true;
|
|
45
|
+
camera.height = HEIGHT + 2;
|
|
46
|
+
camera.position = { x: WIDTH / 2, y: HEIGHT / 2, z: 50 };
|
|
47
|
+
camera.background = INK;
|
|
48
|
+
|
|
49
|
+
rect(world, "floor", WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT, FLOOR, -10);
|
|
50
|
+
rect(world, "midline", WIDTH / 2, HEIGHT / 2, 0.06, HEIGHT, LINE, -9);
|
|
51
|
+
|
|
52
|
+
for (const player of [0, 1]) {
|
|
53
|
+
const e = rect(world, `fighter-${player}`, player === 0 ? 3 : WIDTH - 3, HEIGHT / 2, FIGHTER * 2, FIGHTER * 2, INKS[player]!, 1);
|
|
54
|
+
must(world.insert(e, og.PlayerInput, { player }));
|
|
55
|
+
must(world.insert(e, Fighter, { faceX: player === 0 ? 1 : -1 }));
|
|
56
|
+
}
|
|
57
|
+
const coin = rect(world, "coin", WIDTH / 2, HEIGHT / 2, COIN * 2, COIN * 2, GOLD, 0, 0.6);
|
|
58
|
+
must(world.insert(coin, Coin));
|
|
59
|
+
|
|
60
|
+
// The feedback (src/game.ts Feedback, Voices): one voice per sound, the coin's sparks.
|
|
61
|
+
for (const [path, bit, volume] of [
|
|
62
|
+
["audio/coin.ogt", Sound.Coin, 0.7],
|
|
63
|
+
["audio/dash.ogt", Sound.Dash, 0.45],
|
|
64
|
+
["audio/win.ogt", Sound.Win, 0.8],
|
|
65
|
+
] as const) {
|
|
66
|
+
const v = must(world.spawn({ name: `sfx-${bit}` }));
|
|
67
|
+
must(world.insert(v, og.AudioSource, { sound: must(og.load.sound(world, path)), playing: false, bus: "sfx", volume, priority: 200 }));
|
|
68
|
+
must(world.insert(v, Voice, { bit }));
|
|
69
|
+
}
|
|
70
|
+
const sparks = must(world.spawn({ name: "sparks", position: { x: WIDTH / 2, y: HEIGHT / 2, z: 2 } }));
|
|
71
|
+
must(world.insert(sparks, og.ParticleSystem, { emitter: must(og.load.emitter(world, "fx/coin.ogt")), seed: 7 }));
|
|
72
|
+
must(world.insert(sparks, Sparks));
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default og.game({
|
|
77
|
+
tick: 60,
|
|
78
|
+
seed: 1,
|
|
79
|
+
look: "looks/arena.ogt",
|
|
80
|
+
resources: [Duel, Tuning],
|
|
81
|
+
systems: [Submit, Move, CoinDrop, Feedback, Voices, Hud],
|
|
82
|
+
start,
|
|
83
|
+
commands: {
|
|
84
|
+
/** `bot:<n>`: this peer's input comes from scripted bot n (0 hands it back to the keys). */
|
|
85
|
+
bot: (_world, args) => setBot(Number(args[0])),
|
|
86
|
+
/** `warp:<player>:<x>:<y>`: put a fighter there. */
|
|
87
|
+
warp: (world, args) => {
|
|
88
|
+
const e = world.find(`fighter-${Number(args[0])}`);
|
|
89
|
+
const x = Number(args[1]);
|
|
90
|
+
const y = Number(args[2]);
|
|
91
|
+
if (e === null || !Number.isFinite(x) || !Number.isFinite(y)) throw new Error("write warp:<player>:<x>:<y>");
|
|
92
|
+
must(world.set(e, og.Transform, { position: { x, y, z: 0 } }));
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
commandHelp: {
|
|
96
|
+
bot: { usage: "<n>", doc: "Drive this peer's player by scripted bot n (1, 2, ...); 0 gives it back to the keys." },
|
|
97
|
+
warp: { usage: "<player>:<x>:<y>", doc: "Put fighter 0 (Red) or 1 (Blue) at a point of the floor." },
|
|
98
|
+
},
|
|
99
|
+
facts,
|
|
100
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Two processes play one duel in lockstep through a relay (docs/design.md
|
|
2
|
+
// §2.10): each drives its own seat by a different scripted bot, and both
|
|
3
|
+
// quit on tick 600 (the steps run on the room's shared ticks), where both
|
|
4
|
+
// worlds hash the same, no og.Desync was sent, and the coin moved.
|
|
5
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
6
|
+
|
|
7
|
+
interface Duel {
|
|
8
|
+
value: { score0: number; score1: number; coins: number };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default playtest({
|
|
12
|
+
name: "two processes in one room play the same duel to tick 600",
|
|
13
|
+
commands: "0:bot:1;9.5:get:Duel:duel.json;10:quit",
|
|
14
|
+
room: { players: 2, commands: ["0:bot:1;9.5:get:Duel:duel.json;10:quit", "0:bot:2;9.5:get:Duel:duel.json;10:quit"], name: "duel" },
|
|
15
|
+
check(run, t) {
|
|
16
|
+
t.equal(run.peers.length, 1, "one peer beside the run");
|
|
17
|
+
const peer = run.peers[0]!;
|
|
18
|
+
t.equal(run.tick, 600, "the run quit on tick 600");
|
|
19
|
+
t.equal(peer.tick, 600, "the peer quit on tick 600");
|
|
20
|
+
t.ok(run.lockstep?.running === true && peer.lockstep?.running === true, "lockstep ran on both");
|
|
21
|
+
t.equal([run.lockstep?.peer, peer.lockstep?.peer].sort(), [0, 1], "the peers are 0 and 1");
|
|
22
|
+
t.equal(run.lockstep?.desync ?? null, null, "no desync on the run");
|
|
23
|
+
t.equal(peer.lockstep?.desync ?? null, null, "no desync on the peer");
|
|
24
|
+
t.ok(run.netHash.length > 0, "the run has a shared hash");
|
|
25
|
+
t.equal(peer.netHash, run.netHash, `both worlds hash ${run.netHash} at tick 600`);
|
|
26
|
+
const a = run.json<Duel>("duel.json").value;
|
|
27
|
+
const b = peer.json<Duel>("duel.json").value;
|
|
28
|
+
t.ok(a.coins > 0, `the fighters took coins (${a.coins})`);
|
|
29
|
+
// The reads ran on one tick of the room's clock: the same duel, field for field.
|
|
30
|
+
t.equal(b, a, `the peer read the same duel at 9.5 s`);
|
|
31
|
+
},
|
|
32
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Coin Duel alone (no room): the local keys drive Red. D walks it right
|
|
2
|
+
// through the coin at the centre (Red 1), Space dashes, and the HUD reads
|
|
3
|
+
// both scores. The frame at 2 s is what
|
|
4
|
+
// `og polish` reads for contrast, text size and the HUD's share.
|
|
5
|
+
import { playtest } from "@origingame/engine/playtest";
|
|
6
|
+
|
|
7
|
+
export default playtest({
|
|
8
|
+
name: "alone, the keys walk Red through the coin and dash it, and the HUD shows the scores",
|
|
9
|
+
commands: [
|
|
10
|
+
"0.2:key_down:KeyD",
|
|
11
|
+
"1.2:expect:entity:fighter-0:within:7,0,-1,16,9,1",
|
|
12
|
+
"1.2:key_up:KeyD",
|
|
13
|
+
"1.3:key_down:Space",
|
|
14
|
+
"1.4:key_up:Space",
|
|
15
|
+
"1.5:expect:entity:fighter-1:within:12.5,4,-1,13.5,5,1",
|
|
16
|
+
"2:screenshot:solo.png",
|
|
17
|
+
"2:expect:ui:text:Red 1",
|
|
18
|
+
"2:expect:ui:text:Blue 0",
|
|
19
|
+
"2:expect:ui:text:Local: Red",
|
|
20
|
+
"2.2:quit",
|
|
21
|
+
].join(";"),
|
|
22
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"types": [],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"exactOptionalPropertyTypes": true,
|
|
10
|
+
"noFallthroughCasesInSwitch": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"verbatimModuleSyntax": true,
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"noEmit": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*.ts", "tests/**/*.ts", "host.d.ts"]
|
|
17
|
+
}
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
| `assets/audio/*.ogt` | CC0 1.0 | `og sfx` presets (click, select, back, error, levelup) that `og cook` synthesises, written by the same script |
|
|
9
9
|
| `assets/strings/*.ogt` | CC0 1.0 | self-made: the English and Chinese string tables |
|
|
10
10
|
| `assets/fonts/NotoSansSC-subset.ttf` | SIL Open Font License 1.1 (`assets/fonts/OFL.txt`) | Noto Sans SC Regular, subset to Latin-1 and the characters of `assets/strings/zh-CN.ogt` by the same script from the project template's `assets/fonts/NotoSansSC-Regular-subset.ttf` |
|
|
11
|
-
| `assets/
|
|
11
|
+
| `assets/styles/sparkorb/*` | CC0 1.0 art, SIL OFL 1.1 fonts | the engine's neon style pack (`templates/styles/neon`, `assets/styles/sparkorb/LICENSES.md`) with this game's palette; `atlas.png` is the pack's atlas with its magenta frames turned violet by the same script |
|
|
12
12
|
| `references/*/*.png` | CC0 1.0 | frames of this game recorded by `tests/frames.og.ts` |
|
|
@@ -62,7 +62,7 @@ og build . --publish # dist/: the play page as it ships
|
|
|
62
62
|
fanfare; the supernova bursts 200 sparks, holds the world 10 ticks,
|
|
63
63
|
shakes and punches it.
|
|
64
64
|
- **og.ui counters on the tokens** (og-ui §2–§6, og-taste §1–§7): the
|
|
65
|
-
engine's neon pack recoloured as `assets/
|
|
65
|
+
engine's neon pack recoloured as `assets/styles/sparkorb` (the orb's gold
|
|
66
66
|
as the one accent on night violet: a burnished amber under the buttons'
|
|
67
67
|
cream labels, the bright gold `accentInk` for gold words and icons); the wallet and the rate top left, the
|
|
68
68
|
stardust (an `og.ui.counter`) and Pause top right, the four generators
|
|
@@ -171,7 +171,7 @@ pure functions, the stars come from an og.Rng stream forked by name, and
|
|
|
171
171
|
the frame's treatment and names the skin; `extends "<slug>"` there
|
|
172
172
|
starts from a style of the catalogue (og-taste §12), and the reference
|
|
173
173
|
frames are then recorded again (`OG_FX_CAPTURE=1 og test .`). The
|
|
174
|
-
skin's palette is `assets/
|
|
174
|
+
skin's palette is `assets/styles/sparkorb/style.ogt`, the art
|
|
175
175
|
`tools/make-assets.py`: `python3 tools/make-assets.py && og cook .`.
|
|
176
176
|
5. **Words and numbers**: `assets/strings/*.ogt` (a locale's `num.step`
|
|
177
177
|
and units make its big numbers); a new Chinese string needs the script
|
|
@@ -222,7 +222,7 @@ in the engine repository).
|
|
|
222
222
|
give the same bytes): the orb, the glow, the spark and the motes, the
|
|
223
223
|
emitters, the sounds and the music, the `og sfx` preset files of the UI's
|
|
224
224
|
sounds, the font subset and the skin's recoloured atlas. `LICENSES.md`
|
|
225
|
-
lists them; the skin's are in `assets/
|
|
225
|
+
lists them; the skin's are in `assets/styles/sparkorb/LICENSES.md`.
|
|
226
226
|
|
|
227
227
|
## Known limits (engine gaps, not design)
|
|
228
228
|
|
|
@@ -8,7 +8,7 @@ version 1
|
|
|
8
8
|
# and the reference frames are then recorded again (OG_FX_CAPTURE=1 og test .).
|
|
9
9
|
name "Spark Orb"
|
|
10
10
|
# The UI wears the sparkorb skin (start keeps it and adds the sounds).
|
|
11
|
-
|
|
11
|
+
ui "styles/sparkorb/style.ogt"
|
|
12
12
|
# The night and the orb are authored colour: not tone mapped, and no light
|
|
13
13
|
# from the sky.
|
|
14
14
|
RenderSettings {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Spark Orb's skin (the engine's neon style pack, recoloured): licences
|
|
2
2
|
|
|
3
|
-
The palette, the body size and the fallback font in `
|
|
3
|
+
The palette, the body size and the fallback font in `style.ogt` are this
|
|
4
4
|
game's edits by hand; `atlas.png` is the pack's atlas with its magenta
|
|
5
5
|
frames turned violet by `tools/make-assets.py`; the rest is the pack as
|
|
6
|
-
`templates/
|
|
6
|
+
`templates/styles/neon` ships it.
|
|
7
7
|
|
|
8
8
|
| File | Licence | Origin |
|
|
9
9
|
|---|---|---|
|
|
10
|
-
| `atlas.png` | CC0 1.0 | self-made by the Origin Engine authors: drawn by `templates/ui-kit/tools/make-
|
|
10
|
+
| `atlas.png` | CC0 1.0 | self-made by the Origin Engine authors: drawn by `templates/ui-kit/tools/make-styles.py` (deterministic) |
|
|
11
11
|
| `icons.png` | CC0 1.0 | self-made: the kit's 32 icons (`tools/make-assets.py`) restyled by the same script |
|
|
12
|
-
| `
|
|
12
|
+
| `style.ogt`, `*.ogt` | CC0 1.0 | written by the same script |
|
|
13
13
|
| `ChakraPetch-BoldItalic.ttf` | SIL Open Font License 1.1 (`OFL.txt`) | Chakra Petch Bold Italic (github.com/m4rc1e/Chakra-Petch); unmodified. Copyright 2018 The Chakra Petch Project Authors (https://github.com/m4rc1e/Chakra-Petch.git) |
|
|
14
14
|
| `Orbitron-Medium.ttf` | SIL Open Font License 1.1 (`OFL.txt`) | Orbitron Medium (github.com/theleagueof/orbitron); unmodified. Copyright 2018 The Orbitron Project Authors (https://github.com/theleagueof/orbitron), with Reserved Font Name: "Orbitron". |
|
|
15
15
|
| `Rajdhani-Bold.ttf` | SIL Open Font License 1.1 (`OFL.txt`) | Rajdhani Bold (Indian Type Foundry, Google Fonts); subset to Latin-1 with fontTools. Copyright (c) 2014 Indian Type Foundry (info@indiantypefoundry.com) |
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
type
|
|
1
|
+
type style
|
|
2
2
|
version 1
|
|
3
3
|
---
|
|
4
|
-
# Spark Orb's skin: the engine's neon style pack (templates/ui-kit/tools/make-
|
|
4
|
+
# Spark Orb's skin: the engine's neon style pack (templates/ui-kit/tools/make-styles.py, CC0 art,
|
|
5
5
|
# OFL fonts; LICENSES.md) with this game's palette (the orb's gold as the one accent on night
|
|
6
6
|
# violet) and its Chinese fallback font, edited by hand.
|
|
7
7
|
name "sparkorb"
|
|
8
|
-
|
|
9
|
-
atlas "
|
|
8
|
+
scheme dark
|
|
9
|
+
atlas "styles/sparkorb/atlas.png" 384 256
|
|
10
10
|
scale 1
|
|
11
11
|
palette {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
accentFg "#fff6e6"
|
|
32
|
-
accentInk "#ffc35c"
|
|
33
|
-
accentSoft "#ffb02e28"
|
|
12
|
+
backdrop "#0a0614"
|
|
13
|
+
well "#120a22"
|
|
14
|
+
panel "#1c1232"
|
|
15
|
+
panelHover "#281a46"
|
|
16
|
+
panelRaised "#1c1232"
|
|
17
|
+
line "#4a3470"
|
|
18
|
+
lineStrong "#c9a6ff"
|
|
19
|
+
ink "#fff6e6"
|
|
20
|
+
inkMuted "#e3d4bd"
|
|
21
|
+
inkFaint "#b9a890"
|
|
22
|
+
inkInverse "#140a00"
|
|
23
|
+
control "#3a2a5c"
|
|
24
|
+
controlStrong "#4a3874"
|
|
25
|
+
primary "#ad690a"
|
|
26
|
+
primaryHover "#d98f1f"
|
|
27
|
+
primaryActive "#a8650a"
|
|
28
|
+
onPrimary "#fff6e6"
|
|
29
|
+
primarySoft "#ffb02e28"
|
|
30
|
+
highlight "#ffc35c"
|
|
34
31
|
focus "#ffd27a"
|
|
35
|
-
|
|
32
|
+
knob "#5a3aa6"
|
|
33
|
+
hud "#1c1232"
|
|
36
34
|
scrim "#030008cc"
|
|
35
|
+
shadow "#000000aa"
|
|
36
|
+
sheen "#ffffff52"
|
|
37
37
|
success "#3ddc97"
|
|
38
38
|
warn "#ffd23d"
|
|
39
39
|
danger "#f45f80"
|
|
40
40
|
info "#36e8ff"
|
|
41
|
-
|
|
41
|
+
health "#3ddc97"
|
|
42
|
+
mana "#0a84ff"
|
|
43
|
+
xp "#bf5af2"
|
|
44
|
+
gold "#ad690a"
|
|
42
45
|
}
|
|
43
46
|
radius {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
panel 14
|
|
49
|
-
sheet 14
|
|
50
|
-
button 12
|
|
47
|
+
small 6
|
|
48
|
+
control 6
|
|
49
|
+
bar 6
|
|
50
|
+
panel 10
|
|
51
51
|
}
|
|
52
52
|
ramp {
|
|
53
53
|
body 16 21
|
|
@@ -68,12 +68,12 @@ durations {
|
|
|
68
68
|
slow 380
|
|
69
69
|
}
|
|
70
70
|
fonts {
|
|
71
|
-
body "
|
|
72
|
-
display "
|
|
73
|
-
numeric "
|
|
71
|
+
body "styles/sparkorb/Rajdhani-Bold.ttf"
|
|
72
|
+
display "styles/sparkorb/ChakraPetch-BoldItalic.ttf"
|
|
73
|
+
numeric "styles/sparkorb/Orbitron-Medium.ttf"
|
|
74
74
|
fallback "fonts/NotoSansSC-subset.ttf"
|
|
75
75
|
}
|
|
76
|
-
icons "
|
|
76
|
+
icons "styles/sparkorb/icons.png" 8 4 {
|
|
77
77
|
names "heart" "star" "coin" "lock" "pause" "gear" "sword" "shield" "potion" "gem" "key" "map" "bolt" "clock" "trophy" "home" "plus" "close" "check" "play" "back" "bag" "bomb" "crown" "flag" "apple" "leaf" "fire" "drop" "skull" "music" "person"
|
|
78
78
|
}
|
|
79
79
|
slice panel 4 4 96 96 22 authored
|
|
@@ -85,21 +85,21 @@ slice buttonDisabled 328 4 48 48 16 tint
|
|
|
85
85
|
slice field 4 104 48 48 10 tint
|
|
86
86
|
slice slot 56 104 48 48 12 tint
|
|
87
87
|
slice tooltip 108 104 32 32 10 tint
|
|
88
|
-
slice
|
|
88
|
+
slice hud 144 104 32 32 14 tint
|
|
89
89
|
slice track 180 104 32 16 6 tint
|
|
90
90
|
slice fill 216 104 32 16 6 tint
|
|
91
91
|
soft 252 104 64 64 24
|
|
92
|
-
corner 320 104 32 32 20 20
|
|
92
|
+
corner 320 104 32 32 20 20 primary 2
|
|
93
93
|
corners card
|
|
94
|
-
divider 4 172 128 24 128 24
|
|
95
|
-
flourish 136 172 64 24 36 16
|
|
94
|
+
divider 4 172 128 24 128 24 primary
|
|
95
|
+
flourish 136 172 64 24 36 16 primary 0
|
|
96
96
|
tile 204 172 64 64 48 48 0.12 10 panel
|
|
97
97
|
shadow panel 0 0 0 0 "#00000000"
|
|
98
|
-
glow button 6
|
|
99
|
-
glow
|
|
100
|
-
glow panel 14
|
|
98
|
+
glow button 6 primary 0.35
|
|
99
|
+
glow hud 4 primary 0.25
|
|
100
|
+
glow panel 14 primary 0.18
|
|
101
101
|
glow slot 3 focus 0.2
|
|
102
|
-
textGlow display 2.0
|
|
102
|
+
textGlow display 2.0 primary 0.7
|
|
103
103
|
textGlow numeric 1.2 focus 0.5
|
|
104
104
|
press 0.96 0.96 0
|
|
105
105
|
hover 0 1.04
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -37,9 +37,9 @@ function start(world: World): void {
|
|
|
37
37
|
for (const l of LANGUAGES) must(og.i18n.load(world, `strings/${l.code}.ogt`));
|
|
38
38
|
// GameDesc.look set the frame and loaded the skin before start; the UI
|
|
39
39
|
// keeps that skin and adds the sounds.
|
|
40
|
-
const skin = og.render.look(world)?.
|
|
40
|
+
const skin = og.render.look(world)?.style ?? null;
|
|
41
41
|
const sound = (path: string) => must(og.load.sound(world, path));
|
|
42
|
-
must(og.ui.configure(world, { skin, sounds: { press: sound("audio/ui-press.ogt"), open: sound("audio/ui-open.ogt"), close: sound("audio/ui-close.ogt"), error: sound("audio/ui-error.ogt"), success: sound("audio/ui-success.ogt") } }));
|
|
42
|
+
must(og.ui.configure(world, { style: skin, sounds: { press: sound("audio/ui-press.ogt"), open: sound("audio/ui-open.ogt"), close: sound("audio/ui-close.ogt"), error: sound("audio/ui-error.ogt"), success: sound("audio/ui-success.ogt") } }));
|
|
43
43
|
|
|
44
44
|
const camera = must(world.resource(og.Camera));
|
|
45
45
|
camera.orthographic = true;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Spark Orb's screens on og.ui and the skin in assets/
|
|
1
|
+
// Spark Orb's screens on og.ui and the skin in assets/styles/sparkorb (the
|
|
2
2
|
// engine's neon pack in the orb's gold on night violet): the title, the
|
|
3
3
|
// HUD (the sparks and their rate top left, stardust and pause top right,
|
|
4
4
|
// the four generators along the bottom, the supernova's progress), the
|
|
@@ -166,7 +166,7 @@ function platform(world: World, g: GameV, p: PrefsV): void {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
function capsule(id: string, build: () => void): void {
|
|
169
|
-
og.ui.row(id, { gap: S.xs, cross: "center", padding: { left: S.sm, top: S.xs, right: S.md, bottom: S.xs }, frame: "
|
|
169
|
+
og.ui.row(id, { gap: S.xs, cross: "center", padding: { left: S.sm, top: S.xs, right: S.md, bottom: S.xs }, frame: "hud", background: { token: "panel" } }, build);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
function hud(world: World, g: GameV): void {
|
|
@@ -176,13 +176,13 @@ function hud(world: World, g: GameV): void {
|
|
|
176
176
|
og.ui.setNavigation(false);
|
|
177
177
|
og.ui.anchor("Wallet", { anchor: "topLeft", direction: "column", gap: S.xs }, () => {
|
|
178
178
|
capsule("Sparks", () => {
|
|
179
|
-
og.ui.icon("Icon", "star", { size: 24, tint: { token: "
|
|
179
|
+
og.ui.icon("Icon", "star", { size: 24, tint: { token: "highlight" } });
|
|
180
180
|
// The sparks change every tick, so they are a label in the locale's words, not a counter
|
|
181
181
|
// (a counter re-counts from where it is on every change); counters show what jumps.
|
|
182
182
|
og.ui.label("Amount", big(world, g.sparks), { step: "xl", font: "display", nowrap: true });
|
|
183
183
|
});
|
|
184
184
|
og.ui.row("RateRow", { padding: { left: S.sm, top: 0, right: 0, bottom: 0 } }, () => {
|
|
185
|
-
og.ui.label("Rate", say(world, "hud.rate", { n: big(world, g.rate) }), { step: "body", color: { token: "
|
|
185
|
+
og.ui.label("Rate", say(world, "hud.rate", { n: big(world, g.rate) }), { step: "body", color: { token: "inkMuted" }, nowrap: true });
|
|
186
186
|
});
|
|
187
187
|
});
|
|
188
188
|
let paused = false;
|
|
@@ -213,10 +213,10 @@ function hud(world: World, g: GameV): void {
|
|
|
213
213
|
if (g.refusedSlot === i && g.refusedTick === world.tick - 1) og.ui.shake({ sound: true });
|
|
214
214
|
if (g.milestoneSlot === i && g.milestoneTick === world.tick - 1) og.ui.burst({ count: 10 });
|
|
215
215
|
og.ui.row("Head", { gap: S.xxs, cross: "center" }, () => {
|
|
216
|
-
og.ui.label("Name", say(world, `gen.${name}`), { step: "body", color: { token: g.selected === i ? "
|
|
217
|
-
og.ui.counter("Owned", n, { font: "mono", prefix: "×", color: { token: "
|
|
216
|
+
og.ui.label("Name", say(world, `gen.${name}`), { step: "body", color: { token: g.selected === i ? "highlight" : "ink" }, nowrap: true });
|
|
217
|
+
og.ui.counter("Owned", n, { font: "mono", prefix: "×", color: { token: "inkMuted" } });
|
|
218
218
|
});
|
|
219
|
-
og.ui.label("Cost", big(world, cost), { font: "mono", color: { token: can ? "
|
|
219
|
+
og.ui.label("Cost", big(world, cost), { font: "mono", color: { token: can ? "highlight" : "inkMuted" }, nowrap: true });
|
|
220
220
|
});
|
|
221
221
|
});
|
|
222
222
|
});
|
|
@@ -226,9 +226,9 @@ function hud(world: World, g: GameV): void {
|
|
|
226
226
|
og.ui.anchor("Nova", { anchor: phone ? "topRight" : "bottomRight", offsetY: phone ? 64 : 0, direction: "column", cross: "center", gap: S.xxs }, () => {
|
|
227
227
|
if (gain >= 1) {
|
|
228
228
|
if (og.ui.actionButton("Supernova", say(world, "hud.nova"), { icon: "bolt", size: 64, primary: true }).clicked) g.confirmNova = true;
|
|
229
|
-
og.ui.label("Gain", say(world, "hud.novaGain", { n: gain }), { color: { token: "
|
|
229
|
+
og.ui.label("Gain", say(world, "hud.novaGain", { n: gain }), { color: { token: "highlight" }, nowrap: true });
|
|
230
230
|
} else if (g.runEarned > 0) {
|
|
231
|
-
og.ui.label("At", say(world, "hud.novaAt", { n: big(world, novaAt(t)) }), { step: "caption", color: { token: "
|
|
231
|
+
og.ui.label("At", say(world, "hud.novaAt", { n: big(world, novaAt(t)) }), { step: "caption", color: { token: "inkMuted" }, nowrap: true });
|
|
232
232
|
og.ui.meter("Progress", Math.min(g.runEarned, novaAt(t)), novaAt(t), { width: px(phone ? 110 : 140) });
|
|
233
233
|
}
|
|
234
234
|
});
|
|
@@ -250,7 +250,7 @@ function settings(world: World, g: GameV, p: PrefsV): void {
|
|
|
250
250
|
p.master = slider("Master", "settings.master", p.master);
|
|
251
251
|
p.music = slider("Music", "settings.music", p.music);
|
|
252
252
|
p.effects = slider("Effects", "settings.effects", p.effects);
|
|
253
|
-
og.ui.label("LanguageLabel", say(world, "settings.language"), { color: { token: "
|
|
253
|
+
og.ui.label("LanguageLabel", say(world, "settings.language"), { color: { token: "inkMuted" } });
|
|
254
254
|
const r = og.ui.radio("Language", LANGUAGES.map((l) => say(world, l.key)), p.language, { horizontal: true });
|
|
255
255
|
if (r.selected !== p.language) setLanguage(world, p, r.selected);
|
|
256
256
|
p.reducedMotion = og.ui.toggle("Motion", p.reducedMotion, say(world, "settings.motion")).on;
|
|
@@ -287,7 +287,7 @@ function dialogs(world: World, g: GameV): void {
|
|
|
287
287
|
}
|
|
288
288
|
let collect = false;
|
|
289
289
|
const w = og.ui.modal("Welcome", g.welcome, { title: say(world, "welcome.title"), width }, () => {
|
|
290
|
-
og.ui.row("Mark", { width: grow, align: "center" }, () => og.ui.icon("Icon", "clock", { size: 40, tint: { token: "
|
|
290
|
+
og.ui.row("Mark", { width: grow, align: "center" }, () => og.ui.icon("Icon", "clock", { size: 40, tint: { token: "highlight" } }));
|
|
291
291
|
og.ui.label("Body", say(world, "welcome.body", { time: duration(world, g.away), n: big(world, g.offline) }), { width: grow, align: "center" });
|
|
292
292
|
og.ui.row("Actions", { width: grow, align: "center" }, () => {
|
|
293
293
|
if (og.ui.button("Collect", say(world, "welcome.collect"), { variant: "primary" }).clicked) collect = true;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
the sky's haze), spark.png (particles and the fixed stars) and
|
|
9
9
|
mote-<generator>.png (the four motes: an ember, a bolt, a crystal, a
|
|
10
10
|
star),
|
|
11
|
-
- assets/
|
|
11
|
+
- assets/styles/sparkorb/atlas.png: the neon pack's atlas
|
|
12
12
|
(templates/ui-kit) with its magenta frames turned violet,
|
|
13
13
|
- assets/fx/*.ogt: the particle emitters (the tap's burst, a milestone's
|
|
14
14
|
ring, the supernova, the sparks drifting up from the orb, the stars),
|
|
@@ -275,7 +275,7 @@ render sprite 0
|
|
|
275
275
|
# ── the skin's atlas ───────────────────────────────────────────────────────
|
|
276
276
|
|
|
277
277
|
def read_png(path):
|
|
278
|
-
"""An 8-bit RGBA, non-interlaced PNG's rows of pixels (what make-
|
|
278
|
+
"""An 8-bit RGBA, non-interlaced PNG's rows of pixels (what make-styles.py writes)."""
|
|
279
279
|
data = open(path, "rb").read()
|
|
280
280
|
at, idat, w, h = 8, b"", 0, 0
|
|
281
281
|
while at < len(data):
|
|
@@ -315,7 +315,7 @@ def read_png(path):
|
|
|
315
315
|
def atlas():
|
|
316
316
|
"""The neon pack's atlas with its baked magenta frames turned to the
|
|
317
317
|
night's violet (hue 300 to 262), the rest untouched."""
|
|
318
|
-
src = os.path.join(root, "..", "..", "
|
|
318
|
+
src = os.path.join(root, "..", "..", "styles", "neon", "atlas.png")
|
|
319
319
|
if not os.path.exists(src):
|
|
320
320
|
print("atlas recolour skipped (no templates/ui-kit here); the committed atlas stays")
|
|
321
321
|
return None
|
|
@@ -434,7 +434,7 @@ def main():
|
|
|
434
434
|
write(f"sprites/mote-{kind}.png.ogt", LINEAR)
|
|
435
435
|
recoloured = atlas()
|
|
436
436
|
if recoloured is not None:
|
|
437
|
-
write("
|
|
437
|
+
write("styles/sparkorb/atlas.png", recoloured)
|
|
438
438
|
write("fx/tap.ogt", TAP)
|
|
439
439
|
write("fx/milestone.ogt", MILESTONE)
|
|
440
440
|
write("fx/nova.ogt", NOVA)
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
| `assets/fx/*.ogt` | CC0 1.0 | self-made: the hit's burst, same script |
|
|
10
10
|
| `assets/strings/*.ogt` | CC0 1.0 | self-made: the English and Chinese string tables |
|
|
11
11
|
| `assets/fonts/NotoSansSC-subset.ttf` | SIL Open Font License 1.1 (`assets/fonts/OFL.txt`) | Noto Sans SC Regular, subset to Latin-1 and the characters of `assets/strings/zh-CN.ogt` by the same script from the project template's `assets/fonts/NotoSansSC-Regular-subset.ttf` |
|
|
12
|
-
| `assets/
|
|
12
|
+
| `assets/styles/lanebeat/*` | CC0 1.0 art, SIL OFL 1.1 fonts | the engine's sci-fi style pack (`templates/styles/scifi`, `assets/styles/lanebeat/LICENSES.md`) with this game's palette |
|
|
13
13
|
| `references/*/*.png` | CC0 1.0 | frames of this game recorded by `tests/frames.og.ts` |
|
|
@@ -71,7 +71,7 @@ og build . --publish # dist/: the play page as it ships
|
|
|
71
71
|
with reduced motion). There is no hit stop: it would hold the picture
|
|
72
72
|
while the music runs on.
|
|
73
73
|
- **Screens on og.ui with a skin** (og-ui §2–§6, og-taste §1–§7): the
|
|
74
|
-
engine's sci-fi pack recoloured as `assets/
|
|
74
|
+
engine's sci-fi pack recoloured as `assets/styles/lanebeat`; the title
|
|
75
75
|
(Play, Calibrate, Settings), the HUD (the score as an `og.ui.counter`
|
|
76
76
|
and the groove top left, Pause top right, the combo beside the
|
|
77
77
|
highway), `og.ui.pauseMenu` (Resume, Restart, Settings, Title), the
|
|
@@ -169,7 +169,7 @@ og.music (before og.audio) writes the clock and sends og.MusicBeat.
|
|
|
169
169
|
bar-aligned) and `partsAt` in `src/systems.ts`, which says which stem
|
|
170
170
|
starts on which bar.
|
|
171
171
|
3. **The difficulty**: the windows, the scroll and the groove in `Tuning`.
|
|
172
|
-
4. **The look**: `assets/
|
|
172
|
+
4. **The look**: `assets/styles/lanebeat/style.ogt`'s palette, the lanes'
|
|
173
173
|
colours (`LANE_COLOURS`) and the art in `tools/make-assets.py`.
|
|
174
174
|
5. **Words**: `assets/strings/*.ogt`; a new Chinese string needs the
|
|
175
175
|
script run again to subset the font.
|
|
@@ -222,7 +222,7 @@ give the same bytes): the chart and the stems from one set of note lists,
|
|
|
222
222
|
the click, the taps, the miss, the clear and the fail, the note, the ring,
|
|
223
223
|
the lane's glow, the spark, the hit's burst, the `og sfx` preset files of
|
|
224
224
|
the UI's sounds and the font subset. `LICENSES.md` lists them; the skin's
|
|
225
|
-
are in `assets/
|
|
225
|
+
are in `assets/styles/lanebeat/LICENSES.md`.
|
|
226
226
|
|
|
227
227
|
## Known limits (engine gaps, not design)
|
|
228
228
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Three-Lane Beat's skin (the engine's sci-fi style pack, recoloured): licences
|
|
2
2
|
|
|
3
|
-
The palette, the body sizes and the fallback font in `
|
|
4
|
-
game's edits by hand; the rest is the pack as `templates/
|
|
3
|
+
The palette, the body sizes and the fallback font in `style.ogt` are this
|
|
4
|
+
game's edits by hand; the rest is the pack as `templates/styles/scifi` ships it.
|
|
5
5
|
|
|
6
6
|
| File | Licence | Origin |
|
|
7
7
|
|---|---|---|
|
|
8
|
-
| `atlas.png` | CC0 1.0 | self-made by the Origin Engine authors: drawn by `templates/ui-kit/tools/make-
|
|
8
|
+
| `atlas.png` | CC0 1.0 | self-made by the Origin Engine authors: drawn by `templates/ui-kit/tools/make-styles.py` (deterministic) |
|
|
9
9
|
| `icons.png` | CC0 1.0 | self-made: the kit's 32 icons (`tools/make-assets.py`) restyled by the same script |
|
|
10
|
-
| `
|
|
10
|
+
| `style.ogt`, `*.ogt` | CC0 1.0 | written by the same script |
|
|
11
11
|
| `ChakraPetch-Medium.ttf` | SIL Open Font License 1.1 (`OFL.txt`) | Chakra Petch Medium (github.com/m4rc1e/Chakra-Petch); unmodified. Copyright 2018 The Chakra Petch Project Authors (https://github.com/m4rc1e/Chakra-Petch.git) |
|
|
12
12
|
| `JetBrainsMono-Regular.ttf` | SIL Open Font License 1.1 (`OFL.txt`) | JetBrains Mono (github.com/JetBrains/JetBrainsMono); unmodified. Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) |
|
|
13
13
|
| `Orbitron-Bold.ttf` | SIL Open Font License 1.1 (`OFL.txt`) | Orbitron Bold (github.com/theleagueof/orbitron); unmodified. Copyright 2018 The Orbitron Project Authors (https://github.com/theleagueof/orbitron), with Reserved Font Name: "Orbitron". |
|