summaryrefslogtreecommitdiff
path: root/2026/framing
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-08-04 04:35:44 -0400
committerLLLL Colonq <llll@colonq>2026-08-04 04:35:44 -0400
commit3c7796f066647090ed8436778bdfe25f11844c05 (patch)
tree0644a101004d91af4fcdc2f51fcc2e03f7f255ce /2026/framing
parenta75221ab93f59d688f90cd83f0284ff98951fcfa (diff)
Prepare for upload
Diffstat (limited to '2026/framing')
-rw-r--r--2026/framing/art/font0.asepritebin18591 -> 18592 bytes
-rw-r--r--2026/framing/dist/game_lib-11388961d9fc6d79.js (renamed from 2026/framing/dist/game_lib-aa603afdb40ff7d9.js)41
-rw-r--r--2026/framing/dist/game_lib-11388961d9fc6d79_bg.wasm (renamed from 2026/framing/dist/game_lib-aa603afdb40ff7d9_bg.wasm)bin21793265 -> 21820609 bytes
-rw-r--r--2026/framing/dist/index.html25
-rw-r--r--2026/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js4
-rw-r--r--2026/framing/index.html19
-rw-r--r--2026/framing/src/assets/audio/thump.wavbin0 -> 20419 bytes
-rw-r--r--2026/framing/src/assets/fonts/font2.pngbin8060 -> 8057 bytes
-rw-r--r--2026/framing/src/bindings.js4
-rw-r--r--2026/framing/src/game.rs70
10 files changed, 142 insertions, 21 deletions
diff --git a/2026/framing/art/font0.aseprite b/2026/framing/art/font0.aseprite
index d6c11a8..f2fb61d 100644
--- a/2026/framing/art/font0.aseprite
+++ b/2026/framing/art/font0.aseprite
Binary files differ
diff --git a/2026/framing/dist/game_lib-aa603afdb40ff7d9.js b/2026/framing/dist/game_lib-11388961d9fc6d79.js
index b47f990..53cec92 100644
--- a/2026/framing/dist/game_lib-aa603afdb40ff7d9.js
+++ b/2026/framing/dist/game_lib-11388961d9fc6d79.js
@@ -236,6 +236,24 @@ export function end_game(win) {
wasm.end_game(win);
}
+/**
+ * @param {number} streak
+ */
+export function game_over(streak) {
+ wasm.game_over(streak);
+}
+
+export function reset() {
+ wasm.reset();
+}
+
+/**
+ * @param {number} highscore
+ */
+export function set_leaderboard_highscore(highscore) {
+ wasm.set_leaderboard_highscore(highscore);
+}
+
export function main_js() {
wasm.main_js();
}
@@ -1333,6 +1351,9 @@ function __wbg_get_imports() {
imports.wbg.__wbg_stop_6d875c19a6df48fc = function() { return handleError(function (arg0) {
arg0.stop();
}, arguments) };
+ imports.wbg.__wbg_stop_769013bf5186c20b = function() { return handleError(function (arg0, arg1) {
+ arg0.stop(arg1);
+ }, arguments) };
imports.wbg.__wbg_style_59ace31f3c27e375 = function(arg0) {
const ret = arg0.style;
return ret;
@@ -1474,43 +1495,43 @@ function __wbg_get_imports() {
const ret = false;
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3203 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3230 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 530, __wbg_adapter_43);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3204 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3231 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 530, __wbg_adapter_43);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3205 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3232 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 530, __wbg_adapter_43);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3206 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3233 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 530, __wbg_adapter_43);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3207 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3234 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 530, __wbg_adapter_43);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3208 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3235 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 530, __wbg_adapter_54);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper3434 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper3461 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 605, __wbg_adapter_57);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper466 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper468 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 113, __wbg_adapter_34);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper468 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper470 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 117, __wbg_adapter_37);
return ret;
};
- imports.wbg.__wbindgen_closure_wrapper470 = function(arg0, arg1, arg2) {
+ imports.wbg.__wbindgen_closure_wrapper472 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 115, __wbg_adapter_40);
return ret;
};
diff --git a/2026/framing/dist/game_lib-aa603afdb40ff7d9_bg.wasm b/2026/framing/dist/game_lib-11388961d9fc6d79_bg.wasm
index 75e96d8..973ddba 100644
--- a/2026/framing/dist/game_lib-aa603afdb40ff7d9_bg.wasm
+++ b/2026/framing/dist/game_lib-11388961d9fc6d79_bg.wasm
Binary files differ
diff --git a/2026/framing/dist/index.html b/2026/framing/dist/index.html
index 61cdd04..2852915 100644
--- a/2026/framing/dist/index.html
+++ b/2026/framing/dist/index.html
@@ -6,8 +6,8 @@
<meta charset="UTF-8">
<script type="module">
-import init, * as bindings from '/framing/dist/game_lib-aa603afdb40ff7d9.js';
-const wasm = await init({ module_or_path: '/framing/dist/game_lib-aa603afdb40ff7d9_bg.wasm' });
+import init, * as bindings from '/framing/dist/game_lib-11388961d9fc6d79.js';
+const wasm = await init({ module_or_path: '/framing/dist/game_lib-11388961d9fc6d79_bg.wasm' });
window.wasmBindings = bindings;
@@ -22,27 +22,40 @@ dispatchEvent(new CustomEvent("TrunkApplicationStarted", {detail: {wasm}}));
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#404040">
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<link rel="stylesheet" href="/framing/dist/index-1e3cd2ca0ba4d1ec.css" integrity="sha384-1q3UDTmLdOyf9/QxW+Imap//HWhTWNfvn7j2iwuUap3HSD6IOGG7pDS9VJMk7nKv"/>
- <title>TODO TITLE</title>
- <link rel="modulepreload" href="/framing/dist/game_lib-aa603afdb40ff7d9.js" crossorigin="anonymous" integrity="sha384-eMCeJjAlA+b75LleOY7IhYi/P6ZjaOCSkvTktuCryApU0uVsgxpHwsIIit0mOM42"><link rel="modulepreload" href="/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js" crossorigin="anonymous" integrity="sha384-OqSoI1U/qGAdOIY23X7G4HXgi2h6nb8jbT8RiF1LDHgJg7UPDyGz1ZQ/rgmUg4ue"><link rel="modulepreload" href="/framing/dist/snippets/teleia-727bf4351691f1c8/src/helpers.js" crossorigin="anonymous" integrity="sha384-HhtEY2WfGmhyPUSRWKZvqsRxYsdT/DLEdFUqWyDZt6G6lrNHmE1zMlw4BJ3RycRd"><link rel="preload" href="/framing/dist/game_lib-aa603afdb40ff7d9_bg.wasm" crossorigin="anonymous" integrity="sha384-SqLip8RuTHuwH8gIf8seGo1v5B+xd39TtwJaaxne6cjMYgKQWKOqYRjVWL0ZsIa9" as="fetch" type="application/wasm"></head>
+ <title>Jam 2026 Framing Device</title>
+ <link rel="modulepreload" href="/framing/dist/game_lib-11388961d9fc6d79.js" crossorigin="anonymous" integrity="sha384-Rte3JuKt4XKm+pQHuHryu/S4lDtyVZ9MQjc3KLF6IZKiX/KUHmVsVwSTTalLcswu"><link rel="modulepreload" href="/framing/dist/snippets/teleia-727bf4351691f1c8/src/helpers.js" crossorigin="anonymous" integrity="sha384-HhtEY2WfGmhyPUSRWKZvqsRxYsdT/DLEdFUqWyDZt6G6lrNHmE1zMlw4BJ3RycRd"><link rel="modulepreload" href="/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js" crossorigin="anonymous" integrity="sha384-t8Fub2hhFd/kaqYNAU4KkZkCz5hrHWVD39SHYeSqNY8o4WnGFVGzS0XQ6RGr01oH"><link rel="preload" href="/framing/dist/game_lib-11388961d9fc6d79_bg.wasm" crossorigin="anonymous" integrity="sha384-G6x/3NgGuW/PN2jqYoYr+Xqr6ZM2SeJz92V3UePODdvXh4PqbF2bKhQQEqZJbDp1" as="fetch" type="application/wasm"></head>
<body>
<script type="module">
window.addEventListener("TrunkApplicationStarted", async (event) => {
console.log("initialized, starting...");
window.wasmBindings.main_js();
});
+ window.fetch("https://api.colonq.computer/api/leaderboard/jam2026?n=1").then(async (resp) => {
+ const top = await resp.json();
+ const score = top?.[0]?.[2];
+ if (typeof score === "number") {
+ console.log(`high score: ${score}`);
+ window.wasmBindings.set_leaderboard_highscore(score);
+ }
+ });
window.addEventListener("message", ev => {
switch (ev.data.op) {
case "titlescreenclick":
window.wasmBindings.titlescreen_click();
break;
case "startgame":
- console.log("verb!", ev.data.verb);
window.wasmBindings.start_game(ev.data.verb);
break;
case "endgame":
window.wasmBindings.end_game(ev.data.win);
break;
- default: console.log(`unknown event: ${ev}`); break;
+ case "gameover":
+ window.wasmBindings.game_over(ev.data.streak);
+ break;
+ case "reset":
+ window.wasmBindings.reset();
+ break;
+ default: console.log(`unknown event in framing iframe: ${ev}`); break;
}
});
</script>
diff --git a/2026/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js b/2026/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js
index a95d4a5..e9c2655 100644
--- a/2026/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js
+++ b/2026/framing/dist/snippets/game_lib-09da6449fcb9d06e/src/bindings.js
@@ -1,3 +1,7 @@
export function js_update_lifetotal(lives) {
window.parent.postMessage({op: "lifetotal", lives: lives});
}
+
+export function js_ready_to_reset() {
+ window.parent.postMessage({op: "readytoreset"});
+}
diff --git a/2026/framing/index.html b/2026/framing/index.html
index a11064b..b91b89a 100644
--- a/2026/framing/index.html
+++ b/2026/framing/index.html
@@ -11,7 +11,7 @@
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#404040">
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<link data-trunk rel="css" href="index.css" />
- <title>TODO TITLE</title>
+ <title>Jam 2026 Framing Device</title>
</head>
<body>
<script type="module">
@@ -19,19 +19,32 @@
console.log("initialized, starting...");
window.wasmBindings.main_js();
});
+ window.fetch("https://api.colonq.computer/api/leaderboard/jam2026?n=1").then(async (resp) => {
+ const top = await resp.json();
+ const score = top?.[0]?.[2];
+ if (typeof score === "number") {
+ console.log(`high score: ${score}`);
+ window.wasmBindings.set_leaderboard_highscore(score);
+ }
+ });
window.addEventListener("message", ev => {
switch (ev.data.op) {
case "titlescreenclick":
window.wasmBindings.titlescreen_click();
break;
case "startgame":
- console.log("verb!", ev.data.verb);
window.wasmBindings.start_game(ev.data.verb);
break;
case "endgame":
window.wasmBindings.end_game(ev.data.win);
break;
- default: console.log(`unknown event: ${ev}`); break;
+ case "gameover":
+ window.wasmBindings.game_over(ev.data.streak);
+ break;
+ case "reset":
+ window.wasmBindings.reset();
+ break;
+ default: console.log(`unknown event in framing iframe: ${ev}`); break;
}
});
</script>
diff --git a/2026/framing/src/assets/audio/thump.wav b/2026/framing/src/assets/audio/thump.wav
new file mode 100644
index 0000000..42fdb65
--- /dev/null
+++ b/2026/framing/src/assets/audio/thump.wav
Binary files differ
diff --git a/2026/framing/src/assets/fonts/font2.png b/2026/framing/src/assets/fonts/font2.png
index 1a3ddfe..fad9fb3 100644
--- a/2026/framing/src/assets/fonts/font2.png
+++ b/2026/framing/src/assets/fonts/font2.png
Binary files differ
diff --git a/2026/framing/src/bindings.js b/2026/framing/src/bindings.js
index a95d4a5..e9c2655 100644
--- a/2026/framing/src/bindings.js
+++ b/2026/framing/src/bindings.js
@@ -1,3 +1,7 @@
export function js_update_lifetotal(lives) {
window.parent.postMessage({op: "lifetotal", lives: lives});
}
+
+export function js_ready_to_reset() {
+ window.parent.postMessage({op: "readytoreset"});
+}
diff --git a/2026/framing/src/game.rs b/2026/framing/src/game.rs
index fa2efff..5284132 100644
--- a/2026/framing/src/game.rs
+++ b/2026/framing/src/game.rs
@@ -164,7 +164,9 @@ pub struct Game {
font1: font::Bitmap,
font2: font::Bitmap,
lives: Lives,
+ streak: i32,
verb: Option<String>,
+ highscore: Option<i32>,
}
impl Game {
@@ -176,13 +178,16 @@ impl Game {
font1: font::Bitmap::from_image(ctx, 32, 48, 512, 288, include_bytes!("assets/fonts/font1.png")),
font2: font::Bitmap::from_image(ctx, 32, 48, 512, 288, include_bytes!("assets/fonts/font2.png")),
lives: Lives::new(),
+ streak: 0,
verb: None,
+ highscore: None,
}
}
pub fn reset(&mut self) {
self.mode = Mode::Titlescreen;
self.mode_started = 0;
self.lives = Lives::new();
+ self.streak = 0;
self.verb = None;
}
pub fn switch(&mut self, _ctx: &context::Context, st: &mut state::State, m: Mode) {
@@ -237,6 +242,7 @@ impl teleia::state::Game for Game {
("wind".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/wind.wav"))),
("footsteps".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/footsteps.wav"))),
("explosion".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/explosion.wav"))),
+ ("thump".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/thump.wav"))),
("gamingtime".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/gamingtime.wav"))),
("booyah".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/booyah.wav"))),
("excellent".to_owned(), audio::Audio::new(actx, include_bytes!("assets/audio/excellent.wav"))),
@@ -261,6 +267,19 @@ impl teleia::state::Game for Game {
self.switch(ctx, st, Mode::BetweenGames);
}
},
+ Mode::PostGames => {
+ if t == 1 {
+ st.audio.fade_out_music(0.0);
+ st.audio.play_sfx("thump");
+ }
+ if t == 61 {
+ st.audio.play_sfx("thump");
+ }
+ if t == 121 {
+ st.audio.play_sfx("thump");
+ js_ready_to_reset();
+ }
+ }
_ => {},
}
Ok(())
@@ -302,6 +321,35 @@ impl teleia::state::Game for Game {
// self.lives.render(ctx, st, &mut self.renderer)?;
},
Mode::PostGames => {
+ let is_highscore = if let Some(hs) = self.highscore { self.streak > hs } else { false };
+ self.renderer.begin_frame(ctx, st, if is_highscore { Vec4::new(0.2, 1.0, 0.4, 1.0) } else { Vec4::new(0.0, 0.0, 0.0, 1.0) });
+ self.renderer.text_screen(ctx, st,
+ glam::Vec2::new(st.render_dims.x / 2.0, st.render_dims.y / 2.0 - 40.0),
+ if is_highscore { "HIGH SCORE" } else { "GAME OVER" }
+ )
+ .centered()
+ .font(if (t / 16).is_multiple_of(2) { &self.font1 } else { &self.font2 })
+ .color(glam::Vec4::ONE)
+ .render();
+ if t > 60 {
+ self.renderer.text_screen(ctx, st,
+ glam::Vec2::new(st.render_dims.x / 2.0, st.render_dims.y / 2.0 + 40.0),
+ &if is_highscore { format!("your streak: {} (take a screenshot and share it!)", self.streak) }
+ else { format!("your streak: {}", self.streak) }
+ )
+ .centered()
+ .color(glam::Vec4::ONE)
+ .render();
+ }
+ if t > 120 {
+ self.renderer.text_screen(ctx, st,
+ glam::Vec2::new(st.render_dims.x / 2.0, st.render_dims.y / 2.0 + 80.0),
+ if is_highscore { "click to restart" } else { "click to try again" }
+ )
+ .centered()
+ .color(glam::Vec4::ONE)
+ .render();
+ }
},
}
Ok(())
@@ -314,6 +362,7 @@ impl teleia::state::Game for Game {
#[wasm_bindgen(module = "/src/bindings.js")]
extern {
fn js_update_lifetotal(lives: i32);
+ fn js_ready_to_reset();
}
#[wasm_bindgen]
@@ -342,16 +391,33 @@ pub fn end_game(win: bool) {
g.play_random_sound(ctx, st, SOUND_POSITIVE);
} else {
g.lives.lose_life(ctx, st);
- st.audio.play_sfx("footsteps");
- g.play_random_sound(ctx, st, SOUND_NEGATIVE);
+ if g.lives.lives_remaining() > 0 {
+ st.audio.play_sfx("footsteps");
+ g.play_random_sound(ctx, st, SOUND_NEGATIVE);
+ }
}
js_update_lifetotal(g.lives.lives_remaining());
});
}
#[wasm_bindgen]
+pub fn game_over(streak: i32) {
+ contextualize(|ctx, st, g: &mut Game| {
+ g.switch(ctx, st, Mode::PostGames);
+ g.streak = streak;
+ })
+}
+
+#[wasm_bindgen]
pub fn reset() {
contextualize(|_ctx, _st, g: &mut Game| {
g.reset();
})
}
+
+#[wasm_bindgen]
+pub fn set_leaderboard_highscore(highscore: i32) {
+ contextualize(|_ctx, _st, g: &mut Game| {
+ g.highscore = Some(highscore);
+ })
+}