{"asset_map": {"excavator_body_reference": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/excavator_body_reference_3ea22063-2cea-482f-8078-c42f89ae766d.webp", "type": "image", "prompt": "Generate a detailed 3/4 view reference image of an industrial excavator's main body and cabin. Industrial yellow-orange paint with black accents and hazard warning stripes. Features include cabin windows, exhaust pipe, panel lines, and rivets. Add sci-fi touches like subtle glowing accent lights and a futuristic control panel visible through the glass. Professional 3D modeling reference style, clean lines, semi-realistic industrial textures, transparent background.", "description": "3/4 view reference of the industrial excavator cabin with sci-fi accents", "subtype": "object", "aspect_ratio": [870, 944], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "excavator_boom_reference": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/excavator_boom_reference_fb797395-b4ae-44b6-ad3e-8533d43dfc50.webp", "type": "image", "prompt": "Generate a detailed side view reference image of a heavy-duty excavator boom. Color scheme: industrial yellow-orange with metallic grey hydraulic cylinders and black hoses. Show clear hydraulic pistons, connection points, structural beams, bolts, and welds. Match the industrial style and color of excavator_body_reference. Clean 3D asset reference, transparent background.", "description": "Side view reference of the excavator's primary boom with hydraulic details", "subtype": "object", "aspect_ratio": [924, 941], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "excavator_arm_reference": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/excavator_arm_reference_13b0e394-c0e8-4b1a-a9ae-5d83728e749b.webp", "type": "image", "prompt": "Generate a detailed side view reference image of an excavator's secondary arm (dipper). Features hydraulic pistons, pivot points, and structural framework. Color scheme: industrial yellow-orange with grey hydraulics and black hose routing. Consistent with the mechanical style of excavator_boom_reference. Semi-realistic industrial design, transparent background.", "description": "Side view reference of the excavator's secondary arm", "subtype": "object", "aspect_ratio": [1005, 1022], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "excavator_bucket_reference": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/excavator_bucket_reference_f5f6e1b5-9516-4bf0-b5a3-3764d09e3664.webp", "type": "image", "prompt": "Generate a reference image of an industrial excavator bucket shown from front and side angles. Features reinforced steel teeth, wear plates, and hydraulic attachment points. Color: dark grey weathered metal with yellow-orange supports. Heavy-duty industrial style with realistic scratches and metallic wear. Transparent background.", "description": "Reference image of the excavator digging bucket with wear and tear", "subtype": "object", "aspect_ratio": [905, 680], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "excavator_tracks_reference": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/excavator_tracks_reference_7894169b-3638-47c2-ae28-4846ae00f2f6.webp", "type": "image", "prompt": "Generate a 3/4 view reference image of heavy-duty excavator tracks and treads. Black rubber/metal track links, drive sprocket, idler wheels, and a yellow-orange track frame. Includes mud guards and undercarriage structure. Industrial aesthetic matching the rest of the excavator components, transparent background.", "description": "3/4 view of the excavator treads and undercarriage", "subtype": "object", "aspect_ratio": [1002, 950], "compression_suggestion": "high", "duration_secs": null, "loop": null, "animation": null}, "alien_terrain_texture": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/alien_terrain_texture_79741fea-9ccf-4b54-a525-26361e42f998.webp", "type": "image", "prompt": "Generate a fully tileable texture for alien planet ground that repeats seamlessly in all directions. Mix of rust-red and purple-grey soil with strange mineral veins and tiny bioluminescent spots. High contrast between soil and small rocky deposits. Otherworldly, sci-fi geological texture, high resolution, 512x512 style.", "description": "Seamlessly tiling alien soil texture with red and purple hues", "subtype": "ground", "aspect_ratio": [1024, 1024], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "alien_rock_texture": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/alien_rock_texture_db4a3530-b545-4dbb-be47-cf702723da4d.webp", "type": "image", "prompt": "Generate a fully tileable texture for alien rock formations, designed to repeat seamlessly. Layered, stratified rock with cyan-tinted stone, purple-grey layers, and rust-red veins. Include crystalline formations and strange geological patterns. Hard, solid surface appearance, high resolution, 512x512 style.", "description": "Seamlessly tiling stratified alien rock texture", "subtype": "ground", "aspect_ratio": [1024, 1024], "compression_suggestion": "low", "duration_secs": null, "loop": null, "animation": null}, "objective_marker_hologram": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/objective_marker_hologram_cffe8537-a005-4cb3-85d3-64535cfa817b.webp", "type": "image", "prompt": "Generate a futuristic holographic objective marker icon. A glowing, translucent blue-cyan frame with geometric patterns, scan lines, and a pulsing digital glow. Sci-fi UI element, floating projection style, transparent background.", "description": "Holographic UI marker for terraforming targets", "subtype": "ui", "aspect_ratio": [741, 730], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "ui_panel_background": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/images/ui_panel_background_5ae3638d-8cf4-4f1a-8117-72d7fc6a8996.webp", "type": "image", "prompt": "Generate a futuristic semi-transparent UI panel background. Dark blue-grey base with 70% opacity, glowing cyan accent lines, and techy corner elements. Subtle hexagonal patterns and circuit-board decorative details. Sleek sci-fi HUD style, 2:1 aspect ratio, transparent background.", "description": "Futuristic semi-transparent HUD panel background", "subtype": "ui", "aspect_ratio": [1196, 827], "compression_suggestion": "medium", "duration_secs": null, "loop": null, "animation": null}, "excavator_engine_sound": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/excavator_engine_sound_cfdc12d1-e41d-443f-b643-52bad4876875.mp3", "type": "audio", "prompt": "Low-frequency industrial diesel engine idling, heavy machinery rumble, mechanical vibration, deep rhythmic thrumming, constant mechanical hum, loopable, realistic construction site atmosphere, high-quality 48kHz recording.", "description": "Deep, rumbling diesel engine idle sound for the heavy excavator.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 5, "loop": true, "animation": null}, "hydraulic_movement_sound": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/hydraulic_movement_sound_065e7657-44a6-4441-9c18-12068db457f2.mp3", "type": "audio", "prompt": "Mechanical hydraulic hiss and whir, pneumatic piston extension and retraction, high-pressure fluid 'pssshhh' sound, subtle metallic creak of heavy articulated joints, smooth industrial movement sound effect.", "description": "Mechanical hiss and whir of hydraulic pistons for arm and boom movements.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.77, "loop": false, "animation": null}, "bucket_scoop_sound": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/bucket_scoop_sound_37793213-df98-4e8c-8533-87f3291f203c.mp3", "type": "audio", "prompt": "Heavy metal bucket scraping against rocky earth, crumbling soil and gravel clatter, gritty texture, powerful digging impact, deep crunching sound of dirt being compressed, industrial earthmoving.", "description": "Gritty sound of a metal bucket digging into rocky alien soil.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 2.53, "loop": false, "animation": null}, "dirt_dump_sound": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/dirt_dump_sound_5b404fe8-ae18-4346-ab55-f6393b8215c9.mp3", "type": "audio", "prompt": "Heavy thud of soil hitting the ground, falling rocks and loose earth 'whoosh', granular debris settling, scattering pebbles, low-frequency impact followed by soft dirt dispersal.", "description": "Sound of soil and rocks falling from the bucket and hitting the ground.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.89, "loop": false, "animation": null}, "objective_complete_sound": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/objective_complete_sound_b6092cdb-8257-41ea-9391-ae8ede5584da.mp3", "type": "audio", "prompt": "Futuristic sci-fi achievement notification, clean electronic chime, positive rising melody, high-tech holographic UI sound, rewarding and satisfying digital ping, short and non-intrusive.", "description": "Futuristic UI chime for completing a terraforming goal.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 1.28, "loop": false, "animation": null}, "ambient_alien_wind": {"url": "https://d2oir5eh8rty2e.cloudfront.net/assets/sounds/effect/ambient_alien_wind_7585d58d-991b-491b-9415-631292daff84.mp3", "type": "audio", "prompt": "Ambient alien planet wind, low whistling through rocky canyons, eerie atmospheric drone, subtle harmonic resonance, otherworldly texture, desolate and cold feeling, seamless loop, high-quality spatial depth.", "description": "Eerie, otherworldly wind for the barren planet atmosphere.", "subtype": "effect", "aspect_ratio": null, "compression_suggestion": "original", "duration_secs": 15, "loop": true, "animation": null}, "333333.gif": {"url": "https://dzmv1mxivz48k.cloudfront.net/images/Google_107480926520269799577/1787507132941_01M0QVMJGDWX8261XGP3GQVAPT.333333.gif", "type": "image", "prompt": null, "description": "User-provided animated GIF to use exactly as the game's thumbnail, without edits.", "subtype": null, "aspect_ratio": [640, 960], "compression_suggestion": "original", "duration_secs": null, "loop": null, "animation": null}}, "game_code": "<!DOCTYPE html>\n<html>\n<head>\n    <title>Terraform Tycoon</title>\n    <link href=\"https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Inter:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n    <style>\n        :root {\n            --transition-fast: 150ms;\n            --transition-normal: 300ms;\n            --ease-out: cubic-bezier(0.0, 0, 0.2, 1);\n            --space-xs: 8px;\n            --space-sm: 16px;\n            --space-md: 24px;\n            --space-lg: 32px;\n            --space-xl: 48px;\n            --color-primary: #00e5ff;\n            --color-bg: rgba(10, 20, 40, 0.85);\n            --color-accent: #ff6d00;\n        }\n\n        * {\n            -webkit-user-select: none !important;\n            -moz-user-select: none !important;\n            -ms-user-select: none !important;\n            user-select: none !important;\n            -webkit-touch-callout: none !important;\n            -webkit-user-drag: none !important;\n            -webkit-tap-highlight-color: transparent !important;\n        }\n\n        body, html {\n            margin: 0;\n            padding: 0;\n            width: 100%;\n            height: 100%;\n            overflow: hidden;\n            touch-action: none;\n            -ms-touch-action: none;\n            background: #000;\n            font-family: 'Inter', sans-serif;\n            -webkit-tap-highlight-color: transparent;\n        }\n\n        #game-world {\n            position: relative;\n            width: 100%;\n            height: 100%;\n        }\n\n        canvas {\n            display: block;\n            width: 100%;\n            height: 100%;\n        }\n\n        .ui-overlay {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            pointer-events: none;\n            z-index: 10;\n        }\n\n        .ui-overlay > * {\n            pointer-events: auto;\n        }\n\n        .hud-top {\n            position: absolute;\n            top: 45%;\n            transform: translateY(-50%);\n            left: var(--space-sm);\n            right: var(--space-sm);\n            display: flex;\n            justify-content: space-between;\n            align-items: flex-start;\n            pointer-events: none;\n            z-index: 15;\n        }\n\n        .hud-top > * {\n            pointer-events: auto;\n        }\n\n        .hud-panel {\n            background: var(--color-bg);\n            border: 2px solid rgba(0, 229, 255, 0.5);\n            border-radius: 10px;\n            padding: 10px 20px;\n            color: #fff;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 22px;\n            text-shadow: 0 0 8px var(--color-primary);\n        }\n\n        .hud-panel .label {\n            font-size: 14px;\n            font-weight: bold;\n            color: var(--color-primary);\n            margin-bottom: 4px;\n        }\n\n        /* Treasure Inventory Panel */\n        .treasure-panel {\n            position: absolute;\n            top: 265px;\n            left: var(--space-sm);\n            right: auto;\n            background: rgba(10, 20, 45, 0.95);\n            border: 2px solid #ffd700;\n            border-radius: 10px;\n            padding: 12px 16px;\n            color: #fff;\n            font-family: 'Orbitron', sans-serif;\n            width: 220px;\n            max-height: 280px;\n            overflow-y: auto;\n            box-shadow: 0 0 16px rgba(255, 215, 0, 0.35);\n            pointer-events: auto; /* Allow scrolling */\n            display: none; /* Hidden by default */\n            z-index: 99;\n        }\n\n        /* Control Mode Toggle Button */\n        .control-mode-toggle-btn {\n            position: absolute;\n            top: 330px;\n            right: var(--space-sm);\n            background: rgba(10, 20, 45, 0.95);\n            border: 2px solid var(--color-primary);\n            border-radius: 12px;\n            color: #fff;\n            padding: 12px 20px;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 18px;\n            font-weight: bold;\n            cursor: pointer;\n            pointer-events: auto;\n            z-index: 100;\n            box-shadow: 0 0 16px rgba(0, 229, 255, 0.45);\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .control-mode-toggle-btn:active {\n            transform: scale(0.95);\n        }\n\n        /* Graphics Toggle Button */\n        .graphics-toggle-btn {\n            position: absolute;\n            top: 395px;\n            right: var(--space-sm);\n            background: rgba(10, 20, 45, 0.95);\n            border: 2px solid #00ff66;\n            border-radius: 12px;\n            color: #fff;\n            padding: 12px 20px;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 18px;\n            font-weight: bold;\n            cursor: pointer;\n            pointer-events: auto;\n            z-index: 100;\n            box-shadow: 0 0 16px rgba(0, 255, 102, 0.45);\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .graphics-toggle-btn:active {\n            transform: scale(0.95);\n        }\n\n        .treasure-panel.expanded {\n            display: block;\n        }\n\n        /* Treasure Toggle Button */\n        .treasure-toggle-btn {\n            position: absolute;\n            top: 200px;\n            left: var(--space-sm);\n            right: auto;\n            background: rgba(10, 20, 45, 0.95);\n            border: 2px solid #ffd700;\n            border-radius: 12px;\n            color: #fff;\n            padding: 12px 20px;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 18px;\n            font-weight: bold;\n            cursor: pointer;\n            pointer-events: auto;\n            z-index: 100;\n            box-shadow: 0 0 16px rgba(255, 215, 0, 0.45);\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .treasure-toggle-btn:active {\n            transform: scale(0.95);\n        }\n\n        /* Handbook styles */\n        .handbook-toggle-btn {\n            position: absolute;\n            top: 265px;\n            right: var(--space-sm);\n            background: rgba(10, 20, 45, 0.95);\n            border: 2px solid var(--color-primary);\n            border-radius: 12px;\n            color: #fff;\n            padding: 12px 20px;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 18px;\n            font-weight: bold;\n            cursor: pointer;\n            pointer-events: auto;\n            z-index: 100;\n            box-shadow: 0 0 16px rgba(0, 229, 255, 0.45);\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .handbook-toggle-btn:active {\n            transform: scale(0.95);\n        }\n\n        .handbook-modal {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(5, 10, 25, 0.97);\n            z-index: 1000;\n            display: none;\n            flex-direction: column;\n            color: #fff;\n            font-family: 'Inter', sans-serif;\n            pointer-events: auto;\n        }\n\n        .handbook-modal.active {\n            display: flex;\n        }\n\n        .handbook-header {\n            padding: 20px;\n            border-bottom: 2px solid var(--color-primary);\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            background: rgba(10, 25, 50, 0.9);\n        }\n\n        .handbook-header h2 {\n            font-family: 'Orbitron', sans-serif;\n            margin: 0;\n            font-size: 24px;\n            color: var(--color-primary);\n            text-shadow: 0 0 10px rgba(0, 229, 255, 0.5);\n            display: flex;\n            align-items: center;\n            gap: 10px;\n        }\n\n        .handbook-close-btn {\n            background: rgba(255, 0, 85, 0.2);\n            border: 1px solid #ff0055;\n            color: #ff0055;\n            padding: 6px 16px;\n            border-radius: 8px;\n            cursor: pointer;\n            font-family: 'Orbitron', sans-serif;\n            font-weight: bold;\n            font-size: 14px;\n        }\n\n        .handbook-close-btn:active {\n            transform: scale(0.95);\n        }\n\n        .handbook-tabs {\n            display: flex;\n            background: rgba(5, 12, 30, 0.8);\n            border-bottom: 1px solid rgba(0, 229, 255, 0.2);\n            overflow-x: auto;\n            white-space: nowrap;\n        }\n\n        .handbook-tab {\n            padding: 14px 20px;\n            cursor: pointer;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 13px;\n            font-weight: bold;\n            color: #8892b0;\n            border-bottom: 2px solid transparent;\n            transition: all var(--transition-fast) var(--ease-out);\n        }\n\n        .handbook-tab.active {\n            color: var(--color-primary);\n            border-bottom-color: var(--color-primary);\n            background: rgba(0, 229, 255, 0.05);\n        }\n\n        .handbook-content-container {\n            flex: 1;\n            padding: 24px;\n            overflow-y: auto;\n            line-height: 1.6;\n        }\n\n        .handbook-pane {\n            display: none;\n        }\n\n        .handbook-pane.active {\n            display: block;\n        }\n\n        .handbook-pane h3 {\n            font-family: 'Orbitron', sans-serif;\n            color: var(--color-accent);\n            margin-top: 0;\n            font-size: 18px;\n            border-bottom: 1px solid rgba(255, 109, 0, 0.3);\n            padding-bottom: 8px;\n        }\n\n        .handbook-section {\n            background: rgba(255, 255, 255, 0.03);\n            border-left: 3px solid var(--color-primary);\n            padding: 12px 16px;\n            border-radius: 0 8px 8px 0;\n            margin-bottom: 16px;\n        }\n\n        .handbook-section.accent {\n            border-left-color: var(--color-accent);\n        }\n\n        .control-key-row {\n            display: flex;\n            align-items: center;\n            margin-bottom: 10px;\n            gap: 12px;\n        }\n\n        .key-badge {\n            background: rgba(255, 255, 255, 0.15);\n            border: 1px solid rgba(255, 255, 255, 0.3);\n            border-bottom-width: 3px;\n            padding: 4px 10px;\n            border-radius: 6px;\n            font-family: 'Orbitron', monospace;\n            font-size: 12px;\n            font-weight: bold;\n            min-width: 24px;\n            text-align: center;\n            color: #00e5ff;\n        }\n\n        /* Mission Progress Header */\n        .mission-panel {\n            position: absolute;\n            top: var(--space-sm);\n            right: var(--space-sm);\n            background: rgba(10, 25, 50, 0.95);\n            border: 2px solid var(--color-primary);\n            box-shadow: 0 0 20px rgba(0, 229, 255, 0.5);\n            border-radius: 12px;\n            padding: 12px 16px;\n            color: #fff;\n            font-family: 'Orbitron', sans-serif;\n            text-align: center;\n            width: 260px;\n            z-index: 100;\n            cursor: pointer;\n            transition: all 0.2s;\n        }\n        .mission-panel:hover {\n            box-shadow: 0 0 28px rgba(0, 229, 255, 0.8);\n            border-color: #ffffff;\n        }\n        .mission-panel:active {\n            transform: scale(0.96);\n        }\n\n        .mission-title {\n            font-size: 16px;\n            color: var(--color-primary);\n            letter-spacing: 2px;\n            margin-bottom: 8px;\n            font-weight: 900;\n        }\n\n        .mission-bar-container {\n            width: 100%;\n            height: 16px;\n            background: rgba(255,255,255,0.1);\n            border-radius: 8px;\n            overflow: hidden;\n            border: 1.5px solid rgba(0, 229, 255, 0.5);\n            position: relative;\n        }\n\n        .mission-bar-fill {\n            width: 0%;\n            height: 100%;\n            background: linear-gradient(90deg, #00e5ff, #00ff66);\n            box-shadow: 0 0 10px #00ff66;\n            transition: width 0.5s ease-out;\n        }\n\n        .mission-status {\n            font-size: 13px;\n            margin-top: 6px;\n            color: #ffea00;\n            font-weight: bold;\n        }\n\n        /* Custom scrollbar for treasure panel */\n        .treasure-panel::-webkit-scrollbar {\n            width: 4px;\n        }\n        .treasure-panel::-webkit-scrollbar-track {\n            background: rgba(0,0,0,0.2);\n        }\n        .treasure-panel::-webkit-scrollbar-thumb {\n            background: #ffd700;\n            border-radius: 2px;\n        }\n\n        .treasure-panel h4 {\n            margin: 0 0 10px 0;\n            font-size: 14px;\n            color: #ffd700;\n            letter-spacing: 1px;\n            text-transform: uppercase;\n            border-bottom: 2px solid rgba(255, 215, 0, 0.4);\n            padding-bottom: 6px;\n        }\n\n        .treasure-row {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            font-size: 16px;\n            margin: 8px 0;\n        }\n\n        .treasure-icon {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        /* Removed radar styles */\n\n        .controls-panel {\n            position: absolute;\n            bottom: var(--space-sm);\n            left: var(--space-sm);\n            right: var(--space-sm);\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            gap: 10px;\n        }\n\n        /* Mode Switcher Button */\n        .mode-toggle-btn {\n            position: absolute;\n            top: 14px;\n            right: 14px;\n            background: rgba(0, 229, 255, 0.2);\n            border: 1px solid var(--color-primary);\n            border-radius: 20px;\n            color: #fff;\n            padding: 6px 14px;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 12px;\n            font-weight: bold;\n            cursor: pointer;\n            pointer-events: auto;\n            z-index: 100;\n            box-shadow: 0 0 10px rgba(0, 229, 255, 0.3);\n            display: flex;\n            align-items: center;\n            gap: 6px;\n        }\n\n        .mode-toggle-btn:active {\n            background: rgba(0, 229, 255, 0.5);\n            transform: scale(0.95);\n        }\n\n        /* Simple controls layout */\n        .simple-actions-panel {\n            display: grid;\n            grid-template-columns: repeat(2, 80px);\n            grid-template-rows: repeat(2, 60px);\n            gap: 8px;\n        }\n\n        .simple-btn {\n            background: rgba(255, 109, 0, 0.2);\n            border: 1px solid var(--color-accent);\n            border-radius: 8px;\n            color: #fff;\n            font-size: 12px;\n            font-family: 'Orbitron', sans-serif;\n            font-weight: bold;\n            cursor: pointer;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            gap: 4px;\n            text-align: center;\n            box-shadow: 0 0 5px rgba(255, 109, 0, 0.2);\n        }\n\n        .simple-btn.blue {\n            background: rgba(0, 229, 255, 0.2);\n            border: 1px solid var(--color-primary);\n            box-shadow: 0 0 5px rgba(0, 229, 255, 0.2);\n        }\n\n        .simple-btn:active {\n            transform: scale(0.95);\n            filter: brightness(1.3);\n        }\n\n        .joystick-container {\n            width: 180px;\n            height: 180px;\n            position: relative;\n        }\n\n        .joystick-base {\n            width: 160px;\n            height: 160px;\n            border-radius: 50%;\n            background: rgba(0, 229, 255, 0.15);\n            border: 4px solid var(--color-primary);\n            box-shadow: 0 0 20px rgba(0, 229, 255, 0.6), inset 0 0 15px rgba(0, 229, 255, 0.4);\n            position: absolute;\n            bottom: 10px;\n            left: 10px;\n        }\n\n        .joystick-stick {\n            width: 68px;\n            height: 68px;\n            border-radius: 50%;\n            background: #00e5ff; /* Solid Neon Cyan */\n            border: 3px solid #ffffff;\n            /* Embossed 3D look */\n            box-shadow: 0 6px 0 #0097a7, 0 8px 16px rgba(0, 0, 0, 0.6);\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            transition: none;\n        }\n\n        .joystick-label {\n            position: absolute;\n            top: -28px;\n            width: 100%;\n            text-align: center;\n            color: var(--color-primary);\n            font-family: 'Orbitron', sans-serif;\n            font-size: 14px;\n            font-weight: 900;\n            text-shadow: 0 0 8px rgba(0, 229, 255, 0.8);\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            pointer-events: none;\n        }\n\n        /* Auto Dig & Dump buttons above right joystick */\n        .auto-btn-container {\n            position: absolute;\n            bottom: 155px;\n            left: 0;\n            width: 100%;\n            display: flex;\n            flex-direction: column;\n            gap: 12px;\n            pointer-events: auto;\n            z-index: 200;\n        }\n\n        .auto-btn {\n            width: 100%;\n            height: 64px; /* Enlarged */\n            background: #ff6d00; /* Solid Color */\n            border: none;\n            border-radius: 12px;\n            color: #fff;\n            font-size: 18px; /* Enlarged font */\n            font-family: 'Orbitron', 'Inter', sans-serif;\n            font-weight: 900;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            cursor: pointer;\n            /* Embossed/Raised look */\n            box-shadow: 0 6px 0 #b34a00, 0 8px 16px rgba(0, 0, 0, 0.6);\n            text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);\n            outline: none;\n            position: relative;\n            transform: translateY(-4px);\n            transition: transform 0.05s, box-shadow 0.05s;\n        }\n\n        .auto-btn:active {\n            transform: translateY(2px);\n            box-shadow: 0 0px 0 #b34a00, 0 2px 4px rgba(0, 0, 0, 0.4);\n        }\n\n        .drive-panel {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 4px;\n            background: rgba(10, 20, 40, 0.6);\n            border: 1px solid rgba(0, 229, 255, 0.2);\n            border-radius: 8px;\n            padding: 6px;\n        }\n\n        .drive-panel-label {\n            font-family: 'Orbitron', sans-serif;\n            font-size: 11px;\n            font-weight: bold;\n            color: var(--color-primary);\n            text-align: center;\n            margin-bottom: 4px;\n            text-shadow: 0 0 6px rgba(0, 229, 255, 0.6);\n        }\n\n        .drive-grid {\n            display: grid;\n            grid-template-columns: repeat(3, 60px);\n            grid-template-rows: repeat(2, 60px);\n            gap: 6px;\n        }\n\n        .drive-btn {\n            background: #00cbd6; /* Solid Cyan */\n            border: none;\n            border-radius: 12px;\n            color: #fff;\n            font-size: 18px; /* Enlarged font */\n            font-family: 'Orbitron', sans-serif;\n            font-weight: 900;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            user-select: none;\n            -webkit-user-select: none;\n            /* Embossed/Raised look */\n            box-shadow: 0 6px 0 #008e96, 0 8px 16px rgba(0, 0, 0, 0.6);\n            position: relative;\n            transform: translateY(-4px);\n            transition: transform 0.05s, box-shadow 0.05s;\n        }\n\n        .drive-btn:active {\n            transform: translateY(2px);\n            box-shadow: 0 0px 0 #008e96, 0 2px 4px rgba(0, 0, 0, 0.4);\n        }\n\n        .ctrl-btn {\n            display: none; /* replaced by joystick control */\n        }\n\n        .info-text {\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            color: #fff;\n            font-family: 'Orbitron', sans-serif;\n            font-size: 24px;\n            text-align: center;\n            text-shadow: 0 0 16px var(--color-primary);\n            opacity: 0;\n            transition: opacity 0.5s;\n            pointer-events: none;\n        }\n\n        .info-text.visible {\n            opacity: 1;\n        }\n\n        .edit-overlay {\n            position: absolute;\n            top: var(--space-sm);\n            left: var(--space-sm);\n            background: var(--color-bg);\n            border: 1px solid rgba(0, 229, 255, 0.3);\n            border-radius: 8px;\n            padding: 16px;\n            color: #fff;\n            font-size: 16px;\n        }\n\n        .edit-overlay h2 {\n            font-family: 'Orbitron', sans-serif;\n            font-size: 18px;\n            color: var(--color-primary);\n            margin: 0 0 8px 0;\n        }\n\n        .edit-overlay p {\n            margin: 4px 0;\n            font-size: 14px;\n            opacity: 0.8;\n        }\n\n        /* Floating Gem Styles */\n        .floating-gem {\n            position: absolute;\n            font-size: 36px;\n            filter: drop-shadow(0 0 12px var(--shadow-color));\n            pointer-events: none;\n            z-index: 10000;\n            transition: left 2.0s cubic-bezier(0.25, 1, 0.5, 1), top 2.0s cubic-bezier(0.25, 1, 0.5, 1), transform 2.0s ease-in-out, opacity 2.0s ease-in-out;\n            transform: translate(-50%, -50%) scale(1);\n        }\n        /* Tutorial / Guide Modals */\n        .tutorial-modal-overlay {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(5, 10, 20, 0.95);\n            z-index: 20000;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            pointer-events: auto;\n            font-family: 'Inter', sans-serif;\n        }\n        .tutorial-modal {\n            background: rgba(10, 25, 45, 0.98);\n            border: 3px solid var(--color-primary);\n            box-shadow: 0 0 30px rgba(0, 229, 255, 0.6);\n            border-radius: 16px;\n            width: 580px;\n            max-width: 90%;\n            max-height: 85%;\n            overflow-y: auto;\n            color: #fff;\n            padding: 30px;\n            display: flex;\n            flex-direction: column;\n            gap: 20px;\n        }\n        .tutorial-modal h2 {\n            font-family: 'Orbitron', sans-serif;\n            color: var(--color-primary);\n            text-align: center;\n            margin: 0;\n            font-size: 26px;\n            letter-spacing: 2px;\n            text-shadow: 0 0 10px rgba(0, 229, 255, 0.5);\n        }\n        .tutorial-step {\n            background: rgba(255, 255, 255, 0.03);\n            border-left: 4px solid var(--color-accent);\n            padding: 12px 16px;\n            border-radius: 0 8px 8px 0;\n            display: flex;\n            gap: 16px;\n            align-items: flex-start;\n        }\n        .tutorial-step-num {\n            background: var(--color-accent);\n            color: #fff;\n            font-family: 'Orbitron', sans-serif;\n            font-weight: 900;\n            font-size: 14px;\n            width: 26px;\n            height: 26px;\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            flex-shrink: 0;\n            box-shadow: 0 0 8px var(--color-accent);\n        }\n        .tutorial-step-content {\n            flex: 1;\n        }\n        .tutorial-step-content strong {\n            color: #ffd700;\n            display: block;\n            margin-bottom: 4px;\n            font-size: 16px;\n        }\n        .tutorial-step-content p {\n            margin: 0;\n            font-size: 14px;\n            color: #cbd5e1;\n            line-height: 1.5;\n        }\n        .tutorial-btn {\n            background: linear-gradient(135deg, var(--color-primary), #00ff66);\n            border: none;\n            border-radius: 12px;\n            color: #020617;\n            font-family: 'Orbitron', sans-serif;\n            font-weight: 900;\n            font-size: 18px;\n            padding: 15px;\n            cursor: pointer;\n            box-shadow: 0 0 20px rgba(0, 229, 255, 0.4);\n            transition: all 0.2s;\n            text-align: center;\n        }\n        .tutorial-btn:active {\n            transform: scale(0.97);\n            filter: brightness(1.2);\n        }\n        @media (prefers-reduced-motion: reduce) {\n            * {\n                transition: none !important;\n                animation: none !important;\n            }\n        }\n    </style>\n</head>\n<body>\n    <div id=\"loading-screen\" style=\"\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background: radial-gradient(circle at center, #0d1b2a 0%, #010811 100%);\n        display: flex;\n        flex-direction: column;\n        justify-content: center;\n        align-items: center;\n        z-index: 10000;\n        font-family: 'Orbitron', sans-serif;\n        color: #fff;\n        transition: opacity 0.5s ease-out;\n        overflow: hidden;\n    \">\n        <div id=\"loading-title\" style=\"font-size: 32px; font-weight: 900; letter-spacing: 3px; color: #00e5ff; text-shadow: 0 0 15px rgba(0, 229, 255, 0.6); margin-bottom: 8px; z-index: 2;\">TERRAFORM TYCOON</div>\n        <div id=\"loading-subtitle\" style=\"font-size: 11px; letter-spacing: 4px; color: #8892b0; margin-bottom: 40px; text-transform: uppercase; z-index: 2;\">Heavy Excavator Sandbox</div>\n        \n        <!-- Interactive Loader -->\n        <div style=\"width: 260px; height: 6px; background: rgba(0, 229, 255, 0.1); border-radius: 3px; border: 1px solid rgba(0, 229, 255, 0.3); overflow: hidden; position: relative; margin-bottom: 15px; z-index: 2;\">\n            <div id=\"loading-progress-bar\" style=\"width: 0%; height: 100%; background: linear-gradient(90deg, #00e5ff, #00ff66); box-shadow: 0 0 10px #00e5ff; transition: width 0.3s ease-out;\"></div>\n        </div>\n        \n        <div id=\"loading-status-text\" style=\"font-size: 12px; color: #00e5ff; letter-spacing: 1.5px; animation: loadingPulse 1.5s infinite; text-transform: uppercase; z-index: 2;\">CALIBRATING NEURAL LINK...</div>\n        \n        <!-- Cute green alien mini-zombies decoration -->\n        <div class=\"loading-zombie\" style=\"bottom: 80px; animation: zWalk 14s infinite linear;\">\n            <div class=\"z-antenna\"></div>\n            <div class=\"z-bulb\"></div>\n            <div class=\"z-head\">\n                <div class=\"z-eye l\"></div>\n                <div class=\"z-eye r\"></div>\n                <div class=\"z-mouth\"></div>\n            </div>\n            <div class=\"z-body\"></div>\n            <div class=\"z-arm l\"></div>\n            <div class=\"z-arm r\"></div>\n            <div class=\"z-leg l\"></div>\n            <div class=\"z-leg r\"></div>\n        </div>\n\n        <div class=\"loading-zombie\" style=\"top: 40%; animation: zPeekRight 8s infinite ease-in-out;\">\n            <div class=\"z-antenna\"></div>\n            <div class=\"z-bulb\"></div>\n            <div class=\"z-head\">\n                <div class=\"z-eye l\"></div>\n                <div class=\"z-eye r\"></div>\n                <div class=\"z-mouth\"></div>\n            </div>\n            <div class=\"z-body\"></div>\n            <div class=\"z-arm l\"></div>\n            <div class=\"z-arm r\"></div>\n            <div class=\"z-leg l\"></div>\n            <div class=\"z-leg r\"></div>\n        </div>\n\n        <div class=\"loading-zombie\" style=\"top: 60%; animation: zPeekLeft 10s infinite ease-in-out;\">\n            <div class=\"z-antenna\"></div>\n            <div class=\"z-bulb\"></div>\n            <div class=\"z-head\">\n                <div class=\"z-eye l\"></div>\n                <div class=\"z-eye r\"></div>\n                <div class=\"z-mouth\"></div>\n            </div>\n            <div class=\"z-body\"></div>\n            <div class=\"z-arm l\"></div>\n            <div class=\"z-arm r\"></div>\n            <div class=\"z-leg l\"></div>\n            <div class=\"z-leg r\"></div>\n        </div>\n\n        <div class=\"loading-zombie\" style=\"top: calc(50% - 130px); left: calc(50% + 100px); transform: scale(0.85); animation: zBob 2s infinite ease-in-out;\">\n            <div class=\"z-antenna\"></div>\n            <div class=\"z-bulb\"></div>\n            <div class=\"z-head\">\n                <div class=\"z-eye l\"></div>\n                <div class=\"z-eye r\"></div>\n                <div class=\"z-mouth\"></div>\n            </div>\n            <div class=\"z-body\"></div>\n            <div class=\"z-arm l\"></div>\n            <div class=\"z-arm r\"></div>\n            <div class=\"z-leg l\"></div>\n            <div class=\"z-leg r\"></div>\n        </div>\n\n        <style>\n            @keyframes loadingPulse {\n                0% { opacity: 0.5; }\n                50% { opacity: 1; }\n                100% { opacity: 0.5; }\n            }\n            .loading-zombie {\n                position: absolute;\n                width: 40px;\n                height: 55px;\n                pointer-events: none;\n                z-index: 1;\n            }\n            .z-head {\n                position: absolute;\n                top: 0;\n                left: 8px;\n                width: 24px;\n                height: 24px;\n                background: #39ff14;\n                border-radius: 50%;\n                box-shadow: 0 0 10px rgba(57, 255, 20, 0.7);\n                animation: zBob 1.2s infinite ease-in-out;\n            }\n            .z-antenna {\n                position: absolute;\n                top: -6px;\n                left: 19px;\n                width: 2px;\n                height: 8px;\n                background: #39ff14;\n            }\n            .z-bulb {\n                position: absolute;\n                top: -10px;\n                left: 17px;\n                width: 6px;\n                height: 6px;\n                background: #ff0055;\n                border-radius: 50%;\n                box-shadow: 0 0 8px #ff0055;\n                animation: bulbFlash 0.5s infinite alternate;\n            }\n            .z-eye {\n                position: absolute;\n                top: 8px;\n                width: 4px;\n                height: 4px;\n                background: #ff0000;\n                border-radius: 50%;\n                box-shadow: 0 0 5px #ff0000;\n            }\n            .z-eye.l { left: 5px; }\n            .z-eye.r { right: 5px; }\n            .z-mouth {\n                position: absolute;\n                bottom: 4px;\n                left: 10px;\n                width: 4px;\n                height: 4px;\n                background: #0d1b2a;\n                border-radius: 50%;\n            }\n            .z-body {\n                position: absolute;\n                top: 20px;\n                left: 10px;\n                width: 20px;\n                height: 24px;\n                background: #228b22;\n                border-radius: 5px 5px 0 0;\n            }\n            .z-arm {\n                position: absolute;\n                top: 24px;\n                width: 12px;\n                height: 5px;\n                background: #39ff14;\n                border-radius: 2px;\n                animation: zArmWave 1s infinite ease-in-out alternate;\n            }\n            .z-arm.l {\n                left: 0;\n                transform-origin: right center;\n            }\n            .z-arm.r {\n                right: 0;\n                transform-origin: left center;\n                animation-delay: 0.5s;\n            }\n            .z-leg {\n                position: absolute;\n                bottom: 0;\n                width: 5px;\n                height: 12px;\n                background: #1a601a;\n                border-radius: 2px;\n                animation: zLegSwing 0.4s infinite ease-in-out alternate;\n            }\n            .z-leg.l {\n                left: 11px;\n            }\n            .z-leg.r {\n                right: 11px;\n                animation-delay: 0.2s;\n            }\n\n            @keyframes zBob {\n                0%, 100% { transform: translateY(0); }\n                50% { transform: translateY(-3px); }\n            }\n            @keyframes zArmWave {\n                0% { transform: rotate(-15deg); }\n                100% { transform: rotate(15deg); }\n            }\n            @keyframes zLegSwing {\n                0% { transform: translateY(0) rotate(-10deg); }\n                100% { transform: translateY(-1px) rotate(10deg); }\n            }\n            @keyframes bulbFlash {\n                0% { opacity: 0.4; filter: brightness(0.8); }\n                100% { opacity: 1; filter: brightness(1.5); }\n            }\n\n            /* Specific path animations for zombies */\n            @keyframes zWalk {\n                0% { left: -50px; transform: scaleX(1); }\n                45% { transform: scaleX(1); }\n                50% { left: calc(100% + 10px); transform: scaleX(-1); }\n                95% { transform: scaleX(-1); }\n                100% { left: -50px; transform: scaleX(1); }\n            }\n            @keyframes zPeekRight {\n                0%, 100% { right: -40px; transform: scaleX(1); }\n                20%, 80% { right: 15px; transform: scaleX(1); }\n            }\n            @keyframes zPeekLeft {\n                0%, 100% { left: -40px; transform: scaleX(-1); }\n                30%, 70% { left: 15px; transform: scaleX(-1); }\n            }\n        </style>\n    </div>\n\n    <div id=\"game-world\"></div>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js\"></script>\n    <script>\n    /*\n     * TERRAFORM TYCOON\n     * A 3D creative sandbox where players operate a detailed excavator\n     * to terraform alien planet terrain. Built with Three.js.\n     * Features: articulated excavator, deformable heightmap terrain,\n     * objective system, mobile touch controls.\n     */\n\n    async function run(mode) {\n        const gameWorld = document.getElementById('game-world');\n        gameWorld.innerHTML = '';\n\n        const config = window.gameConfig;\n        let isModalOpen = false;\n\n        // ===== CINEMATIC TUTORIAL STATE =====\n        let isCinematicActive = (mode === 'play');\n        let updateCinematicOverlay;\n        let cinematicStep = 0;\n        let cinematicInterpolation = 0; // LERP transitions\n        let cinematicLerpSpeed = 2.0;\n\n        const cinematicSteps = [\n            {\n                camPos: new THREE.Vector3(0, 48, 62),\n                lookAt: new THREE.Vector3(0, 4, 0),\n                titleKey: 'cineWelcomeTitle',\n                descKey: 'cineWelcomeDesc'\n            },\n            {\n                camPos: new THREE.Vector3(5, 5.5, 17.5),\n                lookAt: new THREE.Vector3(0, 2.5, 10),\n                titleKey: 'cineExcavatorTitle',\n                descKey: 'cineExcavatorDesc'\n            },\n            {\n                camPos: new THREE.Vector3(-10, 15, -4),\n                lookAt: new THREE.Vector3(0, 5, -15),\n                titleKey: 'cineLanderTitle',\n                descKey: 'cineLanderDesc'\n            },\n            {\n                camPos: new THREE.Vector3(-19, 12, -10),\n                lookAt: new THREE.Vector3(-11, 4.5, -19),\n                titleKey: 'cineTitanTitle',\n                descKey: 'cineTitanDesc'\n            },\n            {\n                camPos: new THREE.Vector3(-20, 9, -21),\n                lookAt: new THREE.Vector3(-28, 1.5, -28),\n                titleKey: 'cineHiveTitle',\n                descKey: 'cineHiveDesc'\n            },\n            {\n                camPos: new THREE.Vector3(-15, 6.5, 17.5),\n                lookAt: new THREE.Vector3(-22, 1.0, 22),\n                titleKey: 'cineHazardTitle',\n                descKey: 'cineHazardDesc'\n            }\n        ];\n\n        let cineCurrentPos = new THREE.Vector3(0, 48, 62);\n        let cineCurrentLookAt = new THREE.Vector3(0, 4, 0);\n        let cineStartPos = new THREE.Vector3(0, 48, 62);\n        let cineStartLookAt = new THREE.Vector3(0, 4, 0);\n\n        function nextCinematicStep() {\n            if (cinematicStep < cinematicSteps.length - 1) {\n                cineStartPos.copy(camera.position);\n                cineStartLookAt.copy(cineCurrentLookAt);\n                \n                cinematicStep++;\n                cinematicInterpolation = 0;\n                updateCinematicOverlay();\n                playSynthBeep(1200, 0.05);\n            } else {\n                endCinematic();\n            }\n        }\n\n        function endCinematic() {\n            isCinematicActive = false;\n            isModalOpen = false;\n            const overlayEl = document.getElementById('cinematic-overlay');\n            if (overlayEl) {\n                overlayEl.style.transition = 'opacity 0.5s ease-out';\n                overlayEl.style.opacity = '0';\n                setTimeout(() => {\n                    overlayEl.remove();\n                }, 500);\n            }\n            playSynthBeep(1600, 0.2);\n            \n            // Set camera coordinates to smoothly transition behind the excavator\n            camState.azimuth = Math.PI * 0.75;\n            camState.elevation = 0.8;\n            camState.distance = 32;\n        }\n\n        // ===== LOCALIZATION SYSTEM =====\n        const translations = {\n            en: { depth: 'DEPTH', graphicsHigh: 'Graphics: Ultra 3D', graphicsLow: 'Graphics: 60 FPS (Fast)', credits: 'CREDITS', buildBudget: 'Build Budget', baseBuild: '\ud83d\ude80 BASE BUILD PROGRESS', mission: '\ud83e\ude90 ALIEN TERRAFORMING MISSION \ud83e\ude90', vault: 'Vault', expand: 'Expand', collapse: 'Collapse', handbook: 'Handbook', modeSimple: 'Mode: Simple (A)', modeClassic: 'Mode: Classic', autoDig: '\ud83e\udd16 Auto Dig', autoDump: '\ud83e\udd16 Auto Dump', leftJoy: 'Drive & Steer', cabinRot: 'Cabin Rotation', left: '\u25c0 Left', right: 'Right \u25b6', guide: '\ud83d\udca1 Tap Here For Detailed Guide \ud83d\udca1', missionComplete: 'Mission Complete!', awarded: 'Credits Awarded', progress: 'Progress', reward: 'Reward', allComplete: '\ud83c\udf89 All 30 missions completed! You are the Sector Overlord! \ud83d\ude80', loading: 'CALIBRATING NEURAL LINK...', cabinInterface: 'Calibrating Cabin Interface...', bootEngine: 'Booting Three.js Engine...', genPlanets: 'Generating Procedural Planets...', monoliths: 'Erecting Alien Monoliths...', launchpad: 'Constructing Colony Launchpad...', audioSync: 'Syncing Audio Interfaces...', ready: 'System Ready!', titanAssembly: '\ud83e\udd16 TITAN ASSEMBLY', titanDesc: 'Assemble the colossal planetary guard!', found: 'FOUND', missing: 'MISSING', partsProgress: 'Progress', treasury: 'Treasury & Artifacts', editMode: 'EDIT MODE', editDesc: 'Use the Game Parameters panel to adjust settings.', editSave: 'Changes are saved automatically.', guideTitle: 'MISSION GUIDE', objective: 'Your Objective:', actionSteps: 'Action Steps:', tipSuccess: 'Tip for Success:', gotIt: 'Got It!', handbookTitle: '\ud83d\udcd6 CABIN OPERATIONS MANUAL', close: 'CLOSE [X]', tabIntro: 'Mission Brief', tabControls: 'Simple Controls', tabRadar: 'Titan Archaeology', tabThreats: 'Subterranean Threats', systemFault: '\u26a0\ufe0f SYSTEM CRITICAL FAULT \u26a0\ufe0f', rebootIn: 'System rebooting in:', launched: '\ud83d\ude80 LAUNCHED! \ud83d\ude80', warning: '\u26a0\ufe0f WARNING! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 SANDWORM SLAIN! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOMB TRIGGERED! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOMB DISARMED \ud83c\udfaf', blastWave: '\ud83d\udca5 BLAST WAVE DETECTED \ud83d\udca5', assembling: 'Assembling', shipReady: '\ud83c\udf89 Starship Assembled! Ready for Launch!', skip: 'SKIP [X]', next: 'NEXT', startExploring: 'START EXPLORING', cineWelcomeTitle: '\ud83d\ude80 TERRAFORM TYCOON PROTOCOL', cineWelcomeDesc: 'Welcome Pioneer! You have been deployed to this desolate alien planet. Your objective is to reshape the terrain, gather critical resources, and build a massive colony starship base.', cineExcavatorTitle: '\ud83d\ude9c YOUR HEAVY EXCAVATOR', cineExcavatorDesc: 'Use the Left Joystick to drive and steer, and the Q/E keys (or Cabin Rotation buttons) to turn the upper base. Tap the orange Auto Dig and blue Auto Dump buttons to easily shape the sandy terrain!', cineLanderTitle: '\ud83d\ude80 COLONY SPACESHIP LANDER', cineLanderDesc: 'Reshape the terrain and collect resource gemstones to fund construction. Watch the Starship physically assemble and prepare for launch as your credits scale up!', cineTitanTitle: '\ud83e\udd16 ANCIENT TITAN MECH', cineTitanDesc: 'Six legendary components are buried deep in the dunes. Use Auto Dig to unearth them and let the tractor beam deliver them here. Retrieve all six to activate a colossal 10-meter-tall bodyguard!', cineHiveTitle: '\ud83d\udc7e ALIEN INFESTATION NESTS', cineHiveDesc: 'Pulsating hive nests in the corners of the map spawn aggressive green zombies. Smash them with your heavy bucket to secure the sector, earn +300 Credits, and freeze zombie spawns!', cineHazardTitle: '\u26a0\ufe0f SUBTERRANEAN HAZARDS', cineHazardDesc: 'Be careful! Purple glowing dunes hide giant sleeping Sandworms that attack if disturbed. Flashing high-tech landmines will detonate and send your vehicle flying if run over or dug up!', cineOverview: 'SYSTEM PROTOCOL OVERVIEW', warnSandworm: 'Giant Purple Sandworm!', bucketImpact: '\ud83d\udca5 BUCKET IMPACT! (+100) \ud83d\udca5', trackCollision: '\ud83d\ude9c TRACK COLLISION! (+100) \ud83d\ude9c', sandwormHp: 'Sandworm HP: {hp} / 10', warnLandmine: 'Landmine! 2s!', titanAssembled: '\ud83e\udd16 TITAN FULLY ASSEMBLED! \ud83e\udd16', titanActivated: 'Planetary Ancient Guardian Activated!', titanBonus: '\ud83c\udf81 Bonus Award: +5,000 Credits!', partRetrieved: '\ud83e\udd16 PART RETRIEVED! \ud83e\udd16', partDelivered: 'Delivered {name} to Assembly Site', titanProgress: 'Progress: {count} / 6 Parts' },\n            zh: { depth: '\u6df1\u5ea6', graphicsHigh: '\u753b\u8d28: \u9ad8\u7ea73D', graphicsLow: '\u753b\u8d28: 60\u5e27\u6781\u901f', credits: '\u8d44\u91d1', buildBudget: '\u5efa\u8bbe\u9884\u7b97', baseBuild: '\ud83d\ude80 \u57fa\u5730\u5efa\u8bbe\u8fdb\u5ea6', mission: '\ud83e\ude90 \u5916\u661f\u6539\u9020\u4efb\u52a1 \ud83e\ude90', vault: '\u5b9d\u5e93', expand: '\u5c55\u5f00', collapse: '\u6536\u8d77', handbook: '\u624b\u518c', modeSimple: '\u6a21\u5f0f: \u7b80\u6613 (A)', modeClassic: '\u6a21\u5f0f: \u7ecf\u5178', autoDig: '\ud83e\udd16 \u81ea\u52a8\u6316\u6398', autoDump: '\ud83e\udd16 \u81ea\u52a8\u503e\u5012', leftJoy: '\u9a7e\u9a76\u8f6c\u5411', cabinRot: '\u8231\u4f53\u65cb\u8f6c', left: '\u25c0 \u5de6', right: '\u53f3 \u25b6', guide: '\ud83d\udca1 \u70b9\u51fb\u67e5\u770b\u8be6\u7ec6\u6307\u5357 \ud83d\udca1', missionComplete: '\u4efb\u52a1\u5b8c\u6210\uff01', awarded: '\u8d44\u91d1\u5956\u52b1', progress: '\u8fdb\u5ea6', reward: '\u5956\u52b1', allComplete: '\ud83c\udf89 \u5168\u90e830\u4e2a\u4efb\u52a1\u5df2\u5b8c\u6210\uff01\u4f60\u662f\u661f\u9645\u9738\u4e3b\uff01\ud83d\ude80', loading: '\u6821\u51c6\u795e\u7ecf\u94fe\u8def...', cabinInterface: '\u6821\u51c6\u5ea7\u8231\u754c\u9762...', bootEngine: '\u542f\u52a8\u4e09\u7ef4\u5f15\u64ce...', genPlanets: '\u751f\u6210\u7a0b\u5e8f\u5316\u884c\u661f...', monoliths: '\u7ad6\u7acb\u5916\u661f\u5de8\u77f3...', launchpad: '\u5efa\u9020\u6b96\u6c11\u53d1\u5c04\u53f0...', audioSync: '\u540c\u6b65\u97f3\u9891\u63a5\u53e3...', ready: '\u7cfb\u7edf\u5c31\u7eea\uff01', titanAssembly: '\ud83e\udd16 \u6cf0\u5766\u7ec4\u88c5', titanDesc: '\u7ec4\u88c5\u5de8\u578b\u884c\u661f\u5b88\u536b\uff01', found: '\u5df2\u627e\u5230', missing: '\u7f3a\u5931', partsProgress: '\u8fdb\u5ea6', treasury: '\u5b9d\u85cf\u4e0e\u6587\u7269', editMode: '\u7f16\u8f91\u6a21\u5f0f', editDesc: '\u4f7f\u7528\u6e38\u620f\u53c2\u6570\u9762\u677f\u8c03\u6574\u8bbe\u7f6e\u3002', editSave: '\u66f4\u6539\u81ea\u52a8\u4fdd\u5b58\u3002', guideTitle: '\u4efb\u52a1\u6307\u5357', objective: '\u76ee\u6807\uff1a', actionSteps: '\u64cd\u4f5c\u6b65\u9aa4\uff1a', tipSuccess: '\u6210\u529f\u63d0\u793a\uff1a', gotIt: '\u660e\u767d\u4e86\uff01', handbookTitle: '\ud83d\udcd6 \u9a7e\u9a76\u8231\u64cd\u4f5c\u624b\u518c', close: '\u5173\u95ed [X]', tabIntro: '\u4efb\u52a1\u7b80\u62a5', tabControls: '\u7b80\u6613\u64cd\u63a7', tabRadar: '\u6cf0\u5766\u8003\u53e4', tabThreats: '\u5730\u4e0b\u5a01\u80c1', systemFault: '\u26a0\ufe0f \u7cfb\u7edf\u4e25\u91cd\u6545\u969c \u26a0\ufe0f', rebootIn: '\u7cfb\u7edf\u91cd\u542f\u4e2d\uff1a', launched: '\ud83d\ude80 \u88ab\u70b8\u98de\u4e86\uff01\ud83d\ude80', warning: '\u26a0\ufe0f \u8b66\u544a\uff01\u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u6c99\u866b\u5df2\u51fb\u6740\uff01\ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u70b8\u5f39\u89e6\u53d1\uff01\ud83d\udca3', bombDisarmed: '\ud83c\udfaf \u70b8\u5f39\u5df2\u62c6\u9664 \ud83c\udfaf', blastWave: '\ud83d\udca5 \u68c0\u6d4b\u5230\u51b2\u51fb\u6ce2 \ud83d\udca5', assembling: '\u6b63\u5728\u7ec4\u88c5', shipReady: '\ud83c\udf89 \u98de\u8239\u7ec4\u88c5\u5b8c\u6bd5\uff01\u51c6\u5907\u53d1\u5c04\uff01', skip: '\u8df3\u8fc7 [X]', next: '\u4e0b\u4e00\u6b65', startExploring: '\u5f00\u59cb\u63a2\u7d22', cineWelcomeTitle: '\ud83d\ude80 \u5916\u661f\u6539\u9020\u8ba1\u5212\u542f\u52a8', cineWelcomeDesc: '\u6b22\u8fce\u6765\u5230\u5f00\u62d3\u8005\u57fa\u5730\uff01\u4f60\u5df2\u88ab\u90e8\u7f72\u5230\u8fd9\u9897\u8352\u51c9\u7684\u5916\u661f\u8352\u6f20\u4e2d\u3002\u4f60\u7684\u4efb\u52a1\u662f\u91cd\u5851\u5730\u5f62\uff0c\u641c\u96c6\u5173\u952e\u8d44\u6e90\uff0c\u5e76\u5efa\u9020\u5b8f\u4f1f\u7684\u6b96\u6c11\u661f\u9645\u98de\u8239\u53d1\u5c04\u573a\u3002', cineExcavatorTitle: '\ud83d\ude9c \u91cd\u578b\u91cd\u529b\u6316\u6398\u673a', cineExcavatorDesc: '\u4f7f\u7528\u5de6\u4fa7\u6447\u6746\u9a7e\u9a76\u548c\u8f6c\u5411\uff0c\u4f7f\u7528\u952e\u76d8 Q/E \u952e\uff08\u6216\u5c4f\u5e55\u4e0a\u7684\u65cb\u8f6c\u6309\u94ae\uff09\u65cb\u8f6c\u4e0a\u90e8\u8231\u4f53\u3002\u70b9\u51fb\u6a59\u8272\u201c\u81ea\u52a8\u6316\u6398\u201d\u4e0e\u84dd\u8272\u201c\u81ea\u52a8\u503e\u5012\u201d\u5373\u53ef\u8f7b\u677e\u6539\u53d8\u6c99\u4e18\u5730\u5f62\uff01', cineLanderTitle: '\ud83d\ude80 \u6b96\u6c11\u661f\u9645\u98de\u8239\u53d1\u5c04\u53f0', cineLanderDesc: '\u901a\u8fc7\u6539\u9020\u5730\u5f62\u548c\u53d1\u6398\u53d1\u5149\u7684\u77ff\u77f3\u8d44\u6e90\u6765\u83b7\u53d6\u5efa\u8bbe\u8d44\u91d1\u3002\u5f53\u4f60\u7d2f\u79ef\u7684\u8d44\u91d1\u9010\u6b65\u5347\u9ad8\u65f6\uff0c\u661f\u9645\u98de\u8239\u5c06\u5b8c\u6574\u7ec4\u88c5\u5e76\u51c6\u5907\u817e\u7a7a\u53d1\u5c04\uff01', cineTitanTitle: '\ud83e\udd16 \u8fdc\u53e4\u6cf0\u5766\u673a\u7532\u7ec4\u88c5\u70b9', cineTitanDesc: '\u516d\u4e2a\u8fdc\u53e4\u4f20\u5947\u673a\u7532\u90e8\u4ef6\u57cb\u85cf\u4e8e\u6c99\u4e18\u6df1\u5904\u3002\u4f7f\u7528\u81ea\u52a8\u6316\u6398\u5c06\u5176\u6398\u51fa\uff0c\u7275\u5f15\u5149\u675f\u4f1a\u81ea\u52a8\u5c06\u5176\u8fd0\u9001\u81f3\u6b64\u3002\u627e\u9f50\u6240\u6709\u90e8\u4ef6\u5373\u53ef\u6fc0\u6d3b\u4e00\u5c0a\u9ad8\u8038\u5165\u4e91\u7684\u91cd\u88c5\u5b88\u62a4\u795e\uff01', cineHiveTitle: '\ud83d\udc7e \u5916\u661f\u5f02\u5f62\u6bcd\u5de2', cineHiveDesc: '\u5730\u56fe\u8fb9\u7f18\u5b58\u5728\u7740\u4e0d\u65ad\u640f\u52a8\u7684\u5f02\u5f62\u6bcd\u5de2\uff0c\u4f1a\u6e90\u6e90\u4e0d\u65ad\u5730\u4ea7\u51fa\u5543\u98df\u5c65\u5e26\u7684\u7eff\u8272\u50f5\u5c38\u3002\u9a7e\u8f66\u9a76\u8fd1\u5e76\u7528\u6316\u6398\u94f2\u72e0\u72e0\u7838\u788e\u5b83\u4eec\uff0c\u53ef\u6536\u83b7\u5927\u91cf\u8d44\u91d1\u5e76\u505c\u6ede\u602a\u7269\u4ea7\u5375\uff01', cineHazardTitle: '\u26a0\ufe0f \u5730\u4e0b\u6f5c\u85cf\u7684\u751f\u5b58\u5371\u673a', cineHazardDesc: '\u5c0f\u5fc3\uff01\u6cdb\u7740\u7d2b\u8272\u8367\u5149\u7684\u6c99\u5730\u4e4b\u4e0b\u6c89\u7761\u7740\u81f4\u547d\u7684\u5de8\u578b\u6c99\u866b\u3002\u800c\u95ea\u70c1\u7740\u8b66\u793a\u706f\u7684\u9ad8\u79d1\u6280\u5730\u96f7\u4e00\u65e6\u88ab\u5c65\u5e26\u78be\u538b\u6216\u88ab\u6316\u6398\u94f2\u89e6\u53d1\uff0c\u5c06\u4f1a\u5f15\u53d1\u60ca\u5929\u5927\u7206\u70b8\uff01', cineOverview: '\u7cfb\u7edf\u534f\u8bae\u6982\u89c8', warnSandworm: '\u5de8\u578b\u7d2b\u8272\u6c99\u866b\uff01', bucketImpact: '\ud83d\udca5 \u6316\u6597\u91cd\u51fb\uff01(+100) \ud83d\udca5', trackCollision: '\ud83d\ude9c \u5c65\u5e26\u78be\u538b\uff01(+100) \ud83d\ude9c', sandwormHp: '\u6c99\u866b\u751f\u547d\u503c\uff1a{hp} / 10', warnLandmine: '\u9ad8\u7206\u5730\u96f7\uff012\u79d2\uff01', titanAssembled: '\ud83e\udd16 \u6cf0\u5766\u673a\u7532\u7ec4\u88c5\u5b8c\u6bd5\uff01\ud83e\udd16', titanActivated: '\u8fdc\u53e4\u884c\u661f\u5b88\u536b\u5df2\u6fc0\u6d3b\uff01', titanBonus: '\ud83c\udf81 \u5956\u52b1\uff1a+5,000 \u8d44\u91d1\uff01', partRetrieved: '\ud83e\udd16 \u90e8\u4ef6\u5df2\u56de\u6536\uff01\ud83e\udd16', partDelivered: '\u5df2\u5c06 {name} \u9001\u8fbe\u7ec4\u88c5\u533a', titanProgress: '\u8fdb\u5ea6\uff1a{count} / 6 \u4e2a\u90e8\u4ef6' },\n            es: { depth: 'PROFUNDIDAD', graphicsHigh: 'Gr\u00e1ficos: Ultra 3D', graphicsLow: 'Gr\u00e1ficos: 60 FPS (R\u00e1pido)', credits: 'CR\u00c9DITOS', buildBudget: 'Presupuesto', baseBuild: '\ud83d\ude80 PROGRESO DE BASE', mission: '\ud83e\ude90 MISI\u00d3N DE TERRAFORMACI\u00d3N \ud83e\ude90', vault: 'B\u00f3veda', expand: 'Expandir', collapse: 'Colapsar', handbook: 'Manual', modeSimple: 'Modo: Simple (A)', modeClassic: 'Modo: Cl\u00e1sico', autoDig: '\ud83e\udd16 Auto Excavar', autoDump: '\ud83e\udd16 Auto Volcar', leftJoy: 'Conducir', cabinRot: 'Rotaci\u00f3n Cabina', left: '\u25c0 Izq', right: 'Der \u25b6', guide: '\ud83d\udca1 Toca Aqu\u00ed Para Gu\u00eda \ud83d\udca1', missionComplete: '\u00a1Misi\u00f3n Completa!', awarded: 'Cr\u00e9ditos Otorgados', progress: 'Progreso', reward: 'Recompensa', allComplete: '\ud83c\udf89 \u00a1Las 30 misiones completadas! \u00a1Eres el Se\u00f1or del Sector! \ud83d\ude80', loading: 'CALIBRANDO ENLACE NEURAL...', cabinInterface: 'Calibrando interfaz...', bootEngine: 'Iniciando motor 3D...', genPlanets: 'Generando planetas...', monoliths: 'Erigiendo monolitos...', launchpad: 'Construyendo plataforma...', audioSync: 'Sincronizando audio...', ready: '\u00a1Sistema listo!', titanAssembly: '\ud83e\udd16 ENSAMBLAJE TIT\u00c1N', titanDesc: '\u00a1Ensambla al guardi\u00e1n planetario!', found: 'ENCONTRADO', missing: 'FALTA', partsProgress: 'Progreso', treasury: 'Tesoro y Artefactos', editMode: 'MODO EDICI\u00d3N', editDesc: 'Usa el panel de par\u00e1metros.', editSave: 'Cambios guardados autom\u00e1ticamente.', guideTitle: 'GU\u00cdA DE MISI\u00d3N', objective: 'Tu Objetivo:', actionSteps: 'Pasos:', tipSuccess: 'Consejo:', gotIt: '\u00a1Entendido!', handbookTitle: '\ud83d\udcd6 MANUAL DE OPERACIONES', close: 'CERRAR [X]', tabIntro: 'Resumen', tabControls: 'Controles', tabRadar: 'Arqueolog\u00eda Tit\u00e1n', tabThreats: 'Amenazas', systemFault: '\u26a0\ufe0f FALLO CR\u00cdTICO \u26a0\ufe0f', rebootIn: 'Reiniciando en:', launched: '\ud83d\ude80 \u00a1LANZADO! \ud83d\ude80', warning: '\u26a0\ufe0f \u00a1ADVERTENCIA! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u00a1GUSANO ELIMINADO! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u00a1BOMBA ACTIVADA! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOMBA DESARMADA \ud83c\udfaf', blastWave: '\ud83d\udca5 ONDA EXPANSIVA \ud83d\udca5', assembling: 'Ensamblando', shipReady: '\ud83c\udf89 \u00a1Nave lista para lanzar!' },\n            fr: { depth: 'PROFONDEUR', graphicsHigh: 'Graphismes: Ultra 3D', graphicsLow: 'Graphismes: 60 FPS (Rapide)', credits: 'CR\u00c9DITS', buildBudget: 'Budget', baseBuild: '\ud83d\ude80 PROGRESSION BASE', mission: '\ud83e\ude90 MISSION TERRAFORMATION \ud83e\ude90', vault: 'Coffre', expand: 'Ouvrir', collapse: 'Fermer', handbook: 'Manuel', modeSimple: 'Mode: Simple (A)', modeClassic: 'Mode: Classique', autoDig: '\ud83e\udd16 Creuser Auto', autoDump: '\ud83e\udd16 Vider Auto', leftJoy: 'Conduire', cabinRot: 'Rotation Cabine', left: '\u25c0 Gauche', right: 'Droite \u25b6', guide: '\ud83d\udca1 Appuyez Pour le Guide \ud83d\udca1', missionComplete: 'Mission Accomplie!', awarded: 'Cr\u00e9dits Accord\u00e9s', progress: 'Progression', reward: 'R\u00e9compense', allComplete: '\ud83c\udf89 30 missions termin\u00e9es! Seigneur du Secteur! \ud83d\ude80', loading: 'CALIBRAGE LIEN NEURAL...', cabinInterface: 'Calibrage interface...', bootEngine: 'D\u00e9marrage moteur 3D...', genPlanets: 'G\u00e9n\u00e9ration plan\u00e8tes...', monoliths: '\u00c9rection monolithes...', launchpad: 'Construction rampe...', audioSync: 'Sync audio...', ready: 'Syst\u00e8me pr\u00eat!', titanAssembly: '\ud83e\udd16 ASSEMBLAGE TITAN', titanDesc: 'Assemblez le gardien!', found: 'TROUV\u00c9', missing: 'MANQUANT', partsProgress: 'Progression', treasury: 'Tr\u00e9sor & Art\u00e9facts', editMode: 'MODE \u00c9DITION', editDesc: 'Utilisez le panneau param\u00e8tres.', editSave: 'Sauvegarde automatique.', guideTitle: 'GUIDE MISSION', objective: 'Objectif:', actionSteps: '\u00c9tapes:', tipSuccess: 'Conseil:', gotIt: 'Compris!', handbookTitle: '\ud83d\udcd6 MANUEL OP\u00c9RATIONS', close: 'FERMER [X]', tabIntro: 'Briefing', tabControls: 'Commandes', tabRadar: 'Arch\u00e9ologie Titan', tabThreats: 'Menaces', systemFault: '\u26a0\ufe0f PANNE CRITIQUE \u26a0\ufe0f', rebootIn: 'Red\u00e9marrage:', launched: '\ud83d\ude80 \u00c9JECT\u00c9! \ud83d\ude80', warning: '\u26a0\ufe0f ATTENTION! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 VER \u00c9LIMIN\u00c9! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOMBE D\u00c9CLENCH\u00c9E! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOMBE D\u00c9SAMORC\u00c9E \ud83c\udfaf', blastWave: '\ud83d\udca5 ONDE DE CHOC \ud83d\udca5', assembling: 'Assemblage', shipReady: '\ud83c\udf89 Vaisseau pr\u00eat au d\u00e9collage!' },\n            de: { depth: 'TIEFE', graphicsHigh: 'Grafik: Ultra 3D', graphicsLow: 'Grafik: 60 FPS (Schnell)', credits: 'CREDITS', buildBudget: 'Budget', baseBuild: '\ud83d\ude80 BASIS-FORTSCHRITT', mission: '\ud83e\ude90 TERRAFORMING-MISSION \ud83e\ude90', vault: 'Tresor', expand: '\u00d6ffnen', collapse: 'Schlie\u00dfen', handbook: 'Handbuch', modeSimple: 'Modus: Einfach (A)', modeClassic: 'Modus: Klassisch', autoDig: '\ud83e\udd16 Auto Graben', autoDump: '\ud83e\udd16 Auto Kippen', leftJoy: 'Fahren', cabinRot: 'Kabine drehen', left: '\u25c0 Links', right: 'Rechts \u25b6', guide: '\ud83d\udca1 Tippen f\u00fcr Anleitung \ud83d\udca1', missionComplete: 'Mission Abgeschlossen!', awarded: 'Credits Erhalten', progress: 'Fortschritt', reward: 'Belohnung', allComplete: '\ud83c\udf89 Alle 30 Missionen abgeschlossen! \ud83d\ude80', loading: 'KALIBRIERUNG...', cabinInterface: 'Kabine kalibrieren...', bootEngine: '3D-Engine starten...', genPlanets: 'Planeten generieren...', monoliths: 'Monolithen errichten...', launchpad: 'Startrampe bauen...', audioSync: 'Audio synchronisieren...', ready: 'System bereit!', titanAssembly: '\ud83e\udd16 TITAN-MONTAGE', titanDesc: 'Baue den W\u00e4chter!', found: 'GEFUNDEN', missing: 'FEHLT', partsProgress: 'Fortschritt', treasury: 'Schatz & Artefakte', editMode: 'BEARBEITUNGSMODUS', editDesc: 'Parameter-Panel verwenden.', editSave: 'Automatisch gespeichert.', guideTitle: 'MISSIONSANLEITUNG', objective: 'Ziel:', actionSteps: 'Schritte:', tipSuccess: 'Tipp:', gotIt: 'Verstanden!', handbookTitle: '\ud83d\udcd6 BETRIEBSHANDBUCH', close: 'SCHLIE\u00dfEN [X]', tabIntro: 'Briefing', tabControls: 'Steuerung', tabRadar: 'Titan-Arch\u00e4ologie', tabThreats: 'Bedrohungen', systemFault: '\u26a0\ufe0f SYSTEMFEHLER \u26a0\ufe0f', rebootIn: 'Neustart in:', launched: '\ud83d\ude80 GESCHLEUDERT! \ud83d\ude80', warning: '\u26a0\ufe0f WARNUNG! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 SANDWURM BESIEGT! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOMBE AUSGEL\u00d6ST! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOMBE ENTSCH\u00c4RFT \ud83c\udfaf', blastWave: '\ud83d\udca5 DRUCKWELLE \ud83d\udca5', assembling: 'Montage', shipReady: '\ud83c\udf89 Raumschiff startklar!' },\n            ja: { depth: '\u6df1\u5ea6', graphicsHigh: '\u753b\u8cea: \u30a6\u30eb\u30c8\u30e93D', graphicsLow: '\u753b\u8cea: 60 FPS (\u9ad8\u901f)', credits: '\u30af\u30ec\u30b8\u30c3\u30c8', buildBudget: '\u5efa\u8a2d\u4e88\u7b97', baseBuild: '\ud83d\ude80 \u57fa\u5730\u5efa\u8a2d\u9032\u6357', mission: '\ud83e\ude90 \u30c6\u30e9\u30d5\u30a9\u30fc\u30df\u30f3\u30b0\u30df\u30c3\u30b7\u30e7\u30f3 \ud83e\ude90', vault: '\u91d1\u5eab', expand: '\u5c55\u958b', collapse: '\u9589\u3058\u308b', handbook: '\u30cf\u30f3\u30c9\u30d6\u30c3\u30af', modeSimple: '\u30e2\u30fc\u30c9: \u30b7\u30f3\u30d7\u30eb (A)', modeClassic: '\u30e2\u30fc\u30c9: \u30af\u30e9\u30b7\u30c3\u30af', autoDig: '\ud83e\udd16 \u81ea\u52d5\u6398\u524a', autoDump: '\ud83e\udd16 \u81ea\u52d5\u6295\u68c4', leftJoy: '\u64cd\u7e26', cabinRot: '\u30ad\u30e3\u30d3\u30f3\u56de\u8ee2', left: '\u25c0 \u5de6', right: '\u53f3 \u25b6', guide: '\ud83d\udca1 \u30ac\u30a4\u30c9\u306f\u3053\u3053\u3092\u30bf\u30c3\u30d7 \ud83d\udca1', missionComplete: '\u30df\u30c3\u30b7\u30e7\u30f3\u5b8c\u4e86\uff01', awarded: '\u30af\u30ec\u30b8\u30c3\u30c8\u7372\u5f97', progress: '\u9032\u6357', reward: '\u5831\u916c', allComplete: '\ud83c\udf89 \u516830\u30df\u30c3\u30b7\u30e7\u30f3\u9054\u6210\uff01\u30bb\u30af\u30bf\u30fc\u8987\u738b\uff01\ud83d\ude80', loading: '\u30cb\u30e5\u30fc\u30e9\u30eb\u30ea\u30f3\u30af\u8abf\u6574\u4e2d...', cabinInterface: '\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u8abf\u6574...', bootEngine: '3D\u30a8\u30f3\u30b8\u30f3\u8d77\u52d5...', genPlanets: '\u60d1\u661f\u751f\u6210\u4e2d...', monoliths: '\u30e2\u30ce\u30ea\u30b9\u5efa\u8a2d\u4e2d...', launchpad: '\u767a\u5c04\u53f0\u5efa\u8a2d\u4e2d...', audioSync: '\u30aa\u30fc\u30c7\u30a3\u30aa\u540c\u671f...', ready: '\u30b7\u30b9\u30c6\u30e0\u6e96\u5099\u5b8c\u4e86\uff01', titanAssembly: '\ud83e\udd16 \u30bf\u30a4\u30bf\u30f3\u7d44\u7acb', titanDesc: '\u5de8\u5927\u5b88\u8b77\u8005\u3092\u7d44\u307f\u7acb\u3066\u3088\u3046\uff01', found: '\u767a\u898b\u6e08', missing: '\u672a\u767a\u898b', partsProgress: '\u9032\u6357', treasury: '\u8ca1\u5b9d\uff06\u907a\u7269', editMode: '\u7de8\u96c6\u30e2\u30fc\u30c9', editDesc: '\u30d1\u30e9\u30e1\u30fc\u30bf\u30d1\u30cd\u30eb\u3067\u8abf\u6574\u3002', editSave: '\u81ea\u52d5\u4fdd\u5b58\u3055\u308c\u307e\u3059\u3002', guideTitle: '\u30df\u30c3\u30b7\u30e7\u30f3\u30ac\u30a4\u30c9', objective: '\u76ee\u6a19:', actionSteps: '\u624b\u9806:', tipSuccess: '\u30d2\u30f3\u30c8:', gotIt: '\u4e86\u89e3\uff01', handbookTitle: '\ud83d\udcd6 \u64cd\u4f5c\u30de\u30cb\u30e5\u30a2\u30eb', close: '\u9589\u3058\u308b [X]', tabIntro: '\u30d6\u30ea\u30fc\u30d5\u30a3\u30f3\u30b0', tabControls: '\u64cd\u4f5c\u65b9\u6cd5', tabRadar: '\u30bf\u30a4\u30bf\u30f3\u8003\u53e4\u5b66', tabThreats: '\u8105\u5a01', systemFault: '\u26a0\ufe0f \u30b7\u30b9\u30c6\u30e0\u969c\u5bb3 \u26a0\ufe0f', rebootIn: '\u518d\u8d77\u52d5\u4e2d:', launched: '\ud83d\ude80 \u5439\u304d\u98db\u3070\u3055\u308c\u305f\uff01\ud83d\ude80', warning: '\u26a0\ufe0f \u8b66\u544a\uff01\u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u30b5\u30f3\u30c9\u30ef\u30fc\u30e0\u6483\u7834\uff01\ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u7206\u5f3e\u8d77\u52d5\uff01\ud83d\udca3', bombDisarmed: '\ud83c\udfaf \u7206\u5f3e\u89e3\u9664 \ud83c\udfaf', blastWave: '\ud83d\udca5 \u885d\u6483\u6ce2\u691c\u51fa \ud83d\udca5', assembling: '\u7d44\u7acb\u4e2d', shipReady: '\ud83c\udf89 \u5b87\u5b99\u8239\u5b8c\u6210\uff01\u767a\u5c04\u6e96\u5099\u5b8c\u4e86\uff01' },\n            ko: { depth: '\uae4a\uc774', graphicsHigh: '\uadf8\ub798\ud53d: \uc6b8\ud2b8\ub77c 3D', graphicsLow: '\uadf8\ub798\ud53d: 60 FPS (\ube60\ub984)', credits: '\ud06c\ub808\ub527', buildBudget: '\uac74\uc124 \uc608\uc0b0', baseBuild: '\ud83d\ude80 \uae30\uc9c0 \uac74\uc124 \uc9c4\ud589', mission: '\ud83e\ude90 \ud14c\ub77c\ud3ec\ubc0d \ubbf8\uc158 \ud83e\ude90', vault: '\uae08\uace0', expand: '\uc5f4\uae30', collapse: '\ub2eb\uae30', handbook: '\ud578\ub4dc\ubd81', modeSimple: '\ubaa8\ub4dc: \uc2ec\ud50c (A)', modeClassic: '\ubaa8\ub4dc: \ud074\ub798\uc2dd', autoDig: '\ud83e\udd16 \uc790\ub3d9 \uad74\ucc29', autoDump: '\ud83e\udd16 \uc790\ub3d9 \ud22c\ud558', leftJoy: '\uc870\uc885', cabinRot: '\uce90\ube48 \ud68c\uc804', left: '\u25c0 \uc88c', right: '\uc6b0 \u25b6', guide: '\ud83d\udca1 \uac00\uc774\ub4dc\ub97c \ubcf4\ub824\uba74 \ud0ed \ud83d\udca1', missionComplete: '\ubbf8\uc158 \uc644\ub8cc!', awarded: '\ud06c\ub808\ub527 \ud68d\ub4dd', progress: '\uc9c4\ud589', reward: '\ubcf4\uc0c1', allComplete: '\ud83c\udf89 30\uac1c \ubbf8\uc158 \ubaa8\ub450 \uc644\ub8cc! \uc139\ud130 \uad70\uc8fc! \ud83d\ude80', loading: '\ub274\ub7f4 \ub9c1\ud06c \ubcf4\uc815 \uc911...', cabinInterface: '\uc778\ud130\ud398\uc774\uc2a4 \ubcf4\uc815...', bootEngine: '3D \uc5d4\uc9c4 \uc2dc\uc791...', genPlanets: '\ud589\uc131 \uc0dd\uc131 \uc911...', monoliths: '\ubaa8\ub178\ub9ac\uc2a4 \uac74\uc124...', launchpad: '\ubc1c\uc0ac\ub300 \uac74\uc124...', audioSync: '\uc624\ub514\uc624 \ub3d9\uae30\ud654...', ready: '\uc2dc\uc2a4\ud15c \uc900\ube44 \uc644\ub8cc!', titanAssembly: '\ud83e\udd16 \ud0c0\uc774\ud0c4 \uc870\ub9bd', titanDesc: '\uac70\ub300 \uc218\ud638\uc790\ub97c \uc870\ub9bd\ud558\uc138\uc694!', found: '\ubc1c\uacac', missing: '\ubbf8\ubc1c\uacac', partsProgress: '\uc9c4\ud589', treasury: '\ubcf4\ubb3c & \uc720\ubb3c', editMode: '\ud3b8\uc9d1 \ubaa8\ub4dc', editDesc: '\ub9e4\uac1c\ubcc0\uc218 \ud328\ub110\uc744 \uc0ac\uc6a9\ud558\uc138\uc694.', editSave: '\uc790\ub3d9 \uc800\uc7a5\ub429\ub2c8\ub2e4.', guideTitle: '\ubbf8\uc158 \uac00\uc774\ub4dc', objective: '\ubaa9\ud45c:', actionSteps: '\ub2e8\uacc4:', tipSuccess: '\ud301:', gotIt: '\ud655\uc778!', handbookTitle: '\ud83d\udcd6 \uc870\uc791 \ub9e4\ub274\uc5bc', close: '\ub2eb\uae30 [X]', tabIntro: '\ube0c\ub9ac\ud551', tabControls: '\uc870\uc791\ubc95', tabRadar: '\ud0c0\uc774\ud0c4 \uace0\uace0\ud559', tabThreats: '\uc704\ud611', systemFault: '\u26a0\ufe0f \uc2dc\uc2a4\ud15c \uc7a5\uc560 \u26a0\ufe0f', rebootIn: '\uc7ac\ubd80\ud305:', launched: '\ud83d\ude80 \ub0a0\uc544\uac14\ub2e4! \ud83d\ude80', warning: '\u26a0\ufe0f \uacbd\uace0! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \uc0cc\ub4dc\uc6dc \ucc98\uce58! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 \ud3ed\ud0c4 \uc791\ub3d9! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf \ud3ed\ud0c4 \ud574\uc81c \ud83c\udfaf', blastWave: '\ud83d\udca5 \ucda9\uaca9\ud30c \uac10\uc9c0 \ud83d\udca5', assembling: '\uc870\ub9bd \uc911', shipReady: '\ud83c\udf89 \uc6b0\uc8fc\uc120 \uc870\ub9bd \uc644\ub8cc! \ubc1c\uc0ac \uc900\ube44!' },\n            ru: { depth: '\u0413\u041b\u0423\u0411\u0418\u041d\u0410', graphicsHigh: '\u0413\u0440\u0430\u0444\u0438\u043a\u0430: \u0423\u043b\u044c\u0442\u0440\u0430 3D', graphicsLow: '\u0413\u0440\u0430\u0444\u0438\u043a\u0430: 60 FPS (\u0411\u044b\u0441\u0442\u0440\u043e)', credits: '\u041a\u0420\u0415\u0414\u0418\u0422\u042b', buildBudget: '\u0411\u044e\u0434\u0436\u0435\u0442', baseBuild: '\ud83d\ude80 \u041f\u0420\u041e\u0413\u0420\u0415\u0421\u0421 \u0411\u0410\u0417\u042b', mission: '\ud83e\ude90 \u041c\u0418\u0421\u0421\u0418\u042f \u0422\u0415\u0420\u0420\u0410\u0424\u041e\u0420\u041c\u0418\u0420\u041e\u0412\u0410\u041d\u0418\u042f \ud83e\ude90', vault: '\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435', expand: '\u041e\u0442\u043a\u0440\u044b\u0442\u044c', collapse: '\u0417\u0430\u043a\u0440\u044b\u0442\u044c', handbook: '\u0421\u043f\u0440\u0430\u0432\u043a\u0430', modeSimple: '\u0420\u0435\u0436\u0438\u043c: \u041f\u0440\u043e\u0441\u0442\u043e\u0439 (A)', modeClassic: '\u0420\u0435\u0436\u0438\u043c: \u041a\u043b\u0430\u0441\u0441\u0438\u043a\u0430', autoDig: '\ud83e\udd16 \u0410\u0432\u0442\u043e \u041a\u043e\u043f\u0430\u0442\u044c', autoDump: '\ud83e\udd16 \u0410\u0432\u0442\u043e \u0421\u0431\u0440\u043e\u0441', leftJoy: '\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435', cabinRot: '\u041f\u043e\u0432\u043e\u0440\u043e\u0442 \u043a\u0430\u0431\u0438\u043d\u044b', left: '\u25c0 \u041b\u0435\u0432\u043e', right: '\u041f\u0440\u0430\u0432\u043e \u25b6', guide: '\ud83d\udca1 \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \ud83d\udca1', missionComplete: '\u041c\u0438\u0441\u0441\u0438\u044f \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430!', awarded: '\u041a\u0440\u0435\u0434\u0438\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b', progress: '\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441', reward: '\u041d\u0430\u0433\u0440\u0430\u0434\u0430', allComplete: '\ud83c\udf89 \u0412\u0441\u0435 30 \u043c\u0438\u0441\u0441\u0438\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b! \ud83d\ude80', loading: '\u041a\u0410\u041b\u0418\u0411\u0420\u041e\u0412\u041a\u0410...', cabinInterface: '\u041a\u0430\u043b\u0438\u0431\u0440\u043e\u0432\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430...', bootEngine: '\u0417\u0430\u043f\u0443\u0441\u043a 3D \u0434\u0432\u0438\u0436\u043a\u0430...', genPlanets: '\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043b\u0430\u043d\u0435\u0442...', monoliths: '\u0412\u043e\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u043e\u0432...', launchpad: '\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0438...', audioSync: '\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0443\u0434\u0438\u043e...', ready: '\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0433\u043e\u0442\u043e\u0432\u0430!', titanAssembly: '\ud83e\udd16 \u0421\u0411\u041e\u0420\u041a\u0410 \u0422\u0418\u0422\u0410\u041d\u0410', titanDesc: '\u0421\u043e\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0442\u0440\u0430\u0436\u0430!', found: '\u041d\u0410\u0419\u0414\u0415\u041d', missing: '\u041d\u0415\u0422', partsProgress: '\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441', treasury: '\u0421\u043e\u043a\u0440\u043e\u0432\u0438\u0449\u0430', editMode: '\u0420\u0415\u0416\u0418\u041c \u0420\u0415\u0414\u0410\u041a\u0422\u0418\u0420\u041e\u0412\u0410\u041d\u0418\u042f', editDesc: '\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u0430\u043d\u0435\u043b\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.', editSave: '\u0410\u0432\u0442\u043e\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435.', guideTitle: '\u0420\u0423\u041a\u041e\u0412\u041e\u0414\u0421\u0422\u0412\u041e', objective: '\u0426\u0435\u043b\u044c:', actionSteps: '\u0428\u0430\u0433\u0438:', tipSuccess: '\u0421\u043e\u0432\u0435\u0442:', gotIt: '\u041f\u043e\u043d\u044f\u043b!', handbookTitle: '\ud83d\udcd6 \u0420\u0423\u041a\u041e\u0412\u041e\u0414\u0421\u0422\u0412\u041e', close: '\u0417\u0410\u041a\u0420\u042b\u0422\u042c [X]', tabIntro: '\u0411\u0440\u0438\u0444\u0438\u043d\u0433', tabControls: '\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435', tabRadar: '\u0410\u0440\u0445\u0435\u043e\u043b\u043e\u0433\u0438\u044f \u0422\u0438\u0442\u0430\u043d\u0430', tabThreats: '\u0423\u0433\u0440\u043e\u0437\u044b', systemFault: '\u26a0\ufe0f \u0421\u0418\u0421\u0422\u0415\u041c\u041d\u042b\u0419 \u0421\u0411\u041e\u0419 \u26a0\ufe0f', rebootIn: '\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430:', launched: '\ud83d\ude80 \u0417\u0410\u041f\u0423\u0429\u0415\u041d! \ud83d\ude80', warning: '\u26a0\ufe0f \u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u0427\u0415\u0420\u0412\u042c \u0423\u0411\u0418\u0422! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u0411\u041e\u041c\u0411\u0410! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf \u041e\u0411\u0415\u0417\u0412\u0420\u0415\u0416\u0415\u041d\u041e \ud83c\udfaf', blastWave: '\ud83d\udca5 \u0423\u0414\u0410\u0420\u041d\u0410\u042f \u0412\u041e\u041b\u041d\u0410 \ud83d\udca5', assembling: '\u0421\u0431\u043e\u0440\u043a\u0430', shipReady: '\ud83c\udf89 \u041a\u043e\u0440\u0430\u0431\u043b\u044c \u0433\u043e\u0442\u043e\u0432 \u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443!' },\n            pt: { depth: 'PROFUNDIDADE', graphicsHigh: 'Gr\u00e1ficos: Ultra 3D', graphicsLow: 'Gr\u00e1ficos: 60 FPS (R\u00e1pido)', credits: 'CR\u00c9DITOS', buildBudget: 'Or\u00e7amento', baseBuild: '\ud83d\ude80 PROGRESSO DA BASE', mission: '\ud83e\ude90 MISS\u00c3O DE TERRAFORMA\u00c7\u00c3O \ud83e\ude90', vault: 'Cofre', expand: 'Expandir', collapse: 'Fechar', handbook: 'Manual', modeSimple: 'Modo: Simples (A)', modeClassic: 'Modo: Cl\u00e1ssico', autoDig: '\ud83e\udd16 Escavar Auto', autoDump: '\ud83e\udd16 Despejar Auto', leftJoy: 'Dirigir', cabinRot: 'Rota\u00e7\u00e3o Cabine', left: '\u25c0 Esq', right: 'Dir \u25b6', guide: '\ud83d\udca1 Toque Para Guia \ud83d\udca1', missionComplete: 'Miss\u00e3o Completa!', awarded: 'Cr\u00e9ditos Recebidos', progress: 'Progresso', reward: 'Recompensa', allComplete: '\ud83c\udf89 Todas as 30 miss\u00f5es conclu\u00eddas! \ud83d\ude80', loading: 'CALIBRANDO...', cabinInterface: 'Calibrando interface...', bootEngine: 'Iniciando motor 3D...', genPlanets: 'Gerando planetas...', monoliths: 'Erguendo mon\u00f3litos...', launchpad: 'Construindo plataforma...', audioSync: 'Sincronizando \u00e1udio...', ready: 'Sistema pronto!', titanAssembly: '\ud83e\udd16 MONTAGEM TIT\u00c3', titanDesc: 'Monte o guardi\u00e3o!', found: 'ENCONTRADO', missing: 'FALTA', partsProgress: 'Progresso', treasury: 'Tesouro & Artefatos', editMode: 'MODO EDI\u00c7\u00c3O', editDesc: 'Use o painel de par\u00e2metros.', editSave: 'Salvo automaticamente.', guideTitle: 'GUIA DA MISS\u00c3O', objective: 'Objetivo:', actionSteps: 'Passos:', tipSuccess: 'Dica:', gotIt: 'Entendi!', handbookTitle: '\ud83d\udcd6 MANUAL DE OPERA\u00c7\u00d5ES', close: 'FECHAR [X]', tabIntro: 'Briefing', tabControls: 'Controles', tabRadar: 'Arqueologia Tit\u00e3', tabThreats: 'Amea\u00e7as', systemFault: '\u26a0\ufe0f FALHA CR\u00cdTICA \u26a0\ufe0f', rebootIn: 'Reiniciando:', launched: '\ud83d\ude80 LAN\u00c7ADO! \ud83d\ude80', warning: '\u26a0\ufe0f AVISO! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 VERME ELIMINADO! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOMBA ATIVADA! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOMBA DESARMADA \ud83c\udfaf', blastWave: '\ud83d\udca5 ONDA DE CHOQUE \ud83d\udca5', assembling: 'Montando', shipReady: '\ud83c\udf89 Nave pronta para lan\u00e7amento!' },\n            vi: { depth: '\u0110\u1ed8 S\u00c2U', graphicsHigh: '\u0110\u1ed3 h\u1ecda: Cao 3D', graphicsLow: '\u0110\u1ed3 h\u1ecda: 60 FPS (Nhanh)', credits: 'T\u00cdN D\u1ee4NG', buildBudget: 'Ng\u00e2n s\u00e1ch', baseBuild: '\ud83d\ude80 TI\u1ebeN \u0110\u1ed8 C\u0102N C\u1ee8', mission: '\ud83e\ude90 NHI\u1ec6M V\u1ee4 C\u1ea2I T\u1ea0O \ud83e\ude90', vault: 'Kho b\u00e1u', expand: 'M\u1edf', collapse: '\u0110\u00f3ng', handbook: 'S\u1ed5 tay', modeSimple: 'Ch\u1ebf \u0111\u1ed9: \u0110\u01a1n gi\u1ea3n (A)', modeClassic: 'Ch\u1ebf \u0111\u1ed9: C\u1ed5 \u0111i\u1ec3n', autoDig: '\ud83e\udd16 T\u1ef1 \u0111\u1ed9ng \u0111\u00e0o', autoDump: '\ud83e\udd16 T\u1ef1 \u0111\u1ed9ng \u0111\u1ed5', leftJoy: 'L\u00e1i xe', cabinRot: 'Xoay cabin', left: '\u25c0 Tr\u00e1i', right: 'Ph\u1ea3i \u25b6', guide: '\ud83d\udca1 Nh\u1ea5n \u0111\u1ec3 xem h\u01b0\u1edbng d\u1eabn \ud83d\udca1', missionComplete: 'Ho\u00e0n th\u00e0nh nhi\u1ec7m v\u1ee5!', awarded: 'T\u00edn d\u1ee5ng nh\u1eadn \u0111\u01b0\u1ee3c', progress: 'Ti\u1ebfn \u0111\u1ed9', reward: 'Ph\u1ea7n th\u01b0\u1edfng', allComplete: '\ud83c\udf89 Ho\u00e0n th\u00e0nh 30 nhi\u1ec7m v\u1ee5! B\u00e1 ch\u1ee7! \ud83d\ude80', loading: '\u0110ANG HI\u1ec6U CH\u1ec8NH...', cabinInterface: 'Hi\u1ec7u ch\u1ec9nh giao di\u1ec7n...', bootEngine: 'Kh\u1edfi \u0111\u1ed9ng 3D...', genPlanets: 'T\u1ea1o h\u00e0nh tinh...', monoliths: 'D\u1ef1ng \u0111\u00e1 nguy\u00ean kh\u1ed1i...', launchpad: 'X\u00e2y b\u1ec7 ph\u00f3ng...', audioSync: '\u0110\u1ed3ng b\u1ed9 \u00e2m thanh...', ready: 'H\u1ec7 th\u1ed1ng s\u1eb5n s\u00e0ng!', titanAssembly: '\ud83e\udd16 L\u1eaeP R\u00c1P TITAN', titanDesc: 'L\u1eafp r\u00e1p ng\u01b0\u1eddi b\u1ea3o v\u1ec7!', found: '\u0110\u00c3 T\u00ccM', missing: 'THI\u1ebeU', partsProgress: 'Ti\u1ebfn \u0111\u1ed9', treasury: 'Kho b\u00e1u & Di v\u1eadt', editMode: 'CH\u1ebe \u0110\u1ed8 CH\u1ec8NH S\u1eecA', editDesc: 'D\u00f9ng b\u1ea3ng tham s\u1ed1.', editSave: 'T\u1ef1 \u0111\u1ed9ng l\u01b0u.', guideTitle: 'H\u01af\u1edaNG D\u1eaaN', objective: 'M\u1ee5c ti\u00eau:', actionSteps: 'C\u00e1c b\u01b0\u1edbc:', tipSuccess: 'M\u1eb9o:', gotIt: 'Hi\u1ec3u r\u1ed3i!', handbookTitle: '\ud83d\udcd6 S\u1ed4 TAY V\u1eacN H\u00c0NH', close: '\u0110\u00d3NG [X]', tabIntro: 'T\u00f3m t\u1eaft', tabControls: '\u0110i\u1ec1u khi\u1ec3n', tabRadar: 'Kh\u1ea3o c\u1ed5 Titan', tabThreats: 'M\u1ed1i \u0111e d\u1ecda', systemFault: '\u26a0\ufe0f L\u1ed6I H\u1ec6 TH\u1ed0NG \u26a0\ufe0f', rebootIn: 'Kh\u1edfi \u0111\u1ed9ng l\u1ea1i:', launched: '\ud83d\ude80 B\u1eca B\u1eaeN BAY! \ud83d\ude80', warning: '\u26a0\ufe0f C\u1ea2NH B\u00c1O! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 GIUN C\u00c1T B\u1eca TI\u00caU DI\u1ec6T! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOM K\u00cdCH HO\u1ea0T! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOM \u0110\u00c3 TH\u00c1O \ud83c\udfaf', blastWave: '\ud83d\udca5 S\u00d3NG XUNG K\u00cdCH \ud83d\udca5', assembling: '\u0110ang l\u1eafp r\u00e1p', shipReady: '\ud83c\udf89 T\u00e0u s\u1eb5n s\u00e0ng ph\u00f3ng!' },\n            th: { depth: '\u0e04\u0e27\u0e32\u0e21\u0e25\u0e36\u0e01', graphicsHigh: '\u0e01\u0e23\u0e32\u0e1f\u0e34\u0e01: \u0e2d\u0e31\u0e25\u0e15\u0e23\u0e32 3D', graphicsLow: '\u0e01\u0e23\u0e32\u0e1f\u0e34\u0e01: 60 FPS (\u0e40\u0e23\u0e47\u0e27)', credits: '\u0e40\u0e04\u0e23\u0e14\u0e34\u0e15', buildBudget: '\u0e07\u0e1a\u0e01\u0e48\u0e2d\u0e2a\u0e23\u0e49\u0e32\u0e07', baseBuild: '\ud83d\ude80 \u0e04\u0e27\u0e32\u0e21\u0e04\u0e37\u0e1a\u0e2b\u0e19\u0e49\u0e32\u0e10\u0e32\u0e19', mission: '\ud83e\ude90 \u0e20\u0e32\u0e23\u0e01\u0e34\u0e08\u0e1b\u0e23\u0e31\u0e1a\u0e2a\u0e20\u0e32\u0e1e\u0e14\u0e32\u0e27 \ud83e\ude90', vault: '\u0e04\u0e25\u0e31\u0e07', expand: '\u0e40\u0e1b\u0e34\u0e14', collapse: '\u0e1b\u0e34\u0e14', handbook: '\u0e04\u0e39\u0e48\u0e21\u0e37\u0e2d', modeSimple: '\u0e42\u0e2b\u0e21\u0e14: \u0e07\u0e48\u0e32\u0e22 (A)', modeClassic: '\u0e42\u0e2b\u0e21\u0e14: \u0e04\u0e25\u0e32\u0e2a\u0e2a\u0e34\u0e01', autoDig: '\ud83e\udd16 \u0e02\u0e38\u0e14\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34', autoDump: '\ud83e\udd16 \u0e40\u0e17\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34', leftJoy: '\u0e02\u0e31\u0e1a\u0e40\u0e04\u0e25\u0e37\u0e48\u0e2d\u0e19', cabinRot: '\u0e2b\u0e21\u0e38\u0e19\u0e2b\u0e49\u0e2d\u0e07\u0e42\u0e14\u0e22\u0e2a\u0e32\u0e23', left: '\u25c0 \u0e0b\u0e49\u0e32\u0e22', right: '\u0e02\u0e27\u0e32 \u25b6', guide: '\ud83d\udca1 \u0e41\u0e15\u0e30\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e14\u0e39\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33 \ud83d\udca1', missionComplete: '\u0e20\u0e32\u0e23\u0e01\u0e34\u0e08\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08!', awarded: '\u0e44\u0e14\u0e49\u0e23\u0e31\u0e1a\u0e40\u0e04\u0e23\u0e14\u0e34\u0e15', progress: '\u0e04\u0e27\u0e32\u0e21\u0e04\u0e37\u0e1a\u0e2b\u0e19\u0e49\u0e32', reward: '\u0e23\u0e32\u0e07\u0e27\u0e31\u0e25', allComplete: '\ud83c\udf89 \u0e20\u0e32\u0e23\u0e01\u0e34\u0e08\u0e17\u0e31\u0e49\u0e07 30 \u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08! \ud83d\ude80', loading: '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e1b\u0e23\u0e31\u0e1a\u0e40\u0e17\u0e35\u0e22\u0e1a...', cabinInterface: '\u0e1b\u0e23\u0e31\u0e1a\u0e40\u0e17\u0e35\u0e22\u0e1a\u0e2d\u0e34\u0e19\u0e40\u0e17\u0e2d\u0e23\u0e4c\u0e40\u0e1f\u0e0b...', bootEngine: '\u0e40\u0e23\u0e34\u0e48\u0e21\u0e15\u0e49\u0e19\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e22\u0e19\u0e15\u0e4c 3D...', genPlanets: '\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e14\u0e32\u0e27\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c...', monoliths: '\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e40\u0e2a\u0e32\u0e2b\u0e34\u0e19...', launchpad: '\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e10\u0e32\u0e19\u0e1b\u0e25\u0e48\u0e2d\u0e22...', audioSync: '\u0e0b\u0e34\u0e07\u0e04\u0e4c\u0e40\u0e2a\u0e35\u0e22\u0e07...', ready: '\u0e23\u0e30\u0e1a\u0e1a\u0e1e\u0e23\u0e49\u0e2d\u0e21!', titanAssembly: '\ud83e\udd16 \u0e1b\u0e23\u0e30\u0e01\u0e2d\u0e1a\u0e44\u0e17\u0e17\u0e31\u0e19', titanDesc: '\u0e1b\u0e23\u0e30\u0e01\u0e2d\u0e1a\u0e1c\u0e39\u0e49\u0e1e\u0e34\u0e17\u0e31\u0e01\u0e29\u0e4c!', found: '\u0e1e\u0e1a\u0e41\u0e25\u0e49\u0e27', missing: '\u0e02\u0e32\u0e14', partsProgress: '\u0e04\u0e27\u0e32\u0e21\u0e04\u0e37\u0e1a\u0e2b\u0e19\u0e49\u0e32', treasury: '\u0e2a\u0e21\u0e1a\u0e31\u0e15\u0e34 & \u0e42\u0e1a\u0e23\u0e32\u0e13\u0e27\u0e31\u0e15\u0e16\u0e38', editMode: '\u0e42\u0e2b\u0e21\u0e14\u0e41\u0e01\u0e49\u0e44\u0e02', editDesc: '\u0e43\u0e0a\u0e49\u0e41\u0e1c\u0e07\u0e1e\u0e32\u0e23\u0e32\u0e21\u0e34\u0e40\u0e15\u0e2d\u0e23\u0e4c', editSave: '\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34', guideTitle: '\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e20\u0e32\u0e23\u0e01\u0e34\u0e08', objective: '\u0e40\u0e1b\u0e49\u0e32\u0e2b\u0e21\u0e32\u0e22:', actionSteps: '\u0e02\u0e31\u0e49\u0e19\u0e15\u0e2d\u0e19:', tipSuccess: '\u0e40\u0e04\u0e25\u0e47\u0e14\u0e25\u0e31\u0e1a:', gotIt: '\u0e40\u0e02\u0e49\u0e32\u0e43\u0e08\u0e41\u0e25\u0e49\u0e27!', handbookTitle: '\ud83d\udcd6 \u0e04\u0e39\u0e48\u0e21\u0e37\u0e2d\u0e1b\u0e0f\u0e34\u0e1a\u0e31\u0e15\u0e34\u0e01\u0e32\u0e23', close: '\u0e1b\u0e34\u0e14 [X]', tabIntro: '\u0e2a\u0e23\u0e38\u0e1b\u0e20\u0e32\u0e23\u0e01\u0e34\u0e08', tabControls: '\u0e01\u0e32\u0e23\u0e04\u0e27\u0e1a\u0e04\u0e38\u0e21', tabRadar: '\u0e42\u0e1a\u0e23\u0e32\u0e13\u0e04\u0e14\u0e35\u0e44\u0e17\u0e17\u0e31\u0e19', tabThreats: '\u0e20\u0e31\u0e22\u0e04\u0e38\u0e01\u0e04\u0e32\u0e21', systemFault: '\u26a0\ufe0f \u0e23\u0e30\u0e1a\u0e1a\u0e02\u0e31\u0e14\u0e02\u0e49\u0e2d\u0e07 \u26a0\ufe0f', rebootIn: '\u0e23\u0e35\u0e1a\u0e39\u0e15:', launched: '\ud83d\ude80 \u0e16\u0e39\u0e01\u0e40\u0e2b\u0e27\u0e35\u0e48\u0e22\u0e07! \ud83d\ude80', warning: '\u26a0\ufe0f \u0e04\u0e33\u0e40\u0e15\u0e37\u0e2d\u0e19! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u0e2b\u0e19\u0e2d\u0e19\u0e17\u0e23\u0e32\u0e22\u0e16\u0e39\u0e01\u0e2a\u0e31\u0e07\u0e2b\u0e32\u0e23! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u0e23\u0e30\u0e40\u0e1a\u0e34\u0e14\u0e17\u0e33\u0e07\u0e32\u0e19! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf \u0e1b\u0e25\u0e14\u0e23\u0e30\u0e40\u0e1a\u0e34\u0e14\u0e41\u0e25\u0e49\u0e27 \ud83c\udfaf', blastWave: '\ud83d\udca5 \u0e04\u0e25\u0e37\u0e48\u0e19\u0e01\u0e23\u0e30\u0e41\u0e17\u0e01 \ud83d\udca5', assembling: '\u0e01\u0e33\u0e25\u0e31\u0e07\u0e1b\u0e23\u0e30\u0e01\u0e2d\u0e1a', shipReady: '\ud83c\udf89 \u0e22\u0e32\u0e19\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e1b\u0e25\u0e48\u0e2d\u0e22!' },\n            id: { depth: 'KEDALAMAN', graphicsHigh: 'Grafis: Ultra 3D', graphicsLow: 'Grafis: 60 FPS (Cepat)', credits: 'KREDIT', buildBudget: 'Anggaran', baseBuild: '\ud83d\ude80 PROGRES BASIS', mission: '\ud83e\ude90 MISI TERRAFORMASI \ud83e\ude90', vault: 'Brankas', expand: 'Buka', collapse: 'Tutup', handbook: 'Buku Panduan', modeSimple: 'Mode: Sederhana (A)', modeClassic: 'Mode: Klasik', autoDig: '\ud83e\udd16 Gali Otomatis', autoDump: '\ud83e\udd16 Buang Otomatis', leftJoy: 'Kemudi', cabinRot: 'Rotasi Kabin', left: '\u25c0 Kiri', right: 'Kanan \u25b6', guide: '\ud83d\udca1 Ketuk Untuk Panduan \ud83d\udca1', missionComplete: 'Misi Selesai!', awarded: 'Kredit Diterima', progress: 'Progres', reward: 'Hadiah', allComplete: '\ud83c\udf89 Semua 30 misi selesai! \ud83d\ude80', loading: 'KALIBRASI...', cabinInterface: 'Kalibrasi antarmuka...', bootEngine: 'Memulai mesin 3D...', genPlanets: 'Membuat planet...', monoliths: 'Mendirikan monolit...', launchpad: 'Membangun landasan...', audioSync: 'Sinkronisasi audio...', ready: 'Sistem siap!', titanAssembly: '\ud83e\udd16 PERAKITAN TITAN', titanDesc: 'Rakit penjaga planet!', found: 'DITEMUKAN', missing: 'HILANG', partsProgress: 'Progres', treasury: 'Harta & Artefak', editMode: 'MODE EDIT', editDesc: 'Gunakan panel parameter.', editSave: 'Tersimpan otomatis.', guideTitle: 'PANDUAN MISI', objective: 'Tujuan:', actionSteps: 'Langkah:', tipSuccess: 'Tips:', gotIt: 'Mengerti!', handbookTitle: '\ud83d\udcd6 MANUAL OPERASI', close: 'TUTUP [X]', tabIntro: 'Ringkasan', tabControls: 'Kontrol', tabRadar: 'Arkeologi Titan', tabThreats: 'Ancaman', systemFault: '\u26a0\ufe0f KERUSAKAN SISTEM \u26a0\ufe0f', rebootIn: 'Memulai ulang:', launched: '\ud83d\ude80 TERLONTAR! \ud83d\ude80', warning: '\u26a0\ufe0f PERINGATAN! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 CACING PASIR DIKALAHKAN! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOM AKTIF! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOM DIJINAKKAN \ud83c\udfaf', blastWave: '\ud83d\udca5 GELOMBANG LEDAKAN \ud83d\udca5', assembling: 'Merakit', shipReady: '\ud83c\udf89 Pesawat siap diluncurkan!' },\n            fil: { depth: 'LALIM', graphicsHigh: 'Graphics: Ultra 3D', graphicsLow: 'Graphics: 60 FPS (Mabilis)', credits: 'KREDITO', buildBudget: 'Budget', baseBuild: '\ud83d\ude80 PROGRESO NG BASE', mission: '\ud83e\ude90 MISYON NG TERRAFORMING \ud83e\ude90', vault: 'Kabang-yaman', expand: 'Buksan', collapse: 'Isara', handbook: 'Manwal', modeSimple: 'Mode: Simple (A)', modeClassic: 'Mode: Klasiko', autoDig: '\ud83e\udd16 Auto Hukay', autoDump: '\ud83e\udd16 Auto Tapon', leftJoy: 'Magmaneho', cabinRot: 'Ikot ng Cabin', left: '\u25c0 Kaliwa', right: 'Kanan \u25b6', guide: '\ud83d\udca1 I-tap Para sa Gabay \ud83d\udca1', missionComplete: 'Misyon Tapos!', awarded: 'Kredito Natanggap', progress: 'Progreso', reward: 'Gantimpala', allComplete: '\ud83c\udf89 Lahat ng 30 misyon tapos na! \ud83d\ude80', loading: 'NAGKA-CALIBRATE...', cabinInterface: 'Calibrating interface...', bootEngine: 'Starting 3D engine...', genPlanets: 'Gumagawa ng planeta...', monoliths: 'Nagtatayo ng monolit...', launchpad: 'Nagtatayo ng launchpad...', audioSync: 'Sync ng audio...', ready: 'Sistema handa na!', titanAssembly: '\ud83e\udd16 PAGSASAMA NG TITAN', titanDesc: 'Buuin ang tagapagtanggol!', found: 'NATAGPUAN', missing: 'NAWAWALA', partsProgress: 'Progreso', treasury: 'Kayamanan & Artifact', editMode: 'EDIT MODE', editDesc: 'Gamitin ang parameter panel.', editSave: 'Auto-save.', guideTitle: 'GABAY SA MISYON', objective: 'Layunin:', actionSteps: 'Mga Hakbang:', tipSuccess: 'Tip:', gotIt: 'Sige!', handbookTitle: '\ud83d\udcd6 MANUAL NG OPERASYON', close: 'ISARA [X]', tabIntro: 'Briefing', tabControls: 'Kontrol', tabRadar: 'Arkeolohiya ng Titan', tabThreats: 'Banta', systemFault: '\u26a0\ufe0f SISTEMA SIRA \u26a0\ufe0f', rebootIn: 'Reboot:', launched: '\ud83d\ude80 LUMIPAD! \ud83d\ude80', warning: '\u26a0\ufe0f BABALA! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 SANDWORM NATALO! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 BOMBA AKTIBO! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf BOMBA NA-DISARM \ud83c\udfaf', blastWave: '\ud83d\udca5 SHOCKWAVE \ud83d\udca5', assembling: 'Nagbubuod', shipReady: '\ud83c\udf89 Sasakyang handa na!' },\n            hi: { depth: '\u0917\u0939\u0930\u093e\u0908', graphicsHigh: '\u0917\u094d\u0930\u093e\u092b\u093f\u0915\u094d\u0938: \u0905\u0932\u094d\u091f\u094d\u0930\u093e 3D', graphicsLow: '\u0917\u094d\u0930\u093e\u092b\u093f\u0915\u094d\u0938: 60 \u090f\u092b\u092a\u0940\u090f\u0938 (\u0924\u0947\u091c)', credits: '\u0915\u094d\u0930\u0947\u0921\u093f\u091f', buildBudget: '\u092c\u091c\u091f', baseBuild: '\ud83d\ude80 \u092c\u0947\u0938 \u0928\u093f\u0930\u094d\u092e\u093e\u0923 \u092a\u094d\u0930\u0917\u0924\u093f', mission: '\ud83e\ude90 \u091f\u0947\u0930\u093e\u092b\u0949\u0930\u094d\u092e\u093f\u0902\u0917 \u092e\u093f\u0936\u0928 \ud83e\ude90', vault: '\u0924\u093f\u091c\u094b\u0930\u0940', expand: '\u0916\u094b\u0932\u0947\u0902', collapse: '\u092c\u0902\u0926 \u0915\u0930\u0947\u0902', handbook: '\u092a\u0941\u0938\u094d\u0924\u093f\u0915\u093e', modeSimple: '\u092e\u094b\u0921: \u0938\u0930\u0932 (A)', modeClassic: '\u092e\u094b\u0921: \u0915\u094d\u0932\u093e\u0938\u093f\u0915', autoDig: '\ud83e\udd16 \u0911\u091f\u094b \u0916\u0941\u0926\u093e\u0908', autoDump: '\ud83e\udd16 \u0911\u091f\u094b \u0921\u0902\u092a', leftJoy: '\u0921\u094d\u0930\u093e\u0907\u0935', cabinRot: '\u0915\u0947\u092c\u093f\u0928 \u0918\u0941\u092e\u093e\u090f\u0902', left: '\u25c0 \u092c\u093e\u090f\u0902', right: '\u0926\u093e\u090f\u0902 \u25b6', guide: '\ud83d\udca1 \u0917\u093e\u0907\u0921 \u0915\u0947 \u0932\u093f\u090f \u091f\u0948\u092a \u0915\u0930\u0947\u0902 \ud83d\udca1', missionComplete: '\u092e\u093f\u0936\u0928 \u092a\u0942\u0930\u093e!', awarded: '\u0915\u094d\u0930\u0947\u0921\u093f\u091f \u092a\u094d\u0930\u093e\u092a\u094d\u0924', progress: '\u092a\u094d\u0930\u0917\u0924\u093f', reward: '\u0907\u0928\u093e\u092e', allComplete: '\ud83c\udf89 \u0938\u092d\u0940 30 \u092e\u093f\u0936\u0928 \u092a\u0942\u0930\u0947! \ud83d\ude80', loading: '\u0915\u0948\u0932\u093f\u092c\u094d\u0930\u0947\u091f \u0939\u094b \u0930\u0939\u093e \u0939\u0948...', cabinInterface: '\u0907\u0902\u091f\u0930\u092b\u0947\u0938 \u0915\u0948\u0932\u093f\u092c\u094d\u0930\u0947\u091f...', bootEngine: '3D \u0907\u0902\u091c\u0928 \u0936\u0941\u0930\u0942...', genPlanets: '\u0917\u094d\u0930\u0939 \u092c\u0928\u093e \u0930\u0939\u093e...', monoliths: '\u092e\u094b\u0928\u094b\u0932\u093f\u0925 \u0916\u0921\u093c\u0947 \u0915\u0930 \u0930\u0939\u093e...', launchpad: '\u0932\u0949\u0928\u094d\u091a\u092a\u0948\u0921 \u092c\u0928\u093e \u0930\u0939\u093e...', audioSync: '\u0911\u0921\u093f\u092f\u094b \u0938\u093f\u0902\u0915...', ready: '\u0938\u093f\u0938\u094d\u091f\u092e \u0924\u0948\u092f\u093e\u0930!', titanAssembly: '\ud83e\udd16 \u091f\u093e\u0907\u091f\u0928 \u0905\u0938\u0947\u0902\u092c\u0932\u0940', titanDesc: '\u0930\u0915\u094d\u0937\u0915 \u0915\u094b \u091c\u094b\u0921\u093c\u0947\u0902!', found: '\u092e\u093f\u0932\u093e', missing: '\u0917\u093e\u092f\u092c', partsProgress: '\u092a\u094d\u0930\u0917\u0924\u093f', treasury: '\u0916\u091c\u093e\u0928\u093e \u0914\u0930 \u0915\u0932\u093e\u0915\u0943\u0924\u093f\u092f\u093e\u0901', editMode: '\u0938\u0902\u092a\u093e\u0926\u0928 \u092e\u094b\u0921', editDesc: '\u092a\u0948\u0930\u093e\u092e\u0940\u091f\u0930 \u092a\u0948\u0928\u0932 \u0915\u093e \u0909\u092a\u092f\u094b\u0917 \u0915\u0930\u0947\u0902\u0964', editSave: '\u0938\u094d\u0935\u091a\u093e\u0932\u093f\u0924 \u0938\u0939\u0947\u091c\u093e \u0917\u092f\u093e\u0964', guideTitle: '\u092e\u093f\u0936\u0928 \u0917\u093e\u0907\u0921', objective: '\u0932\u0915\u094d\u0937\u094d\u092f:', actionSteps: '\u0915\u0926\u092e:', tipSuccess: '\u0938\u0941\u091d\u093e\u0935:', gotIt: '\u0938\u092e\u091d \u0917\u092f\u093e!', handbookTitle: '\ud83d\udcd6 \u0938\u0902\u091a\u093e\u0932\u0928 \u092e\u0948\u0928\u0941\u0905\u0932', close: '\u092c\u0902\u0926 \u0915\u0930\u0947\u0902 [X]', tabIntro: '\u092c\u094d\u0930\u0940\u092b\u093f\u0902\u0917', tabControls: '\u0928\u093f\u092f\u0902\u0924\u094d\u0930\u0923', tabRadar: '\u091f\u093e\u0907\u091f\u0928 \u092a\u0941\u0930\u093e\u0924\u0924\u094d\u0935', tabThreats: '\u0916\u0924\u0930\u0947', systemFault: '\u26a0\ufe0f \u0938\u093f\u0938\u094d\u091f\u092e \u0935\u093f\u092b\u0932\u0924\u093e \u26a0\ufe0f', rebootIn: '\u0930\u0940\u092c\u0942\u091f:', launched: '\ud83d\ude80 \u0909\u0921\u093c \u0917\u090f! \ud83d\ude80', warning: '\u26a0\ufe0f \u091a\u0947\u0924\u093e\u0935\u0928\u0940! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u0938\u0948\u0902\u0921\u0935\u0949\u0930\u094d\u092e \u092e\u093e\u0930\u093e \u0917\u092f\u093e! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u092c\u092e \u0938\u0915\u094d\u0930\u093f\u092f! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf \u092c\u092e \u0928\u093f\u0937\u094d\u0915\u094d\u0930\u093f\u092f \ud83c\udfaf', blastWave: '\ud83d\udca5 \u0935\u093f\u0938\u094d\u092b\u094b\u091f \u0924\u0930\u0902\u0917 \ud83d\udca5', assembling: '\u091c\u094b\u0921\u093c \u0930\u0939\u093e \u0939\u0948', shipReady: '\ud83c\udf89 \u0905\u0902\u0924\u0930\u093f\u0915\u094d\u0937 \u092f\u093e\u0928 \u0924\u0948\u092f\u093e\u0930!' },\n            ar: { depth: '\u0627\u0644\u0639\u0645\u0642', graphicsHigh: '\u0627\u0644\u0631\u0633\u0648\u0645\u064a\u0627\u062a: \u0641\u0627\u0626\u0642\u0629 3D', graphicsLow: '\u0627\u0644\u0631\u0633\u0648\u0645\u064a\u0627\u062a: 60 \u0625\u0637\u0627\u0631 (\u0633\u0631\u064a\u0639)', credits: '\u0627\u0644\u0631\u0635\u064a\u062f', buildBudget: '\u0627\u0644\u0645\u064a\u0632\u0627\u0646\u064a\u0629', baseBuild: '\ud83d\ude80 \u062a\u0642\u062f\u0645 \u0627\u0644\u0642\u0627\u0639\u062f\u0629', mission: '\ud83e\ude90 \u0645\u0647\u0645\u0629 \u062a\u0634\u0643\u064a\u0644 \u0627\u0644\u0643\u0648\u0643\u0628 \ud83e\ude90', vault: '\u0627\u0644\u062e\u0632\u0646\u0629', expand: '\u0641\u062a\u062d', collapse: '\u0625\u063a\u0644\u0627\u0642', handbook: '\u0627\u0644\u062f\u0644\u064a\u0644', modeSimple: '\u0627\u0644\u0648\u0636\u0639: \u0628\u0633\u064a\u0637 (A)', modeClassic: '\u0627\u0644\u0648\u0636\u0639: \u0643\u0644\u0627\u0633\u064a\u0643\u064a', autoDig: '\ud83e\udd16 \u062d\u0641\u0631 \u062a\u0644\u0642\u0627\u0626\u064a', autoDump: '\ud83e\udd16 \u062a\u0641\u0631\u064a\u063a \u062a\u0644\u0642\u0627\u0626\u064a', leftJoy: '\u0627\u0644\u0642\u064a\u0627\u062f\u0629', cabinRot: '\u062a\u062f\u0648\u064a\u0631 \u0627\u0644\u0645\u0642\u0635\u0648\u0631\u0629', left: '\u25c0 \u064a\u0633\u0627\u0631', right: '\u064a\u0645\u064a\u0646 \u25b6', guide: '\ud83d\udca1 \u0627\u0636\u063a\u0637 \u0644\u0644\u062f\u0644\u064a\u0644 \ud83d\udca1', missionComplete: '\u0627\u0644\u0645\u0647\u0645\u0629 \u0645\u0643\u062a\u0645\u0644\u0629!', awarded: '\u0631\u0635\u064a\u062f \u0645\u0643\u062a\u0633\u0628', progress: '\u0627\u0644\u062a\u0642\u062f\u0645', reward: '\u0627\u0644\u0645\u0643\u0627\u0641\u0623\u0629', allComplete: '\ud83c\udf89 \u0627\u0643\u062a\u0645\u0644\u062a \u062c\u0645\u064a\u0639 \u0627\u0644\u0645\u0647\u0627\u0645 \u0627\u0644\u064030! \ud83d\ude80', loading: '\u062c\u0627\u0631\u064a \u0627\u0644\u0645\u0639\u0627\u064a\u0631\u0629...', cabinInterface: '\u0645\u0639\u0627\u064a\u0631\u0629 \u0627\u0644\u0648\u0627\u062c\u0647\u0629...', bootEngine: '\u062a\u0634\u063a\u064a\u0644 \u0645\u062d\u0631\u0643 3D...', genPlanets: '\u062a\u0648\u0644\u064a\u062f \u0627\u0644\u0643\u0648\u0627\u0643\u0628...', monoliths: '\u0628\u0646\u0627\u0621 \u0627\u0644\u0623\u0639\u0645\u062f\u0629...', launchpad: '\u0628\u0646\u0627\u0621 \u0645\u0646\u0635\u0629 \u0627\u0644\u0625\u0637\u0644\u0627\u0642...', audioSync: '\u0645\u0632\u0627\u0645\u0646\u0629 \u0627\u0644\u0635\u0648\u062a...', ready: '\u0627\u0644\u0646\u0638\u0627\u0645 \u062c\u0627\u0647\u0632!', titanAssembly: '\ud83e\udd16 \u062a\u062c\u0645\u064a\u0639 \u0627\u0644\u062a\u0627\u064a\u062a\u0646', titanDesc: '\u0627\u062c\u0645\u0639 \u0627\u0644\u062d\u0627\u0631\u0633 \u0627\u0644\u0639\u0645\u0644\u0627\u0642!', found: '\u0645\u0648\u062c\u0648\u062f', missing: '\u0645\u0641\u0642\u0648\u062f', partsProgress: '\u0627\u0644\u062a\u0642\u062f\u0645', treasury: '\u0627\u0644\u0643\u0646\u0648\u0632 \u0648\u0627\u0644\u0642\u0637\u0639 \u0627\u0644\u0623\u062b\u0631\u064a\u0629', editMode: '\u0648\u0636\u0639 \u0627\u0644\u062a\u062d\u0631\u064a\u0631', editDesc: '\u0627\u0633\u062a\u062e\u062f\u0645 \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0639\u0644\u0645\u0627\u062a.', editSave: '\u062d\u0641\u0638 \u062a\u0644\u0642\u0627\u0626\u064a.', guideTitle: '\u062f\u0644\u064a\u0644 \u0627\u0644\u0645\u0647\u0645\u0629', objective: '\u0627\u0644\u0647\u062f\u0641:', actionSteps: '\u0627\u0644\u062e\u0637\u0648\u0627\u062a:', tipSuccess: '\u0646\u0635\u064a\u062d\u0629:', gotIt: '\u0641\u0647\u0645\u062a!', handbookTitle: '\ud83d\udcd6 \u062f\u0644\u064a\u0644 \u0627\u0644\u0639\u0645\u0644\u064a\u0627\u062a', close: '\u0625\u063a\u0644\u0627\u0642 [X]', tabIntro: '\u0645\u0644\u062e\u0635', tabControls: '\u0627\u0644\u062a\u062d\u0643\u0645', tabRadar: '\u0622\u062b\u0627\u0631 \u0627\u0644\u062a\u0627\u064a\u062a\u0646', tabThreats: '\u0627\u0644\u062a\u0647\u062f\u064a\u062f\u0627\u062a', systemFault: '\u26a0\ufe0f \u0639\u0637\u0644 \u0641\u064a \u0627\u0644\u0646\u0638\u0627\u0645 \u26a0\ufe0f', rebootIn: '\u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u062a\u0634\u063a\u064a\u0644:', launched: '\ud83d\ude80 \u062a\u0645 \u0627\u0644\u0642\u0630\u0641! \ud83d\ude80', warning: '\u26a0\ufe0f \u062a\u062d\u0630\u064a\u0631! \u26a0\ufe0f', sandwormSlain: '\ud83c\udfc6 \u062f\u0648\u062f\u0629 \u0627\u0644\u0631\u0645\u0644 \u0645\u0647\u0632\u0648\u0645\u0629! \ud83c\udfc6', bombTriggered: '\ud83d\udca3 \u0627\u0644\u0642\u0646\u0628\u0644\u0629 \u0645\u0641\u0639\u0651\u0644\u0629! \ud83d\udca3', bombDisarmed: '\ud83c\udfaf \u062a\u0645 \u062a\u0641\u0643\u064a\u0643 \u0627\u0644\u0642\u0646\u0628\u0644\u0629 \ud83c\udfaf', blastWave: '\ud83d\udca5 \u0645\u0648\u062c\u0629 \u0627\u0646\u0641\u062c\u0627\u0631 \ud83d\udca5', assembling: '\u062a\u062c\u0645\u064a\u0639', shipReady: '\ud83c\udf89 \u0627\u0644\u0645\u0631\u0643\u0628\u0629 \u062c\u0627\u0647\u0632\u0629 \u0644\u0644\u0625\u0637\u0644\u0627\u0642!' }\n        };\n\n        function detectLanguage() {\n            const lang = (navigator.language || navigator.userLanguage || 'en').toLowerCase();\n            const code = lang.split('-')[0];\n            if (translations[code]) return code;\n            // Check for regional variants\n            if (lang.startsWith('zh')) return 'zh';\n            if (lang.startsWith('pt')) return 'pt';\n            if (lang.startsWith('fil') || lang.startsWith('tl')) return 'fil';\n            return 'en';\n        }\n\n        const currentLang = detectLanguage();\n        const isRTL = (currentLang === 'ar');\n        if (isRTL) {\n            document.documentElement.setAttribute('dir', 'rtl');\n            document.body.style.direction = 'rtl';\n        }\n\n        function t(key) {\n            const langData = translations[currentLang] || translations['en'];\n            return langData[key] || translations['en'][key] || key;\n        }\n\n        // ===== LOADING HUD PROGRESS =====\n        const loadingBar = document.getElementById('loading-progress-bar');\n        const loadingText = document.getElementById('loading-status-text');\n        const loadingScreen = document.getElementById('loading-screen');\n\n        function setLoadProgress(percent, msg) {\n            if (loadingBar) loadingBar.style.width = percent + '%';\n            if (loadingText) loadingText.textContent = msg.toUpperCase();\n        }\n\n        setLoadProgress(15, t('cabinInterface'));\n\n        // ===== TREASURE TYPES =====\n        const treasureTypes = [\n            { id: 'purple_gem', name: 'Sandworm Heart Gem', color: 0xda00ff, score: 500, emoji: '\ud83d\udc9c' },\n            { id: 'ruby', name: 'Uncut Ruby', color: 0xff0055, score: 150, emoji: '\ud83d\udc8e' },\n            { id: 'gold', name: 'Raw Gold Nugget', color: 0xffd700, score: 100, emoji: '\ud83e\ude99' },\n            { id: 'crystal', name: 'Brilliant Sapphire', color: 0x00e5ff, score: 200, emoji: '\ud83d\udd2e' },\n            { id: 'emerald', name: 'Emerald Crystal', color: 0x00ff66, score: 180, emoji: '\u2747\ufe0f' },\n            { id: 'statue', name: 'Ancient Stone Statue', color: 0x90a4ae, score: 300, emoji: '\ud83d\uddff' },\n            { id: 'chest', name: 'Old Machine Chest', color: 0xffb300, score: 250, emoji: '\ud83d\udce6' },\n            { id: 'plate', name: 'Bronze Ritual Plate', color: 0x8d6e63, score: 120, emoji: '\ud83d\udcbf' },\n            { id: 'crown', name: 'Ancient Imperial Crown', color: 0xffea00, score: 400, emoji: '\ud83d\udc51' },\n            { id: 'sword', name: 'Obsidian Ancient Sword', color: 0x78909c, score: 180, emoji: '\ud83d\udde1\ufe0f' },\n            { id: 'vase', name: 'Double-handled Amphora', color: 0xd84315, score: 160, emoji: '\ud83c\udffa' },\n            { id: 'chalice', name: 'Golden Chalice', color: 0xffca28, score: 350, emoji: '\ud83c\udfc6' },\n            { id: 'tablet', name: 'Ancient Rune Tablet', color: 0x455a64, score: 280, emoji: '\ud83d\udcdc' },\n            { id: 'ring', name: 'Superstring Energy Ring', color: 0x26a69a, score: 220, emoji: '\ud83d\udc8d' },\n            { id: 'key', name: 'Stargate Machine Key', color: 0x9e9d24, score: 140, emoji: '\ud83d\udd11' }\n        ];\n\n        const collectedInventory = {};\n        treasureTypes.forEach(t => { collectedInventory[t.id] = 0; });\n\n        const titanCollection = {\n            titan_l_leg: false,\n            titan_r_leg: false,\n            titan_torso: false,\n            titan_l_arm: false,\n            titan_r_arm: false,\n            titan_head: false\n        };\n\n        let titanActive = false;\n        let titanX = -11;\n        let titanZ = -19;\n        let titanY = 0;\n        let titanSpeed = 5.0;\n        let titanWalkCycle = 0;\n        let titanAttackTimer = 0;\n\n        // Show game parameters\n        lib.showGameParameters({\n            name: 'Terraform Tycoon',\n            params: {\n                'Excavator Speed': { key: 'excavator.speed', type: 'slider', min: 0.5, max: 2.0, step: 0.1 },\n                'Bucket Capacity': { key: 'excavator.bucketCapacity', type: 'slider', min: 0.5, max: 2.0, step: 0.1 },\n                'Terrain Roughness': { key: 'terrain.roughness', type: 'slider', min: 0.3, max: 2.0, step: 0.1 },\n                'Terrain Hardness': { key: 'terrain.hardness', type: 'slider', min: 0.3, max: 1.5, step: 0.1 },\n                'Gravity': { key: 'physics.gravity', type: 'slider', min: 0.5, max: 2.0, step: 0.1 },\n                'Sky Color': { key: 'environment.skyColor', type: 'color' },\n                'Fog Density': { key: 'environment.fogDensity', type: 'slider', min: 0, max: 0.05, step: 0.005 },\n                'Soil Color': { key: 'terrain.soilColor', type: 'color' }\n            }\n        });\n        setLoadProgress(30, t('bootEngine'));\n\n        // ===== THREE.JS SETUP =====\n        const scene = new THREE.Scene();\n        const camera = new THREE.PerspectiveCamera(60, gameWorld.clientWidth / gameWorld.clientHeight, 0.1, 500);\n        const renderer = new THREE.WebGLRenderer({ antialias: true });\n        renderer.setSize(gameWorld.clientWidth, gameWorld.clientHeight);\n        gameWorld.appendChild(renderer.domElement);\n\n        // Resize handler\n        window.addEventListener('resize', () => {\n            camera.aspect = gameWorld.clientWidth / gameWorld.clientHeight;\n            camera.updateProjectionMatrix();\n            renderer.setSize(gameWorld.clientWidth, gameWorld.clientHeight);\n        });\n\n        // ===== GRAPHICS QUALITY SETTINGS (AUTO FPS OPTIMIZATION FOR LOW-END PHONES) =====\n        let currentGraphicsMode = 'low'; // Default to highly-optimized low graphics for flawless 60 FPS on low-end Southeast Asian phones!\n\n        function setGraphicsQuality(quality) {\n            currentGraphicsMode = quality;\n            \n            if (quality === 'low') {\n                // Render at clean 1.0 device ratio to save up to 70% fillrate and pixel processing!\n                renderer.setPixelRatio(1.0);\n                renderer.shadowMap.enabled = false;\n                if (typeof sunLight !== 'undefined') {\n                    sunLight.castShadow = false;\n                }\n            } else {\n                // Render at high device ratio with fully detailed PCFSoft shadows!\n                renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5));\n                renderer.shadowMap.enabled = true;\n                renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n                if (typeof sunLight !== 'undefined') {\n                    sunLight.castShadow = true;\n                }\n            }\n            \n            // Toggle cast/receive shadow flags dynamically on all elements to optimize draw calls\n            scene.traverse(child => {\n                if (child.isMesh) {\n                    if (quality === 'low') {\n                        child.castShadow = false;\n                        child.receiveShadow = false;\n                    } else {\n                        if (typeof terrainMesh !== 'undefined' && child === terrainMesh) {\n                            child.receiveShadow = true;\n                        } else {\n                            child.castShadow = true;\n                            child.receiveShadow = true;\n                        }\n                    }\n                }\n            });\n\n            // Mark materials for update to cleanly compile shader programs with/without shadow code\n            if (typeof terrainMaterial !== 'undefined') {\n                terrainMaterial.needsUpdate = true;\n            }\n            \n            // Sync button UI indicators\n            const btn = document.getElementById('graphics-toggle-btn');\n            if (btn) {\n                btn.innerHTML = `\u26a1 ${currentGraphicsMode === 'low' ? t('graphicsLow') : t('graphicsHigh')}`;\n                btn.style.borderColor = currentGraphicsMode === 'low' ? '#00ff66' : '#00e5ff';\n                btn.style.boxShadow = currentGraphicsMode === 'low' ? '0 0 16px rgba(0, 255, 102, 0.45)' : '0 0 16px rgba(0, 229, 255, 0.45)';\n            }\n        }\n\n        // ===== ENVIRONMENT =====\n        const skyColor = new THREE.Color(config.environment.skyColor);\n        scene.background = skyColor;\n        scene.fog = new THREE.FogExp2(skyColor, config.environment.fogDensity);\n\n        // Lighting\n        const ambientLight = new THREE.AmbientLight(0x665577, 0.5);\n        scene.add(ambientLight);\n\n        const sunLight = new THREE.DirectionalLight(0xffcc88, 1.2);\n        sunLight.position.set(50, 80, 30);\n        sunLight.castShadow = true;\n        sunLight.shadow.mapSize.set(1024, 1024); // Highly optimized from 2048 to 1024 to save 75% depth texture bandwidth!\n        sunLight.shadow.camera.near = 0.5;\n        sunLight.shadow.camera.far = 200;\n        sunLight.shadow.camera.left = -60;\n        sunLight.shadow.camera.right = 60;\n        sunLight.shadow.camera.top = 60;\n        sunLight.shadow.camera.bottom = -60;\n        scene.add(sunLight);\n\n        const fillLight = new THREE.DirectionalLight(0x8844aa, 0.3);\n        fillLight.position.set(-30, 20, -50);\n        scene.add(fillLight);\n\n        setLoadProgress(45, t('genPlanets'));\n\n        // ===== TERRAIN SYSTEM =====\n        const TERRAIN_SIZE = 100;\n        const TERRAIN_RES = 100;\n        const heightMap = [];\n\n        function generateTerrain() {\n            const roughness = config.terrain.roughness;\n            for (let z = 0; z < TERRAIN_RES; z++) {\n                heightMap[z] = [];\n                for (let x = 0; x < TERRAIN_RES; x++) {\n                    const nx = x / TERRAIN_RES;\n                    const nz = z / TERRAIN_RES;\n                    let h = 0;\n                    h += Math.sin(nx * 3.14 * 2) * Math.cos(nz * 3.14 * 3) * 3 * roughness;\n                    h += Math.sin(nx * 7 + 1.3) * Math.cos(nz * 5 + 0.7) * 1.5 * roughness;\n                    h += Math.sin(nx * 13 + 2.1) * Math.sin(nz * 11 + 1.4) * 0.7 * roughness;\n                    // crater\n                    const cx = nx - 0.5, cz = nz - 0.5;\n                    const dist = Math.sqrt(cx*cx + cz*cz);\n                    if (dist < 0.15) h -= (0.15 - dist) * 20 * roughness;\n                    heightMap[z][x] = h;\n                }\n            }\n        }\n        generateTerrain();\n\n        // Create terrain mesh\n        const terrainGeometry = new THREE.PlaneGeometry(TERRAIN_SIZE, TERRAIN_SIZE, TERRAIN_RES - 1, TERRAIN_RES - 1);\n        terrainGeometry.rotateX(-Math.PI / 2);\n\n        // Add color attribute for vertex colors (sandy color gradient)\n        const terrainColors = new Float32Array(TERRAIN_RES * TERRAIN_RES * 3);\n        terrainGeometry.setAttribute('color', new THREE.BufferAttribute(terrainColors, 3));\n\n        const treasures = [];\n        const sandworms = [];\n        const landmines = [];\n        let excavatorShakeIntensity = 0; // Vibration intensity of the excavator when sandworm is nearby/attacking\n        let cameraShakeIntensity = 0; // Screen shaking intensity from explosions\n        let bomberSpawnTimer = 0; // Timer for bomb zombies\n        let excavatorMalfunctionTimer = 0; // Malfunction duration timer\n        let wasMalfunctioning = false;\n\n        function createSandwormMesh() {\n            const group = new THREE.Group();\n            \n            // Wet-looking organic purple skin and glowing accent with higher shininess for biological slimy feel\n            const skinMat = new THREE.MeshPhongMaterial({\n                color: 0x410a50, // Deep slimy organic plum purple\n                specular: 0xda70d6,\n                shininess: 90, // Slimy wet skin reflection!\n                flatShading: true\n            });\n            const accentMat = new THREE.MeshPhongMaterial({\n                color: 0x6b006b,\n                emissive: 0xff00b7, // Vibrant hot magenta emissive glow\n                emissiveIntensity: 0.9,\n                shininess: 60\n            });\n            const toothMat = new THREE.MeshPhongMaterial({ color: 0xfff0f5, shininess: 80 });\n            const eyeMat = new THREE.MeshBasicMaterial({ color: 0xff00ff });\n\n            // Head\n            const headGroup = new THREE.Group();\n            const headGeo = new THREE.DodecahedronGeometry(1.6, 1);\n            const headMesh = new THREE.Mesh(headGeo, skinMat);\n            headMesh.castShadow = true;\n            headMesh.receiveShadow = true;\n            headGroup.add(headMesh);\n\n            // Giant mouth cylinder with dark purple/slimy interior\n            const mouthGeo = new THREE.CylinderGeometry(1.0, 1.0, 0.4, 8);\n            mouthGeo.rotateX(Math.PI / 2);\n            const mouthMesh = new THREE.Mesh(mouthGeo, new THREE.MeshPhongMaterial({ color: 0x15001a, shininess: 100 }));\n            mouthMesh.position.z = 0.8;\n            headGroup.add(mouthMesh);\n\n            // Concentric double rows of jagged sharp teeth\n            // Inner row:\n            for (let i = 0; i < 8; i++) {\n                const angle = (i / 8) * Math.PI * 2;\n                const toothGeo = new THREE.ConeGeometry(0.16, 0.5, 4);\n                toothGeo.rotateX(Math.PI / 2);\n                const tooth = new THREE.Mesh(toothGeo, toothMat);\n                tooth.position.set(Math.sin(angle) * 0.72, Math.cos(angle) * 0.72, 0.9);\n                tooth.lookAt(new THREE.Vector3(0, 0, 1.8));\n                headGroup.add(tooth);\n            }\n            // Outer row (creepy predatory offset teeth):\n            for (let i = 0; i < 6; i++) {\n                const angle = ((i + 0.5) / 6) * Math.PI * 2;\n                const toothGeo = new THREE.ConeGeometry(0.2, 0.6, 4);\n                toothGeo.rotateX(Math.PI / 2);\n                const tooth = new THREE.Mesh(toothGeo, toothMat);\n                tooth.position.set(Math.sin(angle) * 0.92, Math.cos(angle) * 0.92, 0.8);\n                tooth.lookAt(new THREE.Vector3(0, 0, 1.6));\n                headGroup.add(tooth);\n            }\n\n            // Five creepy biological sensory mouth feelers/palps\n            const feelers = [];\n            for (let i = 0; i < 5; i++) {\n                const angle = (i / 5) * Math.PI * 2;\n                const feelerGeo = new THREE.ConeGeometry(0.12, 0.8, 4);\n                feelerGeo.rotateX(Math.PI / 2 - 0.4); // Angled outwards\n                const feeler = new THREE.Mesh(feelerGeo, skinMat);\n                feeler.position.set(Math.sin(angle) * 1.05, Math.cos(angle) * 1.05, 0.7);\n                feeler.lookAt(new THREE.Vector3(Math.sin(angle) * 2.0, Math.cos(angle) * 2.0, 2.0));\n                headGroup.add(feeler);\n                feelers.push(feeler);\n            }\n\n            // Clustered arachnid creepy eyes (6 small eyes instead of 2 simple ones)\n            const eyeGeo = new THREE.SphereGeometry(0.14, 6, 6);\n            const eyeOffsets = [\n                {x: -0.6, y: 0.7, z: 0.6},\n                {x: 0.6, y: 0.7, z: 0.6},\n                {x: -0.85, y: 0.4, z: 0.75},\n                {x: 0.85, y: 0.4, z: 0.75},\n                {x: -0.4, y: 0.9, z: 0.4},\n                {x: 0.4, y: 0.9, z: 0.4}\n            ];\n            eyeOffsets.forEach(offset => {\n                const eye = new THREE.Mesh(eyeGeo, eyeMat);\n                eye.position.set(offset.x, offset.y, offset.z);\n                headGroup.add(eye);\n            });\n\n            group.add(headGroup);\n\n            // Body segments with predatory biological spikes/carapace ribs (highly optimized, saves ~670 polygons!)\n            const segments = [];\n            const segmentCount = 6;\n            for (let s = 1; s <= segmentCount; s++) {\n                const radius = 1.4 - s * 0.12;\n                const segGeo = new THREE.DodecahedronGeometry(radius, 1);\n                const segMesh = new THREE.Mesh(segGeo, skinMat);\n                segMesh.position.z = -s * 1.5;\n                segMesh.castShadow = true;\n                segMesh.receiveShadow = true;\n                \n                // Creepy biological spikes on each segment (ConeGeometry is extremely fast to render)\n                for (let j = 0; j < 4; j++) {\n                    const angle = (j / 4) * Math.PI * 2;\n                    const spikeGeo = new THREE.ConeGeometry(0.18, 0.8, 4);\n                    spikeGeo.rotateX(Math.PI / 4); // Slanted backwards\n                    const spike = new THREE.Mesh(spikeGeo, accentMat);\n                    spike.position.set(Math.sin(angle) * radius, Math.cos(angle) * radius, 0);\n                    spike.lookAt(new THREE.Vector3(Math.sin(angle) * (radius + 2.0), Math.cos(angle) * (radius + 2.0), -1.0));\n                    segMesh.add(spike);\n                }\n\n                group.add(segMesh);\n                segments.push(segMesh);\n            }\n\n            group.scale.set(1.6, 1.6, 1.6); // Massive Giant Sandworm!\n            return { group, headGroup, segments, feelers };\n        }\n\n        function spawnSandworms() {\n            const positions = [\n                { x: -22, z: 22, depth: 3.5 },\n                { x: 22, z: -22, depth: 4.0 },\n                { x: -5, z: -25, depth: 3.0 }\n            ];\n\n            positions.forEach((pos, idx) => {\n                const terrainHeightAtPos = getTerrainHeight(pos.x, pos.z);\n                const y = terrainHeightAtPos - pos.depth;\n\n                const wormData = createSandwormMesh();\n                // Position deep underground sleeping\n                wormData.group.position.set(pos.x, y, pos.z);\n                scene.add(wormData.group);\n\n                sandworms.push({\n                    id: idx,\n                    x: pos.x,\n                    z: pos.z,\n                    y: y,\n                    buriedY: y,\n                    depth: pos.depth,\n                    hp: 10, // Requires 10 hits\n                    state: 'sleeping', // 'sleeping', 'emerging', 'active', 'dead'\n                    meshGroup: wormData.group,\n                    headGroup: wormData.headGroup,\n                    segments: wormData.segments,\n                    feelers: wormData.feelers, // Store feelers reference\n                    hitCooldown: 0,\n                    attackTimer: 0,\n                    slitherTime: Math.random() * 50,\n                    emergenceProgress: 0\n                });\n            });\n        }\n\n        function createLandmineMesh(depth) {\n            const group = new THREE.Group();\n            \n            // Outer casing (scaled up to look much more obvious)\n            const casingMat = new THREE.MeshPhongMaterial({\n                color: 0x3a3f47,\n                specular: 0x888888,\n                shininess: 60,\n                flatShading: true\n            });\n            const casingGeo = new THREE.CylinderGeometry(1.4, 1.8, 0.6, 8);\n            const casing = new THREE.Mesh(casingGeo, casingMat);\n            casing.castShadow = true;\n            casing.receiveShadow = true;\n            group.add(casing);\n\n            // Tech hazard stripe rim\n            const rimMat = new THREE.MeshPhongMaterial({\n                color: 0xffaa00,\n                specular: 0x555555,\n                shininess: 30\n            });\n            const rimGeo = new THREE.TorusGeometry(1.4, 0.12, 8, 16);\n            rimGeo.rotateX(Math.PI / 2);\n            const rim = new THREE.Mesh(rimGeo, rimMat);\n            group.add(rim);\n\n            // LED light indicator (scaled up)\n            const ledMat = new THREE.MeshBasicMaterial({ color: 0x00ff66 });\n            const ledGeo = new THREE.SphereGeometry(0.35, 8, 8);\n            const led = new THREE.Mesh(ledGeo, ledMat);\n            led.position.y = 0.4;\n            group.add(led);\n\n            return { group, led, ledMat, warningRing: null, warningRingMat: null };\n        }\n\n        function spawnLandmines() {\n            const targetCount = 18; // At least 15 landmines! Let's place 18 for intense mining thrills!\n            let spawned = 0;\n            let attempts = 0;\n            while (spawned < targetCount && attempts < 300) {\n                attempts++;\n                const x = (Math.random() - 0.5) * 80;\n                const z = (Math.random() - 0.5) * 80;\n\n                const distToPad = Math.sqrt(x * x + (z + 15) * (z + 15));\n                if (distToPad < 15) continue;\n\n                const distToStart = Math.sqrt(x * x + (z - 10) * (z - 10));\n                if (distToStart < 10) continue;\n\n                const terrainHeightAtPos = getTerrainHeight(x, z);\n                \n                // Shallow depth so the upper body is clearly visible on the surface\n                const depth = 0.12 + Math.random() * 0.12;\n                const y = terrainHeightAtPos - depth;\n\n                const mineData = createLandmineMesh(depth);\n                mineData.group.position.set(x, y, z);\n                mineData.group.rotation.set(\n                    (Math.random() - 0.5) * 0.1,\n                    Math.random() * Math.PI,\n                    (Math.random() - 0.5) * 0.1\n                );\n\n                scene.add(mineData.group);\n\n                landmines.push({\n                    id: spawned,\n                    x: x,\n                    z: z,\n                    y: y,\n                    buriedY: terrainHeightAtPos, // Initial terrain height serves as reference\n                    depth: depth,\n                    state: 'buried', // 'buried', 'triggered', 'exploded'\n                    fuseTimer: 2.0,\n                    meshGroup: mineData.group,\n                    ledMesh: mineData.led,\n                    ledMaterial: mineData.ledMat,\n                    warningRing: mineData.warningRing,\n                    warningRingMat: mineData.warningRingMat,\n                    lastBlinkTime: 0,\n                    blinkState: false\n                });\n                \n                spawned++;\n            }\n        }\n\n        function updateTerrainGeometry() {\n            const positions = terrainGeometry.attributes.position.array;\n            const colors = terrainGeometry.attributes.color.array;\n            \n            // Rich sandy color-shifting gradient based on depth/height\n            const colorHigh = new THREE.Color('#dca868'); // light golden dune sand\n            const colorMid = new THREE.Color(config.terrain.soilColor || '#a67a53'); // warm dry sand\n            const colorDeep = new THREE.Color('#4a2e1b'); // dark damp rich organic soil\n\n            for (let z = 0; z < TERRAIN_RES; z++) {\n                const worldZ = (z / (TERRAIN_RES - 1)) * TERRAIN_SIZE - TERRAIN_SIZE / 2;\n                for (let x = 0; x < TERRAIN_RES; x++) {\n                    const worldX = (x / (TERRAIN_RES - 1)) * TERRAIN_SIZE - TERRAIN_SIZE / 2;\n                    const idx = (z * TERRAIN_RES + x) * 3;\n                    const h = heightMap[z][x];\n                    positions[idx + 1] = h;\n\n                    let c = new THREE.Color();\n                    if (h >= 0) {\n                        const t = Math.min(1.0, h / 6.0);\n                        c.lerpColors(colorMid, colorHigh, t);\n                    } else {\n                        const t = Math.min(1.0, -h / 12.0);\n                        c.lerpColors(colorMid, colorDeep, t);\n                    }\n\n                    // Faintly color/glow the sand with the color of the buried treasures in proximity\n                    if (currentGraphicsMode !== 'low' && typeof treasures !== 'undefined' && treasures.length > 0) {\n                        for (let i = 0; i < treasures.length; i++) {\n                            const tr = treasures[i];\n                            if (tr.collected || tr.scooped) continue;\n                            const dx = worldX - tr.x;\n                            const dz = worldZ - tr.z;\n                            const dist = Math.sqrt(dx * dx + dz * dz);\n                            if (tr.isTitanPart) {\n                                if (dist < 6.5) {\n                                    // Massive golden breathing pool indicating legendary archeology dig site!\n                                    const tintFactor = (1.0 - dist / 6.5) * 0.95;\n                                    const goldColor = new THREE.Color(0xff8c00);\n                                    c.lerp(goldColor, tintFactor);\n                                }\n                            } else if (dist < 4.0) {\n                                // Dynamic gradient: stronger blend closer to the gem\n                                const tintFactor = (1.0 - dist / 4.0) * 0.7; // Max 70% tinting with the gem's color\n                                const gemColor = new THREE.Color(tr.type.color);\n                                c.lerp(gemColor, tintFactor);\n                            }\n                        }\n                    }\n\n                    // Faintly color the sand purple near buried sleeping sandworms!\n                    if (currentGraphicsMode !== 'low' && typeof sandworms !== 'undefined' && sandworms.length > 0) {\n                        for (let i = 0; i < sandworms.length; i++) {\n                            const sw = sandworms[i];\n                            if (sw.state !== 'sleeping') continue;\n                            const dx = worldX - sw.x;\n                            const dz = worldZ - sw.z;\n                            const dist = Math.sqrt(dx * dx + dz * dz);\n                            if (dist < 6.0) {\n                                const tintFactor = (1.0 - dist / 6.0) * 0.85;\n                                const purpleColor = new THREE.Color(0x8a00e6); // Rich cosmic purple\n                                c.lerp(purpleColor, tintFactor);\n                            }\n                        }\n                    }\n\n                    // Faintly color/glow the sand bright hazard red near active landmines!\n                    if (currentGraphicsMode !== 'low' && typeof landmines !== 'undefined' && landmines.length > 0) {\n                        for (let i = 0; i < landmines.length; i++) {\n                            const mine = landmines[i];\n                            if (mine.state === 'exploded') continue;\n                            const dx = worldX - mine.x;\n                            const dz = worldZ - mine.z;\n                            const dist = Math.sqrt(dx * dx + dz * dz);\n                            if (dist < 4.5) {\n                                const tintFactor = (1.0 - dist / 4.5) * 0.85;\n                                const mineColor = new THREE.Color(mine.state === 'triggered' ? 0xff0000 : 0xff3300); // glowing hazard red/orange\n                                c.lerp(mineColor, tintFactor);\n                            }\n                        }\n                    }\n\n                    colors[idx] = c.r;\n                    colors[idx + 1] = c.g;\n                    colors[idx + 2] = c.b;\n                }\n            }\n            terrainGeometry.attributes.position.needsUpdate = true;\n            terrainGeometry.attributes.color.needsUpdate = true;\n            terrainGeometry.computeVertexNormals();\n        }\n        updateTerrainGeometry();\n\n        const terrainMaterial = new THREE.MeshPhongMaterial({\n            vertexColors: true,\n            flatShading: true,\n            shininess: 10\n        });\n        const terrainMesh = new THREE.Mesh(terrainGeometry, terrainMaterial);\n        terrainMesh.receiveShadow = true;\n        scene.add(terrainMesh);\n\n        // Apply initial graphics optimization settings\n        setGraphicsQuality(currentGraphicsMode);\n\n        setLoadProgress(60, t('monoliths'));\n\n        // ===== ALIEN MONOLITHS & WALLS WITH EMBEDDED RELICS =====\n        const cityGroup = new THREE.Group();\n        const wallColors = [0x222a33, 0x1c242b, 0x151c22, 0x2e3945];\n        const buildingCount = 48;\n        const monoliths = [];\n        \n        for (let i = 0; i < buildingCount; i++) {\n            const angle = (i / buildingCount) * Math.PI * 2;\n            const radius = 48 + Math.random() * 8;\n            const bx = Math.sin(angle) * radius;\n            const bz = Math.cos(angle) * radius;\n            \n            // Avoid placing right on top of space base zone at (0, -15)\n            if (Math.sqrt(bx*bx + (bz + 15)*(bz + 15)) < 15) continue;\n            \n            const bWidth = 8 + Math.random() * 6;\n            const bDepth = 8 + Math.random() * 6;\n            const bHeight = 30 + Math.random() * 40;\n\n            // Create main monolith / ancient alien wall pillar\n            const bGeo = new THREE.BoxGeometry(bWidth, bHeight, bDepth);\n            const bCol = wallColors[Math.floor(Math.random() * wallColors.length)];\n            const bMat = new THREE.MeshPhongMaterial({\n                color: bCol,\n                specular: 0x445566,\n                shininess: 40,\n                flatShading: true\n            });\n            const bMesh = new THREE.Mesh(bGeo, bMat);\n            bMesh.position.set(bx, bHeight / 2 - 2, bz);\n            bMesh.castShadow = true;\n            bMesh.receiveShadow = true;\n            \n            // Look towards center slightly to face the player's digging field\n            bMesh.lookAt(0, bHeight / 2 - 2, 0);\n            cityGroup.add(bMesh);\n\n            // Embed glowing alien civilization treasures/relics inside the wall surface!\n            // We place them on the side facing the center (front face of the wall)\n            const relicCount = 3 + Math.floor(Math.random() * 4);\n            const relicColors = [0x00e5ff, 0xffd700, 0xff0055, 0x00ff66, 0xff00ff, 0xff6d00];\n            const monolithRelics = [];\n            \n            for (let r = 0; r < relicCount; r++) {\n                // Random height on the wall\n                const ry = (Math.random() - 0.4) * (bHeight - 8);\n                // Random offset along the width\n                const rx = (Math.random() - 0.5) * (bWidth - 2);\n                \n                // Relic shapes: crystals, runic tablets, power spheres, glowing gems\n                const shapeType = Math.floor(Math.random() * 4);\n                let relicGeo;\n                if (shapeType === 0) {\n                    relicGeo = new THREE.DodecahedronGeometry(0.5 + Math.random() * 0.4, 0); // crystalline gem\n                } else if (shapeType === 1) {\n                    relicGeo = new THREE.CylinderGeometry(0.1, 0.4, 1.2, 5); // ancient power crystal spire\n                } else if (shapeType === 2) {\n                    relicGeo = new THREE.BoxGeometry(0.8, 0.8, 0.2); // glowing runic tablet\n                } else {\n                    relicGeo = new THREE.OctahedronGeometry(0.6, 0); // hovering core relic\n                }\n                \n                const relicCol = relicColors[Math.floor(Math.random() * relicColors.length)];\n                const relicMat = new THREE.MeshPhongMaterial({\n                    color: relicCol,\n                    emissive: relicCol,\n                    emissiveIntensity: 1.5,\n                    shininess: 100,\n                    specular: 0xffffff\n                });\n                \n                const relicMesh = new THREE.Mesh(relicGeo, relicMat);\n                // Positioned on the front face of the monolith (positive Z relative to lookAt orientation)\n                relicMesh.position.set(rx, ry, bDepth / 2 + 0.1);\n                \n                // Add some random rotation\n                relicMesh.rotation.set(Math.random() * 0.5, Math.random() * 0.5, Math.random() * Math.PI * 2);\n                bMesh.add(relicMesh);\n                \n                // Add a glowing tech bracket/border around the embedded treasure\n                const borderGeo = new THREE.BoxGeometry(1.2, 1.2, 0.1);\n                const borderMat = new THREE.MeshPhongMaterial({ color: 0x111111, shininess: 50 });\n                const borderMesh = new THREE.Mesh(borderGeo, borderMat);\n                borderMesh.position.set(rx, ry, bDepth / 2 + 0.02);\n                bMesh.add(borderMesh);\n\n                const typeInfo = treasureTypes[Math.floor(Math.random() * treasureTypes.length)];\n                monolithRelics.push({\n                    mesh: relicMesh,\n                    borderMesh: borderMesh,\n                    typeInfo: typeInfo,\n                    released: false\n                });\n            }\n\n            monoliths.push({\n                mesh: bMesh,\n                x: bx,\n                z: bz,\n                width: bWidth,\n                depth: bDepth,\n                height: bHeight,\n                hp: 100,\n                relics: monolithRelics,\n                destroyed: false\n            });\n        }\n        scene.add(cityGroup);\n        setLoadProgress(75, t('launchpad'));\n\n        // ===== COLONY BASE & MISSION LANDER (ROCKET & SPACESHIP CONSTRUCTION SITE) =====\n        const colonyBaseGroup = new THREE.Group();\n        colonyBaseGroup.position.set(0, 0, -15);\n        scene.add(colonyBaseGroup);\n\n        // Highly Detailed Spaceship & Rocket Construction Assembly\n        const landerMesh = new THREE.Group();\n        \n        // Materials for high-tech look\n        const metalDarkMat = new THREE.MeshPhongMaterial({ color: 0x1e272e, specular: 0x555555, shininess: 80, flatShading: true });\n        const metalWhiteMat = new THREE.MeshPhongMaterial({ color: 0xf5f6fa, specular: 0xaaaaaa, shininess: 90 });\n        const metalOrangeMat = new THREE.MeshPhongMaterial({ color: 0xff4757, specular: 0x888888, shininess: 70 });\n        const glassCockpitMat = new THREE.MeshPhongMaterial({ color: 0x00e5ff, transparent: true, opacity: 0.6, specular: 0xffffff, shininess: 100 });\n        const glowEngineMat = new THREE.MeshPhongMaterial({ color: 0xff6d00, emissive: 0xff3d00, emissiveIntensity: 2.0, shininess: 50 });\n        const goldFoilMat = new THREE.MeshPhongMaterial({ color: 0xd4af37, specular: 0xffffff, shininess: 100 });\n        const solarPanelMat = new THREE.MeshPhongMaterial({ color: 0x0a3d62, specular: 0xff00ff, shininess: 90 });\n\n        // 1. Launch Pad Platform\n        const padBaseGeo = new THREE.CylinderGeometry(6.5, 7.5, 1.2, 6); // Hexagonal launchpad\n        const padBase = new THREE.Mesh(padBaseGeo, metalDarkMat);\n        padBase.position.y = 0.6;\n        padBase.receiveShadow = true;\n        padBase.castShadow = true;\n        landerMesh.add(padBase);\n\n        // Launch pad support pillars\n        for (let s = 0; s < 6; s++) {\n            const angle = (s / 6) * Math.PI * 2;\n            const pilGeo = new THREE.BoxGeometry(1.0, 1.5, 1.0);\n            const pil = new THREE.Mesh(pilGeo, metalDarkMat);\n            pil.position.set(Math.sin(angle) * 6.5, -0.15, Math.cos(angle) * 6.5);\n            landerMesh.add(pil);\n        }\n\n        // Glowing launch pad lights\n        const padLights = [];\n        for (let l = 0; l < 6; l++) {\n            const angle = (l / 6) * Math.PI * 2;\n            const lightGeo = new THREE.SphereGeometry(0.25, 8, 8);\n            const lightMat = new THREE.MeshBasicMaterial({ color: 0x00ff66 });\n            const light = new THREE.Mesh(lightGeo, lightMat);\n            light.position.set(Math.sin(angle) * 6.8, 1.25, Math.cos(angle) * 6.8);\n            landerMesh.add(light);\n            padLights.push(light);\n        }\n\n        // 2. Central Rocket Core Group (Modular & scales with points)\n        const rocketAssemblyGroup = new THREE.Group();\n        rocketAssemblyGroup.position.set(0, 1.2, 0);\n        landerMesh.add(rocketAssemblyGroup);\n\n        // Core structural cylinder (Skeleton / Tier 1)\n        const coreTrussGeo = new THREE.CylinderGeometry(1.8, 2.0, 11.0, 8, 1, true);\n        const coreTrussMat = new THREE.MeshPhongMaterial({ color: 0x475569, wireframe: true });\n        const coreTruss = new THREE.Mesh(coreTrussGeo, coreTrussMat);\n        coreTruss.position.y = 5.5;\n        rocketAssemblyGroup.add(coreTruss);\n\n        // Stage 1 Fuel Tank (Unlocks/scales on low points)\n        const stage1Group = new THREE.Group();\n        const stage1TankGeo = new THREE.CylinderGeometry(1.7, 1.9, 5.0, 12);\n        const stage1Tank = new THREE.Mesh(stage1TankGeo, metalWhiteMat);\n        stage1Tank.position.y = 2.5;\n        stage1Tank.castShadow = true;\n        stage1Tank.receiveShadow = true;\n        stage1Group.add(stage1Tank);\n\n        // Fuel pipes running down the sides\n        const pipeGeo = new THREE.CylinderGeometry(0.1, 0.1, 5.0, 4);\n        for (let p = 0; p < 4; p++) {\n            const angle = (p / 4) * Math.PI * 2;\n            const pipe = new THREE.Mesh(pipeGeo, metalOrangeMat);\n            pipe.position.set(Math.sin(angle) * 1.85, 2.5, Math.cos(angle) * 1.85);\n            stage1Group.add(pipe);\n        }\n        rocketAssemblyGroup.add(stage1Group);\n\n        // Side Boosters (Unlocks on medium points)\n        const sideBoostersGroup = new THREE.Group();\n        for (let sb = -1; sb <= 1; sb += 2) {\n            const boosterGroup = new THREE.Group();\n            boosterGroup.position.set(sb * 2.5, 2.0, 0);\n\n            const sTankGeo = new THREE.CylinderGeometry(0.7, 0.8, 4.0, 8);\n            const sTank = new THREE.Mesh(sTankGeo, metalWhiteMat);\n            sTank.castShadow = true;\n            boosterGroup.add(sTank);\n\n            // Nose cones for boosters\n            const sNoseGeo = new THREE.ConeGeometry(0.8, 1.2, 8);\n            const sNose = new THREE.Mesh(sNoseGeo, metalOrangeMat);\n            sNose.position.y = 2.6;\n            boosterGroup.add(sNose);\n\n            // Booster engines\n            const sNozzleGeo = new THREE.CylinderGeometry(0.3, 0.5, 0.6, 8);\n            const sNozzle = new THREE.Mesh(sNozzleGeo, metalDarkMat);\n            sNozzle.position.y = -2.3;\n            boosterGroup.add(sNozzle);\n\n            const sGlowGeo = new THREE.CylinderGeometry(0.2, 0.4, 0.2, 8);\n            const sGlow = new THREE.Mesh(sGlowGeo, glowEngineMat);\n            sGlow.position.y = -2.6;\n            boosterGroup.add(sGlow);\n\n            sideBoostersGroup.add(boosterGroup);\n        }\n        rocketAssemblyGroup.add(sideBoostersGroup);\n\n        // Stage 2 Upper Tank (Unlocks on high points)\n        const stage2Group = new THREE.Group();\n        const stage2TankGeo = new THREE.CylinderGeometry(1.5, 1.7, 4.0, 12);\n        const stage2Tank = new THREE.Mesh(stage2TankGeo, metalWhiteMat);\n        stage2Tank.position.y = 7.0;\n        stage2Tank.castShadow = true;\n        stage2Group.add(stage2Tank);\n\n        // Gold insulation wrapping\n        const goldWrapGeo = new THREE.CylinderGeometry(1.52, 1.52, 1.2, 12);\n        const goldWrap = new THREE.Mesh(goldWrapGeo, goldFoilMat);\n        goldWrap.position.y = 6.2;\n        stage2Group.add(goldWrap);\n        rocketAssemblyGroup.add(stage2Group);\n\n        // 3. Futuristic Super Orbiter Spaceship (Mounted at the top!)\n        const spaceshipGroup = new THREE.Group();\n        spaceshipGroup.position.set(0, 11.5, 0);\n        rocketAssemblyGroup.add(spaceshipGroup);\n\n        // Spaceship main fuselage (highly detailed)\n        const shipBodyGeo = new THREE.CylinderGeometry(0.7, 1.3, 4.8, 10);\n        const shipBody = new THREE.Mesh(shipBodyGeo, metalWhiteMat);\n        shipBody.castShadow = true;\n        spaceshipGroup.add(shipBody);\n\n        // Sleek Space Shuttle Wings\n        const wingShape = new THREE.Group();\n        const wingPartGeo = new THREE.BoxGeometry(3.5, 0.15, 2.0);\n        const wingPart = new THREE.Mesh(wingPartGeo, metalWhiteMat);\n        wingPart.rotation.y = Math.PI / 12; // Swept back\n        wingShape.add(wingPart);\n\n        // Starfighter wingtips with red lasers/nav lights\n        for (let side = -1; side <= 1; side += 2) {\n            const tipLightGeo = new THREE.SphereGeometry(0.12, 6, 6);\n            const tipLight = new THREE.Mesh(tipLightGeo, new THREE.MeshBasicMaterial({ color: 0xff0055 }));\n            tipLight.position.set(side * 2.2, 0.1, -0.2);\n            wingShape.add(tipLight);\n        }\n        spaceshipGroup.add(wingShape);\n\n        // Dual aerodynamic tail fins\n        for (let f = -1; f <= 1; f += 2) {\n            const finGeo = new THREE.BoxGeometry(0.12, 1.5, 1.0);\n            const fin = new THREE.Mesh(finGeo, metalOrangeMat);\n            fin.position.set(f * 0.7, 1.2, -0.6);\n            fin.rotation.z = f * 0.25; // angled outwards\n            fin.rotation.y = -0.1;\n            spaceshipGroup.add(fin);\n        }\n\n        // Sleek Cabin Canopy (Glass)\n        const canopyGeo = new THREE.SphereGeometry(0.6, 12, 12);\n        canopyGeo.scale(1.0, 0.6, 1.8);\n        const canopy = new THREE.Mesh(canopyGeo, glassCockpitMat);\n        canopy.position.set(0, 0.8, 0.6);\n        spaceshipGroup.add(canopy);\n\n        // Main Nose Cone\n        const noseConeGeo = new THREE.ConeGeometry(0.7, 1.8, 10);\n        const noseCone = new THREE.Mesh(noseConeGeo, metalDarkMat);\n        noseCone.position.y = 3.3;\n        spaceshipGroup.add(noseCone);\n\n        // Thruster engines\n        const engineBellGeo = new THREE.CylinderGeometry(0.4, 0.7, 1.0, 8);\n        const engineBell = new THREE.Mesh(engineBellGeo, metalDarkMat);\n        engineBell.position.y = -2.9;\n        spaceshipGroup.add(engineBell);\n\n        const mainEngineGlow = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.6, 0.2, 8), glowEngineMat);\n        mainEngineGlow.position.y = -3.4;\n        spaceshipGroup.add(mainEngineGlow);\n\n        // Solar panels (extend outward as progress increases)\n        const solarPanelLeft = new THREE.Group();\n        solarPanelLeft.position.set(-1.4, 0, 0);\n        const panelMeshL = new THREE.Mesh(new THREE.BoxGeometry(2.8, 0.05, 1.2), solarPanelMat);\n        panelMeshL.position.x = -1.4;\n        solarPanelLeft.add(panelMeshL);\n        spaceshipGroup.add(solarPanelLeft);\n\n        const solarPanelRight = new THREE.Group();\n        solarPanelRight.position.set(1.4, 0, 0);\n        const panelMeshR = new THREE.Mesh(new THREE.BoxGeometry(2.8, 0.05, 1.2), solarPanelMat);\n        panelMeshR.position.x = 1.4;\n        solarPanelRight.add(panelMeshR);\n        spaceshipGroup.add(solarPanelRight);\n\n        // 4. Heavy Launch Tower Assembly (Side crane, umbilical arms, hoses)\n        const towerGroup = new THREE.Group();\n        towerGroup.position.set(-4.5, 0, -3.0);\n        landerMesh.add(towerGroup);\n\n        const towerHeight = 18;\n        const towerTrussGeo = new THREE.BoxGeometry(2.0, towerHeight, 2.0);\n        const towerTrussMat = new THREE.MeshPhongMaterial({ color: 0xe056fd, wireframe: true }); // glowing cyberpunk structure\n        const towerTruss = new THREE.Mesh(towerTrussGeo, towerTrussMat);\n        towerTruss.position.y = towerHeight / 2 + 0.6;\n        towerGroup.add(towerTruss);\n\n        // Rotating Heavy Crane\n        const craneGantry = new THREE.Group();\n        craneGantry.position.set(0, towerHeight - 1.5, 0);\n        const craneGantryArm = new THREE.Mesh(new THREE.BoxGeometry(6.5, 0.6, 0.6), metalOrangeMat);\n        craneGantryArm.position.x = 2.8;\n        craneGantry.add(craneGantryArm);\n\n        // Suspended wire and magnetic receiver target\n        const craneCable = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, 5.0, 4), metalDarkMat);\n        craneCable.position.set(5.5, -2.5, 0);\n        craneGantry.add(craneCable);\n\n        const craneMagnet = new THREE.Mesh(new THREE.CylinderGeometry(1.0, 1.0, 0.4, 8), metalDarkMat);\n        craneMagnet.position.set(5.5, -5.0, 0);\n        craneGantry.add(craneMagnet);\n\n        const laserTargetVisual = new THREE.Mesh(new THREE.CylinderGeometry(1.2, 1.2, 0.15, 8), new THREE.MeshBasicMaterial({ color: 0x00e5ff, transparent: true, opacity: 0.8 }));\n        laserTargetVisual.position.set(5.5, -5.2, 0);\n        craneGantry.add(laserTargetVisual);\n\n        towerGroup.add(craneGantry);\n\n        // Animated Umbilical Arms (clamped onto rocket, retracts with points)\n        const umbilicalArms = [];\n        for (let u = 0; u < 3; u++) {\n            const arm = new THREE.Group();\n            arm.position.set(1.0, 4.0 + u * 4.5, 1.5);\n            \n            const armBeam = new THREE.Mesh(new THREE.BoxGeometry(3.0, 0.3, 0.3), metalDarkMat);\n            armBeam.position.x = 1.5;\n            arm.add(armBeam);\n\n            const clamp = new THREE.Mesh(new THREE.CylinderGeometry(1.2, 1.2, 0.4, 8, 1, true), metalOrangeMat);\n            clamp.position.set(3.0, 0, 0);\n            arm.add(clamp);\n\n            towerGroup.add(arm);\n            umbilicalArms.push(arm);\n        }\n\n        // Tractor beam target point representing original target base coordinates (y=3.65)\n        const receiverGlobalTarget = new THREE.Group();\n        receiverGlobalTarget.position.set(0, 3.65, 0);\n        colonyBaseGroup.add(receiverGlobalTarget);\n\n        const beamGeo = new THREE.CylinderGeometry(1.8, 1.8, 2.5, 12, 1, true);\n        const beamMat = new THREE.MeshBasicMaterial({\n            color: 0x00e5ff,\n            transparent: true,\n            opacity: 0.2,\n            side: THREE.DoubleSide\n        });\n        const beam = new THREE.Mesh(beamGeo, beamMat);\n        beam.position.y = 1.25;\n        receiverGlobalTarget.add(beam);\n\n        colonyBaseGroup.add(landerMesh);\n\n        // Holographic Dome (Target construction)\n        const domeGroup = new THREE.Group();\n        domeGroup.position.set(10, 0, -12);\n        \n        // Glowing wireframe hemisphere\n        const wireDomeGeo = new THREE.SphereGeometry(5.0, 16, 12, 0, Math.PI * 2, 0, Math.PI / 2);\n        const wireDomeMat = new THREE.MeshBasicMaterial({\n            color: 0x00ff66,\n            wireframe: true,\n            transparent: true,\n            opacity: 0.4\n        });\n        const wireDome = new THREE.Mesh(wireDomeGeo, wireDomeMat);\n        domeGroup.add(wireDome);\n\n        // Solid dome components that will unlock based on progress\n        const domeParts = [];\n        const partColors = [0xdddddd, 0x88ccff, 0x4488ff, 0x11ffaa, 0xffaa00];\n        \n        // Spawn 6 futuristic modular blocks (Habitats & Labs) inside the dome that appear as we build\n        for (let j = 0; j < 6; j++) {\n            const partGroup = new THREE.Group();\n            \n            // 1. Habitat Main Body (Sleek hexagonal pod)\n            const houseGeo = new THREE.CylinderGeometry(1.1, 1.4, 1.6, 6);\n            const houseMat = new THREE.MeshPhongMaterial({ \n                color: partColors[j % partColors.length], \n                shininess: 60, \n                flatShading: true,\n                specular: 0xaaaaaa\n            });\n            const house = new THREE.Mesh(houseGeo, houseMat);\n            partGroup.add(house);\n            \n            // 2. High-Tech Windows (Glowing cyan)\n            const winMat = new THREE.MeshPhongMaterial({ color: 0xffffff, emissive: 0x00e5ff, emissiveIntensity: 1.5 });\n            for (let w = 0; w < 3; w++) {\n                const winGeo = new THREE.SphereGeometry(0.22, 8, 8);\n                winGeo.scale(1, 1.4, 0.5);\n                const window = new THREE.Mesh(winGeo, winMat);\n                const wAngle = (w / 3) * Math.PI * 2 + (j * 0.5);\n                window.position.set(Math.sin(wAngle) * 1.25, 0.2, Math.cos(wAngle) * 1.25);\n                window.lookAt(0, 0.2, 0);\n                window.position.add(window.getWorldDirection(new THREE.Vector3()).multiplyScalar(-1.25));\n                partGroup.add(window);\n            }\n\n            // 3. Communications Antenna\n            const antGroup = new THREE.Group();\n            const antGeo = new THREE.CylinderGeometry(0.02, 0.04, 1.2, 4);\n            const antenna = new THREE.Mesh(antGeo, new THREE.MeshPhongMaterial({ color: 0x333333 }));\n            antenna.position.set(0, 1.4, 0);\n            antGroup.add(antenna);\n            const dishGeo = new THREE.BoxGeometry(0.4, 0.05, 0.4);\n            const dish = new THREE.Mesh(dishGeo, houseMat);\n            dish.position.set(0, 1.8, 0);\n            antGroup.add(dish);\n            antGroup.position.set(0.5, 0, 0.5);\n            partGroup.add(antGroup);\n            \n            // 4. Structural Base\n            const houseBase = new THREE.Mesh(new THREE.CylinderGeometry(1.5, 1.5, 0.4, 6), new THREE.MeshPhongMaterial({ color: 0x1a1a1a }));\n            houseBase.position.y = -0.9;\n            partGroup.add(houseBase);\n\n            // Set positions inside the colony dome radius\n            const dist = 1.3 + (j % 2) * 1.6;\n            const angle = (j / 6) * Math.PI * 2;\n            partGroup.position.set(Math.sin(angle) * dist, 0.8, Math.cos(angle) * dist);\n            partGroup.scale.set(0, 0, 0); // Initially scale 0 (hidden)\n            \n            domeGroup.add(partGroup);\n            domeParts.push(partGroup);\n        }\n\n        colonyBaseGroup.add(domeGroup);\n\n        // ===== TITAN MECH ASSEMBLY SITE =====\n        const titanGroup = new THREE.Group();\n        titanGroup.position.set(-11, 0, -19); // Beside the rocket launcher pad (0, 0, -15) + (-11, 0, -4)\n        titanGroup.scale.set(3.25, 3.25, 3.25); // 5 times larger (0.65 * 5 = 3.25)\n        scene.add(titanGroup);\n\n        // Materials\n        const titanHoloMat = new THREE.MeshBasicMaterial({\n            color: 0x00e5ff,\n            wireframe: true,\n            transparent: true,\n            opacity: 0.15\n        });\n        const titanArmorMat = new THREE.MeshPhongMaterial({\n            color: 0x222a30,\n            specular: 0x888888,\n            shininess: 80,\n            flatShading: true\n        });\n        const titanGlowMat = new THREE.MeshPhongMaterial({\n            color: 0xff3c00,\n            emissive: 0xff3c00,\n            emissiveIntensity: 1.5,\n            shininess: 50\n        });\n\n        const titanPartMeshes = {};\n\n        // 1. Torso\n        const torsoGroup = new THREE.Group();\n        torsoGroup.position.set(0, 4.5, 0);\n        \n        const torsoArmor = new THREE.Mesh(new THREE.BoxGeometry(3.0, 2.5, 2.0), titanArmorMat);\n        torsoArmor.castShadow = true;\n        torsoArmor.receiveShadow = true;\n        torsoGroup.add(torsoArmor);\n        // Core reactor\n        const reactor = new THREE.Mesh(new THREE.SphereGeometry(0.7, 8, 8), titanGlowMat);\n        reactor.position.set(0, 0, 1.0);\n        torsoGroup.add(reactor);\n        \n        titanGroup.add(torsoGroup);\n        titanPartMeshes['titan_torso'] = torsoGroup;\n\n        // 2. Left Leg\n        const lLegGroup = new THREE.Group();\n        lLegGroup.position.set(-1.2, 0, 0);\n        const lThigh = new THREE.Mesh(new THREE.BoxGeometry(0.8, 2.2, 0.8), titanArmorMat);\n        lThigh.position.y = 3.1;\n        lThigh.castShadow = true;\n        lLegGroup.add(lThigh);\n        const lCalf = new THREE.Mesh(new THREE.BoxGeometry(0.7, 2.2, 0.7), titanArmorMat);\n        lCalf.position.y = 1.3;\n        lCalf.castShadow = true;\n        lLegGroup.add(lCalf);\n        const lFoot = new THREE.Mesh(new THREE.BoxGeometry(1.2, 0.4, 1.6), titanArmorMat);\n        lFoot.position.set(0, 0.2, 0.2);\n        lFoot.castShadow = true;\n        lLegGroup.add(lFoot);\n        \n        titanGroup.add(lLegGroup);\n        titanPartMeshes['titan_l_leg'] = lLegGroup;\n\n        // 3. Right Leg\n        const rLegGroup = new THREE.Group();\n        rLegGroup.position.set(1.2, 0, 0);\n        const rThigh = new THREE.Mesh(new THREE.BoxGeometry(0.8, 2.2, 0.8), titanArmorMat);\n        rThigh.position.y = 3.1;\n        rThigh.castShadow = true;\n        rLegGroup.add(rThigh);\n        const rCalf = new THREE.Mesh(new THREE.BoxGeometry(0.7, 2.2, 0.7), titanArmorMat);\n        rCalf.position.y = 1.3;\n        rCalf.castShadow = true;\n        rLegGroup.add(rCalf);\n        const rFoot = new THREE.Mesh(new THREE.BoxGeometry(1.2, 0.4, 1.6), titanArmorMat);\n        rFoot.position.set(0, 0.2, 0.2);\n        rFoot.castShadow = true;\n        rLegGroup.add(rFoot);\n        \n        titanGroup.add(rLegGroup);\n        titanPartMeshes['titan_r_leg'] = rLegGroup;\n\n        // 4. Left Arm\n        const lArmGroup = new THREE.Group();\n        lArmGroup.position.set(-2.2, 5.0, 0);\n        const lShoulder = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1.2, 1.2), titanArmorMat);\n        lShoulder.castShadow = true;\n        lArmGroup.add(lShoulder);\n        const lBicep = new THREE.Mesh(new THREE.CylinderGeometry(0.35, 0.35, 2.0, 6), titanArmorMat);\n        lBicep.position.set(-0.4, -1.2, 0);\n        lBicep.rotation.z = 0.2;\n        lBicep.castShadow = true;\n        lArmGroup.add(lBicep);\n        const lForearm = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 1.8, 6), titanArmorMat);\n        lForearm.position.set(-0.7, -2.8, 0.2);\n        lForearm.castShadow = true;\n        lArmGroup.add(lForearm);\n        const lWeapon = new THREE.Mesh(new THREE.ConeGeometry(0.5, 1.2, 5), titanGlowMat);\n        lWeapon.position.set(-0.7, -3.8, 0.2);\n        lWeapon.rotation.x = Math.PI;\n        lWeapon.castShadow = true;\n        lArmGroup.add(lWeapon);\n        \n        titanGroup.add(lArmGroup);\n        titanPartMeshes['titan_l_arm'] = lArmGroup;\n\n        // 5. Right Arm\n        const rArmGroup = new THREE.Group();\n        rArmGroup.position.set(2.2, 5.0, 0);\n        const rShoulder = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1.2, 1.2), titanArmorMat);\n        rShoulder.castShadow = true;\n        rArmGroup.add(rShoulder);\n        const rBicep = new THREE.Mesh(new THREE.CylinderGeometry(0.35, 0.35, 2.0, 6), titanArmorMat);\n        rBicep.position.set(0.4, -1.2, 0);\n        rBicep.rotation.z = -0.2;\n        rBicep.castShadow = true;\n        rArmGroup.add(rBicep);\n        const rForearm = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 1.8, 6), titanArmorMat);\n        rForearm.position.set(0.7, -2.8, 0.2);\n        rForearm.castShadow = true;\n        rArmGroup.add(rForearm);\n        const rWeapon = new THREE.Mesh(new THREE.BoxGeometry(0.1, 1.5, 0.4), titanGlowMat);\n        rWeapon.position.set(0.7, -3.8, 0.2);\n        rWeapon.castShadow = true;\n        rArmGroup.add(rWeapon);\n        \n        titanGroup.add(rArmGroup);\n        titanPartMeshes['titan_r_arm'] = rArmGroup;\n\n        // 6. Head\n        const headGroup = new THREE.Group();\n        headGroup.position.set(0, 6.2, 0);\n        const helm = new THREE.Mesh(new THREE.BoxGeometry(1.2, 1.2, 1.2), titanArmorMat);\n        helm.castShadow = true;\n        headGroup.add(helm);\n        const visor = new THREE.Mesh(new THREE.BoxGeometry(1.0, 0.25, 0.3), titanGlowMat);\n        visor.position.set(0, 0.2, 0.55);\n        headGroup.add(visor);\n        const hornsL = new THREE.Mesh(new THREE.ConeGeometry(0.2, 1.0, 4), titanArmorMat);\n        hornsL.position.set(-0.6, 1.0, 0);\n        hornsL.rotation.z = 0.5;\n        hornsL.castShadow = true;\n        headGroup.add(hornsL);\n        const hornsR = new THREE.Mesh(new THREE.ConeGeometry(0.2, 1.0, 4), titanArmorMat);\n        hornsR.position.set(0.6, 1.0, 0);\n        hornsR.rotation.z = -0.5;\n        hornsR.castShadow = true;\n        headGroup.add(hornsR);\n        \n        titanGroup.add(headGroup);\n        titanPartMeshes['titan_head'] = headGroup;\n\n        function updateTitanVisuals() {\n            Object.keys(titanPartMeshes).forEach(key => {\n                const grp = titanPartMeshes[key];\n                const isCollected = titanCollection[key];\n                grp.traverse(child => {\n                    if (child.isMesh) {\n                        if (isCollected) {\n                            if (child.geometry.type === 'SphereGeometry' || child.geometry.type === 'ConeGeometry' || (key === 'titan_r_arm' && child.position.y < -3.0) || (key === 'titan_head' && child.position.z > 0.4)) {\n                                child.material = titanGlowMat;\n                            } else {\n                                child.material = titanArmorMat;\n                            }\n                            child.castShadow = true;\n                            child.receiveShadow = true;\n                        } else {\n                            child.material = titanHoloMat;\n                            child.castShadow = false;\n                            child.receiveShadow = false;\n                        }\n                    }\n                });\n            });\n        }\n        updateTitanVisuals();\n\n        // ===== EXCAVATOR MODEL =====\n        const excavatorGroup = new THREE.Group();\n        excavatorGroup.position.set(0, 0, 0);\n\n        // Materials\n        const bodyMat = new THREE.MeshPhongMaterial({ color: 0xe6a300, specular: 0x222222 });\n        const darkMat = new THREE.MeshPhongMaterial({ color: 0x222222 });\n        const greyMat = new THREE.MeshPhongMaterial({ color: 0x666666, specular: 0x444444 });\n        const warnMat = new THREE.MeshPhongMaterial({ color: 0x111111 });\n        const bucketMat = new THREE.MeshPhongMaterial({ color: 0x444444, specular: 0x333333 });\n        const glassMat = new THREE.MeshPhongMaterial({ color: 0x88ccff, transparent: true, opacity: 0.5, specular: 0xffffff });\n\n        // Tracks (base platform)\n        const baseGroup = new THREE.Group();\n\n        // Left track\n        const trackGeo = new THREE.BoxGeometry(1.2, 0.8, 5);\n        const leftTrack = new THREE.Mesh(trackGeo, darkMat);\n        leftTrack.position.set(-1.8, 0.4, 0);\n        leftTrack.castShadow = true;\n        baseGroup.add(leftTrack);\n\n        // Right track\n        const rightTrack = new THREE.Mesh(trackGeo, darkMat);\n        rightTrack.position.set(1.8, 0.4, 0);\n        rightTrack.castShadow = true;\n        baseGroup.add(rightTrack);\n\n        // Track front/back visual indicators (Headlights & Taillights)\n        const frontLightGeo = new THREE.BoxGeometry(0.4, 0.3, 0.1);\n        const frontLightMat = new THREE.MeshBasicMaterial({ color: 0x00ffcc }); // cyan headlights\n        const leftFrontLight = new THREE.Mesh(frontLightGeo, frontLightMat);\n        leftFrontLight.position.set(-1.8, 0.6, 2.51);\n        baseGroup.add(leftFrontLight);\n\n        const rightFrontLight = new THREE.Mesh(frontLightGeo, frontLightMat);\n        rightFrontLight.position.set(1.8, 0.6, 2.51);\n        baseGroup.add(rightFrontLight);\n\n        const rearLightGeo = new THREE.BoxGeometry(0.4, 0.2, 0.1);\n        const rearLightMat = new THREE.MeshBasicMaterial({ color: 0xff0055 }); // red brake lights\n        const leftRearLight = new THREE.Mesh(rearLightGeo, rearLightMat);\n        leftRearLight.position.set(-1.8, 0.6, -2.51);\n        baseGroup.add(leftRearLight);\n\n        const rightRearLight = new THREE.Mesh(rearLightGeo, rearLightMat);\n        rightRearLight.position.set(1.8, 0.6, -2.51);\n        baseGroup.add(rightRearLight);\n\n        // Holographic Directional Pointer directly under the excavator tracks on the ground pointing forward (positive Z)\n        const holoArrowGroup = new THREE.Group();\n        holoArrowGroup.position.set(0, 0.05, 0); // slightly above ground level\n\n        // Holographic Ring on the ground\n        const holoRingGeo = new THREE.RingGeometry(2.2, 2.4, 32);\n        holoRingGeo.rotateX(-Math.PI / 2);\n        const holoRingMat = new THREE.MeshBasicMaterial({ color: 0x00ffcc, side: THREE.DoubleSide, transparent: true, opacity: 0.4, depthTest: false, depthWrite: false });\n        const holoRing = new THREE.Mesh(holoRingGeo, holoRingMat);\n        holoRing.renderOrder = 9999;\n        holoArrowGroup.add(holoRing);\n\n        // Triangle pointer pointing forward (positive Z)\n        const pointerGeo = new THREE.ConeGeometry(0.8, 1.5, 3);\n        pointerGeo.rotateX(Math.PI / 2);\n        const pointerMat = new THREE.MeshBasicMaterial({ color: 0x00ffcc, transparent: true, opacity: 0.8, depthTest: false, depthWrite: false });\n        const pointer = new THREE.Mesh(pointerGeo, pointerMat);\n        pointer.position.set(0, 0, 4.0);\n        pointer.renderOrder = 9999;\n        holoArrowGroup.add(pointer);\n\n        baseGroup.add(holoArrowGroup);\n\n        // Track wheels\n        const wheelGeo = new THREE.CylinderGeometry(0.35, 0.35, 0.3, 8);\n        for (let side = -1; side <= 1; side += 2) {\n            for (let i = -2; i <= 2; i++) {\n                const wheel = new THREE.Mesh(wheelGeo, greyMat);\n                wheel.rotation.z = Math.PI / 2;\n                wheel.position.set(side * 1.8, 0.35, i * 1.1);\n                baseGroup.add(wheel);\n            }\n        }\n\n        // Track frame connector\n        const frameGeo = new THREE.BoxGeometry(2.4, 0.4, 4.5);\n        const frame = new THREE.Mesh(frameGeo, greyMat);\n        frame.position.set(0, 0.5, 0);\n        baseGroup.add(frame);\n\n        excavatorGroup.add(baseGroup);\n\n        // Turntable / Upper body\n        const upperGroup = new THREE.Group();\n        upperGroup.position.set(0, 1.0, 0);\n\n        // Turntable ring\n        const turntableGeo = new THREE.CylinderGeometry(1.5, 1.5, 0.3, 16);\n        const turntable = new THREE.Mesh(turntableGeo, greyMat);\n        upperGroup.add(turntable);\n\n        // Main body\n        const bodyGeo = new THREE.BoxGeometry(3.0, 1.8, 3.5);\n        const body = new THREE.Mesh(bodyGeo, bodyMat);\n        body.position.set(0, 1.1, -0.3);\n        body.castShadow = true;\n        upperGroup.add(body);\n\n        // Engine compartment (rear)\n        const engineGeo = new THREE.BoxGeometry(2.8, 1.4, 1.5);\n        const engine = new THREE.Mesh(engineGeo, bodyMat);\n        engine.position.set(0, 0.9, -1.8);\n        engine.castShadow = true;\n        upperGroup.add(engine);\n\n        // Cabin\n        const cabinGeo = new THREE.BoxGeometry(2.2, 1.6, 2.0);\n        const cabin = new THREE.Mesh(cabinGeo, bodyMat);\n        cabin.position.set(0, 2.5, 0.2);\n        cabin.castShadow = true;\n        upperGroup.add(cabin);\n\n        // Cabin glass\n        const glassGeo = new THREE.BoxGeometry(2.0, 1.2, 0.1);\n        const glassFront = new THREE.Mesh(glassGeo, glassMat);\n        glassFront.position.set(0, 2.6, 1.21);\n        upperGroup.add(glassFront);\n\n        const glassSideGeo = new THREE.BoxGeometry(0.1, 1.2, 1.8);\n        const glassLeft = new THREE.Mesh(glassSideGeo, glassMat);\n        glassLeft.position.set(-1.11, 2.6, 0.2);\n        upperGroup.add(glassLeft);\n        const glassRight = new THREE.Mesh(glassSideGeo, glassMat);\n        glassRight.position.set(1.11, 2.6, 0.2);\n        upperGroup.add(glassRight);\n\n        // Exhaust pipe\n        const exhaustGeo = new THREE.CylinderGeometry(0.1, 0.12, 1.0, 8);\n        const exhaust = new THREE.Mesh(exhaustGeo, darkMat);\n        exhaust.position.set(1.2, 2.8, -1.5);\n        upperGroup.add(exhaust);\n\n        // Warning stripes on body\n        const stripeGeo = new THREE.BoxGeometry(3.02, 0.15, 0.5);\n        const stripeMat = new THREE.MeshPhongMaterial({ color: 0x111111 });\n        for (let i = 0; i < 3; i++) {\n            const stripe = new THREE.Mesh(stripeGeo, stripeMat);\n            stripe.position.set(0, 0.4 + i * 0.4, 1.5);\n            upperGroup.add(stripe);\n        }\n\n        // Boom (first arm segment)\n        const boomGroup = new THREE.Group();\n        boomGroup.position.set(0, 1.8, 1.5);\n\n        const boomGeo = new THREE.BoxGeometry(0.6, 0.5, 5.0);\n        const boom = new THREE.Mesh(boomGeo, bodyMat);\n        boom.position.set(0, 0, 2.5);\n        boom.castShadow = true;\n        boomGroup.add(boom);\n\n        // Boom hydraulic pistons\n        const pistonGeo = new THREE.CylinderGeometry(0.08, 0.08, 3.0, 6);\n        const pistonL = new THREE.Mesh(pistonGeo, greyMat);\n        pistonL.rotation.x = Math.PI / 2;\n        pistonL.position.set(-0.25, 0.3, 1.5);\n        boomGroup.add(pistonL);\n        const pistonR = new THREE.Mesh(pistonGeo, greyMat);\n        pistonR.rotation.x = Math.PI / 2;\n        pistonR.position.set(0.25, 0.3, 1.5);\n        boomGroup.add(pistonR);\n\n        // Arm (second segment)\n        const armGroup = new THREE.Group();\n        armGroup.position.set(0, 0, 5.0);\n\n        const armGeo = new THREE.BoxGeometry(0.45, 0.4, 3.5);\n        const arm = new THREE.Mesh(armGeo, bodyMat);\n        arm.position.set(0, 0, 1.75);\n        arm.castShadow = true;\n        armGroup.add(arm);\n\n        // Arm hydraulic\n        const armPistonGeo = new THREE.CylinderGeometry(0.06, 0.06, 2.0, 6);\n        const armPiston = new THREE.Mesh(armPistonGeo, greyMat);\n        armPiston.rotation.x = Math.PI / 2;\n        armPiston.position.set(0, 0.25, 1.0);\n        armGroup.add(armPiston);\n\n        // Bucket\n        const bucketGroup = new THREE.Group();\n        bucketGroup.position.set(0, 0, 3.5);\n        bucketGroup.scale.set(3, 3, 3);\n\n        // Bucket body (open-top shape using multiple parts)\n        const bucketBackGeo = new THREE.BoxGeometry(1.2, 0.8, 0.1);\n        const bucketBack = new THREE.Mesh(bucketBackGeo, bucketMat);\n        bucketBack.position.set(0, 0, 0);\n        bucketBack.castShadow = true;\n        bucketGroup.add(bucketBack);\n\n        const bucketBottomGeo = new THREE.BoxGeometry(1.2, 0.1, 0.8);\n        const bucketBottom = new THREE.Mesh(bucketBottomGeo, bucketMat);\n        bucketBottom.position.set(0, -0.4, 0.4);\n        bucketGroup.add(bucketBottom);\n\n        const bucketSideGeo = new THREE.BoxGeometry(0.1, 0.8, 0.8);\n        const bucketSideL = new THREE.Mesh(bucketSideGeo, bucketMat);\n        bucketSideL.position.set(-0.55, 0, 0.4);\n        bucketGroup.add(bucketSideL);\n        const bucketSideR = new THREE.Mesh(bucketSideGeo, bucketMat);\n        bucketSideR.position.set(0.55, 0, 0.4);\n        bucketGroup.add(bucketSideR);\n\n        // Bucket teeth\n        const toothGeo = new THREE.ConeGeometry(0.06, 0.25, 4);\n        for (let i = -3; i <= 3; i++) {\n            const tooth = new THREE.Mesh(toothGeo, greyMat);\n            tooth.position.set(i * 0.16, -0.45, 0.8);\n            tooth.rotation.x = Math.PI / 4;\n            bucketGroup.add(tooth);\n        }\n\n        // Dirt mesh inside bucket\n        const bucketDirtGeo = new THREE.SphereGeometry(0.4, 8, 8);\n        bucketDirtGeo.scale(2.5, 1.4, 1.6); // shape it to fill the bucket nicely\n        const bucketDirtMat = new THREE.MeshLambertMaterial({ color: new THREE.Color(config.terrain.soilColor) });\n        const bucketDirtMesh = new THREE.Mesh(bucketDirtGeo, bucketDirtMat);\n        bucketDirtMesh.position.set(0, -0.1, 0.35); // Center it in the bucket\n        bucketGroup.add(bucketDirtMesh);\n        armGroup.add(bucketGroup);\n        boomGroup.add(armGroup);\n        upperGroup.add(boomGroup);\n        excavatorGroup.add(upperGroup);\n        scene.add(excavatorGroup);\n\n        // ===== EXCAVATOR STATE =====\n        let excState = {\n            x: config.excavator.startX || 0,\n            z: config.excavator.startZ || 10,\n            rotation: 0, // base vehicle rotation\n            upperRotation: 0, // turret rotation\n            boomAngle: -0.3, // boom pitch\n            armAngle: 0.5, // arm pitch relative to boom\n            bucketAngle: 0.3, // bucket pitch\n            bucketOpen: false,\n            dirtInBucket: 0\n        };\n\n        // Excavator launch physics from landmines\n        let excavatorLaunchY = 0;\n        let excavatorLaunchVY = 0;\n        let excavatorLaunchVX = 0;\n        let excavatorLaunchVZ = 0;\n        let excavatorLaunchRotX = 0;\n        let excavatorLaunchRotZ = 0;\n\n        // ===== CAMERA STATE =====\n        let camState = {\n            distance: 32,\n            azimuth: Math.PI * 0.75,\n            elevation: 0.8,\n            targetOffset: new THREE.Vector3(0, 3, 0)\n        };\n\n        // ===== OBJECTIVE SYSTEM (30 PROGRESSIVE MISSIONS) =====\n        // Specially redesigned and streamlined for Simple Mode!\n        const missions = [\n            { id: 1, title: \"1. Rotate Cabin\", text: \"Rotate the cabin 180 degrees using Q/E keys or touch controls\", type: \"rotate\", target: Math.PI, progress: 0, complete: false, reward: 200 },\n            { id: 2, title: \"2. First Dig\", text: \"Dig down to a depth of 0.5 meters\", type: \"dig\", target: 0.5, progress: 0, complete: false, reward: 300 },\n            { id: 3, title: \"3. Earn Credits\", text: \"Acquire 500 Credits\", type: \"credits\", target: 500, progress: 0, complete: false, reward: 400 },\n            { id: 4, title: \"4. Squish Zombies\", text: \"Crush 1 green alien zombie under your tracks\", type: \"zombies_slain\", target: 1, progress: 0, complete: false, reward: 500 },\n            { id: 5, title: \"5. Deliver Treasure\", text: \"Deliver 1 buried treasure/relic to the launchpad at (0, -15)\", type: \"deliver\", target: 1, progress: 0, complete: false, reward: 600 },\n            \n            { id: 6, title: \"6. Deeper Digging\", text: \"Dig down to a depth of 1.0 meter\", type: \"dig\", target: 1.0, progress: 0, complete: false, reward: 700 },\n            { id: 7, title: \"7. Accumulate Funds\", text: \"Acquire 3,000 Credits\", type: \"credits\", target: 3000, progress: 0, complete: false, reward: 800 },\n            { id: 8, title: \"8. Fight Back\", text: \"Splat or squash 1 alien zombie\", type: \"zombies_slain\", target: 1, progress: 0, complete: false, reward: 900 },\n            { id: 9, title: \"9. Nest Demolition\", text: \"Smash and destroy 1 alien nest hive with your bucket\", type: \"bases_destroyed\", target: 1, progress: 0, complete: false, reward: 1000 },\n            { id: 10, title: \"10. Energy Transporter\", text: \"Deliver 1 buried treasure to the launchpad\", type: \"deliver\", target: 1, progress: 0, complete: false, reward: 1100 },\n            \n            { id: 11, title: \"11. Search Deeper\", text: \"Dig down to a depth of 1.5 meters\", type: \"dig\", target: 1.5, progress: 0, complete: false, reward: 1200 },\n            { id: 12, title: \"12. Wealth Growth\", text: \"Acquire 15,000 Credits\", type: \"credits\", target: 15000, progress: 0, complete: false, reward: 1300 },\n            { id: 13, title: \"13. Zombie Sweeper\", text: \"Splat or squash 2 alien zombies\", type: \"zombies_slain\", target: 2, progress: 0, complete: false, reward: 1400 },\n            { id: 14, title: \"14. Clear Threat\", text: \"Destroy 1 alien hive nest\", type: \"bases_destroyed\", target: 1, progress: 0, complete: false, reward: 1500 },\n            { id: 15, title: \"15. Synthesis Materials\", text: \"Deliver 2 buried treasures to the launchpad\", type: \"deliver\", target: 2, progress: 0, complete: false, reward: 1600 },\n            \n            { id: 16, title: \"16. Underground Exploration\", text: \"Dig down to a depth of 2.0 meters\", type: \"dig\", target: 2.0, progress: 0, complete: false, reward: 1700 },\n            { id: 17, title: \"17. High Earner\", text: \"Acquire 40,000 Credits\", type: \"credits\", target: 40000, progress: 0, complete: false, reward: 1800 },\n            { id: 18, title: \"18. Security Protocol\", text: \"Eliminate 2 alien zombies\", type: \"zombies_slain\", target: 2, progress: 0, complete: false, reward: 1900 },\n            { id: 19, title: \"19. Base Expansion\", text: \"Destroy 1 alien hive nest\", type: \"bases_destroyed\", target: 1, progress: 0, complete: false, reward: 2000 },\n            { id: 20, title: \"20. Rebuild Titan\", text: \"Deliver 2 treasures or Titan parts to the launchpad\", type: \"deliver\", target: 2, progress: 0, complete: false, reward: 2100 },\n            \n            { id: 21, title: \"21. Core Excavation\", text: \"Dig down to a depth of 2.5 meters\", type: \"dig\", target: 2.5, progress: 0, complete: false, reward: 2200 },\n            { id: 22, title: \"22. Mining Tycoon\", text: \"Acquire 80,000 Credits\", type: \"credits\", target: 80000, progress: 0, complete: false, reward: 2300 },\n            { id: 23, title: \"23. Sector Purge\", text: \"Eliminate 2 alien zombies\", type: \"zombies_slain\", target: 2, progress: 0, complete: false, reward: 2400 },\n            { id: 24, title: \"24. Eradicate\", text: \"Destroy 1 alien hive nest\", type: \"bases_destroyed\", target: 1, progress: 0, complete: false, reward: 2500 },\n            { id: 25, title: \"25. Advanced Delivery\", text: \"Deliver 3 buried treasures to the launchpad\", type: \"deliver\", target: 3, progress: 0, complete: false, reward: 2600 },\n            \n            { id: 26, title: \"26. Ultimate Depth\", text: \"Dig down to a depth of 3.0 meters\", type: \"dig\", target: 3.0, progress: 0, complete: false, reward: 2700 },\n            { id: 27, title: \"27. Cosmic Billionaire\", text: \"Acquire 150,000 Credits\", type: \"credits\", target: 150000, progress: 0, complete: false, reward: 2800 },\n            { id: 28, title: \"28. Swarm Purge\", text: \"Eliminate 3 alien zombies\", type: \"zombies_slain\", target: 3, progress: 0, complete: false, reward: 2900 },\n            { id: 29, title: \"29. Perfect Delivery\", text: \"Deliver 3 buried treasures to the launchpad\", type: \"deliver\", target: 3, progress: 0, complete: false, reward: 3000 },\n            { id: 30, title: \"30. Grand Launch\", text: \"Accumulate 300,000 Credits to launch the rocket\", type: \"credits\", target: 300000, progress: 0, complete: false, reward: 5000 }\n        ];\n        let currentMissionIdx = 0; // index of active mission (0 to 29)\n        let zombiesSlainCount = 0;\n        let basesDestroyedCount = 0;\n        let totalRotation = 0;\n        let maxDigDepth = 0;\n\n        // ===== TREASURE SYSTEM =====\n        // treasures array declared earlier to avoid temporal dead zone in updateTerrainGeometry\n        // Create rough, uncut organic geometries for raw ores\n        function createRoughOreGeometry(radius) {\n            const geom = new THREE.DodecahedronGeometry(radius, 1);\n            const pos = geom.attributes.position;\n            for (let i = 0; i < pos.count; i++) {\n                const x = pos.getX(i);\n                const y = pos.getY(i);\n                const z = pos.getZ(i);\n                // Apply irregular noise to vertices to remove clean cuts/facets\n                const jitter = radius * 0.25;\n                pos.setXYZ(\n                    i,\n                    x + (Math.random() - 0.5) * jitter,\n                    y + (Math.random() - 0.5) * jitter,\n                    z + (Math.random() - 0.5) * jitter\n                );\n            }\n            geom.computeVertexNormals();\n            return geom;\n        }\n\n        // Create a multi-part compound 3D group for highly volumetric raw ores and ancient relics\n        function createTreasureGroup(typeInfo) {\n            const group = new THREE.Group();\n            const id = typeInfo.id;\n            \n            // Core materials\n            const shinyMat = new THREE.MeshPhongMaterial({\n                color: typeInfo.color,\n                emissive: typeInfo.color,\n                emissiveIntensity: 0.6,\n                shininess: 90,\n                specular: 0xffffff,\n                flatShading: true\n            });\n            const secondaryMat = new THREE.MeshPhongMaterial({\n                color: 0x333333,\n                shininess: 30\n            });\n\n            if (id.startsWith('titan_')) {\n                // Return a beautiful, high-tech, glowing robotic part mesh!\n                const partArmorMat = new THREE.MeshPhongMaterial({\n                    color: 0x333d45,\n                    specular: 0xcccccc,\n                    shininess: 90,\n                    flatShading: true\n                });\n                const partGlowMat = new THREE.MeshPhongMaterial({\n                    color: typeInfo.color,\n                    emissive: typeInfo.color,\n                    emissiveIntensity: 1.5,\n                    shininess: 100\n                });\n\n                if (id.includes('leg')) {\n                    const foot = new THREE.Mesh(new THREE.BoxGeometry(0.8, 0.3, 1.0), partArmorMat);\n                    foot.castShadow = true;\n                    group.add(foot);\n                    const ankle = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.2, 0.8), partGlowMat);\n                    ankle.position.y = 0.4;\n                    ankle.castShadow = true;\n                    group.add(ankle);\n                } else if (id.includes('torso')) {\n                    const chest = new THREE.Mesh(new THREE.BoxGeometry(1.0, 0.8, 0.6), partArmorMat);\n                    chest.castShadow = true;\n                    group.add(chest);\n                    const core = new THREE.Mesh(new THREE.SphereGeometry(0.3, 8, 8), partGlowMat);\n                    core.position.z = 0.35;\n                    group.add(core);\n                } else if (id.includes('arm')) {\n                    const forearm = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.2, 1.0), partArmorMat);\n                    forearm.castShadow = true;\n                    group.add(forearm);\n                    const claw = new THREE.Mesh(new THREE.ConeGeometry(0.3, 0.5, 4), partGlowMat);\n                    claw.position.y = -0.6;\n                    claw.rotation.x = Math.PI;\n                    claw.castShadow = true;\n                    group.add(claw);\n                } else if (id.includes('head')) {\n                    const helm = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.6, 0.6), partArmorMat);\n                    helm.castShadow = true;\n                    group.add(helm);\n                    const eye = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.12, 0.15), partGlowMat);\n                    eye.position.set(0, 0.1, 0.3);\n                    group.add(eye);\n                }\n                return group;\n            }\n            \n            if (id === 'ruby' || id === 'gold' || id === 'crystal' || id === 'emerald') {\n                const piecesCount = 3 + Math.floor(Math.random() * 3); // 3 to 5 overlapping pieces\n                for (let i = 0; i < piecesCount; i++) {\n                    const isCore = (i === 0);\n                    const sizeFactor = isCore ? 1.0 : (0.45 + Math.random() * 0.45);\n                    const radius = 0.45 * sizeFactor;\n                    const geom = createRoughOreGeometry(radius);\n                    const mesh = new THREE.Mesh(geom, shinyMat);\n                    mesh.castShadow = true;\n                    mesh.receiveShadow = true;\n                    \n                    if (!isCore) {\n                        mesh.position.set(\n                            (Math.random() - 0.5) * 0.45,\n                            (Math.random() - 0.5) * 0.45,\n                            (Math.random() - 0.5) * 0.45\n                        );\n                        mesh.rotation.set(\n                            Math.random() * Math.PI,\n                            Math.random() * Math.PI,\n                            Math.random() * Math.PI\n                        );\n                    }\n                    group.add(mesh);\n                }\n            } else if (id === 'statue') {\n                const base = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.15, 0.5), shinyMat);\n                base.position.y = -0.3;\n                group.add(base);\n                const body = new THREE.Mesh(new THREE.CylinderGeometry(0.18, 0.24, 0.5, 6), shinyMat);\n                body.position.y = 0.025;\n                group.add(body);\n                const head = new THREE.Mesh(new THREE.BoxGeometry(0.25, 0.32, 0.25), shinyMat);\n                head.position.y = 0.4;\n                group.add(head);\n                const nose = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.12, 0.08), secondaryMat);\n                nose.position.set(0, 0.4, 0.14);\n                group.add(nose);\n            } else if (id === 'chest') {\n                const chestBase = new THREE.Mesh(new THREE.BoxGeometry(0.7, 0.45, 0.45), shinyMat);\n                chestBase.position.y = -0.1;\n                group.add(chestBase);\n                const lid = new THREE.Mesh(new THREE.BoxGeometry(0.72, 0.22, 0.47), secondaryMat);\n                lid.position.y = 0.235;\n                group.add(lid);\n                const lock = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.12, 0.04), shinyMat);\n                lock.position.set(0, 0.12, 0.25);\n                group.add(lock);\n            } else if (id === 'plate') {\n                const plate = new THREE.Mesh(new THREE.CylinderGeometry(0.45, 0.45, 0.06, 12), shinyMat);\n                plate.rotation.x = Math.PI / 2;\n                group.add(plate);\n                const core = new THREE.Mesh(new THREE.CylinderGeometry(0.22, 0.22, 0.08, 12), secondaryMat);\n                core.rotation.x = Math.PI / 2;\n                group.add(core);\n            } else if (id === 'crown') {\n                const rim = new THREE.Mesh(new THREE.CylinderGeometry(0.35, 0.35, 0.15, 12, 1, true), shinyMat);\n                group.add(rim);\n                for (let i = 0; i < 6; i++) {\n                    const angle = (i / 6) * Math.PI * 2;\n                    const spike = new THREE.Mesh(new THREE.ConeGeometry(0.06, 0.2, 4), shinyMat);\n                    spike.position.set(Math.sin(angle) * 0.35, 0.15, Math.cos(angle) * 0.35);\n                    group.add(spike);\n                }\n                const gem = new THREE.Mesh(new THREE.DodecahedronGeometry(0.1, 0), secondaryMat);\n                gem.position.y = 0.04;\n                group.add(gem);\n            } else if (id === 'sword') {\n                const blade = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.8, 0.02), shinyMat);\n                blade.position.y = 0.15;\n                group.add(blade);\n                const guard = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.05, 0.05), secondaryMat);\n                guard.position.y = -0.22;\n                group.add(guard);\n                const handle = new THREE.Mesh(new THREE.CylinderGeometry(0.035, 0.035, 0.2, 6), secondaryMat);\n                handle.position.y = -0.35;\n                group.add(handle);\n            } else if (id === 'vase') {\n                const body = new THREE.Mesh(new THREE.SphereGeometry(0.3, 12, 12), shinyMat);\n                group.add(body);\n                const neck = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.15, 0.25, 10), shinyMat);\n                neck.position.y = 0.35;\n                group.add(neck);\n                const rim = new THREE.Mesh(new THREE.CylinderGeometry(0.18, 0.18, 0.05, 10), secondaryMat);\n                rim.position.y = 0.48;\n                group.add(rim);\n            } else if (id === 'chalice') {\n                const cup = new THREE.Mesh(new THREE.CylinderGeometry(0.28, 0.12, 0.35, 10), shinyMat);\n                cup.position.y = 0.15;\n                group.add(cup);\n                const stem = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, 0.25, 8), secondaryMat);\n                stem.position.y = -0.12;\n                group.add(stem);\n                const base = new THREE.Mesh(new THREE.CylinderGeometry(0.22, 0.22, 0.06, 10), shinyMat);\n                base.position.y = -0.26;\n                group.add(base);\n            } else if (id === 'tablet') {\n                const tablet = new THREE.Mesh(new THREE.BoxGeometry(0.45, 0.65, 0.1), shinyMat);\n                group.add(tablet);\n                const line1 = new THREE.Mesh(new THREE.BoxGeometry(0.25, 0.03, 0.12), secondaryMat);\n                line1.position.set(0, 0.18, 0.01);\n                group.add(line1);\n                const line2 = new THREE.Mesh(new THREE.BoxGeometry(0.18, 0.03, 0.12), secondaryMat);\n                line2.position.set(-0.03, 0, 0.01);\n                group.add(line2);\n                const line3 = new THREE.Mesh(new THREE.BoxGeometry(0.22, 0.03, 0.12), secondaryMat);\n                line3.position.set(0.01, -0.18, 0.01);\n                group.add(line3);\n            } else if (id === 'ring') {\n                const band = new THREE.Mesh(new THREE.CylinderGeometry(0.28, 0.28, 0.12, 10, 1, true), secondaryMat);\n                band.rotation.x = Math.PI / 2;\n                group.add(band);\n                const gem = new THREE.Mesh(new THREE.DodecahedronGeometry(0.15, 0), shinyMat);\n                gem.position.set(0, 0.3, 0);\n                group.add(gem);\n            } else if (id === 'key') {\n                const shaft = new THREE.Mesh(new THREE.CylinderGeometry(0.035, 0.035, 0.6, 8), shinyMat);\n                shaft.position.y = -0.08;\n                group.add(shaft);\n                const head = new THREE.Mesh(new THREE.CylinderGeometry(0.18, 0.18, 0.05, 8, 1, true), shinyMat);\n                head.rotation.x = Math.PI / 2;\n                head.position.y = 0.25;\n                group.add(head);\n                const tooth1 = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.06, 0.05), shinyMat);\n                tooth1.position.set(0.08, -0.3, 0);\n                group.add(tooth1);\n                const tooth2 = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.06, 0.05), shinyMat);\n                tooth2.position.set(0.08, -0.18, 0);\n                group.add(tooth2);\n            }\n            \n            return group;\n        }\n\n        const titanPartsList = [\n            { id: 'titan_l_leg', name: 'Titan Left Leg', color: 0xff5500, score: 500, emoji: '\ud83e\uddbf', x: -25, z: -10, depth: 3.5, isTitanPart: true },\n            { id: 'titan_r_leg', name: 'Titan Right Leg', color: 0xff5500, score: 500, emoji: '\ud83e\uddbf', x: 25, z: 15, depth: 4.0, isTitanPart: true },\n            { id: 'titan_torso', name: 'Titan Power Torso', color: 0x00ffcc, score: 800, emoji: '\ud83d\udee1\ufe0f', x: -10, z: 25, depth: 5.5, isTitanPart: true },\n            { id: 'titan_l_arm', name: 'Titan Left Arm', color: 0xaa00ff, score: 600, emoji: '\ud83e\uddbe', x: 20, z: -20, depth: 4.5, isTitanPart: true },\n            { id: 'titan_r_arm', name: 'Titan Right Arm', color: 0xaa00ff, score: 600, emoji: '\ud83e\uddbe', x: -5, z: -30, depth: 5.0, isTitanPart: true },\n            { id: 'titan_head', name: 'Titan Neural Head', color: 0xffff00, score: 1000, emoji: '\ud83e\udd16', x: 15, z: 30, depth: 6.0, isTitanPart: true }\n        ];\n\n        function spawnTreasures() {\n            // 1. Spawn Titan Parts first at fixed coordinates\n            titanPartsList.forEach((tp, idx) => {\n                const terrainHeightAtPos = getTerrainHeight(tp.x, tp.z);\n                const y = terrainHeightAtPos - tp.depth;\n\n                // Create custom mesh group for Titan parts\n                const partGroup = createTreasureGroup(tp);\n                partGroup.position.set(tp.x, y, tp.z);\n                partGroup.rotation.set(Math.random() * 0.4, Math.random() * Math.PI, Math.random() * 0.4);\n                partGroup.scale.set(0.8, 0.8, 0.8);\n\n                scene.add(partGroup);\n\n                treasures.push({\n                    id: 'titan_' + idx,\n                    x: tp.x,\n                    y: y,\n                    z: tp.z,\n                    type: tp,\n                    score: tp.score,\n                    mesh: partGroup,\n                    ringMesh: null,\n                    discMesh: null,\n                    buriedY: y,\n                    depth: tp.depth,\n                    exposed: false,\n                    scooped: false,\n                    collected: false,\n                    isTitanPart: true\n                });\n            });\n\n            // 2. Spawn 24 regular gemstones\n            const count = 24;\n            for (let i = 0; i < count; i++) {\n                const x = (Math.random() - 0.5) * 85;\n                const z = (Math.random() - 0.5) * 85;\n                \n                if (Math.sqrt(x*x + z*z) < 5) continue;\n\n                const terrainHeightAtPos = getTerrainHeight(x, z);\n                \n                let depth;\n                const r = Math.random();\n                if (r < 0.05) {\n                    depth = 0.5 + Math.random() * 2.5;\n                } else if (r < 0.30) {\n                    depth = 3.0 + Math.random() * 5.0;\n                } else {\n                    depth = 8.0 + Math.random() * 8.0;\n                }\n                const y = terrainHeightAtPos - depth;\n\n                const typeInfo = treasureTypes[Math.floor(Math.random() * treasureTypes.length)];\n                \n                const gemGroup = createTreasureGroup(typeInfo);\n                gemGroup.position.set(x, y, z);\n                gemGroup.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI);\n                \n                const depthScaleFactor = 0.5 + (depth / 16.0) * 1.5;\n                const randScale = 0.53 * (0.8 + Math.random() * 0.4) * depthScaleFactor;\n                gemGroup.scale.set(randScale, randScale * (0.9 + Math.random() * 0.3), randScale);\n                \n                scene.add(gemGroup);\n\n                treasures.push({\n                    id: i,\n                    x, y, z,\n                    type: typeInfo,\n                    score: typeInfo.score, // Match base score exactly to resolve user request\n                    mesh: gemGroup,\n                    ringMesh: null,\n                    discMesh: null,\n                    buriedY: y,\n                    depth: depth,\n                    exposed: false,\n                    scooped: false,\n                    collected: false,\n                    isTitanPart: false\n                });\n            }\n        }\n        spawnTreasures();\n        spawnSandworms();\n        spawnLandmines();\n        updateTerrainGeometry();\n\n        // ===== ALIEN ZOMBIE SYSTEM =====\n        const zombies = [];\n        const zombieBases = [];\n        let zombieSpawnReductionTimer = 0; // Cooldown timer in seconds when a base is destroyed\n        let zombieSpawnTimer = 0; // Timer to control zombie spawning at 15-second intervals\n\n        function createZombieBaseMesh(x, z, y) {\n            const baseGroup = new THREE.Group();\n            baseGroup.position.set(x, y, z);\n\n            // Alien hive core (pulsating organic glowing dome)\n            const coreGeo = new THREE.DodecahedronGeometry(1.8, 1);\n            const coreMat = new THREE.MeshPhongMaterial({\n                color: 0x00ff66,\n                emissive: 0x0a4a1a,\n                emissiveIntensity: 1.5,\n                shininess: 50,\n                flatShading: true\n            });\n            const core = new THREE.Mesh(coreGeo, coreMat);\n            core.position.y = 0.8;\n            core.castShadow = true;\n            core.receiveShadow = true;\n            baseGroup.add(core);\n\n            // Spikes/pods surrounding the core\n            const spikeGeo = new THREE.ConeGeometry(0.3, 1.2, 5);\n            const spikeMat = new THREE.MeshPhongMaterial({ color: 0x4a1a6a, shininess: 30 }); // Deep alien purple\n            for (let i = 0; i < 6; i++) {\n                const angle = (i / 6) * Math.PI * 2;\n                const spike = new THREE.Mesh(spikeGeo, spikeMat);\n                spike.position.set(Math.sin(angle) * 1.5, 0.5, Math.cos(angle) * 1.5);\n                spike.rotation.x = Math.PI / 4;\n                spike.rotation.z = -angle;\n                spike.castShadow = true;\n                baseGroup.add(spike);\n            }\n\n            // Health bar UI elements inside 3D\n            const hpBgGeo = new THREE.BoxGeometry(2.0, 0.15, 0.05);\n            const hpBgMat = new THREE.MeshBasicMaterial({ color: 0x333333 });\n            const hpBg = new THREE.Mesh(hpBgGeo, hpBgMat);\n            hpBg.position.set(0, 3.2, 0);\n            baseGroup.add(hpBg);\n\n            const hpBarGeo = new THREE.BoxGeometry(1.98, 0.11, 0.06);\n            const hpBarMat = new THREE.MeshBasicMaterial({ color: 0x00ff66 });\n            const hpBar = new THREE.Mesh(hpBarGeo, hpBarMat);\n            hpBar.position.set(0, 3.2, 0.01);\n            baseGroup.add(hpBar);\n\n            return { group: baseGroup, core, hpBar, hpBg };\n        }\n\n        function spawnZombieBases() {\n            const positions = [\n                { x: -28, z: -28 },\n                { x: 28, z: 28 },\n                { x: -32, z: 22 }\n            ];\n\n            positions.forEach((pos, idx) => {\n                const y = getTerrainHeight(pos.x, pos.z);\n                const baseData = createZombieBaseMesh(pos.x, pos.z, y);\n                scene.add(baseData.group);\n\n                zombieBases.push({\n                    id: idx,\n                    x: pos.x,\n                    z: pos.z,\n                    y: y,\n                    hp: 100,\n                    maxHp: 100,\n                    destroyed: false,\n                    respawnTimer: 0,\n                    hitCooldown: 0,\n                    meshGroup: baseData.group,\n                    coreMesh: baseData.core,\n                    hpBar: baseData.hpBar,\n                    hpBg: baseData.hpBg\n                });\n            });\n        }\n        spawnZombieBases();\n\n        function spawnZombie() {\n            const activeZombies = zombies.filter(z => z.state === 'alive');\n            if (activeZombies.length >= 8) return; // Limit total active zombies to 8\n\n            // Spawn at some distance from excavator\n            const angle = Math.random() * Math.PI * 2;\n            const dist = 30 + Math.random() * 15;\n            const zx = excState.x + Math.sin(angle) * dist;\n            const zz = excState.z + Math.cos(angle) * dist;\n\n            // Make sure zombie spawns on terrain\n            const zy = getTerrainHeight(zx, zz);\n\n            // Create a cute mini green alien zombie group\n            const zGroup = new THREE.Group();\n            \n            // Zombie Head (green sphere with glowing red eyes)\n            const headGeo = new THREE.SphereGeometry(0.35, 8, 8);\n            const headMat = new THREE.MeshPhongMaterial({ color: 0x39ff14, shininess: 30 }); // toxic green\n            const head = new THREE.Mesh(headGeo, headMat);\n            head.position.y = 0.6;\n            zGroup.add(head);\n\n            // Glowing red eyes\n            const eyeGeo = new THREE.SphereGeometry(0.08, 4, 4);\n            const eyeMat = new THREE.MeshBasicMaterial({ color: 0xff0000 });\n            const eyeL = new THREE.Mesh(eyeGeo, eyeMat);\n            eyeL.position.set(-0.12, 0.65, 0.28);\n            zGroup.add(eyeL);\n            const eyeR = new THREE.Mesh(eyeGeo, eyeMat);\n            eyeR.position.set(0.12, 0.65, 0.28);\n            zGroup.add(eyeR);\n\n            // Body\n            const bodyGeo = new THREE.CylinderGeometry(0.2, 0.25, 0.5, 8);\n            const bodyMat = new THREE.MeshPhongMaterial({ color: 0x228b22 });\n            const body = new THREE.Mesh(bodyGeo, bodyMat);\n            body.position.y = 0.25;\n            zGroup.add(body);\n\n            // Tiny arms reaching forward (Z-direction)\n            const armGeo = new THREE.BoxGeometry(0.08, 0.08, 0.35);\n            const armL = new THREE.Mesh(armGeo, headMat);\n            armL.position.set(-0.25, 0.45, 0.15);\n            zGroup.add(armL);\n            const armR = new THREE.Mesh(armGeo, headMat);\n            armR.position.set(0.25, 0.45, 0.15);\n            zGroup.add(armR);\n\n            // Assemble and position group\n            zGroup.position.set(zx, zy, zz);\n            scene.add(zGroup);\n\n            zombies.push({\n                mesh: zGroup,\n                armL: armL,\n                armR: armR,\n                x: zx,\n                z: zz,\n                y: zy,\n                speed: 1.5 + Math.random() * 1.5,\n                state: 'alive', // 'alive' or 'dead'\n                deadTimer: 0,\n                interfereTimer: 0,\n                bobTimer: Math.random() * 10\n            });\n        }\n\n        function spawnBomberZombie() {\n            const activeZombies = zombies.filter(z => z.state === 'alive');\n            if (activeZombies.length >= 8) return; // Limit total active zombies\n\n            // Spawn at some distance from excavator\n            const angle = Math.random() * Math.PI * 2;\n            const dist = 32 + Math.random() * 12;\n            const zx = excState.x + Math.sin(angle) * dist;\n            const zz = excState.z + Math.cos(angle) * dist;\n\n            // Make sure zombie spawns on terrain\n            const zy = getTerrainHeight(zx, zz);\n\n            // Create a slightly larger alien zombie group (1.4x normal size)\n            const zGroup = new THREE.Group();\n            \n            // Zombie Head (cyan-green sphere with glowing orange eyes)\n            const headGeo = new THREE.SphereGeometry(0.35, 8, 8);\n            const headMat = new THREE.MeshPhongMaterial({ color: 0x00ffcc, shininess: 40 }); // Cyan/Teal toxic green\n            const head = new THREE.Mesh(headGeo, headMat);\n            head.position.y = 0.6;\n            zGroup.add(head);\n\n            // Glowing orange eyes\n            const eyeGeo = new THREE.SphereGeometry(0.08, 4, 4);\n            const eyeMat = new THREE.MeshBasicMaterial({ color: 0xffaa00 });\n            const eyeL = new THREE.Mesh(eyeGeo, eyeMat);\n            eyeL.position.set(-0.12, 0.65, 0.28);\n            zGroup.add(eyeL);\n            const eyeR = new THREE.Mesh(eyeGeo, eyeMat);\n            eyeR.position.set(0.12, 0.65, 0.28);\n            zGroup.add(eyeR);\n\n            // Body\n            const bodyGeo = new THREE.CylinderGeometry(0.2, 0.25, 0.5, 8);\n            const bodyMat = new THREE.MeshPhongMaterial({ color: 0x008b8b }); // dark cyan\n            const body = new THREE.Mesh(bodyGeo, bodyMat);\n            body.position.y = 0.25;\n            zGroup.add(body);\n\n            // Left arm reaching forward\n            const armGeo = new THREE.BoxGeometry(0.08, 0.08, 0.35);\n            const armL = new THREE.Mesh(armGeo, headMat);\n            armL.position.set(-0.25, 0.45, 0.15);\n            zGroup.add(armL);\n\n            // Right arm carrying a bomb\n            const armR = new THREE.Mesh(armGeo, headMat);\n            armR.position.set(0.25, 0.45, 0.15);\n            zGroup.add(armR);\n\n            // The BOMB: a sphere with yellow flashing fuse\n            const bombGroup = new THREE.Group();\n            bombGroup.position.set(0.3, 0.35, 0.35); // near right arm\n\n            const bombSphereGeo = new THREE.SphereGeometry(0.25, 8, 8);\n            const bombSphereMat = new THREE.MeshPhongMaterial({ color: 0x2c3e50, specular: 0x999999, shininess: 50 });\n            const bombSphere = new THREE.Mesh(bombSphereGeo, bombSphereMat);\n            bombGroup.add(bombSphere);\n\n            // Glowing bomb fuse/wick\n            const fuseGeo = new THREE.CylinderGeometry(0.03, 0.03, 0.15, 4);\n            const fuseMat = new THREE.MeshPhongMaterial({ color: 0xffea00, emissive: 0xffaa00, emissiveIntensity: 1.0 });\n            const fuse = new THREE.Mesh(fuseGeo, fuseMat);\n            fuse.position.y = 0.28;\n            fuse.rotation.z = 0.3;\n            bombGroup.add(fuse);\n\n            // Glowing light on the bomb\n            const lightGeo = new THREE.SphereGeometry(0.06, 6, 6);\n            const lightMat = new THREE.MeshBasicMaterial({ color: 0xff3300 });\n            const light = new THREE.Mesh(lightGeo, lightMat);\n            light.position.set(0, 0, 0.22);\n            bombGroup.add(light);\n\n            zGroup.add(bombGroup);\n\n            // Scale up the entire bomber zombie (slightly larger than normal)\n            zGroup.scale.set(1.4, 1.4, 1.4);\n\n            // Assemble and position group\n            zGroup.position.set(zx, zy, zz);\n            scene.add(zGroup);\n\n            zombies.push({\n                mesh: zGroup,\n                armL: armL,\n                armR: armR,\n                x: zx,\n                z: zz,\n                y: zy,\n                speed: 1.8 + Math.random() * 0.8, // Slightly faster than normal\n                state: 'alive',\n                deadTimer: 0,\n                interfereTimer: 0,\n                bobTimer: Math.random() * 10,\n                isBomber: true,\n                bombLight: light,\n                bombLightMat: lightMat,\n                lastBlinkTime: 0,\n                blinkState: false\n            });\n        }\n\n        // Spawn some initial zombies\n        for (let j = 0; j < 4; j++) {\n            spawnZombie();\n        }\n        // Objective marker in 3D (Holographic targeting zone removed as requested)\n        const markerGroup = new THREE.Group();\n        let marker = null;\n\n        // ===== PARTICLE SYSTEM =====\n        const particles = [];\n        const particleGeo = new THREE.SphereGeometry(0.15, 4, 4);\n        const particleMat = new THREE.MeshLambertMaterial({ color: new THREE.Color(config.terrain.soilColor) });\n\n        // Soil color variants for multi-layer stratified look\n        const soilColorsList = [0x5c6b73, 0x415a77, 0x778da9, 0xe0e1dd, 0x3d5a80, 0x293241];\n\n        // Glowing scanning ring for high-tech terraforming effect\n        const digRingGeo = new THREE.RingGeometry(2.0, 2.2, 16);\n        digRingGeo.rotateX(-Math.PI / 2);\n        const digRingMat = new THREE.MeshBasicMaterial({ color: 0x00e5ff, side: THREE.DoubleSide, transparent: true, opacity: 0 });\n        const digRing = new THREE.Mesh(digRingGeo, digRingMat);\n        scene.add(digRing);\n\n        function spawnParticles(pos, count) {\n            const actualCount = currentGraphicsMode === 'low' ? Math.max(1, Math.floor(count * 0.5)) : count;\n            for (let i = 0; i < actualCount; i++) {\n                // Use random color from stratified layers for awesome aesthetic variety\n                const col = soilColorsList[Math.floor(Math.random() * soilColorsList.length)];\n                const customMat = new THREE.MeshLambertMaterial({ color: col, flatShading: true });\n                \n                // Create random geometric shapes for rock shards (box, sphere, dodecahedron)\n                let mesh;\n                const rType = Math.random();\n                if (rType < 0.3) {\n                    mesh = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.2, 0.2), customMat);\n                } else if (rType < 0.6) {\n                    mesh = new THREE.Mesh(new THREE.DodecahedronGeometry(0.15, 0), customMat);\n                } else {\n                    mesh = new THREE.Mesh(particleGeo, customMat);\n                }\n\n                mesh.position.copy(pos);\n                mesh.position.x += (Math.random() - 0.5) * 1.5;\n                mesh.position.z += (Math.random() - 0.5) * 1.5;\n                scene.add(mesh);\n                particles.push({\n                    mesh,\n                    vel: new THREE.Vector3((Math.random()-0.5)*3.5, Math.random()*4.5+1.5, (Math.random()-0.5)*3.5),\n                    life: 1.5\n                });\n            }\n        }\n\n        function updateParticles(dt) {\n            const gravity = config.physics.gravity * 9.8;\n            for (let i = particles.length - 1; i >= 0; i--) {\n                const p = particles[i];\n                p.vel.y -= gravity * dt;\n                p.mesh.position.add(p.vel.clone().multiplyScalar(dt));\n                p.life -= dt;\n                if (p.life <= 0) {\n                    scene.remove(p.mesh);\n                    particles.splice(i, 1);\n                }\n            }\n        }\n\n        // ===== TERRAIN HELPERS =====\n        function getTerrainHeight(worldX, worldZ) {\n            const gx = (worldX + TERRAIN_SIZE/2) / TERRAIN_SIZE * (TERRAIN_RES - 1);\n            const gz = (worldZ + TERRAIN_SIZE/2) / TERRAIN_SIZE * (TERRAIN_RES - 1);\n            const ix = Math.floor(gx), iz = Math.floor(gz);\n            if (ix < 0 || ix >= TERRAIN_RES-1 || iz < 0 || iz >= TERRAIN_RES-1) return 0;\n            const fx = gx - ix, fz = gz - iz;\n            const h00 = heightMap[iz][ix];\n            const h10 = heightMap[iz][ix+1];\n            const h01 = heightMap[iz+1][ix];\n            const h11 = heightMap[iz+1][ix+1];\n            return h00*(1-fx)*(1-fz) + h10*fx*(1-fz) + h01*(1-fx)*fz + h11*fx*fz;\n        }\n\n        function modifyTerrain(worldX, worldZ, amount, radius) {\n            const hardness = config.terrain.hardness;\n            const actualAmount = amount / hardness;\n            const gxCenter = (worldX + TERRAIN_SIZE/2) / TERRAIN_SIZE * (TERRAIN_RES - 1);\n            const gzCenter = (worldZ + TERRAIN_SIZE/2) / TERRAIN_SIZE * (TERRAIN_RES - 1);\n            const gridRadius = radius / TERRAIN_SIZE * (TERRAIN_RES - 1);\n\n            let modified = false;\n            for (let z = Math.max(0, Math.floor(gzCenter - gridRadius)); z <= Math.min(TERRAIN_RES-1, Math.ceil(gzCenter + gridRadius)); z++) {\n                for (let x = Math.max(0, Math.floor(gxCenter - gridRadius)); x <= Math.min(TERRAIN_RES-1, Math.ceil(gxCenter + gridRadius)); x++) {\n                    const dx = x - gxCenter, dz = z - gzCenter;\n                    const dist = Math.sqrt(dx*dx + dz*dz);\n                    if (dist < gridRadius) {\n                        const falloff = 1 - (dist / gridRadius);\n                        heightMap[z][x] += actualAmount * falloff;\n                        modified = true;\n                    }\n                }\n            }\n            if (modified) updateTerrainGeometry();\n            return modified;\n        }\n\n        // ===== AUDIO =====\n        let audioCtx = null;\n        const audioBuffers = {};\n\n        async function initAudio() {\n            try {\n                audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n            } catch(e) { }\n        }\n\n        async function loadAudio(id) {\n            if (!audioCtx) return;\n            try {\n                const asset = lib.getAsset(id);\n                if (!asset || asset.type !== 'audio') return;\n                const response = await fetch(asset.url);\n                const arrayBuffer = await response.arrayBuffer();\n                audioBuffers[id] = await audioCtx.decodeAudioData(arrayBuffer);\n            } catch(e) { }\n        }\n\n        function playSound(id, loop = false, volume = 0.5) {\n            if (!audioCtx || !audioBuffers[id]) return null;\n            if (audioCtx.state === 'suspended') audioCtx.resume();\n            const source = audioCtx.createBufferSource();\n            source.buffer = audioBuffers[id];\n            source.loop = loop;\n            const gain = audioCtx.createGain();\n            gain.gain.value = volume;\n            source.connect(gain);\n            gain.connect(audioCtx.destination);\n            source.start(0);\n            return { source, gain };\n        }\n\n        function playSynthBeep(frequency, duration) {\n            if (!audioCtx) return;\n            if (audioCtx.state === 'suspended') audioCtx.resume();\n            try {\n                const osc = audioCtx.createOscillator();\n                const gain = audioCtx.createGain();\n                osc.type = 'sine';\n                osc.frequency.setValueAtTime(frequency, audioCtx.currentTime);\n                gain.gain.setValueAtTime(0.25, audioCtx.currentTime);\n                gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration);\n                osc.connect(gain);\n                gain.connect(audioCtx.destination);\n                osc.start();\n                osc.stop(audioCtx.currentTime + duration);\n            } catch (e) {}\n        }\n\n        function playSynthExplosion() {\n            if (!audioCtx) return;\n            if (audioCtx.state === 'suspended') audioCtx.resume();\n            try {\n                // Low frequency boom\n                const osc = audioCtx.createOscillator();\n                const gain = audioCtx.createGain();\n                osc.type = 'triangle';\n                osc.frequency.setValueAtTime(120, audioCtx.currentTime);\n                osc.frequency.exponentialRampToValueAtTime(10, audioCtx.currentTime + 1.2);\n                \n                // Synth noise generator for explosion grit\n                const bufferSize = audioCtx.sampleRate * 1.5;\n                const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);\n                const data = buffer.getChannelData(0);\n                for (let i = 0; i < bufferSize; i++) {\n                    data[i] = Math.random() * 2 - 1;\n                }\n                const noise = audioCtx.createBufferSource();\n                noise.buffer = buffer;\n                \n                const filter = audioCtx.createBiquadFilter();\n                filter.type = 'lowpass';\n                filter.frequency.setValueAtTime(600, audioCtx.currentTime);\n                filter.frequency.exponentialRampToValueAtTime(15, audioCtx.currentTime + 1.2);\n                \n                const noiseGain = audioCtx.createGain();\n                noiseGain.gain.setValueAtTime(0.6, audioCtx.currentTime);\n                noiseGain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 1.4);\n                \n                gain.gain.setValueAtTime(0.9, audioCtx.currentTime);\n                gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 1.1);\n                \n                osc.connect(gain);\n                gain.connect(audioCtx.destination);\n                \n                noise.connect(filter);\n                filter.connect(noiseGain);\n                noiseGain.connect(audioCtx.destination);\n                \n                osc.start();\n                osc.stop(audioCtx.currentTime + 1.2);\n                \n                noise.start();\n                noise.stop(audioCtx.currentTime + 1.5);\n            } catch (e) {}\n        }\n\n        setLoadProgress(90, t('audioSync'));\n        await initAudio();\n        // Load audio assets\n        const audioIds = ['excavator_engine_sound', 'hydraulic_movement_sound', 'bucket_scoop_sound', 'dirt_dump_sound', 'objective_complete_sound', 'ambient_alien_wind'];\n        for (const id of audioIds) {\n            await loadAudio(id);\n        }\n\n        let engineSound = null;\n        let ambientSound = null;\n        let scoopSoundObj = null;\n        let dumpSoundObj = null;\n\n        // ===== INPUT HANDLING =====\n        const keys = {};\n        const touchState = {\n            leftJoy: { active: false, x: 0, y: 0, id: null },\n            rightJoy: { active: false, x: 0, y: 0, id: null },\n            drive: { fwd: false, back: false, left: false, right: false, cabL: false, cabR: false }\n        };\n\n        let lastSpaceAction = 'dump'; // starts with 'dump' so first press triggers 'dig'\n\n        document.addEventListener('keydown', e => { \n            keys[e.code] = true; \n            if (e.key) {\n                keys[e.key] = true;\n                keys[e.key.toLowerCase()] = true;\n                keys[e.key.toUpperCase()] = true;\n            }\n            if (e.code === 'Space') {\n                e.preventDefault();\n                if (mode === 'play' && !isModalOpen) {\n                    if (lastSpaceAction === 'dump') {\n                        triggerAutoDig();\n                        lastSpaceAction = 'dig';\n                    } else {\n                        triggerAutoDump();\n                        lastSpaceAction = 'dump';\n                    }\n                }\n            }\n        });\n        document.addEventListener('keyup', e => { \n            keys[e.code] = false; \n            if (e.key) {\n                keys[e.key] = false;\n                keys[e.key.toLowerCase()] = false;\n                keys[e.key.toUpperCase()] = false;\n            }\n        });\n\n        // Ensure iframe window has focus so keyboard events are caught immediately\n        window.addEventListener('mousedown', () => window.focus());\n        window.addEventListener('touchstart', () => window.focus());\n        \n        // Prevent accidental text selection and context menus globally, especially on long press\n        document.addEventListener('selectstart', e => e.preventDefault());\n        document.addEventListener('contextmenu', e => e.preventDefault());\n\n        // ===== UI =====\n        const overlay = document.createElement('div');\n        overlay.className = 'ui-overlay';\n        gameWorld.appendChild(overlay);\n\n        let currentControlMode = 'simple'; // Simple Mode (Option A) is default\n\n        if (mode === 'play') {\n            // Cinematic Tutorial Overlay\n            const cinematicOverlay = document.createElement('div');\n            cinematicOverlay.id = 'cinematic-overlay';\n            cinematicOverlay.style.cssText = `\n                position: absolute;\n                top: 0;\n                left: 0;\n                width: 100%;\n                height: 100%;\n                background: rgba(0, 0, 0, 0.4);\n                pointer-events: auto;\n                z-index: 15000;\n                display: flex;\n                flex-direction: column;\n                justify-content: space-between;\n                padding: var(--space-md) var(--space-sm);\n                box-sizing: border-box;\n                font-family: 'Inter', sans-serif;\n            `;\n            cinematicOverlay.innerHTML = `\n                <!-- Top banner with skip button -->\n                <div style=\"display: flex; justify-content: space-between; align-items: center; width: 100%;\">\n                    <div style=\"font-family: 'Orbitron', sans-serif; font-size: 14px; font-weight: bold; color: var(--color-primary); text-shadow: 0 0 10px rgba(0, 229, 255, 0.5); letter-spacing: 2px;\">\n                        ${t('cineOverview')}\n                    </div>\n                    <button id=\"cine-skip-btn\" style=\"\n                        background: #e11d48;\n                        border: none;\n                        color: #fff;\n                        padding: 8px 16px;\n                        border-radius: 8px;\n                        font-family: 'Orbitron', sans-serif;\n                        font-size: 12px;\n                        font-weight: 900;\n                        cursor: pointer;\n                        box-shadow: 0 4px 0 #9f1239, 0 6px 12px rgba(0,0,0,0.5);\n                        transform: translateY(-2px);\n                        transition: transform 0.05s, box-shadow 0.05s;\n                    \">\n                        ${t('skip')}\n                    </button>\n                </div>\n\n                <!-- Center/Bottom Caption Box -->\n                <div style=\"\n                    background: rgba(10, 25, 45, 0.95);\n                    border: 3px solid var(--color-primary);\n                    box-shadow: 0 0 25px rgba(0, 229, 255, 0.5);\n                    border-radius: 16px;\n                    width: 100%;\n                    max-width: 600px;\n                    margin: 0 auto;\n                    padding: 20px;\n                    box-sizing: border-box;\n                    color: #fff;\n                    display: flex;\n                    flex-direction: column;\n                    gap: 12px;\n                \">\n                    <h3 id=\"cine-title\" style=\"\n                        font-family: 'Orbitron', sans-serif;\n                        color: var(--color-primary);\n                        margin: 0;\n                        font-size: 20px;\n                        letter-spacing: 1.5px;\n                        text-shadow: 0 0 10px rgba(0, 229, 255, 0.4);\n                        text-align: center;\n                    \"></h3>\n                    \n                    <p id=\"cine-desc\" style=\"\n                        margin: 0;\n                        font-size: 14px;\n                        line-height: 1.5;\n                        color: #cbd5e1;\n                        text-align: center;\n                    \"></p>\n\n                    <!-- Navigation Buttons -->\n                    <div style=\"display: flex; justify-content: space-between; align-items: center; margin-top: 8px; gap: 12px;\">\n                        <div id=\"cine-step-dots\" style=\"display: flex; gap: 6px;\"></div>\n                        \n                        <button id=\"cine-next-btn\" style=\"\n                            background: #ff6d00;\n                            border: none;\n                            border-radius: 10px;\n                            color: #fff;\n                            font-family: 'Orbitron', sans-serif;\n                            font-weight: 900;\n                            font-size: 14px;\n                            padding: 10px 24px;\n                            cursor: pointer;\n                            box-shadow: 0 6px 0 #b34a00, 0 8px 16px rgba(0, 0, 0, 0.6);\n                            transform: translateY(-4px);\n                            transition: transform 0.05s, box-shadow 0.05s;\n                        \">\n                            ${t('next')}\n                        </button>\n                    </div>\n                </div>\n            `;\n            \n            overlay.appendChild(cinematicOverlay);\n            isModalOpen = true; // prevent controls activity\n\n            updateCinematicOverlay = function() {\n                const step = cinematicSteps[cinematicStep];\n                if (!step) return;\n\n                const titleEl = document.getElementById('cine-title');\n                const descEl = document.getElementById('cine-desc');\n                if (titleEl) titleEl.innerHTML = t(step.titleKey);\n                if (descEl) descEl.innerHTML = t(step.descKey);\n\n                // Step dots\n                const dotsContainer = document.getElementById('cine-step-dots');\n                if (dotsContainer) {\n                    dotsContainer.innerHTML = '';\n                    for (let i = 0; i < cinematicSteps.length; i++) {\n                        const dot = document.createElement('div');\n                        dot.style.width = '10px';\n                        dot.style.height = '10px';\n                        dot.style.borderRadius = '50%';\n                        dot.style.background = (i === cinematicStep) ? 'var(--color-primary)' : 'rgba(255, 255, 255, 0.2)';\n                        dot.style.boxShadow = (i === cinematicStep) ? '0 0 8px var(--color-primary)' : 'none';\n                        dotsContainer.appendChild(dot);\n                    }\n                }\n\n                // Change next btn text\n                const nextBtn = document.getElementById('cine-next-btn');\n                if (nextBtn) {\n                    nextBtn.innerHTML = (cinematicStep === cinematicSteps.length - 1) ? t('startExploring') : t('next');\n                }\n            }\n\n            // Wire up buttons\n            setTimeout(() => {\n                const skipBtn = document.getElementById('cine-skip-btn');\n                if (skipBtn) {\n                    skipBtn.addEventListener('click', endCinematic);\n                    skipBtn.addEventListener('touchstart', (e) => { e.preventDefault(); endCinematic(); });\n                }\n\n                const nextBtn = document.getElementById('cine-next-btn');\n                if (nextBtn) {\n                    nextBtn.addEventListener('click', nextCinematicStep);\n                    nextBtn.addEventListener('touchstart', (e) => { e.preventDefault(); nextCinematicStep(); });\n                }\n\n                updateCinematicOverlay();\n            }, 100);\n\n            // HUD\n            const hudTop = document.createElement('div');\n            hudTop.className = 'hud-top';\n            hudTop.innerHTML = `\n                <div class=\"hud-panel\"><div class=\"label\">${t('depth')}</div><span id=\"depth\">0.0</span>m</div>\n                <div class=\"hud-panel\" id=\"credits-panel\" style=\"border-color: #ffd700; box-shadow: 0 0 10px rgba(255, 215, 0, 0.3);\">\n                    <div class=\"label\" style=\"color: #ffd700;\">${t('credits')}</div>\n                    <span id=\"credits\">0</span>\n                    <div style=\"font-size: 10px; color: #a5b4fc; margin-top: 4px; font-family: 'Inter', sans-serif; font-weight: normal; text-shadow: none;\">${t('buildBudget')}</div>\n                </div>\n            `;\n            overlay.appendChild(hudTop);\n\n            // Base Build Progress Panel (Explaining connection between credits and base construction)\n            const baseBuildPanel = document.createElement('div');\n            baseBuildPanel.id = 'base-build-status-panel';\n            baseBuildPanel.className = 'hud-panel';\n            baseBuildPanel.style.cssText = `\n                position: absolute;\n                top: var(--space-sm);\n                left: var(--space-sm);\n                border-color: #00ff66;\n                box-shadow: 0 0 12px rgba(0, 255, 102, 0.35);\n                width: 240px;\n                font-size: 14px;\n                background: rgba(10, 20, 40, 0.95);\n                pointer-events: auto;\n                z-index: 100;\n            `;\n            baseBuildPanel.innerHTML = `\n                <div class=\"label\" style=\"color: #00ff66; font-size: 12px; font-weight: 900;\">${t('baseBuild')}</div>\n                <div style=\"font-weight: 900; font-size: 20px; margin: 4px 0; color: #fff;\" id=\"base-build-pct\">0.0%</div>\n                <div class=\"mission-bar-container\" style=\"height: 10px; margin-bottom: 6px; border-color: rgba(0, 255, 102, 0.5); background: rgba(0,0,0,0.5);\">\n                    <div class=\"mission-bar-fill\" id=\"base-build-bar\" style=\"width: 0%; background: linear-gradient(90deg, #00ff66, #00e5ff); box-shadow: 0 0 8px #00ff66;\"></div>\n                </div>\n                <div style=\"font-size: 10px; color: #cbd5e1; line-height: 1.4; font-family: 'Inter', sans-serif;\" id=\"base-build-desc\">\n                    ${t('assembling')}: Launch Pad & Rocket Core\n                </div>\n            `;\n            overlay.appendChild(baseBuildPanel);\n\n            // Colony Construction Mission HUD Progress\n            const missionPanel = document.createElement('div');\n            missionPanel.className = 'mission-panel';\n            missionPanel.title = 'Click for detailed newbie guide!';\n            missionPanel.innerHTML = `\n                <div class=\"mission-title\" style=\"font-size: 12px; font-weight: 900; color: #00e5ff;\">${t('mission')}</div>\n                <div class=\"mission-bar-container\" style=\"margin: 6px 0;\">\n                    <div class=\"mission-bar-fill\" id=\"mission-progress-bar\" style=\"width: 0%\"></div>\n                </div>\n                <div class=\"mission-status\" id=\"mission-status-text\">${t('loading')}</div>\n                <div style=\"font-size: 9px; color: #00ffcc; letter-spacing: 1px; margin-top: 4px; font-weight: bold; text-transform: uppercase;\">${t('guide')}</div>\n            `;\n            overlay.appendChild(missionPanel);\n\n            // Detailed Mission Guide Modal\n            const missionGuideOverlay = document.createElement('div');\n            missionGuideOverlay.className = 'tutorial-modal-overlay';\n            missionGuideOverlay.style.display = 'none';\n            missionGuideOverlay.innerHTML = `\n                <div class=\"tutorial-modal\">\n                    <h2 id=\"guide-modal-title\">${t('guideTitle')}</h2>\n                    <div style=\"font-size: 14px; line-height: 1.6; display: flex; flex-direction: column; gap: 14px;\">\n                        <div class=\"tutorial-step\" style=\"border-left-color: #00e5ff;\">\n                            <div class=\"tutorial-step-num\">!</div>\n                            <div class=\"tutorial-step-content\">\n                                <strong>${t('objective')}</strong>\n                                <p id=\"guide-objective-text\"></p>\n                            </div>\n                        </div>\n                        <div class=\"tutorial-step\" style=\"border-left-color: #ffd700;\">\n                            <div class=\"tutorial-step-num\">\u2605</div>\n                            <div class=\"tutorial-step-content\">\n                                <strong>${t('actionSteps')}</strong>\n                                <p id=\"guide-action-text\"></p>\n                            </div>\n                        </div>\n                        <div class=\"tutorial-step\" style=\"border-left-color: #00ff66;\">\n                            <div class=\"tutorial-step-num\">\u2714</div>\n                            <div class=\"tutorial-step-content\">\n                                <strong>${t('tipSuccess')}</strong>\n                                <p id=\"guide-tip-text\"></p>\n                            </div>\n                        </div>\n                    </div>\n                    <button class=\"tutorial-btn\" id=\"close-guide-btn\">${t('gotIt')}</button>\n                </div>\n            `;\n            overlay.appendChild(missionGuideOverlay);\n\n            const showMissionGuide = () => {\n                const currentMission = missions[currentMissionIdx];\n                if (!currentMission) return;\n\n                const guideTitle = document.getElementById('guide-modal-title');\n                const guideObjective = document.getElementById('guide-objective-text');\n                const guideAction = document.getElementById('guide-action-text');\n                const guideTip = document.getElementById('guide-tip-text');\n\n                guideTitle.textContent = `\ud83c\udfaf GUIDE: ${currentMission.title}`;\n                guideObjective.innerHTML = `<strong>${currentMission.text}</strong>`;\n\n                let action = \"\";\n                let tip = \"\";\n\n                if (currentMission.type === 'rotate') {\n                    action = \"1. Press and hold the <strong>\u25c0 Left / Right \u25b6 Cabin Rotation</strong> buttons on your touch panel.<br>2. Or press the <strong>Q / E keys</strong> on your keyboard.<br>3. Spin the upper cabin 180 degrees to get the driver nice and dizzy!\";\n                    tip = \"Remember, in Simple Mode, the Left Joystick handles driving/steering your tracks, while the Cabin Rotation buttons spin the turret base.\";\n                } else if (currentMission.type === 'dig') {\n                    action = \"1. Drag the <strong>Left Joystick</strong> in any direction (or use WASD keys) to drive to a bumpy terrain area.<br>2. Position your heavy bucket over the alien sand.<br>3. Tap the orange <strong>\ud83e\udd16 Auto Dig</strong> button on the bottom-right (or press Space / Z on keyboard).<br>4. Keep digging in the same hole to excavate deep!\";\n                    tip = \"Your digging depth is shown on the top-left indicator. Digging repeatedly in deep craters is the fastest way to hit your depth target!\";\n                } else if (currentMission.type === 'credits') {\n                    action = \"1. Drive over to colored, <strong>glowing resource pools</strong> on the dunes using the <strong>Left Joystick</strong>.<br>2. Tap the <strong>\ud83e\udd16 Auto Dig</strong> button to scoop up buried precious gemstones.<br>3. When scooped, gems automatically launch via tractor beam to the central rocket and award high credits!\";\n                    tip = \"Precious treasures hidden deep underground offer massive multiplier bonuses! Scan for fluorescent ground waves to locate top-value targets.\";\n                } else if (currentMission.type === 'zombies_slain') {\n                    action = \"1. Wait for annoying green alien zombies to crawl toward you.<br>2. Drive over them directly using the <strong>Left Joystick</strong> (WASD keys) to crush them under your heavy caterpillar tracks.<br>3. Or tap <strong>\ud83e\udd16 Auto Dig</strong> to smack them with the steel bucket when they get close!\";\n                    tip = \"Zombies clinging to your tracks will degrade your vehicle driving speed. Defeat them immediately to restore 100% maneuverability!\";\n                } else if (currentMission.type === 'bases_destroyed') {\n                    action = \"1. Find a giant pulsating alien hive outpost located in the corners of the map.<br>2. Drive close to the outpost structure using the <strong>Left Joystick</strong>.<br>3. Repeatedly tap <strong>\ud83e\udd16 Auto Dig</strong> to smash the glowing hive core with your bucket until its health bar falls to zero!\";\n                    tip = \"Demolishing an active hive grants a massive +300 credits reward and halts zombie spawning in that area for 2 minutes!\";\n                } else if (currentMission.type === 'deliver') {\n                    action = \"1. Look for <strong>glowing resource rings</strong> on the terrain, or <strong>golden sand pools</strong> indicating rare buried Titan Mech parts.<br>2. Position your excavator and tap <strong>\ud83e\udd16 Auto Dig</strong> to scoop the gem/relic into your bucket.<br>3. After resting in your bucket for 3 seconds, it will fly automatically to the central rocket launchpad!\";\n                    tip = \"Deliveries must be brought to the central pad at coordinates (0, -15). The automatic tractor beam activates as soon as items are held in your bucket.\";\n                }\n\n                guideAction.innerHTML = action;\n                guideTip.innerHTML = tip;\n\n                missionGuideOverlay.style.display = 'flex';\n                isModalOpen = true;\n            };\n\n            missionPanel.addEventListener('click', (e) => {\n                e.preventDefault();\n                e.stopPropagation();\n                showMissionGuide();\n            });\n            missionPanel.addEventListener('touchstart', (e) => {\n                e.preventDefault();\n                e.stopPropagation();\n                showMissionGuide();\n            });\n\n            document.getElementById('close-guide-btn').addEventListener('click', () => {\n                missionGuideOverlay.style.display = 'none';\n                isModalOpen = false;\n            });\n            document.getElementById('close-guide-btn').addEventListener('touchstart', () => {\n                missionGuideOverlay.style.display = 'none';\n                isModalOpen = false;\n            });\n\n            // Info text element for level complete alerts\n            const infoText = document.createElement('div');\n            infoText.className = 'info-text';\n            infoText.id = 'info-text-element';\n            overlay.appendChild(infoText);\n\n            // Radar Detector Panel removed per user request\n\n            // Handbook Button\n            const handbookToggleBtn = document.createElement('div');\n            handbookToggleBtn.className = 'handbook-toggle-btn';\n            handbookToggleBtn.id = 'handbook-toggle-btn';\n            handbookToggleBtn.innerHTML = `\ud83d\udcd6 ${t('handbook')}`;\n            overlay.appendChild(handbookToggleBtn);\n\n            // Graphics Quality Toggle Button (Highly visible, allows toggling graphics at runtime)\n            const graphicsToggleBtn = document.createElement('div');\n            graphicsToggleBtn.className = 'graphics-toggle-btn';\n            graphicsToggleBtn.id = 'graphics-toggle-btn';\n            graphicsToggleBtn.innerHTML = `\u26a1 ${currentGraphicsMode === 'low' ? t('graphicsLow') : t('graphicsHigh')}`;\n            overlay.appendChild(graphicsToggleBtn);\n\n            const toggleGraphicsQuality = (e) => {\n                if (e) {\n                    e.preventDefault();\n                    e.stopPropagation();\n                }\n                const nextMode = currentGraphicsMode === 'low' ? 'high' : 'low';\n                setGraphicsQuality(nextMode);\n            };\n            graphicsToggleBtn.addEventListener('click', toggleGraphicsQuality);\n            graphicsToggleBtn.addEventListener('touchstart', toggleGraphicsQuality);\n\n            // Control Mode Toggle Button (Option A!)\n            const controlModeToggleBtn = document.createElement('div');\n            controlModeToggleBtn.className = 'control-mode-toggle-btn';\n            controlModeToggleBtn.id = 'control-mode-toggle-btn';\n            controlModeToggleBtn.innerHTML = `\ud83d\udd79\ufe0f ${t('modeSimple')}`;\n            overlay.appendChild(controlModeToggleBtn);\n\n            const toggleControlMode = (e) => {\n                if (e) {\n                    e.preventDefault();\n                    e.stopPropagation();\n                }\n                if (currentControlMode === 'simple') {\n                    currentControlMode = 'classic';\n                    controlModeToggleBtn.innerHTML = `\ud83d\udd79\ufe0f ${t('modeClassic')}`;\n                } else {\n                    currentControlMode = 'simple';\n                    controlModeToggleBtn.innerHTML = `\ud83d\udd79\ufe0f ${t('modeSimple')}`;\n                }\n                renderControls();\n            };\n            controlModeToggleBtn.addEventListener('click', toggleControlMode);\n            controlModeToggleBtn.addEventListener('touchstart', toggleControlMode);\n\n            // Handbook Modal UI\n            const handbookModal = document.createElement('div');\n            handbookModal.className = 'handbook-modal';\n            handbookModal.id = 'handbook-modal';\n            handbookModal.innerHTML = `\n                <div class=\"handbook-header\">\n                    <h2>${t('handbookTitle')}</h2>\n                    <button class=\"handbook-close-btn\" id=\"handbook-close-btn\">${t('close')}</button>\n                </div>\n                <div class=\"handbook-tabs\">\n                    <div class=\"handbook-tab active\" data-pane=\"tab-intro\">${t('tabIntro')}</div>\n                    <div class=\"handbook-tab\" data-pane=\"tab-controls\">${t('tabControls')}</div>\n                    <div class=\"handbook-tab\" data-pane=\"tab-radar\">${t('tabRadar')}</div>\n                    <div class=\"handbook-tab\" data-pane=\"tab-threats\">${t('tabThreats')}</div>\n                </div>\n                <div class=\"handbook-content-container\">\n                    <!-- Tab 1: Intro -->\n                    <div class=\"handbook-pane active\" id=\"tab-intro\">\n                        <h3>\ud83e\ude90 TERRAFORM TYCOON PROTOCOL</h3>\n                        <div class=\"handbook-section\">\n                            <strong>Welcome Pioneer!</strong> You are tasked with preparing the extreme alien landscape for colony expansion. Reshaping terrain, building infrastructure, and securing resources are vital to construct our deep space rockets and colony geodesic domes.\n                        </div>\n                        <div class=\"handbook-section accent\">\n                            <strong>Project Milestones & Progression:</strong>\n                            <p>\u2022 <strong>Missions & Tasks:</strong> Progress through 30 structured terraforming milestones, unlocking massive credit bonuses.</p>\n                            <p>\u2022 <strong>Colony Construction:</strong> Watch a high-tech spaceship and launch tower physically materialize at the launch coordinates (0, -15) as your credits scale up to 100,000!</p>\n                            <p>\u2022 <strong>Colony Habitats:</strong> Deliver excavated planetary relics to expand communications towers and unlock futuristic dome laboratories.</p>\n                        </div>\n                    </div>\n\n                    <!-- Tab 2: Controls -->\n                    <div class=\"handbook-pane\" id=\"tab-controls\">\n                        <h3>\ud83d\ude9c SIMPLE COCKPIT NAVIGATION (OPTION A)</h3>\n                        \n                        <div class=\"handbook-section accent\" style=\"background: rgba(0, 229, 255, 0.05); border-left-color: #00e5ff;\">\n                            <strong>\ud83d\udcf1 DETAILED TOUCH CONTROLS GUIDE:</strong>\n                            <p style=\"margin-top: 8px; color: #ffd700; font-weight: bold;\">Supercharge your mining efficiency with streamlined mobile controls!</p>\n                            \n                            <div style=\"background: rgba(0,0,0,0.4); padding: 10px; border-radius: 6px; margin: 8px 0; border: 1px solid rgba(0, 229, 255, 0.2);\">\n                                <span style=\"color: #00e5ff; font-weight: bold;\">\ud83d\udd79\ufe0f Left Joystick (Drive & Steer):</span>\n                                <p style=\"margin: 4px 0 0 12px; font-size: 13px; color: #e2e8f0;\">\n                                    \u2022 Drag the stick in any direction to drive and steer the heavy caterpillar tracks effortlessly.\n                                </p>\n                            </div>\n\n                            <div style=\"background: rgba(0,0,0,0.4); padding: 10px; border-radius: 6px; margin: 8px 0; border: 1px solid rgba(0, 229, 255, 0.2);\">\n                                <span style=\"color: #00e5ff; font-weight: bold;\">\ud83d\udd79\ufe0f Cabin Rotation Buttons (Left / Right):</span>\n                                <p style=\"margin: 4px 0 0 12px; font-size: 13px; color: #e2e8f0;\">\n                                    \u2022 Tap the <strong>\u25c0 Left</strong> or <strong>Right \u25b6</strong> buttons on your touchscreen panel to swing the turntable body around.\n                                </p>\n                            </div>\n\n                            <div style=\"background: rgba(0,0,0,0.4); padding: 10px; border-radius: 6px; margin: 8px 0; border: 1px solid rgba(0, 229, 255, 0.2);\">\n                                <span style=\"color: #00e5ff; font-weight: bold;\">\ud83e\udd16 Automation Buttons (Auto Dig / Auto Dump):</span>\n                                <p style=\"margin: 4px 0 0 12px; font-size: 13px; color: #e2e8f0;\">\n                                    \u2022 Tap orange <strong>\ud83e\udd16 Auto Dig</strong> to perform a complete automatic dig sequence (lower boom, scoop, curl, raise arm).<br>\n                                    \u2022 Tap blue <strong>\ud83e\udd16 Auto Dump</strong> to automatically tip the bucket forward and dump the collected soil!\n                                </p>\n                            </div>\n\n                            <div style=\"background: rgba(0,0,0,0.4); padding: 10px; border-radius: 6px; margin: 8px 0; border: 1px solid rgba(0, 229, 255, 0.2);\">\n                                <span style=\"color: #00e5ff; font-weight: bold;\">\ud83c\udfa5 Satellite Camera Orbit:</span>\n                                <p style=\"margin: 4px 0 0 12px; font-size: 13px; color: #e2e8f0;\">\n                                    \u2022 Simply <strong>drag anywhere on the open 3D viewport</strong> to orbit, tilt, and align the camera view around your vehicle.\n                                </p>\n                            </div>\n                        </div>\n\n                        <div class=\"handbook-section\" style=\"border-left-color: #ffd700;\">\n                            <strong>\u2328\ufe0f Desktop Keyboard & Hotkeys:</strong>\n                            <div style=\"margin-top: 10px;\">\n                                <div class=\"control-key-row\"><span class=\"key-badge\" style=\"background:#ffaa00; border-color:#ff6d00;\">SPACE</span> <span><strong>One-Key Toggle Sequence:</strong> Press once to <strong>Auto Dig</strong>, and press again to <strong>Auto Dump</strong>!</span></div>\n                                <div class=\"control-key-row\"><span class=\"key-badge\">W</span> <span class=\"key-badge\">S</span> <span>Drive tracks forward & backward</span></div>\n                                <div class=\"control-key-row\"><span class=\"key-badge\">A</span> <span class=\"key-badge\">D</span> <span>Steer base chassis left & right</span></div>\n                                <div class=\"control-key-row\"><span class=\"key-badge\">Q</span> <span class=\"key-badge\">E</span> <span>Rotate excavator turret left & right</span></div>\n                                <div class=\"control-key-row\"><span class=\"key-badge\">Z</span> <span>Direct shortcut: Trigger Auto Dig</span></div>\n                                <div class=\"control-key-row\"><span class=\"key-badge\">X</span> / <span class=\"key-badge\">C</span> <span>Direct shortcut: Trigger Auto Dump</span></div>\n                                <div class=\"control-key-row\"><span style=\"color:#00e5ff;\">Left Click Drag</span> <span>Orbit and tilt satellite camera</span></div>\n                            </div>\n                        </div>\n                    </div>\n\n                    <!-- Tab 3: Radar -->\n                    <div class=\"handbook-pane\" id=\"tab-radar\">\n                        <h3>\ud83e\udd16 ANCIENT TITAN MECH ARCHAEOLOGY</h3>\n                        <div class=\"handbook-section\" style=\"border-left-color: #ffd700;\">\n                            <strong>Colossal Planetary Guardian:</strong> An ancient, legendary 10-meter-tall protector Titan is waiting to be rebuilt! 6 mythical <strong>Titan Mech Parts</strong> are buried deep in the planet's dunes.\n                        </div>\n                        <div class=\"handbook-section accent\" style=\"border-left-color: #00e5ff;\">\n                            <strong>How to Rebuild and Activate:</strong>\n                            <p>\u2022 <strong>Golden Beacon Pools:</strong> Scan the landscape for intense, highly-visible <strong>pulsating golden glowing zones</strong>. These mark coordinates of buried tech!</p>\n                            <p>\u2022 <strong>Unearth the Tech:</strong> Drive over and use <strong>Auto Dig</strong> to scoop deep into the golden sand until the component is retrieved into your bucket.</p>\n                            <p>\u2022 <strong>Spaceship Delivery:</strong> Once held in your bucket, a secure tractor beam instantly launches the part to the assembly site next to the rocket. Delivering a part physically constructs that section of the massive 3D Titan!</p>\n                            <p>\u2022 <strong>Active Guard Protocols:</strong> Once all 6 parts are delivered, the colossal giant wakes up! He will automatically follow your excavator as a heavy bodyguard, turning and stomping any green alien zombies that crawl near!</p>\n                        </div>\n                    </div>\n\n                    <!-- Tab 4: Threats -->\n                    <div class=\"handbook-pane\" id=\"tab-threats\">\n                        <h3>\ud83d\udc7e EXTREME SUBTERRANEAN DEFENSE PROTOCOLS</h3>\n                        \n                        <div class=\"handbook-section accent\" style=\"border-left-color: #ff0055;\">\n                            <strong>\u26a0\ufe0f GIANT VIOLET SANDWORMS (ALERT!):</strong>\n                            <p style=\"margin-top: 6px; color: #ff00ff; font-weight: bold;\">Massive, highly-aggressive predators slumbering deep beneath the dunes!</p>\n                            <p>\u2022 <strong>Awakening:</strong> Purple/violet dunes indicate sleeping sandworms. Digging in these areas will unearth them, causing them to erupt and chase you!</p>\n                            <p>\u2022 <strong>Vibrations:</strong> Their proximity and lunging attacks induce a <strong>noticeable mechanical vibration and cockpit shaking</strong> on your excavator.</p>\n                            <p>\u2022 <strong>How to Slay (10-Hit Boss):</strong> Protect yourself by fighting back! It takes exactly <strong>10 heavy hits</strong> (striking them with Auto Dig or ramming them with tracks) to slay them.</p>\n                            <p>\u2022 <strong>Attack Bonus:</strong> Each hit on a Sandworm awards you <strong>+100 Credits</strong> immediately!</p>\n                            <p>\u2022 <strong>Bounty & Loot Drop:</strong> Defeating a Sandworm rewards you with <strong>+800 Credits</strong> AND drops a legendary <strong>Sandworm Heart Gem</strong> (worth +500 Credits upon tractor delivery)!</p>\n                        </div>\n\n                        <div class=\"handbook-section\" style=\"border-left-color: #ffaa00; background: rgba(255, 170, 0, 0.05);\">\n                            <strong>\ud83d\udca3 ALIEN BOMBER ZOMBIES (NEW!):</strong>\n                            <p>\u2022 <strong>Warning Signal:</strong> A larger, dangerous bomber zombie crawls near every 30 seconds holding a flashing explosive shell.</p>\n                            <p>\u2022 <strong>Direct Detonation:</strong> If it successfully contacts your vehicle body, it will detonate causing intense shaking and a <strong>2-second system critical fault</strong> that locks all controls!</p>\n                            <p>\u2022 <strong>Counter-strategy:</strong> Strike and disarm the bomber from a distance with your heavy bucket before it gets close. Safe disarms award a massive bounty of <strong>+150 Credits</strong>!</p>\n                        </div>\n\n                        <div class=\"handbook-section\" style=\"border-left-color: #00ff66;\">\n                            <strong>\ud83d\udc7e INVASIVE GREEN ALIEN ZOMBIES:</strong>\n                            <p>\u2022 <strong>Maneuver Penalty:</strong> Small alien zombies will crawl towards you. Latching onto your caterpillar tracks degrades driving speed by 20% per zombie.</p>\n                            <p>\u2022 <strong>Splat!</strong> Drive over them or strike them with your heavy bucket to instantly crush them.</p>\n                            <p>\u2022 <strong>Hive Bases:</strong> Purge glowing hive outposts with your heavy bucket to stop zombie spawning in that area for 120 seconds and earn +300 Credits!</p>\n                        </div>\n                    </div>\n                </div>\n            `;\n            overlay.appendChild(handbookModal);\n\n            // Treasure Toggle Button\n            const treasureToggleBtn = document.createElement('div');\n            treasureToggleBtn.className = 'treasure-toggle-btn';\n            treasureToggleBtn.id = 'treasure-toggle-btn';\n            treasureToggleBtn.innerHTML = `\ud83d\udc51 ${t('vault')} [${t('expand')}]`;\n            overlay.appendChild(treasureToggleBtn);\n\n            // Treasure Inventory Panel\n            const treasurePanel = document.createElement('div');\n            treasurePanel.className = 'treasure-panel';\n            treasurePanel.id = 'treasure-panel';\n            overlay.appendChild(treasurePanel);\n            updateTreasureUI();\n\n            const toggleTreasure = (e) => {\n                if (e) {\n                    e.preventDefault();\n                    e.stopPropagation();\n                }\n                const isExpanded = treasurePanel.classList.toggle('expanded');\n                treasureToggleBtn.innerHTML = isExpanded ? `\ud83d\udc51 ${t('vault')} [${t('collapse')}]` : `\ud83d\udc51 ${t('vault')} [${t('expand')}]`;\n            };\n            treasureToggleBtn.addEventListener('click', toggleTreasure);\n            treasureToggleBtn.addEventListener('touchstart', toggleTreasure);\n            updateObjectiveUI();\n\n            // Handbook modal wiring\n            const toggleHandbook = (e) => {\n                if (e) {\n                    e.preventDefault();\n                    e.stopPropagation();\n                }\n                const isActive = handbookModal.classList.toggle('active');\n                isModalOpen = isActive;\n            };\n\n            handbookToggleBtn.addEventListener('click', toggleHandbook);\n            handbookToggleBtn.addEventListener('touchstart', toggleHandbook);\n\n            const closeBtn = document.getElementById('handbook-close-btn');\n            closeBtn.addEventListener('click', toggleHandbook);\n            closeBtn.addEventListener('touchstart', toggleHandbook);\n\n            // Tab switching\n            const tabs = handbookModal.querySelectorAll('.handbook-tab');\n            const panes = handbookModal.querySelectorAll('.handbook-pane');\n            tabs.forEach(tab => {\n                const handler = (e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    tabs.forEach(t => t.classList.remove('active'));\n                    panes.forEach(p => p.classList.remove('active'));\n                    tab.classList.add('active');\n                    const targetPane = handbookModal.querySelector(`#${tab.getAttribute('data-pane')}`);\n                    if (targetPane) targetPane.classList.add('active');\n                };\n                tab.addEventListener('click', handler);\n                tab.addEventListener('touchstart', handler);\n            });\n\n            // Mobile controls container\n            const controlsPanel = document.createElement('div');\n            controlsPanel.className = 'controls-panel';\n            overlay.appendChild(controlsPanel);\n\n            function renderControls() {\n                if (currentControlMode === 'simple') {\n                    controlsPanel.innerHTML = `\n                        <div class=\"joystick-container\" id=\"joy-left-area\">\n                            <div class=\"joystick-label\">${t('leftJoy')}</div>\n                            <div class=\"joystick-base\">\n                                <div class=\"joystick-stick\" id=\"joy-left-stick\"></div>\n                            </div>\n                        </div>\n\n                        <div style=\"display: flex; flex-direction: column; gap: 8px; width: 150px; align-items: center;\">\n                            <div class=\"drive-panel-label\" style=\"color: var(--color-primary); font-size: 11px;\">${t('cabinRot')}</div>\n                            <div style=\"display: flex; gap: 8px; justify-content: center; width: 100%;\">\n                                <div class=\"drive-btn\" id=\"btn-cab-left\" style=\"width: 70px; height: 55px; font-size: 13px;\">${t('left')}</div>\n                                <div class=\"drive-btn\" id=\"btn-cab-right\" style=\"width: 70px; height: 55px; font-size: 13px;\">${t('right')}</div>\n                            </div>\n                        </div>\n\n                        <div style=\"display: flex; flex-direction: column; gap: 12px; width: 150px;\">\n                            <div class=\"auto-btn\" id=\"btn-auto-dig\" style=\"background: #ff6d00; box-shadow: 0 6px 0 #b34a00, 0 8px 16px rgba(0,0,0,0.6);\">${t('autoDig')}</div>\n                            <div class=\"auto-btn\" id=\"btn-auto-dump\" style=\"background: #0091ea; box-shadow: 0 6px 0 #00609f, 0 8px 16px rgba(0,0,0,0.6);\">${t('autoDump')}</div>\n                        </div>\n                    `;\n\n                    const joyLeftArea = document.getElementById('joy-left-area');\n                    const joyLeftStick = document.getElementById('joy-left-stick');\n                    const joyLeftBase = joyLeftArea.querySelector('.joystick-base');\n\n                    setupJoystick(joyLeftArea, joyLeftStick, joyLeftBase, touchState.leftJoy);\n\n                    const btnAutoDig = document.getElementById('btn-auto-dig');\n                    const btnAutoDump = document.getElementById('btn-auto-dump');\n                    if (btnAutoDig) {\n                        btnAutoDig.addEventListener('touchstart', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDig(); });\n                        btnAutoDig.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDig(); });\n                    }\n                    if (btnAutoDump) {\n                        btnAutoDump.addEventListener('touchstart', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDump(); });\n                        btnAutoDump.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDump(); });\n                    }\n\n                    // Setup cab rotation buttons for simple mode\n                    const btnCabL = document.getElementById('btn-cab-left');\n                    const btnCabR = document.getElementById('btn-cab-right');\n                    if (btnCabL) {\n                        btnCabL.addEventListener('touchstart', e => { e.preventDefault(); touchState.drive.cabL = true; });\n                        btnCabL.addEventListener('touchend', e => { e.preventDefault(); touchState.drive.cabL = false; });\n                        btnCabL.addEventListener('mousedown', e => { e.preventDefault(); touchState.drive.cabL = true; });\n                        btnCabL.addEventListener('mouseup', e => { e.preventDefault(); touchState.drive.cabL = false; });\n                        btnCabL.addEventListener('mouseleave', () => { touchState.drive.cabL = false; });\n                    }\n                    if (btnCabR) {\n                        btnCabR.addEventListener('touchstart', e => { e.preventDefault(); touchState.drive.cabR = true; });\n                        btnCabR.addEventListener('touchend', e => { e.preventDefault(); touchState.drive.cabR = false; });\n                        btnCabR.addEventListener('mousedown', e => { e.preventDefault(); touchState.drive.cabR = true; });\n                        btnCabR.addEventListener('mouseup', e => { e.preventDefault(); touchState.drive.cabR = false; });\n                        btnCabR.addEventListener('mouseleave', () => { touchState.drive.cabR = false; });\n                    }\n                } else {\n                    controlsPanel.innerHTML = `\n                        <div class=\"joystick-container\" id=\"joy-left-area\">\n                            <div class=\"joystick-label\">Left Joystick<br>Swing & Arm</div>\n                            <div class=\"joystick-base\">\n                                <div class=\"joystick-stick\" id=\"joy-left-stick\"></div>\n                            </div>\n                        </div>\n\n                        <div class=\"drive-panel\">\n                            <div class=\"drive-panel-label\">Drive Tracks</div>\n                            <div class=\"drive-grid\">\n                                <div></div>\n                                <div class=\"drive-btn\" id=\"drive-fwd\">\u25b2 FWD</div>\n                                <div></div>\n                                <div class=\"drive-btn\" id=\"drive-left\">\u25c0 L</div>\n                                <div class=\"drive-btn\" id=\"drive-back\">\u25bc REV</div>\n                                <div class=\"drive-btn\" id=\"drive-right\">R \u25b6</div>\n                            </div>\n                        </div>\n\n                        <div class=\"joystick-container\" id=\"joy-right-area\">\n                            <div class=\"auto-btn-container\">\n                                <div class=\"auto-btn\" id=\"btn-auto-dig\">${t('autoDig')}</div>\n                                <div class=\"auto-btn\" id=\"btn-auto-dump\">${t('autoDump')}</div>\n                            </div>\n                            <div class=\"joystick-label\" style=\"top: auto; bottom: -28px;\">Right Joystick<br>Boom & Bucket</div>\n                            <div class=\"joystick-base\">\n                                <div class=\"joystick-stick\" id=\"joy-right-stick\"></div>\n                            </div>\n                        </div>\n                    `;\n\n                    // Bind original classic elements\n                    const joyLeftArea = document.getElementById('joy-left-area');\n                    const joyLeftStick = document.getElementById('joy-left-stick');\n                    const joyLeftBase = joyLeftArea.querySelector('.joystick-base');\n\n                    const joyRightArea = document.getElementById('joy-right-area');\n                    const joyRightStick = document.getElementById('joy-right-stick');\n                    const joyRightBase = joyRightArea.querySelector('.joystick-base');\n\n                    setupJoystick(joyLeftArea, joyLeftStick, joyLeftBase, touchState.leftJoy);\n                    setupJoystick(joyRightArea, joyRightStick, joyRightBase, touchState.rightJoy);\n\n                    setupDriveButton('drive-fwd', 'fwd');\n                    setupDriveButton('drive-back', 'back');\n                    setupDriveButton('drive-left', 'left');\n                    setupDriveButton('drive-right', 'right');\n\n                    const btnAutoDig = document.getElementById('btn-auto-dig');\n                    const btnAutoDump = document.getElementById('btn-auto-dump');\n                    if (btnAutoDig) {\n                        btnAutoDig.addEventListener('touchstart', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDig(); });\n                        btnAutoDig.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDig(); });\n                    }\n                    if (btnAutoDump) {\n                        btnAutoDump.addEventListener('touchstart', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDump(); });\n                        btnAutoDump.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation(); triggerAutoDump(); });\n                    }\n                }\n            }\n\n            renderControls();\n\n            function setupJoystick(area, stick, base, joyState) {\n                function handleStart(e) {\n                    e.preventDefault();\n                    const touch = e.changedTouches ? e.changedTouches[0] : e;\n                    joyState.active = true;\n                    joyState.id = touch.identifier || 0;\n                    handleMove(e);\n                }\n                function handleMove(e) {\n                    if (!joyState.active) return;\n                    const touch = e.changedTouches ? Array.from(e.changedTouches).find(t => t.identifier === joyState.id) : e;\n                    if (!touch) return;\n                    const rect = base.getBoundingClientRect();\n                    const cx = rect.left + rect.width/2;\n                    const cy = rect.top + rect.height/2;\n                    let dx = (touch.clientX - cx) / (rect.width/2);\n                    let dy = (touch.clientY - cy) / (rect.height/2);\n                    const mag = Math.sqrt(dx*dx + dy*dy);\n                    if (mag > 1) { dx /= mag; dy /= mag; }\n                    joyState.x = dx;\n                    joyState.y = dy;\n                    stick.style.transform = `translate(calc(-50% + ${dx*42}px), calc(-50% + ${dy*42}px))`;\n                }\n                function handleEnd(e) {\n                    joyState.active = false;\n                    joyState.x = 0;\n                    joyState.y = 0;\n                    stick.style.transform = 'translate(-50%, -50%)';\n                }\n\n                area.addEventListener('touchstart', handleStart, { passive: false });\n                area.addEventListener('touchmove', handleMove, { passive: false });\n                area.addEventListener('touchend', handleEnd);\n                area.addEventListener('mousedown', handleStart);\n\n                document.addEventListener('mousemove', (e) => {\n                    if (joyState.active && !e.changedTouches) {\n                        handleMove(e);\n                    }\n                });\n                document.addEventListener('mouseup', (e) => {\n                    if (joyState.active) {\n                        handleEnd(e);\n                    }\n                });\n            }\n\n            function setupDriveButton(id, direction) {\n                const btn = document.getElementById(id);\n                if (!btn) return;\n                const setVal = (val) => { touchState.drive[direction] = val; };\n                btn.addEventListener('touchstart', e => { e.preventDefault(); setVal(true); });\n                btn.addEventListener('touchend', e => { e.preventDefault(); setVal(false); });\n                btn.addEventListener('mousedown', e => { e.preventDefault(); setVal(true); });\n                btn.addEventListener('mouseup', e => { e.preventDefault(); setVal(false); });\n                btn.addEventListener('mouseleave', () => { setVal(false); });\n            }\n\n            renderControls();\n\n            // Camera rotation via drag on canvas\n            let camDrag = false;\n            let lastMX = 0, lastMY = 0;\n            renderer.domElement.addEventListener('mousedown', e => {\n                if (e.button === 2 || e.button === 0) { camDrag = true; lastMX = e.clientX; lastMY = e.clientY; }\n            });\n            renderer.domElement.addEventListener('contextmenu', e => e.preventDefault());\n            document.addEventListener('mousemove', e => {\n                if (camDrag) {\n                    const dx = e.clientX - lastMX;\n                    const dy = e.clientY - lastMY;\n                    camState.azimuth -= dx * 0.005;\n                    camState.elevation = Math.max(0.1, Math.min(1.4, camState.elevation + dy * 0.005));\n                    lastMX = e.clientX;\n                    lastMY = e.clientY;\n                }\n            });\n            document.addEventListener('mouseup', () => { camDrag = false; });\n\n            // Touch camera\n            let camTouchId = null;\n            let camLastX = 0, camLastY = 0;\n            renderer.domElement.addEventListener('touchstart', e => {\n                if (e.touches.length === 1 && !touchState.leftJoy.active) {\n                    camTouchId = e.touches[0].identifier;\n                    camLastX = e.touches[0].clientX;\n                    camLastY = e.touches[0].clientY;\n                }\n            });\n            renderer.domElement.addEventListener('touchmove', e => {\n                for (const t of e.changedTouches) {\n                    if (t.identifier === camTouchId) {\n                        const dx = t.clientX - camLastX;\n                        const dy = t.clientY - camLastY;\n                        camState.azimuth -= dx * 0.008;\n                        camState.elevation = Math.max(0.1, Math.min(1.4, camState.elevation + dy * 0.005));\n                        camLastX = t.clientX;\n                        camLastY = t.clientY;\n                    }\n                }\n            });\n            renderer.domElement.addEventListener('touchend', e => {\n                for (const t of e.changedTouches) {\n                    if (t.identifier === camTouchId) camTouchId = null;\n                }\n            });\n\n            // Start sounds\n            function startAudio() {\n                if (!engineSound) engineSound = playSound('excavator_engine_sound', true, 0.2);\n                if (!ambientSound) ambientSound = playSound('ambient_alien_wind', true, 0.15);\n                document.removeEventListener('click', startAudio);\n                document.removeEventListener('touchstart', startAudio);\n            }\n            document.addEventListener('click', startAudio);\n            document.addEventListener('touchstart', startAudio);\n\n        } else {\n            // EDIT MODE\n            const editInfo = document.createElement('div');\n            editInfo.className = 'edit-overlay';\n            editInfo.innerHTML = `\n                <h2>${t('editMode')}</h2>\n                <p>${t('editDesc')}</p>\n                <p>${t('editSave')}</p>\n            `;\n            overlay.appendChild(editInfo);\n\n            // In edit mode, allow camera orbit\n            let editDrag = false;\n            let editLastX = 0, editLastY = 0;\n            renderer.domElement.addEventListener('mousedown', e => { editDrag = true; editLastX = e.clientX; editLastY = e.clientY; });\n            document.addEventListener('mousemove', e => {\n                if (editDrag) {\n                    camState.azimuth -= (e.clientX - editLastX) * 0.005;\n                    camState.elevation = Math.max(0.1, Math.min(1.4, camState.elevation + (e.clientY - editLastY) * 0.005));\n                    editLastX = e.clientX; editLastY = e.clientY;\n                }\n            });\n            document.addEventListener('mouseup', () => { editDrag = false; });\n            renderer.domElement.addEventListener('touchstart', e => { editDrag = true; editLastX = e.touches[0].clientX; editLastY = e.touches[0].clientY; });\n            renderer.domElement.addEventListener('touchmove', e => {\n                if (editDrag) {\n                    camState.azimuth -= (e.touches[0].clientX - editLastX) * 0.008;\n                    camState.elevation = Math.max(0.1, Math.min(1.4, camState.elevation + (e.touches[0].clientY - editLastY) * 0.005));\n                    editLastX = e.touches[0].clientX; editLastY = e.touches[0].clientY;\n                }\n            });\n            renderer.domElement.addEventListener('touchend', () => { editDrag = false; });\n        }\n\n        function updateObjectiveUI() {\n            const currentMission = missions[currentMissionIdx];\n            if (!currentMission) {\n                const statusText = document.getElementById('mission-status-text');\n                if (statusText) {\n                    statusText.innerHTML = `<span style=\"color: #00ff66; font-weight: bold; font-size: 15px;\">${t('allComplete')}</span>`;\n                }\n                const barFill = document.getElementById('mission-progress-bar');\n                if (barFill) barFill.style.width = '100%';\n                return;\n            }\n\n            // Update title\n            const titleEl = document.querySelector('.mission-title');\n            if (titleEl) {\n                titleEl.innerHTML = `\ud83e\ude90 Mission ${currentMission.id}/30: ${currentMission.title} \ud83e\ude90`;\n            }\n\n            // Calculate progress value for display\n            let displayProgress = 0;\n            let displayTarget = currentMission.target;\n            let displayUnit = \"\";\n\n            if (currentMission.type === 'rotate') {\n                displayProgress = Math.min(currentMission.target, totalRotation);\n                displayTarget = currentMission.target;\n                displayUnit = \"\u00b0\";\n                displayProgress = Math.floor(displayProgress * (180 / Math.PI));\n                displayTarget = Math.floor(currentMission.target * (180 / Math.PI));\n            } else if (currentMission.type === 'dig') {\n                displayProgress = maxDigDepth;\n                displayTarget = currentMission.target;\n                displayUnit = \"m\";\n            } else if (currentMission.type === 'credits') {\n                displayProgress = credits;\n                displayTarget = currentMission.target;\n                displayUnit = \"pts\";\n            } else if (currentMission.type === 'zombies_slain') {\n                displayProgress = zombiesSlainCount;\n                displayTarget = currentMission.target;\n                displayUnit = \"\";\n            } else if (currentMission.type === 'bases_destroyed') {\n                displayProgress = basesDestroyedCount;\n                displayTarget = currentMission.target;\n                displayUnit = \"\";\n            } else if (currentMission.type === 'deliver') {\n                displayProgress = totalDelivered;\n                displayTarget = currentMission.target;\n                displayUnit = \"\";\n            }\n\n            const pct = Math.min(100, (displayProgress / displayTarget) * 100);\n            const barFill = document.getElementById('mission-progress-bar');\n            if (barFill) barFill.style.width = `${pct}%`;\n\n            const statusText = document.getElementById('mission-status-text');\n            if (statusText) {\n                statusText.innerHTML = `\n                    <div style=\"font-size: 12px; color: #ccc; margin-bottom: 6px; line-height: 1.4; text-align: left;\">${currentMission.text}</div>\n                    <div style=\"color: #ffea00; font-weight: bold; font-size: 14px; margin-bottom: 4px;\">${t('progress')}: ${displayProgress.toFixed(displayProgress % 1 === 0 ? 0 : 1)} / ${displayTarget}${displayUnit} (${pct.toFixed(0)}%)</div>\n                    <div style=\"font-size: 13px; color: #00ff66; font-weight: bold;\">\ud83c\udf81 ${t('reward')}: +${currentMission.reward} ${t('credits')}</div>\n                `;\n            }\n        }\n\n        function checkMissionCompletion() {\n            const currentMission = missions[currentMissionIdx];\n            if (!currentMission) return;\n\n            let isCompleted = false;\n\n            if (currentMission.type === 'rotate') {\n                isCompleted = totalRotation >= currentMission.target;\n            } else if (currentMission.type === 'dig') {\n                isCompleted = maxDigDepth >= currentMission.target;\n            } else if (currentMission.type === 'credits') {\n                isCompleted = credits >= currentMission.target;\n            } else if (currentMission.type === 'zombies_slain') {\n                isCompleted = zombiesSlainCount >= currentMission.target;\n            } else if (currentMission.type === 'bases_destroyed') {\n                isCompleted = basesDestroyedCount >= currentMission.target;\n            } else if (currentMission.type === 'deliver') {\n                isCompleted = totalDelivered >= currentMission.target;\n            }\n\n            if (isCompleted && !currentMission.complete) {\n                currentMission.complete = true;\n                \n                // Reward credits!\n                updateCredits(currentMission.reward);\n\n                // Show floating score at the credits HUD panel position\n                const creditsPanel = document.getElementById('credits-panel');\n                if (creditsPanel) {\n                    const rect = creditsPanel.getBoundingClientRect();\n                    const div = document.createElement('div');\n                    div.style.cssText = `\n                        position: absolute;\n                        left: ${rect.left + rect.width / 2}px;\n                        top: ${rect.top + rect.height}px;\n                        transform: translate(-50%, 0);\n                        font-family: 'Orbitron', sans-serif;\n                        font-size: 26px;\n                        font-weight: 900;\n                        color: #00ff66;\n                        text-shadow: 0 0 10px #00ff66;\n                        pointer-events: none;\n                        z-index: 10005;\n                        opacity: 1;\n                        transition: transform 1.5s cubic-bezier(0.25, 1, 0.5, 1), opacity 1.5s ease-out;\n                    `;\n                    div.textContent = `+${currentMission.reward} ${t('credits')} [Mission]`;\n                    document.body.appendChild(div);\n                    \n                    requestAnimationFrame(() => {\n                        div.style.transform = 'translate(-50%, 120px) scale(1.3)';\n                        div.style.opacity = '0';\n                    });\n                    \n                    setTimeout(() => {\n                        div.remove();\n                    }, 1500);\n                }\n\n                // Play completion sound\n                if (audioBuffers['objective_complete_sound']) {\n                    playSound('objective_complete_sound', false, 0.85);\n                }\n\n                // Show screen feedback info-text!\n                const infoText = document.getElementById('info-text-element');\n                if (infoText) {\n                    infoText.innerHTML = `<span style=\"color: #ffd700; font-weight: 900; text-shadow: 0 0 10px rgba(255,215,0,0.8); font-size: 24px;\">${t('missionComplete')}</span><br><span style=\"font-size: 15px; color: #00ff66\">+${currentMission.reward} ${t('awarded')}</span>`;\n                    infoText.classList.add('visible');\n                    setTimeout(() => {\n                        infoText.classList.remove('visible');\n                    }, 3000);\n                }\n\n                // Advance to next mission!\n                currentMissionIdx++;\n                \n                // Refresh UI\n                updateObjectiveUI();\n            }\n        }\n\n        function updateTreasureUI() {\n            const panel = document.getElementById('treasure-panel');\n            if (!panel) return;\n            \n            // Calculate Titan Mech Parts Progress\n            let titanCount = 0;\n            const titanPartsListDisplay = [\n                { id: 'titan_l_leg', name: 'Titan Left Leg', emoji: '\ud83e\uddbf' },\n                { id: 'titan_r_leg', name: 'Titan Right Leg', emoji: '\ud83e\uddbf' },\n                { id: 'titan_torso', name: 'Titan Torso Core', emoji: '\ud83d\udee1\ufe0f' },\n                { id: 'titan_l_arm', name: 'Titan Left Arm', emoji: '\ud83e\uddbe' },\n                { id: 'titan_r_arm', name: 'Titan Right Arm', emoji: '\ud83e\uddbe' },\n                { id: 'titan_head', name: 'Titan Neural Head', emoji: '\ud83e\udd16' }\n            ];\n            \n            titanPartsListDisplay.forEach(p => {\n                if (titanCollection[p.id]) titanCount++;\n            });\n\n            let html = `\n            <div style=\"border-bottom: 2px solid #00e5ff; padding-bottom: 8px; margin-bottom: 12px;\">\n                <h4 style=\"color: #00e5ff; margin: 0 0 4px 0; font-size: 13px; letter-spacing: 1.5px; text-shadow: 0 0 6px rgba(0, 229, 255, 0.4);\">${t('titanAssembly')}</h4>\n                <div style=\"font-size: 10px; color: #a5b4fc; margin-bottom: 8px;\">${t('titanDesc')}</div>\n            `;\n            \n            titanPartsListDisplay.forEach(p => {\n                const found = titanCollection[p.id];\n                html += `\n                <div class=\"treasure-row\" style=\"opacity: ${found ? 1.0 : 0.45}; font-size: 11px; margin: 4px 0;\">\n                    <div class=\"treasure-icon\">${p.emoji} ${p.name}</div>\n                    <span style=\"color: ${found ? '#00ff66' : '#8892b0'}; font-weight: bold;\">${found ? t('found') : t('missing')}</span>\n                </div>`;\n            });\n            \n            html += `\n                <div style=\"font-size: 12px; color: #ffd700; font-weight: bold; margin-top: 8px; text-align: center;\">\n                    ${t('partsProgress')}: ${titanCount} / 6\n                </div>\n            </div>\n            `;\n\n            // Regular treasures\n            html += `<h4>${t('treasury')}</h4>`;\n            treasureTypes.forEach(tr => {\n                const count = collectedInventory[tr.id] || 0;\n                const isGem = ['ruby', 'gold', 'crystal', 'emerald'].includes(tr.id);\n                if (count > 0 || isGem) {\n                    html += `\n                    <div class=\"treasure-row\">\n                        <div class=\"treasure-icon\">${tr.emoji} ${tr.name} <span style=\"font-size: 11px; color: #ffd700; margin-left: 6px;\">(+${tr.score})</span></div>\n                        <span>x<strong id=\"count-${tr.id}\">${count}</strong></span>\n                    </div>`;\n                }\n            });\n            panel.innerHTML = html;\n        }\n\n        // ===== GAME LOGIC =====\n        let lastTime = performance.now();\n        let credits = 0;\n        let totalDelivered = 0; // Tracks artifacts delivered to spaceship base station\n        let digging = false;\n\n        // Helper function to update credits and submit to leaderboard\n        function updateCredits(amount) {\n            if (amount <= 0) return;\n            \n            credits += amount;\n            \n            // Update UI\n            const credEl = document.getElementById('credits');\n            if (credEl) credEl.textContent = credits;\n            \n            // Submit to leaderboard (silent background operation, don't await)\n            try {\n                if (typeof lib.addPlayerScoreToLeaderboard === 'function') {\n                    lib.addPlayerScoreToLeaderboard(credits).catch(function(error) {\n                        // Silently fail - game continues without leaderboard\n                    });\n                }\n            } catch(e) {\n                // Silently fail - game continues without leaderboard\n            }\n        }\n\n        function toScreenPosition(objPosition, camera) {\n            const vector = objPosition.clone().project(camera);\n            vector.x = (vector.x + 1) / 2 * gameWorld.clientWidth;\n            vector.y = -(vector.y - 1) / 2 * gameWorld.clientHeight;\n            return { x: vector.x, y: vector.y };\n        }\n\n        function showFloatingScore(amount, colorHex) {\n            const landerPos = new THREE.Vector3(0, 3.65, -15);\n            const screenPos = toScreenPosition(landerPos, camera);\n            \n            const div = document.createElement('div');\n            div.style.cssText = `\n                position: absolute;\n                left: ${screenPos.x}px;\n                top: ${screenPos.y}px;\n                transform: translate(-50%, -50%);\n                font-family: 'Orbitron', sans-serif;\n                font-size: 24px;\n                font-weight: 900;\n                color: ${colorHex || '#ffd700'};\n                text-shadow: 0 0 8px ${colorHex || '#ffd700'};\n                pointer-events: none;\n                z-index: 10005;\n                opacity: 1;\n                transition: transform 1.5s cubic-bezier(0.25, 1, 0.5, 1), opacity 1.5s ease-out;\n            `;\n            div.textContent = `+${amount} ${t('credits')}`;\n            document.body.appendChild(div);\n            \n            requestAnimationFrame(() => {\n                div.style.transform = 'translate(-50%, -180px) scale(1.4)';\n                div.style.opacity = '0';\n            });\n            \n            setTimeout(() => {\n                div.remove();\n            }, 1500);\n        }\n\n        function showFloatingScoreAtPos(amount, colorHex, worldPos) {\n            const screenPos = toScreenPosition(worldPos, camera);\n            \n            const div = document.createElement('div');\n            div.style.cssText = `\n                position: absolute;\n                left: ${screenPos.x}px;\n                top: ${screenPos.y}px;\n                transform: translate(-50%, -50%);\n                font-family: 'Orbitron', sans-serif;\n                font-size: 18px;\n                font-weight: 900;\n                color: ${colorHex || '#39ff14'};\n                text-shadow: 0 0 6px ${colorHex || '#39ff14'};\n                pointer-events: none;\n                z-index: 10005;\n                opacity: 1;\n                transition: transform 1.2s ease-out, opacity 1.2s ease-out;\n            `;\n            div.textContent = `+${amount}`;\n            document.body.appendChild(div);\n            \n            requestAnimationFrame(() => {\n                div.style.transform = 'translate(-50%, -80px) scale(1.2)';\n                div.style.opacity = '0';\n            });\n            \n            setTimeout(() => {\n                div.remove();\n            }, 1200);\n        }\n\n        let currentResistance = 0;\n        let liftAmount = 0;\n        let tiltX = 0;\n        let tiltZ = 0;\n\n        // Auto operation states for Simple mode\n        let autoDigActive = false;\n        let autoDigStage = 0; // 0: prepare/lower, 1: scoop/curl, 2: lift back\n        let autoDigTimer = 0;\n\n        let autoDumpActive = false;\n        let autoDumpStage = 0; // 0: tilt bucket down, 1: restore bucket\n        let autoDumpTimer = 0;\n\n        function triggerAutoDig() {\n            if (autoDigActive || autoDumpActive) return;\n            autoDigActive = true;\n            autoDigStage = 0;\n            autoDigTimer = 0;\n        }\n\n        function triggerAutoDump() {\n            if (autoDigActive || autoDumpActive) return;\n            autoDumpActive = true;\n            autoDumpStage = 0;\n            autoDumpTimer = 0;\n        }\n\n        function getBucketWorldPos() {\n            // Calculate bucket tip world position\n            const pos = new THREE.Vector3();\n            bucketGroup.getWorldPosition(pos);\n            // Offset to bucket tip (scaled 3x)\n            const tipOffset = new THREE.Vector3(0, -1.2, 2.4);\n            tipOffset.applyQuaternion(bucketGroup.getWorldQuaternion(new THREE.Quaternion()));\n            pos.add(tipOffset);\n            return pos;\n        }\n\n        function getBucketCenterWorldPos() {\n            const pos = new THREE.Vector3();\n            bucketGroup.getWorldPosition(pos);\n            // Offset to bucket center (scaled 3x), positioned slightly higher (y: 0.2) to showcase the gem proud of any bucket soil\n            const centerOffset = new THREE.Vector3(0, 0.2, 1.1);\n            centerOffset.applyQuaternion(bucketGroup.getWorldQuaternion(new THREE.Quaternion()));\n            pos.add(centerOffset);\n            return pos;\n        }\n\n        function update(dt) {\n            if (mode !== 'play') return;\n            if (isModalOpen) return;\n\n            // Apply excavator launch physics (explosion blowback / launch in air)\n            if (excavatorLaunchY > 0 || excavatorLaunchVY > 0) {\n                excavatorLaunchVY -= 35.0 * dt; // gravity deceleration\n                excavatorLaunchY += excavatorLaunchVY * dt;\n                \n                // Apply horizontal velocities\n                excState.x += excavatorLaunchVX * dt;\n                excState.z += excavatorLaunchVZ * dt;\n                \n                // Decay horizontal velocities\n                excavatorLaunchVX *= Math.exp(-4.0 * dt);\n                excavatorLaunchVZ *= Math.exp(-4.0 * dt);\n                \n                // Clamp to terrain boundaries\n                excState.x = Math.max(-TERRAIN_SIZE/2 + 3, Math.min(TERRAIN_SIZE/2 - 3, excState.x));\n                excState.z = Math.max(-TERRAIN_SIZE/2 + 3, Math.min(TERRAIN_SIZE/2 - 3, excState.z));\n                \n                // Tumble rotation\n                excavatorLaunchRotX = Math.sin(markerTime * 12.0) * 0.45 * Math.max(0, excavatorLaunchVY / 26.0);\n                excavatorLaunchRotZ = Math.cos(markerTime * 12.0) * 0.45 * Math.max(0, excavatorLaunchVY / 26.0);\n\n                if (excavatorLaunchY <= 0) {\n                    excavatorLaunchY = 0;\n                    excavatorLaunchVY = 0;\n                    excavatorLaunchVX = 0;\n                    excavatorLaunchVZ = 0;\n                    excavatorLaunchRotX = 0;\n                    excavatorLaunchRotZ = 0;\n                    \n                    // Landing dust/rubble impact particles\n                    spawnParticles(excavatorGroup.position, 15);\n                    if (audioBuffers['dirt_dump_sound']) {\n                        playSound('dirt_dump_sound', false, 0.8);\n                    }\n                }\n            }\n\n            // --- ZOMBIES, BASES & WALL DIGGING LOGIC ---\n            if (zombieSpawnReductionTimer > 0) {\n                zombieSpawnReductionTimer -= dt;\n            }\n\n            // Malfunction timer decay\n            if (excavatorMalfunctionTimer > 0) {\n                excavatorMalfunctionTimer -= dt;\n            }\n\n            // Bomber zombie spawn timer: spawn every 30 seconds\n            bomberSpawnTimer += dt;\n            if (bomberSpawnTimer >= 30.0) {\n                bomberSpawnTimer = 0;\n                spawnBomberZombie();\n            }\n\n            // Spawn new zombie every 15 seconds if there is no suppression timer active\n            if (zombieSpawnReductionTimer <= 0) {\n                zombieSpawnTimer += dt;\n                if (zombieSpawnTimer >= 15.0) {\n                    zombieSpawnTimer = 0;\n                    spawnZombie();\n                }\n            } else {\n                zombieSpawnTimer = 0; // reset spawn timer when suppressed\n            }\n\n            const bucketPos = getBucketWorldPos();\n            const terrainH = getTerrainHeight(bucketPos.x, bucketPos.z);\n            const penetration = Math.max(0, terrainH - bucketPos.y);\n            const hardness = config.terrain.hardness;\n\n            // Check if bucket is in correct posture\n            const isBucketAngleCorrect = excState.bucketAngle >= -0.65 && excState.bucketAngle <= 1.05;\n            const isTouchingTerrain = bucketPos.y <= terrainH + 0.5;\n            const manualCurl = keys['Space'] || keys['KeyZ'] || (currentControlMode === 'classic' && touchState.rightJoy.active && touchState.rightJoy.x < -0.1);\n            let armInputVal = 0;\n            if (currentControlMode !== 'simple') {\n                if (keys['ArrowRight']) armInputVal += 1;\n                if (keys['ArrowLeft']) armInputVal -= 1;\n            }\n            if (currentControlMode === 'classic' && touchState.leftJoy.active && Math.abs(touchState.leftJoy.y) > 0.1) {\n                armInputVal -= touchState.leftJoy.y;\n            }\n            const isDigging = isTouchingTerrain && isBucketAngleCorrect && (manualCurl || keys['ArrowLeft'] || armInputVal < -0.1 || autoDigActive);\n\n            // Zombie Bases Interaction Loop\n            zombieBases.forEach(base => {\n                if (base.hitCooldown > 0) base.hitCooldown -= dt;\n                if (base.destroyed) {\n                    base.respawnTimer -= dt;\n                    if (base.respawnTimer <= 0) {\n                        // Respawn base!\n                        base.destroyed = false;\n                        base.hp = 100;\n                        base.meshGroup.scale.set(1, 1, 1);\n                        base.hpBar.scale.set(1, 1, 1);\n                        base.hpBar.visible = true;\n                        base.hpBg.visible = true;\n                        spawnParticles(base.meshGroup.position, 10);\n                        if (audioBuffers['objective_complete_sound']) {\n                            playSound('objective_complete_sound', false, 0.4);\n                        }\n                    }\n                    return;\n                }\n\n                // Pulsate the core mesh of the alive zombie base\n                base.coreMesh.scale.setScalar(1 + Math.sin(markerTime * 5 + base.id) * 0.1);\n                base.meshGroup.lookAt(camera.position.x, base.meshGroup.position.y, camera.position.z); // health bar billboard\n\n                // Collision with active bucket digging\n                const distToBase = bucketPos.distanceTo(base.meshGroup.position);\n                if (distToBase < 3.5) {\n                    if (isDigging) {\n                        if (base.hitCooldown <= 0) {\n                            base.hp -= 50; // Two digs to reach 0 (100 -> 50 -> 0)\n                            base.hitCooldown = 1.0; // Cooldown to ensure distinct hits\n                            \n                            // Visual & Audio feedback for a \"hit\"\n                            spawnParticles(bucketPos, 10);\n                            if (audioBuffers['bucket_scoop_sound']) {\n                                playSound('bucket_scoop_sound', false, 0.6);\n                            }\n                        }\n                        \n                        base.hpBar.scale.x = Math.max(0, base.hp / base.maxHp);\n                        \n                        // Shake base mesh while digging contact is maintained\n                        base.meshGroup.position.x = base.x + (Math.random() - 0.5) * 0.4;\n                        base.meshGroup.position.z = base.z + (Math.random() - 0.5) * 0.4;\n\n                        if (base.hp <= 0) {\n                            // Destroy base!\n                            base.destroyed = true;\n                            base.respawnTimer = 120.0; // Respawns in 120 seconds (2 minutes)\n                            base.hpBar.visible = false;\n                            base.hpBg.visible = false;\n                            \n                            // Collapse/shrink animation\n                            base.meshGroup.scale.set(1, 0.1, 1);\n                            \n                            // Huge explosion of green zombie blood/slime particles\n                            spawnParticles(base.meshGroup.position, 25);\n                            \n                            // Play explosion/complete sound\n                            if (audioBuffers['objective_complete_sound']) {\n                                playSound('objective_complete_sound', false, 0.9);\n                            }\n\n                            // Give credits!\n                            updateCredits(300);\n                            showFloatingScoreAtPos(300, '#00ff66', base.meshGroup.position);\n                            basesDestroyedCount++;\n\n                            // Set zombie spawn reduction timer for 120 seconds (2 minutes)!\n                            zombieSpawnReductionTimer = 120.0;\n                        }\n                    }\n                } else {\n                    // Smoothly reset base shake\n                    base.meshGroup.position.x = THREE.MathUtils.lerp(base.meshGroup.position.x, base.x, 5 * dt);\n                    base.meshGroup.position.z = THREE.MathUtils.lerp(base.meshGroup.position.z, base.z, 5 * dt);\n                }\n            });\n\n            // Wall Digging Check (Indestructible walls, but allows shaking off relics)\n            for (let i = 0; i < monoliths.length; i++) {\n                const mono = monoliths[i];\n                if (mono.destroyed) continue;\n\n                const dx = bucketPos.x - mono.x;\n                const dz = bucketPos.z - mono.z;\n                const distToWall = Math.sqrt(dx*dx + dz*dz);\n                \n                // If bucket is close to the wall pillar and digging or moving forcefully\n                if (distToWall < (mono.width + mono.depth) / 2 + 1.8 && bucketPos.y < mono.height) {\n                    if (isDigging) {\n                        // Shake the wall very slightly for physical touch feedback, but never collapse or destroy it\n                        mono.mesh.position.x = mono.x + (Math.random() - 0.5) * 0.15;\n                        mono.mesh.position.z = mono.z + (Math.random() - 0.5) * 0.15;\n                        \n                        // Spawn rock debris particles\n                        if (Math.random() < 0.3) {\n                            spawnParticles(bucketPos, 2);\n                        }\n\n                        // Play a crunchy digging/impact sound\n                        if (Math.random() < 0.08 && audioBuffers['bucket_scoop_sound']) {\n                            playSound('bucket_scoop_sound', false, 0.4);\n                        }\n\n                        // Release embedded relics when digging without destroying the wall!\n                        mono.relics.forEach(relic => {\n                            if (!relic.released && Math.random() < 0.08) {\n                                relic.released = true;\n                                \n                                const relicWorldPos = new THREE.Vector3();\n                                relic.mesh.getWorldPosition(relicWorldPos);\n                                \n                                mono.mesh.remove(relic.mesh);\n                                if (relic.borderMesh) mono.mesh.remove(relic.borderMesh);\n                                \n                                relic.mesh.position.copy(relicWorldPos);\n                                relic.mesh.scale.set(1.5, 1.5, 1.5);\n                                scene.add(relic.mesh);\n\n                                const tid = treasures.length;\n                                treasures.push({\n                                    id: tid,\n                                    x: relicWorldPos.x,\n                                    y: getTerrainHeight(relicWorldPos.x, relicWorldPos.z),\n                                    z: relicWorldPos.z,\n                                    type: relic.typeInfo,\n                                    mesh: relic.mesh,\n                                    buriedY: getTerrainHeight(relicWorldPos.x, relicWorldPos.z),\n                                    exposed: true,\n                                    scooped: false,\n                                    collected: false\n                                });\n                                \n                                spawnParticles(relicWorldPos, 8);\n                            }\n                        });\n                    }\n                } else {\n                    // Reset position back to original when not being touched\n                    mono.mesh.position.x = THREE.MathUtils.lerp(mono.mesh.position.x, mono.x, 5 * dt);\n                    mono.mesh.position.z = THREE.MathUtils.lerp(mono.mesh.position.z, mono.z, 5 * dt);\n                }\n            }\n\n            // Zombie Update Loops and Collisions\n            let speedReduction = 0;\n            const ex = excavatorGroup.position.x;\n            const ez = excavatorGroup.position.z;\n\n            for (let zi = zombies.length - 1; zi >= 0; zi--) {\n                const z = zombies[zi];\n                if (z.state === 'dead') {\n                    z.deadTimer += dt;\n                    if (z.deadTimer > 2.0) {\n                        scene.remove(z.mesh);\n                        zombies.splice(zi, 1);\n                    }\n                    continue;\n                }\n\n                z.bobTimer += dt;\n\n                const dx = ex - z.x;\n                const dz = ez - z.z;\n                const distToExc = Math.sqrt(dx*dx + dz*dz);\n\n                // Flashing bomb light and tick warning sounds\n                if (z.isBomber && z.bombLightMat) {\n                    const flashInterval = z.fuseActive ? Math.max(0.04, z.fuseTimer * 0.12) : 0.25; // Blink much faster during fuse countdown!\n                    if (markerTime - z.lastBlinkTime > flashInterval) {\n                        z.lastBlinkTime = markerTime;\n                        z.blinkState = !z.blinkState;\n                        z.bombLightMat.color.setHex(z.blinkState ? 0xff0000 : 0x110000);\n                        if (distToExc < 15.0 && z.blinkState) {\n                            playSynthBeep(z.fuseActive ? 1800 : 1500, 0.03);\n                        }\n                    }\n                }\n\n                // Check collision with the bucket (smashed by bucket)\n                const distToBucket = bucketPos.distanceTo(z.mesh.position);\n                const isSmashedByBucket = distToBucket < 2.2;\n\n                // Proximity explosion check for bomb zombie\n                if (z.isBomber && !z.fuseActive && distToExc < 6.0) {\n                    z.fuseActive = true;\n                    z.fuseTimer = 2.0;\n                    playSynthBeep(1200, 0.2);\n                    \n                    const infoText = document.getElementById('info-text-element');\n                    if (infoText) {\n                        infoText.innerHTML = `<span style=\"color: #ff3300; font-weight: 900; text-shadow: 0 0 10px rgba(255,51,0,0.8); font-size: 22px;\">${t('bombTriggered')}</span><br><span style=\"font-size: 15px; color: #ffaa00;\">2.0s!</span>`;\n                        infoText.classList.add('visible');\n                        setTimeout(() => {\n                            if (!z.fuseActive || z.state === 'dead') {\n                                infoText.classList.remove('visible');\n                            }\n                        }, 2000);\n                    }\n                }\n\n                // If fuse is active, count down\n                if (z.isBomber && z.fuseActive) {\n                    z.fuseTimer -= dt;\n                    if (z.fuseTimer <= 0) {\n                        z.state = 'dead';\n                        scene.remove(z.mesh); // completely vaporized!\n\n                        // Explosion sound & visuals\n                        playSynthExplosion();\n\n                        const blastPos = z.mesh.position.clone();\n                        const fireCol = 0xff4500;\n                        const smokeCol = 0x2c3e50;\n                        const sparkCol = 0xffea00;\n                        \n                        for (let p = 0; p < 24; p++) {\n                            const col = Math.random() < 0.4 ? fireCol : (Math.random() < 0.7 ? smokeCol : sparkCol);\n                            const pMat = new THREE.MeshBasicMaterial({ color: col });\n                            const pMesh = new THREE.Mesh(particleGeo, pMat);\n                            pMesh.position.copy(blastPos);\n                            scene.add(pMesh);\n                            particles.push({\n                                mesh: pMesh,\n                                vel: new THREE.Vector3((Math.random() - 0.5) * 12, Math.random() * 8 + 3, (Math.random() - 0.5) * 12),\n                                life: 1.0 + Math.random() * 0.5\n                            });\n                        }\n\n                        // Camera/Screen Shake & chassis vibration\n                        cameraShakeIntensity = Math.min(2.5, cameraShakeIntensity + 1.8);\n                        excavatorShakeIntensity = Math.min(1.0, excavatorShakeIntensity + 1.0);\n\n                        // Malfunction check (only if player is still close to the explosion)\n                        if (distToExc < 5.0) {\n                            excavatorMalfunctionTimer = 2.0;\n\n                            // Display fault message immediately\n                            const infoText = document.getElementById('info-text-element');\n                            if (infoText) {\n                                infoText.innerHTML = `<span style=\"color: #ff3300; font-weight: 900; text-shadow: 0 0 15px rgba(255,51,0,0.9); font-size: 26px;\">${t('systemFault')}</span><br><span style=\"font-size: 16px; color: #ffaa00;\">${t('rebootIn')} 2.0s</span>`;\n                                infoText.classList.add('visible');\n                            }\n                        } else {\n                            const infoText = document.getElementById('info-text-element');\n                            if (infoText) {\n                                infoText.classList.remove('visible');\n                            }\n                        }\n\n                        continue;\n                    }\n                }\n\n                // Normal zombie run over by tracks check (or normal zombie hit check)\n                const isRunOver = !z.isBomber && distToExc < 3.0 && bucketPos.y > 1.2;\n\n                if (isSmashedByBucket || isRunOver) {\n                    z.state = 'dead';\n                    \n                    if (z.isBomber) {\n                        scene.remove(z.mesh); // completely remove\n                        \n                        // Cyber teal disarm explosion\n                        const disarmCol = 0x00ffcc;\n                        const disarmMat = new THREE.MeshBasicMaterial({ color: disarmCol });\n                        for (let p = 0; p < 15; p++) {\n                            const pMesh = new THREE.Mesh(particleGeo, disarmMat);\n                            pMesh.position.copy(z.mesh.position);\n                            scene.add(pMesh);\n                            particles.push({\n                                mesh: pMesh,\n                                vel: new THREE.Vector3((Math.random()-0.5)*5, Math.random()*4 + 1.5, (Math.random()-0.5)*5),\n                                life: 1.2\n                            });\n                        }\n                        \n                        updateCredits(150);\n                        showFloatingScoreAtPos(150, '#00ffcc', z.mesh.position);\n                        zombiesSlainCount++;\n                        \n                        const infoText = document.getElementById('info-text-element');\n                        if (infoText) {\n                            infoText.innerHTML = `<span style=\"color: #00ffcc; font-weight: 900; text-shadow: 0 0 10px rgba(0,255,204,0.8); font-size: 22px;\">${t('bombDisarmed')} (+150)</span>`;\n                            infoText.classList.add('visible');\n                            setTimeout(() => {\n                                infoText.classList.remove('visible');\n                            }, 2500);\n                        }\n                    } else {\n                        z.mesh.scale.y = 0.05; // Flattened!\n                        z.mesh.position.y = getTerrainHeight(z.x, z.z) + 0.02; // Rest on ground\n                        \n                        // Spawn toxic green blood splatters\n                        const bloodCol = 0x39ff14;\n                        const bloodMat = new THREE.MeshBasicMaterial({ color: bloodCol });\n                        for (let p = 0; p < 12; p++) {\n                            const bMesh = new THREE.Mesh(particleGeo, bloodMat);\n                            bMesh.position.copy(z.mesh.position);\n                            scene.add(bMesh);\n                            particles.push({\n                                mesh: bMesh,\n                                vel: new THREE.Vector3((Math.random()-0.5)*5, Math.random()*3 + 1, (Math.random()-0.5)*5),\n                                life: 1.0\n                            });\n                        }\n                        \n                        updateCredits(50);\n                        showFloatingScoreAtPos(50, '#39ff14', z.mesh.position);\n                        zombiesSlainCount++;\n                    }\n\n                    if (audioBuffers['dirt_dump_sound']) {\n                        playSound('dirt_dump_sound', false, 0.5);\n                    }\n                    continue;\n                }\n\n                // Crawl on excavator causing speed penalty\n                if (z.isBomber && z.fuseActive) {\n                    // Bomber is frozen/stopped!\n                    z.y = getTerrainHeight(z.x, z.z);\n                    z.mesh.position.set(z.x, z.y, z.z);\n                    z.mesh.lookAt(ex, z.y, ez);\n\n                    // Rapid head bobbing angrily as fuse ticks down\n                    z.mesh.children[0].position.y = 0.6 + Math.sin(z.bobTimer * 18) * 0.12;\n                    \n                    // Rapid arm swinging\n                    if (z.armL && z.armR) {\n                        z.armL.rotation.x = Math.sin(z.bobTimer * 25) * 1.2;\n                        z.armR.rotation.x = -Math.sin(z.bobTimer * 25) * 1.2;\n                    }\n                } else if (distToExc < 3.2) {\n                    z.interfereTimer += dt;\n                    speedReduction += 0.20; // 20% speed reduction per zombie\n                    \n                    // Stand in place on the terrain\n                    z.y = getTerrainHeight(z.x, z.z);\n                    z.mesh.position.set(z.x, z.y, z.z);\n                    z.mesh.lookAt(ex, z.y, ez);\n\n                    // Head bobbing angrily during attack\n                    z.mesh.children[0].position.y = 0.6 + Math.sin(z.bobTimer * 12) * 0.08;\n\n                    // Attack animation with arms swinging up and down rapidly\n                    if (z.armL && z.armR) {\n                        z.armL.rotation.x = Math.sin(z.bobTimer * 20) * 1.0;\n                        z.armR.rotation.x = -Math.sin(z.bobTimer * 20) * 1.0;\n                    }\n                } else {\n                    const moveX = (dx / distToExc) * z.speed * dt;\n                    const moveZ = (dz / distToExc) * z.speed * dt;\n                    z.x += moveX;\n                    z.z += moveZ;\n                    z.y = getTerrainHeight(z.x, z.z);\n\n                    z.mesh.position.set(z.x, z.y, z.z);\n                    z.mesh.lookAt(ex, z.y, ez);\n\n                    z.mesh.children[0].position.y = 0.6 + Math.sin(z.bobTimer * 8) * 0.1;\n                    z.mesh.position.y = z.y + Math.abs(Math.sin(z.bobTimer * 6)) * 0.15;\n\n                    // Standard zombie arm swing motion\n                    if (z.armL && z.armR) {\n                        z.armL.rotation.x = Math.sin(z.bobTimer * 6) * 0.4;\n                        z.armR.rotation.x = -Math.sin(z.bobTimer * 6) * 0.4;\n                    }\n                }\n            }\n\n            const zombieSpeedFactor = Math.max(0.3, 1.0 - speedReduction);\n            // ------------------------------------\n\n            // Decay excavator vibration shaking over time\n            if (typeof excavatorShakeIntensity !== 'undefined' && excavatorShakeIntensity > 0) {\n                excavatorShakeIntensity = Math.max(0, excavatorShakeIntensity - dt * 2.0);\n            }\n\n            // Decay camera/screen shake over time\n            if (typeof cameraShakeIntensity !== 'undefined' && cameraShakeIntensity > 0) {\n                cameraShakeIntensity = Math.max(0, cameraShakeIntensity - dt * 4.0);\n            }\n\n            // Handle system fault UI overlay when malfunctioning\n            if (excavatorMalfunctionTimer > 0) {\n                wasMalfunctioning = true;\n                const infoText = document.getElementById('info-text-element');\n                if (infoText) {\n                    infoText.innerHTML = `<span style=\"color: #ff3300; font-weight: 900; text-shadow: 0 0 15px rgba(255,51,0,0.9); font-size: 26px;\">${t('systemFault')}</span><br><span style=\"font-size: 16px; color: #ffaa00;\">${t('rebootIn')} ${excavatorMalfunctionTimer.toFixed(1)}s</span>`;\n                    infoText.classList.add('visible');\n                }\n                \n                // Spawn mechanical short-circuit spark particles on the excavator body\n                if (Math.random() < 0.25) {\n                    const sparkPos = new THREE.Vector3();\n                    excavatorGroup.getWorldPosition(sparkPos);\n                    sparkPos.y += 1.5; // near engine/cabin\n                    sparkPos.x += (Math.random() - 0.5) * 2;\n                    sparkPos.z += (Math.random() - 0.5) * 2;\n                    \n                    const pMesh = new THREE.Mesh(particleGeo, new THREE.MeshBasicMaterial({ color: 0x00e5ff }));\n                    pMesh.position.copy(sparkPos);\n                    scene.add(pMesh);\n                    particles.push({\n                        mesh: pMesh,\n                        vel: new THREE.Vector3((Math.random() - 0.5) * 4, Math.random() * 3 + 1, (Math.random() - 0.5) * 4),\n                        life: 0.6\n                    });\n                }\n            } else if (wasMalfunctioning) {\n                wasMalfunctioning = false;\n                const infoText = document.getElementById('info-text-element');\n                if (infoText) {\n                    infoText.classList.remove('visible');\n                }\n            }\n\n            // --- SANDWORM AI, ATTACK & COLLISION PROTOCOL ---\n            if (typeof sandworms !== 'undefined' && sandworms.length > 0) {\n                for (let si = sandworms.length - 1; si >= 0; si--) {\n                    const sw = sandworms[si];\n                    if (sw.state === 'dead') continue;\n\n                    // 1. Sleeping detection: wake up if dug up\n                    const currentTh = getTerrainHeight(sw.x, sw.z);\n                    if (sw.state === 'sleeping') {\n                        if (currentTh <= sw.buriedY + 0.1) {\n                            sw.state = 'emerging';\n                            sw.emergenceProgress = 0;\n                            \n                            // Spawn emergence purple particles\n                            spawnParticles(sw.meshGroup.position, 15);\n                            \n                            if (audioBuffers['bucket_scoop_sound']) {\n                                playSound('bucket_scoop_sound', false, 0.9);\n                            }\n                            \n                            // Alert HUD popup\n                            const infoText = document.getElementById('info-text-element');\n                            if (infoText) {\n                                infoText.innerHTML = `<span style=\"color: #ff00ff; font-weight: 900; text-shadow: 0 0 15px rgba(255,0,255,0.8); font-size: 24px;\">${t('warning')}</span><br><span style=\"font-size: 16px; color: #da70d6;\">${t('warnSandworm')}</span>`;\n                                infoText.classList.add('visible');\n                                setTimeout(() => {\n                                    infoText.classList.remove('visible');\n                                }, 4000);\n                            }\n                        }\n                        continue; // Skip movement/combat if sleeping\n                    }\n\n                    if (sw.hitCooldown > 0) sw.hitCooldown -= dt;\n\n                    // 2. Emerging state\n                    if (sw.state === 'emerging') {\n                        sw.emergenceProgress += dt * 1.5;\n                        const targetHeight = getTerrainHeight(sw.x, sw.z);\n                        sw.meshGroup.position.y = THREE.MathUtils.lerp(sw.buriedY, targetHeight + 0.5, sw.emergenceProgress);\n                        sw.meshGroup.rotation.y += dt * 5.0; // spin as it crawls up!\n                        \n                        if (sw.emergenceProgress >= 1.0) {\n                            sw.state = 'active';\n                        }\n                        \n                        // Shake excavator slightly during emergence\n                        excavatorShakeIntensity = Math.max(excavatorShakeIntensity, 0.35);\n                        continue;\n                    }\n\n                    // 3. Active AI state (Chase & Attack)\n                    if (sw.state === 'active') {\n                        const ex = excavatorGroup.position.x;\n                        const ez = excavatorGroup.position.z;\n                        const dx = ex - sw.x;\n                        const dz = ez - sw.z;\n                        const distToExc = Math.sqrt(dx * dx + dz * dz);\n\n                        // Face and chase the excavator\n                        const targetAngle = Math.atan2(dx, dz);\n                        let angleDiff = targetAngle - sw.meshGroup.rotation.y;\n                        angleDiff = Math.atan2(Math.sin(angleDiff), Math.cos(angleDiff));\n                        sw.meshGroup.rotation.y += angleDiff * dt * 3.5;\n\n                        // Incremental slitherTime in active state for continuous breathing/slithering\n                        sw.slitherTime += dt * 6.5;\n\n                        if (distToExc > 4.5) {\n                            // Chase/Slither\n                            const wormSpeed = 3.8;\n                            sw.x += Math.sin(sw.meshGroup.rotation.y) * wormSpeed * dt;\n                            sw.z += Math.cos(sw.meshGroup.rotation.y) * wormSpeed * dt;\n                            sw.y = getTerrainHeight(sw.x, sw.z);\n                            sw.meshGroup.position.set(sw.x, sw.y + 0.5, sw.z);\n\n                            sw.headGroup.position.set(0, 0, 0); // reset head lunge\n                        } else {\n                            // Attack!\n                            sw.attackTimer += dt;\n                            \n                            // Rear back and lunge forward animation\n                            const lungeAngle = (sw.attackTimer * 4.0) % (Math.PI * 2);\n                            const lungeZ = -Math.sin(lungeAngle) * 1.8;\n                            sw.headGroup.position.z = lungeZ;\n                            sw.headGroup.position.y = Math.max(0, Math.cos(lungeAngle) * 0.8);\n\n                            // Trigger excavator vibration\n                            excavatorShakeIntensity = Math.min(1.0, excavatorShakeIntensity + dt * 1.8);\n                        }\n\n                        // Slithering body wave and peristaltic contraction animation (simulating organic locomotion)\n                        sw.segments.forEach((seg, idx) => {\n                            const wave = Math.sin(sw.slitherTime - idx * 0.8) * 0.5;\n                            seg.position.x = wave;\n                            seg.position.y = Math.cos(sw.slitherTime - idx * 0.8) * 0.25;\n\n                            // Organic peristaltic breathing contraction\n                            const pulse = 1.0 + Math.sin(sw.slitherTime * 1.5 - idx * 1.2) * 0.12;\n                            seg.scale.set(pulse, pulse, pulse);\n                        });\n\n                        // Wriggle the mouth feelers organically\n                        if (sw.feelers) {\n                            sw.feelers.forEach((feeler, fIdx) => {\n                                const feelerWave = Math.sin(sw.slitherTime * 2.5 + fIdx) * 0.15;\n                                feeler.rotation.z = feelerWave;\n                                feeler.rotation.y = Math.cos(sw.slitherTime * 2.5 + fIdx) * 0.15;\n                            });\n                        }\n\n                        // 4. Hit detection: Bucket collision\n                        const distToBucket = bucketPos.distanceTo(sw.meshGroup.position);\n                        if (distToBucket < 4.2 && isDigging && sw.hitCooldown <= 0) {\n                            sw.hp--;\n                            sw.hitCooldown = 1.0;\n\n                            // Award credits on hit\n                            updateCredits(100);\n\n                            // Blast purple particles!\n                            spawnParticles(bucketPos, 15);\n                            if (audioBuffers['bucket_scoop_sound']) {\n                                playSound('bucket_scoop_sound', false, 0.8);\n                            }\n\n                            excavatorShakeIntensity = 1.0;\n\n                            const infoText = document.getElementById('info-text-element');\n                            if (infoText) {\n                                infoText.innerHTML = `<span style=\"color: #ff00ff; font-weight: 900; text-shadow: 0 0 10px rgba(255,0,255,0.8); font-size: 22px;\">${t('bucketImpact')}</span><br><span style=\"font-size: 15px; color: #fff;\">${t('sandwormHp').replace('{hp}', sw.hp)}</span>`;\n                                infoText.classList.add('visible');\n                                setTimeout(() => {\n                                    infoText.classList.remove('visible');\n                                }, 1500);\n                            }\n                        }\n\n                        // 5. Hit detection: Track/Body collision (\u649e\u51fb)\n                        if (distToExc < 4.2 && sw.hitCooldown <= 0) {\n                            sw.hp--;\n                            sw.hitCooldown = 1.2;\n\n                            // Award credits on hit\n                            updateCredits(100);\n\n                            // Blast dust particles from tracks\n                            spawnParticles(excavatorGroup.position, 15);\n                            if (audioBuffers['dirt_dump_sound']) {\n                                playSound('dirt_dump_sound', false, 0.8);\n                            }\n\n                            excavatorShakeIntensity = 1.0;\n\n                            const infoText = document.getElementById('info-text-element');\n                            if (infoText) {\n                                infoText.innerHTML = `<span style=\"color: #ff00ff; font-weight: 900; text-shadow: 0 0 10px rgba(255,0,255,0.8); font-size: 22px;\">${t('trackCollision')}</span><br><span style=\"font-size: 15px; color: #fff;\">${t('sandwormHp').replace('{hp}', sw.hp)}</span>`;\n                                infoText.classList.add('visible');\n                                setTimeout(() => {\n                                    infoText.classList.remove('visible');\n                                }, 1500);\n                            }\n                        }\n\n                        // 6. Death sequence\n                        if (sw.hp <= 0) {\n                            sw.state = 'dead';\n                            const deathPos = sw.meshGroup.position.clone();\n                            const purpleCol = 0xda70d6;\n                            const purpleMat = new THREE.MeshBasicMaterial({ color: purpleCol });\n                            for (let p = 0; p < 25; p++) {\n                                const pMesh = new THREE.Mesh(particleGeo, purpleMat);\n                                pMesh.position.copy(deathPos);\n                                scene.add(pMesh);\n                                particles.push({\n                                    mesh: pMesh,\n                                    vel: new THREE.Vector3((Math.random()-0.5)*7, Math.random()*5 + 2, (Math.random()-0.5)*7),\n                                    life: 1.5\n                                });\n                            }\n\n                            // Play glorious chime\n                            if (audioBuffers['objective_complete_sound']) {\n                                playSound('objective_complete_sound', false, 1.0);\n                            }\n\n                            // Sinking death animation\n                            let sinkProg = 0;\n                            const animateWormSink = () => {\n                                sinkProg += 0.05;\n                                sw.meshGroup.position.y -= 0.15;\n                                sw.meshGroup.scale.multiplyScalar(0.92);\n                                if (sinkProg < 1.0) {\n                                    requestAnimationFrame(animateWormSink);\n                                } else {\n                                    scene.remove(sw.meshGroup);\n                                }\n                            };\n                            animateWormSink();\n\n                            updateCredits(800);\n\n                            // Spawn collectible purple gem dropped on the ground\n                            const gemType = treasureTypes.find(t => t.id === 'purple_gem') || { id: 'purple_gem', name: 'Sandworm Heart Gem', color: 0xda00ff, score: 500, emoji: '\ud83d\udc9c' };\n                            const gemGroup = createTreasureGroup(gemType);\n                            const finalY = getTerrainHeight(deathPos.x, deathPos.z);\n                            gemGroup.position.set(deathPos.x, finalY - 0.4, deathPos.z);\n                            gemGroup.scale.set(1.5, 1.5, 1.5);\n                            scene.add(gemGroup);\n\n                            // Create glowing rings for dropped gem!\n                            const ringGeo = new THREE.RingGeometry(1.5, 1.7, 16);\n                            ringGeo.rotateX(-Math.PI / 2);\n                            const ringMat = new THREE.MeshBasicMaterial({\n                                color: 0xda00ff,\n                                side: THREE.DoubleSide,\n                                transparent: true,\n                                opacity: 0.6\n                            });\n                            const ringMesh = new THREE.Mesh(ringGeo, ringMat);\n                            ringMesh.position.set(deathPos.x, finalY + 0.05, deathPos.z);\n                            scene.add(ringMesh);\n\n                            const discGeo = new THREE.CylinderGeometry(1.5, 1.5, 0.02, 16);\n                            const discMat = new THREE.MeshBasicMaterial({\n                                color: 0xda00ff,\n                                transparent: true,\n                                opacity: 0.2\n                            });\n                            const discMesh = new THREE.Mesh(discGeo, discMat);\n                            discMesh.position.set(deathPos.x, finalY + 0.04, deathPos.z);\n                            scene.add(discMesh);\n\n                            const tid = treasures.length;\n                            treasures.push({\n                                id: tid,\n                                x: deathPos.x,\n                                y: finalY - 0.4,\n                                z: deathPos.z,\n                                type: gemType,\n                                score: gemType.score,\n                                mesh: gemGroup,\n                                ringMesh: ringMesh,\n                                discMesh: discMesh,\n                                buriedY: finalY,\n                                exposed: true,\n                                scooped: false,\n                                collected: false,\n                                isTitanPart: false\n                            });\n\n                            const infoText = document.getElementById('info-text-element');\n                            if (infoText) {\n                                infoText.innerHTML = `<span style=\"color: #00ff66; font-weight: 900; text-shadow: 0 0 15px rgba(0,255,102,0.8); font-size: 24px;\">${t('sandwormSlain')}</span><br><span style=\"font-size: 16px; color: #ffd700;\">+800 ${t('credits')}!</span>`;\n                                infoText.classList.add('visible');\n                                setTimeout(() => {\n                                    infoText.classList.remove('visible');\n                                }, 4000);\n                            }\n\n                            checkMissionCompletion();\n                            updateObjectiveUI();\n                            updateTreasureUI();\n                        }\n                    }\n                }\n            }\n\n            // --- ALIEN LANDMINE UPDATE LOOP ---\n            for (let mi = landmines.length - 1; mi >= 0; mi--) {\n                const mine = landmines[mi];\n                if (mine.state === 'exploded') continue;\n\n                const currentTh = getTerrainHeight(mine.x, mine.z);\n\n                const dxToExc = excState.x - mine.x;\n                const dzToExc = excState.z - mine.z;\n                const distToExcBase = Math.sqrt(dxToExc * dxToExc + dzToExc * dzToExc);\n\n                // Directly stepping/driving on a mine triggers INSTANT detonation!\n                if (distToExcBase < 3.0) {\n                    mine.state = 'triggered';\n                    mine.fuseTimer = 0; // Detonate instantly!\n                }\n\n                // Update warning ring animations\n                if (mine.warningRing) {\n                    // Rotate the warning ring\n                    mine.warningRing.rotation.z += dt * 1.5;\n                    // Pulse scale and opacity\n                    const pulse = Math.sin(markerTime * 5.0 + mine.id) * 0.12;\n                    mine.warningRing.scale.set(1.0 + pulse, 1.0 + pulse, 1.0 + pulse);\n                    \n                    if (mine.state === 'triggered') {\n                        // Rapid alert flash\n                        mine.warningRingMat.color.setHex(0xff0000);\n                        mine.warningRingMat.opacity = 0.4 + Math.sin(markerTime * 15.0) * 0.4;\n                    } else {\n                        // Standard breathing glow\n                        mine.warningRingMat.opacity = 0.35 + Math.sin(markerTime * 4.0 + mine.id) * 0.15;\n                    }\n                }\n\n                if (mine.state === 'buried') {\n                    // Keep the landmine mesh sitting proud on the terrain surface\n                    mine.meshGroup.position.y = currentTh - mine.depth;\n\n                    // Slow blinking of warning LED\n                    const blinkInterval = 0.8;\n                    if (markerTime - mine.lastBlinkTime > blinkInterval) {\n                        mine.lastBlinkTime = markerTime;\n                        mine.blinkState = !mine.blinkState;\n                        mine.ledMaterial.color.setHex(mine.blinkState ? 0xffaa00 : 0x221100);\n                    }\n\n                    // Trigger detection: bucket proximity and digging action OR terrain excavated below its original level\n                    const distToBucket = bucketPos.distanceTo(mine.meshGroup.position);\n                    const isSmashed = distToBucket < 3.2 && isDigging;\n\n                    if (currentTh < mine.buriedY - 0.15 || isSmashed) {\n                        mine.state = 'triggered';\n                        mine.meshGroup.position.y = currentTh;\n                        mine.ledMaterial.color.setHex(0xff0000); // Glowing solid red on trigger\n\n                        // Notification alert\n                        const infoText = document.getElementById('info-text-element');\n                        if (infoText) {\n                            infoText.innerHTML = `<span style=\"color: #ff3300; font-weight: 900; text-shadow: 0 0 10px rgba(255,51,0,0.8); font-size: 24px;\">${t('warning')}</span><br><span style=\"font-size: 16px; color: #ffaa00;\">${t('warnLandmine')}</span>`;\n                            infoText.classList.add('visible');\n                            setTimeout(() => {\n                                infoText.classList.remove('visible');\n                            }, 2000);\n                        }\n                        \n                        // play initial trigger warning beep\n                        playSynthBeep(1000, 0.15);\n                    }\n                }\n\n                if (mine.state === 'triggered') {\n                    // Stay flush with current deforming terrain surface\n                    mine.meshGroup.position.y = currentTh;\n\n                    mine.fuseTimer -= dt;\n\n                    // Blinking alarm and beeping that accelerates as fuse goes down\n                    const blinkInterval = Math.max(0.06, mine.fuseTimer * 0.18);\n                    if (markerTime - mine.lastBlinkTime > blinkInterval) {\n                        mine.lastBlinkTime = markerTime;\n                        mine.blinkState = !mine.blinkState;\n                        mine.ledMaterial.color.setHex(mine.blinkState ? 0xff0000 : 0x1a0000);\n                        \n                        // Beeping sound (frequency increases as fuse ticks down)\n                        const frequency = mine.blinkState ? 900 + (2.0 - mine.fuseTimer) * 200 : 1300 + (2.0 - mine.fuseTimer) * 200;\n                        playSynthBeep(frequency, 0.05);\n                    }\n\n                    if (mine.fuseTimer <= 0) {\n                        mine.state = 'exploded';\n\n                        // 1. Blast a huge crater (sand pit) in the deforming terrain heightmap!\n                        modifyTerrain(mine.x, mine.z, -5.5, 5.0);\n\n                        // 2. Play explosion audio\n                        playSynthExplosion();\n\n                        // 3. Spawn a glorious shockwave particle system of flames, smoke and sand rubble\n                        const blastPos = mine.meshGroup.position.clone();\n                        blastPos.y = getTerrainHeight(mine.x, mine.z); // center on the new crater floor\n                        \n                        const fireCol = 0xff4500; // orange flames\n                        const smokeCol = 0x2c3e50; // dark thick smoke\n                        const sparkCol = 0xffd700; // bright gold sparks\n                        \n                        for (let p = 0; p < 36; p++) {\n                            const col = Math.random() < 0.4 ? fireCol : (Math.random() < 0.7 ? smokeCol : sparkCol);\n                            const pMat = new THREE.MeshBasicMaterial({ color: col });\n                            const pMesh = new THREE.Mesh(particleGeo, pMat);\n                            pMesh.position.copy(blastPos);\n                            scene.add(pMesh);\n                            particles.push({\n                                mesh: pMesh,\n                                vel: new THREE.Vector3(\n                                    (Math.random() - 0.5) * 16, \n                                    Math.random() * 11 + 4, \n                                    (Math.random() - 0.5) * 16\n                                ),\n                                life: 1.0 + Math.random() * 0.9\n                            });\n                        }\n\n                        // 4. Trigger screen shake & heavy track vibration\n                        cameraShakeIntensity = Math.min(2.2, cameraShakeIntensity + 1.8);\n                        excavatorShakeIntensity = Math.min(1.0, excavatorShakeIntensity + 1.0);\n\n                        // 5. Check physical shockwave collision with excavator\n                        const exX = excavatorGroup.position.x;\n                        const exZ = excavatorGroup.position.z;\n                        const dx = exX - mine.x;\n                        const dz = exZ - mine.z;\n                        const distToExc = Math.sqrt(dx*dx + dz*dz);\n                        \n                        if (distToExc < 8.5) {\n                            // Push the heavy excavator tracks away from blast center\n                            const pushForce = (8.5 - distToExc) * 1.35;\n                            excState.x += (dx / distToExc) * pushForce;\n                            excState.z += (dz / distToExc) * pushForce;\n\n                            if (distToExc < 3.5) {\n                                // Launch the excavator high up!\n                                excavatorLaunchVY = 26.0;\n                                excavatorLaunchY = 0.1;\n                                const dirX = distToExc > 0.1 ? (dx / distToExc) : (Math.random() - 0.5);\n                                const dirZ = distToExc > 0.1 ? (dz / distToExc) : (Math.random() - 0.5);\n                                const mag = Math.sqrt(dirX*dirX + dirZ*dirZ);\n                                excavatorLaunchVX = (dirX / mag) * 16.0;\n                                excavatorLaunchVZ = (dirZ / mag) * 16.0;\n                                excavatorMalfunctionTimer = 2.5;\n\n                                const infoText = document.getElementById('info-text-element');\n                                if (infoText) {\n                                    infoText.innerHTML = `<span style=\"color: #ff3300; font-weight: 900; text-shadow: 0 0 15px rgba(255,51,0,0.9); font-size: 26px;\">${t('launched')}</span><br><span style=\"font-size: 16px; color: #ffaa00;\">${t('rebootIn')} 2.5s</span>`;\n                                    infoText.classList.add('visible');\n                                    setTimeout(() => {\n                                        infoText.classList.remove('visible');\n                                    }, 3500);\n                                }\n                            } else {\n                                const infoText = document.getElementById('info-text-element');\n                                if (infoText) {\n                                    infoText.innerHTML = `<span style=\"color: #ff3300; font-weight: 900; text-shadow: 0 0 10px rgba(255,51,0,0.8); font-size: 22px;\">${t('blastWave')}</span>`;\n                                    infoText.classList.add('visible');\n                                    setTimeout(() => {\n                                        infoText.classList.remove('visible');\n                                    }, 2000);\n                                }\n                            }\n                        }\n\n                        // 6. Kill any green zombies in the blast radius!\n                        zombies.forEach(z => {\n                            if (z.state === 'alive') {\n                                const zDx = z.x - mine.x;\n                                const zDz = z.z - mine.z;\n                                const zDist = Math.sqrt(zDx*zDx + zDz*zDz);\n                                if (zDist < 6.5) {\n                                    z.state = 'dead';\n                                    z.mesh.scale.y = 0.05;\n                                    z.mesh.position.y = getTerrainHeight(z.x, z.z) + 0.02;\n\n                                    updateCredits(50);\n                                    showFloatingScoreAtPos(50, '#39ff14', z.mesh.position);\n                                    zombiesSlainCount++;\n\n                                    // green blood particles\n                                    const bloodMat = new THREE.MeshBasicMaterial({ color: 0x39ff14 });\n                                    for (let p = 0; p < 8; p++) {\n                                        const bMesh = new THREE.Mesh(particleGeo, bloodMat);\n                                        bMesh.position.copy(z.mesh.position);\n                                        scene.add(bMesh);\n                                        particles.push({\n                                            mesh: bMesh,\n                                            vel: new THREE.Vector3((Math.random()-0.5)*5, Math.random()*3 + 1, (Math.random()-0.5)*5),\n                                            life: 1.0\n                                        });\n                                    }\n                                }\n                            }\n                        });\n\n                        // 7. Damage any active sandworms caught in the blast!\n                        sandworms.forEach(sw => {\n                            if (sw.state === 'active') {\n                                const sDx = sw.x - mine.x;\n                                const sDz = sw.z - mine.z;\n                                const sDist = Math.sqrt(sDx*sDx + sDz*sDz);\n                                if (sDist < 8.0) {\n                                    sw.hp = Math.max(1, sw.hp - 3); // takes 3 heavy hits of damage!\n                                    spawnParticles(sw.meshGroup.position, 8);\n                                }\n                            }\n                        });\n\n                        // 8. Remove the mine group from Three.js scene\n                        scene.remove(mine.meshGroup);\n                    }\n                }\n            }\n\n            const speed = config.excavator.speed;\n            const armSpeed = 1.0 * speed;\n\n            // Interaction resistance scales with depth and terrain hardness\n            currentResistance = Math.min(1.0, penetration * 1.5 * hardness);\n            const movementFactor = (1.0 - (currentResistance * 0.7)) * zombieSpeedFactor;\n\n            // Calculate realistic track/cabin tilt and lift due to bucket push force\n            if (penetration > 0.05) {\n                const upperYaw = excState.rotation + excState.upperRotation;\n                // Upward ground force lifts chassis and tilts it away from bucket position\n                liftAmount = THREE.MathUtils.lerp(liftAmount, penetration * 0.5 * hardness, 10 * dt);\n                tiltX = THREE.MathUtils.lerp(tiltX, -Math.cos(upperYaw) * penetration * 0.12 * hardness, 10 * dt);\n                tiltZ = THREE.MathUtils.lerp(tiltZ, Math.sin(upperYaw) * penetration * 0.12 * hardness, 10 * dt);\n            } else {\n                liftAmount = THREE.MathUtils.lerp(liftAmount, 0, 8 * dt);\n                tiltX = THREE.MathUtils.lerp(tiltX, 0, 8 * dt);\n                tiltZ = THREE.MathUtils.lerp(tiltZ, 0, 8 * dt);\n            }\n\n            // Engine load sound effect (pitch/volume modulation based on resistance)\n            if (engineSound && audioCtx) {\n                try {\n                    engineSound.source.playbackRate.setTargetAtTime(1.0 + currentResistance * 0.4, audioCtx.currentTime, 0.1);\n                    engineSound.gain.gain.setTargetAtTime(0.2 + currentResistance * 0.25, audioCtx.currentTime, 0.1);\n                } catch(e) {}\n            }\n\n            // Track Movement & Steering\n            let driveFwd = 0;\n            let turnInput = 0;\n\n            if (excavatorMalfunctionTimer <= 0) {\n                if (currentControlMode === 'simple') {\n                    if (touchState.leftJoy.active) {\n                        const jx = touchState.leftJoy.x;\n                        const jy = touchState.leftJoy.y;\n                        const mag = Math.sqrt(jx * jx + jy * jy);\n                        if (mag > 0.05) {\n                            // Calculate target angle based on camera horizontal angle and joystick direction\n                            const targetAngle = camState.azimuth + Math.atan2(-jx, -jy) + Math.PI;\n                            \n                            // Smoothly rotate tracks towards target direction (scaled by movement factors)\n                            let diff = targetAngle - excState.rotation;\n                            diff = Math.atan2(Math.sin(diff), Math.cos(diff));\n                            excState.rotation += diff * 10 * movementFactor * dt;\n                            \n                            // Drive forward in the direction of the tracks' arrow\n                            driveFwd = mag;\n                        }\n                    }\n                    // Keyboard fallback for simple mode (W/S or Up/Down to drive, A/D or Left/Right to turn)\n                    if (keys['KeyW'] || keys['w'] || keys['W'] || keys['ArrowUp']) driveFwd += 1;\n                    if (keys['KeyS'] || keys['s'] || keys['S'] || keys['ArrowDown']) driveFwd -= 1;\n                    if (keys['KeyA'] || keys['a'] || keys['A'] || keys['ArrowLeft']) turnInput -= 1;\n                    if (keys['KeyD'] || keys['d'] || keys['D'] || keys['ArrowRight']) turnInput += 1;\n                } else {\n                    if (keys['KeyW'] || keys['w'] || keys['W'] || touchState.drive.fwd) driveFwd += 1;\n                    if (keys['KeyS'] || keys['s'] || keys['S'] || touchState.drive.back) driveFwd -= 1;\n                    if (keys['KeyA'] || keys['a'] || keys['A'] || touchState.drive.left) turnInput -= 1;\n                    if (keys['KeyD'] || keys['d'] || keys['D'] || touchState.drive.right) turnInput += 1;\n                }\n            }\n\n            // Apply movement in excavator's facing direction (impacted by soil resistance if dragging bucket)\n            if (driveFwd !== 0 || turnInput !== 0) {\n                const moveSpeed = 4 * speed * movementFactor * dt;\n                const rotSpeed = 1.5 * speed * movementFactor * dt;\n\n                // Turn the vehicle base left/right when driving or steering\n                if (turnInput !== 0) {\n                    excState.rotation -= turnInput * rotSpeed;\n                }\n\n                // Move forward or backward along facing heading\n                if (driveFwd !== 0) {\n                    const angle = excState.rotation;\n                    const dx = Math.sin(angle) * driveFwd * moveSpeed;\n                    const dz = Math.cos(angle) * driveFwd * moveSpeed;\n\n                    excState.x += dx;\n                    excState.z += dz;\n                }\n\n                // Clamp to terrain\n                excState.x = Math.max(-TERRAIN_SIZE/2 + 3, Math.min(TERRAIN_SIZE/2 - 3, excState.x));\n                excState.z = Math.max(-TERRAIN_SIZE/2 + 3, Math.min(TERRAIN_SIZE/2 - 3, excState.z));\n            }\n\n            // Left Joystick / Keys: Swing Base Left/Right (Impacted by resistance)\n            let rotInput = 0;\n            if (excavatorMalfunctionTimer <= 0) {\n                if (currentControlMode === 'simple') {\n                    if (touchState.drive.cabL) rotInput -= 1.0;\n                    if (touchState.drive.cabR) rotInput += 1.0;\n                    // Q/E keyboard fallback in Simple Mode\n                    if (keys['KeyQ'] || keys['q'] || keys['Q']) rotInput -= 1;\n                    if (keys['KeyE'] || keys['e'] || keys['E']) rotInput += 1;\n                } else {\n                    if (keys['KeyQ'] || keys['q'] || keys['Q']) rotInput -= 1;\n                    if (keys['KeyE'] || keys['e'] || keys['E']) rotInput += 1;\n                    if (touchState.leftJoy.active && Math.abs(touchState.leftJoy.x) > 0.1) {\n                        rotInput += touchState.leftJoy.x;\n                    }\n                }\n            }\n\n            // Apply rotation if no auto-actions are overriding\n            if (rotInput !== 0 && !autoDigActive && !autoDumpActive) {\n                const rotDelta = rotInput * 1.5 * speed * movementFactor * dt;\n                excState.upperRotation += rotDelta;\n                totalRotation += Math.abs(rotDelta);\n                checkMissionCompletion();\n                updateObjectiveUI();\n            }\n\n            if (excavatorMalfunctionTimer > 0) {\n                autoDigActive = false;\n                autoDumpActive = false;\n            }\n\n            // Handle Auto Digging / Dumping Sequencers first, else handle manual\n            let curlActive = false;\n            let dumpActive = false;\n            let armInput = 0;\n            let boomInput = 0;\n\n            if (autoDigActive) {\n                const lerpSpeed = 3.0 * dt;\n                if (autoDigStage === 0) {\n                    // Phase 0: Lower boom, extend arm, tilt bucket open\n                    excState.boomAngle = THREE.MathUtils.lerp(excState.boomAngle, 0.3, lerpSpeed);\n                    excState.armAngle = THREE.MathUtils.lerp(excState.armAngle, 1.0, lerpSpeed);\n                    excState.bucketAngle = THREE.MathUtils.lerp(excState.bucketAngle, 0.9, lerpSpeed);\n                    \n                    if (Math.abs(excState.boomAngle - 0.3) < 0.1 && Math.abs(excState.armAngle - 1.0) < 0.1) {\n                        autoDigStage = 1;\n                    }\n                } else if (autoDigStage === 1) {\n                    // Phase 1: Scoop/Curl bucket to dig up dirt\n                    curlActive = true; // triggers actual digging/particle logic\n                    excState.bucketAngle = THREE.MathUtils.lerp(excState.bucketAngle, -0.7, lerpSpeed * 1.5);\n                    excState.armAngle = THREE.MathUtils.lerp(excState.armAngle, 0.5, lerpSpeed * 0.5);\n                    // Keep boom slightly pressed down to ensure deep digging\n                    excState.boomAngle = THREE.MathUtils.lerp(excState.boomAngle, 0.45, lerpSpeed);\n\n                    if (excState.bucketAngle < -0.55) {\n                        autoDigStage = 2;\n                    }\n                } else if (autoDigStage === 2) {\n                    // Phase 2: Lift up to safety/carrying height\n                    excState.boomAngle = THREE.MathUtils.lerp(excState.boomAngle, -0.5, lerpSpeed);\n                    excState.armAngle = THREE.MathUtils.lerp(excState.armAngle, 0.3, lerpSpeed);\n                    \n                    if (Math.abs(excState.boomAngle - (-0.5)) < 0.1) {\n                        autoDigActive = false; // Finished auto dig!\n                    }\n                }\n            } else if (autoDumpActive) {\n                const lerpSpeed = 4.0 * dt;\n                if (autoDumpStage === 0) {\n                    // Phase 0: Tilt bucket open to dump soil\n                    dumpActive = true; // triggers soil falling logic\n                    excState.bucketAngle = THREE.MathUtils.lerp(excState.bucketAngle, 1.3, lerpSpeed);\n                    if (excState.bucketAngle > 1.0) {\n                        autoDumpStage = 1;\n                        autoDumpTimer = 0;\n                    }\n                } else if (autoDumpStage === 1) {\n                    // Phase 1: Wait a brief moment then return bucket to carrying angle\n                    autoDumpTimer += dt;\n                    if (autoDumpTimer > 0.5) {\n                        excState.bucketAngle = THREE.MathUtils.lerp(excState.bucketAngle, 0.2, lerpSpeed);\n                        if (Math.abs(excState.bucketAngle - 0.2) < 0.1) {\n                            autoDumpActive = false; // Finished auto dump!\n                        }\n                    }\n                }\n            } else {\n                if (excavatorMalfunctionTimer <= 0) {\n                    // Classic manual controls\n                    if (currentControlMode !== 'simple') {\n                        if (keys['ArrowRight']) armInput += 1;\n                        if (keys['ArrowLeft']) armInput -= 1;\n                    }\n                    if (currentControlMode === 'classic' && touchState.leftJoy.active && Math.abs(touchState.leftJoy.y) > 0.1) {\n                        armInput -= touchState.leftJoy.y;\n                    }\n\n                    if (armInput > 0) {\n                        excState.armAngle = Math.min(1.4, excState.armAngle + armSpeed * movementFactor * dt * armInput);\n                    } else if (armInput < 0) {\n                        excState.armAngle = Math.max(-0.3, excState.armAngle + armSpeed * movementFactor * dt * armInput);\n                    }\n\n                    if (currentControlMode !== 'simple') {\n                        if (keys['ArrowUp']) boomInput -= 1;\n                        if (keys['ArrowDown']) boomInput += 1;\n                    }\n                    if (currentControlMode === 'classic' && touchState.rightJoy.active && Math.abs(touchState.rightJoy.y) > 0.1) {\n                        boomInput += touchState.rightJoy.y;\n                    }\n\n                    if (boomInput < 0) {\n                        excState.boomAngle = Math.max(-0.8, excState.boomAngle + armSpeed * movementFactor * dt * boomInput);\n                    } else if (boomInput > 0) {\n                        excState.boomAngle = Math.min(0.4, excState.boomAngle + armSpeed * movementFactor * dt * boomInput);\n                    }\n\n                    curlActive = keys['KeyZ'] || keys['z'] || keys['Z'] || (currentControlMode === 'classic' && touchState.rightJoy.active && touchState.rightJoy.x < -0.1);\n                    dumpActive = keys['KeyX'] || keys['x'] || keys['X'] || keys['KeyC'] || keys['c'] || keys['C'] || (currentControlMode === 'classic' && touchState.rightJoy.active && touchState.rightJoy.x > 0.1);\n\n                    if (curlActive) {\n                        let factor = 1.0;\n                        if (currentControlMode === 'classic' && touchState.rightJoy.active && touchState.rightJoy.x < -0.1) factor = Math.abs(touchState.rightJoy.x);\n                        excState.bucketAngle = Math.max(-0.8, excState.bucketAngle - armSpeed * 1.5 * movementFactor * dt * factor);\n                    }\n                    if (dumpActive) {\n                        let factor = 1.0;\n                        if (currentControlMode === 'classic' && touchState.rightJoy.active && touchState.rightJoy.x > 0.1) factor = Math.abs(touchState.rightJoy.x);\n                        excState.bucketAngle = Math.min(1.4, excState.bucketAngle + armSpeed * 1.5 * movementFactor * dt * factor);\n                    }\n                }\n            }\n\n            // Anti-clipping system for bucket: prevent penetrating ground or walls when not actively digging\n            // Skip anti-clipping entirely during auto-dig/auto-dump to prevent fighting the automation\n            if (!isDigging && !autoDigActive && !autoDumpActive) {\n                let safetyTries = 12;\n                let penetrating = true;\n                while (penetrating && safetyTries > 0) {\n                    // Apply current proposed angles to model locally to compute exact world position\n                    boomGroup.rotation.x = excState.boomAngle;\n                    armGroup.rotation.x = excState.armAngle;\n                    bucketGroup.rotation.x = excState.bucketAngle;\n                    excavatorGroup.updateMatrixWorld(true);\n\n                    const bPos = getBucketWorldPos();\n                    const terH = getTerrainHeight(bPos.x, bPos.z);\n                    const terrainPenetration = terH - bPos.y;\n\n                    let wallPenetration = 0;\n                    for (let i = 0; i < monoliths.length; i++) {\n                        const mono = monoliths[i];\n                        const dx = bPos.x - mono.x;\n                        const dz = bPos.z - mono.z;\n                        const distToWall = Math.sqrt(dx * dx + dz * dz);\n                        const wallRadius = (mono.width + mono.depth) / 4 + 1.2;\n                        if (distToWall < wallRadius && bPos.y < mono.height) {\n                            wallPenetration = wallRadius - distToWall;\n                            break;\n                        }\n                    }\n\n                    if (terrainPenetration > 0.05) {\n                        // Lift the boom (make boomAngle smaller/more negative)\n                        excState.boomAngle -= 0.04;\n                        // Slightly curl bucket to slide along ground\n                        excState.bucketAngle -= 0.02;\n                        safetyTries--;\n                    } else if (wallPenetration > 0.05) {\n                        // Push back arm or boom to slide along walls\n                        excState.boomAngle -= 0.03;\n                        excState.armAngle -= 0.03;\n                        safetyTries--;\n                    } else {\n                        penetrating = false;\n                    }\n                }\n                // Clamp to safe limits\n                excState.boomAngle = Math.max(-0.8, Math.min(0.4, excState.boomAngle));\n                excState.armAngle = Math.max(-0.3, Math.min(1.4, excState.armAngle));\n                excState.bucketAngle = Math.max(-0.8, Math.min(1.4, excState.bucketAngle));\n            }\n\n            // Check if bucket is near or in terrain and oriented correctly for digging (inside/middle of bucket facing terrain, not the back/outer side)\n            // Re-evaluating based on latest frame adjustments\n            const bucketNearTerrain = bucketPos.y <= terrainH + 0.5;\n            // Digging logic (loading things into the bucket) - only allowed when bucket angle is correct (scooping with the inside/middle)\n            if (isTouchingTerrain && isBucketAngleCorrect && (curlActive || keys['ArrowLeft'] || armInput < -0.1)) {\n                // Dig into terrain (highly boosted during automated digging)\n                const digFactor = autoDigActive ? 5.0 : 2.0;\n                const digAmount = -2.5 * config.excavator.bucketCapacity * dt * digFactor;\n                modifyTerrain(bucketPos.x, bucketPos.z, digAmount, 3.5);\n                \n                // Show glowing terraforming grid circle on terrain\n                digRing.position.set(bucketPos.x, terrainH + 0.05, bucketPos.z);\n                digRing.material.opacity = THREE.MathUtils.lerp(digRing.material.opacity, 0.8, 10 * dt);\n                digRing.scale.set(1 + Math.sin(markerTime * 15) * 0.15, 1 + Math.sin(markerTime * 15) * 0.15, 1);\n                \n                // Load dirt into the bucket!\n                excState.dirtInBucket = Math.min(1.0, excState.dirtInBucket + 0.4 * config.excavator.bucketCapacity * dt * digFactor);\n                \n                // Spawn digging particles\n                if (Math.random() < 0.6) {\n                    spawnParticles(bucketPos, 1);\n                }\n\n                // Play scoop sound\n                if (!scoopSoundObj && audioBuffers['bucket_scoop_sound']) {\n                    scoopSoundObj = playSound('bucket_scoop_sound', true, 0.25);\n                }\n\n                // Track depth\n                const newH = getTerrainHeight(bucketPos.x, bucketPos.z);\n                const depth = Math.max(0, -newH);\n                if (depth > maxDigDepth) {\n                    maxDigDepth = depth;\n                    const depthEl = document.getElementById('depth');\n                    if (depthEl) depthEl.textContent = maxDigDepth.toFixed(1);\n                    checkMissionCompletion();\n                    updateObjectiveUI();\n                }\n            } else {\n                // Stop scoop sound when not digging\n                if (scoopSoundObj) {\n                    try { scoopSoundObj.source.stop(); } catch(e) {}\n                    scoopSoundObj = null;\n                }\n                // Fade out digging holographic ring when inactive\n                if (digRing) {\n                    digRing.material.opacity = THREE.MathUtils.lerp(digRing.material.opacity, 0, 8 * dt);\n                }\n            }\n\n            // Dumping / spilling logic (unloading things from the bucket)\n            if (excState.bucketAngle > 0.4 && excState.dirtInBucket > 0) {\n                // Spill dirt based on angle\n                const spillAmount = (excState.bucketAngle - 0.3) * 3.0 * dt;\n                excState.dirtInBucket = Math.max(0, excState.dirtInBucket - spillAmount);\n\n                // Deposit spilled dirt back onto the terrain at the bucket's current position (create a pile!)\n                const depositAmount = spillAmount * 4.5 * config.excavator.bucketCapacity;\n                modifyTerrain(bucketPos.x, bucketPos.z, depositAmount, 3.5);\n\n                // Spawn falling soil particles\n                spawnParticles(bucketPos, 2);\n\n                // Play dump sound\n                if (!dumpSoundObj && audioBuffers['dirt_dump_sound']) {\n                    dumpSoundObj = playSound('dirt_dump_sound', false, 0.3); // play as one-shot or repeat\n                }\n            } else {\n                // Reset/stop dump sound\n                dumpSoundObj = null;\n            }\n\n            // Check active mission completion triggers\n            checkMissionCompletion();\n            updateObjectiveUI();\n\n            // Update particles\n            updateParticles(dt);\n\n            // Dynamic Spaceship & Rocket Construction progress and scaling based on credits!\n            // Progress increases by 1% for every 1000 credits, reaching 100% at 100,000 credits.\n            const progressRatio = Math.min(1.0, credits / 100000); \n            \n            // Update Base Build Progress UI\n            const baseBuildPctEl = document.getElementById('base-build-pct');\n            const baseBuildBarEl = document.getElementById('base-build-bar');\n            const baseBuildDescEl = document.getElementById('base-build-desc');\n            if (baseBuildPctEl && baseBuildBarEl && baseBuildDescEl) {\n                const buildPct = (progressRatio * 100).toFixed(1);\n                baseBuildPctEl.innerHTML = `${buildPct}% <span style=\"font-size:11px; color:#aaa; font-weight:normal;\">(${credits.toLocaleString()}/100,000)</span>`;\n                baseBuildBarEl.style.width = `${progressRatio * 100}%`;\n                \n                if (progressRatio >= 1.0) {\n                    baseBuildDescEl.innerHTML = `<span style=\"color:#00ff66; font-weight:bold;\">${t('shipReady')}</span>`;\n                } else if (progressRatio >= 0.75) {\n                    baseBuildDescEl.innerHTML = `${t('assembling')}: <strong>Spaceship Orbiter Cabin</strong>`;\n                } else if (progressRatio >= 0.5) {\n                    baseBuildDescEl.innerHTML = `${t('assembling')}: <strong>Stage 2 Core Fuel Tank</strong>`;\n                } else if (progressRatio >= 0.25) {\n                    baseBuildDescEl.innerHTML = `${t('assembling')}: <strong>Side Rocket Boosters</strong>`;\n                } else {\n                    baseBuildDescEl.innerHTML = `${t('assembling')}: <strong>Launch Pad & Rocket Core</strong>`;\n                }\n            } \n            \n            // Overall assembly grows and gets grander as score increases\n            const targetBaseScale = 0.85 + progressRatio * 0.45; // Grows from 0.85 to 1.30\n            landerMesh.scale.set(targetBaseScale, targetBaseScale, targetBaseScale);\n\n            // Animate Launch pad warning light colors\n            padLights.forEach((light, lIdx) => {\n                const wave = Math.sin(markerTime * 5 + lIdx);\n                light.material.color.setHex(wave > 0 ? 0x00ff66 : 0xff3d00);\n            });\n\n            // Stage 1 (Booster Base Tank): grows in [0.0, 0.25] of progressRatio\n            const stage1Scale = Math.max(0.001, Math.min(1.0, progressRatio / 0.25));\n            stage1Group.scale.setScalar(THREE.MathUtils.lerp(0.8, 1.0, stage1Scale));\n\n            // Side Boosters: Grow in [0.25, 0.50] of progressRatio\n            const boostersScale = Math.max(0.001, Math.min(1.0, (progressRatio - 0.25) / 0.25));\n            sideBoostersGroup.scale.set(boostersScale, boostersScale, boostersScale);\n\n            // Stage 2 (Upper Tank & Gold wrap): Grow in [0.50, 0.75] of progressRatio\n            const stage2Scale = Math.max(0.001, Math.min(1.0, (progressRatio - 0.50) / 0.25));\n            stage2Group.scale.set(stage2Scale, stage2Scale, stage2Scale);\n\n            // The main Spaceship Orbiter: Assembles and becomes detailed in [0.75, 1.00] of progressRatio\n            const spaceshipScale = Math.max(0.001, Math.min(1.0, (progressRatio - 0.75) / 0.25));\n            spaceshipGroup.scale.set(spaceshipScale, spaceshipScale, spaceshipScale);\n\n            // Rotate Spaceship's Solar Panels as they extend\n            const solarAngle = Math.sin(markerTime * 1.5) * 0.15 + (progressRatio * Math.PI / 2.5);\n            solarPanelLeft.rotation.y = solarAngle;\n            solarPanelRight.rotation.y = -solarAngle;\n\n            // Animate Titan Mech assembly parts with idle sway when they are collected!\n            if (!titanActive) {\n                if (titanCollection['titan_head'] && headGroup) {\n                    headGroup.rotation.y = Math.sin(markerTime * 1.2) * 0.15;\n                }\n                if (titanCollection['titan_l_arm'] && lArmGroup) {\n                    lArmGroup.rotation.x = Math.sin(markerTime * 0.8) * 0.12;\n                }\n                if (titanCollection['titan_r_arm'] && rArmGroup) {\n                    rArmGroup.rotation.x = -Math.sin(markerTime * 0.8) * 0.12;\n                }\n                if (titanCollection['titan_torso'] && torsoGroup) {\n                    // Breathing pulsation for core torso\n                    torsoGroup.position.y = 4.5 + Math.sin(markerTime * 1.5) * 0.08;\n                }\n            }\n\n            // Retract Umbilical Arms on the tower as the launch complexity gets completed!\n            umbilicalArms.forEach((arm, armIdx) => {\n                const armThresholdRatio = 0.2 + armIdx * 0.3; // thresholds at 20%, 50%, 80% progress\n                if (progressRatio > armThresholdRatio) {\n                    // Swing/retract away from the rocket!\n                    arm.rotation.y = THREE.MathUtils.lerp(arm.rotation.y, Math.PI / 2.2, 3.0 * dt);\n                } else {\n                    // Keep locked onto the rocket structure\n                    arm.rotation.y = THREE.MathUtils.lerp(arm.rotation.y, 0, 3.0 * dt);\n                }\n            });\n\n            // Rotate Gantry Crane slowly to simulate scanning/building\n            if (craneGantry) {\n                craneGantry.rotation.y = Math.sin(markerTime * 0.3) * 0.5;\n            }\n\n            // Update treasures and radar\n            let nearestDist = Infinity;\n            let nearestDepth = 0;\n            let nearestName = '';\n            let nearestTreasure = null;\n\n            // Alias translation function before loop shadows it with treasure variable\n            const _t = t;\n\n            // Get the list of all uncollected treasures with distances\n            const uncollectedSorted = treasures\n                .filter(t => !t.collected)\n                .map(t => {\n                    const dx = t.x - excavatorGroup.position.x;\n                    const dz = t.z - excavatorGroup.position.z;\n                    const dist = Math.sqrt(dx * dx + dz * dz);\n                    return { treasure: t, dist };\n                })\n                .sort((a, b) => a.dist - b.dist);\n\n            // We only show the top 3 nearest gems to avoid clutter\n            const top3Nearest = uncollectedSorted.slice(0, 3);\n\n            for (let i = 0; i < treasures.length; i++) {\n                const t = treasures[i];\n                if (t.collected) continue;\n\n                // Animate gem rotation to catch light and pulse emissive intensity for gemstone brilliance\n                if (t.exposed || t.scooped) {\n                    t.mesh.rotation.y += dt * 1.5;\n                    t.mesh.rotation.x += dt * 0.8;\n                    // Pulse each part of the rough compound ore cluster\n                    t.mesh.children.forEach(child => {\n                        if (child.material) {\n                            child.material.emissiveIntensity = 1.2 + Math.sin(markerTime * 6.0 + t.id) * 0.6;\n                        }\n                    });\n                }\n\n                // Check actual terrain height at treasure position\n                const currentTh = getTerrainHeight(t.x, t.z);\n\n                // Update glowing ground marker position and breathing animation\n                if (t.ringMesh && t.discMesh) {\n                    // Place slightly above current deforming terrain surface\n                    t.ringMesh.position.y = currentTh + 0.05;\n                    t.discMesh.position.y = currentTh + 0.04;\n\n                    if (t.collected || t.scooped) {\n                        t.ringMesh.visible = false;\n                        t.discMesh.visible = false;\n                    } else {\n                        t.ringMesh.visible = true;\n                        t.discMesh.visible = true;\n\n                        // Breathing fluorescent animation\n                        const pulse = Math.sin(markerTime * 3.5 + t.id) * 0.15;\n                        t.ringMesh.scale.set(1.0 + pulse, 1.0 + pulse, 1.0 + pulse);\n                        t.ringMesh.material.opacity = 0.25 + Math.sin(markerTime * 4.0 + t.id) * 0.1;\n                        \n                        // Slightly pulsing color disk\n                        t.discMesh.scale.set(1.0 + pulse * 0.5, 1.0 + pulse * 0.5, 1.0 + pulse * 0.5);\n                        t.discMesh.material.opacity = 0.12 + Math.sin(markerTime * 2.0 + t.id) * 0.03;\n                    }\n                }\n\n                // If terrain is dug down below or near the treasure, it becomes exposed!\n                // Tightened threshold so gems only appear after significant digging\n                if (!t.exposed && currentTh <= t.buriedY + 0.1) {\n                    t.exposed = true;\n                    // Semi-buried in the sand/soil as requested\n                    t.mesh.position.y = currentTh - 0.4;\n                    // Spawn a burst of sparkling colored particles\n                    spawnParticles(t.mesh.position, 5);\n                }\n\n                // Update visual position of treasure based on state\n                if (t.scooped) {\n                    // Follow the bucket position when scooped up and stay ABOVE the dirt in the bucket!\n                    t.mesh.position.copy(getBucketCenterWorldPos());\n                    \n                    // Scatter gems deterministically across the bucket's soil surface so they don't overlap\n                    const localX = ((t.id % 3) - 1) * 0.35; // Spread horizontally (-0.35, 0, 0.35)\n                    const localZ = (((t.id * 7) % 3) - 1) * 0.25; // Spread front-to-back (-0.25, 0, 0.25)\n                    const localY = 0.95 + Math.abs(Math.sin(t.id * 1.5)) * 0.15; // Keep them resting nicely on dirt layer\n                    \n                    const scatterOffset = new THREE.Vector3(localX, localY, localZ);\n                    scatterOffset.applyQuaternion(bucketGroup.getWorldQuaternion(new THREE.Quaternion()));\n                    t.mesh.position.add(scatterOffset);\n                    t.mesh.quaternion.copy(bucketGroup.getWorldQuaternion(new THREE.Quaternion()));\n                } else if (!t.exposed) {\n                    // Stay buried relative to potential digging, but keep visual coordinate updated\n                    t.mesh.position.y = t.buriedY;\n                } else {\n                    // Keep it half-buried in current terrain, not floating, not moving on its own\n                    t.mesh.position.y = currentTh - 0.4;\n                }\n                // Distance to bucket\n                const distToBucket = bucketPos.distanceTo(t.mesh.position);\n\n                // STAGE 1: Scoop/Dig Phase\n                // If bucket is close, low enough (digging into/near terrain), and not yet scooped\n                if (!t.scooped) {\n                    const isBucketLow = bucketPos.y <= currentTh + 1.8;\n                    const isDigging = curlActive || keys['ArrowLeft'] || armInput < -0.1 || autoDigActive;\n                    if (distToBucket < 12.0 && isBucketLow && isDigging) {\n                        t.scooped = true;\n                        t.scoopTimer = 3.0; // Displayed inside the bucket for 3 seconds first!\n                        // Trigger a small visual scoop confirmation\n                        spawnParticles(bucketPos, 4);\n                        updateTerrainGeometry();\n                    }\n                }\n\n                // If scooped, countdown to fly towards the lander base station\n                if (t.scooped && !t.collected) {\n                    t.scoopTimer -= dt;\n                    if (t.scoopTimer <= 0) {\n                        t.collected = true;\n                        t.scooped = false;\n\n                        // Start 3D flight animation from current bucket position to the Colony Lander!\n                        const startPos = t.mesh.position.clone();\n                        const endPos = new THREE.Vector3(0, 3.65, -15);\n                        \n                        let flightProgress = 0;\n                        const flightDuration = 1.2; // 1.2 seconds gorgeous flight\n\n                        // Keep the mesh in the scene but animate its trajectory\n                        t.mesh.scale.set(0.4, 0.4, 0.4); // slightly smaller during transit\n\n                        const animateFlight = () => {\n                            const now = performance.now();\n                            const elapsed = 1 / 60; // frame approximation\n                            flightProgress += elapsed / flightDuration;\n\n                            if (flightProgress >= 1.0) {\n                                // Arrived at the Lander!\n                                scene.remove(t.mesh);\n                                if (t.ringMesh) scene.remove(t.ringMesh);\n                                if (t.discMesh) scene.remove(t.discMesh);\n\n                                // Tractor beam absorption particle burst\n                                const burstColor = new THREE.Color(t.type.color);\n                                for (let p = 0; p < 15; p++) {\n                                    const pMesh = new THREE.Mesh(particleGeo, new THREE.MeshBasicMaterial({ color: burstColor }));\n                                    pMesh.position.copy(endPos);\n                                    scene.add(pMesh);\n                                    particles.push({\n                                        mesh: pMesh,\n                                        vel: new THREE.Vector3((Math.random()-0.5)*6, Math.random()*5 + 1, (Math.random()-0.5)*6),\n                                        life: 1.2\n                                    });\n                                }\n\n                                // Increment global delivered count & credits\n                                totalDelivered++;\n                                const awardAmount = t.score || t.type.score;\n                                updateCredits(awardAmount);\n\n                                // Show beautiful floating score on-screen!\n                                let gemColorHex = '#ffd700';\n                                if (t.type && t.type.color) {\n                                    gemColorHex = '#' + t.type.color.toString(16).padStart(6, '0');\n                                }\n                                showFloatingScore(awardAmount, gemColorHex);\n\n                                if (t.isTitanPart) {\n                                    titanCollection[t.type.id] = true;\n                                    updateTitanVisuals();\n\n                                    // Special celebration explosion of gold and cyan sparks at the assembly site!\n                                    const titanAsmPos = new THREE.Vector3(-11, 2.5, -19); // World coordinates of titan\n                                    for (let p = 0; p < 30; p++) {\n                                        const pMesh = new THREE.Mesh(particleGeo, new THREE.MeshBasicMaterial({ \n                                            color: p % 2 === 0 ? 0xffaa00 : 0x00e5ff \n                                        }));\n                                        pMesh.position.copy(titanAsmPos);\n                                        scene.add(pMesh);\n                                        particles.push({\n                                            mesh: pMesh,\n                                            vel: new THREE.Vector3((Math.random()-0.5)*8, Math.random()*6 + 2, (Math.random()-0.5)*8),\n                                            life: 1.5\n                                        });\n                                    }\n\n                                    // Check if all 6 Titan parts are collected to activate the colossal guard!\n                                    let titanCount = 0;\n                                    Object.keys(titanCollection).forEach(k => {\n                                        if (titanCollection[k]) titanCount++;\n                                    });\n\n                                    // Special screen notification\n                                    const infoText = document.getElementById('info-text-element');\n                                    if (infoText) {\n                                        if (titanCount === 6) {\n                                            titanActive = true;\n                                            // Massive activation ceremony!\n                                            infoText.innerHTML = `\n                                            <span style=\"color: #ffd700; font-weight: 900; text-shadow: 0 0 15px rgba(255,215,0,0.9); font-size: 26px;\">${_t('titanAssembled')}</span><br>\n                                            <span style=\"font-size: 16px; color: #00ffcc;\">${_t('titanActivated')}</span><br>\n                                            <span style=\"font-size: 14px; color: #00ff66;\">${_t('titanBonus')}</span>`;\n                                            updateCredits(5000);\n                                            \n                                            // Scale up the Titan and play a magnificent particle show\n                                            let scaleTimer = 0;\n                                            const activateTitan = () => {\n                                                scaleTimer += 0.05;\n                                                const wave = Math.sin(scaleTimer * 8.0);\n                                                titanArmorMat.color.setHSL(0.5 + wave * 0.1, 0.8, 0.35);\n                                                titanGlowMat.emissiveIntensity = 2.0 + Math.sin(scaleTimer * 12.0) * 1.0;\n                                                if (scaleTimer < 5.0) {\n                                                    requestAnimationFrame(activateTitan);\n                                                } else {\n                                                    // Reset colors\n                                                    titanArmorMat.color.setHex(0x222a30);\n                                                    titanGlowMat.emissiveIntensity = 1.5;\n                                                }\n                                            };\n                                            activateTitan();\n\n                                            // Play awesome completion chime\n                                            if (audioBuffers['objective_complete_sound']) {\n                                                playSound('objective_complete_sound', false, 1.0);\n                                            }\n                                        } else {\n                                            infoText.innerHTML = `\n                                            <span style=\"color: #00e5ff; font-weight: 900; font-size: 22px;\">${_t('partRetrieved')}</span><br>\n                                            <span style=\"font-size: 15px; color: #a5b4fc;\">${_t('partDelivered').replace('{name}', t.type.name)}</span><br>\n                                            <span style=\"font-size: 13px; color: #ffd700;\">${_t('titanProgress').replace('{count}', titanCount)}</span>`;\n                                        }\n                                        infoText.classList.add('visible');\n                                        setTimeout(() => {\n                                            infoText.classList.remove('visible');\n                                        }, 4000);\n                                    }\n                                } else {\n                                    // Increment regular collection count\n                                    collectedInventory[t.type.id]++;\n                                }\n\n                                // Update credits panel text & scale pulse\n                                const credEl = document.getElementById('credits');\n                                if (credEl) {\n                                    credEl.textContent = credits;\n                                    credEl.style.transform = 'scale(1.4)';\n                                    credEl.style.color = '#' + t.type.color.toString(16).padStart(6, '0');\n                                    credEl.style.textShadow = `0 0 15px #${t.type.color.toString(16).padStart(6, '0')}`;\n                                    setTimeout(() => {\n                                        credEl.style.transform = 'scale(1)';\n                                        credEl.style.color = '';\n                                        credEl.style.textShadow = '';\n                                    }, 200);\n                                }\n\n                                // Update Mission progress bar & status\n                                checkMissionCompletion();\n                                updateObjectiveUI();\n\n                                // Incrementally build dome parts based on progress\n                                const activeParts = Math.min(domeParts.length, Math.floor(totalDelivered / 1.66) + 1);\n                                for (let d = 0; d < activeParts; d++) {\n                                    const part = domeParts[d];\n                                    if (part && part.scale.x < 0.1) {\n                                        // Animate scaling up from 0 to 1 with an energetic pop!\n                                        let currentScale = 0;\n                                        const scaleUp = () => {\n                                            currentScale += 0.08;\n                                            if (currentScale < 1.0) {\n                                                part.scale.set(currentScale, currentScale, currentScale);\n                                                requestAnimationFrame(scaleUp);\n                                            } else {\n                                                part.scale.set(1, 1, 1);\n                                                // Splash building completion particles\n                                                const domeWorldPos = new THREE.Vector3();\n                                                part.getWorldPosition(domeWorldPos);\n                                                spawnParticles(domeWorldPos, 6);\n                                            }\n                                        };\n                                        scaleUp();\n                                    }\n                                }\n\n                                updateTreasureUI();\n                                playSound('objective_complete_sound', false, 0.7);\n\n                            } else {\n                                // Parabolic flight calculation\n                                const nextPos = new THREE.Vector3();\n                                nextPos.lerpVectors(startPos, endPos, flightProgress);\n                                // Add parabolic height arch to the flight\n                                const archHeight = 12 * Math.sin(flightProgress * Math.PI);\n                                nextPos.y += archHeight;\n\n                                t.mesh.position.copy(nextPos);\n                                t.mesh.rotation.y += 0.1;\n\n                                requestAnimationFrame(animateFlight);\n                            }\n                        };\n                        animateFlight();\n                    }\n                }\n\n                // Keep track of nearest uncollected treasure for HUD/radar/arrow guidance\n                if (!t.collected) {\n                    const distToExc = excavatorGroup.position.distanceTo(t.mesh.position);\n                    if (distToExc < nearestDist) {\n                        nearestDist = distToExc;\n                        nearestDepth = Math.max(0, currentTh - t.mesh.position.y);\n                        nearestName = t.type.name;\n                        nearestTreasure = t;\n                    }\n                }\n            }\n\n            // ===== TITAN MECH AI & COMBAT PROTOCOL =====\n            if (titanActive) {\n                // Titan AI: auto find closest living zombie\n                let closestZombie = null;\n                let minZDist = Infinity;\n                for (let zi = 0; zi < zombies.length; zi++) {\n                    const z = zombies[zi];\n                    if (z.state === 'alive') {\n                        const tDist = Math.sqrt((z.x - titanX) * (z.x - titanX) + (z.z - titanZ) * (z.z - titanZ));\n                        if (tDist < minZDist) {\n                            minZDist = tDist;\n                            closestZombie = z;\n                        }\n                    }\n                }\n\n                if (closestZombie) {\n                    // Turn towards target\n                    const dx = closestZombie.x - titanX;\n                    const dz = closestZombie.z - titanZ;\n                    const angle = Math.atan2(dx, dz);\n                    titanGroup.rotation.y = angle;\n\n                    if (minZDist > 8.0) {\n                        // Walk towards zombie\n                        titanX += Math.sin(angle) * titanSpeed * dt;\n                        titanZ += Math.cos(angle) * titanSpeed * dt;\n                        titanY = getTerrainHeight(titanX, titanZ);\n                        titanGroup.position.set(titanX, titanY, titanZ);\n\n                        // Animate walking legs/arms\n                        titanWalkCycle += dt * 8.0;\n                        if (lLegGroup) lLegGroup.rotation.x = Math.sin(titanWalkCycle) * 0.5;\n                        if (rLegGroup) rLegGroup.rotation.x = -Math.sin(titanWalkCycle) * 0.5;\n                        if (lArmGroup) lArmGroup.rotation.x = -Math.sin(titanWalkCycle) * 0.3;\n                        if (rArmGroup) rArmGroup.rotation.x = Math.sin(titanWalkCycle) * 0.3;\n                        if (headGroup) headGroup.rotation.y = Math.sin(titanWalkCycle * 0.5) * 0.1;\n                    } else {\n                        // Close enough to attack!\n                        titanWalkCycle = 0;\n                        titanY = getTerrainHeight(titanX, titanZ);\n                        titanGroup.position.set(titanX, titanY, titanZ);\n\n                        // Swing arms down to smash!\n                        titanAttackTimer += dt;\n                        if (lLegGroup) lLegGroup.rotation.x = THREE.MathUtils.lerp(lLegGroup.rotation.x, 0, dt * 10);\n                        if (rLegGroup) rLegGroup.rotation.x = THREE.MathUtils.lerp(rLegGroup.rotation.x, 0, dt * 10);\n                        \n                        // Smashing motion: pull arms back and slam them down\n                        const swing = Math.sin(titanAttackTimer * Math.PI * 2);\n                        if (lArmGroup) lArmGroup.rotation.x = -0.5 + swing * 1.0;\n                        if (rArmGroup) rArmGroup.rotation.x = -0.5 - swing * 1.0;\n\n                        // Damage/kill the zombie after hitting\n                        if (titanAttackTimer >= 0.5) {\n                            closestZombie.state = 'dead';\n                            closestZombie.mesh.scale.y = 0.05;\n                            closestZombie.mesh.position.y = getTerrainHeight(closestZombie.x, closestZombie.z) + 0.02;\n\n                            // Spawn green splash particles\n                            const bloodCol = 0x39ff14;\n                            const bloodMat = new THREE.MeshBasicMaterial({ color: bloodCol });\n                            for (let p = 0; p < 15; p++) {\n                                const bMesh = new THREE.Mesh(particleGeo, bloodMat);\n                                bMesh.position.copy(closestZombie.mesh.position);\n                                scene.add(bMesh);\n                                particles.push({\n                                    mesh: bMesh,\n                                    vel: new THREE.Vector3((Math.random()-0.5)*6, Math.random()*4 + 1.5, (Math.random()-0.5)*6),\n                                    life: 1.2\n                                });\n                            }\n\n                            updateCredits(50);\n                            showFloatingScoreAtPos(50, '#39ff14', closestZombie.mesh.position);\n                            zombiesSlainCount++;\n\n                            if (audioBuffers['dirt_dump_sound']) {\n                                playSound('dirt_dump_sound', false, 0.7);\n                            }\n\n                            titanAttackTimer = 0;\n                        }\n                    }\n                } else {\n                    // No zombies left: follow/protect player!\n                    const px = excavatorGroup.position.x;\n                    const pz = excavatorGroup.position.z;\n                    const dx = px - titanX;\n                    const dz = pz - titanZ;\n                    const distToPlayer = Math.sqrt(dx*dx + dz*dz);\n                    \n                    if (distToPlayer > 12.0) {\n                        // Walk towards player\n                        const angle = Math.atan2(dx, dz);\n                        titanGroup.rotation.y = angle;\n                        titanX += Math.sin(angle) * titanSpeed * dt;\n                        titanZ += Math.cos(angle) * titanSpeed * dt;\n                        titanY = getTerrainHeight(titanX, titanZ);\n                        titanGroup.position.set(titanX, titanY, titanZ);\n\n                        // Walk cycle\n                        titanWalkCycle += dt * 8.0;\n                        if (lLegGroup) lLegGroup.rotation.x = Math.sin(titanWalkCycle) * 0.5;\n                        if (rLegGroup) rLegGroup.rotation.x = -Math.sin(titanWalkCycle) * 0.5;\n                        if (lArmGroup) lArmGroup.rotation.x = -Math.sin(titanWalkCycle) * 0.3;\n                        if (rArmGroup) rArmGroup.rotation.x = Math.sin(titanWalkCycle) * 0.3;\n                        if (headGroup) headGroup.rotation.y = Math.sin(titanWalkCycle * 0.5) * 0.1;\n                    } else {\n                        // Stand guard near player\n                        titanWalkCycle = 0;\n                        titanY = getTerrainHeight(titanX, titanZ);\n                        titanGroup.position.set(titanX, titanY, titanZ);\n                        \n                        // Turn to face the same way as the player's excavator upper cabin\n                        const playerUpperYaw = excState.rotation + excState.upperRotation;\n                        titanGroup.rotation.y = THREE.MathUtils.lerp(titanGroup.rotation.y, playerUpperYaw, dt * 3);\n\n                        if (lLegGroup) lLegGroup.rotation.x = THREE.MathUtils.lerp(lLegGroup.rotation.x, 0, dt * 5);\n                        if (rLegGroup) rLegGroup.rotation.x = THREE.MathUtils.lerp(rLegGroup.rotation.x, 0, dt * 5);\n                        \n                        // Idle breathing sway\n                        if (lArmGroup) lArmGroup.rotation.x = THREE.MathUtils.lerp(lArmGroup.rotation.x, Math.sin(markerTime * 0.8) * 0.12, dt * 5);\n                        if (rArmGroup) rArmGroup.rotation.x = THREE.MathUtils.lerp(rArmGroup.rotation.x, -Math.sin(markerTime * 0.8) * 0.12, dt * 5);\n                        if (headGroup) headGroup.rotation.y = THREE.MathUtils.lerp(headGroup.rotation.y, Math.sin(markerTime * 1.2) * 0.15, dt * 5);\n                    }\n                }\n            } else {\n                // Titan not active, keep static at base coordinates\n                titanY = getTerrainHeight(-11, -19);\n                titanGroup.position.set(-11, titanY, -19);\n            }\n            // Radar updates removed per user request\n        }\n\n        function updateExcavatorTransform() {\n            const terrainY = getTerrainHeight(excState.x, excState.z);\n            \n            let posX = excState.x;\n            let posY = terrainY + liftAmount + excavatorLaunchY;\n            let posZ = excState.z;\n            \n            let rotX = tiltX + excavatorLaunchRotX;\n            let rotY = excState.rotation;\n            let rotZ = tiltZ + excavatorLaunchRotZ;\n\n            // Apply vibration shaking if active (due to sandworm attack)\n            if (typeof excavatorShakeIntensity !== 'undefined' && excavatorShakeIntensity > 0) {\n                posX += (Math.random() - 0.5) * excavatorShakeIntensity * 0.42;\n                posY += (Math.random() - 0.5) * excavatorShakeIntensity * 0.42;\n                posZ += (Math.random() - 0.5) * excavatorShakeIntensity * 0.42;\n                \n                rotX += (Math.random() - 0.5) * excavatorShakeIntensity * 0.05;\n                rotY += (Math.random() - 0.5) * excavatorShakeIntensity * 0.05;\n                rotZ += (Math.random() - 0.5) * excavatorShakeIntensity * 0.05;\n            }\n            \n            // Add liftAmount to terrain height for physical push-back interaction\n            excavatorGroup.position.set(posX, posY, posZ);\n            \n            // Apply original rotation and combine with tilt interaction angles (tiltX, tiltZ)\n            excavatorGroup.rotation.set(rotX, rotY, rotZ);\n            \n            upperGroup.rotation.y = excState.upperRotation;\n            boomGroup.rotation.x = excState.boomAngle;\n            armGroup.rotation.x = excState.armAngle;\n            bucketGroup.rotation.x = excState.bucketAngle;\n            if (bucketDirtMesh) {\n                // Ensure bucket dirt is always visible when gems are in the bucket, showing gems resting on top of it\n                const gemInBucket = treasures.some(t => t.scooped && !t.collected);\n                const visualDirtScale = gemInBucket ? Math.max(0.7, excState.dirtInBucket) : excState.dirtInBucket;\n                bucketDirtMesh.scale.set(visualDirtScale, visualDirtScale, visualDirtScale);\n                bucketDirtMesh.visible = (visualDirtScale > 0.05);\n            }\n        }\n\n        function updateCamera(dt) {\n            if (typeof isCinematicActive !== 'undefined' && isCinematicActive) {\n                const step = cinematicSteps[cinematicStep];\n                if (step) {\n                    cinematicInterpolation = Math.min(1.0, cinematicInterpolation + dt * 1.5);\n                    \n                    const tVal = cinematicInterpolation;\n                    const easeT = tVal < 0.5 ? 4 * tVal * tVal * tVal : 1 - Math.pow(-2 * tVal + 2, 3) / 2;\n\n                    cineCurrentPos.lerpVectors(cineStartPos, step.camPos, easeT);\n                    cineCurrentLookAt.lerpVectors(cineStartLookAt, step.lookAt, easeT);\n\n                    camera.position.copy(cineCurrentPos);\n                    camera.lookAt(cineCurrentLookAt);\n                }\n                return;\n            }\n\n            const target = new THREE.Vector3(excState.x, getTerrainHeight(excState.x, excState.z) + 3, excState.z);\n            \n            // Apply camera/screen shake displacement to target lookAt\n            if (typeof cameraShakeIntensity !== 'undefined' && cameraShakeIntensity > 0) {\n                target.x += (Math.random() - 0.5) * cameraShakeIntensity * 0.7;\n                target.y += (Math.random() - 0.5) * cameraShakeIntensity * 0.7;\n                target.z += (Math.random() - 0.5) * cameraShakeIntensity * 0.7;\n            }\n\n            const cx = target.x + Math.sin(camState.azimuth) * Math.cos(camState.elevation) * camState.distance;\n            const cy = target.y + Math.sin(camState.elevation) * camState.distance;\n            const cz = target.z + Math.cos(camState.azimuth) * Math.cos(camState.elevation) * camState.distance;\n            \n            camera.position.set(cx, cy, cz);\n\n            // Apply camera position shake\n            if (typeof cameraShakeIntensity !== 'undefined' && cameraShakeIntensity > 0) {\n                camera.position.x += (Math.random() - 0.5) * cameraShakeIntensity;\n                camera.position.y += (Math.random() - 0.5) * cameraShakeIntensity;\n                camera.position.z += (Math.random() - 0.5) * cameraShakeIntensity;\n            }\n\n            camera.lookAt(target);\n        }\n\n        // Marker animation\n        let markerTime = 0;\n\n        function gameLoop(timestamp) {\n            const dt = Math.min((timestamp - lastTime) / 1000, 0.11);\n            lastTime = timestamp;\n\n            // Update environment from config (live in edit mode)\n            if (mode === 'edit') {\n                scene.background = new THREE.Color(config.environment.skyColor);\n                scene.fog.color = new THREE.Color(config.environment.skyColor);\n                scene.fog.density = config.environment.fogDensity;\n                updateTerrainGeometry();\n                if (bucketDirtMat) {\n                    bucketDirtMat.color = new THREE.Color(config.terrain.soilColor);\n                }\n            }\n\n            update(dt);\n            updateExcavatorTransform();\n            updateCamera(dt);\n\n            // Animate marker if exists\n            markerTime += dt;\n            if (marker) {\n                marker.position.y = getTerrainHeight(20, 20) + 0.5 + Math.sin(markerTime * 2) * 0.3;\n                marker.rotation.y += dt * 0.5;\n            }\n\n            renderer.render(scene, camera);\n            requestAnimationFrame(gameLoop);\n        }\n\n        // Complete loading and fade out screen\n        setLoadProgress(100, t('ready'));\n        setTimeout(() => {\n            if (loadingScreen) {\n                loadingScreen.style.opacity = '0';\n                setTimeout(() => {\n                    loadingScreen.style.display = 'none';\n                }, 500);\n            }\n        }, 600);\n\n        lastTime = performance.now();\n        requestAnimationFrame(gameLoop);\n    }\n    window.run = run;\n    </script>\n</body>\n</html>", "game_config": "{\n  \"excavator\": {\n    \"speed\": 1.25,\n    \"bucketCapacity\": 1.0,\n    \"startX\": 0,\n    \"startZ\": 10\n  },\n  \"terrain\": {\n    \"roughness\": 1.0,\n    \"hardness\": 0.65,\n    \"soilColor\": \"#a67a53\"\n  },\n  \"environment\": {\n    \"skyColor\": \"#8a9ba8\",\n    \"fogDensity\": 0.01\n  },\n  \"physics\": {\n    \"gravity\": 1.0\n  }\n}", "game_design_document": "## Core Game Loop and Mechanics\n\n**Terraform Tycoon** is a 3D creative sandbox where players operate a detailed excavator to terraform an alien planet's surface. The core loop involves:\n\n1. **Survey the terrain** - Players view a barren alien landscape with hills, valleys, and rough terrain\n2. **Operate the excavator** - Control a fully articulated 3D excavator with realistic arm, boom, and bucket movements\n3. **Dig and sculpt** - Remove terrain, create flat areas, dig trenches, pile up earth\n4. **Build colony foundations** - Flatten areas for landing pads, create water reservoirs, shape protective barriers\n5. **Complete objectives** - Fulfill specific terraforming goals (flatten X area, create Y depth trench, etc.)\n6. **Unlock progression** - Earn credits to unlock new excavator types and planet locations\n\nThe gameplay emphasizes precision control, creative freedom, and the satisfaction of transforming raw terrain into purposeful landscapes.\n\n## Starting Scope\n\nFor the initial implementation, we'll focus on creating a polished, playable core experience:\n\n**Must Have (First Iteration):**\n- Single 3D excavator model with fully articulated parts (base rotation, boom, arm, bucket)\n- Deformable voxel-based terrain system that responds to excavator actions\n- Third-person camera that follows the excavator with manual rotation\n- Realistic excavator controls (rotate base, raise/lower boom, extend/retract arm, open/close bucket)\n- One alien planet environment with procedurally varied terrain\n- Basic tutorial/objective system (e.g., \"Flatten this marked area\", \"Dig a trench 5 units deep\")\n- Simple physics for dirt/terrain chunks\n- Day/night cycle or atmospheric lighting for alien world feel\n\n**Future Iterations:**\n- Multiple excavator types with different capabilities\n- Fleet management (multiple excavators working simultaneously)\n- More complex objectives and colony building elements\n- Additional planets with unique terrain properties\n- Upgrade system for excavators\n- Time-based challenges\n\n## Game Perspective\n\n**3D Third-Person** - The camera follows behind and above the excavator, allowing players to see the machine's articulation and the terrain being modified. Players can rotate the camera around the excavator for better viewing angles during precision work.\n\n## Game World and Level Design\n\n**Setting:** Alien planets with barren, rocky terrain featuring hills, valleys, craters, and uneven surfaces. The environment has an otherworldly feel with unusual rock formations, strange colored soil (rust-red, purple-grey, cyan-tinted), and a distant alien sky.\n\n**Level Structure:**\n- **Tutorial Zone**: A small, contained area (50x50 units) with clear objectives to teach excavator controls\n  - Objective 1: Rotate the excavator base 360 degrees\n  - Objective 2: Dig a small hole (3 units deep)\n  - Objective 3: Flatten a marked 10x10 area\n  \n- **Main Terraforming Zone**: A larger open area (100x100 units) with varied terrain\n  - Multiple objective markers showing areas that need terraforming\n  - Procedurally generated hills (5-15 units high) and valleys (3-10 units deep)\n  - Visual markers for colony foundation sites (landing pad locations, water reservoir sites)\n  - Terrain has realistic physics - loose soil on slopes, stable flat areas\n\n**Terrain System:**\n- Voxel-based deformable terrain that responds realistically to excavator bucket\n- Terrain \"chunks\" can be scooped, moved, and deposited\n- Visual feedback showing terrain deformation in real-time\n- Different soil densities (loose surface soil vs. harder packed earth deeper down)\n\n## Edit Mode Design\n\nPlayers can customize their terraforming experience through these editable parameters:\n\n**Excavator Properties:**\n- Excavator color scheme (body, boom, bucket colors)\n- Movement speed (rotation, boom/arm speed)\n- Bucket capacity (how much terrain per scoop)\n- Control sensitivity\n\n**Terrain Properties:**\n- Initial terrain roughness (how varied the starting landscape is)\n- Soil color palette (rust-red, purple-grey, cyan, earth-brown, etc.)\n- Terrain hardness (how easily it deforms)\n- Gravity strength (affects falling dirt physics)\n\n**Environment Properties:**\n- Sky color and atmosphere\n- Lighting intensity and color\n- Time of day\n- Fog density for alien atmosphere\n\n**Objective Properties:**\n- Target area sizes for flattening objectives\n- Required trench depths\n- Number of objectives to complete\n- Time limits (optional challenge mode)\n\n**Constraints:**\n- Excavator speed: 0.5x to 2x normal\n- Bucket capacity: 50% to 200% of default\n- Terrain size: Fixed at 100x100 to maintain performance\n- Minimum objective size: 5x5 units (to ensure completable goals)\n\n## Control Design\n\n**Desktop Controls:**\n- **Mouse Look (Right-click + drag or pointer lock)**: Rotate camera around excavator\n- **WASD**: Move excavator forward/backward/strafe left/right\n- **Q/E**: Rotate excavator base left/right\n- **Arrow Up/Down**: Raise/lower boom\n- **Arrow Left/Right**: Extend/retract arm\n- **Space**: Open/close bucket (hold to scoop, release to drop)\n- **Shift**: Boost movement speed\n- **Tab**: Toggle between free camera and follow camera\n- **ESC**: Pause menu / release pointer lock\n\n**Mobile Controls:**\n- **Left Virtual Joystick**: Move excavator (forward/back/strafe)\n- **Right Virtual Joystick**: Rotate camera\n- **Bottom-right Button Panel**:\n  - Rotate Base Left/Right buttons (Q/E equivalent)\n  - Boom Up/Down buttons (arrow up/down)\n  - Arm Extend/Retract buttons (arrow left/right)\n  - Bucket Open/Close toggle button (space)\n- **Pinch gesture**: Zoom camera in/out\n- **Two-finger drag**: Pan camera\n\n**Control Notes:**\n- Excavator controls are designed to feel realistic but accessible\n- Each articulated part (base, boom, arm, bucket) operates independently\n- Visual feedback shows which part is currently moving\n- Smooth interpolation for all movements to feel mechanical but responsive\n- Camera automatically adjusts to keep excavator in view during operation\n\n## Win/Lose Conditions\n\n**Win Conditions:**\n- Complete all terraforming objectives in the current zone\n- Each objective has clear success criteria (e.g., \"95% of marked area must be within 0.5 units of target height\")\n- Visual feedback shows objective progress (green checkmark when complete)\n- Completing all objectives unlocks the next planet/zone\n\n**No Traditional Lose Condition:**\n- This is a creative sandbox with objectives, not a fail-state game\n- Players can take as long as needed to complete objectives\n- Optional challenge mode (future iteration) could add time limits\n- Players can reset terrain if they want to start over\n\n**Progression:**\n- Earn \"Terraform Credits\" for completing objectives\n- Credits unlock new excavator paint schemes and planet environments\n- Completion percentage tracked for each planet\n\n## Technical Implementation Notes\n\n**3D Rendering:**\n- Use Three.js for 3D rendering (available via CDN)\n- Excavator model built from geometric primitives (boxes, cylinders) with proper hierarchy\n- Base \u2192 Boom \u2192 Arm \u2192 Bucket parent-child relationships for realistic articulation\n\n**Terrain System:**\n- Simplified voxel/heightmap hybrid approach\n- Grid-based terrain (e.g., 100x100 grid of height values)\n- Terrain mesh updates in real-time as excavator modifies it\n- Use vertex displacement for smooth terrain deformation\n\n**Physics:**\n- Basic physics for dirt particles when digging\n- Simplified collision detection between bucket and terrain\n- No complex rigid body physics needed - focus on terrain deformation\n\n**Performance:**\n- Optimize terrain mesh updates (only update affected chunks)\n- Limit particle effects to maintain 30+ FPS on mobile\n- Use LOD (Level of Detail) for distant terrain if needed\n\n## Art Style and Visual Theme\n\n**Overall Style:** Semi-realistic industrial with sci-fi elements. The excavator should look like a real, functional machine with clear mechanical parts, while the alien environment provides otherworldly color and atmosphere.\n\n**Color Palette:**\n- **Excavator**: Industrial yellow/orange with black accents, metallic grey details, warning stripes\n- **Terrain**: Alien soil colors - rust-red, purple-grey, cyan-tinted earth, unusual rock formations\n- **Sky**: Otherworldly - purple-pink gradients, dual suns, strange cloud formations\n- **UI**: Clean, futuristic HUD with holographic-style objective markers\n\n**Visual Elements:**\n- Excavator has visible hydraulic pistons, treads, cabin details\n- Terrain shows layers (topsoil, subsoil, bedrock colors)\n- Particle effects for dust/dirt when digging\n- Atmospheric effects (light fog, god rays, alien atmosphere glow)\n- Objective markers are holographic-style floating UI elements in 3D space\n\n**Asset Approach:**\n- Excavator: Generate detailed 3D-style reference images for each component, then build with Three.js primitives\n- Terrain: Procedural generation with texture maps for surface detail\n- Sky: Gradient skybox or simple procedural sky\n- UI elements: Generate clean, futuristic interface graphics", "persistent_storage_config": {"leaderboard": {"sort_ascending": false}}, "game_metadata": {"game_id": "01KVCTYVNGGV78YZW1YKV3RMD4", "title": "\u00a0Excavator Simulator", "description": "Command excavators to reshape alien worlds into thriving colonies through strategic digging and terrain sculpting!", "thumbnail_url": "https://dzmv1mxivz48k.cloudfront.net/images/Google_107480926520269799577/1787507132941_01M0QVMJGDWX8261XGP3GQVAPT.333333.gif", "created_at": 1781768729, "updated_at": 1787507259341.1624, "art_style": null}, "task_plan": null}