A Jigsaw Colour-Sorting Puzzle — Unity Template
Version 0.1.0 | Unity 6+ | URP
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 jigsaw colour-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.
Everything ships under one top-level folder, Assets/Jig Sort/ (single-folder Asset Store publishing). The shared win / lose / booster / developer-mode UI stack (originally the "NewestDevUI" package) is folded into the game folder — its scripts live in Scripts/, prefabs in Prefabs/, and its setup wizard is at Tools → NewestDevUI → Setup Wizard. After importing, run that wizard first (it builds the UI into the scene), then Tools → Jig Sort → Setup Wizard.
Jig Sort is a relaxing jigsaw colour-sorting puzzle. Each level shows a vertical stack of empty colored boxes and a bottom tray of loose jigsaw-quadrant pieces. The player drags each quadrant into the box of its matching colour; when all four quadrants of a box are in place the picture snaps together, a glass cap sweeps over it, star particles burst, and the box clears. Complete every box to win. The game ships with three boosters, a visual level editor, an automatic level generator, and a starter pack of 500 hand-tuned / generated JSON levels.
Drag colour-coded quadrant pieces from the tray into matching-colour boxes. Each box needs its four quadrants (top-left, top-right, bottom-left, bottom-right) before it completes — pieces only fit their own cell.
Every level's tray is the exact complement of its boxes — never a missing or surplus piece. All boxes are visible at level start, so there is always a valid move and no dead ends.
A full Unity Editor window with a level list, per-box colour selection, a per-box picture picker that shows the real target image split into its 4 jigsaw quadrants, mystery-box toggles, per-level booster counts, and one-click Save All / Reload.
Batch-generate fresh levels with a fast concave difficulty curve, configurable box count, colour variety, random picture assignment, booster allowances, and a mystery-box difficulty ramp. Append-only — never overwrites hand-tuned levels.
Shuffle (re-randomise the whole tray incl. top/under), Magical Fill (pull a box's pieces in along curved trails), and Hint (animated ghost showing a valid move). Each is level-gated and shows a one-time tutorial popup on first use.
Optional hidden boxes that show a greyed “?” and reject pieces until a set number of other boxes clear, then reveal their real colour + picture with a pop. Per-level in the editor; difficulty-ramped in the generator.
Some loose pieces spawn as a greyed piece tucked below + behind a front piece, locked until the front one is placed — then it surfaces to full colour with a pop and becomes draggable.
Levels ship as plain JSON under Assets/Jig Sort/Resources/Levels/. Regenerate or extend at any time with the Auto Level Generator.
HypercasualGameEngine).Edit > Project Settings > Graphics).Assets/Jig Sort/Scenes/GameNew.unity.Tools > NewestDevUI > Setup Wizard → Run All Steps — it builds the Canvas, HUD, win/lose panels, booster popups and developer-mode button into the scene.Tools > Jig Sort > Setup Wizard → Run All Steps — it creates the SoundManager / GameManager, auto-wires audio, applies the Player & Build settings, and retargets post-processing.Once in Play mode, drag a tray piece onto its matching-colour box cell. When all four quadrants of a box sit in their cells, the picture assembles, SoundManager.Instance.PlayLevelClear()-adjacent feedback plays, and the box clears. Clear every box to win — the next level loads automatically. Press the → / ← arrow keys in Play mode to jump between levels for QA.
During development the package is two top-level folders. The Jig Sort folder holds all game-specific content; NewestDevUI holds the shared UI stack (folded into Jig Sort before Asset Store publishing).
Each level displays a vertical stack of empty colored 2×2 boxes down the centre, flanked by two side columns of loose jigsaw-quadrant pieces. The player drags a piece onto a box; it only fits the box of its own colour, and only the cell matching its quadrant (top-left, top-right, bottom-left, bottom-right). When all four quadrants of a box are placed, the picture assembles and the box clears.
typeIndex 1–4 (cells (0,0), (1,0), (0,1), (1,1)) in its own colourCheckCompleteGrid → CompleteGrid)JigSortGameManager.TriggerWin() so the clear sound fires exactly once before the panel showsLevelManager.AdvanceLevel() runs before the scene reloads (driven by the NewestDevUI LoseWinPanelManager, or the built-in fallback)Colours are defined by the ColorType enum (LevelData.cs) and mapped to RGB + picture sprites in the ColorData asset. A sample of the palette:
| Color Key | Color |
|---|---|
Red | Red |
Green | Green |
Blue | Blue |
Yellow | Yellow |
Orange | Orange |
Pink | Pink |
JigSortGameManager.TriggerWin(), the level index advances, and the next level loads automatically.JigSortGameManager.TriggerLose(). The base mechanic is non-failing (sorting puzzle), so a lose state can be wired to a move/time limit if desired.Pieces lerp to their target cells; the box pulses on each fill; a glass cap scales over the completed picture and star particles burst. The dragged piece shows a 2D sprite outline (OutlineController + Resources/BlockOutline.shader) and the target box highlights white while a piece hovers over it.
Game-specific runtime scripts use the JigSort.Scripts namespace; editor scripts use JigSort.Editor. The static LevelManager and the SoundManager singleton live under HypercasualGameEngine so the shared NewestDevUI scripts resolve against them. The win/lose, booster, and developer-mode scripts are provided by the NewestDevUI package (also HypercasualGameEngine).
| Script | Description |
|---|---|
GameLevel | Main gameplay controller. Pulls the current level from LevelManager.GetCurrentLevel() (no Inspector fallback), spawns the boxes and the data-driven tray supply, validates and animates drag-placement, detects box completion, routes win/lose through the GameManager, and implements the three booster effects (ShuffleSupply, BombFillRandomBox, UnlockNextSupplyPiece). |
InputManager | Touch / mouse drag handling via the new Input System. Raycasts the Canvas to pick a tappable piece, tracks the drag with a ghost preview, fires the pickup SFX, applies the outline, and hands off to GameLevel.DragBlockTo on release. |
Block | A jigsaw quadrant piece. Stores typeIndex (1–4), blockType (sprite), colorType, target gridPosition, the lock list (blockReleases), and rendering components. |
Box | A colored 2×2 target box; holds its colour and the list of placed quadrants. |
LevelData | Level schema (ScriptableObject, JSON-serialised). Contains the box columns, the tray supply, and the three booster counts (shuffleBoosterCount, bombBoosterCount, unlockBoosterCount). Runtime instances get HideFlags.HideAndDontSave to survive scene reloads. |
JigSortGameManager | Scene orchestrator ([DefaultExecutionOrder(-100)]). Pre-warms the level cache, creates missing infrastructure with FindFirstObjectByType, owns the single TriggerWin() / TriggerLose() choke point (plays the clear/fail sound, flips state, then forwards to the panel), drives arrow-key dev level navigation, and forwards booster effects. |
OutlineController | Toggles the sprite outline on the dragged piece using a single static shared material (zero per-frame GC); loads the shader from Resources first with a Shader.Find fallback. |
BlockData / ColorData | ScriptableObject lookups: block-type → cell footprint + sprite, and ColorType → colour + picture sprite. |
| Script | Description |
|---|---|
LevelManager | Static loader (HypercasualGameEngine). Reads Assets/Jig Sort/Resources/Levels/*.json (editor: disk; player: Resources.Load), tracks the current level under PlayerPrefs key Jig Sort_CurrentLevel, and exposes GetCurrentLevel, AdvanceLevel, GoToPreviousLevel, LevelCount, ForceReload, plus editor-only disk-write helpers used by the level tools. |
SoundManager | SFX singleton (HypercasualGameEngine). One 2D AudioSource, masterVolume, and one Play method per event — including the four NewestDevUI-required methods (PlayBlocked, PlayBoosterShuffle, PlayBoosterBomb, PlayBoosterUnlock). |
CameraSwitcher | Shared camera helper carried over from the engine. |
| Script | Description |
|---|---|
LevelEditorWindow | Tools/Jig Sort/Level Editor — two-pane level designer. |
AutoLevelGeneratorWindow | Tools/Jig Sort/Auto Level Generator — batch generator with a difficulty curve. |
JigSortSetupWizard | Tools/Jig Sort/Setup Wizard — idempotent scene / audio / settings / post-processing automation. |
JigSortWelcomePopup | Tools/Jig Sort/Welcome — first-open splash linking both wizards + tools. |
InputSystemCheck | Warns if Active Input Handling is not set to Both. |
| Script | Description |
|---|---|
LoseWinPanelManager | Win / Lose panels, the winLevelText label, button re-wire on every show, and Next-Level progression (AdvanceLevel before scene reload). |
BoosterManager | The three booster buttons, level-gated counts (Init(LevelData) reads the three counts), one-time tutorial popups (shown before the can-run gate), and SFX. |
DeveloperModeButton / DeveloperSettingsController | Developer-mode panel with Shift+U/W/L/R hotkeys (ad-guarded). |
Open it from Tools > Jig Sort > Level Editor. The window is split into two panes:
+ Add Level, Duplicate Selected, Delete Selected (with confirm), Save All Levels (green), and Reload from Disk (with confirm). A footer shows the total level count.Levels are written to Assets/Jig Sort/Resources/Levels/Level_N.json on Save All Levels.
Open it from Tools > Jig Sort > Auto Level Generator. It appends new levels starting after the last existing one (never overwrites). Tunables:
Every generated level is solvable by construction: each box gets one colour, the tray is the exact 4-quadrant complement of all boxes, and all boxes are visible at start — there is no luck-based generation and no "force a matching turn" post-process. A red Delete All Levels button (with confirm) clears the folder.
Three boosters, level-gated by the per-level counts in LevelData. The buttons, counts, and one-time tutorial popups are provided by the NewestDevUI BoosterManager; the effects are implemented game-side in GameLevel / JigSortGameManager.
| Booster | Effect | SoundManager method |
|---|---|---|
| Shuffle | Re-randomises all loose tray pieces — including their top/under stacking, so a hidden under-piece can surface and hide a different one. Pieces animate to their new slots. | PlayBoosterShuffle() |
| Magical Fill | Picks a random visible box and pulls its proper pieces in one after another along arced curves with fading trails, then completes it. | PlayBoosterBomb() |
| Hint | Flashes a movable piece and loops a translucent ghost of it gliding to its correct box, with a flashing target ghost left on the destination cell. | PlayBoosterUnlock() |
The one-time tutorial popup fires on the first click of each booster before any "can this run" gate, so the player always learns what a booster does. Popup state is persisted under PlayerPrefs keys BoosterPopupShown_Shuffle/Bomb/Unlock.
Swap the quadrant sprites in the BlockData asset and the per-colour picture sprites in the ColorData asset. The 13-colour ColorType palette can be re-tinted in ColorData without touching code.
Drop your puzzle images (PNG) into Assets/Jig Sort/PuzzleImages/, then run Tools → Jig Sort → Refresh Puzzle Images — it imports them as sprites and builds Resources/PuzzleImageData.asset. The Auto Level Generator then assigns a random picture to each colour in every level (same-colour boxes share a picture); the four quadrants of a box assemble that image. If a level has no picture assigned for a colour, it falls back to the ColorData sprite. Tip: for the four quadrants to tile cleanly, give the images a consistent sprite size / Pixels-Per-Unit in the importer.
Use the Auto Level Generator's min/max ranges and difficulty ceiling, or hand-author levels in the Level Editor. Levels 1–5 are hand-tuned as a gentle on-ramp.
Drop your WAV clips into Assets/Jig Sort/Audio/ (use names containing LevelClear, LevelFail, Blocked, Pickup, Place, Complete, Shuffle, Bomb, Unlock, or the Success*/Fail*/Pop*/Switch* pools) and run the Jig Sort Setup Wizard's "Auto-wire SoundManager clips" step.
The shared HC URP profile lives at Assets/Jig Sort/PostProcessing/HC-PostProcessing-Volume.asset. The Setup Wizard retargets the scene's Global Volume and the URP render-pipeline assets to it at weight 0.8.
This template is part of the HyperCasual Game Engine — Mobile Puzzle Templates Kit. For questions about the shared UI / booster / developer-mode stack, see Assets/Jig Sort/Documentation/NewestDevUI-README.md. For the game-specific systems, the in-line XML comments in each script under Assets/Jig Sort/Scripts/ and Assets/Jig Sort/Editor/ are the source of truth.
Questions, bug reports, or feature requests? Email ragendom@gmail.com.
| Symptom | Cause / Fix |
|---|---|
| "No levels found" error on Play | The Levels folder is empty. Run Tools > Jig Sort > Auto Level Generator to generate levels. |
| No win/lose panel, no booster buttons | NewestDevUI isn't imported or its Setup Wizard hasn't run. Import it and run Tools > NewestDevUI > Setup Wizard, then re-run the Jig Sort Setup Wizard. |
| Game is silent | No audio clips in Assets/Jig Sort/Audio/. Import the SFX pack and re-run the Setup Wizard's audio step. |
| Magenta / pink screen | URP is not the active render pipeline. Check Project Settings > Graphics. |
| Level 2 doesn't load after a win | A LevelData lost its HideFlags.HideAndDontSave. The shipped LevelManager sets it; don't remove it. |