A Jelly Sorting Puzzle Game — Unity Template
Version 1.0 | Unity 6+
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 jelly 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.
Jelly Loop Jam is a color-sorting puzzle game where players tap color-coded bowls to send them onto a conveyor belt, which collects jelly balls from a softbody image. The image is built from Voronoi-based softbody jelly balls derived from real photographs quantized into a limited color palette. The game features softbody jelly physics, a built-in level editor, an automatic level generator with image import, a booster system, and full AdMob ad integration.
Real-time softbody jelly ball simulation with Voronoi rendering, Verlet integration physics, gravity, and dynamic color palettes extracted from source images.
Full Unity Editor window for designing levels — import images, configure bowl grids, edit palettes, and manage bowl assignments visually.
Batch-generate levels from a folder of images with configurable min/max ranges for colors, grid size, mystery bowls, and booster counts.
Three in-game boosters — Extra Slot, Shuffle, and Magic Pick — with level-based unlocks, tutorial popups, and usage tracking.
Ragendom Monetization module with banner, interstitial, and rewarded video ads. Includes a Dummy provider for editor testing.
K-means++ algorithm converts any photograph into a limited-palette pixel grid. Re-rollable seeds for color variety.
Assets/Jelly Loop Jam/Scenes/GameNew.unityOnce in Play mode, tap any highlighted (clickable) bowl on the grid to send it to the conveyor belt. The belt extracts matching jelly balls from the softbody image above into the bowl. Match all bowls to complete the level. The next level loads automatically on win.
Each level presents a softbody jelly image above a grid of color-coded bowls and a conveyor belt. The player taps bowls to send them onto the belt, which automatically extracts the matching color of jelly balls from the image into the bowls.
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.
The SandSimulator manages an 80×80 simulation grid populated with jelly balls. Balls use Verlet integration for gravity and collision, with spatial hashing for performance. The image is rendered using Voronoi-based softbody visualization at 160×160 pixels with bilinear filtering. Jelly balls are extracted from the image into bowls on the conveyor belt via a suction system, with flying particle animations.
All scripts use the HypercasualGameEngine namespace.
| Script | Description |
|---|---|
JellyLoopJamGameManager |
Main game controller. Initializes all subsystems (jelly simulator, bowl manager, conveyor), builds UI at runtime, handles input (raycast bowl clicking), manages all three boosters, and triggers win/lose conditions. |
SandSimulator |
Manages the softbody jelly ball simulation with Verlet integration physics, Voronoi rendering, spatial hash collision detection, dynamic color palettes, flying particle effects, and jelly ball extraction for the conveyor belt suction system. |
BucketManager |
Creates and manages the clickable bowl grid. Handles BFS pathfinding for clickability, 3D bowl visuals with transparent body and colored lid (using bowl.fbx prefab with TransparentBowl material), scale-up animations when becoming clickable, lid enable/disable, magic wand hover, and shuffle animation. |
ConveyorManager |
Controls the conveyor belt system. Manages belt slots with object pooling, jelly ball extraction via suction mechanics, liquid fill visualization (cylindrical volume with wave animation), bowl completion with lid bounce animation, sphere particle explosions on completion, and bowl-to-belt positioning. |
BucketData |
Data class storing per-bowl state: grid position, color assignment, quota tracking, belt status, mystery flag, animation state (jump, squeeze, fly-to-belt, body scale, lid bounce), 3D visual references (body renderer, lid object, lid renderer), and liquid surface data. |
LevelData |
Serializable data structures for levels: jelly grid (byte array), color palette, bowl 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(), PlayBucketComplete(), 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. |
| 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). |
| Script | Description |
|---|---|
LevelEditorWindow |
Unity Editor window (Tools > Jelly Loop Jam > Level Editor) for visually designing levels. Import images, edit palettes, configure bowl grids, manage bowl color assignments and mystery toggles. |
AutoLevelGeneratorWindow |
Unity Editor window (Tools > Jelly Loop Jam > Auto Level Generator) for batch-generating levels from a folder of images with configurable min/max parameters. |
In the Unity menu bar, go to Tools > Jelly Loop Jam > Level Editor. This opens a dedicated Editor window — no need to enter Play mode.
| Mode | Click Action |
|---|---|
| Select Bowls | Click a bowl 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. |
All levels are stored as individual JSON files in Assets/Jelly Loop Jam/Resources/Levels/ with the naming convention Level_1.json, Level_2.json, etc. They are loaded at runtime via Resources.LoadAll.
The Automatic Level Generator is an Editor tool that batch-generates levels from a folder of source images. It quantizes each image into a jelly grid and configures bowl grids with randomized parameters.
In the Unity menu bar, go to Tools > Jelly Loop Jam > Auto Level Generator.
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. |
| Bowl Rows (Min/Max) | Number of rows in the bowl grid (default: 4–5). |
| Bowl Columns (Min/Max) | Number of columns in the bowl grid (default: 4–5). |
| Disable Tiles % (Min/Max) | Percentage of grid cells disabled (become walls). Creates irregular layouts. |
| Mystery % (Min/Max) | Percentage of bowls 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). |
Assets/Jelly Loop Jam/Art/JellyImages/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.
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 bowls on the grid using Fisher-Yates shuffle. Bowls fly simultaneously to their new positions with an arc animation. | Tap the shuffle booster button. All grid bowls shuffle instantly. |
| Magic Pick | Allows picking any bowl from the grid, even if it is not naturally clickable (blocked by other bowls). Non-clickable bowls 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 bowl to send it to the belt. Tap the button again to cancel. |
Press the U key during gameplay to unlock all boosters (sets all unlock levels to 0). This is useful for testing.
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.
Full setup and configuration instructions for the ad system are provided in a separate documentation file located at:
That documentation covers AdMob app IDs, ad unit IDs, UMP/GDPR consent, test devices, and all monetization settings.
If you prefer a video walkthrough over reading documentation, watch the full ads setup tutorial here:
▶ Watch Ads Setup Tutorial on YouTube
MonetizationInitModule component. It initializes the ad system on Awake using the assigned MonetizationSettings asset.Assets/Jelly Loop Jam/RagendomAds/Modules/Monetization/MonetizationSettings.asset. Contains all ad provider configuration, timing, and consent settings.Dummy provider for editor testing.| 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. |
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.
Place your source images (PNG, JPG, TGA, or BMP) in Assets/Jelly Loop Jam/Art/JellyImages/. This is the dedicated folder that the Auto Level Generator scans for images. Each image will be quantized into a jelly ball grid using K-means++ color extraction. For best results, use images with clear color regions and good contrast.
The jelly simulation is rendered procedurally in SandSimulator.cs using Voronoi-based softbody rendering. Key parameters:
GRID_SIZE — Default 80 units. The simulation space for jelly ball physics.TEX_SIZE — Default 160 pixels. The render texture resolution (higher = smoother but slower).BALL_RADIUS — Default 1.9. Controls jelly ball size and spacing.RENDER_RADIUS — Default 3.8. Voronoi max influence radius for soft blending between balls.GRAVITY — Default 0.04. Downward acceleration applied each sub-step. Increase for heavier jelly, decrease for floatier feel.DAMPING — Default 0.92. Velocity multiplier each frame (0–1). Lower values = more friction, higher = bouncier jelly.SOLVER_ITERATIONS — Default 3. Collision resolution passes per sub-step. More iterations = more stable but slower.JIGGLE_FORCE — Default 0.002. Random per-frame force that makes the jelly wobble organically.BLEND_ZONE — Default 0.55. Width of the smooth boundary between differently-colored jelly regions (in sim units).MAX_BALLS — Default 800. Hard cap on total jelly balls in the simulation.SUB_STEPS — Default 3. Physics sub-steps per frame. More = smoother physics but higher CPU cost.Color32 arrays in SandSimulator.csLevelData.paletteThe beveled wall meshes surrounding the bowl grid are generated procedurally in BucketManager.cs. Key constants:
wallTopY = 0.10, wallBottomY = -0.12 — Wall height rangebR = 0.045 — Bevel radius (roundness of edges)bSegs = 8 — Arc segments per bevel (smoothness)RGB(0.553, 0.627, 0.745) — light blue-grayRGB(0.44, 0.50, 0.60) — darker blue-grayNew boosters can be added by following the existing pattern in JellyLoopJamGameManager.cs:
HookUpExistingBoosters() using Transform.Find()OnNewBooster())UpdateBoosterUI() with lock/unlock/depleted logicSoundManager call for audio feedbackLevelData.cs for per-level configurationEach level is a JSON file with the following structure:
The sandGrid is a flattened row-major byte array (80×80 = 6400 entries) where each value is a 1-based palette index (0 = empty). This grid determines the color of jelly balls at each position. The palette array uses normalized RGB floats (0.0–1.0). gridCellEnabled determines which bowl grid positions are active; disabled cells become walls.
| Issue | Solution |
|---|---|
| No levels load / default lighthouse level appears | Ensure JSON level files exist in Assets/Jelly Loop Jam/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/Jelly Loop Jam/Art/JellyImages/ and click the refresh button in the generator window. |
Resources/Levels/ folder regularlyIf you get stuck or have any issues, feel free to reach out to us at ragendom@gmail.com. We are happy to help!