🚀 qwen3-coder

LiteChat Model Race Result (RUNJS)

```runjs
// Clear any previous content
litechat.target.replaceChildren();

async function createScrollShooter() {
    try {
        litechat.utils.log('info', '🚀 Starting Scroll Shooter creation...');
        
        // Load Three.js and required modules
        const modules = await litechat.utils.loadModules([
            {
                url: 'https://unpkg.com/three@0.170.0/build/three.module.js',
                name: 'THREE',
                globalKey: 'THREE',
                importMap: {
                    "three": "https://unpkg.com/three@0.170.0/build/three.module.js"
                }
            }
        ]);

        const { THREE } = modules;
        
        // Game state
        const gameState = {
            score: 0,
            lives: 3,
            fireRate: 1,
            bouncyShots: 0,
            gunMode: 1, // 1: single, 2: double, 3: triple
            enemySpeedMultiplier: 1,
            enemiesKilled: 0,
            powerups: {
                fireRate: 0,
                bouncy: 0,
                guns: 0,
                lives: 0
            }
        };

        // Create container
        const container = document.createElement('div');
        container.className = 'relative w-full h-[600px] bg-gradient-to-b from-purple-900 to-indigo-800 rounded-lg overflow-hidden';
        
        // Create canvas
        const canvas = document.createElement('canvas');
        canvas.width = 800;
        canvas.height = 600;
        canvas.className = 'absolute inset-0';
        container.appendChild(canvas);
        
        // UI Overlay
        const uiOverlay = document.createElement('div');
        uiOverlay.className = 'absolute inset-0 pointer-events-none';
        container.appendChild(uiOverlay);
        
        // Score display
        const scoreDisplay = document.createElement('div');
        scoreDisplay.className = 'absolute top-4 left-4 text-yellow-300 font-bold text-xl';
        scoreDisplay.textContent = `Score: ${gameState.score}`;
        uiOverlay.appendChild(scoreDisplay);
        
        // Lives display
        const livesDisplay = document.createElement('div');
        livesDisplay.className = 'absolute top-4 right-4 text-red-400 font-bold text-xl';
        livesDisplay.textContent = `Lives: ${gameState.lives}`;
        uiOverlay.appendChild(livesDisplay);
        
        // Powerup display
        const powerupDisplay = document.createElement('div');
        powerupDisplay.className = 'absolute bottom-4 left-4 text-white text-sm';
        powerupDisplay.innerHTML = `
            <div>Fire Rate: ${(gameState.fireRate).toFixed(1)}x</div>
            <div>Bouncy Shots: ${gameState.bouncyShots}</div>
            <div>Guns: ${gameState.gunMode}</div>
        `;
        uiOverlay.appendChild(powerupDisplay);
        
        // Instructions
        const instructions = document.createElement('div');
        instructions.className = 'absolute bottom-4 right-4 text-white text-sm text-right';
        instructions.innerHTML = `
            <div>← → : Move</div>
            <div>SPACE : Shoot</div>
            <div>Catch powerups!</div>
        `;
        uiOverlay.appendChild(instructions);
        
        litechat.target.appendChild(container);

        // Three.js scene setup
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x1a0033); // Deep purple
        
        const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
        camera.position.set(0, 0, 10);
        
        const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
        renderer.setSize(canvas.width, canvas.height);
        
        // Lighting
        const ambientLight = new THREE.AmbientLight(0x404040, 1.5);
        scene.add(ambientLight);
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(5, 5, 5);
        scene.add(directionalLight);
        
        // Player ship
        const playerGeometry = new THREE.ConeGeometry(0.5, 1.5, 4);
        playerGeometry.rotateX(Math.PI / 2);
        const playerMaterial = new THREE.MeshPhongMaterial({ 
            color: 0x00ffff,
            emissive: 0x004444,
            shininess: 100
        });
        const player = new THREE.Mesh(playerGeometry, playerMaterial);
        player.position.z = -5;
        scene.add(player);
        
        // Game objects
        const bullets = [];
        const enemies = [];
        const powerups = [];
        const particles = [];
        
        // Create starfield background
        const starGeometry = new THREE.BufferGeometry();
        const starCount = 1000;
        const starPositions = new Float32Array(starCount * 3);
        
        for (let i = 0; i < starCount * 3; i += 3) {
            starPositions[i] = (Math.random() - 0.5) * 100;
            starPositions[i + 1] = (Math.random() - 0.5) * 100;
            starPositions[i + 2] = (Math.random() - 0.5) * 100 - 10;
        }
        
        starGeometry.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
        const starMaterial = new THREE.PointsMaterial({
            color: 0xffffff,
            size: 0.1,
            transparent: true,
            opacity: 0.8
        });
        const starField = new THREE.Points(starGeometry, starMaterial);
        scene.add(starField);
        
        // Input handling
        const keys = {};
        window.addEventListener('keydown', (e) => {
            keys[e.key] = true;
            
            // Prevent spacebar from scrolling page
            if (e.key === ' ') {
                e.preventDefault();
            }
        });
        window.addEventListener('keyup', (e) => {
            keys[e.key] = false;
        });
        
        // Touch handling for mobile
        let touchStartX = 0;
        canvas.addEventListener('touchstart', (e) => {
            touchStartX = e.touches[0].clientX;
            e.preventDefault();
        });
        
        canvas.addEventListener('touchmove', (e) => {
            const touchX = e.touches[0].clientX;
            const diff = touchX - touchStartX;
            
            // Move player based on touch movement
            player.position.x += diff * 0.01;
            player.position.x = Math.max(-8, Math.min(8, player.position.x));
            
            touchStartX = touchX;
            e.preventDefault();
        });
        
        // Shooting
        let lastShot = 0;
        const shoot = () => {
            const now = Date.now();
            if (now - lastShot > 200 / gameState.fireRate) {
                lastShot = now;
                
                const createBullet = (xOffset = 0, yOffset = 0, zOffset = 0) => {
                    const bulletGeometry = new THREE.SphereGeometry(0.1, 8, 8);
                    const bulletMaterial = new THREE.MeshPhongMaterial({ 
                        color: 0xff00ff,
                        emissive: 0x440044
                    });
                    const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);
                    bullet.position.set(
                        player.position.x + xOffset,
                        player.position.y + yOffset,
                        player.position.z + zOffset
                    );
                    bullet.userData = { 
                        bounces: gameState.bouncyShots,
                        isBullet: true 
                    };
                    scene.add(bullet);
                    bullets.push(bullet);
                };
                
                // Different gun modes
                switch (gameState.gunMode) {
                    case 1: // Single shot
                        createBullet();
                        break;
                    case 2: // Double shot
                        createBullet(-0.3, 0, 0);
                        createBullet(0.3, 0, 0);
                        break;
                    case 3: // Triple shot
                        createBullet(-0.4, 0, 0);
                        createBullet(0, 0, 0.2);
                        createBullet(0.4, 0, 0);
                        break;
                }
            }
        };
        
        // Create enemy
        const createEnemy = () => {
            const enemyGeometry = new THREE.OctahedronGeometry(0.5);
            const enemyMaterial = new THREE.MeshPhongMaterial({ 
                color: 0xff5500,
                emissive: 0x442200
            });
            const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
            
            // Random position at top of screen
            enemy.position.set(
                (Math.random() - 0.5) * 16,
                10,
                player.position.z - 5
            );
            
            enemy.userData = { 
                speed: 0.05 * gameState.enemySpeedMultiplier,
                health: 1 + Math.floor(gameState.enemiesKilled / 20),
                isEnemy: true 
            };
            
            scene.add(enemy);
            enemies.push(enemy);
        };
        
        // Create powerup
        const createPowerup = () => {
            const types = ['fireRate', 'bouncy', 'guns', 'lives'];
            const type = types[Math.floor(Math.random() * types.length)];
            
            let color, emissive;
            switch (type) {
                case 'fireRate': color = 0xffff00; emissive = 0x444400; break; // Yellow
                case 'bouncy': color = 0x00ff00; emissive = 0x004400; break;   // Green
                case 'guns': color = 0xff00ff; emissive = 0x440044; break;     // Magenta
                case 'lives': color = 0xff0000; emissive = 0x440000; break;    // Red
            }
            
            const powerupGeometry = new THREE.IcosahedronGeometry(0.3);
            const powerupMaterial = new THREE.MeshPhongMaterial({ 
                color, 
                emissive,
                shininess: 100
            });
            const powerup = new THREE.Mesh(powerupGeometry, powerupMaterial);
            
            powerup.position.set(
                (Math.random() - 0.5) * 16,
                10,
                player.position.z - 5
            );
            
            powerup.userData = { 
                type,
                isPowerup: true 
            };
            
            scene.add(powerup);
            powerups.push(powerup);
        };
        
        // Create explosion particles
        const createExplosion = (position) => {
            for (let i = 0; i < 10; i++) {
                const particleGeometry = new THREE.SphereGeometry(0.1, 4, 4);
                const particleMaterial = new THREE.MeshPhongMaterial({ 
                    color: 0xff5500,
                    emissive: 0x442200
                });
                const particle = new THREE.Mesh(particleGeometry, particleMaterial);
                
                particle.position.copy(position);
                particle.userData = {
                    velocity: new THREE.Vector3(
                        (Math.random() - 0.5) * 0.2,
                        (Math.random() - 0.5) * 0.2,
                        (Math.random() - 0.5) * 0.2
                    ),
                    life: 30
                };
                
                scene.add(particle);
                particles.push(particle);
            }
        };
        
        // Game loop
        let lastEnemySpawn = 0;
        let lastPowerupSpawn = 0;
        
        const animate = () => {
            requestAnimationFrame(animate);
            
            // Player movement
            if (keys['ArrowLeft'] || keys['a']) {
                player.position.x -= 0.2;
            }
            if (keys['ArrowRight'] || keys['d']) {
                player.position.x += 0.2;
            }
            
            // Keep player in bounds
            player.position.x = Math.max(-8, Math.min(8, player.position.x));
            
            // Shooting
            if (keys[' '] || keys['w'] || keys['ArrowUp']) {
                shoot();
            }
            
            // Spawn enemies
            const now = Date.now();
            if (now - lastEnemySpawn > 1000) {
                lastEnemySpawn = now;
                createEnemy();
            }
            
            // Spawn powerups (less frequently)
            if (now - lastPowerupSpawn > 5000) {
                lastPowerupSpawn = now;
                if (Math.random() > 0.7) { // 30% chance
                    createPowerup();
                }
            }
            
            // Update bullets
            for (let i = bullets.length - 1; i >= 0; i--) {
                const bullet = bullets[i];
                bullet.position.y += 0.5;
                
                // Remove bullets that go off screen
                if (bullet.position.y > 15) {
                    scene.remove(bullet);
                    bullets.splice(i, 1);
                }
            }
            
            // Update enemies
            for (let i = enemies.length - 1; i >= 0; i--) {
                const enemy = enemies[i];
                enemy.position.y -= enemy.userData.speed;
                enemy.rotation.x += 0.05;
                enemy.rotation.y += 0.03;
                
                // Remove enemies that go off screen
                if (enemy.position.y < -10) {
                    scene.remove(enemy);
                    enemies.splice(i, 1);
                    // Lose a life when enemy escapes
                    gameState.lives--;
                    livesDisplay.textContent = `Lives: ${gameState.lives}`;
                    
                    if (gameState.lives <= 0) {
                        // Game over
                        const gameOver = document.createElement('div');
                        gameOver.className = 'absolute inset-0 flex items-center justify-center bg-black bg-opacity-70 text-white text-4xl font-bold';
                        gameOver.textContent = 'GAME OVER';
                        uiOverlay.appendChild(gameOver);
                        return;
                    }
                }
            }
            
            // Update powerups
            for (let i = powerups.length - 1; i >= 0; i--) {
                const powerup = powerups[i];
                powerup.position.y -= 0.05;
                powerup.rotation.x += 0.03;
                powerup.rotation.y += 0.05;
                
                // Remove powerups that go off screen
                if (powerup.position.y < -10) {
                    scene.remove(powerup);
                    powerups.splice(i, 1);
                }
            }
            
            // Update particles
            for (let i = particles.length - 1; i >= 0; i--) {
                const particle = particles[i];
                particle.position.add(particle.userData.velocity);
                particle.userData.life--;
                
                if (particle.userData.life <= 0) {
                    scene.remove(particle);
                    particles.splice(i, 1);
                }
            }
            
            // Collision detection - bullets vs enemies
            for (let i = bullets.length - 1; i >= 0; i--) {
                const bullet = bullets[i];
                
                for (let j = enemies.length - 1; j >= 0; j--) {
                    const enemy = enemies[j];
                    
                    const distance = bullet.position.distanceTo(enemy.position);
                    if (distance < 0.8) {
                        // Hit!
                        createExplosion(enemy.position);
                        
                        // Remove enemy
                        scene.remove(enemy);
                        enemies.splice(j, 1);
                        
                        // Handle bouncy shots
                        if (bullet.userData.bounces > 0) {
                            bullet.userData.bounces--;
                            // Keep bullet, change direction randomly
                            bullet.position.y -= 1; // Move down a bit
                        } else {
                            // Remove bullet
                            scene.remove(bullet);
                            bullets.splice(i, 1);
                        }
                        
                        // Update score
                        gameState.score += 10;
                        scoreDisplay.textContent = `Score: ${gameState.score}`;
                        
                        gameState.enemiesKilled++;
                        
                        // Increase difficulty every 10 kills
                        if (gameState.enemiesKilled % 10 === 0) {
                            gameState.enemySpeedMultiplier += 0.1;
                        }
                        
                        break;
                    }
                }
            }
            
            // Collision detection - player vs enemies
            for (let i = enemies.length - 1; i >= 0; i--) {
                const enemy = enemies[i];
                const distance = player.position.distanceTo(enemy.position);
                
                if (distance < 1) {
                    // Collision!
                    createExplosion(enemy.position);
                    scene.remove(enemy);
                    enemies.splice(i, 1);
                    
                    gameState.lives--;
                    livesDisplay.textContent = `Lives: ${gameState.lives}`;
                    
                    if (gameState.lives <= 0) {
                        // Game over
                        const gameOver = document.createElement('div');
                        gameOver.className = 'absolute inset-0 flex items-center justify-center bg-black bg-opacity-70 text-white text-4xl font-bold';
                        gameOver.textContent = 'GAME OVER';
                        uiOverlay.appendChild(gameOver);
                        return;
                    }
                }
            }
            
            // Collision detection - player vs powerups
            for (let i = powerups.length - 1; i >= 0; i--) {
                const powerup = powerups[i];
                const distance = player.position.distanceTo(powerup.position);
                
                if (distance < 1) {
                    // Collect powerup
                    switch (powerup.userData.type) {
                        case 'fireRate':
                            gameState.fireRate += 0.1;
                            gameState.powerups.fireRate++;
                            break;
                        case 'bouncy':
                            gameState.bouncyShots++;
                            gameState.powerups.bouncy++;
                            break;
                        case 'guns':
                            gameState.gunMode = Math.min(3, gameState.gunMode + 1);
                            gameState.powerups.guns++;
                            break;
                        case 'lives':
                            gameState.lives++;
                            gameState.powerups.lives++;
                            livesDisplay.textContent = `Lives: ${gameState.lives}`;
                            break;
                    }
                    
                    // Update powerup display
                    powerupDisplay.innerHTML = `
                        <div>Fire Rate: ${(gameState.fireRate).toFixed(1)}x</div>
                        <div>Bouncy Shots: ${gameState.bouncyShots}</div>
                        <div>Guns: ${gameState.gunMode}</div>
                    `;
                    
                    scene.remove(powerup);
                    powerups.splice(i, 1);
                }
            }
            
            // Rotate player slightly for visual effect
            player.rotation.z = Math.sin(Date.now() * 0.005) * 0.1;
            
            // Move starfield for parallax effect
            starField.position.y -= 0.01;
            if (starField.position.y < -50) {
                starField.position.y = 50;
            }
            
            renderer.render(scene, camera);
        };

        animate();
        litechat.utils.log('info', '🎉 SUCCESS! Scroll Shooter is ready!');
        
    } catch (error) {
        litechat.utils.log('error', '❌ FAILED to create game:', error.message);
        const errorDiv = document.createElement('div');
        errorDiv.className = 'p-4 text-red-600 bg-red-100 border border-red-200 rounded-md';
        errorDiv.textContent = `Error: ${error.message}`;
        litechat.target.appendChild(errorDiv);
    }
}

createScrollShooter();
```