From 796143f20c9473591ce984ee94d2379168c046e3 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Thu, 5 Nov 2026 15:17:05 +0100 Subject: [PATCH] Credit qwen3.8-flash-next-iq3xxs with Strata in OpenCode, with pixel marks Co-Authored-By: Claude Opus 5.5 --- CREDITS.md | 3 ++ README.md | 7 +++++ lang/de.lang | 1 + lang/en.lang | 1 + src/main.rs | 1 + src/menu.rs | 64 ++++++++++++++++++++++++++++++---------- tools/make_standalone.py | 2 +- 7 files changed, 63 insertions(+), 16 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index ce350b5..5274c3e 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -8,5 +8,8 @@ ## Made with Claude Code The game was developed with the help of [Claude Code](https://claude.com/claude-code), Anthropic's AI coding assistant. The small pixel-art mark next to the note on the title and login screens is a rendition of the Claude Code logo. Claude, Claude Code and Anthropic are trademarks of Anthropic; the mark only credits the tool and is not covered by the MIT licence of this project. +## Made with qwen3.8-flash-next-iq3xxs, Strata and OpenCode +Parts of the game were also developed with the language model qwen3.8-flash-next-iq3xxs, run with Strata in [OpenCode](https://opencode.ai). The two small pixel-art marks next to the second note on the title and login screens are renditions of the Qwen and the OpenCode logo. Qwen and OpenCode are trademarks of their respective owners; the marks only credit the tools and are not covered by the MIT licence of this project. + ## Everything else Code, procedural graphics and game design: the DungeonCraft project. diff --git a/README.md b/README.md index 2c4dc4c..0b9ef24 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ An evil little dungeon game for the browser - in glorious pixels, in 3D, for fre Rust WebAssembly Made with Claude Code + Made with qwen3.8-flash-next-iq3xxs and Strata in OpenCode MIT License English and German

@@ -157,6 +158,12 @@ the music, the texts and this page. Claude, Claude Code and Anthropic are tradem credits the tool.


+## Made with qwen3.8-flash-next-iq3xxs, Strata and OpenCode + +Parts of DungeonCraft were also developed with the language model qwen3.8-flash-next-iq3xxs, run with Strata in +OpenCode. Qwen and OpenCode are trademarks of their respective owners; the pixel +marks on the title screen only credit the tools. + ## License DungeonCraft is released under the **[MIT License](LICENSE)** - © 2026 Richard Zink. It covers the code, the generated diff --git a/lang/de.lang b/lang/de.lang index 6e0a1cd..b6b1142 100644 --- a/lang/de.lang +++ b/lang/de.lang @@ -561,6 +561,7 @@ unit.wyrm = Glutwyrm job.rest = Erholt sich im Horst job.torment = Bearbeitet einen Gefangenen menu.made_with = Erstellt mit Hilfe von Claude Code +menu.made_with_qwen = Erstellt mit Hilfe von qwen3.8-flash-next-iq3xxs mit Strata in OpenCode menu.license = DungeonCraft - MIT-Lizenz - (c) 2026 Richard Zink # steel walls diff --git a/lang/en.lang b/lang/en.lang index 01a1ebd..4f738c9 100644 --- a/lang/en.lang +++ b/lang/en.lang @@ -562,6 +562,7 @@ unit.wyrm = Ember Wyrm job.rest = Recovering in the aerie job.torment = Working on a prisoner menu.made_with = Made with the help of Claude Code +menu.made_with_qwen = Made with the help of qwen3.8-flash-next-iq3xxs with Strata in OpenCode menu.license = DungeonCraft - MIT License - (c) 2026 Richard Zink # steel walls diff --git a/src/main.rs b/src/main.rs index fa3c3b8..48c5703 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1480,6 +1480,7 @@ async fn main() { } MenuAction::OpenRepo => platform::open_url(menu::REPO_URL), MenuAction::OpenClaudeCode => platform::open_url(menu::CLAUDE_CODE_URL), + MenuAction::OpenOpenCode => platform::open_url(menu::OPENCODE_URL), a @ (MenuAction::Login(..) | MenuAction::Logout | MenuAction::OpenAccount diff --git a/src/menu.rs b/src/menu.rs index 9262c69..59a9049 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -260,6 +260,7 @@ enum Btn { Goals, Repo, ClaudeCode, + OpenCode, Field(usize), DoLogin, Account, @@ -292,6 +293,7 @@ enum Btn { pub const REPO_URL: &str = "https://git.familie-zink.org/zink/dungeoncraft"; pub const CLAUDE_CODE_URL: &str = "https://claude.com/claude-code"; +pub const OPENCODE_URL: &str = "https://opencode.ai"; // the game version (file VERSION, "vYYYYMM-NNNNN"): tools/bump_version.py raises it with every // change, and the title screen and the pause menu show it @@ -310,9 +312,27 @@ const CLAUDE_MARK: [&str; 5] = [ "....#.#....#.#....", ]; -pub fn draw_claude_mark(x: f32, y: f32, px: f32) { - let c = Color::from_rgba(0xd9, 0x77, 0x57, 255); - for (r, row) in CLAUDE_MARK.iter().enumerate() { +// pixel renditions of the Qwen and the OpenCode mark (the second "made with" note) +const QWEN_MARK: [&str; 5] = [ + "...###...", + ".##.#.##.", + "#..###..#", + ".##.#.##.", + "...###...", +]; +const OPENCODE_MARK: [&str; 5] = [ + "#######", + "#.....#", + "#.#...#", + "#..#.##", + "#######", +]; +const CLAUDE_COL: Color = Color { r: 0xd9 as f32 / 255.0, g: 0x77 as f32 / 255.0, b: 0x57 as f32 / 255.0, a: 1.0 }; +const QWEN_COL: Color = Color { r: 0x7b as f32 / 255.0, g: 0x6c as f32 / 255.0, b: 0xf6 as f32 / 255.0, a: 1.0 }; +const OPENCODE_COL: Color = Color { r: 0.86, g: 0.86, b: 0.88, a: 1.0 }; + +fn draw_mark(mark: &[&str], x: f32, y: f32, px: f32, c: Color) { + for (r, row) in mark.iter().enumerate() { for (k, ch) in row.chars().enumerate() { if ch == '#' { draw_rectangle(x + k as f32 * px, y + r as f32 * px, px, px, c); @@ -321,6 +341,7 @@ pub fn draw_claude_mark(x: f32, y: f32, px: f32) { } } + pub enum MenuAction { None, Consumed, @@ -353,6 +374,7 @@ pub enum MenuAction { CampaignStart(usize), OpenRepo, OpenClaudeCode, + OpenOpenCode, Login(String, String), Logout, OpenAccount, @@ -646,6 +668,7 @@ impl Menu { Some(Btn::NameField) => MenuAction::EditName, Some(Btn::Repo) => MenuAction::OpenRepo, Some(Btn::ClaudeCode) => MenuAction::OpenClaudeCode, + Some(Btn::OpenCode) => MenuAction::OpenOpenCode, Some(Btn::Field(i)) => { self.focus = i; if matches!(self.page, Some(Page::Match { .. })) { @@ -882,19 +905,30 @@ impl Menu { pub fn draw_license(&mut self, gfx: &Gfx) { let (sw, sh) = (sw(), sh()); let (mx, my) = mouse(); - // "made with Claude Code" with the pixel mark, a link to Claude Code - let made = tr("menu.made_with"); + // "made with" notes with their pixel marks, links to the tools: + // Claude Code, then qwen3.8-flash-next-iq3xxs with Strata in OpenCode let px = (SMALL() * 2.0).round().max(2.0); - let mark_w = 18.0 * px; - let tw = gfx.measure(&made, SMALL()); - let total = mark_w + CW() * 0.5 + tw; - let mx0 = grid_center(sw, total); - let my0 = sh - CH() * 4.0; - let r = Rect::new(mx0, my0, total, GH * SMALL() + 2.0); - let hot = r.contains(vec2(mx, my)); - draw_claude_mark(mx0, my0 + (GH * SMALL() - 5.0 * px) * 0.5, px); - gfx.text(&made, mx0 + mark_w + CW() * 0.5, my0, SMALL(), if hot { FRAME_HI } else { Color::from_rgba(0xd9, 0x77, 0x57, 255) }); - self.buttons.push((r, Btn::ClaudeCode)); + let credits: [(&[&[&str]], &[Color], String, Color, Btn, f32); 2] = [ + (&[&CLAUDE_MARK], &[CLAUDE_COL], tr("menu.made_with"), CLAUDE_COL, Btn::ClaudeCode, 4.6), + (&[&QWEN_MARK, &OPENCODE_MARK], &[QWEN_COL, OPENCODE_COL], tr("menu.made_with_qwen"), QWEN_COL, Btn::OpenCode, 3.6), + ]; + for (marks, cols, made, col, btn, row) in credits { + let widths: Vec = marks.iter().map(|m| m[0].len() as f32 * px).collect(); + let mark_w: f32 = widths.iter().sum::() + px * 2.0 * (marks.len() as f32 - 1.0); + let tw = gfx.measure(&made, SMALL()); + let total = mark_w + CW() * 0.5 + tw; + let mx0 = grid_center(sw, total); + let my0 = sh - CH() * row; + let r = Rect::new(mx0, my0, total, GH * SMALL() + 2.0); + let hot = r.contains(vec2(mx, my)); + let mut x = mx0; + for (k, m) in marks.iter().enumerate() { + draw_mark(m, x, my0 + (GH * SMALL() - 5.0 * px) * 0.5, px, cols[k]); + x += widths[k] + px * 2.0; + } + gfx.text(&made, mx0 + mark_w + CW() * 0.5, my0, SMALL(), if hot { FRAME_HI } else { col }); + self.buttons.push((r, btn)); + } let lic = tr("menu.license"); gfx.text(&lic, grid_center(sw, gfx.measure(&lic, SMALL())), sh - CH() * 2.5, SMALL(), DIM); let ver = tr("menu.version"); diff --git a/tools/make_standalone.py b/tools/make_standalone.py index a89d590..0e5f903 100644 --- a/tools/make_standalone.py +++ b/tools/make_standalone.py @@ -39,7 +39,7 @@ html = f""" - +