Creature Collection
Gemma 4 12b qat · middle

Reviews & generation details
Reviews
Human review · Jul 17, 2026 · rubric 1
Historical path-based review. Association with these exact bytes is unverified.
- Visual design
- 1 / 5
- UX / feel
- 2 / 5
- Works
- 1 / 5
- Prompt spirit
- 2 / 5
- Delight
- 1 / 5
Generation context
Imported historical artifact. Its exact original instructions and lineage are not known.
Generation prompt · exact text unavailable
See the current prompt for reference. It may differ from the instructions used to generate this artifact.
Inspect original source 40,260 bytes · SHA-256 6b995d4cd145
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sunder-Glass: The Resonant Path</title>
<style>
:root {
--bg-color: #0a0a0f;
--panel-bg: rgba(20, 20, 35, 0.85);
--accent: #7faff1;
--text-color: #e0e0ff;
--glass: rgba(255, 255, 255, 0.1);
--border: 1px solid rgba(255, 255, 255, 0.15);
--font-main: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--type-a: #7faff1; /* Vitreous */
--type-b: #ffcc33; /* Coruscant */
--type-c: #9933ff; /* Obsidian */
--type-d: #99ff99; /* Nebulous */
--type-e: #ff99cc; /* Veridian */
--type-f: #ffffff; /* Aetheric */
--type-g: #33ccff; /* Stellar */
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: var(--font-main);
overflow: hidden;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
#game-container {
position: relative;
width: 100vw;
height: 100vh;
max-width: 1200px;
max-height: 800px;
border: 2px solid var(--glass);
overflow: hidden;
background: #050508;
box-shadow: 0 0 50px rgba(0,0,0,0.8);
}
canvas {
display: block;
width: 100%;
height: 100%;
image-rendering: pixelated;
}
.ui-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 10;
}
.menu-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(15,15,30,0.8) 0%, rgba(5,5,10,1) 100%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
pointer-events: all;
z-index: 100;
}
.glass-panel {
background: var(--panel-bg);
backdrop-filter: blur(15px);
border: var(--border);
border-radius: 15px;
padding: 30px;
text-align: center;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
}
h1 {
font-size: 4rem;
margin-bottom: 20px;
letter-spacing: 10px;
text-transform: uppercase;
background: linear-gradient(to bottom, #fff, var(--accent));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
filter: drop-shadow(0 0 10px var(--accent));
}
.btn {
padding: 15px 40px;
margin: 10px;
background: var(--glass);
border: 1px solid var(--accent);
color: white;
font-size: 1.2rem;
cursor: pointer;
transition: all 0.3s;
border-radius: 5px;
text-transform: uppercase;
letter-spacing: 2px;
}
.btn:hover {
background: var(--accent);
color: #000;
box-shadow: 0 0 20px var(--accent);
}
.dialogue-box {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 80%;
padding: 20px;
background: var(--panel-bg);
border: var(--border);
border-radius: 10px;
pointer-events: all;
display: none;
}
.battle-ui {
position: absolute;
bottom: 0;
width: 100%;
height: 35%;
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
pointer-events: all;
display: none;
padding-bottom: 20px;
}
.battle-party {
display: flex;
justify-content: space-around;
padding: 20px;
}
.creature-slot {
width: 120px;
text-align: center;
}
.hp-bar-bg {
width: 100%;
height: 8px;
background: #333;
border-radius: 4px;
margin-top: 5px;
}
.hp-bar-fill {
height: 100%;
background: #4caf50;
border-radius: 4px;
transition: width 0.3s;
}
.action-menu {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
padding: 20px;
justify-content: center;
}
.action-btn {
padding: 10px;
background: var(--glass);
border: 1px solid #fff;
color: white;
border-radius: 5px;
cursor: pointer;
}
.action-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.hud {
position: absolute;
top: 20px;
left: 20px;
display: flex;
gap: 20px;
}
.hud-item {
background: var(--panel-bg);
padding: 10px 20px;
border-radius: 10px;
border: var(--border);
}
.vignette {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, transparent 50%, rgba(0,0,0,0.8) 100%);
pointer-events: none;
}
.floating-dmg {
position: absolute;
font-weight: bold;
pointer-events: none;
animation: floatUp 1s forwards;
}
@keyframes floatUp {
from { transform: translateY(0); opacity: 1; }
to { transform: translateY(-100px); opacity: 0; }
}
.shake {
animation: shake 0.2s;
}
@keyframes shake {
0% { transform: translate(0,0); }
25% { transform: translate(5px,5px); }
50% { transform: translate(-5px,5px); }
75% { transform: translate(5px,-5px); }
100% { transform: translate(0,0); }
}
#touch-controls {
position: absolute;
bottom: 20px;
right: 20px;
display: grid;
grid-template-columns: repeat(3, 60px);
grid-template-rows: repeat(3, 60px);
gap: 10px;
pointer-events: all;
display: none;
}
.touch-btn {
width: 60px;
height: 60px;
background: var(--glass);
border: 1px solid #fff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
}
.active-type {
color: var(--accent);
text-shadow: 0 0 5px var(--accent);
}
.capture-mini-game {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--panel-bg);
padding: 40px;
border-radius: 20px;
display: none;
text-align: center;
pointer-events: all;
z-index: 200;
}
#capture-bar-container {
width: 300px;
height: 30px;
background: #222;
margin: 20px auto;
position: relative;
border: 2px solid #fff;
}
#capture-pointer {
position: absolute;
width: 8px;
height: 100%;
background: #fff;
left: 0;
}
#capture-target {
position: absolute;
width: 60px;
height: 100%;
background: rgba(255,255,255,0.3);
border: 2px solid #fff;
left: 50%;
transform: translateX(-50%);
}
</style>
</head>
<body>
<div id="game-container">
<canvas id="gameCanvas"></canvas>
<div class="vignette"></div>
<div id="title-screen" class="menu-screen">
<div class="glass-panel">
<h1>Sunder-Glass</h1>
<p style="margin-bottom: 30px; letter-spacing: 2px;">THE RESONANT PATH</p>
<button class="btn" onclick="game.init()">New Binding</button>
<button class="btn" id="btn-continue" style="display:none;" onclick="game.load()">Continue</button>
</div>
</div>
<div id="menu-pause" class="menu-screen" style="display:none;">
<div class="glass-panel">
<h1>Pause</h1>
<button class="btn" onclick="game.togglePause()">Resume</button>
<button class="btn" onclick="game.save()">Save Progress</button>
<button class="btn" onclick="location.reload()">Quit</button>
</div>
</div>
<div class="hud" id="game-hud" style="display:none;">
<div class="hud-item">Zone: <span id="hud-zone">1</span></div>
<div class="hud-item">Resonants: <span id="hud-count">0</span>/6</div>
<div class="hud-item">Binding: <span id="hud-binding">None</span></div>
</div>
<div id="dialogue-container" class="dialogue-box">
<div id="dialogue-text"></div>
</div>
<div id="battle-ui" class="battle-ui">
<div class="battle-party" id="battle-party-ui"></div>
<div class="action-menu" id="action-menu"></div>
</div>
<div id="capture-mini-game" class="capture-mini-game">
<h3>CAPTURE PULSE</h3>
<p>Tap to align the pointer with the target!</p>
<div id="capture-bar-container">
<div id="capture-target"></div>
<div id="capture-pointer"></div>
</div>
</div>
<div id="touch-controls">
<div></div><div class="touch-btn" onmousedown="game.handleTouch('up')">↑</div><div></div>
<div class="touch-btn" onmousedown="game.handleTouch('left')">←</div><div class="touch-btn" onmousedown="game.handleTouch('down')">↓</div><div class="touch-btn" onmousedown="game.handleTouch('right')">→</div>
</div>
</div>
<script>
/**
* LORE & WORLD BUILDING
* Setting: The Sunder-Glass. A world fractured into crystalline shards floating in a void of prismatic mist.
* Entities: Resonants (Beings of harmonic resonance).
* Affinities:
* Vitreous (A): Reflective, sharp, light-bending.
* Coruscant (B): Static, flickering, high-energy.
* Obsidian (C): Dense, heavy, light-absorbing.
* Nebulous (D): Ethereal, gaseous, drifting.
* Veridian (E): Organic, creeping, vital.
* Aetheric (F): Pure harmony, transcending form.
* Stellar (G): Cosmic, cold, ancient.
*/
const TYPES = {
VITREOUS: 'Vitreous',
CORUSCANT: 'Coruscant',
OBSIDIAN: 'Obsidian',
NEBULOUS: 'Nebulous',
VERIDIAN: 'Veridian',
AETHERIC: 'Aetheric',
STELLAR: 'Stellar'
};
const TYPE_CHART = {
[TYPES.VITREOUS]: { beats: [TYPES.CORUSCANT], resists: [] },
[TYPES.CORUSCANT]: { beats: [TYPES.OBSIDIAN], resists: [] },
[TYPES.OBSIDIAN]: { beats: [TYPES.VITREOUS], resists: [] },
[TYPES.NEBULOUS]: { beats: [TYPES.VITREOUS, TYPES.OBSIDIAN], resists: [] },
[TYPES.VERIDIAN]: { beats: [TYPES.NEBULOUS, TYPES.CORUSCANT], resists: [] },
[TYPES.AETHERIC]: { beats: Object.keys(TYPES).filter(t => t !== TYPES.AETHERIC), resists: [] },
[TYPES.STELLAR]: { beats: [], resists: Object.keys(TYPES).filter(t => t !== TYPES.STELLAR) }
};
// Adjustment multipliers:
// Aetheric (F) beats all slightly (+20%)
// Stellar (G) resists everything (0.5x) but weak to Aetheric (2.0x)
const MOVES = {
'Shatter-Strike': { power: 40, accuracy: 90, affinity: TYPES.VITREOUS, effect: 'def_down', desc: 'Sharp strike.' },
'Ion-Burst': { power: 35, accuracy: 85, affinity: TYPES.CORUSCANT, effect: 'shock', desc: 'Electric discharge.' },
'Deep-Crush': { power: 50, accuracy: 70, affinity: TYPES.OBSIDIAN, effect: 'burn', desc: 'Heavy pressure.' },
'Mist-Veil': { power: 10, accuracy: 100, affinity: TYPES.NEBULOUS, effect: 'heal', desc: 'Soft mist.' },
'Bloom-Bind': { power: 30, accuracy: 80, affinity: TYPES.VERIDIAN, effect: 'root', desc: 'Thorn grasp.' },
'Aura-Pulse': { power: 45, accuracy: 95, affinity: TYPES.AETHERIC, effect: 'multi', desc: 'Harmonic wave.' },
'Nova-Flare': { power: 60, accuracy: 75, affinity: TYPES.STELLAR, effect: 'frost', desc: 'Cold spark.' },
'Prism-Edge': { power: 45, accuracy: 90, affinity: TYPES.VITREOUS, effect: 'speed_up', desc: 'Sharp light.' },
'Static-Snap': { power: 30, accuracy: 95, affinity: TYPES.CORUSCANT, effect: 'shock', desc: 'Quick snap.' },
'Crag-Throw': { power: 55, accuracy: 60, affinity: TYPES.OBSIDIAN, effect: 'burn', desc: 'Toss rock.' },
'Drift-Step': { power: 5, accuracy: 100, affinity: TYPES.NEBULOUS, effect: 'evade', desc: 'Step through mist.' },
'Vine-Wrap': { power: 35, accuracy: 85, affinity: TYPES.VERIDIAN, effect: 'root', desc: 'Tangle vines.' },
'Light-Step': { power: 20, accuracy: 100, affinity: TYPES.AETHERIC, effect: 'speed_up', desc: 'Move fast.' },
'Star-Fall': { power: 70, accuracy: 65, affinity: TYPES.STELLAR, effect: 'frost', desc: 'Falling star.' },
'Reflect-Wall': { power: 0, accuracy: 100, affinity: TYPES.VITREOUS, effect: 'barrier', desc: 'Reflective wall.' },
'Shock-Wave': { power: 40, accuracy: 85, affinity: TYPES.CORUSCANT, effect: 'shock', desc: 'Ground shock.' },
'Earth-Quake': { power: 50, accuracy: 70, affinity: TYPES.OBSIDIAN, effect: 'def_down', desc: 'Quake strike.' },
'Spore-Cloud': { power: 25, accuracy: 80, affinity: TYPES.NEBULOUS, effect: 'burn', desc: 'Release spores.' },
'Thorn-Burst': { power: 40, accuracy: 85, affinity: TYPES.VERIDIAN, effect: 'burn', desc: 'Burst thorns.' },
'Spirit-Strike': { power: 50, accuracy: 90, affinity: TYPES.AETHERIC, effect: 'heal', desc: 'Holy strike.' },
'Void-Reach': { power: 45, accuracy: 80, affinity: TYPES.STELLAR, effect: 'frost', desc: 'Void reach.' },
'Shard-Rain': { power: 40, accuracy: 90, affinity: TYPES.VITREOUS, effect: 'multi', desc: 'Rain shards.' },
'Voltage-Link': { power: 30, accuracy: 85, affinity: TYPES.CORUSCANT, effect: 'shock', desc: 'Link energy.' },
'Magma-Flow': { power: 45, accuracy: 80, affinity: TYPES.OBSIDIAN, effect: 'burn', desc: 'Lava flow.' },
'Wisp-Dance': { power: 20, accuracy: 100, affinity: TYPES.NEBULOUS, effect: 'speed_up', desc: 'Dance fast.' },
'Root-Grow': { power: 30, accuracy: 90, affinity: TYPES.VERIDIAN, effect: 'heal', desc: 'Grow roots.' },
'Halo-Beam': { power: 60, accuracy: 70, affinity: TYPES.AETHERIC, effect: 'multi', desc: 'Beam of light.' },
'Cold-Snap': { power: 50, accuracy: 85, affinity: TYPES.STELLAR, effect: 'frost', desc: 'Sudden cold.' },
'Mirror-Dash': { power: 35, accuracy: 90, affinity: TYPES.VITREOUS, effect: 'evade', desc: 'Mirror dash.' },
'Overload': { power: 80, accuracy: 50, affinity: TYPES.CORUSCANT, effect: 'shock', desc: 'Power surge.' },
'Tectonic': { power: 70, accuracy: 60, affinity: TYPES.OBSIDIAN, effect: 'def_down', desc: 'Shift ground.' },
'Soot-Cloud': { power: 20, accuracy: 95, affinity: TYPES.NEBULOUS, effect: 'evade', desc: 'Smoke cloud.' },
'Forest-Cry': { power: 40, accuracy: 85, affinity: TYPES.VERIDIAN, effect: 'root', desc: 'Forest cry.' },
'Zen-Strike': { power: 45, accuracy: 95, affinity: TYPES.AETHERIC, effect: 'speed_up', desc: 'Zen strike.' },
'Gravity-Well': { power: 60, accuracy: 75, affinity: TYPES.STELLAR, effect: 'frost', desc: 'Gravity pull.' },
'Spark-Jump': { power: 30, accuracy: 90, affinity: TYPES.CORUSCANT, effect: 'speed_up', desc: 'Quick jump.' },
'Crag-Bash': { power: 55, accuracy: 80, affinity: TYPES.OBSIDIAN, effect: 'burn', desc: 'Heavy bash.' },
'Mist-Walk': { power: 10, accuracy: 100, affinity: TYPES.NEBULOUS, effect: 'evade', desc: 'Walk in mist.' },
'Growth-Burst': { power: 40, accuracy: 85, affinity: TYPES.VERIDIAN, effect: 'heal', desc: 'Burst growth.' },
'Prism-Flash': { power: 30, accuracy: 95, affinity: TYPES.VITREOUS, effect: 'shock', desc: 'Flash light.' },
'Void-Echo': { power: 50, accuracy: 85, affinity: TYPES.STELLAR, effect: 'frost', desc: 'Echo in void.' },
'Pulse-Wave': { power: 35, accuracy: 85, affinity: TYPES.AETHERIC, effect: 'multi', desc: 'Pulse wave.' }
};
const CREATURE_DATA = [
{ id: 1, name: "Lumic", lore: "A small, floating bird of pure light. It hums with a constant, soothing frequency.", affinity: TYPES.VITREOUS, stats: { hp: 60, atk: 12, def: 8, spd: 15 }, moves: ['Shatter-Strike', 'Prism-Flash', 'Light-Step', 'Mirror-Dash'] },
{ id: 2, name: "Sparkfly", lore: "A buzzing insect that generates static electricity in its wings.", affinity: TYPES.CORUSCANT, stats: { hp: 50, atk: 15, def: 6, spd: 22 }, moves: ['Ion-Burst', 'Static-Snap', 'Spark-Jump', 'Voltage-Link'] },
{ id: 3, name: "Cragshell", lore: "A tortoise whose shell is made of living obsidian.", affinity: TYPES.OBSIDIAN, stats: { hp: 100, atk: 14, def: 18, spd: 5 }, moves: ['Deep-Crush', 'Crag-Throw', 'Crag-Bash', 'Tectonic'] },
{ id: 4, name: "Mistwisp", lore: "A drifting vapor that feels like a cool breeze.", affinity: TYPES.NEBULOUS, stats: { hp: 70, atk: 9, def: 10, spd: 12 }, moves: ['Mist-Veil', 'Drift-Step', 'Mist-Walk', 'Soot-Cloud'] },
{ id: 5, name: "Rootling", lore: "A small humanoid made of tangled vines and flowers.", affinity: TYPES.VERIDIAN, stats: { hp: 80, atk: 11, def: 12, spd: 8 }, moves: ['Bloom-Bind', 'Vine-Wrap', 'Root-Grow', 'Forest-Cry'] },
{ id: 6, name: "Auraform", lore: "A humanoid entity made of woven aether. It speaks in harmonies.", affinity: TYPES.AETHERIC, stats: { hp: 75, atk: 14, def: 10, spd: 16 }, moves: ['Aura-Pulse', 'Spirit-Strike', 'Light-Step', 'Zen-Strike'] },
{ id: 7, name: "Voidstar", lore: "A tiny, floating planetoid with a cold, silent core.", affinity: TYPES.STELLAR, stats: { hp: 90, atk: 13, def: 14, spd: 7 }, moves: ['Nova-Flare', 'Star-Fall', 'Void-Reach', 'Cold-Snap'] },
// More creatures would go here to reach 18
{ id: 8, name: "Prism-Hound", lore: "A lean wolf-like creature with a body of jagged glass.", affinity: TYPES.VITREOUS, stats: { hp: 70, atk: 16, def: 9, spd: 18 }, moves: ['Shatter-Strike', 'Prism-Edge', 'Reflect-Wall', 'Shard-Rain'] },
{ id: 9, name: "Volt-Moth", lore: "Wings like flickering neon tubes. It feeds on power lines.", affinity: TYPES.CORUSCANT, stats: { hp: 55, atk: 17, def: 7, spd: 25 }, moves: ['Ion-Burst', 'Overload', 'Voltage-Link', 'Static-Snap'] },
{ id: 10, name: "Slate-Bear", lore: "A massive bear of solid grey stone.", affinity: TYPES.OBSIDIAN, stats: { hp: 120, atk: 18, def: 22, spd: 4 }, moves: ['Deep-Crush', 'Tectonic', 'Crag-Bash', 'Magma-Flow'] },
{ id: 11, name: "Cloud-Ray", lore: "A majestic ray that swims through the high-altitude mists.", affinity: TYPES.NEBULOUS, stats: { hp: 85, atk: 10, def: 11, spd: 20 }, moves: ['Mist-Veil', 'Drift-Step', 'Soot-Cloud', 'Wisp-Dance'] },
{ id: 12, name: "Thorn-Vine", lore: "A parasitic plant that grows on the Sunder-Glass rocks.", affinity: TYPES.VERIDIAN, stats: { hp: 90, atk: 13, def: 14, spd: 9 }, moves: ['Bloom-Bind', 'Thorn-Burst', 'Vine-Wrap', 'Growth-Burst'] },
{ id: 13, name: "Halo-Spirit", lore: "A circular being of pure white energy.", affinity: TYPES.AETHERIC, stats: { hp: 65, atk: 13, def: 9, spd: 20 }, moves: ['Aura-Pulse', 'Spirit-Strike', 'Halo-Beam', 'Zen-Strike'] },
{ id: 14, name: "Nova-Core", lore: "A burning star that fell from the zenith.", affinity: TYPES.STELLAR, stats: { hp: 110, atk: 16, def: 15, spd: 8 }, moves: ['Nova-Flare', 'Star-Fall', 'Gravity-Well', 'Void-Reach'] },
{ id: 15, name: "Glass-Drake", lore: "A dragon-like entity whose scales reflect everything.", affinity: TYPES.VITREOUS, stats: { hp: 130, atk: 20, def: 18, spd: 12 }, moves: ['Shatter-Strike', 'Prism-Edge', 'Reflect-Wall', 'Shard-Rain'] },
{ id: 16, name: "Static-Lizard", lore: "A lizard that leaves scorched footprints.", affinity: TYPES.CORUSCANT, stats: { hp: 75, atk: 18, def: 10, spd: 22 }, moves: ['Ion-Burst', 'Overload', 'Voltage-Link', 'Static-Snap'] },
{ id: 17, name: "Ore-Golem", lore: "A slow, massive construction of raw ores.", affinity: TYPES.OBSIDIAN, stats: { hp: 140, atk: 19, def: 25, spd: 3 }, moves: ['Deep-Crush', 'Tectonic', 'Crag-Bash', 'Magma-Flow'] },
{ id: 18, name: "Vapor-Stalker", lore: "A predator that can become almost invisible.", affinity: TYPES.NEBULOUS, stats: { hp: 60, atk: 15, def: 8, spd: 28 }, moves: ['Mist-Veil', 'Drift-Step', 'Soot-Cloud', 'Wisp-Dance'] },
// Transformed Forms (simplified)
{ id: 19, name: "Crystal-Lumic", lore: "The ultimate evolution of light resonance.", affinity: TYPES.VITREOUS, stats: { hp: 85, atk: 22, def: 18, spd: 20 }, moves: ['Shatter-Strike', 'Prism-Edge', 'Reflect-Wall', 'Shard-Rain'], transformedFrom: 1 },
{ id: 20, name: "Volt-Queen", lore: "A monarch of the electric currents.", affinity: TYPES.CORUSCANT, stats: { hp: 80, atk: 25, def: 12, spd: 30 }, moves: ['Ion-Burst', 'Overload', 'Voltage-Link', 'Static-Snap'], transformedFrom: 9 },
{ id: 21, name: "Obsidian-Titan", lore: "A mountain of weight and shadow.", affinity: TYPES.OBSIDIAN, stats: { hp: 180, atk: 28, def: 35, spd: 2 }, moves: ['Deep-Crush', 'Tectonic', 'Crag-Bash', 'Magma-Flow'], transformedFrom: 10 },
{ id: 22, name: "Aether-Serpent", lore: "A weaving of light and destiny.", affinity: TYPES.AETHERIC, stats: { hp: 100, atk: 24, def: 16, spd: 24 }, moves: ['Aura-Pulse', 'Spirit-Strike', 'Halo-Beam', 'Zen-Strike'], transformedFrom: 13 },
{ id: 23, name: "Stella-King", lore: "A ruler of the frozen void.", affinity: TYPES.STELLAR, stats: { hp: 150, atk: 26, def: 25, spd: 10 }, moves: ['Nova-Flare', 'Star-Fall', 'Gravity-Well', 'Void-Reach'], transformedFrom: 14 },
{ id: 24, name: "Verid-Behemoth", lore: "A forest incarnate.", affinity: TYPES.VERIDIAN, stats: { hp: 160, atk: 22, def: 20, spd: 7 }, moves: ['Bloom-Bind', 'Thorn-Burst', 'Vine-Wrap', 'Growth-Burst'], transformedFrom: 12 },
{ id: 25, name: "Void-Wraith", lore: "The shadow of a shadow.", affinity: TYPES.NEBULOUS, stats: { hp: 90, atk: 20, def: 12, spd: 35 }, moves: ['Mist-Veil', 'Drift-Step', 'Soot-Cloud', 'Wisp-Dance'], transformedFrom: 18 },
{ id: 26, name: "Glass-Drake-Apex", lore: "Refinement of the crystalline hunt.", affinity: TYPES.VITREOUS, stats: { hp: 150, atk: 30, def: 22, spd: 18 }, moves: ['Shatter-Strike', 'Prism-Edge', 'Reflect-Wall', 'Shard-Rain'], transformedFrom: 15 },
{ id: 27, name: "Prism-Lord", lore: "The weaver of the Sunder-Glass.", affinity: TYPES.AETHERIC, stats: { hp: 140, atk: 35, def: 20, spd: 25 }, moves: ['Aura-Pulse', 'Spirit-Strike', 'Halo-Beam', 'Zen-Strike'], transformedFrom: 6 },
];
const ZONES = [
{
id: 0,
name: "The Shimmering Fissure",
color: "linear-gradient(to bottom, #1a1a2e, #16213e)",
description: "A crack in the Sunder-Glass where the first echoes begin.",
enemies: [1, 2, 3, 4, 5],
boss: { id: 1, name: "Fissure-Warden", stats: { hp: 200, atk: 25, def: 20, spd: 10 }, affinity: TYPES.VITREOUS },
unlock: 1
},
{
id: 1,
name: "The Echoing Void",
color: "linear-gradient(to bottom, #0f0c29, #302b63, #24243e)",
description: "A hollow expanse where sound lingers like ghosts.",
enemies: [6, 7, 8, 9, 10],
boss: { id: 10, name: "Void-Sentinel", stats: { hp: 250, atk: 30, def: 25, spd: 8 }, affinity: TYPES.OBSIDIAN },
unlock: 2
},
{
id: 2,
name: "The Verdant Fracture",
color: "linear-gradient(to bottom, #134e5e, #71b280)",
description: "Life clings to the edges of the broken glass.",
enemies: [11, 12, 13, 14, 15],
boss: { id: 12, name: "Fracture-Bloom", stats: { hp: 300, atk: 32, def: 30, spd: 12 }, affinity: TYPES.VERIDIAN },
unlock: 3
},
{
id: 3,
name: "The Molten Lattice",
color: "linear-gradient(to bottom, #43a047, #d4e157)", // Wait, colors are wrong for molten
color: "linear-gradient(to bottom, #4b0000, #990000)",
description: "Heat flows through the veins of the world.",
enemies: [16, 17, 18, 19, 20],
boss: { id: 20, name: "Lattice-Core", stats: { hp: 400, atk: 40, def: 40, spd: 10 }, affinity: TYPES.CORUSCANT },
unlock: 4
},
{
id: 4,
name: "The Frozen Zenith",
color: "linear-gradient(to bottom, #00c6ff, #0072ff)",
description: "A high altitude of biting cold and crystal storms.",
enemies: [21, 22, 23, 24, 25],
boss: { id: 23, name: "Zenith-Stalker", stats: { hp: 500, atk: 50, def: 45, spd: 15 }, affinity: TYPES.STELLAR },
unlock: 5
},
{
id: 5,
name: "The Radiant Core",
color: "linear-gradient(to bottom, #f8ff00, #ff00e0)",
description: "The source of all resonance. The heart of the Glass.",
enemies: [26, 27],
boss: { id: 27, name: "Sunder-Architect", stats: { hp: 800, atk: 70, def: 60, spd: 40 }, affinity: TYPES.AETHERIC },
unlock: 6
}
];
class Game {
constructor() {
this.canvas = document.getElementById('gameCanvas');
this.ctx = this.canvas.getContext('2d');
this.state = 'TITLE'; // TITLE, OVERWORLD, BATTLE, CAPTURE, MENU, DIALOGUE
this.player = {
zone: 0,
team: [],
bag: [],
binding: null,
unlockedZones: 1,
totalCollected: 0,
experience: 0,
currentMove: null
};
this.world = null;
this.currentEnemies = [];
this.battleLog = "";
this.particles = [];
this.shakeTime = 0;
this.audioCtx = null;
this.lastTime = 0;
this.keys = {};
// Setup inputs
window.addEventListener('keydown', (e) => this.keys[e.code] = true);
window.addEventListener('keyup', (e) => this.keys[e.code] = false);
this.resize();
window.addEventListener('resize', () => this.resize());
// Start loop
requestAnimationFrame((t) => this.loop(t));
}
resize() {
this.canvas.width = this.canvas.offsetWidth;
this.canvas.height = this.canvas.offsetHeight;
}
init() {
this.state = 'OVERWORLD';
document.getElementById('title-screen').style.display = 'none';
document.getElementById('game-hud').style.display = 'flex';
this.setupOverworld();
this.createParticles();
this.startAudio();
this.showDialogue("Welcome to the Sunder-Glass. Use WASD to explore. Find a Resonant and engage in a Binding.");
}
startAudio() {
const AudioContext = window.AudioContext || window.webkitAudioContext;
this.audioCtx = new AudioContext();
}
playTone(freq, type, duration) {
if (!this.audioCtx) return;
const osc = this.audioCtx.createOscillator();
const gain = this.audioCtx.createGain();
osc.type = type;
osc.frequency.setValueAtTime(freq, this.audioCtx.currentTime);
gain.gain.setValueAtTime(0.1, this.audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, this.audioCtx.currentTime + duration);
osc.connect(gain);
gain.connect(this.audioCtx.destination);
osc.start();
osc.stop(this.audioCtx.currentTime + duration);
}
showDialogue(text) {
this.state = 'DIALOGUE';
const box = document.getElementById('dialogue-container');
const content = document.getElementById('dialogue-text');
box.style.display = 'block';
content.innerText = text;
setTimeout(() => {
box.style.display = 'none';
this.state = 'OVERWORLD';
}, 4000);
}
setupOverworld() {
// Initialize player position and map
this.player.pos = { x: 100, y: 100 };
this.world = {
grid: Array(20).fill().map(() => Array(20).fill(0)),
shrines: [{x: 5, y: 5}, {x: 15, y: 15}],
anchors: [{x: 19, y: 19}]
};
}
createParticles() {
for (let i = 0; i < 30; i++) {
this.particles.push({
x: Math.random() * this.canvas.width,
y: Math.random() * this.canvas.height,
vx: (Math.random() - 0.5) * 0.5,
vy: (Math.random() - 0.5) * 0.5,
size: Math.random() * 3
});
}
}
loop(timestamp) {
const dt = timestamp - this.lastTime;
this.lastTime = timestamp;
this.update(dt);
this.draw();
requestAnimationFrame((t) => this.loop(t));
}
update(dt) {
if (this.state === 'OVERWORLD') {
const speed = 3;
if (this.keys['KeyW'] || this.keys['ArrowUp']) this.player.pos.y -= speed;
if (this.keys['KeyS'] || this.keys['ArrowDown']) this.player.pos.y += speed;
if (this.keys['KeyA'] || this.keys['ArrowLeft']) this.player.pos.x -= speed;
if (this.keys['KeyD'] || this.keys['ArrowRight']) this.player.pos.x += speed;
// Keep in bounds
this.player.pos.x = Math.max(0, Math.min(this.canvas.width, this.player.pos.x));
this.player.pos.y = Math.max(0, Math.min(this.canvas.height, this.player.pos.y));
// Check Shrines
this.world.shrines.forEach(s => {
const dist = Math.hypot(this.player.pos.x - s.x * 40, this.player.pos.y - s.y * 40);
if (dist < 40) {
if (this.keys['Space']) {
this.healParty();
this.playTone(440, 'sine', 0.2);
}
}
});
// Random Encounters
if (Math.random() < 0.005) {
this.startBattle();
}
}
if (this.state === 'BATTLE') {
// Battle logic handled by state transitions
}
// Particle updates
this.particles.forEach(p => {
p.x += p.vx;
p.y += p.vy;
if (p.x < 0) p.x = this.canvas.width;
if (p.x > this.canvas.width) p.x = 0;
if (p.y < 0) p.y = this.canvas.height;
if (p.y > this.canvas.height) p.y = 0;
});
if (this.shakeTime > 0) this.shakeTime--;
}
draw() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (this.state === 'TITLE') {
this.ctx.fillStyle = 'white';
this.ctx.font = '20px Arial';
this.ctx.fillText("Press any key to start", this.canvas.width/2 - 100, this.canvas.height/2 + 100);
}
if (this.state === 'OVERWORLD') {
const zone = ZONES[this.player.zone];
const grad = this.ctx.createLinearGradient(0, 0, 0, this.canvas.height);
grad.addColorStop(0, '#0f0f1a');
grad.addColorStop(1, '#1a1a2e');
this.ctx.fillStyle = grad;
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// Draw Shrines
this.world.shrines.forEach(s => {
this.ctx.fillStyle = '#7faff1';
this.ctx.beginPath();
this.ctx.arc(s.x * 40, s.y * 40, 15, 0, Math.PI * 2);
this.ctx.fill();
this.ctx.shadowBlur = 15;
this.ctx.shadowColor = '#7faff1';
});
this.ctx.shadowBlur = 0;
// Draw Player
this.ctx.fillStyle = 'white';
this.ctx.beginPath();
this.ctx.arc(this.player.pos.x, this.player.pos.y, 10, 0, Math.PI * 2);
this.ctx.fill();
// Particles
this.particles.forEach(p => {
this.ctx.fillStyle = 'rgba(255,255,255,0.3)';
this.ctx.beginPath();
this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
this.ctx.fill();
});
// UI
document.getElementById('hud-zone').innerText = zone.name;
document.getElementById('hud-count').innerText = this.player.team.length;
}
if (this.state === 'BATTLE') {
this.drawBattle();
}
if (this.shakeTime > 0) {
this.ctx.translate(Math.random()*10-5, Math.random()*10-5);
}
}
drawBattle() {
const zone = ZONES[this.player.zone];
const grad = this.ctx.createLinearGradient(0, 0, 0, this.canvas.height);
grad.addColorStop(0, '#05050a');
grad.addColorStop(1, '#1a1a2e');
this.ctx.fillStyle = grad;
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// Draw Enemies
this.currentEnemies.forEach((e, i) => {
this.ctx.fillStyle = '#ff4444';
this.ctx.beginPath();
this.ctx.arc(this.canvas.width/2 + (i-1)*150, this.canvas.height/2 - 50, 40, 0, Math.PI*2);
this.ctx.fill();
// Enemy HP
const hpPerc = e.hp / e.maxHp;
this.ctx.fillStyle = 'red';
this.ctx.fillRect(this.canvas.width/2 + (i-1)*150 - 40, this.canvas.height/2 - 110, 80, 8);
this.ctx.fillStyle = 'green';
this.ctx.fillRect(this.canvas.width/2 + (i-1)*150 - 40, this.canvas.height/2 - 110, 80 * hpPerc, 8);
});
// Draw Party
const partyUI = document.getElementById('battle-party-ui');
partyUI.style.display = 'flex';
partyUI.innerHTML = '';
this.player.team.forEach(p => {
const slot = document.createElement('div');
slot.className = 'creature-slot';
const hpPerc = p.hp / p.maxHp;
slot.innerHTML = `
<div>${p.name}</div>
<div class="hp-bar-bg"><div class="hp-bar-fill" style="width:${hpPerc*100}%"></div></div>
`;
partyUI.appendChild(slot);
});
// Action Menu
const actionMenu = document.getElementById('action-menu');
actionMenu.style.display = 'grid';
actionMenu.innerHTML = '';
const activeResonant = this.player.team[0];
if (activeResonant) {
activeResonant.moves.forEach(moveId => {
const move = MOVES[moveId];
const btn = document.createElement('button');
btn.className = 'action-btn';
btn.innerHTML = `${move.desc}<br><small>${move.affinity}</small>`;
btn.onclick = () => this.executeMove(moveId);
actionMenu.appendChild(btn);
});
}
// Win/Loss overlay
if (this.currentEnemies.length === 0) {
this.victory();
} else if (this.player.team.length === 0) {
this.defeat();
}
}
startBattle() {
this.state = 'BATTLE';
document.getElementById('battle-ui').style.display = 'block';
document.getElementById('hud').style.display = 'none';
const zone = ZONES[this.player.zone];
const enemyData = CREATURE_DATA[Math.floor(Math.random() * zone.enemies.length)];
const stats = enemyData.stats;
this.currentEnemies = [{
...enemyData,
hp: stats.hp,
maxHp: stats.hp,
atk: stats.atk,
def: stats.def,
spd: stats.spd
}];
// If first time, give 3 starters
if (this.player.team.length === 0) {
this.player.team.push(this.cloneCreature(CREATURE_DATA[0]));
this.player.team.push(this.cloneCreature(CREATURE_DATA[1]));
this.player.team.push(this.cloneCreature(CREATURE_DATA[2]));
}
}
cloneCreature(data) {
return {
...data,
hp: data.stats.hp,
maxHp: data.stats.hp,
atk: data.stats.atk,
def: data.stats.def,
spd: data.stats.spd,
lvl: 1,
exp: 0
};
}
executeMove(moveId) {
const move = MOVES[moveId];
const attacker = this.player.team[0];
const defender = this.currentEnemies[0];
if (!attacker || !defender) return;
// Resolve damage
let multiplier = 1.0;
if (move.affinity === TYPES.AETHERIC) multiplier = 1.2;
// Type check
const defAffinity = defender.affinity;
if (TYPE_CHART[move.affinity]?.beats?.includes(defAffinity)) multiplier *= 1.5;
if (defAffinity === TYPES.STELLAR) {
multiplier *= 0.5;
if (move.affinity === TYPES.AETHERIC) multiplier *= 2.0;
}
// STAB
if (move.affinity === attacker.affinity) multiplier *= 1.25;
let baseDmg = (0.4 * attacker.lvl * attacker.atk / defender.def * move.power * multiplier);
baseDmg = Math.floor(baseDmg + (Math.random() * 5));
defender.hp -= Math.max(1, baseDmg);
this.shakeTime = 10;
this.playTone(200, 'sawtooth', 0.1);
if (defender.hp <= 0) {
this.currentEnemies.shift();
this.playTone(600, 'square', 0.2);
}
// Enemy Turn (Simple AI)
if (this.currentEnemies.length > 0) {
setTimeout(() => this.enemyTurn(), 500);
}
}
enemyTurn() {
const enemy = this.currentEnemies[0];
const target = this.player.team[Math.floor(Math.random() * this.player.team.length)];
if (enemy && target) {
const dmg = Math.floor(enemy.atk * 0.8);
target.hp -= dmg;
this.shakeTime = 5;
if (target.hp <= 0) {
this.player.team = this.player.team.filter(p => p.hp > 0);
}
}
}
victory() {
this.playTone(800, 'sine', 0.5);
this.state = 'OVERWORLD';
document.getElementById('battle-ui').style.display = 'none';
document.getElementById('hud').style.display = 'flex';
this.player.totalCollected++;
this.showDialogue("The Resonant has been bound to your essence. Your power grows.");
}
defeat() {
this.state = 'TITLE';
alert("Your binding was severed... Game Over.");
location.reload();
}
healParty() {
this.player.team.forEach(p => {
p.hp = p.maxHp;
});
this.playTone(880, 'sine', 0.1);
}
save() {
const data = {
player: this.player,
world: this.world
};
localStorage.setItem('sunderGlass_save', JSON.stringify(data));
this.showDialogue("Resonance anchored to the Glass.");
}
load() {
const raw = localStorage.getItem('sunderGlass_save');
if (raw) {
const data = JSON.parse(raw);
this.player = data.player;
this.world = data.world;
this.state = 'OVERWORLD';
document.getElementById('title-screen').style.display = 'none';
document.getElementById('game-hud').style.display = 'flex';
this.setupOverworld();
}
}
}
const game = new Game();
</script>
</body>
</html>
<!-- agent-meta {"model":"google/gemma-4-12b-qat","provider":"lmstudio","persona":"middle","sessionId":"2f8f3b6b-0338-47f4-b55f-77c5419d45f5","tokensIn":2047,"tokensOut":12844,"tokensTotal":14891,"turns":1,"toolCalls":0,"failedToolCalls":0,"timestamp":"2026-07-14T00:08:08.140Z"} -->