← Creature Collection results

Creature Collection

Gemma 4 12b qat · middle

Initial view of Creature Collection

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"} -->