A downloadable Modding code

Here is minion rush 3d remake source modding code for the game 

// ==========================================

// 1. GAME STATE & MODIFIABLE CONFIGURATION

// ==========================================

let audioEnabled = true;

let synth = null;


let scene, camera, renderer;

let minionGroup, bodyMesh, goggleMesh, eyeMesh, pupilMesh, overallMesh, accessoryMesh;

let trackTiles = [];

let obstacles = [];

let bananas = [];


// Saved Cloud Data Slots

window.cloudSavesList = [

    { id: 'save_default', name: 'Agent Dave Backup', bananas: 1250, tokens: 45, highscore: 3420, gameVersion: 'v2.8.0', savedAt: new Date().toLocaleDateString() }

];


// Outfit Data - Modify colors, pricing, or currency types

const costumeData = [

    { id: 'classic', name: 'Classic Dave', color: 0xffd200, price: 0, currency: 'banana', desc: 'Standard yellow Minion' },

    { id: 'tourist', name: 'Tourist Carl', color: 0x38bdf8, price: 500, currency: 'banana', desc: 'Beach vibes & cool outfit' },

    { id: 'disco', name: 'Disco Stuart', color: 0xa855f7, price: 1000, currency: 'banana', desc: 'Groovy dance style' },

    { id: 'evil', name: 'Evil Minion', color: 0x9333ea, price: 20, currency: 'token', desc: 'Wild purple skin & monster look' }

];


// Power-up Upgrade Configurations

const upgradeData = [

    { id: 'magnet', name: 'Banana Magnet', icon: 'fa-magnet', color: 'text-amber-400', level: 1, maxLevel: 5, desc: 'Attracts nearby bananas automatically' },

    { id: 'shield', name: 'Gru Shield', icon: 'fa-shield-halved', color: 'text-cyan-400', level: 1, maxLevel: 5, desc: 'Protects from 1 fatal crash' }

];


// Main Runtime State Variables

const gameState = {

    bananas: 1250,

    tokens: 45,

    level: 1,

    xp: 60,

    highscore: 3420,

    version: 'v2.8.0',

    currentCostume: 'classic',

    unlockedCostumes: ['classic'],

    controlMode: 'pc',

    

    inGame: false,

    isPaused: false,

    gameMode: 'classic', // Modes: 'classic' | 'challenge'

    activeChallenge: null,

    challengeProgress: 0,

    challengeTimer: 0,

    challengeDodged: 0,

    

    score: 0,

    distance: 0,

    currentLane: 0, // -1: Left Lane, 0: Center, 1: Right Lane

    targetX: 0,

    minionY: 0,

    minionVelocityY: 0,

    isJumping: false,

    isSliding: false,

    slideTimer: 0,

    speed: 0.22, // Modify game runner speed here

    hasShield: false,


    dailyRewardsClaimed: [1]

};


// Moddable Challenge Mission Objectives

const challengeData = [

    {

        id: 'c1',

        title: 'Banana Blitz',

        desc: 'Collect 30 Bananas in under 35 seconds!',

        icon: 'fa-bananas',

        targetType: 'bananas',

        targetVal: 30,

        timeLimit: 35,

        rewardBananas: 500,

        rewardTokens: 10,

        speedMult: 1.0

    },

    {

        id: 'c2',

        title: 'Speed Demon',

        desc: 'Run 400 meters at 1.8x Super Speed!',

        icon: 'fa-gauge-high',

        targetType: 'distance',

        targetVal: 400,

        timeLimit: 0,

        rewardBananas: 800,

        rewardTokens: 20,

        speedMult: 1.8

    },

    {

        id: 'c3',

        title: 'Laser Dodger',

        desc: 'Dodge 15 obstacles without crashing!',

        icon: 'fa-shield-halved',

        targetType: 'dodged',

        targetVal: 15,

        timeLimit: 0,

        rewardBananas: 1000,

        rewardTokens: 25,

        speedMult: 1.2

    }

];


// ==========================================

// 2. THREE.JS 3D SCENE & ENGINE INITIALIZATION

// ==========================================

function initThree() {

    const container = document.getElementById('canvas-container');

    if (!container) return;


    scene = new THREE.Scene();

    scene.background = new THREE.Color(0x0f172a);

    scene.fog = new THREE.FogExp2(0x0f172a, 0.025);


    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);

    camera.position.set(0, 3.5, 6.5);

    camera.lookAt(0, 1, 0);


    renderer = new THREE.WebGLRenderer({ antialias: true });

    renderer.setSize(window.innerWidth, window.innerHeight);

    renderer.shadowMap.enabled = true;

    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

    container.appendChild(renderer.domElement);


    const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);

    scene.add(ambientLight);


    const dirLight = new THREE.DirectionalLight(0xffffff, 0.9);

    dirLight.position.set(5, 12, 8);

    dirLight.castShadow = true;

    scene.add(dirLight);


    // Build 3D Character Geometry Group

    minionGroup = new THREE.Group();


    const bodyGeo = new THREE.CylinderGeometry(0.5, 0.5, 1.2, 32);

    const bodyMat = new THREE.MeshStandardMaterial({ color: 0xffd200, roughness: 0.3 });

    bodyMesh = new THREE.Mesh(bodyGeo, bodyMat);

    bodyMesh.position.y = 0.8;

    bodyMesh.castShadow = true;

    minionGroup.add(bodyMesh);


    const overallGeo = new THREE.CylinderGeometry(0.52, 0.52, 0.5, 32);

    const overallMat = new THREE.MeshStandardMaterial({ color: 0x0055b8, roughness: 0.5 });

    overallMesh = new THREE.Mesh(overallGeo, overallMat);

    overallMesh.position.y = 0.45;

    minionGroup.add(overallMesh);


    const goggleGeo = new THREE.TorusGeometry(0.22, 0.06, 16, 32);

    const goggleMat = new THREE.MeshStandardMaterial({ color: 0x94a3b8, metalness: 0.8, roughness: 0.2 });

    goggleMesh = new THREE.Mesh(goggleGeo, goggleMat);

    goggleMesh.position.set(0, 1.05, 0.48);

    minionGroup.add(goggleMesh);


    const eyeGeo = new THREE.SphereGeometry(0.15, 16, 16);

    const eyeMat = new THREE.MeshBasicMaterial({ color: 0xffffff });

    eyeMesh = new THREE.Mesh(eyeGeo, eyeMat);

    eyeMesh.position.set(0, 1.05, 0.45);

    minionGroup.add(eyeMesh);


    const pupilGeo = new THREE.SphereGeometry(0.06, 16, 16);

    const pupilMat = new THREE.MeshBasicMaterial({ color: 0x3b1c08 });

    pupilMesh = new THREE.Mesh(pupilGeo, pupilMat);

    pupilMesh.position.set(0, 1.05, 0.58);

    minionGroup.add(pupilMesh);


    scene.add(minionGroup);


    // Construct Initial Track Tiles

    for (let i = 0; i < 12; i++) {

        const tile = createTrackTile();

        tile.position.z = -i * 15;

        scene.add(tile);

        trackTiles.push(tile);

        if (i > 1) spawnTileContents(tile.position.z);

    }


    window.addEventListener('resize', onWindowResize, false);

    setupInputListeners();

    animate();

}


function createTrackTile() {

    const tileGroup = new THREE.Group();


    const floorGeo = new THREE.BoxGeometry(7.5, 0.2, 15);

    const floorMat = new THREE.MeshStandardMaterial({ color: 0x1e293b, roughness: 0.8 });

    const floor = new THREE.Mesh(floorGeo, floorMat);

    floor.position.y = -0.1;

    floor.receiveShadow = true;

    tileGroup.add(floor);


    // Lane Lines

    [-1.25, 1.25].forEach(x => {

        const lineGeo = new THREE.BoxGeometry(0.1, 0.02, 15);

        const lineMat = new THREE.MeshBasicMaterial({ color: 0x3b82f6 });

        const line = new THREE.Mesh(lineGeo, lineMat);

        line.position.set(x, 0.01, 0);

        tileGroup.add(line);

    });


    // Side Guard Rails

    [-3.8, 3.8].forEach(x => {

        const borderGeo = new THREE.BoxGeometry(0.3, 0.5, 15);

        const borderMat = new THREE.MeshStandardMaterial({ color: 0xffd200 });

        const border = new THREE.Mesh(borderGeo, borderMat);

        border.position.set(x, 0.25, 0);

        tileGroup.add(border);

    });


    return tileGroup;

}


// Spawns Obstacles & Bananas dynamically

function spawnTileContents(zPos) {

    const lanePositions = [-2, 0, 2];


    if (Math.random() > 0.3) {

        const lane = Math.floor(Math.random() * 3);

        const type = Math.random() > 0.5 ? 'low' : 'high';

        const obsGroup = new THREE.Group();


        if (type === 'low') {

            // Low Hurdle (Requires Jumping)

            const geo = new THREE.BoxGeometry(1.6, 0.7, 0.6);

            const mat = new THREE.MeshStandardMaterial({ color: 0xef4444, roughness: 0.4 });

            const mesh = new THREE.Mesh(geo, mat);

            mesh.position.y = 0.35;

            mesh.castShadow = true;

            obsGroup.add(mesh);

        } else {

            // High Bar (Requires Sliding)

            const postGeo = new THREE.CylinderGeometry(0.08, 0.08, 2, 16);

            const postMat = new THREE.MeshStandardMaterial({ color: 0x64748b });

            const p1 = new THREE.Mesh(postGeo, postMat);

            p1.position.set(-0.8, 1, 0);

            const p2 = new THREE.Mesh(postGeo, postMat);

            p2.position.set(0.8, 1, 0);

            

            const barGeo = new THREE.CylinderGeometry(0.06, 0.06, 1.8, 16);

            const barMat = new THREE.MeshBasicMaterial({ color: 0x06b6d4 });

            const bar = new THREE.Mesh(barGeo, barMat);

            bar.rotation.z = Math.PI / 2;

            bar.position.set(0, 1.4, 0);


            obsGroup.add(p1);

            obsGroup.add(p2);

            obsGroup.add(bar);

        }


        obsGroup.position.set(lanePositions[lane], 0, zPos);

        obsGroup.userData = { lane: lanePositions[lane], type: type, passed: false };

        scene.add(obsGroup);

        obstacles.push(obsGroup);

    }


    // Spawn Pickups

    const bananaLane = Math.floor(Math.random() * 3);

    for (let b = 0; b < 3; b++) {

        const bananaGeo = new THREE.TorusGeometry(0.18, 0.07, 8, 16, Math.PI);

        const bananaMat = new THREE.MeshStandardMaterial({ color: 0xfacc15, roughness: 0.2 });

        const bananaMesh = new THREE.Mesh(bananaGeo, bananaMat);

        bananaMesh.position.set(lanePositions[bananaLane], 0.6, zPos + (b * 1.5));

        bananaMesh.rotation.x = Math.PI / 2;

        scene.add(bananaMesh);

        bananas.push(bananaMesh);

    }

}


// Tone.js Sound Synthesizer Audio Handler

function playSound(type) {

    if (!audioEnabled) return;

    try {

        if (!synth && typeof Tone !== 'undefined') {

            synth = new Tone.Synth().toDestination();

        }

        if (synth) {

            if (type === 'banana') synth.triggerAttackRelease('C6', '16n');

            else if (type === 'jump') synth.triggerAttackRelease('G4', '8n');

            else if (type === 'slide') synth.triggerAttackRelease('E3', '8n');

            else if (type === 'hit') synth.triggerAttackRelease('C2', '4n');

            else if (type === 'click') synth.triggerAttackRelease('E5', '16n');

            else if (type === 'taunt') synth.triggerAttackRelease('A5', '8n');

        }

    } catch(e) {}

}


function toggleAudio() {

    audioEnabled = !audioEnabled;

    const icon = document.getElementById('audio-icon');

    if (icon) {

        icon.className = audioEnabled ? "fa-solid fa-volume-high text-base sm:text-lg" : "fa-solid fa-volume-xmark text-base sm:text-lg text-red-400";

    }

}


// ==========================================

// 3. CONTROLS & PLAYER INPUT LOGIC

// ==========================================

function setupInputListeners() {

    window.addEventListener('keydown', (e) => {

        if (!gameState.inGame) return;

        if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') triggerLaneLeft();

        if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') triggerLaneRight();

        if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W' || e.key === ' ') triggerJump();

        if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') triggerSlide();

        if (e.key === 'p' || e.key === 'P' || e.key === 'Escape') {

            if (gameState.isPaused) resumeGame();

            else pauseGame();

        }

    });


    let touchStartX = 0, touchStartY = 0;

    window.addEventListener('touchstart', (e) => {

        if (e.touches.length > 0) {

            touchStartX = e.touches[0].clientX;

            touchStartY = e.touches[0].clientY;

        }

    });


    window.addEventListener('touchend', (e) => {

        if (!gameState.inGame || e.changedTouches.length === 0) return;

        const touchEndX = e.changedTouches[0].clientX;

        const touchEndY = e.changedTouches[0].clientY;

        const dx = touchEndX - touchStartX;

        const dy = touchEndY - touchStartY;


        if (Math.abs(dx) > Math.abs(dy)) {

            if (dx > 30) triggerLaneRight();

            else if (dx < -30) triggerLaneLeft();

        } else {

            if (dy < -30) triggerJump();

            else if (dy > 30) triggerSlide();

        }

    });

}


function triggerLaneLeft() {

    if (gameState.currentLane > -1) {

        gameState.currentLane--;

        gameState.targetX = gameState.currentLane * 2;

    }

}


function triggerLaneRight() {

    if (gameState.currentLane < 1) {

        gameState.currentLane++;

        gameState.targetX = gameState.currentLane * 2;

    }

}


function triggerJump() {

    if (!gameState.isJumping) {

        gameState.isJumping = true;

        gameState.minionVelocityY = 0.22;

        playSound('jump');

    }

}


function triggerSlide() {

    if (!gameState.isSliding) {

        gameState.isSliding = true;

        gameState.slideTimer = 25;

        if (minionGroup) minionGroup.scale.set(1, 0.5, 1);

        playSound('slide');

    }

}


// ==========================================

// 4. MAIN GAME LOOP & PHYSICS TICK

// ==========================================

function animate() {

    requestAnimationFrame(animate);


    if (gameState.inGame && !gameState.isPaused) {

        // Smooth Lane Interpolation

        minionGroup.position.x += (gameState.targetX - minionGroup.position.x) * 0.2;


        // Gravity & Jump Physics

        if (gameState.isJumping) {

            gameState.minionY += gameState.minionVelocityY;

            gameState.minionVelocityY -= 0.012;


            if (gameState.minionY <= 0) {

                gameState.minionY = 0;

                gameState.isJumping = false;

            }

        }

        minionGroup.position.y = gameState.minionY;


        // Slide State Reset

        if (gameState.isSliding) {

            gameState.slideTimer--;

            if (gameState.slideTimer <= 0) {

                gameState.isSliding = false;

                if (minionGroup) minionGroup.scale.set(1, 1, 1);

            }

        }


        // Idle Bounce Oscillation

        if (!gameState.isJumping && !gameState.isSliding) {

            minionGroup.rotation.z = Math.sin(Date.now() * 0.01) * 0.05;

        }


        let currentSpeed = gameState.speed;

        if (gameState.gameMode === 'challenge' && gameState.activeChallenge) {

            currentSpeed *= gameState.activeChallenge.speedMult;

        }


        // Track Movement & Infinite Recycling

        trackTiles.forEach(tile => {

            tile.position.z += currentSpeed * 2.5;

            if (tile.position.z > 15) {

                tile.position.z -= 12 * 15;

                spawnTileContents(tile.position.z);

            }

        });


        // Update Distance Tracking

        gameState.distance += currentSpeed * 0.8;

        document.getElementById('hud-distance').innerText = Math.floor(gameState.distance);


        // Update Obstacles & Hit Collisions

        for (let i = obstacles.length - 1; i >= 0; i--) {

            const obs = obstacles[i];

            obs.position.z += currentSpeed * 2.5;


            if (!obs.userData.passed && obs.position.z > 0) {

                obs.userData.passed = true;

                gameState.challengeDodged++;

                checkChallengeProgress();

            }


            // Hit Detection Bounds

            if (Math.abs(obs.position.z) < 0.8 && Math.abs(obs.position.x - minionGroup.position.x) < 0.8) {

                let hit = false;

                if (obs.userData.type === 'low' && gameState.minionY < 0.5) hit = true;

                if (obs.userData.type === 'high' && !gameState.isSliding) hit = true;


                if (hit) {

                    if (gameState.hasShield) {

                        gameState.hasShield = false;

                        playSound('hit');

                        scene.remove(obs);

                        obstacles.splice(i, 1);

                        continue;

                    } else {

                        triggerGameOver();

                        return;

                    }

                }

            }


            if (obs.position.z > 10) {

                scene.remove(obs);

                obstacles.splice(i, 1);

            }

        }


        // Pickups & Banana Collisions

        for (let i = bananas.length - 1; i >= 0; i--) {

            const b = bananas[i];

            b.position.z += currentSpeed * 2.5;

            b.rotation.z += 0.05;


            if (Math.abs(b.position.z) < 0.9 && Math.abs(b.position.x - minionGroup.position.x) < 0.9 && gameState.minionY < 1.2) {

                gameState.bananas++;

                gameState.score += 10;

                document.getElementById('hud-banana').innerText = gameState.bananas;

                document.getElementById('banana-count').innerText = gameState.bananas.toLocaleString();

                playSound('banana');


                checkChallengeProgress();


                scene.remove(b);

                bananas.splice(i, 1);

                continue;

            }


            if (b.position.z > 10) {

                scene.remove(b);

                bananas.splice(i, 1);

            }

        }


        // Challenge Mode Timer Check

        if (gameState.gameMode === 'challenge' && gameState.activeChallenge && gameState.activeChallenge.timeLimit > 0) {

            gameState.challengeTimer -= 1 / 60;

            document.getElementById('challenge-timer-hud').innerText = Math.max(0, Math.ceil(gameState.challengeTimer)) + 's';

            if (gameState.challengeTimer <= 0) {

                triggerGameOver();

                return;

            }

        }

    } else if (!gameState.inGame) {

        if (minionGroup) {

            minionGroup.rotation.y += 0.01;

        }

    }


    renderer.render(scene, camera);

}


// ==========================================

// 5. GAME FLOW & MODAL MANAGEMENT

// ==========================================

function startGame(mode) {

    gameState.gameMode = mode;

    gameState.inGame = true;

    gameState.isPaused = false;

    gameState.score = 0;

    gameState.distance = 0;

    gameState.currentLane = 0;

    gameState.targetX = 0;

    gameState.minionY = 0;

    gameState.isJumping = false;

    gameState.isSliding = false;

    gameState.speed = 0.22;

    gameState.challengeDodged = 0;


    obstacles.forEach(o => scene.remove(o));

    bananas.forEach(b => scene.remove(b));

    obstacles = [];

    bananas = [];


    document.getElementById('main-menu').classList.add('hidden');

    document.getElementById('game-hud').classList.remove('hidden');

    document.getElementById('game-over-modal').classList.add('hidden');

    document.getElementById('challenge-modal').classList.add('hidden');


    if (mode === 'challenge' && gameState.activeChallenge) {

        gameState.challengeProgress = 0;

        gameState.challengeTimer = gameState.activeChallenge.timeLimit;

        document.getElementById('challenge-status-bar').classList.remove('hidden');

        document.getElementById('challenge-title-hud').innerText = gameState.activeChallenge.title;

        checkChallengeProgress();

    } else {

        document.getElementById('challenge-status-bar').classList.add('hidden');

    }


    minionGroup.position.set(0, 0, 0);

    camera.position.set(0, 3.5, 6.5);

    camera.lookAt(0, 1, 0);

}


function pauseGame() {

    if (!gameState.inGame) return;

    gameState.isPaused = true;

    document.getElementById('pause-modal')?.classList.remove('hidden');

}


function resumeGame() {

    gameState.isPaused = false;

    document.getElementById('pause-modal')?.classList.add('hidden');

}


function triggerGameOver() {

    gameState.inGame = false;

    playSound('hit');


    if (gameState.distance > gameState.highscore) {

        gameState.highscore = Math.floor(gameState.distance);

    }


    document.getElementById('go-distance').innerText = Math.floor(gameState.distance) + ' m';

    document.getElementById('go-bananas').innerText = '๐ŸŒ +' + gameState.score;

    document.getElementById('go-highscore').innerText = gameState.highscore + ' m';

   

Download

Download
Gemini(use canvas to make, modified versions of minion rush 3d remake)
External
Download
Minion RUSH GAMES
External

Install instructions

1 copy the modding code

2. Go to Gemini(once you are at Gemini use canvas to make your own version

Leave a comment

Log in with itch.io to leave a comment.