<!DOCTYPE html>
<html>
<head>
    <title>Infinite Forest Game with Enhanced UI</title>
    <style>
        /* Remove default margin and hide overflow to prevent scrollbars /
        body { margin: 0; overflow: hidden; font-family: Arial, sans-serif; }

        / Make the canvas fill the screen /
        canvas { display: block; }

        / HP Bar Styles /
        #hpBarContainer {
            position: absolute;
            bottom: 20px;
            left: 20px;
            width: 200px;
            height: 20px;
            background-color: #333;
            border-radius: 10px;
            overflow: hidden;
        }
        #hpBar {
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, #76c7c0, #57a095);
            transition: width 0.3s ease;
        }

        / Interaction Menu Styles /
        #interactionMenu {
            position: absolute;
            bottom: 100px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(50, 50, 50, 0.9);
            padding: 10px 20px;
            border-radius: 5px;
            color: #fff;
            display: none;
            align-items: center;
        }
        #interactionMenu button {
            background-color: #76c7c0;
            border: none;
            padding: 10px 15px;
            margin: 0 10px; / Added margin /
            border-radius: 5px;
            color: #fff;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.2s ease;
        }
        #interactionMenu button:hover {
            background-color: #5aa9a3;
        }

        / Inventory UI Styles */
        #inventoryUI {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(30, 30, 30, 0.95);
            color: #fff;
            display: none;
            flex-direction: column;
            align-items: center;
            padding-top: 50px;
            box-sizing: border-box;
        }
        #inventoryUI h1 {
            margin-bottom: 20px;
        }
        #inventoryItems {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            max-width: 800px;
        }
        .inventoryItem {
            background-color: #444;
            width: 150px;
            height: 150px;
            margin: 10px;
            border-radius: 10px;
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
        }
        .inventoryItem span {
            margin-top: 10px;
            font-size: 16px;
        }
        #closeInventory {
            position: absolute;
            top: 20px;
            right: 20px;
            background-color: transparent;
            border: none;
            color: #fff;
            font-size: 30px;
            cursor: pointer;
            transition: transform 0.2s ease;
        }
        #closeInventory:hover {
            transform: scale(1.1);
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas"></canvas>

    <!-- HP Bar -->
    <div id="hpBarContainer">
        <div id="hpBar"></div>
    </div>

    <!-- Interaction Menu -->
    <div id="interactionMenu">
        <span>Press </span><button id="chopButton">E</button><span> to chop tree</span>
    </div>

    <!-- Inventory UI -->
    <div id="inventoryUI">
        <button id="closeInventory">×</button>
        <h1>Inventory</h1>
        <div id="inventoryItems"></div>
    </div>

    <script>
        // Get the canvas element and its drawing context
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');

        // UI Elements
        const hpBar = document.getElementById('hpBar');
        const interactionMenu = document.getElementById('interactionMenu');
        const chopButton = document.getElementById('chopButton');
        const inventoryUI = document.getElementById('inventoryUI');
        const inventoryItemsContainer = document.getElementById('inventoryItems');
        const closeInventoryButton = document.getElementById('closeInventory');

        // Set the canvas size to match the window size
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        // Player object
        const player = {
            x: 0,
            y: 0,
            size: 10,
            color: 'orange',
            speed: 4,
            prevX: 0,
            prevY: 0,
            hp: 100, // Player's health
            maxHp: 100,
            inventory: {}
        };

        // Camera object to handle scrolling
        const camera = {
            x: 0,
            y: 0,
            width: canvas.width,
            height: canvas.height
        };

        // Object to keep track of key presses
        const keys = {};

        // Event listeners for keyboard input
        window.addEventListener('keydown', function(e) {
            keys[e.key] = true;

            // Handle chopping with 'E' key
            if ((e.key === 'e' || e.key === 'E') && nearbyTree) {
                chopTree();
            }

            // Inventory Toggle
            if ((e.key === 'i' || e.key === 'I')) {
                keys['i'] = false; // Prevent continuous opening/closing
                keys['I'] = false;
                toggleInventory();
            }
        });

        window.addEventListener('keyup', function(e) {
            keys[e.key] = false;
        });

        // Chunks data structure to store generated chunks
        const chunkSize = 500; // Size of each chunk in pixels
        const chunks = {}; // Store chunks by "chunkX,chunkY" keys

        // Rain particles
        const rainParticles = [];
        const rainParticleCount = 200;

        // Initialize rain effect
        for (let i = 0; i < rainParticleCount; i++) {
            let speed = 2 + Math.random() * 3;
            rainParticles.push({
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height,
                vx: 0, // Will be updated based on player movement
                vy: speed,
                length: 10 + Math.random() * 10
            });
        }

        // Wet footprints trail
        const wetTrails = [];

        let showInventory = false;
        let nearbyTree = null;

        // Game loop function
        function gameLoop() {
            update();
            render();
            requestAnimationFrame(gameLoop);
        }

        // Start the game loop
        requestAnimationFrame(gameLoop);

        // Update function to handle game logic
        function update() {
            // Store player's previous position
            player.prevX = player.x;
            player.prevY = player.y;

            // Move player based on keyboard input
            let isMoving = false;
            if ((keys['ArrowUp'] || keys['w']) && !showInventory) {
                player.y -= player.speed;
                isMoving = true;
            }
            if ((keys['ArrowDown'] || keys['s']) && !showInventory) {
                player.y += player.speed;
                isMoving = true;
            }
            if ((keys['ArrowLeft'] || keys['a']) && !showInventory) {
                player.x -= player.speed;
                isMoving = true;
            }
            if ((keys['ArrowRight'] || keys['d']) && !showInventory) {
                player.x += player.speed;
                isMoving = true;
            }

            // Interaction with trees
            nearbyTree = null;
            for (let chunkKey in chunks) {
                let chunk = chunks[chunkKey];
                let trees = chunk.trees;
                for (let i = 0; i < trees.length; i++) {
                    let tree = trees[i];
                    let dx = tree.x - player.x;
                    let dy = tree.y - player.y;
                    let distance = Math.hypot(dx, dy);
                    if (distance < 50) { // Interaction range
                        nearbyTree = { tree: tree, chunk: chunk };
                        break;
                    }
                }
                if (nearbyTree) break;
            }

            if (nearbyTree) {
                interactionMenu.style.display = 'flex';
            } else {
                interactionMenu.style.display = 'none';
            }

            // Create wet trail when moving
            if (isMoving) {
                wetTrails.push({
                    x: player.x,
                    y: player.y,
                    opacity: 0.5, // Starting opacity
                    maxOpacity: 0.5,
                    size: 15 + Math.random() * 5, // Randomize size a bit
                });
            }

            // Update wet trails opacity
            for (let i = wetTrails.length - 1; i >= 0; i--) {
                const trail = wetTrails[i];
                trail.opacity -= 0.005; // Decrease opacity over time
                if (trail.opacity <= 0) {
                    wetTrails.splice(i, 1);
                }
            }

            // Calculate player's movement vector
            let dx = player.x - player.prevX;
            let dy = player.y - player.prevY;

            // Update camera position to center on player
            camera.x = player.x - camera.width / 2;
            camera.y = player.y - camera.height / 2;

            // Update rain wind direction based on player movement
            let maxWindSpeed = 2; // Max horizontal speed of the rain particles
            let rainWindX = -dx / player.speed * maxWindSpeed;

            // Update rain particles
            for (let i = 0; i < rainParticles.length; i++) {
                let p = rainParticles[i];
                p.vx = rainWindX;
                p.x += p.vx;
                p.y += p.vy;

                // Wrap particles around the screen
                if (p.y > canvas.height) {
                    p.y = -p.length;
                    p.x = Math.random() * canvas.width;
                }
                if (p.x > canvas.width) {
                    p.x = 0;
                } else if (p.x < 0) {
                    p.x = canvas.width;
                }
            }

            // Update HP bar
            updateHPBar();
        }

        // Render function to draw everything on the canvas
        function render() {
            // Clear the entire canvas
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // Save the current context state
            ctx.save();

            // Translate the context to the camera's position
            ctx.translate(-camera.x, -camera.y);

            // Calculate visible area
            const startX = camera.x - canvas.width / 2;
            const endX = camera.x + canvas.width * 1.5;
            const startY = camera.y - canvas.height / 2;
            const endY = camera.y + canvas.height * 1.5;

            // Calculate visible chunks
            const startChunkX = Math.floor(startX / chunkSize);
            const endChunkX = Math.floor(endX / chunkSize);
            const startChunkY = Math.floor(startY / chunkSize);
            const endChunkY = Math.floor(endY / chunkSize);

            // Draw all visible chunks
            for (let chunkX = startChunkX; chunkX <= endChunkX; chunkX++) {
                for (let chunkY = startChunkY; chunkY <= endChunkY; chunkY++) {
                    let chunkKey = chunkX + ',' + chunkY;
                    if (!chunks[chunkKey]) {
                        chunks[chunkKey] = generateChunk(chunkX, chunkY);
                    }
                    let chunk = chunks[chunkKey];
                    let trees = chunk.trees;
                    let puddles = chunk.puddles;

                    // Draw puddles
                    for (let i = 0; i < puddles.length; i++) {
                        const puddle = puddles[i];
                        drawPuddle(puddle);
                    }

                    // Draw trees
                    for (let i = 0; i < trees.length; i++) {
                        const tree = trees[i];
                        drawTree(tree);
                    }
                }
            }

            // Draw wet trails
            for (let i = 0; i < wetTrails.length; i++) {
                const trail = wetTrails[i];
                ctx.fillStyle = rgba(105, 105, 105, ${trail.opacity}); // DimGray color with opacity
                ctx.beginPath();
                ctx.ellipse(trail.x, trail.y, trail.size / 2, trail.size / 4, 0, 0, Math.PI * 2);
                ctx.fill();
            }

            // Draw the player
            ctx.fillStyle = player.color;
            ctx.beginPath();
            ctx.arc(player.x, player.y, player.size, 0, Math.PI * 2);
            ctx.fill();

            // Restore the context to its original state
            ctx.restore();

            // Draw rain effect over everything
            ctx.strokeStyle = 'rgba(174,194,224,0.5)'; // Light blue with transparency
            ctx.lineWidth = 1;
            for (let i = 0; i < rainParticles.length; i++) {
                let p = rainParticles[i];
                // Calculate the end position based on particle's velocity
                let t = p.length / p.vy;
                let deltaX = p.vx * t;
                ctx.beginPath();
                ctx.moveTo(p.x, p.y);
                ctx.lineTo(p.x - deltaX, p.y - p.length);
                ctx.stroke();
            }
        }

        // Function to update the HP bar
        function updateHPBar() {
            const hpPercentage = player.hp / player.maxHp;
            hpBar.style.width = (hpPercentage * 100) + '%';
        }

        // Function to toggle the inventory UI
        function toggleInventory() {
            showInventory = !showInventory;
            if (showInventory) {
                updateInventoryUI();
                inventoryUI.style.display = 'flex';
            } else {
                inventoryUI.style.display = 'none';
            }
        }

        // Function to update the inventory UI
        function updateInventoryUI() {
            // Clear current items
            inventoryItemsContainer.innerHTML = '';
            for (let itemName in player.inventory) {
                let itemCount = player.inventory[itemName];
                let itemDiv = document.createElement('div');
                itemDiv.classList.add('inventoryItem');

                // Item Name and Count
                let span = document.createElement('span');
                span.textContent = ${itemName} x${itemCount};
                itemDiv.appendChild(span);

                inventoryItemsContainer.appendChild(itemDiv);
            }
        }

        // Function to draw a tree with more detail
        function drawTree(tree) {
            // Draw tree trunk
            ctx.fillStyle = '#8B4513'; // SaddleBrown color for trunk
            ctx.fillRect(tree.x - tree.trunkWidth / 2,
                         tree.y,
                         tree.trunkWidth,
                         tree.trunkHeight);

            // Draw tree foliage as a canopy using a bezier curve
            ctx.fillStyle = tree.color;
            ctx.beginPath();
            ctx.moveTo(tree.x, tree.y - tree.foliageHeight);
            ctx.bezierCurveTo(tree.x - tree.foliageWidth / 2, tree.y - tree.foliageHeight / 2,
                              tree.x - tree.foliageWidth / 2, tree.y,
                              tree.x, tree.y);
            ctx.bezierCurveTo(tree.x + tree.foliageWidth / 2, tree.y,
                              tree.x + tree.foliageWidth / 2, tree.y - tree.foliageHeight / 2,
                              tree.x, tree.y - tree.foliageHeight);
            ctx.fill();
        }

        // Function to draw a puddle
        function drawPuddle(puddle) {
            ctx.fillStyle = 'rgba(30, 144, 255, 0.5)'; // DodgerBlue with transparency
            ctx.beginPath();
            ctx.ellipse(puddle.x, puddle.y, puddle.width / 2, puddle.height / 2, 0, 0, Math.PI * 2);
            ctx.fill();
        }

        // Function to generate a chunk at given chunk coordinates
        function generateChunk(chunkX, chunkY) {
            const trees = [];
            const puddles = [];
            const numTrees = 15; // Number of trees per chunk
            const numPuddles = 5; // Number of puddles per chunk
            const rand = seededRandom(chunkX, chunkY); // Get a consistent random number generator

            // Generate trees
            for (let i = 0; i < numTrees; i++) {
                const rx = rand();
                const ry = rand();
                const x = chunkX * chunkSize + rx * chunkSize;
                const y = chunkY * chunkSize + ry * chunkSize;
                const size = 30 + rand() * 20;

                // Tree properties
                let tree = {
                    x: x,
                    y: y,
                    size: size,
                    color: 'green',
                    trunkWidth: size / 5,
                    trunkHeight: size / 2,
                    foliageWidth: size,
                    foliageHeight: size,
                };

                // Randomize tree color slightly
                const colorVariation = 50;
                const r = 34 + Math.floor(rand() * colorVariation);
                const g = 139 + Math.floor(rand() * colorVariation);
                const b = 34 + Math.floor(rand() * colorVariation);
                tree.color = rgb(${r},${g},${b});

                trees.push(tree);
            }

            // Generate puddles
            for (let i = 0; i < numPuddles; i++) {
                const rx = rand();
                const ry = rand();
                const x = chunkX * chunkSize + rx * chunkSize;
                const y = chunkY * chunkSize + ry * chunkSize;
                const width = 50 + rand() * 50;
                const height = 30 + rand() * 30;

                const puddle = {
                    x: x,
                    y: y,
                    width: width,
                    height: height,
                };
                puddles.push(puddle);
            }

            return {
                trees: trees,
                puddles: puddles
            };
        }

        // Function to create a seeded random number generator for a chunk
        function seededRandom(chunkX, chunkY) {
            let seed = (chunkX * 9176 + chunkY * 6203) % 2147483647;
            return function() {
                // Linear congruential generator
                seed = (seed * 16807) % 2147483647;
                return (seed - 1) / 2147483646;
            }
        }

        // Adjust canvas and camera size when the window is resized
        window.addEventListener('resize', function() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            camera.width = canvas.width;
            camera.height = canvas.height;
        });

        // Event listener for chopping trees with the button
        chopButton.addEventListener('click', function() {
            if (nearbyTree) {
                chopTree();
            }
        });

        // Function to chop a tree
        function chopTree() {
            if (nearbyTree) {
                // Remove the tree from its chunk
                let index = nearbyTree.chunk.trees.indexOf(nearbyTree.tree);
                if (index > -1) {
                    nearbyTree.chunk.trees.splice(index, 1);
                }

                // Add wood to player inventory
                if (player.inventory['Wood']) {
                    player.inventory['Wood'] += 1;
                } else {
                    player.inventory['Wood'] = 1;
                }

                nearbyTree = null;
                interactionMenu.style.display = 'none';
            }
        }

        // Event listener for closing inventory
        closeInventoryButton.addEventListener('click', function() {
            toggleInventory();
        });
    </script>
</body>
</html>

Make game fully dark, add lantern to our character that casting light, fix ugly UI and make it looks like in modern games with smooth minimalistic design