# Falling Sand Simulation ๐Ÿงฑโœจ A high-performance, modular falling sand physics sandbox built in vanilla JavaScript and HTML5 Canvas. Experience realistic particulate physics, fluid dynamics, thermodynamics, combustion, and chemical reactions running at a silky-smooth 60+ FPS. --- ## โšก Performance & Engine Architecture * **Direct 32-Bit Pixel Blitter (`Uint32Array` / `ImageData`):** Replaces traditional Canvas 2D `fillRect` / `arc` draw calls with direct memory writes into a 32-bit RGBA pixel buffer on an offscreen buffer canvas, delivering a **50xโ€“100x rendering speedup** that comfortably handles hundreds of thousands of active particles. * **Rapid Fluid Dispersion:** Liquids (water, acid, oil) dynamically disperse up to customizable multi-cell horizontal steps per frame, eliminating gelatinous stacking and delivering realistic splashing and surface leveling. * **Oil & Water Emulsion & Separation:** Water and oil mix dynamically with diagonal and horizontal swapping before buoyantly separating out according to density. * **Lava & Rock Sinking:** Dense molten lava plunges into water, boiling it into rising steam, and solidifies into stone that naturally sinks through liquid to the bottom of the pool. * **Monotonic Frame Counter & Alternating Sweep:** Eliminates the legacy full-grid `updated = false` pass. Cells track `lastUpdated = currentFrame`. The simulation loop alternates horizontal scan direction (left-to-right vs. right-to-left) every frame to eliminate asymmetric pile-up bias in liquids and sand. * **Zero-Allocation Hot Loop:** All neighbor evaluations, directional offsets, and particle physics run with zero heap allocations or closures, preventing garbage collection pauses and stuttering. * **Bresenham Stroke Interpolation:** Uses Bresenham's line algorithm between consecutive cursor samples to ensure smooth, gapless lines even when drawing at high speeds. * **Non-Destructive Canvas Resizing:** Resizing the window or changing device orientation preserves existing particles on the canvas rather than wiping the simulation. --- ## ๐Ÿงช Element & Reaction Ecosystem | Element | Category | Behavior & Unique Reactions | | :--- | :--- | :--- | | **Sand** | Solid | Granular physics; forms realistic dunes; sinks through liquids. | | **Dirt** | Solid | Rich earthen soil; supports plant and grass roots; displaceable by explosions. | | **Rock** | Solid | Heavy barrier; holds back blasts; naturally sinks through liquids to form riverbeds. | | **Wood** | Solid | Rigid structural block; flammable when exposed to fire or lava. | | **Ice** | Solid | Crystalline cold block; slowly freezes touching water; melts near heat/fire/lava. | | **Water** | Liquid | Flows rapidly; mixes with and separates from oil; turns lava into rock; boils into steam. | | **Lava** | Liquid | Heavy molten magma; plunges into water boiling it into steam; cools into solid rock. | | **Oil** | Liquid | Viscous flammable liquid; mixes with water and then floats to the surface; catches fire intensely. | | **Acid** | Liquid | Corrosive fluid; fast dispersion; sinks through lighter liquids; dissolves organics, metals, and earth. | | **Plant** | Organics | Grows upwards towards light; absorbs water; turns into wood under vertical load. | | **Grass** | Organics | Colonizes surface dirt and sand; sprouts blades; accelerates with moisture. | | **Fire** | Gas / Energy | Dynamic temperature shading (yellow $\rightarrow$ orange $\rightarrow$ red); ignites flammables; spawns smoke. | | **Steam** | Gas | Rises through atmosphere and liquids; escapes into the sky or condenses back into water. | | **Smoke** | Gas | Produced by fires, explosions, and burning oil; drifts with air turbulence and dissipates. | | **TNT** | Energetic | Detonates from fire, lava, or acid; clusters into unified blast waves launching particles kinetically. | | **Eraser** | Tool | Clears cells within brush radius; also accessible via right-click drag. | --- ## ๐ŸŽฎ Controls & Shortcuts | Action | Control | | :--- | :--- | | **Draw Element** | `Left Click` + Drag / Touch | | **Erase** | `Right Click` + Drag or select **Eraser** | | **Brush Size** | `Mouse Wheel` or `[` / `]` or Drawer Slider | | **Pause / Play** | `Spacebar` or Pause button (โธ / โ–ถ) | | **Single Frame Step** | `S` or `.` (Period) or Step button (โญ) | | **Clear Canvas** | Clear button in Elements drawer | --- ## โš™๏ธ Configuration & Customization All simulation and material parameters can be tuned in real time via the **Settings โš™๏ธ** drawer: * **Time & Global:** Simulation speed (0โ€“20), gravity (-1.0 to 2.0), air drag (0.1 to 1.0). * **Explosive:** Blast force, blast reach, plus independent destruction toggles for Rock, Wood, Dirt, Sand, Plant, Grass, Water, Acid, Ice, Lava, and Oil. * **Acid:** Dissolve rate, sink rate, spread speed, explode TNT toggle, plus independent dissolve toggles for Rock, Wood, Dirt, Sand, Plant, Grass, Water (infection), Ice, and Oil. * **Water:** Flow rate and horizontal spread speed (dispersion). * **Lava:** Flow rate, spread speed, cooling rate, and water sink rate. * **Oil:** Flow rate, spread speed, burn rate, water sink rate, and oil float rate. * **Ice:** Melt rate and freeze rate. * **Fire, Steam & Smoke:** Fire decay rate, condensation rate, and smoke dissipation rate. * **Plant & Grass:** Growth rate, woodification rate, and burn rate. * **Visuals:** Switch between `blocky`, `fuzzy` (filtered bloom), or `bloby` rendering, and toggle multi-tone grain color noise. * Settings are automatically saved to `localStorage` and can be restored using **Reset to Defaults**. --- ## ๐Ÿ“‚ Project Structure ```text โ”œโ”€โ”€ index.html # HTML5 entrypoint with drawers and canvas โ”œโ”€โ”€ index.css # Glassmorphic dark UI design and responsive styles โ”œโ”€โ”€ index.js # Main initialization loop, event loop, and input wiring โ”œโ”€โ”€ config.js # Config defaults, settings persistence, and schema โ”œโ”€โ”€ state.js # Grid buffers, canvas dimensions, brush, and frame counter โ”œโ”€โ”€ actions.js # Atomic grid operations (move, swap) with frame tagging โ”œโ”€โ”€ renderer.js # Fast 32-bit Uint32Array blitter with cursor overlay โ”œโ”€โ”€ physics.js # Simulation loop dispatcher and particle generation โ”œโ”€โ”€ dirt.js # Granular sand and soil physics with liquid displacement โ”œโ”€โ”€ water.js # Fast fluid dynamics, oil mixing/separation, and plant hydration โ”œโ”€โ”€ lava.js # Dense molten thermodynamics, water penetration, and rock formation โ”œโ”€โ”€ oil.js # Flammable buoyant liquid physics with water emulsion/separation โ”œโ”€โ”€ ice.js # Freezing and melting thermal logic โ”œโ”€โ”€ acid.js # Fast-spreading corrosive fluid, sinking, and dissolution physics โ”œโ”€โ”€ fire.js # Combustion, heat transfer, temperature decay, and smoke emission โ”œโ”€โ”€ steam.js # Atmospheric rising and condensation โ”œโ”€โ”€ smoke.js # Rising particulate dispersion and decay โ”œโ”€โ”€ plant.js # Root propagation, woodification, and phototropism โ”œโ”€โ”€ grass.js # Surface dirt colonization and blade growth โ”œโ”€โ”€ explosive.js # Clustered BFS blast waves and kinetic shockwaves โ””โ”€โ”€ ui.js # Categorized elements palette, Bresenham strokes, and settings drawer ``` --- ## ๐Ÿš€ Getting Started No build step or external dependencies are required. Simply serve the directory with any local static HTTP server: ```bash # Using Python python -m http.server 8080 # Using Node.js (npx) npx serve . ``` Open `http://localhost:8080` in any modern web browser.