Sand Flow Puzzle

A Sand Sorting Puzzle Game — Unity Template

Version 1.0 | Unity 6+

🌟 This asset was made with the HyperCasual Game Engine!   Check it out — mobile puzzle templates & more. Click here to learn more ➔

Important: Template / Starting Point

This asset is designed as a template and starting point for your own game development. It provides the core systems, architecture, and tools needed to build a sand sorting puzzle game. You are expected to customize, extend, and modify this template to create your unique game. This is not a complete, ready-to-publish game — it's a foundation for developers to build upon.

Overview

Sand Flow Puzzle is a color-sorting puzzle game where players tap color-coded buckets to send them onto a conveyor belt, which pours sand into a pixel-art image. The image is quantized from real photographs into a limited color palette using K-means++ quantization. The game features procedurally generated sand physics, a built-in level editor, an automatic level generator with image import, a booster system, and full AdMob ad integration.

Pixel Sand Physics

Real-time 80×80 sand simulation with gravity, particle effects, and dynamic color palettes extracted from source images.

Level Editor

Full Unity Editor window for designing levels — import images, configure bucket grids, edit palettes, and manage bucket assignments visually.

Auto Level Generator

Batch-generate levels from a folder of images with configurable min/max ranges for colors, grid size, mystery buckets, and booster counts.

Booster System

Three in-game boosters — Extra Slot, Shuffle, and Magic Pick — with level-based unlocks, tutorial popups, and usage tracking.

AdMob Integration

Ragendom Monetization module with banner, interstitial, and rewarded video ads. Includes a Dummy provider for editor testing.

Image Quantization

K-means++ algorithm converts any photograph into a limited-palette pixel grid. Re-rollable seeds for color variety.

Getting Started

Requirements

Installation

  1. Import the Sand Flow Puzzle package into your Unity project
  2. Open the game scene at Assets/Sand Flow Puzzle/Scenes/GameNew.unity
  3. Press Play to test the first level

Quick Test

Once in Play mode, tap any highlighted (clickable) bucket on the grid to send it to the conveyor belt. The belt pours sand from the bucket into the pixel image above. Match all buckets to complete the image and win the level. The next level loads automatically on win.

Folder Structure

Sand Flow Puzzle/ │ ├── Art/ │ ├── Materials/ — Conveyor belt, ground, and pipe materials │ ├── Models/ — FBX models (ground tile, pipe base, pipe end) │ └── Textures/ — Source images for level generation (242 PNGs) │ ├── Audio/ — Sound effect .wav files (flat, no subfolders) │ ├── Documentation/ — This documentation file │ ├── Editor/ — Editor-only scripts (excluded from builds) │ ├── LevelEditorWindow.cs — Visual level designer │ └── AutoLevelGeneratorWindow.cs — Batch level generator from images │ ├── Prefabs/ — UI panels and developer tools │ ├── GameHUD_Panel.prefab │ ├── GameOverPanel.prefab │ ├── LevelClearedPanel.prefab │ ├── LoseWinPanel.prefab │ ├── Popup_Powerup_Picker.prefab │ └── DeveloperModeButton.prefab │ ├── RagendomAds/ — Monetization & ad system (separate documentation inside) │ ├── Core/ — Shared interfaces and callbacks │ ├── Documentation/ — Ad system documentation │ ├── Examples/ — Ad example scene and scripts │ ├── Icons/ │ └── Modules/ │ ├── Defines/ — Scripting define management │ └── Monetization/ — Ad providers (AdMob, Dummy), settings, managers │ ├── Resources/ — Unity Resources folder (loaded at runtime) │ ├── Levels/ — Level JSON files (Level_1.json, Level_2.json, ...) │ ├── Sounds/ — Sound effect .wav files loaded at runtime │ ├── cylinder-hole-new.fbx — Bucket mesh │ └── ground.fbx — Tile mesh │ ├── Scenes/ │ └── GameNew.unity — Main game scene │ ├── Scripts/ — All runtime scripts │ ├── CameraSwitcher.cs — Multi-game camera switching │ ├── DeveloperModeButton.cs — Dev panel toggle button │ ├── DeveloperSettingsController.cs — Dev panel controls (level nav, ads) │ ├── LoseWinPanelManager.cs — Win/Lose UI panel controller │ └── SandFlowPuzzle/ — Core game scripts │ ├── BucketData.cs — Bucket state data class │ ├── BucketManager.cs — Bucket grid, pathfinding, merged wall meshes │ ├── ConveyorManager.cs — Conveyor belt with suction mechanics │ ├── ImageQuantizer.cs — K-means++ image quantization │ ├── LevelData.cs — Serializable level data structures │ ├── LevelManager.cs — Level loading, progression, persistence │ ├── SandFlowPuzzleGameManager.cs — Main game controller │ ├── SandSimulator.cs — 80×80 sand physics simulation │ └── SoundManager.cs — Audio system (singleton) │ └── Shaders/ └── BucketOutline.shader — Custom outline shader (vertex extrusion, Cull Front)

Gameplay

Core Mechanics

Each level presents a pixel-art image above a grid of color-coded buckets and a conveyor belt. The player taps buckets to send them onto the belt, which automatically pours the matching color of sand into the image to reconstruct it.

Sand Palette Colors

Colors are dynamically extracted from source images via K-means++ quantization. The default fallback palette uses:

Index Color Hex Value
0 (Empty) Gray #555555
1 (Blue) Blue #2196F3
2 (White) White #FDFBF7
3 (Red) Red #F44336
4 (Orange) Orange #FFCA28

Each level can have 2–10 custom colors defined in its palette. The quantizer extracts dominant colors from the source image automatically.

Win & Lose Conditions

Sand Physics

The SandSimulator runs an 80×80 pixel grid with real-time gravity simulation. Sand particles fall downward and settle into piles. Flying particles animate from the conveyor belt into the grid with velocity-based trajectories and color-matched placement.

Scripts Reference

All scripts use the HypercasualGameEngine namespace.

Core Scripts

Script Description
SandFlowPuzzleGameManager Main game controller. Initializes all subsystems (sand simulator, bucket manager, conveyor), builds UI at runtime, handles input (raycast bucket clicking), manages all three boosters, and triggers win/lose conditions.
SandSimulator Manages the 80×80 pixel sand grid with real-time gravity physics, dynamic color palettes, flying particle effects, and pixel extraction for the conveyor belt suction system.
BucketManager Creates and manages the clickable bucket grid. Handles BFS pathfinding for clickability, 3D bucket visuals, animations (jump, squeeze, flip), magic wand hover, shuffle animation, and procedurally generates merged beveled wall meshes around the grid.
ConveyorManager Controls the conveyor belt system. Manages belt slots with object pooling, sand extraction via suction mechanics, bucket completion detection, belt texture scrolling, and bucket-to-belt positioning.
BucketData Data class storing per-bucket state: grid position, color assignment, quota tracking, belt status, mystery flag, animation state (jump, squeeze, fly-to-belt), and 3D visual references.
LevelData Serializable data structures for levels: sand grid (byte array), color palette, bucket definitions, grid cell enable/disable, belt capacity, and booster counts. Serializable to/from JSON.
LevelManager Static class that loads level JSONs from Resources/Levels/, tracks the current level index via PlayerPrefs, and provides methods to advance, go back, or jump to any level. Includes editor-only save/load utilities.
SoundManager Singleton audio system with static API. Provides named methods for each game event (PlayBucketJump(), PlaySandPour(), PlayLevelWin(), etc.), variant clip arrays with random selection, and a master volume control.
ImageQuantizer Static utility for K-means++ color quantization. Converts source images into limited-palette pixel grids. Supports seed-based randomization for re-rollable color extraction.
LoseWinPanelManager Manages the Win and Lose UI panels. Auto-finds child panels by name. Supports auto-loading the next level after a configurable delay on win.

Utility Scripts

Script Description
CameraSwitcher Switches the camera between multiple parent transforms (for multi-game setups). Persists the selected index via PlayerPrefs.
DeveloperModeButton Toggles a developer settings panel on click. Auto-finds a child named DeveloperSettingsPanel if no reference is assigned.
DeveloperSettingsController Developer panel with buttons for level navigation (next, previous, reload, trigger win/lose), visual theme switching, and ad testing (show/hide banner, show/request interstitial, show/request rewarded).

Editor Scripts

Script Description
LevelEditorWindow Unity Editor window (Tools > Sand Flow Puzzle > Level Editor) for visually designing levels. Import images, edit palettes, configure bucket grids, manage bucket color assignments and mystery toggles.
AutoLevelGeneratorWindow Unity Editor window (Tools > Sand Flow Puzzle > Auto Level Generator) for batch-generating levels from a folder of images with configurable min/max parameters.

Level Editor

Opening the Level Editor

In the Unity menu bar, go to Tools > Sand Flow Puzzle > Level Editor. This opens a dedicated Editor window — no need to enter Play mode.

Features

Edit Modes

Mode Click Action
Select Buckets Click a bucket to select it. Inspect and change its color, toggle mystery status.
Edit Cells Click grid cells to toggle them ON (enabled) or OFF (disabled). Disabled cells become walls.

Level Storage

All levels are stored as individual JSON files in Assets/Sand Flow Puzzle/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, etc. They are loaded at runtime via Resources.LoadAll.

Automatic Level Generator

The Automatic Level Generator is an Editor tool that batch-generates levels from a folder of source images. It quantizes each image into a sand grid and configures bucket grids with randomized parameters.

Opening the Tool

In the Unity menu bar, go to Tools > Sand Flow Puzzle > Auto Level Generator.

Settings

All settings use min/max ranges — each generated level picks a random value within the range:

Setting Description
Color Count (Min/Max) Number of colors per level (default: 3–7). More colors = harder levels.
Bucket Rows (Min/Max) Number of rows in the bucket grid (default: 4–5).
Bucket Columns (Min/Max) Number of columns in the bucket grid (default: 4–5).
Disable Tiles % (Min/Max) Percentage of grid cells disabled (become walls). Creates irregular layouts.
Mystery % (Min/Max) Percentage of buckets that are mystery type (hidden color).
Max Belt Slots (Min/Max) Conveyor belt capacity (default: 4–6). Fewer slots = harder.
Slot/Shuffle/Magic Boosters (Min/Max) Number of each booster type per level (default: 1–3 each).

How It Works

  1. Source images are loaded from Assets/Sand Flow Puzzle/Art/Textures/
  2. Select images — use checkboxes to pick which images to include, or "Select All"
  3. Shuffle images — randomize the order of selected images
  4. Click "Generate" — for each image, the generator:
    • Quantizes the image using K-means++ with a random seed
    • Randomizes all settings within your min/max ranges
    • Distributes bucket colors proportionally to pixel coverage
    • Applies mystery bucket percentage
    • Exports a JSON level file

Append or Replace

Choose between append mode (adds levels after existing ones) and replace mode (overwrites all existing levels). Use append mode to safely add new content without losing existing levels.

Boosters

The game includes three booster abilities that players can activate during gameplay. Each booster has a limited number of uses per level, level-based unlock requirements, and an optional tutorial popup that appears on first use (stored in PlayerPrefs).

Booster Effect Activation
Extra Slot Adds one additional slot to the conveyor belt, increasing its capacity. A "+1 Slot" popup animates above the belt counter. Tap the slot booster button. Immediately adds a slot — no target selection needed.
Shuffle Randomizes the positions of all remaining buckets on the grid using Fisher-Yates shuffle. Buckets fly simultaneously to their new positions with an arc animation. Tap the shuffle booster button. All grid buckets shuffle instantly.
Magic Pick Allows picking any bucket from the grid, even if it is not naturally clickable (blocked by other buckets). Non-clickable buckets pulse with a brightness flash while magic mode is active. Tap the magic booster button to enter targeting mode (button tints). Then tap any non-clickable bucket to send it to the belt. Tap the button again to cancel.

Booster Button States

Cheat Mode

Press the U key during gameplay to unlock all boosters (sets all unlock levels to 0). This is useful for testing.

AdMob Ads

This project includes a Ragendom Monetization module for integrating AdMob ads (banners, interstitials, and rewarded videos). The ad system supports both real AdMob ads on device and a built-in Dummy ad provider for testing in the Unity Editor.

Documentation

Full setup and configuration instructions for the ad system are provided in a separate documentation file located at:

Assets/Sand Flow Puzzle/RagendomAds/Documentation/Documentation.html

That documentation covers AdMob app IDs, ad unit IDs, UMP/GDPR consent, test devices, and all monetization settings.

Video Tutorial

If you prefer a video walkthrough over reading documentation, watch the full ads setup tutorial here:

▶ Watch Ads Setup Tutorial on YouTube

Quick Overview

Ad Types

Ad Type Description
Banner A small ad strip displayed at the top or bottom of the screen. Show and hide at any time.
Interstitial A full-screen ad. Must be requested (loaded) first, then shown when ready. Supports cooldown timers and conditions.
Rewarded Video A full-screen video ad that grants a reward on completion. Must be requested first, then shown. Always available regardless of no-ads purchases.

Testing in the Editor

By default, the ad system uses the Dummy provider, which displays test UI overlays in the Editor (a green "TEST BANNER" bar, dark "TEST INTERSTITIAL" overlay, and blue "TEST REWARDED VIDEO" overlay). This lets you verify the ad flow without needing a real device or AdMob account.

The Developer Settings Panel (accessible via the gear icon in-game) includes ad control buttons for testing: Show/Hide Banner, Show/Request Interstitial, and Show/Request Rewarded Video.

Customization Guide

Adding New Source Images

Place new images (PNG, JPG, TGA, or BMP) in Assets/Sand Flow Puzzle/Art/Textures/. They will automatically appear in the Auto Level Generator's image list. For best results, use images with clear color regions and good contrast.

Adjusting Sand Visuals

The sand grid is rendered procedurally in SandSimulator.cs. Key parameters:

Adjusting Wall Visuals

The beveled wall meshes surrounding the bucket grid are generated procedurally in BucketManager.cs. Key constants:

Adding New Boosters

New boosters can be added by following the existing pattern in SandFlowPuzzleGameManager.cs:

  1. Add booster state fields (count, button reference, unlock level)
  2. Find the button in HookUpExistingBoosters() using Transform.Find()
  3. Add a click handler method (e.g., OnNewBooster())
  4. Update UpdateBoosterUI() with lock/unlock/depleted logic
  5. Add a SoundManager call for audio feedback
  6. Add booster count fields to LevelData.cs for per-level configuration

JSON Level Format

Each level is a JSON file with the following structure:

{ "levelName": "Lighthouse", "gridSize": 80, "desiredColorCount": 4, "palette": [ { "r": 0.129, "g": 0.588, "b": 0.953 } ], "sandGrid": [1, 1, 2, 3, 4, ...], // 6400 bytes (80×80) "bucketRows": 5, "bucketColumns": 5, "bucketSpacingX": 0.0, "bucketSpacingY": 0.0, "gridCellEnabled": [true, true, false, ...], "buckets": [ { "row": 0, "col": 0, "colorId": 4, "isMystery": false }, { "row": 0, "col": 1, "colorId": 0, "isMystery": true } ], "maxBeltSlots": 5, "slotBoosterCount": 3, "shuffleBoosterCount": 3, "magicBoosterCount": 3 }

The sandGrid is a flattened row-major byte array where each value is a 1-based palette index (0 = empty). The palette array uses normalized RGB floats (0.0–1.0). gridCellEnabled determines which bucket grid positions are active; disabled cells become walls.

Support

Common Issues

Issue Solution
No levels load / default lighthouse level appears Ensure JSON level files exist in Assets/Sand Flow Puzzle/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, etc. Use the Auto Level Generator to batch-create levels.
Pink/missing materials The game uses URP shaders. Ensure your project has the Universal Render Pipeline package installed and a URP Renderer Asset assigned in Project Settings > Graphics.
Interstitial / Rewarded ads don't show The Monetization.IsActive flag gates these ad types. The Developer Settings panel auto-forces it active, but in production ensure MonetizationInitModule is in the scene and its settings have IsModuleActive = true.
Dev panel buttons don't respond If you added a Canvas component to the panel (e.g., for sorting order), you must also add a GraphicRaycaster component to the same object.
Level Editor shows empty grid Click "Reload from Disk" in the Level Editor, or ensure the Resources/Levels/ folder exists.
Auto Generator shows no images Place PNG/JPG images in Assets/Sand Flow Puzzle/Art/Textures/ and click the refresh button in the generator window.

Tips

Contact Us

If you get stuck or have any issues, feel free to reach out to us at ragendom@gmail.com. We are happy to help!