← Back to Articles Directory
AI Models • August 13, 2026 • 5 min read

Gemini 3.7 Flash Released: Specs, Benchmarks & Interactive Coding Tests

Google released Gemini 3.7 Flash today, August 13, 2026. Featuring a 1M token context window, $0.75/$3.75 pricing, and an Artificial Analysis score of 56, we run hands-on vector SVG and 3D WebGL game coding tests.

Mohid Mirza

Co-Founder & Lead Programmer of AcceleratedLogic AI

After the incremental improvement of Gemini 3.6 Flash, Google has struck again with Gemini 3.7 Flash, another incremental improvement. Apparently, it was supposed to be Gemini 3.5 Pro, but after it underperformed, DeepMind simply rebranded it.

Model Specs & Pricing

Let’s talk about its specs. It has a 1M token context window, costs $0.75/M input tokens and $3.75/M output tokens (but it has a 50% off sale right now on OpenRouter). It scores a 56 on the Intelligence Index, 3 points above DeepSeek V4 Pro 0813, but in Arena.ai’s leaderboard, it scores around the same. So, let’s run it through the usual benchmarks, plus some more, as I do think this is a really interesting model.

Test 1: Photorealistic 3D Glass Sphere with Origami Crane

We’ll be using Google AI Studio to try out this model. For the SVG origami crane generation, it outputted this self-contained vector illustration:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Photorealistic 3D Glass Sphere with Origami Crane</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        body {
            background: radial-gradient(circle at 50% 30%, #16192b 0%, #090a10 70%, #030407 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        }
        .container {
            position: relative;
            width: 100vw;
            height: 100vh;
            max-width: 1000px;
            max-height: 1000px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        svg {
            width: 100%;
            height: 100%;
            filter: drop-shadow(0 30px 50px rgba(0, 0, 0, 0.8));
        }
    </style>
</head>
<body>
    <div class="container">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="100%" height="100%">
            <defs>
                <!-- Ground & Ambient Shadows -->
                <radialGradient id="groundFloor" cx="50%" cy="50%" r="50%">
                    <stop offset="0%" stop-color="#000000" stop-opacity="0.7"/>
                    <stop offset="40%" stop-color="#000000" stop-opacity="0.4"/>
                    <stop offset="75%" stop-color="#04060a" stop-opacity="0.1"/>
                    <stop offset="100%" stop-color="#04060a" stop-opacity="0"/>
                </radialGradient>

                <radialGradient id="contactShadow" cx="50%" cy="50%" r="50%">
                    <stop offset="0%" stop-color="#000000" stop-opacity="0.95"/>
                    <stop offset="25%" stop-color="#000000" stop-opacity="0.7"/>
                    <stop offset="60%" stop-color="#020408" stop-opacity="0.2"/>
                    <stop offset="100%" stop-color="#020408" stop-opacity="0"/>
                </radialGradient>

                <!-- Caustic Glow Under Glass -->
                <radialGradient id="causticGround" cx="45%" cy="45%" r="50%">
                    <stop offset="0%" stop-color="#6df0ff" stop-opacity="0.55"/>
                    <stop offset="25%" stop-color="#2d8bba" stop-opacity="0.3"/>
                    <stop offset="55%" stop-color="#c58bff" stop-opacity="0.12"/>
                    <stop offset="85%" stop-color="#0a1828" stop-opacity="0.03"/>
                    <stop offset="100%" stop-color="#000000" stop-opacity="0"/>
                </radialGradient>

                <!-- Sphere Environment Base & Rim Backing -->
                <radialGradient id="sphereBackdrop" cx="38%" cy="32%" r="68%">
                    <stop offset="0%" stop-color="#1b2438" stop-opacity="0.25"/>
                    <stop offset="45%" stop-color="#0a101d" stop-opacity="0.5"/>
                    <stop offset="75%" stop-color="#04070f" stop-opacity="0.75"/>
                    <stop offset="92%" stop-color="#152942" stop-opacity="0.85"/>
                    <stop offset="100%" stop-color="#4ce8ff" stop-opacity="0.95"/>
                </radialGradient>

                <!-- Dark Inner Absorption Gradient (Thickness) -->
                <radialGradient id="glassThickness" cx="50%" cy="50%" r="50%">
                    <stop offset="70%" stop-color="#000000" stop-opacity="0"/>
                    <stop offset="88%" stop-color="#020914" stop-opacity="0.35"/>
                    <stop offset="96%" stop-color="#08223c" stop-opacity="0.7"/>
                    <stop offset="100%" stop-color="#3ae7ff" stop-opacity="0.9"/>
                </radialGradient>

                <!-- Inner Caustic Orb -->
                <radialGradient id="innerCausticGlow" cx="42%" cy="65%" r="45%">
                    <stop offset="0%" stop-color="#ffffff" stop-opacity="0.45"/>
                    <stop offset="25%" stop-color="#55e1ff" stop-opacity="0.25"/>
                    <stop offset="55%" stop-color="#9d4edd" stop-opacity="0.1"/>
                    <stop offset="100%" stop-color="#000000" stop-opacity="0"/>
                </radialGradient>

                <!-- Front Glass Fresnel Reflection Envelope -->
                <radialGradient id="fresnelFront" cx="35%" cy="30%" r="65%">
                    <stop offset="0%" stop-color="#ffffff" stop-opacity="0.15"/>
                    <stop offset="40%" stop-color="#ffffff" stop-opacity="0.02"/>
                    <stop offset="75%" stop-color="#4aa8ff" stop-opacity="0.08"/>
                    <stop offset="94%" stop-color="#70e5ff" stop-opacity="0.4"/>
                    <stop offset="98%" stop-color="#ffffff" stop-opacity="0.85"/>
                    <stop offset="100%" stop-color="#2675a8" stop-opacity="0.2"/>
                </radialGradient>

                <!-- Primary Key Light Highlight (Softbox Studio Reflection) -->
                <linearGradient id="mainSoftbox" x1="0%" y1="0%" x2="70%" y2="80%">
                    <stop offset="0%" stop-color="#ffffff" stop-opacity="0.95"/>
                    <stop offset="20%" stop-color="#eaf9ff" stop-opacity="0.8"/>
                    <stop offset="55%" stop-color="#80d4ff" stop-opacity="0.25"/>
                    <stop offset="85%" stop-color="#ffffff" stop-opacity="0"/>
                </linearGradient>

                <!-- Secondary Backlight Highlight -->
                <linearGradient id="secondaryGlow" x1="100%" y1="100%" x2="20%" y2="20%">
                    <stop offset="0%" stop-color="#845ec2" stop-opacity="0.6"/>
                    <stop offset="35%" stop-color="#d65db1" stop-opacity="0.2"/>
                    <stop offset="70%" stop-color="#ff6f91" stop-opacity="0"/>
                </linearGradient>

                <!-- Bottom Ground Bounce / Refraction Arch -->
                <linearGradient id="bottomBounce" x1="0%" y1="100%" x2="0%" y2="0%">
                    <stop offset="0%" stop-color="#4eedff" stop-opacity="0.75"/>
                    <stop offset="20%" stop-color="#005b99" stop-opacity="0.4"/>
                    <stop offset="60%" stop-color="#001829" stop-opacity="0"/>
                </linearGradient>

                <!-- ================= ORIGAMI CRANE GRADIENTS ================= -->
                <!-- Paper Textures and Realistic Light/Shade Facets -->
                <!-- Left Wing Main Top (Keylight Lit) -->
                <linearGradient id="p_left_wing_top" x1="30%" y1="10%" x2="80%" y2="90%">
                    <stop offset="0%" stop-color="#ffffff"/>
                    <stop offset="45%" stop-color="#e3ecf5"/>
                    <stop offset="100%" stop-color="#adc4d9"/>
                </linearGradient>

                <!-- Left Wing Outer Fold -->
                <linearGradient id="p_left_wing_mid" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#e1ebf5"/>
                    <stop offset="50%" stop-color="#bacddb"/>
                    <stop offset="100%" stop-color="#7d9cb8"/>
                </linearGradient>

                <!-- Left Wing Underside Shadow -->
                <linearGradient id="p_left_wing_under" x1="0%" y1="30%" x2="100%" y2="70%">
                    <stop offset="0%" stop-color="#46627f"/>
                    <stop offset="60%" stop-color="#2d4359"/>
                    <stop offset="100%" stop-color="#1d2e3f"/>
                </linearGradient>

                <!-- Right Wing Back Turn -->
                <linearGradient id="p_right_wing_top" x1="10%" y1="0%" x2="90%" y2="100%">
                    <stop offset="0%" stop-color="#c2daf0"/>
                    <stop offset="50%" stop-color="#8aa6bf"/>
                    <stop offset="100%" stop-color="#46627a"/>
                </linearGradient>
                
                <linearGradient id="p_right_wing_back" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#799cb8"/>
                    <stop offset="100%" stop-color="#3c5770"/>
                </linearGradient>

                <!-- Body Facets -->
                <linearGradient id="p_body_front_left" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#ffffff"/>
                    <stop offset="60%" stop-color="#d6e4f0"/>
                    <stop offset="100%" stop-color="#9ab5cc"/>
                </linearGradient>

                <linearGradient id="p_body_front_right" x1="0%" y1="0%" x2="80%" y2="100%">
                    <stop offset="0%" stop-color="#bacfe3"/>
                    <stop offset="60%" stop-color="#7d9db8"/>
                    <stop offset="100%" stop-color="#4e6d87"/>
                </linearGradient>

                <linearGradient id="p_body_keel_dark" x1="0%" y1="0%" x2="0%" y2="100%">
                    <stop offset="0%" stop-color="#334b61"/>
                    <stop offset="100%" stop-color="#1c2d3d"/>
                </linearGradient>

                <linearGradient id="p_body_top_crease" x1="0%" y1="0%" x2="100%" y2="50%">
                    <stop offset="0%" stop-color="#ffffff"/>
                    <stop offset="100%" stop-color="#c9dded"/>
                </linearGradient>

                <!-- Tail Facets -->
                <linearGradient id="p_tail_left" x1="20%" y1="0%" x2="80%" y2="100%">
                    <stop offset="0%" stop-color="#dbe8f5"/>
                    <stop offset="50%" stop-color="#9abddb"/>
                    <stop offset="100%" stop-color="#557591"/>
                </linearGradient>

                <linearGradient id="p_tail_underside" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#3a566f"/>
                    <stop offset="100%" stop-color="#1a2b38"/>
                </linearGradient>

                <!-- Neck Facets -->
                <linearGradient id="p_neck_left" x1="30%" y1="0%" x2="70%" y2="100%">
                    <stop offset="0%" stop-color="#ffffff"/>
                    <stop offset="40%" stop-color="#d6e5f2"/>
                    <stop offset="100%" stop-color="#95b5cf"/>
                </linearGradient>

                <linearGradient id="p_neck_right" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#8cb0cc"/>
                    <stop offset="70%" stop-color="#4b6d87"/>
                    <stop offset="100%" stop-color="#2c4457"/>
                </linearGradient>

                <!-- Head & Beak Facets -->
                <linearGradient id="p_head_crown" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#ffffff"/>
                    <stop offset="60%" stop-color="#c5ddf0"/>
                    <stop offset="100%" stop-color="#80a5c4"/>
                </linearGradient>

                <linearGradient id="p_head_side" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#a4c6e3"/>
                    <stop offset="100%" stop-color="#3a5870"/>
                </linearGradient>

                <linearGradient id="p_beak_tip" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#ffb88c"/>
                    <stop offset="100%" stop-color="#de6262"/>
                </linearGradient>

                <!-- Internal Crane Warm Subsurface Glow -->
                <radialGradient id="craneSubsurface" cx="45%" cy="45%" r="50%">
                    <stop offset="0%" stop-color="#ffeedd" stop-opacity="0.3"/>
                    <stop offset="60%" stop-color="#8adfff" stop-opacity="0.1"/>
                    <stop offset="100%" stop-color="#000000" stop-opacity="0"/>
                </radialGradient>

                <!-- Filters for Realistic Optics -->
                <!-- Deep Blur for Distant Dropped Shadows -->
                <filter id="blurGround" x="-50%" y="-50%" width="200%" height="200%">
                    <feGaussianBlur in="SourceGraphic" stdDeviation="38"/>
                </filter>
                
                <filter id="blurContact" x="-50%" y="-50%" width="200%" height="200%">
                    <feGaussianBlur in="SourceGraphic" stdDeviation="8"/>
                </filter>

                <filter id="blurCaustic" x="-50%" y="-50%" width="200%" height="200%">
                    <feGaussianBlur in="SourceGraphic" stdDeviation="18"/>
                </filter>

                <filter id="craneInternalShadow" x="-20%" y="-20%" width="140%" height="140%">
                    <feGaussianBlur in="SourceAlpha" stdDeviation="10"/>
                    <feOffset dx="12" dy="25"/>
                    <feComponentTransfer><feFuncA type="linear" slope="0.45"/></feComponentTransfer>
                    <feMerge>
                        <feMergeNode/>
                        <feMergeNode in="SourceGraphic"/>
                    </feMerge>
                </filter>

                <filter id="softGlow" x="-30%" y="-30%" width="160%" height="160%">
                    <feGaussianBlur stdDeviation="6" result="blur"/>
                    <feMerge>
                        <feMergeNode in="blur"/>
                        <feMergeNode in="SourceGraphic"/>
                    </feMerge>
                </filter>

                <!-- Sphere Clip Path to Contain Internal Elements -->
                <clipPath id="sphereInteriorClip">
                    <circle cx="500" cy="460" r="260"/>
                </clipPath>
            </defs>

            <!-- ================= 1. GROUND SHADOWS & CAUSTICS ================= -->
            <g id="groundPlane">
                <!-- Broad ambient ground shadow -->
                <ellipse cx="500" cy="775" rx="360" ry="85" fill="url(#groundFloor)" filter="url(#blurGround)"/>
                
                <!-- Vibrant caustic focus pool beneath the sphere -->
                <ellipse cx="485" cy="765" rx="210" ry="52" fill="url(#causticGround)" filter="url(#blurCaustic)" style="mix-blend-mode: screen;"/>
                <ellipse cx="480" cy="760" rx="120" ry="28" fill="#a6f5ff" opacity="0.45" filter="url(#blurContact)" style="mix-blend-mode: screen;"/>
                <ellipse cx="475" cy="758" rx="55" ry="14" fill="#ffffff" opacity="0.75" filter="url(#blurContact)" style="mix-blend-mode: screen;"/>

                <!-- Tight contact occlusion shadow right at touch point -->
                <ellipse cx="500" cy="720" rx="85" ry="14" fill="url(#contactShadow)" filter="url(#blurContact)"/>
                <ellipse cx="500" cy="720" rx="42" ry="6" fill="#000000" opacity="0.95"/>
            </g>

            <!-- ================= 2. GLASS SPHERE BACK LAYER ================= -->
            <g id="sphereBackground">
                <!-- Base Outer Rim Boundary -->
                <circle cx="500" cy="460" r="260" fill="url(#sphereBackdrop)"/>
                
                <!-- Inner Backlight/Internal Caustic Core -->
                <circle cx="500" cy="460" r="258" fill="url(#innerCausticGlow)" style="mix-blend-mode: screen;"/>
            </g>

            <!-- ================= 3. INTERNAL 3D ORIGAMI CRANE (Inside Glass) ================= -->
            <g id="internalScene" clip-path="url(#sphereInteriorClip)">
                <!-- Ambient Internal Light Field -->
                <radialGradient id="craneBackGlow" cx="420" cy="400" r="250" gradientUnits="userSpaceOnUse">
                    <stop offset="0%" stop-color="#48a6ff" stop-opacity="0.3"/>
                    <stop offset="50%" stop-color="#733add" stop-opacity="0.1"/>
                    <stop offset="100%" stop-color="#000000" stop-opacity="0"/>
                </radialGradient>
                <circle cx="500" cy="460" r="260" fill="url(#craneBackGlow)" style="mix-blend-mode: screen;"/>

                <!-- Internal Crane Drop Shadow on Back Inner Glass Wall -->
                <g opacity="0.55" transform="translate(18, 32) scale(0.96) skewX(-4)" filter="url(#blurContact)">
                    <path d="M 500,485 L 340,360 L 260,335 L 310,380 L 445,475 L 430,555 L 485,595 L 500,600 L 515,595 L 570,555 L 555,475 L 690,380 L 740,335 L 660,360 Z" fill="#030c17"/>
                </g>

                <!-- THE 3D ORIGAMI CRANE -->
                <g id="origamiCrane" filter="url(#craneInternalShadow)">

                    <!-- === REAR PARTS (Distant / Shadowed Facets) === -->
                    <!-- Tail - Underside / Back Fold -->
                    <polygon points="500,485 555,475 675,370 540,515" fill="url(#p_tail_underside)"/>
                    <!-- Tail - Left/Upper Plane (Facing Light) -->
                    <polygon points="500,485 675,370 705,355 530,520" fill="url(#p_tail_left)" stroke="#9bc7e8" stroke-width="0.35" stroke-linejoin="round"/>

                    <!-- Right Wing (Distant Wing - Tilted Away in Perspective) -->
                    <!-- Right Wing Lower Hull Fold -->
                    <polygon points="500,485 540,515 680,260" fill="url(#p_right_wing_back)"/>
                    <!-- Right Wing Main Triangular Blade -->
                    <polygon points="500,460 500,485 680,260" fill="url(#p_right_wing_top)" stroke="#8cbfe6" stroke-width="0.4"/>
                    <!-- Right Wing Secondary Upper Facet -->
                    <polygon points="500,460 680,260 625,245" fill="#a4cbe8" opacity="0.9"/>

                    <!-- === CENTRAL BODY STRUCTURE === -->
                    <!-- Body Under-Keel Keystones (Shadow Anchor) -->
                    <polygon points="500,580 470,525 500,545" fill="url(#p_body_keel_dark)"/>
                    <polygon points="500,580 530,525 500,545" fill="#131e28"/>
                    
                    <!-- Body Low Side Triangles -->
                    <polygon points="445,490 470,525 500,545 470,490" fill="#4d6b85"/>
                    <polygon points="555,490 530,525 500,545 530,490" fill="#2d4254"/>

                    <!-- Body Central Diamond - Left Half (Main Lit Plane) -->
                    <polygon points="500,460 445,490 470,530 500,575" fill="url(#p_body_front_left)" stroke="#ffffff" stroke-width="0.5" stroke-linejoin="round"/>
                    
                    <!-- Body Central Diamond - Right Half (Shaded Plane) -->
                    <polygon points="500,460 555,490 530,530 500,575" fill="url(#p_body_front_right)" stroke="#a1c3de" stroke-width="0.5" stroke-linejoin="round"/>

                    <!-- Center Dorsal Ridge Pyramid -->
                    <polygon points="500,460 470,490 500,505" fill="url(#p_body_top_crease)"/>
                    <polygon points="500,460 530,490 500,505" fill="#88a8c4"/>

                    <!-- === FOREGROUND LEFT WING (Spectacular Fold Dynamics) === -->
                    <!-- Left Wing Underside Drop Triangle -->
                    <polygon points="500,460 445,490 310,230" fill="url(#p_left_wing_under)"/>
                    
                    <!-- Left Wing Main Facet (Reflecting Vast Light) -->
                    <polygon points="500,460 460,450 280,210 310,230" fill="url(#p_left_wing_top)" stroke="#ffffff" stroke-width="0.6" stroke-linejoin="round"/>
                    
                    <!-- Left Wing Outer Crisp Edge Blade -->
                    <polygon points="460,450 280,210 245,220 375,385" fill="url(#p_left_wing_mid)" stroke="#e1f0fa" stroke-width="0.4"/>
                    
                    <!-- Left Wing Inner Accordion Gusset -->
                    <polygon points="445,490 460,450 375,385 410,465" fill="#698ca8"/>

                    <!-- === NECK, HEAD AND BEAK === -->
                    <!-- Neck Base Trunk -->
                    <polygon points="500,485 460,480 370,390 435,465" fill="#7599b8"/>
                    
                    <!-- Neck Long Column - Left Lit Edge -->
                    <polygon points="460,480 370,390 340,320 375,335" fill="url(#p_neck_left)" stroke="#ffffff" stroke-width="0.4" stroke-linejoin="round"/>
                    
                    <!-- Neck Long Column - Right Shaded Flange -->
                    <polygon points="500,485 435,465 375,335 405,345" fill="url(#p_neck_right)" stroke="#5d83a1" stroke-width="0.3"/>

                    <!-- Head Reverse Fold Peak -->
                    <polygon points="340,320 375,335 345,305 315,310" fill="url(#p_head_crown)" stroke="#ffffff" stroke-width="0.4"/>
                    <polygon points="375,335 405,345 355,315 345,305" fill="url(#p_head_side)"/>

                    <!-- Folded Beak Drooping Forward -->
                    <polygon points="315,310 345,305 285,325" fill="url(#p_beak_tip)" stroke="#ffe1cc" stroke-width="0.3"/>
                    <polygon points="345,305 355,315 285,325" fill="#ab3c3c"/>

                    <!-- Micro Edge Highlights (Origami Paper Crease Crispness) -->
                    <polyline points="280,210 500,460 680,260" fill="none" stroke="#ffffff" stroke-width="0.9" opacity="0.85" filter="url(#softGlow)"/>
                    <polyline points="285,325 345,305 375,335 460,480 500,575" fill="none" stroke="#ffffff" stroke-width="0.75" opacity="0.7"/>
                    <polyline points="500,460 500,575" fill="none" stroke="#ffffff" stroke-width="0.8" opacity="0.9"/>
                    <polyline points="705,355 500,485" fill="none" stroke="#e0f2fe" stroke-width="0.6" opacity="0.6"/>

                    <!-- Delicate Origami Paper Texture / Translucency Sheen -->
                    <ellipse cx="440" cy="420" rx="90" ry="120" fill="url(#craneSubsurface)" style="mix-blend-mode: screen; pointer-events: none;"/>
                </g>

                <!-- Internal Caustic Rings & Spherical Internal Aberration Rays -->
                <path d="M 280,420 Q 320,620 500,680 Q 660,630 710,450 C 660,600 520,650 350,560 Z" fill="#2be7ff" opacity="0.25" style="mix-blend-mode: screen;" filter="url(#blurContact)"/>
                <path d="M 320,380 Q 400,670 600,640 C 460,660 360,540 320,380 Z" fill="#b04eff" opacity="0.2" style="mix-blend-mode: screen;" filter="url(#blurContact)"/>
                
                <!-- Internal Floating Micro Refraction Specks -->
                <circle cx="360" cy="480" r="2.5" fill="#ffffff" opacity="0.6" filter="url(#softGlow)"/>
                <circle cx="580" cy="380" r="1.8" fill="#ffffff" opacity="0.7" filter="url(#softGlow)"/>
                <circle cx="420" cy="270" r="1.5" fill="#aae7ff" opacity="0.5"/>
                <circle cx="630" cy="510" r="2" fill="#88f4ff" opacity="0.6"/>
                <circle cx="490" cy="620" r="2.2" fill="#ffffff" opacity="0.4" filter="url(#softGlow)"/>
            </g>

            <!-- ================= 4. GLASS THICKNESS & FRONT REFRACTIONS ================= -->
            <!-- 3D Glass Shell Body Absorptive Thickness Ring -->
            <circle cx="500" cy="460" r="260" fill="url(#glassThickness)" style="mix-blend-mode: multiply;"/>
            <circle cx="500" cy="460" r="260" fill="url(#glassThickness)" opacity="0.6" style="mix-blend-mode: color-dodge;"/>

            <!-- Front Fresnel Translucent Skin -->
            <circle cx="500" cy="460" r="260" fill="url(#fresnelFront)" style="mix-blend-mode: screen;"/>

            <!-- ================= 5. CURVED SPECULAR GLOSS & REFLECTIONS (The 3D Glass Polish) ================= -->
            <!-- Glass Bottom Ambient Ground Bounce Light Arc -->
            <path d="M 290,560 C 330,680 430,718 500,718 C 570,718 670,680 710,560 C 665,660 580,698 500,698 C 420,698 335,660 290,560 Z" fill="url(#bottomBounce)" style="mix-blend-mode: screen;"/>
            
            <path d="M 370,660 C 430,705 570,705 630,660 C 575,688 425,688 370,660 Z" fill="#ffffff" opacity="0.65" filter="url(#blurContact)" style="mix-blend-mode: screen;"/>

            <!-- Glass Rim Thin Edge Highlight (Surround Fresnel Rim) -->
            <circle cx="500" cy="460" r="258.5" fill="none" stroke="url(#mainSoftbox)" stroke-width="2.5" opacity="0.85" style="mix-blend-mode: screen;"/>
            
            <!-- Secondary Magenta/Violet Edge Rim Light (Right Flank) -->
            <path d="M 680,280 C 745,350 765,470 730,570 C 715,500 710,400 660,330 Z" fill="url(#secondaryGlow)" opacity="0.7" style="mix-blend-mode: screen;" filter="url(#softGlow)"/>

            <!-- PRIMARY STUDIO SOFTBOX REFLECTION (Top-Left Curved Specular) -->
            <g style="mix-blend-mode: screen;">
                <!-- Big Smooth Curved Window Highlight -->
                <path d="M 310,285 C 335,225 400,195 470,205 C 430,225 385,255 360,305 C 345,335 340,380 345,415 C 325,375 320,325 310,285 Z" fill="url(#mainSoftbox)" filter="url(#blurContact)"/>
                
                <!-- Intense Hotspot Center Flare inside Softbox -->
                <path d="M 345,265 C 365,225 415,212 455,218 C 425,232 390,252 375,285 C 365,308 362,342 366,365 C 352,335 348,295 345,265 Z" fill="#ffffff" opacity="0.95" filter="url(#softGlow)"/>

                <!-- Super Hot Tiny Specular Apex Core -->
                <ellipse cx="378" cy="265" rx="18" ry="32" transform="rotate(-30 378 265)" fill="#ffffff"/>
                <circle cx="378" cy="265" r="45" fill="#8ae3ff" opacity="0.5" filter="url(#blurContact)"/>
            </g>

            <!-- Secondary Overhead Pinpoint Light Spot -->
            <ellipse cx="490" cy="212" rx="45" ry="6" fill="#ffffff" opacity="0.4" filter="url(#softGlow)" style="mix-blend-mode: screen;"/>
            <ellipse cx="262" cy="450" rx="4" ry="38" transform="rotate(8 262 450)" fill="#78d5ff" opacity="0.5" filter="url(#softGlow)" style="mix-blend-mode: screen;"/>

            <!-- Subtle Front Diagonal Sheen Visor (Gives Spherical Glass Volume) -->
            <path d="M 275,360 C 360,250 560,240 700,310 C 600,270 410,280 300,420 C 285,400 280,380 275,360 Z" fill="#ffffff" opacity="0.12" style="mix-blend-mode: screen;" filter="url(#blurContact)"/>
        </svg>
    </div>
</body>
</html>
Evaluation: It’s actually quite good, with the crane and glass looking really realistic. My only gripe is that the crane’s head is covered a little.

Test 2: 3D Procedural Globe Generation

Next up: the world generation benchmark featuring a full Three.js procedural globe with custom Simplex noise shaders and particle rings:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Procedural Globe</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            user-select: none;
        }

        body {
            background-color: #030308;
            overflow: hidden;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            color: #ffffff;
            width: 100vw;
            height: 100vh;
        }

        #canvas-container {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
        }

        /* Glassmorphism UI Overlay */
        .ui-panel {
            position: absolute;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(13, 17, 28, 0.7);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            border: 1px solid rgba(255, 255, 255, 0.12);
            border-radius: 16px;
            padding: 16px 24px;
            display: flex;
            flex-direction: column;
            gap: 10px;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6), 0 0 20px rgba(64, 150, 255, 0.1);
            min-width: 280px;
            z-index: 10;
        }

        .ui-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 0.85rem;
            letter-spacing: 0.05em;
            text-transform: uppercase;
            color: #8da2c0;
        }

        .ui-header span#speed-display {
            color: #4facfe;
            font-weight: 600;
            font-family: monospace;
            font-size: 0.95rem;
        }

        .slider-container {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        input[type="range"] {
            -webkit-appearance: none;
            appearance: none;
            width: 100%;
            height: 6px;
            border-radius: 3px;
            background: #1e293b;
            outline: none;
            cursor: pointer;
        }

        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: #00f2fe;
            box-shadow: 0 0 10px #00f2fe, 0 0 20px rgba(0, 242, 254, 0.4);
            cursor: pointer;
            transition: transform 0.1s ease;
        }

        input[type="range"]::-webkit-slider-thumb:hover {
            transform: scale(1.15);
        }

        input[type="range"]::-moz-range-thumb {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: #00f2fe;
            border: none;
            box-shadow: 0 0 10px #00f2fe, 0 0 20px rgba(0, 242, 254, 0.4);
            cursor: pointer;
        }

        .info-hint {
            position: absolute;
            top: 20px;
            left: 20px;
            font-size: 0.8rem;
            color: rgba(255, 255, 255, 0.4);
            pointer-events: none;
            letter-spacing: 0.04em;
        }
    </style>
    <!-- Three.js and OrbitControls via CDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
</head>
<body>

    <div id="canvas-container"></div>
    <div class="info-hint">DRAG TO ROTATE &bull; SCROLL TO ZOOM</div>

    <div class="ui-panel">
        <div class="ui-header">
            <span>Rotation Speed</span>
            <span id="speed-display">1.0x</span>
        </div>
        <div class="slider-container">
            <input type="range" id="rotation-slider" min="0" max="4" step="0.1" value="1.0">
        </div>
    </div>

    <script>
        // --- FAST 3D SIMPLEX NOISE GENERATOR ---
        // Generates seamless procedural continents directly on spherical coordinates
        const SimplexNoise = (function() {
            const F3 = 1.0 / 3.0, G3 = 1.0 / 6.0;
            const p = new Uint8Array(256);
            for (let i = 0; i < 256; i++) p[i] = Math.floor(Math.random() * 256);
            const perm = new Uint8Array(512), permMod12 = new Uint8Array(512);
            for (let i = 0; i < 512; i++) {
                perm[i] = p[i & 255];
                permMod12[i] = (perm[i] % 12);
            }
            const grad3 = new Float32Array([
                1,1,0, -1,1,0, 1,-1,0, -1,-1,0,
                1,0,1, -1,0,1, 1,0,-1, -1,0,-1,
                0,1,1, 0,-1,1, 0,1,-1, 0,-1,-1
            ]);
            return {
                noise: function(xin, yin, zin) {
                    let n0, n1, n2, n3;
                    const s = (xin + yin + zin) * F3;
                    const i = Math.floor(xin + s), j = Math.floor(yin + s), k = Math.floor(zin + s);
                    const t = (i + j + k) * G3;
                    const X0 = i - t, Y0 = j - t, Z0 = k - t;
                    const x0 = xin - X0, y0 = yin - Y0, z0 = zin - Z0;
                    let i1, j1, k1, i2, j2, k2;
                    if (x0 >= y0) {
                        if (y0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; }
                        else if (x0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; }
                        else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; }
                    } else {
                        if (y0 < z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; }
                        else if (x0 < z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; }
                        else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; }
                    }
                    const x1 = x0 - i1 + G3, y1 = y0 - j1 + G3, z1 = z0 - k1 + G3;
                    const x2 = x0 - i2 + 2.0 * G3, y2 = y0 - j2 + 2.0 * G3, z2 = z0 - k2 + 2.0 * G3;
                    const x3 = x0 - 1.0 + 3.0 * G3, y3 = y0 - 1.0 + 3.0 * G3, z3 = z0 - 1.0 + 3.0 * G3;
                    const ii = i & 255, jj = j & 255, kk = k & 255;
                    let t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
                    if (t0 < 0) n0 = 0.0;
                    else {
                        const gi0 = permMod12[ii + perm[jj + perm[kk]]] * 3;
                        t0 *= t0;
                        n0 = t0 * t0 * (grad3[gi0]*x0 + grad3[gi0+1]*y0 + grad3[gi0+2]*z0);
                    }
                    let t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
                    if (t1 < 0) n1 = 0.0;
                    else {
                        const gi1 = permMod12[ii + i1 + perm[jj + j1 + perm[kk + k1]]] * 3;
                        t1 *= t1;
                        n1 = t1 * t1 * (grad3[gi1]*x1 + grad3[gi1+1]*y1 + grad3[gi1+2]*z1);
                    }
                    let t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
                    if (t2 < 0) n2 = 0.0;
                    else {
                        const gi2 = permMod12[ii + i2 + perm[jj + j2 + perm[kk + k2]]] * 3;
                        t2 *= t2;
                        n2 = t2 * t2 * (grad3[gi2]*x2 + grad3[gi2+1]*y2 + grad3[gi2+2]*z2);
                    }
                    let t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
                    if (t3 < 0) n3 = 0.0;
                    else {
                        const gi3 = permMod12[ii + 1 + perm[jj + 1 + perm[kk + 1]]] * 3;
                        t3 *= t3;
                        n3 = t3 * t3 * (grad3[gi3]*x3 + grad3[gi3+1]*y3 + grad3[gi3+2]*z3);
                    }
                    return 32.0 * (n0 + n1 + n2 + n3);
                }
            };
        })();

        // Fractal Brownian Motion
        function fbm(x, y, z, octaves = 5) {
            let val = 0, amp = 0.5, freq = 1.0;
            for (let i = 0; i < octaves; i++) {
                val += amp * SimplexNoise.noise(x * freq, y * freq, z * freq);
                freq *= 2.0;
                amp *= 0.5;
            }
            return val;
        }

        // --- PROCEDURAL TEXTURE GENERATION ---
        function createGlobeTexture() {
            const width = 2048, height = 1024;
            const canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            const ctx = canvas.getContext('2d');
            const imgData = ctx.createImageData(width, height);
            const data = imgData.data;

            for (let y = 0; y < height; y++) {
                const lat = ((y / height) - 0.5) * Math.PI; // -PI/2 to PI/2
                const sinLat = Math.sin(lat);
                const cosLat = Math.cos(lat);
                const absLat = Math.abs(lat) / (Math.PI / 2); // 0 at equator, 1 at poles

                for (let x = 0; x < width; x++) {
                    const lon = (x / width) * Math.PI * 2; // 0 to 2PI
                    const nx = cosLat * Math.sin(lon);
                    const ny = sinLat;
                    const nz = cosLat * Math.cos(lon);

                    // Generate spherical elevation
                    let n = fbm(nx * 1.5, ny * 1.5, nz * 1.5, 6);
                    let elevation = (n + 1) * 0.5; // 0.0 to 1.0

                    // Polar ice caps
                    let iceFactor = Math.pow(absLat, 4) * 1.6;
                    let isIce = (elevation + iceFactor) > 0.85;

                    let r, g, b;

                    if (isIce && absLat > 0.65) {
                        // Ice caps
                        r = 230 + Math.random() * 25;
                        g = 240 + Math.random() * 15;
                        b = 255;
                    } else if (elevation < 0.48) {
                        // Deep Ocean
                        r = 5; g = 18; b = 48;
                    } else if (elevation < 0.52) {
                        // Shallow Coast / Shelf
                        r = 15; g = 65; b = 95;
                    } else if (elevation < 0.54) {
                        // Sand / Beach
                        r = 185; g = 170; b = 120;
                    } else if (elevation < 0.68) {
                        // Lowlands / Forests
                        r = 28; g = 95; b = 48;
                    } else if (elevation < 0.80) {
                        // Highlands / Hills
                        r = 85; g = 72; b = 50;
                    } else {
                        // Mountains / Peaks
                        r = 180; g = 180; b = 190;
                    }

                    // Night lights / city emission subtle boost
                    const idx = (y * width + x) * 4;
                    data[idx] = r;
                    data[idx + 1] = g;
                    data[idx + 2] = b;
                    data[idx + 3] = 255;
                }
            }

            ctx.putImageData(imgData, 0, 0);
            return new THREE.CanvasTexture(canvas);
        }

        function createCloudTexture() {
            const width = 1024, height = 512;
            const canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            const ctx = canvas.getContext('2d');
            const imgData = ctx.createImageData(width, height);
            const data = imgData.data;

            for (let y = 0; y < height; y++) {
                const lat = ((y / height) - 0.5) * Math.PI;
                const sinLat = Math.sin(lat);
                const cosLat = Math.cos(lat);

                for (let x = 0; x < width; x++) {
                    const lon = (x / width) * Math.PI * 2;
                    const nx = cosLat * Math.sin(lon);
                    const ny = sinLat;
                    const nz = cosLat * Math.cos(lon);

                    let cloud = fbm(nx * 2.2 + 10.0, ny * 2.2 + 10.0, nz * 2.2 + 10.0, 5);
                    cloud = (cloud + 1) * 0.5;
                    let density = Math.max(0, (cloud - 0.48) / 0.52);

                    const idx = (y * width + x) * 4;
                    data[idx] = 255;
                    data[idx + 1] = 255;
                    data[idx + 2] = 255;
                    data[idx + 3] = Math.floor(density * 220);
                }
            }

            ctx.putImageData(imgData, 0, 0);
            return new THREE.CanvasTexture(canvas);
        }

        // --- SCENE SETUP ---
        const container = document.getElementById('canvas-container');
        const scene = new THREE.Scene();

        const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 4, 11);

        const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 1.1;
        container.appendChild(renderer.domElement);

        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.minDistance = 5.5;
        controls.maxDistance = 25;
        controls.rotateSpeed = 0.8;

        // --- LIGHTING ---
        const sunLight = new THREE.DirectionalLight(0xfff5e6, 2.0);
        sunLight.position.set(20, 10, 15);
        scene.add(sunLight);

        const ambientLight = new THREE.AmbientLight(0x0d1b2a, 0.8);
        scene.add(ambientLight);

        const blueBackLight = new THREE.DirectionalLight(0x1d4ed8, 1.2);
        blueBackLight.position.set(-15, -10, -15);
        scene.add(blueBackLight);

        // --- GLOBE ROOT GROUP ---
        const globeGroup = new THREE.Group();
        scene.add(globeGroup);

        // 1. Earth Mesh
        const earthRadius = 3.0;
        const earthGeo = new THREE.SphereGeometry(earthRadius, 64, 64);
        const earthTex = createGlobeTexture();
        const earthMat = new THREE.MeshStandardMaterial({
            map: earthTex,
            roughness: 0.7,
            metalness: 0.1,
        });
        const earthMesh = new THREE.Mesh(earthGeo, earthMat);
        globeGroup.add(earthMesh);

        // 2. Cloud Mesh
        const cloudTex = createCloudTexture();
        const cloudGeo = new THREE.SphereGeometry(earthRadius + 0.04, 64, 64);
        const cloudMat = new THREE.MeshStandardMaterial({
            map: cloudTex,
            transparent: true,
            opacity: 0.75,
            blending: THREE.NormalBlending,
            depthWrite: false,
            roughness: 1.0
        });
        const cloudMesh = new THREE.Mesh(cloudGeo, cloudMat);
        globeGroup.add(cloudMesh);

        // 3. Atmosphere Glow Mesh (Custom Fresnel Shader)
        const atmosphereVertexShader = `
            varying vec3 vNormal;
            varying vec3 vPosition;
            void main() {
                vNormal = normalize(normalMatrix * normal);
                vPosition = (modelViewMatrix * vec4(position, 1.0)).xyz;
                gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            }
        `;

        const atmosphereFragmentShader = `
            varying vec3 vNormal;
            varying vec3 vPosition;
            void main() {
                vec3 viewDir = normalize(-vPosition);
                float intensity = pow(1.0 - max(0.0, dot(vNormal, viewDir)), 3.2);
                vec3 glowColor = vec3(0.18, 0.58, 1.0);
                gl_FragColor = vec4(glowColor, intensity * 0.85);
            }
        `;

        const atmosGeo = new THREE.SphereGeometry(earthRadius + 0.35, 64, 64);
        const atmosMat = new THREE.ShaderMaterial({
            vertexShader: atmosphereVertexShader,
            fragmentShader: atmosphereFragmentShader,
            blending: THREE.AdditiveBlending,
            side: THREE.BackSide,
            transparent: true,
            depthWrite: false
        });
        const atmosMesh = new THREE.Mesh(atmosGeo, atmosMat);
        globeGroup.add(atmosMesh);

        // 4. Orbiting Particle Rings
        function createGlowSprite() {
            const canvas = document.createElement('canvas');
            canvas.width = 64;
            canvas.height = 64;
            const ctx = canvas.getContext('2d');
            const grad = ctx.createRadialGradient(32, 32, 0, 32, 32, 32);
            grad.addColorStop(0, 'rgba(255, 255, 255, 1)');
            grad.addColorStop(0.2, 'rgba(0, 242, 254, 0.8)');
            grad.addColorStop(0.6, 'rgba(79, 70, 229, 0.3)');
            grad.addColorStop(1, 'rgba(0, 0, 0, 0)');
            ctx.fillStyle = grad;
            ctx.fillRect(0, 0, 64, 64);
            return new THREE.CanvasTexture(canvas);
        }

        const particleCount = 1800;
        const particleGeo = new THREE.BufferGeometry();
        const positions = new Float32Array(particleCount * 3);
        const colors = new Float32Array(particleCount * 3);
        const color1 = new THREE.Color(0x00f2fe);
        const color2 = new THREE.Color(0x9d4edd);

        for (let i = 0; i < particleCount; i++) {
            const angle = Math.random() * Math.PI * 2;
            const radius = 4.2 + (Math.random() - 0.5) * 1.6;
            const spreadY = (Math.random() - 0.5) * 0.45;

            positions[i * 3] = Math.cos(angle) * radius;
            positions[i * 3 + 1] = spreadY;
            positions[i * 3 + 2] = Math.sin(angle) * radius;

            const mixedColor = color1.clone().lerp(color2, Math.random());
            colors[i * 3] = mixedColor.r;
            colors[i * 3 + 1] = mixedColor.g;
            colors[i * 3 + 2] = mixedColor.b;
        }

        particleGeo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
        particleGeo.setAttribute('color', new THREE.BufferAttribute(colors, 3));

        const particleMat = new THREE.PointsMaterial({
            size: 0.16,
            map: createGlowSprite(),
            vertexColors: true,
            transparent: true,
            blending: THREE.AdditiveBlending,
            depthWrite: false
        });

        const particleRing = new THREE.Points(particleGeo, particleMat);
        particleRing.rotation.x = THREE.MathUtils.degToRad(35);
        particleRing.rotation.z = THREE.MathUtils.degToRad(15);
        scene.add(particleRing);

        // 5. Starfield Background
        const starsGeo = new THREE.BufferGeometry();
        const starsCount = 1200;
        const starPositions = new Float32Array(starsCount * 3);

        for (let i = 0; i < starsCount * 3; i += 3) {
            starPositions[i] = (Math.random() - 0.5) * 200;
            starPositions[i + 1] = (Math.random() - 0.5) * 200;
            starPositions[i + 2] = (Math.random() - 0.5) * 200;
        }
        starsGeo.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
        const starsMat = new THREE.PointsMaterial({
            size: 0.4,
            color: 0x88aaff,
            transparent: true,
            opacity: 0.6
        });
        const starField = new THREE.Points(starsGeo, starsMat);
        scene.add(starField);

        // --- INTERACTIVITY & UI ---
        const slider = document.getElementById('rotation-slider');
        const speedDisplay = document.getElementById('speed-display');
        let speedMultiplier = 1.0;

        slider.addEventListener('input', (e) => {
            speedMultiplier = parseFloat(e.target.value);
            speedDisplay.textContent = speedMultiplier.toFixed(1) + 'x';
        });

        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        // --- ANIMATION LOOP ---
        const clock = new THREE.Clock();

        function animate() {
            requestAnimationFrame(animate);

            const delta = clock.getDelta();
            const baseRot = 0.15 * speedMultiplier * delta;

            // Earth and cloud rotation
            globeGroup.rotation.y += baseRot;
            cloudMesh.rotation.y += baseRot * 0.35; // Cloud differential drift

            // Ring rotation (inclined orbit counter-rotation)
            particleRing.rotation.y -= baseRot * 0.7;

            // Controls update
            controls.update();

            renderer.render(scene, camera);
        }

        animate();
    </script>
</body>
</html>
Evaluation: Again, this is the most maximalist generation I’ve seen, which is really good. It proves the Gemini team is actually trying to make their model less lazy, which has been a really big problem since the start.

Test 3: 3D Low-Poly Wizard Adventure Game

Now for a harder prompt:
> "Create a fully functional, browser-based 3D third-person action-adventure game using Three.js inside a single self-contained HTML file, featuring a low-poly wizard exploring a vibrant floating island archipelago with bright pastel colors, dynamic day-night lighting, and environmental particle effects. Implement smooth WASD movement, spacebar jumping, and mouse-drag camera controls, complete with responsive collision detection, a dynamic camera-follow script, and an objective where the player collects glowing crystal artifacts while dodging automated elemental turrets. Include a clean user interface with a real-time score and health HUD, basic Web Audio API sound effects for jumping and collecting items, and a seamless game-over and restart system."
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Arcane Isles - 3D Wizard Adventure</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            user-select: none;
            -webkit-user-select: none;
        }

        body {
            width: 100vw;
            height: 100vh;
            overflow: hidden;
            background-color: #a0d8ef;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #fff;
        }

        #game-canvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: block;
        }

        /* Stylized UI HUD */
        #hud {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            padding: 24px;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
        }

        .hud-top {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
        }

        .hud-card {
            background: rgba(255, 255, 255, 0.2);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            border: 2px solid rgba(255, 255, 255, 0.4);
            border-radius: 18px;
            padding: 12px 20px;
            box-shadow: 0 8px 32px rgba(31, 38, 135, 0.15);
            display: flex;
            align-items: center;
            gap: 14px;
        }

        /* Health Bar */
        .health-container {
            display: flex;
            flex-direction: column;
            gap: 6px;
        }

        .health-label {
            font-size: 12px;
            font-weight: 800;
            text-transform: uppercase;
            letter-spacing: 1.5px;
            color: #fff;
            text-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }

        .health-bar-bg {
            width: 180px;
            height: 16px;
            background: rgba(0, 0, 0, 0.25);
            border-radius: 10px;
            overflow: hidden;
            border: 1.5px solid rgba(255, 255, 255, 0.5);
            position: relative;
        }

        .health-bar-fill {
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, #ff6b81, #ff4757);
            border-radius: 8px;
            transition: width 0.25s ease-out, background 0.3s;
        }

        /* Score / Crystal Counter */
        .crystal-counter {
            font-size: 20px;
            font-weight: 900;
            display: flex;
            align-items: center;
            gap: 8px;
            color: #ffeaa7;
            text-shadow: 0 2px 8px rgba(0,0,0,0.3);
        }

        .crystal-icon {
            width: 22px;
            height: 22px;
            background: #fdcb6e;
            clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
            box-shadow: 0 0 12px #ffeaa7;
            animation: pulse-gem 2s infinite ease-in-out;
        }

        @keyframes pulse-gem {
            0%, 100% { transform: scale(1) rotate(0deg); }
            50% { transform: scale(1.18) rotate(15deg); }
        }

        /* Time of Day Indicator */
        .time-pill {
            font-size: 13px;
            font-weight: 700;
            color: #fff;
            letter-spacing: 1px;
            text-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }

        /* Controls Hint & Notifications */
        .hud-bottom {
            display: flex;
            justify-content: space-between;
            align-items: flex-end;
        }

        .controls-hint {
            background: rgba(20, 20, 35, 0.3);
            backdrop-filter: blur(8px);
            border-radius: 12px;
            padding: 8px 16px;
            font-size: 12px;
            color: rgba(255,255,255,0.85);
            display: flex;
            gap: 12px;
            border: 1px solid rgba(255,255,255,0.2);
        }

        .key-badge {
            background: rgba(255,255,255,0.3);
            padding: 2px 6px;
            border-radius: 4px;
            font-weight: bold;
            color: #fff;
        }

        .notification {
            position: absolute;
            top: 100px;
            left: 50%;
            transform: translateX(-50%) translateY(-20px);
            background: rgba(255, 255, 255, 0.25);
            backdrop-filter: blur(16px);
            border: 2px solid rgba(255, 255, 255, 0.6);
            padding: 10px 24px;
            border-radius: 30px;
            font-weight: 800;
            font-size: 16px;
            letter-spacing: 1px;
            text-shadow: 0 2px 6px rgba(0,0,0,0.3);
            opacity: 0;
            transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            pointer-events: none;
        }

        .notification.show {
            opacity: 1;
            transform: translateX(-50%) translateY(0);
        }

        /* Damage Flash Overlay */
        #damage-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: radial-gradient(circle, transparent 60%, rgba(255, 50, 50, 0.45) 100%);
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.15s ease-out;
        }

        /* Dialog & Modal Overlays */
        .modal-screen {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(20, 15, 35, 0.65);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            z-index: 100;
            opacity: 1;
            transition: opacity 0.4s ease;
        }

        .modal-content {
            background: linear-gradient(135deg, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0.08));
            border: 2px solid rgba(255, 255, 255, 0.5);
            border-radius: 28px;
            padding: 40px 50px;
            text-align: center;
            max-width: 460px;
            box-shadow: 0 20px 50px rgba(0,0,0,0.4);
            animation: modal-pop 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        }

        @keyframes modal-pop {
            0% { transform: scale(0.85); opacity: 0; }
            100% { transform: scale(1); opacity: 1; }
        }

        .modal-title {
            font-size: 34px;
            font-weight: 900;
            margin-bottom: 12px;
            text-transform: uppercase;
            letter-spacing: 2px;
            text-shadow: 0 4px 12px rgba(0,0,0,0.3);
        }

        .modal-desc {
            font-size: 15px;
            line-height: 1.6;
            margin-bottom: 28px;
            color: rgba(255, 255, 255, 0.9);
        }

        .btn-action {
            background: linear-gradient(135deg, #a29bfe, #6c5ce7);
            color: #fff;
            border: none;
            padding: 14px 36px;
            font-size: 16px;
            font-weight: 800;
            text-transform: uppercase;
            letter-spacing: 2px;
            border-radius: 30px;
            cursor: pointer;
            box-shadow: 0 8px 24px rgba(108, 92, 231, 0.45);
            transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
            outline: none;
        }

        .btn-action:hover {
            transform: translateY(-3px) scale(1.03);
            box-shadow: 0 12px 30px rgba(108, 92, 231, 0.65);
            background: linear-gradient(135deg, #b3acff, #7d6dfa);
        }

        .btn-action:active {
            transform: translateY(1px);
        }

        .hidden {
            display: none !important;
        }
    </style>
    <!-- Three.js CDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
</head>
<body>
    <canvas id="game-canvas"></canvas>
    
    <div id="damage-overlay"></div>

    <div id="hud">
        <div class="hud-top">
            <div class="hud-card">
                <div class="health-container">
                    <div class="health-label">Arcane Vitality</div>
                    <div class="health-bar-bg">
                        <div id="health-bar" class="health-bar-fill"></div>
                    </div>
                </div>
            </div>
            
            <div class="hud-card">
                <div class="crystal-counter">
                    <div class="crystal-icon"></div>
                    <span id="crystal-text">0 / 8</span>
                </div>
            </div>

            <div class="hud-card">
                <div class="time-pill" id="time-pill">☀️ Morning</div>
            </div>
        </div>

        <div id="notification-box" class="notification">Artifact Recovered!</div>

        <div class="hud-bottom">
            <div class="controls-hint">
                <span><span class="key-badge">W A S D</span> Move</span>
                <span><span class="key-badge">SPACE</span> Jump</span>
                <span><span class="key-badge">Left Click + Drag</span> Rotate Cam</span>
                <span><span class="key-badge">Scroll</span> Zoom</span>
            </div>
        </div>
    </div>

    <!-- Start / Intro Screen -->
    <div id="start-modal" class="modal-screen">
        <div class="modal-content">
            <h1 class="modal-title" style="color: #ffeaa7;">Arcane Isles</h1>
            <p class="modal-desc">
                Welcome, Novice Wizard! Explore the floating archipelago, dodge the automated arcane turrets, and gather all <strong>8 Glowing Crystals</strong> to break the celestial seal.
            </p>
            <button class="btn-action" id="start-btn">Begin Journey</button>
        </div>
    </div>

    <!-- Victory Modal -->
    <div id="victory-modal" class="modal-screen hidden">
        <div class="modal-content">
            <h1 class="modal-title" style="color: #55efc4;">Archipelago Cleansed!</h1>
            <p class="modal-desc">
                Magnificent! You've restored all the elemental crystals and quelled the arcane storms across the islands.
            </p>
            <button class="btn-action" id="win-restart-btn">Play Again</button>
        </div>
    </div>

    <!-- Game Over Modal -->
    <div id="gameover-modal" class="modal-screen hidden">
        <div class="modal-content">
            <h1 class="modal-title" style="color: #ff7675;">Mana Depleted</h1>
            <p class="modal-desc">
                The magical defenses overwhelmed your shield. Revitalize your essence and try again!
            </p>
            <button class="btn-action" id="lose-restart-btn">Try Again</button>
        </div>
    </div>

    <script>
        /* --- AUDIO SYNTHESIZER (Web Audio API) --- */
        class SoundFX {
            constructor() {
                this.ctx = null;
            }

            init() {
                if (!this.ctx) {
                    const AudioCtx = window.AudioContext || window.webkitAudioContext;
                    this.ctx = new AudioCtx();
                }
                if (this.ctx.state === 'suspended') {
                    this.ctx.resume();
                }
            }

            playJump() {
                if (!this.ctx) return;
                const osc = this.ctx.createOscillator();
                const gain = this.ctx.createGain();
                osc.type = 'sine';
                const now = this.ctx.currentTime;
                osc.frequency.setValueAtTime(150, now);
                osc.frequency.exponentialRampToValueAtTime(420, now + 0.18);
                gain.gain.setValueAtTime(0.2, now);
                gain.gain.exponentialRampToValueAtTime(0.01, now + 0.18);
                osc.connect(gain);
                gain.connect(this.ctx.destination);
                osc.start(now);
                osc.stop(now + 0.18);
            }

            playCollect() {
                if (!this.ctx) return;
                const notes = [523.25, 659.25, 783.99, 1046.50]; // C5, E5, G5, C6
                notes.forEach((freq, i) => {
                    const osc = this.ctx.createOscillator();
                    const gain = this.ctx.createGain();
                    const now = this.ctx.currentTime + (i * 0.06);
                    osc.type = 'triangle';
                    osc.frequency.setValueAtTime(freq, now);
                    gain.gain.setValueAtTime(0.22, now);
                    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.28);
                    osc.connect(gain);
                    gain.connect(this.ctx.destination);
                    osc.start(now);
                    osc.stop(now + 0.28);
                });
            }

            playHit() {
                if (!this.ctx) return;
                const now = this.ctx.currentTime;
                const osc = this.ctx.createOscillator();
                const gain = this.ctx.createGain();
                osc.type = 'sawtooth';
                osc.frequency.setValueAtTime(140, now);
                osc.frequency.exponentialRampToValueAtTime(35, now + 0.25);
                gain.gain.setValueAtTime(0.3, now);
                gain.gain.exponentialRampToValueAtTime(0.01, now + 0.25);
                osc.connect(gain);
                gain.connect(this.ctx.destination);
                osc.start(now);
                osc.stop(now + 0.25);
            }

            playTurretShot() {
                if (!this.ctx) return;
                const now = this.ctx.currentTime;
                const osc = this.ctx.createOscillator();
                const gain = this.ctx.createGain();
                osc.type = 'sine';
                osc.frequency.setValueAtTime(680, now);
                osc.frequency.exponentialRampToValueAtTime(180, now + 0.22);
                gain.gain.setValueAtTime(0.18, now);
                gain.gain.exponentialRampToValueAtTime(0.01, now + 0.22);
                osc.connect(gain);
                gain.connect(this.ctx.destination);
                osc.start(now);
                osc.stop(now + 0.22);
            }

            playWin() {
                if (!this.ctx) return;
                const melody = [440, 554.37, 659.25, 880];
                melody.forEach((freq, index) => {
                    const osc = this.ctx.createOscillator();
                    const gain = this.ctx.createGain();
                    const now = this.ctx.currentTime + index * 0.12;
                    osc.type = 'sine';
                    osc.frequency.setValueAtTime(freq, now);
                    gain.gain.setValueAtTime(0.25, now);
                    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.5);
                    osc.connect(gain);
                    gain.connect(this.ctx.destination);
                    osc.start(now);
                    osc.stop(now + 0.5);
                });
            }
        }

        const sound = new SoundFX();

        /* --- GAME ENGINE & SETUP --- */
        const canvas = document.getElementById('game-canvas');
        const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: false, powerPreference: "high-performance" });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 1.1;

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);

        // Day-Night Lighting Components
        const hemiLight = new THREE.HemisphereLight(0xe0f7fa, 0x5d4037, 0.65);
        scene.add(hemiLight);

        const dirLight = new THREE.DirectionalLight(0xfff5e6, 1.2);
        dirLight.position.set(40, 60, 30);
        dirLight.castShadow = true;
        dirLight.shadow.mapSize.width = 2048;
        dirLight.shadow.mapSize.height = 2048;
        dirLight.shadow.camera.near = 0.5;
        dirLight.shadow.camera.far = 200;
        const d = 50;
        dirLight.shadow.camera.left = -d;
        dirLight.shadow.camera.right = d;
        dirLight.shadow.camera.top = d;
        dirLight.shadow.camera.bottom = -d;
        dirLight.shadow.bias = -0.0005;
        scene.add(dirLight);

        // Sky & Fog
        const fogColor = new THREE.Color(0xb8e2f2);
        scene.background = fogColor;
        scene.fog = new THREE.FogExp2(fogColor, 0.012);

        /* --- PROCEDURAL WORLD BUILDER --- */
        const colliders = [];
        const collectibles = [];
        const turrets = [];
        const particles = [];

        const pastelPalette = {
            grass: [0x81ecec, 0x74b9ff, 0x55efc4, 0xa8e6cf],
            rock: [0x636e72, 0xb2bec3, 0xa29bfe, 0x8190a5],
            wood: 0xb38968,
            leaves: [0xff9ff3, 0xfeca57, 0x54a0ff, 0x1dd1a1],
            crystal: [0xfd79a8, 0x00cec9, 0xffbe76, 0xa29bfe]
        };

        // Island Generator
        function createFloatingIsland(x, y, z, radius, depth, colorIndex = 0) {
            const islandGroup = new THREE.Group();
            islandGroup.position.set(x, y, z);

            // Island Top (Cylinder with taper)
            const topGeo = new THREE.CylinderGeometry(radius, radius * 0.85, 3, 9);
            const topMat = new THREE.MeshLambertMaterial({ 
                color: pastelPalette.grass[colorIndex % pastelPalette.grass.length],
                flatShading: true 
            });
            const topMesh = new THREE.Mesh(topGeo, topMat);
            topMesh.position.y = 0;
            topMesh.receiveShadow = true;
            topMesh.castShadow = true;
            islandGroup.add(topMesh);

            // Island Bottom Cone / Rocks
            const botGeo = new THREE.ConeGeometry(radius * 0.85, depth, 8);
            const botMat = new THREE.MeshLambertMaterial({ 
                color: pastelPalette.rock[colorIndex % pastelPalette.rock.length], 
                flatShading: true 
            });
            const botMesh = new THREE.Mesh(botGeo, botMat);
            botMesh.rotation.x = Math.PI;
            botMesh.position.y = -depth / 2 - 1.5;
            botMesh.receiveShadow = true;
            islandGroup.add(botMesh);

            // Hanging Mini Rocks / Crystals beneath
            for (let i = 0; i < 3; i++) {
                const subGeo = new THREE.DodecahedronGeometry(radius * 0.15);
                const subMesh = new THREE.Mesh(subGeo, botMat);
                const angle = (i / 3) * Math.PI * 2 + Math.random();
                const r = radius * 0.45;
                subMesh.position.set(Math.cos(angle) * r, -depth * 0.6 - Math.random() * 2, Math.sin(angle) * r);
                islandGroup.add(subMesh);
            }

            scene.add(islandGroup);

            // Store collider data (cylinder bounds)
            const col = {
                type: 'cylinder',
                center: new THREE.Vector3(x, y + 1.5, z),
                radius: radius,
                topY: y + 1.5,
                botY: y - 2.0
            };
            colliders.push(col);

            return islandGroup;
        }

        // Bridge Generator
        function createPlankBridge(p1, p2, count = 7) {
            const bridgeMat = new THREE.MeshLambertMaterial({ color: pastelPalette.wood, flatShading: true });
            for (let i = 0; i <= count; i++) {
                const t = i / count;
                const pos = new THREE.Vector3().lerpVectors(p1, p2, t);
                pos.y -= Math.sin(t * Math.PI) * 1.2; // Natural sag

                const plankGeo = new THREE.BoxGeometry(2.6, 0.35, 1.2);
                const plank = new THREE.Mesh(plankGeo, bridgeMat);
                plank.position.copy(pos);
                plank.lookAt(p2);
                plank.receiveShadow = true;
                plank.castShadow = true;
                scene.add(plank);

                colliders.push({
                    type: 'box',
                    center: pos.clone(),
                    radius: 1.8,
                    topY: pos.y + 0.3
                });
            }
        }

        // Tree Generator
        function createLowPolyTree(x, y, z, color = pastelPalette.leaves[0], scale = 1) {
            const treeGroup = new THREE.Group();
            treeGroup.position.set(x, y, z);
            treeGroup.scale.set(scale, scale, scale);

            // Trunk
            const trunkGeo = new THREE.CylinderGeometry(0.3, 0.45, 2.2, 5);
            const trunkMat = new THREE.MeshLambertMaterial({ color: 0x8b5a2b, flatShading: true });
            const trunk = new THREE.Mesh(trunkGeo, trunkMat);
            trunk.position.y = 1.1;
            trunk.castShadow = true;
            treeGroup.add(trunk);

            // Foliage Cone Layers
            const leavesMat = new THREE.MeshLambertMaterial({ color: color, flatShading: true });
            for (let i = 0; i < 3; i++) {
                const foliageGeo = new THREE.ConeGeometry(1.8 - i * 0.38, 2.2 - i * 0.25, 6);
                const foliage = new THREE.Mesh(foliageGeo, leavesMat);
                foliage.position.y = 2.2 + i * 1.2;
                foliage.castShadow = true;
                foliage.receiveShadow = true;
                treeGroup.add(foliage);
            }

            scene.add(treeGroup);
        }

        // Glowing Crystal Artifact Generator
        function createArtifact(x, y, z, colorHex) {
            const group = new THREE.Group();
            group.position.set(x, y, z);

            const gemGeo = new THREE.OctahedronGeometry(0.85, 0);
            const gemMat = new THREE.MeshStandardMaterial({
                color: colorHex,
                emissive: colorHex,
                emissiveIntensity: 0.7,
                roughness: 0.2,
                metalness: 0.8,
                flatShading: true
            });
            const gemMesh = new THREE.Mesh(gemGeo, gemMat);
            gemMesh.castShadow = true;
            group.add(gemMesh);

            // Small orbital ring
            const ringGeo = new THREE.TorusGeometry(1.3, 0.06, 6, 16);
            const ringMat = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true });
            const ringMesh = new THREE.Mesh(ringGeo, ringMat);
            ringMesh.rotation.x = Math.PI / 3;
            group.add(ringMesh);

            // Point Light for radiance
            const light = new THREE.PointLight(colorHex, 1.8, 9);
            group.add(light);

            scene.add(group);

            const item = {
                group: group,
                mesh: gemMesh,
                ring: ringMesh,
                baseY: y,
                collected: false,
                pos: new THREE.Vector3(x, y, z)
            };
            collectibles.push(item);
            return item;
        }

        // Elemental Turret Generator
        function createTurret(x, y, z) {
            const turretGroup = new THREE.Group();
            turretGroup.position.set(x, y, z);

            // Base pedastal
            const baseGeo = new THREE.CylinderGeometry(1.4, 1.8, 1.2, 6);
            const baseMat = new THREE.MeshLambertMaterial({ color: 0x485460, flatShading: true });
            const baseMesh = new THREE.Mesh(baseGeo, baseMat);
            baseMesh.position.y = 0.6;
            baseMesh.castShadow = true;
            turretGroup.add(baseMesh);

            // Floating Floating Obelisk Core
            const coreGeo = new THREE.OctahedronGeometry(1.1, 0);
            const coreMat = new THREE.MeshStandardMaterial({
                color: 0xff3838,
                emissive: 0xff3838,
                emissiveIntensity: 0.6,
                roughness: 0.3,
                flatShading: true
            });
            const coreMesh = new THREE.Mesh(coreGeo, coreMat);
            coreMesh.position.y = 2.8;
            coreMesh.castShadow = true;
            turretGroup.add(coreMesh);

            scene.add(turretGroup);

            const turretObj = {
                group: turretGroup,
                core: coreMesh,
                pos: new THREE.Vector3(x, y + 2.8, z),
                fireTimer: Math.random() * 2.0,
                fireInterval: 2.8,
                range: 35
            };
            turrets.push(turretObj);
        }

        // Projectiles List
        const projectiles = [];
        function spawnTurretProjectile(origin, targetPos) {
            const dir = new THREE.Vector3().subVectors(targetPos, origin).normalize();
            
            const projGeo = new THREE.SphereGeometry(0.4, 8, 8);
            const projMat = new THREE.MeshBasicMaterial({ color: 0xff4757 });
            const projMesh = new THREE.Mesh(projGeo, projMat);
            projMesh.position.copy(origin);
            
            const pLight = new THREE.PointLight(0xff4757, 2, 8);
            projMesh.add(pLight);
            
            scene.add(projMesh);

            projectiles.push({
                mesh: projMesh,
                dir: dir,
                speed: 16,
                life: 3.5
            });

            sound.playTurretShot();
        }

        /* --- BUILD SCENE ENVIRONMENT --- */
        // Main Archipelago Islands
        const islandsConfig = [
            { x: 0, y: 0, z: 0, r: 14, d: 16, col: 0 },         // 1. Central Spawn
            { x: 26, y: 3, z: -18, r: 10, d: 13, col: 1 },     // 2. North-East Ridge
            { x: -28, y: 4, z: -20, r: 11, d: 14, col: 2 },    // 3. North-West Mystic
            { x: 34, y: 8, z: 22, r: 12, d: 15, col: 3 },      // 4. South-East Summit
            { x: -30, y: 6, z: 24, r: 10, d: 12, col: 0 },     // 5. South-West Spire
            { x: 0, y: 12, z: -48, r: 13, d: 18, col: 1 },     // 6. Northern High Sanctum
            { x: 0, y: 15, z: 50, r: 12, d: 16, col: 2 },      // 7. Southern Arch Island
        ];

        islandsConfig.forEach(cfg => {
            createFloatingIsland(cfg.x, cfg.y, cfg.z, cfg.r, cfg.d, cfg.col);
        });

        // Bridges between islands
        createPlankBridge(new THREE.Vector3(0, 1.5, 0), new THREE.Vector3(26, 4.5, -18), 8);
        createPlankBridge(new THREE.Vector3(0, 1.5, 0), new THREE.Vector3(-28, 5.5, -20), 8);
        createPlankBridge(new THREE.Vector3(26, 4.5, -18), new THREE.Vector3(34, 9.5, 22), 9);
        createPlankBridge(new THREE.Vector3(-28, 5.5, -20), new THREE.Vector3(-30, 7.5, 24), 9);
        createPlankBridge(new THREE.Vector3(26, 4.5, -18), new THREE.Vector3(0, 13.5, -48), 10);
        createPlankBridge(new THREE.Vector3(-28, 5.5, -20), new THREE.Vector3(0, 13.5, -48), 10);
        createPlankBridge(new THREE.Vector3(34, 9.5, 22), new THREE.Vector3(0, 16.5, 50), 9);
        createPlankBridge(new THREE.Vector3(-30, 7.5, 24), new THREE.Vector3(0, 16.5, 50), 9);

        // Decorate Islands with Trees & Vegetation
        // Spawn
        createLowPolyTree(-4, 1.5, -4, pastelPalette.leaves[0], 1.2);
        createLowPolyTree(5, 1.5, -5, pastelPalette.leaves[1], 1.0);
        createLowPolyTree(-6, 1.5, 4, pastelPalette.leaves[2], 0.9);

        // Island 2
        createLowPolyTree(28, 4.5, -22, pastelPalette.leaves[3], 1.3);
        createLowPolyTree(22, 4.5, -14, pastelPalette.leaves[0], 0.8);

        // Island 3
        createLowPolyTree(-32, 5.5, -24, pastelPalette.leaves[1], 1.1);
        createLowPolyTree(-24, 5.5, -16, pastelPalette.leaves[2], 1.0);

        // Island 4 & 5
        createLowPolyTree(38, 9.5, 26, pastelPalette.leaves[0], 1.4);
        createLowPolyTree(-34, 7.5, 28, pastelPalette.leaves[3], 1.2);

        // High Sanctum & South Arch
        createLowPolyTree(-5, 13.5, -52, pastelPalette.leaves[1], 1.5);
        createLowPolyTree(6, 13.5, -45, pastelPalette.leaves[2], 1.3);
        createLowPolyTree(0, 16.5, 54, pastelPalette.leaves[0], 1.5);

        // Distribute 8 Crystals
        const crystalPositions = [
            { x: 0, y: 3.2, z: 6, col: 0x55efc4 },         // Spawn intro
            { x: 28, y: 6.2, z: -18, col: 0xfd79a8 },     // Island 2
            { x: -30, y: 7.2, z: -20, col: 0xffbe76 },    // Island 3
            { x: 36, y: 11.2, z: 22, col: 0x00cec9 },     // Island 4
            { x: -32, y: 9.2, z: 24, col: 0xa29bfe },     // Island 5
            { x: -6, y: 15.2, z: -48, col: 0xfdcb6e },    // Island 6 Left
            { x: 6, y: 15.2, z: -48, col: 0xe056fd },     // Island 6 Right
            { x: 0, y: 18.2, z: 50, col: 0x7ed6df }       // Island 7 Summit
        ];

        crystalPositions.forEach(cp => {
            createArtifact(cp.x, cp.y, cp.z, cp.col);
        });

        // Elemental Turrets (Strategically placed)
        createTurret(24, 4.5, -24);
        createTurret(-26, 5.5, -26);
        createTurret(32, 9.5, 16);
        createTurret(0, 13.5, -42);
        createTurret(0, 16.5, 44);

        /* --- AMBIENT MAGIC PARTICLES --- */
        const moteCount = 120;
        const moteGeo = new THREE.BufferGeometry();
        const motePos = new Float32Array(moteCount * 3);
        for (let i = 0; i < moteCount * 3; i += 3) {
            motePos[i] = (Math.random() - 0.5) * 120;
            motePos[i + 1] = Math.random() * 25 + 2;
            motePos[i + 2] = (Math.random() - 0.5) * 120;
        }
        moteGeo.setAttribute('position', new THREE.BufferAttribute(motePos, 3));
        const moteMat = new THREE.PointsMaterial({
            color: 0xffffff,
            size: 0.6,
            transparent: true,
            opacity: 0.65,
            blending: THREE.AdditiveBlending
        });
        const moteSystem = new THREE.Points(moteGeo, moteMat);
        scene.add(moteSystem);

        /* --- LOW-POLY WIZARD CHARACTER --- */
        class WizardCharacter {
            constructor() {
                this.mesh = new THREE.Group();

                // Materials
                const robeMat = new THREE.MeshLambertMaterial({ color: 0x4834d4, flatShading: true });
                const skinMat = new THREE.MeshLambertMaterial({ color: 0xffd1a4, flatShading: true });
                const hatMat = new THREE.MeshLambertMaterial({ color: 0x301b96, flatShading: true });
                const trimMat = new THREE.MeshLambertMaterial({ color: 0xf9ca24, flatShading: true });
                const beardMat = new THREE.MeshLambertMaterial({ color: 0xecf0f1, flatShading: true });
                const woodMat = new THREE.MeshLambertMaterial({ color: 0x795548, flatShading: true });

                // Body / Robe Cone
                const bodyGeo = new THREE.ConeGeometry(0.7, 1.6, 7);
                this.body = new THREE.Mesh(bodyGeo, robeMat);
                this.body.position.y = 0.8;
                this.body.castShadow = true;
                this.mesh.add(this.body);

                // Belt Trim
                const beltGeo = new THREE.CylinderGeometry(0.52, 0.56, 0.18, 7);
                const belt = new THREE.Mesh(beltGeo, trimMat);
                belt.position.y = 0.75;
                this.mesh.add(belt);

                // Head
                const headGeo = new THREE.SphereGeometry(0.38, 6, 6);
                this.head = new THREE.Mesh(headGeo, skinMat);
                this.head.position.y = 1.85;
                this.head.castShadow = true;
                this.mesh.add(this.head);

                // Beard
                const beardGeo = new THREE.ConeGeometry(0.28, 0.65, 5);
                const beard = new THREE.Mesh(beardGeo, beardMat);
                beard.rotation.x = -Math.PI * 0.15;
                beard.position.set(0, 1.62, 0.28);
                this.mesh.add(beard);

                // Wizard Hat Brim & Cone
                const brimGeo = new THREE.CylinderGeometry(0.9, 0.9, 0.08, 8);
                const brim = new THREE.Mesh(brimGeo, hatMat);
                brim.position.y = 2.05;
                this.mesh.add(brim);

                const hatConeGeo = new THREE.ConeGeometry(0.55, 1.2, 7);
                this.hatCone = new THREE.Mesh(hatConeGeo, hatMat);
                this.hatCone.position.set(0, 2.65, -0.08);
                this.hatCone.rotation.x = -0.15;
                this.mesh.add(this.hatCone);

                // Magic Staff
                this.staffGroup = new THREE.Group();
                this.staffGroup.position.set(0.65, 0.9, 0.35);

                const poleGeo = new THREE.CylinderGeometry(0.06, 0.07, 2.2, 5);
                const pole = new THREE.Mesh(poleGeo, woodMat);
                pole.castShadow = true;
                this.staffGroup.add(pole);

                // Staff Crystal Top
                const staffGemGeo = new THREE.OctahedronGeometry(0.22, 0);
                const staffGemMat = new THREE.MeshStandardMaterial({
                    color: 0x00d2d3,
                    emissive: 0x00d2d3,
                    emissiveIntensity: 0.9,
                    flatShading: true
                });
                this.staffGem = new THREE.Mesh(staffGemGeo, staffGemMat);
                this.staffGem.position.y = 1.15;
                this.staffGroup.add(this.staffGem);

                this.staffLight = new THREE.PointLight(0x00d2d3, 1.2, 6);
                this.staffLight.position.y = 1.15;
                this.staffGroup.add(this.staffLight);

                this.mesh.add(this.staffGroup);

                scene.add(this.mesh);

                // Movement & State Properties
                this.position = this.mesh.position;
                this.position.set(0, 3, 0);
                this.velocity = new THREE.Vector3();
                this.isGrounded = false;
                this.walkCycle = 0;
                this.rotationAngle = 0;
            }

            updateAnimation(delta, isMoving) {
                // Bobbing staff & floating gem rotation
                this.staffGem.rotation.y += delta * 3.5;
                this.staffGem.rotation.x += delta * 2;

                if (isMoving && this.isGrounded) {
                    this.walkCycle += delta * 12;
                    this.body.rotation.z = Math.sin(this.walkCycle) * 0.08;
                    this.staffGroup.position.y = 0.9 + Math.sin(this.walkCycle) * 0.1;
                    this.hatCone.rotation.z = Math.sin(this.walkCycle) * 0.1;
                } else {
                    this.walkCycle = 0;
                    this.body.rotation.z = THREE.MathUtils.lerp(this.body.rotation.z, 0, 0.1);
                    this.hatCone.rotation.z = THREE.MathUtils.lerp(this.hatCone.rotation.z, 0, 0.1);
                    this.staffGroup.position.y = THREE.MathUtils.lerp(this.staffGroup.position.y, 0.9, 0.1);
                }
            }
        }

        const player = new WizardCharacter();

        /* --- GAMEPLAY CONTROLLER & INPUTS --- */
        const keys = { w: false, a: false, s: false, d: false, space: false };
        let mouseLook = { isDragging: false, prevX: 0, prevY: 0, yaw: 0, pitch: 0.35, distance: 11 };

        window.addEventListener('keydown', (e) => {
            const k = e.key.toLowerCase();
            if (k === 'w' || k === 'arrowup') keys.w = true;
            if (k === 'a' || k === 'arrowleft') keys.a = true;
            if (k === 's' || k === 'arrowdown') keys.s = true;
            if (k === 'd' || k === 'arrowright') keys.d = true;
            if (e.code === 'Space') {
                if (!keys.space && player.isGrounded) {
                    player.velocity.y = 12.5;
                    player.isGrounded = false;
                    sound.playJump();
                }
                keys.space = true;
            }
        });

        window.addEventListener('keyup', (e) => {
            const k = e.key.toLowerCase();
            if (k === 'w' || k === 'arrowup') keys.w = false;
            if (k === 'a' || k === 'arrowleft') keys.a = false;
            if (k === 's' || k === 'arrowdown') keys.s = false;
            if (k === 'd' || k === 'arrowright') keys.d = false;
            if (e.code === 'Space') keys.space = false;
        });

        // Mouse Drag Orbit Controls
        window.addEventListener('mousedown', (e) => {
            if (e.button === 0 || e.button === 2) {
                mouseLook.isDragging = true;
                mouseLook.prevX = e.clientX;
                mouseLook.prevY = e.clientY;
            }
        });

        window.addEventListener('mouseup', () => { mouseLook.isDragging = false; });
        window.addEventListener('mousemove', (e) => {
            if (!mouseLook.isDragging) return;
            const dx = e.clientX - mouseLook.prevX;
            const dy = e.clientY - mouseLook.prevY;
            mouseLook.prevX = e.clientX;
            mouseLook.prevY = e.clientY;

            mouseLook.yaw -= dx * 0.007;
            mouseLook.pitch = Math.max(0.08, Math.min(Math.PI / 2.3, mouseLook.pitch + dy * 0.005));
        });

        window.addEventListener('wheel', (e) => {
            mouseLook.distance = Math.max(5, Math.min(22, mouseLook.distance + e.deltaY * 0.015));
        });

        window.addEventListener('contextmenu', e => e.preventDefault());

        /* --- GAME STATE & HUD LOGIC --- */
        let gameState = {
            health: 100,
            maxHealth: 100,
            crystalsCollected: 0,
            totalCrystals: crystalPositions.length,
            isGameOver: false,
            isWon: false,
            dayTime: 0 // 0 to 2PI
        };

        const healthBar = document.getElementById('health-bar');
        const crystalText = document.getElementById('crystal-text');
        const timePill = document.getElementById('time-pill');
        const notifBox = document.getElementById('notification-box');
        const damageOverlay = document.getElementById('damage-overlay');

        function triggerDamage(amount = 20) {
            if (gameState.isGameOver || gameState.isWon) return;
            gameState.health = Math.max(0, gameState.health - amount);
            healthBar.style.width = `${(gameState.health / gameState.maxHealth) * 100}%`;
            
            damageOverlay.style.opacity = '1';
            setTimeout(() => { damageOverlay.style.opacity = '0'; }, 180);
            sound.playHit();

            if (gameState.health <= 0) {
                handleGameOver();
            }
        }

        function showNotification(msg) {
            notifBox.innerText = msg;
            notifBox.classList.add('show');
            setTimeout(() => { notifBox.classList.remove('show'); }, 2200);
        }

        function collectCrystal(item) {
            item.collected = true;
            scene.remove(item.group);
            gameState.crystalsCollected++;
            crystalText.innerText = `${gameState.crystalsCollected} / ${gameState.totalCrystals}`;
            sound.playCollect();
            showNotification(`✨ Crystal Found! (${gameState.crystalsCollected}/${gameState.totalCrystals})`);

            // Spawn Sparkle Burst
            for (let i = 0; i < 16; i++) {
                const spGeo = new THREE.DodecahedronGeometry(0.18);
                const spMat = new THREE.MeshBasicMaterial({ color: 0xffeaa7 });
                const spMesh = new THREE.Mesh(spGeo, spMat);
                spMesh.position.copy(item.pos);
                scene.add(spMesh);
                particles.push({
                    mesh: spMesh,
                    vel: new THREE.Vector3((Math.random() - 0.5) * 8, Math.random() * 8 + 2, (Math.random() - 0.5) * 8),
                    life: 0.8
                });
            }

            if (gameState.crystalsCollected >= gameState.totalCrystals) {
                handleVictory();
            }
        }

        function handleGameOver() {
            gameState.isGameOver = true;
            document.getElementById('gameover-modal').classList.remove('hidden');
        }

        function handleVictory() {
            gameState.isWon = true;
            sound.playWin();
            document.getElementById('victory-modal').classList.remove('hidden');
        }

        function restartGame() {
            gameState.health = 100;
            gameState.crystalsCollected = 0;
            gameState.isGameOver = false;
            gameState.isWon = false;

            healthBar.style.width = '100%';
            crystalText.innerText = `0 / ${gameState.totalCrystals}`;

            player.position.set(0, 3, 0);
            player.velocity.set(0, 0, 0);

            // Re-add collectibles
            collectibles.forEach(item => {
                item.collected = false;
                scene.add(item.group);
            });

            // Clear projectiles
            projectiles.forEach(p => scene.remove(p.mesh));
            projectiles.length = 0;

            document.getElementById('gameover-modal').classList.add('hidden');
            document.getElementById('victory-modal').classList.add('hidden');
            document.getElementById('start-modal').classList.add('hidden');
        }

        document.getElementById('start-btn').addEventListener('click', () => {
            sound.init();
            document.getElementById('start-modal').classList.add('hidden');
        });
        document.getElementById('win-restart-btn').addEventListener('click', restartGame);
        document.getElementById('lose-restart-btn').addEventListener('click', restartGame);

        /* --- COLLISION RESOLUTION --- */
        function checkGroundCollision(pos) {
            let highestGround = -999;
            for (let col of colliders) {
                if (col.type === 'cylinder') {
                    const dx = pos.x - col.center.x;
                    const dz = pos.z - col.center.z;
                    const distSq = dx * dx + dz * dz;
                    if (distSq < col.radius * col.radius) {
                        if (col.topY > highestGround && pos.y >= col.topY - 1.8) {
                            highestGround = col.topY;
                        }
                    }
                } else if (col.type === 'box') {
                    const distSq = pos.distanceToSquared(col.center);
                    if (distSq < col.radius * col.radius) {
                        if (col.topY > highestGround && pos.y >= col.topY - 1.4) {
                            highestGround = col.topY;
                        }
                    }
                }
            }
            return highestGround;
        }

        /* --- MAIN ANIMATION & PHYSICS LOOP --- */
        const clock = new THREE.Clock();

        function animate() {
            requestAnimationFrame(animate);

            const delta = Math.min(clock.getDelta(), 0.08);

            if (!gameState.isGameOver && !gameState.isWon) {
                // Day-Night Cycle
                gameState.dayTime += delta * 0.06;
                const sunAngle = gameState.dayTime;
                dirLight.position.x = Math.cos(sunAngle) * 60;
                dirLight.position.y = Math.sin(sunAngle) * 60;
                dirLight.position.z = Math.sin(sunAngle * 0.5) * 40;

                // Adjust lighting & fog colors dynamically
                const sunY = dirLight.position.y;
                if (sunY > 10) {
                    // Daytime
                    scene.background.setHex(0xb8e2f2);
                    scene.fog.color.setHex(0xb8e2f2);
                    dirLight.color.setHex(0xfff5e6);
                    hemiLight.color.setHex(0xe0f7fa);
                    timePill.innerText = "☀️ Midday";
                } else if (sunY > -10) {
                    // Golden Hour / Sunset
                    scene.background.setHex(0xfbc531);
                    scene.fog.color.setHex(0xfbc531);
                    dirLight.color.setHex(0xff7675);
                    hemiLight.color.setHex(0xfd79a8);
                    timePill.innerText = "🌅 Twilight";
                } else {
                    // Night
                    scene.background.setHex(0x192a56);
                    scene.fog.color.setHex(0x192a56);
                    dirLight.color.setHex(0x487eb0);
                    hemiLight.color.setHex(0x273c75);
                    timePill.innerText = "🌙 Night";
                }

                // Player Movement Physics
                const moveDir = new THREE.Vector3();
                if (keys.w) moveDir.z -= 1;
                if (keys.s) moveDir.z += 1;
                if (keys.a) moveDir.x -= 1;
                if (keys.d) moveDir.x += 1;

                const isMoving = moveDir.lengthSq() > 0;
                if (isMoving) {
                    moveDir.normalize();

                    // Camera yaw relative movement
                    const forward = new THREE.Vector3(0, 0, -1).applyAxisAngle(new THREE.Vector3(0, 1, 0), mouseLook.yaw);
                    const right = new THREE.Vector3(1, 0, 0).applyAxisAngle(new THREE.Vector3(0, 1, 0), mouseLook.yaw);
                    
                    const moveVector = new THREE.Vector3()
                        .addScaledVector(forward, -moveDir.z)
                        .addScaledVector(right, moveDir.x)
                        .normalize();

                    const moveSpeed = 10.5;
                    player.velocity.x = moveVector.x * moveSpeed;
                    player.velocity.z = moveVector.z * moveSpeed;

                    // Smooth rotation towards travel
                    const targetAngle = Math.atan2(moveVector.x, moveVector.z);
                    let diff = targetAngle - player.mesh.rotation.y;
                    while (diff < -Math.PI) diff += Math.PI * 2;
                    while (diff > Math.PI) diff -= Math.PI * 2;
                    player.mesh.rotation.y += diff * 0.18;
                } else {
                    player.velocity.x *= 0.78;
                    player.velocity.z *= 0.78;
                }

                // Apply Gravity
                player.velocity.y -= 28.0 * delta;

                // Move Player
                player.position.x += player.velocity.x * delta;
                player.position.z += player.velocity.z * delta;
                player.position.y += player.velocity.y * delta;

                // Ground Collision Resolution
                const groundY = checkGroundCollision(player.position);
                if (player.position.y <= groundY) {
                    player.position.y = groundY;
                    player.velocity.y = 0;
                    player.isGrounded = true;
                } else {
                    player.isGrounded = false;
                }

                // Void Respawn & Penalty
                if (player.position.y < -30) {
                    player.position.set(0, 4, 0);
                    player.velocity.set(0, 0, 0);
                    triggerDamage(25);
                    showNotification("⚠️ Fallen into the void! Teleported back.");
                }

                // Update Character Animation
                player.updateAnimation(delta, isMoving);

                // Collectibles Animation & Hit Check
                collectibles.forEach(item => {
                    if (item.collected) return;
                    item.mesh.rotation.y += delta * 1.5;
                    item.ring.rotation.z += delta * 2;
                    item.group.position.y = item.baseY + Math.sin(clock.elapsedTime * 3 + item.baseY) * 0.35;

                    // Check Player Proximity
                    if (player.position.distanceTo(item.group.position) < 2.0) {
                        collectCrystal(item);
                    }
                });

                // Turrets AI & Shooting
                turrets.forEach(turret => {
                    turret.core.rotation.y += delta * 2;
                    turret.core.position.y = 2.8 + Math.sin(clock.elapsedTime * 2.5) * 0.25;

                    const distToPlayer = turret.pos.distanceTo(player.position);
                    if (distToPlayer < turret.range) {
                        turret.fireTimer += delta;
                        if (turret.fireTimer >= turret.fireInterval) {
                            turret.fireTimer = 0;
                            // Target player center
                            const target = player.position.clone().add(new THREE.Vector3(0, 1.0, 0));
                            spawnTurretProjectile(turret.pos, target);
                        }
                    }
                });

                // Projectiles Update & Collision
                for (let i = projectiles.length - 1; i >= 0; i--) {
                    const p = projectiles[i];
                    p.mesh.position.addScaledVector(p.dir, p.speed * delta);
                    p.life -= delta;

                    // Hit Player check
                    const playerCenter = player.position.clone().add(new THREE.Vector3(0, 1.0, 0));
                    if (p.mesh.position.distanceTo(playerCenter) < 1.3) {
                        triggerDamage(18);
                        scene.remove(p.mesh);
                        projectiles.splice(i, 1);
                        continue;
                    }

                    // Expired
                    if (p.life <= 0) {
                        scene.remove(p.mesh);
                        projectiles.splice(i, 1);
                    }
                }

                // Particles Update
                for (let i = particles.length - 1; i >= 0; i--) {
                    const pt = particles[i];
                    pt.mesh.position.addScaledVector(pt.vel, delta);
                    pt.vel.y -= 9.8 * delta;
                    pt.life -= delta;
                    pt.mesh.scale.multiplyScalar(0.95);
                    if (pt.life <= 0) {
                        scene.remove(pt.mesh);
                        particles.splice(i, 1);
                    }
                }

                // Ambient Motes Drift
                const posArr = moteSystem.geometry.attributes.position.array;
                for (let i = 1; i < moteCount * 3; i += 3) {
                    posArr[i] += Math.sin(clock.elapsedTime + i) * 0.02;
                }
                moteSystem.geometry.attributes.position.needsUpdate = true;
            }

            // Smooth Third-Person Camera Follow
            const camTarget = player.position.clone().add(new THREE.Vector3(0, 1.5, 0));
            const camOffsetX = Math.sin(mouseLook.yaw) * Math.cos(mouseLook.pitch) * mouseLook.distance;
            const camOffsetY = Math.sin(mouseLook.pitch) * mouseLook.distance;
            const camOffsetZ = Math.cos(mouseLook.yaw) * Math.cos(mouseLook.pitch) * mouseLook.distance;

            const desiredCamPos = new THREE.Vector3(
                camTarget.x + camOffsetX,
                camTarget.y + camOffsetY,
                camTarget.z + camOffsetZ
            );

            camera.position.lerp(desiredCamPos, 0.12);
            camera.lookAt(camTarget);

            renderer.render(scene, camera);
        }

        // Window Resizing
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        // Start Loop
        animate();
    </script>
</body>
</html>
Evaluation: Even with this complex prompt, the model did incredibly well, and made a legitimately good, detailed game. This is the most maximalist generation I’ve seen, which is really good. It proves the Gemini team is actually trying to make their model less lazy, which has been a really big problem since the start.

Final Verdict

Overall, Gemini 3.7 Flash is a really great AI model that shows that Gemini is still in the frontier AI race. Hopefully, with a few new model releases, they’ll be back as the leaders of the pack.
Overall Score: 10 / 10