Sploop Lunar Client

Enhanced Sploop.io client with legal mod

// ==UserScript==
// @name         Sploop Lunar Client
// @namespace    http://tampermonkey.net/
// @version      3
// @description  Enhanced Sploop.io client with legal mod
// @author       hooder
// @match        https://sploop.io/*
// @grant        none
// @require      https://update.greasyfork.org/scripts/130/10066/Portable%20MD5%20Function.js
// ==/UserScript==

(function() {
    'use strict';

    function addStyle(css) {
        const style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);
        return style;
    }

    function makeDraggable(element) {
        let posX = 0, posY = 0, mouseX = 0, mouseY = 0;
        element.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            if (!isDragging) return;
            e.preventDefault();
            mouseX = e.clientX;
            mouseY = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e.preventDefault();
            posX = mouseX - e.clientX;
            posY = mouseY - e.clientY;
            mouseX = e.clientX;
            mouseY = e.clientY;
            const newTop = element.offsetTop - posY;
            const newLeft = element.offsetLeft - posX;
            element.style.top = Math.max(0, Math.min(newTop, window.innerHeight - element.offsetHeight)) + "px";
            element.style.left = Math.max(0, Math.min(newLeft, window.innerWidth - element.offsetWidth)) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    let isDragging = false;
    let menuVisible = true;
    let currentTheme = 'purple';
    let pulseSpeed = 1.5;
    let spinSpeed = 3.1; // Default spin speed for Spinning Spikes

    addStyle(`
        .lunar-menu {
            position: fixed;
            top: 50px;
            left: 50px;
            width: 480px;
            height: 500px;
            background: linear-gradient(135deg, #4b0082, #1a1a1a);
            border: 2px solid #9400d3;
            border-radius: 15px;
            color: white;
            font-family: Arial, sans-serif;
            z-index: 10000;
            padding: 15px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
            overflow-y: auto;
            display: flex;
            flex-direction: column;
        }
        .lunar-menu h2 {
            margin: 0 0 10px 0;
            text-align: center;
            color: #d8bfd8;
            cursor: move;
            font-size: 24px;
        }
        .tab-buttons {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin-bottom: 15px;
        }
        .tab-button {
            background: #9400d3;
            border: none;
            padding: 8px 20px;
            color: white;
            cursor: pointer;
            border-radius: 8px;
            transition: all 0.3s;
        }
        .tab-button:hover {
            background: #d8bfd8;
            color: #1a1a1a;
        }
        .tab-content {
            display: none;
            flex-grow: 1;
        }
        .tab-content.active {
            display: block;
        }
        .mod-toggle {
            margin: 10px 0;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 5px 10px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 5px;
        }
        .move-mods-btn {
            background: #9400d3;
            border: none;
            padding: 10px 20px;
            color: white;
            cursor: pointer;
            border-radius: 8px;
            margin-top: 15px;
            width: 150px;
            align-self: center;
            transition: all 0.3s;
        }
        .move-mods-btn:hover {
            background: #d8bfd8;
            color: #1a1a1a;
        }
        .mod-ui {
            position: fixed;
            padding: 10px;
            color: white;
            z-index: 1000;
            display: none;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            background: rgba(0, 0, 0, 0.8);
        }
        .keystrokes-ui, .pulse-effect-ui {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        .keystrokes-ui div {
            display: flex;
            justify-content: center;
            gap: 5px;
        }
        .keystroke-key {
            width: 40px;
            height: 40px;
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid #fff;
            border-radius: 5px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.1s;
        }
        .keystroke-key.active {
            background: rgba(255, 255, 255, 0.8);
            color: #000;
        }
        .arraylist-container {
            width: auto;
            max-width: 200px;
            background: rgba(0, 0, 0, 0.7);
            border-radius: 5px;
            padding: 5px;
        }
        .arraylist-item {
            padding: 3px 8px;
            background: rgba(255, 255, 255, 0.1);
            margin: 2px 0;
            border-radius: 3px;
            transition: all 0.2s;
        }
        .arraylist-item:hover {
            background: rgba(255, 255, 255, 0.2);
        }
        .player-list {
            position: fixed;
            top: 10%;
            left: 10%;
            width: 300px;
            max-height: 80%;
            background: linear-gradient(135deg, #4b0082, #1a1a1a);
            border: 2px solid #9400d3;
            border-radius: 15px;
            padding: 15px;
            color: white;
            font-family: Arial, sans-serif;
            overflow-y: auto;
            z-index: 9999;
            display: none;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
        }
        .player-list::-webkit-scrollbar {
            width: 8px;
        }
        .player-list::-webkit-scrollbar-thumb {
            background: #9400d3;
            border-radius: 4px;
        }
        .player-name {
            margin: 5px 0;
            font-size: 16px;
            opacity: 0;
            transition: opacity 0.5s;
        }
        .join-notification {
            position: fixed;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 8px 16px;
            border-radius: 8px;
            font-size: 14px;
            opacity: 0;
            transition: opacity 0.5s, top 0.3s;
            z-index: 10001;
        }
        .theme-buttons-container {
            position: fixed;
            top: 10%;
            left: 5%;
            display: none;
            flex-direction: column;
            gap: 10px;
        }
        .theme-button {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            cursor: pointer;
            border: 2px solid #9400d3;
            transition: transform 0.3s;
        }
        .theme-button:hover {
            transform: scale(1.1);
        }
        .pink-button { background: linear-gradient(135deg, #FFC6D9, #FF9494); }
        .light-orange-button { background: linear-gradient(135deg, #FFD699, #FFB74D); }
        .skye-blue-button { background: linear-gradient(135deg, #A6DAFF, #77BDFE); }
        .green-button { background: linear-gradient(135deg, #7CCD7C, #3F7A3F); }
        .account-switcher {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 850px;
            height: 550px;
            background: linear-gradient(135deg, #4b0082, #1a1a1a);
            border: 2px solid #9400d3;
            border-radius: 15px;
            color: white;
            font-family: Arial, sans-serif;
            z-index: 10002;
            padding: 15px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
            display: none;
            flex-direction: column;
        }
        .account-switcher h3 {
            margin: 0 0 10px 0;
            text-align: center;
            color: #d8bfd8;
            font-size: 20px;
            position: relative;
        }
        .account-list {
            overflow-y: auto;
            flex-grow: 1;
            margin-top: 10px;
        }
        .account-card {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 10px;
            margin: 5px 0;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 5px;
        }
        .account-buttons {
            display: flex;
            gap: 10px;
        }
        .acc-btn {
            padding: 5px 15px;
            border: none;
            border-radius: 5px;
            color: white;
            cursor: pointer;
            transition: all 0.3s;
        }
        .acc-btn-switch {
            background: #9400d3;
        }
        .acc-btn-switch:hover {
            background: #d8bfd8;
            color: #1a1a1a;
        }
        .acc-btn-remove {
            background: #ff4040;
        }
        .acc-btn-remove:hover {
            background: #ff6666;
        }
        .add-acc-btn {
            background: #9400d3;
            margin-top: 10px;
            align-self: center;
        }
        .add-acc-btn:hover {
            background: #d8bfd8;
            color: #1a1a1a;
        }
        .close-btn {
            position: absolute;
            top: 5px;
            right: 5px;
            width: 20px;
            height: 20px;
            background: #ff4040;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.3s;
        }
        .close-btn:hover {
            background: #ff6666;
        }
        @keyframes screenPulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }
    `);

    const themes = {
        purple: { background: `linear-gradient(135deg, #4b0082, #1a1a1a)`, border: `#9400d3`, button: `#9400d3` },
        blue: { background: `linear-gradient(135deg, #00008b, #1a1a1a)`, border: `#00b7eb`, button: `#00b7eb` },
        red: { background: `linear-gradient(135deg, #8b0000, #1a1a1a)`, border: `#ff4040`, button: `#ff4040` },
        green: { background: `linear-gradient(135deg, #006400, #1a1a1a)`, border: `#00ff00`, button: `#00ff00` },
        orange: { background: `linear-gradient(135deg, #ff4500, #1a1a1a)`, border: `#ffa500`, button: `#ffa500` },
        cyan: { background: `linear-gradient(135deg, #008b8b, #1a1a1a)`, border: `#00ffff`, button: `#00ffff` },
        pink: { background: `linear-gradient(135deg, #ff1493, #1a1a1a)`, border: `#ff69b4`, button: `#ff69b4` },
        yellow: { background: `linear-gradient(135deg, #ffd700, #1a1a1a)`, border: `#ffff00`, button: `#ffff00` },
        neon: { background: `linear-gradient(135deg, #00ffcc, #1a1a1a)`, border: `#39ff14`, button: `#39ff14` }
    };

    function applyTheme(element, theme) {
        element.style.background = themes[theme].background;
        element.style.border = `2px solid ${themes[theme].border}`;
        if (element.className.includes('tab-button') || element.className.includes('move-mods-btn') || element.className.includes('acc-btn')) {
            element.style.background = themes[theme].button;
        }
    }

    const menu = document.createElement('div');
    menu.className = 'lunar-menu';
    menu.innerHTML = `
        <h2>Sploop Lunar Client</h2>
        <div class="tab-buttons">
            <button class="tab-button" data-tab="visual">Visual</button>
            <button class="tab-button" data-tab="utility">Utility</button>
            <button class="tab-button" data-tab="combat">Combat</button>
            <button class="tab-button" data-tab="players">Players</button>
        </div>
        <div id="visual-tab" class="tab-content">
            <div class="mod-toggle"><input type="checkbox" id="menuThemeMod"> Menu Theme</div>
            <div class="mod-toggle"><input type="checkbox" id="arrayListMod"> ArrayList</div>
            <div class="mod-toggle"><input type="checkbox" id="zoomMod"> Zoom</div>
            <div class="mod-toggle"><input type="checkbox" id="nightVisionMod"> Night Vision</div>
            <div class="mod-toggle"><input type="checkbox" id="spinningSpikesMod"> Spike Spin Mod</div>
            <div class="mod-toggle"><input type="checkbox" id="pulseEffectMod"> Pulse Effect</div>
        </div>
        <div id="utility-tab" class="tab-content">
            <div class="mod-toggle"><input type="checkbox" id="fpsMod"> FPS</div>
            <div class="mod-toggle"><input type="checkbox" id="cpsMod"> CPS</div>
            <div class="mod-toggle"><input type="checkbox" id="fpsBoosterMod"> FPS Booster</div>
            <div class="mod-toggle"><input type="checkbox" id="pingMod"> Ping</div>
            <div class="mod-toggle"><input type="checkbox" id="keystrokesMod"> Keystrokes</div>
            <div class="mod-toggle"><input type="checkbox" id="coordinatesMod"> Coordinates</div>
            <div class="mod-toggle"><input type="checkbox" id="timerMod"> Timer</div>
        </div>
        <div id="combat-tab" class="tab-content">
            <div class="mod-toggle"><input type="checkbox" id="hitMarkersMod"> Hit Markers</div>
            <div class="mod-toggle"><input type="checkbox" id="rangeIndicatorMod"> Range Indicator</div>
            <div class="mod-toggle"><input type="checkbox" id="smoothCrosshairMod"> Smooth Crosshair</div>
            <div class="mod-toggle"><input type="checkbox" id="swingAnimationMod"> Swing Animation</div>
        </div>
        <div id="players-tab" class="tab-content">
            <p>Toggle Player List with ; key</p>
            <p>Made by blubby, edited by hooder</p>
        </div>
        <button class="move-mods-btn">Move Mods</button>
    `;
    document.body.appendChild(menu);
    makeDraggable(menu);
    applyTheme(menu, currentTheme);

    const tabButtons = menu.querySelectorAll('.tab-button');
    const tabContents = menu.querySelectorAll('.tab-content');
    tabButtons.forEach(button => {
        button.addEventListener('click', () => {
            tabContents.forEach(content => content.classList.remove('active'));
            menu.querySelector(`#${button.dataset.tab}-tab`).classList.add('active');
        });
        applyTheme(button, currentTheme);
    });
    menu.querySelector('#visual-tab').classList.add('active');

    const moveModsBtn = menu.querySelector('.move-mods-btn');
    moveModsBtn.addEventListener('click', () => {
        isDragging = !isDragging;
        moveModsBtn.textContent = isDragging ? 'Stop Moving' : 'Move Mods';
    });
    applyTheme(moveModsBtn, currentTheme);

    document.addEventListener('keydown', (e) => {
        if (e.key === 'Shift' && e.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
            menuVisible = !menuVisible;
            menu.style.display = menuVisible ? 'flex' : 'none';
        }
    });

    const playerList = document.createElement('div');
    playerList.className = 'player-list';
    document.body.appendChild(playerList);
    const playerNames = new Set();

    function addPlayerName(name) {
        if (!playerNames.has(name)) {
            const playerNameElement = document.createElement('div');
            playerNameElement.textContent = name;
            playerNameElement.className = 'player-name';
            playerList.appendChild(playerNameElement);
            playerNames.add(name);
            setTimeout(() => playerNameElement.style.opacity = '1', 100);
            displayJoinNotification(name);
        }
    }

    function displayJoinNotification(name) {
        const notification = document.createElement('div');
        notification.textContent = `${name} has joined the server!`;
        notification.className = 'join-notification';
        document.body.appendChild(notification);
        const existingNotifications = document.querySelectorAll('.join-notification');
        const topPosition = 20 + existingNotifications.length * 50;
        notification.style.top = `${topPosition}px`;
        setTimeout(() => notification.style.opacity = '1', 100);
        setTimeout(() => {
            notification.style.opacity = '0';
            existingNotifications.forEach((n, i) => {
                n.style.transition = 'top 0.3s, opacity 0.5s';
                n.style.top = `${20 + i * 50}px`;
            });
            setTimeout(() => notification.remove(), 500);
        }, 3000);
    }

    WebSocket.prototype.realSend = WebSocket.prototype.send;
    WebSocket.prototype.send = function(data) {
        this.realSend(data);
        this.addEventListener('message', handleWebSocketMessages);
    };

    function handleWebSocketMessages(event) {
        try {
            const messageData = JSON.parse(event.data);
            if (messageData[0] === 33) {
                playerList.innerHTML = '';
                playerNames.clear();
                const players = messageData[3];
                if (players.length === 0) addPlayerName("Server Joined");
                else players.forEach(player => addPlayerName(player[1]));
            } else if (messageData[0] === 32 || messageData[0] === 35) {
                addPlayerName(messageData[2]);
            }
        } catch (error) {
            console.error('Error parsing WebSocket message:', error);
        }
    }

    let displayToggled = false;
    document.addEventListener('keydown', (e) => {
        if (e.key === ';') {
            displayToggled = !displayToggled;
            playerList.style.display = displayToggled ? 'block' : 'none';
            themeButtonsContainer.style.display = displayToggled ? 'flex' : 'none';
        }
    });

    const themeButtonsContainer = document.createElement('div');
    themeButtonsContainer.className = 'theme-buttons-container';
    const pinkButton = createThemeButton('pink-button', () => setTheme('#FFC6D9', '#FF9494', '#FF69B4'));
    const orangeButton = createThemeButton('light-orange-button', () => setTheme('#FFD699', '#FFB74D', '#FF9800'));
    const blueButton = createThemeButton('skye-blue-button', () => setTheme('#A6DAFF', '#77BDFE', '#4FC3F7'));
    const greenButton = createThemeButton('green-button', () => setTheme('#7CCD7C', '#3F7A3F', '#4CAF50'));
    themeButtonsContainer.append(pinkButton, orangeButton, blueButton, greenButton);
    document.body.appendChild(themeButtonsContainer);

    function createThemeButton(className, onClick) {
        const button = document.createElement('div');
        button.className = `theme-button ${className}`;
        button.onclick = onClick;
        return button;
    }

    function setTheme(start, end, border) {
        playerList.style.background = `linear-gradient(135deg, ${start}, ${end})`;
        playerList.style.borderColor = border;
        playerList.querySelectorAll('.player-name').forEach(name => name.style.color = '#ffffff');
    }

    const accountSwitcher = document.createElement('div');
    accountSwitcher.className = 'account-switcher';
    accountSwitcher.innerHTML = `
        <h3>Account Switcher - Made by blubby, edited by hooder
            <div class="close-btn" id="close-account-switcher">X</div>
        </h3>
        <div class="account-list" id="account-list"></div>
        <button class="acc-btn add-acc-btn">Add Account</button>
    `;
    document.body.appendChild(accountSwitcher);
    applyTheme(accountSwitcher, currentTheme);

    const accountList = accountSwitcher.querySelector('#account-list');
    const addAccBtn = accountSwitcher.querySelector('.add-acc-btn');
    const closeBtn = accountSwitcher.querySelector('#close-account-switcher');
    applyTheme(addAccBtn, currentTheme);
    closeBtn.addEventListener('click', () => {
        accountSwitcher.style.display = 'none';
    });

    const emailInput = document.getElementById('enter-mail');
    const passInput = document.getElementById('enter-password');
    const loginBtn = document.getElementById('login');
    const logoutBtn = document.getElementById('logout');

    let userpass = [];
    function createAccountCard(data) {
        const card = document.createElement('div');
        card.className = 'account-card';
        card.id = data.randomString;
        card.innerHTML = `
            <span>${data.name} (Score: ${data.score})</span>
            <div class="account-buttons">
                <button class="acc-btn acc-btn-switch">Switch</button>
                <button class="acc-btn acc-btn-remove">Remove</button>
            </div>
        `;
        const switchBtn = card.querySelector('.acc-btn-switch');
        const removeBtn = card.querySelector('.acc-btn-remove');
        applyTheme(switchBtn, currentTheme);
        applyTheme(removeBtn, currentTheme);
        switchBtn.addEventListener('click', () => {
            logoutBtn.click();
            emailInput.value = data.email;
            passInput.value = data.password;
            loginBtn.click();
            accountSwitcher.style.display = 'none';
        });
        removeBtn.addEventListener('click', () => {
            const storedData = JSON.parse(localStorage.getItem('cards') || '[]');
            const index = storedData.findIndex(item => item.randomString === data.randomString);
            storedData.splice(index, 1);
            localStorage.setItem('cards', JSON.stringify(storedData));
            card.remove();
        });
        return card;
    }

    function displayAccounts() {
        accountList.innerHTML = '';
        const storedData = JSON.parse(localStorage.getItem('cards') || '[]');
        storedData.forEach(data => accountList.appendChild(createAccountCard(data)));
    }

    addAccBtn.addEventListener('click', () => {
        const email = prompt('Enter email:');
        const password = prompt('Enter password:');
        if (email && password) {
            fetch(`https://account.sploop.io:443/login?mail=${email}&hash=${hex_md5(password)}`)
                .then(response => response.json())
                .then(json => {
                    const storedData = JSON.parse(localStorage.getItem('cards') || '[]');
                    const randomString = Math.random().toString(36).substring(2, 12);
                    const newData = { name: json.nickname, email, password, score: json.score, randomString };
                    storedData.push(newData);
                    localStorage.setItem('cards', JSON.stringify(storedData));
                    accountList.appendChild(createAccountCard(newData));
                })
                .catch(() => alert('Invalid Account'));
        }
    });

    const switchBtn = document.createElement('div');
    switchBtn.className = 'acc-btn acc-btn-switch';
    switchBtn.textContent = 'Switch Accounts';
    switchBtn.style.position = 'fixed';
    switchBtn.style.top = '40px';
    switchBtn.style.left = '50%';
    switchBtn.style.transform = 'translateX(-50%)';
    document.body.appendChild(switchBtn);
    applyTheme(switchBtn, currentTheme);
    switchBtn.addEventListener('click', () => {
        accountSwitcher.style.display = 'block';
        displayAccounts();
    });

    const logo = document.createElement('div');
    logo.style = `
        position: fixed;
        top: 10px;
        left: 50%;
        transform: translateX(-50%);
        color: #d8bfd8;
        font-family: Arial, sans-serif;
        font-size: 20px;
        z-index: 1000;
        cursor: move;
    `;
    logo.textContent = 'Lunar Client';
    document.body.appendChild(logo);
    makeDraggable(logo);

    // Spinning Spikes Mod with Adjustable Speed
    const spinningSpikesUI = document.createElement('div');
    spinningSpikesUI.className = 'mod-ui';
    spinningSpikesUI.style.top = '10px';
    spinningSpikesUI.style.left = '150px';
    spinningSpikesUI.innerHTML = `
        <label>Spin Speed:</label>
        <input type="range" id="spinSpeedSlider" min="0.5" max="10" step="0.1" value="${spinSpeed}">
    `;
    document.body.appendChild(spinningSpikesUI);
    makeDraggable(spinningSpikesUI);
    applyTheme(spinningSpikesUI, currentTheme);

    const spinSpeedSlider = spinningSpikesUI.querySelector('#spinSpeedSlider');
    spinSpeedSlider.addEventListener('input', (e) => {
        spinSpeed = parseFloat(e.target.value);
    });

    function initSpinningSpikes() {
        const gameCanvas = document.getElementById('game-canvas');
        if (!gameCanvas) {
            console.log('Waiting for game canvas...');
            setTimeout(initSpinningSpikes, 500);
            return;
        }

        const ctx2D = gameCanvas.getContext('2d');
        const ctxWebGL = gameCanvas.getContext('webgl') || gameCanvas.getContext('experimental-webgl');
        console.log('Canvas context - 2D:', !!ctx2D, 'WebGL:', !!ctxWebGL);

        if (!ctx2D && ctxWebGL) {
            console.log('WebGL detected; 2D spinning spikes mod may not work. Attempting overlay fallback.');
            initOverlayFallback(gameCanvas);
            return;
        }

        if (!ctx2D) {
            console.log('No rendering context found; spikes mod cannot initialize.');
            return;
        }

        console.log('Spinning Spikes initialized on canvas (2D):', gameCanvas.id);

        const spikeUrls = new Set([
            "https://sploop.io/img/entity/spike.png?v=1923912",
            "https://sploop.io/img/entity/hard_spike.png?v=1923912",
            "https://sploop.io/img/entity/big_spike.png?v=1923912"
        ]);

        const spikeUpdate = (ctx, img, x, y, width, height, rotation) => {
            ctx.save();
            ctx.translate(x + width / 2, y + height / 2);
            ctx.rotate(rotation);
            ogdraw.call(ctx, img, -width / 2, -height / 2, width, height);
            ctx.restore();
        };

        const ogdraw = CanvasRenderingContext2D.prototype.drawImage;
        CanvasRenderingContext2D.prototype.drawImage = function(img, ...args) {
            const isSpinningEnabled = document.getElementById('spinningSpikesMod')?.checked || false;
            if (this.canvas && this.canvas.id === "game-canvas" && img instanceof HTMLImageElement && spikeUrls.has(img.src) && isSpinningEnabled) {
                console.log('Spike detected:', img.src, 'Args:', args);
                let x, y, width, height;
                if (args.length === 2) {
                    [x, y] = args;
                    width = img.width;
                    height = img.height;
                } else if (args.length === 4) {
                    [x, y, width, height] = args;
                } else if (args.length === 8) {
                    [, , , , x, y, width, height] = args;
                } else {
                    console.log('Unsupported drawImage call:', args);
                    return ogdraw.apply(this, [img, ...args]);
                }
                this.globalAlpha = 0;
                ogdraw.apply(this, [img, ...args]);
                this.globalAlpha = 1;
                const rotation = (performance.now() / 1000 * spinSpeed) % (2 * Math.PI);
                spikeUpdate(this, img, x, y, width, height, rotation);
            } else {
                return ogdraw.apply(this, [img, ...args]);
            }
        };
    }

    function initOverlayFallback(canvas) {
        console.log('Overlay fallback not implemented yet; spikes will not spin.');
    }

    setTimeout(() => {
        initSpinningSpikes();
        console.log('Spike Spin Mod initialization attempted');
    }, 4000);

    const pulseEffectUI = document.createElement('div');
    pulseEffectUI.className = 'mod-ui pulse-effect-ui';
    pulseEffectUI.style.top = '60px';
    pulseEffectUI.style.left = '150px';
    pulseEffectUI.innerHTML = `
        <label>Pulse Speed (seconds): </label>
        <input type="range" id="pulseSpeedSlider" min="0.5" max="3" step="0.1" value="${pulseSpeed}">
    `;
    document.body.appendChild(pulseEffectUI);
    makeDraggable(pulseEffectUI);
    applyTheme(pulseEffectUI, currentTheme);

    const pulseSpeedSlider = pulseEffectUI.querySelector('#pulseSpeedSlider');
    pulseSpeedSlider.addEventListener('input', (e) => {
        pulseSpeed = parseFloat(e.target.value);
        updateCanvasEffects();
    });

    function updateCanvasEffects() {
        const canvas = document.getElementById('game-canvas');
        if (!canvas) return;

        const zoomLevel = document.getElementById('zoomLevel')?.value || 1;
        canvas.style.transform = `scale(${zoomLevel})`;
        canvas.style.transformOrigin = 'center center';

        const isPulseEnabled = document.getElementById('pulseEffectMod')?.checked;
        canvas.style.animation = isPulseEnabled ? `screenPulse ${pulseSpeed}s infinite ease-in-out` : 'none';

        const isFpsBoostEnabled = document.getElementById('fpsBoosterMod')?.checked;
        const isNightVisionEnabled = document.getElementById('nightVisionMod')?.checked;
        let filter = '';
        if (isNightVisionEnabled) filter += ' brightness(1.5)';
        canvas.style.filter = filter.trim();
    }

    const fpsUI = document.createElement('div');
    fpsUI.className = 'mod-ui';
    fpsUI.style.top = '60px';
    fpsUI.style.left = '10px';
    document.body.appendChild(fpsUI);
    makeDraggable(fpsUI);
    applyTheme(fpsUI, currentTheme);
    let lastTime = performance.now();
    function updateFPS() {
        const now = performance.now();
        const fps = Math.round(1000 / (now - lastTime));
        fpsUI.textContent = `FPS: ${fps}`;
        lastTime = now;
        requestAnimationFrame(updateFPS);
    }

    const cpsUI = document.createElement('div');
    cpsUI.className = 'mod-ui';
    cpsUI.style.top = '110px';
    cpsUI.style.left = '10px';
    document.body.appendChild(cpsUI);
    makeDraggable(cpsUI);
    applyTheme(cpsUI, currentTheme);
    let clickTimes = [];
    document.addEventListener('mousedown', () => clickTimes.push(Date.now()));
    setInterval(() => {
        const now = Date.now();
        clickTimes = clickTimes.filter(time => now - time < 1000);
        cpsUI.textContent = `CPS: ${clickTimes.length}`;
    }, 500);

    const fpsBoosterUI = document.createElement('div');
    fpsBoosterUI.className = 'mod-ui';
    fpsBoosterUI.style.top = '160px';
    fpsBoosterUI.style.left = '10px';
    document.body.appendChild(fpsBoosterUI);
    makeDraggable(fpsBoosterUI);
    applyTheme(fpsBoosterUI, currentTheme);
    function toggleFPSBooster(on) {
        const canvas = document.getElementById('game-canvas');
        if (on) {
            canvas.style.imageRendering = 'pixelated';
            document.body.style.background = '#000';
            fpsBoosterUI.textContent = 'FPS Booster: ON';
        } else {
            canvas.style.imageRendering = 'auto';
            document.body.style.background = '#1a1a1a';
            fpsBoosterUI.textContent = 'FPS Booster: OFF';
        }
        updateCanvasEffects();
    }

    const pingUI = document.createElement('div');
    pingUI.className = 'mod-ui';
    pingUI.style.top = '210px';
    pingUI.style.left = '10px';
    document.body.appendChild(pingUI);
    makeDraggable(pingUI);
    applyTheme(pingUI, currentTheme);
    function updatePing() {
        const start = performance.now();
        fetch('https://sploop.io/').then(() => {
            pingUI.textContent = `Ping: ${Math.round(performance.now() - start)}ms`;
        }).catch(() => pingUI.textContent = 'Ping: N/A');
    }

    const keystrokesUI = document.createElement('div');
    keystrokesUI.className = 'mod-ui keystrokes-ui';
    keystrokesUI.style.top = '260px';
    keystrokesUI.style.left = '10px';
    keystrokesUI.innerHTML = `
        <div><div class="keystroke-key" id="keyW">W</div></div>
        <div>
            <div class="keystroke-key" id="keyA">A</div>
            <div class="keystroke-key" id="keyS">S</div>
            <div class="keystroke-key" id="keyD">D</div>
        </div>
        <div><div class="keystroke-key" id="keySpace"> </div></div>
        <div>
            <div class="keystroke-key" id="keyLMB">LMB</div>
            <div class="keystroke-key" id="keyRMB">RMB</div>
        </div>
    `;
    document.body.appendChild(keystrokesUI);
    makeDraggable(keystrokesUI);
    applyTheme(keystrokesUI, currentTheme);
    const keyElements = {
        w: keystrokesUI.querySelector('#keyW'),
        a: keystrokesUI.querySelector('#keyA'),
        s: keystrokesUI.querySelector('#keyS'),
        d: keystrokesUI.querySelector('#keyD'),
        space: keystrokesUI.querySelector('#keySpace'),
        lmb: keystrokesUI.querySelector('#keyLMB'),
        rmb: keystrokesUI.querySelector('#keyRMB')
    };
    document.addEventListener('keydown', (e) => {
        if (!keystrokesMod.checked) return;
        switch (e.key.toLowerCase()) {
            case 'w': keyElements.w.classList.add('active'); break;
            case 'a': keyElements.a.classList.add('active'); break;
            case 's': keyElements.s.classList.add('active'); break;
            case 'd': keyElements.d.classList.add('active'); break;
            case ' ': keyElements.space.classList.add('active'); break;
        }
    });
    document.addEventListener('keyup', (e) => {
        if (!keystrokesMod.checked) return;
        switch (e.key.toLowerCase()) {
            case 'w': keyElements.w.classList.remove('active'); break;
            case 'a': keyElements.a.classList.remove('active'); break;
            case 's': keyElements.s.classList.remove('active'); break;
            case 'd': keyElements.d.classList.remove('active'); break;
            case ' ': keyElements.space.classList.remove('active'); break;
        }
    });
    document.addEventListener('mousedown', (e) => {
        if (!keystrokesMod.checked) return;
        if (e.button === 0) keyElements.lmb.classList.add('active');
        if (e.button === 2) keyElements.rmb.classList.add('active');
    });
    document.addEventListener('mouseup', (e) => {
        if (!keystrokesMod.checked) return;
        if (e.button === 0) keyElements.lmb.classList.remove('active');
        if (e.button === 2) keyElements.rmb.classList.remove('active');
    });

    const menuThemeUI = document.createElement('div');
    menuThemeUI.className = 'mod-ui';
    menuThemeUI.style.top = '10px';
    menuThemeUI.style.left = '150px';
    menuThemeUI.innerHTML = `
        <label>Menu Theme: </label>
        <select id="themeSelect">
            <option value="purple">Purple</option>
            <option value="blue">Blue</option>
            <option value="red">Red</option>
            <option value="green">Green</option>
            <option value="orange">Orange</option>
            <option value="cyan">Cyan</option>
            <option value="pink">Pink</option>
            <option value="yellow">Yellow</option>
            <option value="neon">Neon</option>
        </select>
    `;
    document.body.appendChild(menuThemeUI);
    makeDraggable(menuThemeUI);
    applyTheme(menuThemeUI, currentTheme);

    const themeSelectMenu = menuThemeUI.querySelector('#themeSelect');
    themeSelectMenu.addEventListener('change', (e) => {
        currentTheme = e.target.value;
        applyTheme(menu, currentTheme);
        tabButtons.forEach(btn => applyTheme(btn, currentTheme));
        applyTheme(moveModsBtn, currentTheme);
        applyTheme(fpsUI, currentTheme);
        applyTheme(cpsUI, currentTheme);
        applyTheme(menuThemeUI, currentTheme);
        applyTheme(arrayListUI, currentTheme);
        applyTheme(hitMarkersUI, currentTheme);
        applyTheme(rangeIndicatorUI, currentTheme);
        applyTheme(smoothCrosshairUI, currentTheme);
        applyTheme(fpsBoosterUI, currentTheme);
        applyTheme(swingAnimationUI, currentTheme);
        applyTheme(pingUI, currentTheme);
        applyTheme(keystrokesUI, currentTheme);
        applyTheme(zoomUI, currentTheme);
        applyTheme(nightVisionUI, currentTheme);
        applyTheme(coordinatesUI, currentTheme);
        applyTheme(timerUI, currentTheme);
        applyTheme(playerList, currentTheme);
        applyTheme(accountSwitcher, currentTheme);
        applyTheme(addAccBtn, currentTheme);
        applyTheme(switchBtn, currentTheme);
        applyTheme(pulseEffectUI, currentTheme);
        applyTheme(spinningSpikesUI, currentTheme);
        accountList.querySelectorAll('.acc-btn').forEach(btn => applyTheme(btn, currentTheme));
    });

    const arrayListUI = document.createElement('div');
    arrayListUI.className = 'mod-ui arraylist-container';
    arrayListUI.style.top = '10px';
    arrayListUI.style.right = '10px';
    document.body.appendChild(arrayListUI);
    makeDraggable(arrayListUI);
    applyTheme(arrayListUI, currentTheme);

    function updateArrayList() {
        const activeMods = [];
        if (fpsMod.checked) activeMods.push('FPS');
        if (cpsMod.checked) activeMods.push('CPS');
        if (menuThemeMod.checked) activeMods.push('Menu Theme');
        if (arrayListMod.checked) activeMods.push('ArrayList');
        if (hitMarkersMod.checked) activeMods.push('Hit Markers');
        if (rangeIndicatorMod.checked) activeMods.push('Range Indicator');
        if (smoothCrosshairMod.checked) activeMods.push('Smooth Crosshair');
        if (fpsBoosterMod.checked) activeMods.push('FPS Booster');
        if (swingAnimationMod.checked) activeMods.push('Swing Animation');
        if (pingMod.checked) activeMods.push('Ping');
        if (keystrokesMod.checked) activeMods.push('Keystrokes');
        if (zoomMod.checked) activeMods.push('Zoom');
        if (nightVisionMod.checked) activeMods.push('Night Vision');
        if (coordinatesMod.checked) activeMods.push('Coordinates');
        if (timerMod.checked) activeMods.push('Timer');
        if (spinningSpikesMod.checked) activeMods.push('Spike Spin Mod');
        if (pulseEffectMod.checked) activeMods.push('Pulse Effect');
        activeMods.sort();
        arrayListUI.innerHTML = activeMods.map(mod => `<div class="arraylist-item">${mod}</div>`).join('');
    }

    const hitMarkersUI = document.createElement('div');
    hitMarkersUI.className = 'mod-ui';
    hitMarkersUI.style.top = '360px';
    hitMarkersUI.style.left = '10px';
    document.body.appendChild(hitMarkersUI);
    makeDraggable(hitMarkersUI);
    applyTheme(hitMarkersUI, currentTheme);
    document.addEventListener('mousedown', (e) => {
        if (!hitMarkersMod.checked || e.button !== 0) return;
        const marker = document.createElement('div');
        marker.style = `
            position: fixed;
            top: ${e.clientY - 5}px;
            left: ${e.clientX - 5}px;
            width: 10px;
            height: 10px;
            background: transparent;
            border: 2px solid #ff0000;
            border-radius: 0;
            transform: rotate(45deg);
            z-index: 1000;
            animation: hitFade 0.5s ease-out forwards;
            pointer-events: none;
        `;
        document.body.appendChild(marker);
        setTimeout(() => marker.remove(), 500);
    });
    addStyle(`
        @keyframes hitFade {
            0% { opacity: 1; transform: rotate(45deg) scale(1); }
            100% { opacity: 0; transform: rotate(45deg) scale(1.2); }
        }
    `);

    const rangeIndicatorUI = document.createElement('div');
    rangeIndicatorUI.className = 'mod-ui';
    rangeIndicatorUI.style.top = '410px';
    rangeIndicatorUI.style.left = '10px';
    rangeIndicatorUI.innerHTML = `
        <label>Range: </label>
        <input type="range" id="rangeSize" min="50" max="200" value="100">
    `;
    document.body.appendChild(rangeIndicatorUI);
    makeDraggable(rangeIndicatorUI);
    applyTheme(rangeIndicatorUI, currentTheme);
    const rangeCircle = document.createElement('div');
    rangeCircle.style = `
        position: fixed;
        border: 2px solid #ff0000;
        border-radius: 50%;
        z-index: 999;
        pointer-events: none;
        display: none;
    `;
    document.body.appendChild(rangeCircle);
    document.addEventListener('mousemove', (e) => {
        if (!rangeIndicatorMod.checked) return;
        const size = rangeIndicatorUI.querySelector('#rangeSize').value;
        rangeCircle.style.width = `${size}px`;
        rangeCircle.style.height = `${size}px`;
        rangeCircle.style.top = `${e.clientY - size / 2}px`;
        rangeCircle.style.left = `${e.clientX - size / 2}px`;
        rangeCircle.style.display = 'block';
    });

    const smoothCrosshairUI = document.createElement('div');
    smoothCrosshairUI.className = 'mod-ui';
    smoothCrosshairUI.style.top = '460px';
    smoothCrosshairUI.style.left = '10px';
    document.body.appendChild(smoothCrosshairUI);
    makeDraggable(smoothCrosshairUI);
    applyTheme(smoothCrosshairUI, currentTheme);
    const crosshair = document.createElement('div');
    crosshair.style = `
        position: fixed;
        width: 20px;
        height: 20px;
        background: transparent;
        border: 2px solid #fff;
        border-radius: 50%;
        z-index: 1000;
        pointer-events: none;
        display: none;
    `;
    document.body.appendChild(crosshair);
    document.addEventListener('mousemove', (e) => {
        if (!smoothCrosshairMod.checked) return;
        crosshair.style.top = `${e.clientY - 10}px`;
        crosshair.style.left = `${e.clientX - 10}px`;
        crosshair.style.display = 'block';
    });

    const swingAnimationUI = document.createElement('div');
    swingAnimationUI.className = 'mod-ui';
    swingAnimationUI.style.top = '510px';
    swingAnimationUI.style.left = '10px';
    document.body.appendChild(swingAnimationUI);
    makeDraggable(swingAnimationUI);
    applyTheme(swingAnimationUI, currentTheme);
    document.addEventListener('mousedown', (e) => {
        if (!swingAnimationMod.checked || e.button !== 0) return;
        const swing = document.createElement('div');
        swing.style = `
            position: fixed;
            top: ${e.clientY - 30}px;
            left: ${e.clientX - 30}px;
            width: 60px;
            height: 60px;
            background: rgba(0, 0, 255, 0.3);
            border: none;
            border-radius: 50%;
            z-index: 1000;
            animation: swingFade 0.7s ease-out forwards;
            pointer-events: none;
        `;
        document.body.appendChild(swing);
        setTimeout(() => swing.remove(), 700);
    });
    addStyle(`
        @keyframes swingFade {
            0% { opacity: 1; transform: scale(1); }
            100% { opacity: 0; transform: scale(2); }
        }
    `);

    const zoomUI = document.createElement('div');
    zoomUI.className = 'mod-ui';
    zoomUI.style.top = '110px';
    zoomUI.style.left = '150px';
    zoomUI.innerHTML = `
        <label>Zoom: </label>
        <input type="range" id="zoomLevel" min="0.5" max="2" step="0.1" value="1">
    `;
    document.body.appendChild(zoomUI);
    makeDraggable(zoomUI);
    applyTheme(zoomUI, currentTheme);
    const zoomLevel = zoomUI.querySelector('#zoomLevel');
    zoomLevel.addEventListener('input', () => updateCanvasEffects());

    const nightVisionUI = document.createElement('div');
    nightVisionUI.className = 'mod-ui';
    nightVisionUI.style.top = '160px';
    nightVisionUI.style.left = '150px';
    nightVisionUI.textContent = 'Night Vision: OFF';
    document.body.appendChild(nightVisionUI);
    makeDraggable(nightVisionUI);
    applyTheme(nightVisionUI, currentTheme);
    function toggleNightVision(on) {
        nightVisionUI.textContent = `Night Vision: ${on ? 'ON' : 'OFF'}`;
        updateCanvasEffects();
    }

    let playerPos = { x: 0, y: 0 };

    const coordinatesUI = document.createElement('div');
    coordinatesUI.className = 'mod-ui';
    coordinatesUI.style.top = '310px';
    coordinatesUI.style.left = '10px';
    coordinatesUI.textContent = 'X: 0, Y: 0';
    document.body.appendChild(coordinatesUI);
    makeDraggable(coordinatesUI);
    applyTheme(coordinatesUI, currentTheme);
    function updateCoordinates() {
        if (!coordinatesMod.checked) return;
        coordinatesUI.textContent = `X: ${Math.round(playerPos.x)}, Y: ${Math.round(playerPos.y)}`;
    }
    setInterval(updateCoordinates, 100);

    const timerUI = document.createElement('div');
    timerUI.className = 'mod-ui';
    timerUI.style.top = '360px';
    timerUI.style.left = '10px';
    timerUI.textContent = 'Time: 00:00';
    document.body.appendChild(timerUI);
    makeDraggable(timerUI);
    applyTheme(timerUI, currentTheme);
    let startTime = Date.now();
    function updateTimer() {
        if (!timerMod.checked) return;
        const elapsed = Math.floor((Date.now() - startTime) / 1000);
        const minutes = String(Math.floor(elapsed / 60)).padStart(2, '0');
        const seconds = String(elapsed % 60).padStart(2, '0');
        timerUI.textContent = `Time: ${minutes}:${seconds}`;
    }
    setInterval(updateTimer, 1000);

    const fpsMod = menu.querySelector('#fpsMod');
    const cpsMod = menu.querySelector('#cpsMod');
    const menuThemeMod = menu.querySelector('#menuThemeMod');
    const arrayListMod = menu.querySelector('#arrayListMod');
    const hitMarkersMod = menu.querySelector('#hitMarkersMod');
    const rangeIndicatorMod = menu.querySelector('#rangeIndicatorMod');
    const smoothCrosshairMod = menu.querySelector('#smoothCrosshairMod');
    const fpsBoosterMod = menu.querySelector('#fpsBoosterMod');
    const swingAnimationMod = menu.querySelector('#swingAnimationMod');
    const pingMod = menu.querySelector('#pingMod');
    const keystrokesMod = menu.querySelector('#keystrokesMod');
    const zoomMod = menu.querySelector('#zoomMod');
    const nightVisionMod = menu.querySelector('#nightVisionMod');
    const coordinatesMod = menu.querySelector('#coordinatesMod');
    const timerMod = menu.querySelector('#timerMod');
    const spinningSpikesMod = menu.querySelector('#spinningSpikesMod');
    const pulseEffectMod = menu.querySelector('#pulseEffectMod');

    const modUIs = {
        fps: fpsUI,
        cps: cpsUI,
        menuTheme: menuThemeUI,
        arrayList: arrayListUI,
        hitMarkers: hitMarkersUI,
        rangeIndicator: rangeIndicatorUI,
        smoothCrosshair: smoothCrosshairUI,
        fpsBooster: fpsBoosterUI,
        swingAnimation: swingAnimationUI,
        ping: pingUI,
        keystrokes: keystrokesUI,
        zoom: zoomUI,
        nightVision: nightVisionUI,
        coordinates: coordinatesUI,
        timer: timerUI,
        spinningSpikes: spinningSpikesUI,
        pulseEffect: pulseEffectUI
    };

    function initializeModUIs() {
        Object.keys(modUIs).forEach(mod => {
            const checkbox = menu.querySelector(`#${mod}Mod`);
            modUIs[mod].style.display = checkbox.checked ? 'block' : 'none';
            if (mod === 'rangeIndicator' && checkbox.checked) rangeCircle.style.display = 'block';
            if (mod === 'smoothCrosshair' && checkbox.checked) crosshair.style.display = 'block';
            if (mod === 'fps' && checkbox.checked) requestAnimationFrame(updateFPS);
            if (mod === 'ping' && checkbox.checked) setInterval(updatePing, 2000);
            if (mod === 'fpsBooster' && checkbox.checked) toggleFPSBooster(true);
            if (mod === 'nightVision' && checkbox.checked) toggleNightVision(true);
            if (mod === 'timer' && checkbox.checked) startTime = Date.now();
        });
        updateCanvasEffects();
        updateArrayList();
    }

    function forceCanvasRedraw() {
        const canvas = document.getElementById('game-canvas');
        if (canvas) {
            console.log('Forcing canvas redraw');
            canvas.style.opacity = '0.99';
            requestAnimationFrame(() => {
                canvas.style.opacity = '1';
            });
        }
    }

    fpsMod.addEventListener('change', () => {
        modUIs.fps.style.display = fpsMod.checked ? 'block' : 'none';
        if (fpsMod.checked) requestAnimationFrame(updateFPS);
        updateArrayList();
    });
    cpsMod.addEventListener('change', () => {
        modUIs.cps.style.display = cpsMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    menuThemeMod.addEventListener('change', () => {
        modUIs.menuTheme.style.display = menuThemeMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    arrayListMod.addEventListener('change', () => {
        modUIs.arrayList.style.display = arrayListMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    hitMarkersMod.addEventListener('change', () => {
        modUIs.hitMarkers.style.display = hitMarkersMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    rangeIndicatorMod.addEventListener('change', () => {
        modUIs.rangeIndicator.style.display = rangeIndicatorMod.checked ? 'block' : 'none';
        rangeCircle.style.display = rangeIndicatorMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    smoothCrosshairMod.addEventListener('change', () => {
        modUIs.smoothCrosshair.style.display = smoothCrosshairMod.checked ? 'block' : 'none';
        crosshair.style.display = smoothCrosshairMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    fpsBoosterMod.addEventListener('change', () => {
        modUIs.fpsBooster.style.display = fpsBoosterMod.checked ? 'block' : 'none';
        toggleFPSBooster(fpsBoosterMod.checked);
        updateArrayList();
    });
    swingAnimationMod.addEventListener('change', () => {
        modUIs.swingAnimation.style.display = swingAnimationMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    pingMod.addEventListener('change', () => {
        modUIs.ping.style.display = pingMod.checked ? 'block' : 'none';
        if (pingMod.checked) setInterval(updatePing, 2000);
        updateArrayList();
    });
    keystrokesMod.addEventListener('change', () => {
        modUIs.keystrokes.style.display = keystrokesMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    zoomMod.addEventListener('change', () => {
        modUIs.zoom.style.display = zoomMod.checked ? 'block' : 'none';
        if (!zoomMod.checked) zoomLevel.value = 1;
        updateCanvasEffects();
        updateArrayList();
    });
    nightVisionMod.addEventListener('change', () => {
        modUIs.nightVision.style.display = nightVisionMod.checked ? 'block' : 'none';
        toggleNightVision(nightVisionMod.checked);
        updateArrayList();
    });
    coordinatesMod.addEventListener('change', () => {
        modUIs.coordinates.style.display = coordinatesMod.checked ? 'block' : 'none';
        updateArrayList();
    });
    timerMod.addEventListener('change', () => {
        modUIs.timer.style.display = timerMod.checked ? 'block' : 'none';
        if (timerMod.checked) startTime = Date.now();
        updateArrayList();
    });
    spinningSpikesMod.addEventListener('change', () => {
        modUIs.spinningSpikes.style.display = spinningSpikesMod.checked ? 'block' : 'none';
        updateArrayList();
        forceCanvasRedraw();
    });
    pulseEffectMod.addEventListener('change', () => {
        modUIs.pulseEffect.style.display = pulseEffectMod.checked ? 'block' : 'none';
        updateCanvasEffects();
        updateArrayList();
    });

    initializeModUIs();
})();