Jelly Loop Jam

A Jelly Sorting Puzzle Game — Unity Template

Version 1.0 | Unity 6+

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 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.

Overview

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.

Softbody Jelly Physics

Real-time softbody jelly ball simulation with Voronoi rendering, Verlet integration physics, gravity, and dynamic color palettes extracted from source images.

Level Editor

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

Auto Level Generator

Batch-generate levels from a folder of images with configurable min/max ranges for colors, grid size, mystery bowls, 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 Jelly Loop Jam package into your Unity project
  2. Open the game scene at Assets/Jelly Loop Jam/Scenes/GameNew.unity
  3. Press Play to test the first level

Quick Test

Once 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.

Folder Structure

Jelly Loop Jam/ │ ├── Art/ │ ├── Materials/ — Conveyor belt, ground, and pipe materials │ ├── Models/ — FBX models (ground tile, pipe base, pipe end) │ ├── JellyImages/ — Source images for auto level generation (put your PNGs here) │ └── Textures/ — UI textures (booster icons, panel backgrounds, etc.) │ └── ConveyorBelt/ — Conveyor belt textures │ ├── 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 │ ├── bowl.fbx — Bowl mesh (transparent body + colored lid) │ ├── TransparentBowl.mat — Transparent material for bowl body │ └── 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 │ └── JellyLoopJam/ — Core game scripts │ ├── BucketData.cs — Bowl state data class │ ├── BucketManager.cs — Bowl grid, pathfinding, animations │ ├── ConveyorManager.cs — Conveyor belt with jelly extraction mechanics │ ├── ImageQuantizer.cs — K-means++ image quantization │ ├── LevelData.cs — Serializable level data structures │ ├── LevelManager.cs — Level loading, progression, persistence │ ├── JellyLoopJamGameManager.cs — Main game controller │ ├── SandSimulator.cs — Softbody jelly ball physics simulation (Voronoi rendering) │ └── SoundManager.cs — Audio system (singleton) │ └── Shaders/ └── BucketOutline.shader — Custom outline shader (vertex extrusion, Cull Front)

Gameplay

Core Mechanics

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.

Jelly 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

Softbody Jelly Physics

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.

Scripts Reference

All scripts use the HypercasualGameEngine namespace.

Core Scripts

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.

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 > 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.

Level Editor

Opening the Level Editor

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.

Features

Edit Modes

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.

Level Storage

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.

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 jelly grid and configures bowl grids with randomized parameters.

Opening the Tool

In the Unity menu bar, go to Tools > Jelly Loop Jam > 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.
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).

How It Works

  1. Source images are loaded from Assets/Jelly Loop Jam/Art/JellyImages/
  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 bowl colors proportionally to pixel coverage
    • Applies mystery bowl 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 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.

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/Jelly Loop Jam/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 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.

Adjusting Jelly Visuals

The jelly simulation is rendered procedurally in SandSimulator.cs using Voronoi-based softbody rendering. Key parameters:

Adjusting Wall Visuals

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

Adding New Boosters

New boosters can be added by following the existing pattern in JellyLoopJamGameManager.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 (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.

Support

Common Issues

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.

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!