Hexa Fall

A Hexagon Sorting Puzzle — 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 hexagon sorting puzzle. 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 is a foundation for developers to build upon.

Overview

Hexa Fall is a colour-sorting puzzle. A board of hexagon stacks sits above a tray of crates. Tapping a crate sends it up into the buffer, where it fills itself with matching hexes drawn off the board's front row. A crate can only be tapped when the column above it is clear, so the order you take them in is the whole puzzle.

Everything you can see is generated by the project itself — meshes, materials, the toon shader, the counter font and the particle systems are all produced in code, so there are no imported models or textures to license, swap or maintain.

500 verified levels

Every shipped level was played by a headless solver many times over before it was written, and kept only if it was won often enough. "A winning line exists" is not the same claim as "a player will find one", and in a game with no undo it is the weaker one: a board that clears on a single tap order deadlocks everyone else twenty moves later. Levels 1–10 win 100% of simulated playthroughs and every later level at least 80%.

Manual Level Editor

A two-panel editor window: the set on the left, a clickable tray and board on the right. Paint colours, crates, mystery crates and cut-outs directly.

Auto Level Generator

Batch-generates levels with min/max ranges for every tunable, interpolated by a difficulty curve across the campaign.

Four boosters

Shuffle, Extra Slot and Crate Buster fire on one press; Pick Any arms and lets you choose a crate the rules would otherwise refuse.

Procedural art pipeline

Every mesh, material, texture and glyph is built from a style asset. Change a radius and the whole game re-forms around it.

LiveOps backend included

Menu, level selector, shop, ads, IAP, minigames, daily rewards and battle pass all come from HyperCasualLiveOpsKit, documented separately.

Getting Started

Requirements

  • Unity 6000.0.62f1 or newer
  • Universal Render Pipeline (URP) 17.0.4
  • Input System package 1.14.2 (the project ships configured for it)
  • Linear colour space, portrait orientation

Installation

  1. Import the package into a Unity 6 URP project.
  2. Import TextMesh Pro's essential resources if the project has never had them: Window > TextMeshPro > Import TMP Essential Resources. Every label in the menu uses TMP, and without them the menu installer fails with a NullReferenceException that does not mention TextMesh Pro at all.
  3. Let Package Manager finish resolving. The kit needs com.unity.ugui, com.unity.purchasing, com.unity.mobile.notifications and the built-in com.unity.modules.screencapture.
  4. Open Assets/HexaFall/Scenes/HexaFall_Level.unity.
  5. Press Play.

Quick Test

With the gameplay scene open, press Play and tap a crate in the bottom tray. It should arc up into the buffer row and start drawing matching hexes off the front of the board. Fill every crate and the level is won.

To play the campaign rather than a single level, add the menu scene Assets/HyperCasualLiveOpsKit/StarterMenu/Scenes/HLK_MainMenu.unity as build scene 0 and press Play from there.

Folder Structure

Assets/HexaFall/ Documentation/ this manual Editor/ the three buyer-facing tools and their shared engine HexaFallLevelEditorWindow.cs Tools > Hexa Fall > Manual Level Editor HexaFallAutoLevelGeneratorWindow.cs Tools > Hexa Fall > Auto Level Generator HexaFallWelcomePopup.cs Tools > Hexa Fall > Welcome HexaFallLevelIO.cs reads and writes the level files HexaFallLevelDataEditor.cs inspector for a level asset Materials/ generated, one per palette colour plus the scenery Meshes/ generated hex, crate, plate and socket meshes PowerUps/ the four booster definitions Prefabs/ tile, crate, wooden crate, plate, buffer socket Resources/ HexaFall/ HexaFallCampaign.asset - the shipped campaign Levels/ Level_1.json ... Level_500.json Scenes/ HexaFall_Level.unity Scripts/ runtime C# Settings/ palette, style, materials, font, generator Shaders/ hand-written URP toon, glass, outline, particle Textures/ generated wood, sparkle, counter-font atlas Assets/HyperCasualLiveOpsKit/ the reusable backend, with its own manual

The two folders are separate products. HexaFall holds this game's mechanic and content; HyperCasualLiveOpsKit holds the menu, economy, ads, IAP and minigames, and is documented in its own Documentation.html.

Gameplay

Core Mechanics

  • The board is a hexagonal grid of colour stacks. Only stacks on the front line — the edge nearest the buffer, with nothing in front of them — can be collected. When a front stack empties, the stacks behind advance into the gap.
  • The tray is a grid of crates. Each crate collects one colour and holds a fixed number of hexes.
  • Tapping a crate sends it to a free buffer slot, where it starts pulling matching hexes off the board. A crate is only tappable when every tray cell between it and the buffer is empty.
  • Only one crate per colour collects at a time. Later crates of the same colour wait at 0% until the first one finishes.
  • A full crate seals, pops and leaves, and the buffer closes up.

Palette Colours

Colours live in Settings/HexaFallPalette.asset. Each entry carries an id character, a display name, a tint and a crate capacity — how many hexes one crate of that colour holds. The id character is what the level files use.

Win & Lose Conditions

  • Win: the tray and the buffer are both empty.
  • Lose: the buffer is full and none of the colours parked in it are on the board's front line, so nothing can progress.

Because a level is only lost when the buffer jams, buffer size is the game's tightest difficulty lever — and the reason the Extra Slot booster exists.

Balance

A level is balanced when every colour has exactly as many hexes on the board as its crates can swallow. An unbalanced level is finishable but leaves a stack stranded, which reads as a bug rather than a difficulty. The editor's Check Balance and Auto-Balance Stack Depths buttons report and fix this.

Scripts Reference

Core Scripts

ScriptResponsibility
HexaFallGameOwns the level: taps, the flow of hexes into buffered crates, crate countdowns, win and lose. Also exposes the four booster effects.
HexaFallGameManagerBinds the campaign to the board: which level loads, what happens on win or lose, and every gameplay sound cue.
HexaFallLevelManagerWhich level is selected and how far the player has got. Reads and writes the same keys the menu's level selector uses.
HexaFallLevelBuilderAssembles a whole playable level out of level data: board, tray, crates, buffer, frame and camera framing.
HexaFallLevelDataThe runtime level: board grids, tray grids and the variation feature lists.
HexaFallJsonLevelThe on-disk mirror of a level. One JSON file per level.
HexaFallCampaignHow many levels ship, where they live, and which palette and style they are played with.
HexaFallSolverHeadless playthrough simulator. Measures how often a level is won across independent playthroughs, not merely whether it can be, before it is saved.
HexaFallLevelGeneratorThe generation engine the Auto Level Generator window is built on.

Utility Scripts

ScriptResponsibility
HexaFallBoard / HexaFallBoardModelThe board's visuals and its pure-C# model. The solver and the game share the model, so both obey the same rules.
HexaFallTrayThe tray grid and the accessibility rule that decides which crates are tappable.
HexaFallBufferThe row of parking slots, including the widening the Extra Slot booster performs.
HexaFallBoxOne collector crate: fill percentage, mystery concealment and the reveal lerp.
HexaFallCrateA wooden crate: its countdown, its shudder and its shatter.
HexaFallGlyphMarkerThe world-space "?" on a mystery crate.
HexaFallMeshFactory / HexaFallTextureFactoryBuild every mesh and texture in the game from the style asset.
HexaFallCameraRigFrames the board, buffer and tray, and applies shake presets.
HexaFallHapticsAndroid vibration and iOS Core Haptics, written from scratch. Safe on every platform.
HexaFallPowerUpAdapterConnects the four boosters to the reusable power-up framework.
HexaFallLiveOpsAdapterThe only place the game talks to the backend: rewards, analytics and the leaderboard.

Editor Scripts

ScriptResponsibility
HexaFallLevelEditorWindowThe Manual Level Editor.
HexaFallAutoLevelGeneratorWindowThe Auto Level Generator.
HexaFallWelcomePopupThe first-run greeting.
HexaFallLevelIOLoads, saves, renumbers and validates the level set. Shared by both windows.
HexaFallLevelDataEditorInspector for a hand-authored level asset, with balance and simulation buttons.

Level Editor

Opening the Level Editor

Menu path: Tools > Hexa Fall > Manual Level Editor

Features

  • Left panel — the set. Every level in campaign order. Add, Duplicate, Delete, Move Up and Move Down. Save All writes the whole set back and renumbers the files on disk, so the list order is always the shipped order.
  • Right panel — the selected level. Bold-labelled sections over a clickable board and tray.
  • Board. Click a hex to cycle its colour. The number on it is the stack depth. Rebuild Board For This Tray repaints the board so every colour in the tray has somewhere to come from.
  • Tray grid. Rows and columns sliders, a tool bar, and a clickable grid.
  • Selected Cell. Colour, capacity override, mystery toggle, crate toggle and crate cost for one cell.
  • Rules. Buffer slots, access rule, and whether a starved crate closes early.
  • Boosters. Per-level counts and unlock levels for all four boosters.
  • Validation. Check Balance, Simulate Playthrough and Validate All. Failures are shown in the window, not only in the console.

Edit Modes

ToolWhat a click does
SelectPicks a cell to edit in the Selected Cell section below.
ColourPuts a crate of the chosen colour in the cell.
CrateCovers the cell with a wooden crate, or removes one. The number on it is how many crates must be collected before it opens.
MysteryConceals the cell's colour behind a "?" until it becomes reachable.
Cut-outCuts the cell out of the tray floor. Nothing can ever stand there.
EraseEmpties the cell completely.

Level Storage

Levels are JSON files at Assets/HexaFall/Resources/Levels/Level_N.json, numbered from 1 with no gaps. Assets/HexaFall/Resources/HexaFall/HexaFallCampaign.asset records how many there are and which palette and style they use.

There is deliberately no bulk-generate button in this window. A destructive rewrite of the whole set should not sit one mis-click away from somebody browsing a list — that lives in the Auto Level Generator.

Automatic Level Generator

Opening the Tool

Menu path: Tools > Hexa Fall > Auto Level Generator

Settings

Every tunable is a min/max pair. Min is what level 1 gets, max is what the last level gets, and everything between is interpolated by the difficulty curve then jittered so neighbouring levels are not identical.

SettingMeaning
Difficulty curvepow(t, exponent) across the campaign. 1.0 is linear; below 1 ramps faster early. Default 0.4, so a 500-level batch is at roughly 40% difficulty by level 50 instead of waiting until level 375.
ColoursHow many palette colours a level uses.
Board columnsWidth of the hex board.
Tray rows / columnsSize of the crate grid.
Min / max stack depthHow deep the board's stacks may be.
Buffer slotsParking slots. This one runs down with difficulty.
Cut-outs / crates / mystery from levelThe campaign level each variation family is introduced on.
… shareHow much of the eligible population each family covers, at the easiest and hardest levels.
Crate costHow many crates must be collected before a wooden crate opens by itself.
Booster countsUses each level grants, per booster.
Attempts per levelSeeds tried before a level is loosened, and again before it falls back to a plain board.
Boxes – first / last levelThe campaign's size ramp, and the one thing that is enforced. The tray, its cut-outs and the board are all fitted around this number rather than the other way round.
Board tiles – first / lastTiles standing on the board at each end of the campaign, checked as a band on the level that was built.
Band, early / lateHow far a level may sit from its tile target. Keep the early figure tight: early on the target barely moves, so a wide tolerance admits everything and enforces nothing.
Playthroughs per candidateHow many independent playthroughs judge a candidate. Acceptance is a win rate, not a single win.

Sources

Below the settings is the list of sources the run will consume: every colour in HexaFallPalette.asset with a swatch and an include toggle, and the tray silhouettes the cut-outs are biased toward. Exclude a colour or a silhouette before pressing Generate and it will not appear in the output.

How It Works

  1. The level's difficulty is read off the curve, and every setting is rolled inside its own min/max pair.
  2. The tray footprint is laid out and the cut-outs are cut from it, biased toward the chosen silhouette.
  3. Crates are shared between the colours, and the board is given exactly enough cells and stack depth to fill them — so the level balances by construction.
  4. Wooden crates and mystery crates are placed only on crates that are buried at the start. A lock over something the player could already tap opens on the first move.
  5. The candidate is checked against the ramp — its box count and its board tiles, measured on the level that was just built rather than on the settings it was asked for.
  6. The candidate is played by the solver many times. It is kept only if it is won often enough; a board that can be won but almost never is gets thrown away like one that cannot be won at all. Survivors are re-measured a second time on an independent run of the simulation, because a test repeated a few hundred times per level stops being a test and becomes a search for a board that got lucky.
  7. After the configured number of attempts the level is loosened — its variation features cut to 40% — and tried again.
  8. If that also fails, a plain board is written as a last resort and logged loudly. A level is never saved with a warning.

The run report appears in the window and names how many levels were loosened, how many fell back, and why.

Append or Replace

  • Append adds the new levels after the highest existing one and leaves the earlier levels alone.
  • Replace rebuilds the set from scratch, after a confirmation dialog. Tick Keep level 1 to leave the hand-authored opening level untouched.

The seed makes a run reproducible: the same seed and the same settings produce the same set. Cancelling mid-run keeps everything already written.

Boosters

Four boosters, each answering one thing the levels do to the player. Three of them fire on a single press; only Pick Any arms and waits, because it is the only one where the choice of target matters.

BoosterKindWhat it doesUnlocks
Shuffleone pressSwaps every uncovered crate in the tray into a different cell, flying each along an arc.level 1
Extra Slotone pressAdds one parking slot to the buffer for this level, and re-centres the row.level 2
Pick AnyarmedTakes any crate, even one that is boxed in or under a wooden crate. Every crate it can reach pulses while it is armed.level 5
Crate Busterone pressSmashes every wooden crate on the tray at once, without waiting for the countdowns.level 16

Booster Button States

  • Locked — the button shows the level it opens on and is not pressable.
  • Empty — unlocked but out of charges; the button shows 0 and refuses with a sound.
  • Armed (Pick Any only) — the button pulses and every eligible crate pulses with it. Pressing the button again cancels.

A charge is consumed only when the effect actually does something. Pressing Shuffle with one crate left, or Crate Buster on a board with no crates, is refused and costs nothing.

The first time a booster is pressed, its tutorial popup appears — before the can-use check, so a player who taps an empty booster still gets the explanation.

Per-level counts and unlocks

Both live on the level, not in code. Set them in the Manual Level Editor's Boosters section, or as ranges in the Auto Level Generator. An unlock level of -1 keeps the catalogue's own value.

Level Variation

Three families make level 400 feel different from level 4, and each is introduced on its own level so the player meets one new idea at a time.

Tray cut-outs

Cells with no floor plate that no crate may ever occupy. They shape the tray's silhouette and shorten the columns crates queue in. Nothing stands in a cut-out, so it never blocks the path to the buffer.

Wooden crates

A wooden crate hides the crate beneath it and blocks everything behind it. It is a lock with a cost: it opens once the level's required number of crates has been collected, and it shows that number counting down while the player works elsewhere. The Crate Buster booster opens them early; Pick Any takes one crate out from under its lid.

Mystery crates

A mystery crate renders as a neutral slate with a "?" and reveals its real colour — lerping, not snapping — the moment it becomes reachable. It is never tappable while concealed, so the player is never asked to commit to a colour they cannot see. Mystery removes planning ahead; it is not a gamble.

Buffer slots

The quietest lever and the strongest one: how many crates can be parked at once. It falls as the campaign progresses, and the Extra Slot booster is the counter-move.

Customization Guide

Adding a level

  1. Open Tools > Hexa Fall > Manual Level Editor.
  2. Press + Add, or select a level and press Duplicate.
  3. Set the tray rows and columns, then paint crates with the Colour tool.
  4. Press Rebuild Board For This Tray so the board matches what you painted.
  5. Press Simulate Playthrough. It reports three states, and only the first is a pass: winnable and forgiving, FRAGILE (a winning line exists but players will rarely find it), or NOT WINNABLE. Treat FRAGILE as a failure — widen the buffer, drop a colour, or shorten the board.
  6. Press Save All.

Adding a colour

  1. Open Settings/HexaFallPalette.asset and add an entry: an id character, a display name, a tint and a crate capacity.
  2. Press Play. Materials and meshes are generated per colour on demand, so there is nothing to build by hand.
  3. The new colour appears in both level tools automatically.

Adjusting the look

Everything visual is in Settings/HexaFallStyle.asset: hex radius and bevel, stack spacing, crate size, tray spacing and frame, buffer layout, every animation duration, camera framing and shake, particle counts, lighting and post-processing. Changing a value regenerates the affected meshes the next time the level is built.

Adjusting the difficulty curve

Open the Auto Level Generator and change Difficulty curve, or any min/max pair. Then re-run with Replace and Keep level 1 ticked.

Adding a booster

  1. Add a handler class to HexaFallPowerUpAdapter implementing IPowerUpEffectHandler, and register it in Awake.
  2. Create a PowerUpDefinition asset under Assets/HexaFall/PowerUps/ with the same id.
  3. Set RequiresTarget: off for a booster that acts on the level as a whole, on for one where the player picks the victim.
  4. Raise StarterMenuConfig.GameplayUiBoosterSlotCapacity so the authored bar has a slot for it, then re-run the gameplay UI installer.
sealed class MyEffect : IPowerUpEffectHandler { public string PowerUpId => "hexafall_my_effect"; public PowerUpUseResult TryApply(Object target) { // Refuse rather than throw: a rejected use must not cost a charge. if (nothingToDo) return PowerUpUseResult.Rejected("Nothing to do."); return PowerUpUseResult.Used("Done!"); } }

Level Format

One JSON file per level. The board and the crate colours are text grids — one character per cell — because that is what makes a level readable in a diff and typeable by hand. Everything sparse is a list of cell addresses instead.

CharacterMeaning
.empty cell
R, W, Ba palette id: places that colour
1-9, then A-Za count from 1 to 35 (stack depth, crate capacity)
{ "levelNumber": 42, "levelName": "Level 42", // Board: one string per row. Odd rows sit half a cell in. "boardColors": ["RWBWB", "WBBRWB", "BWRRB"], "boardStacks": ["54455", "445554", "44654"], "defaultStackDepth": 4, // Tray: the crate grid, plus an optional per-cell capacity override. "trayRows": 4, "trayColumns": 5, "trayBoxes": ["..B..", ".RWR.", "RWBWR", ".BWB."], "trayCapacities": [], // Variation families, as cell addresses. "obstacles": [ { "row": 0, "col": 0 } ], "crates": [ { "row": 2, "col": 1, "boxesRequired": 3 } ], "mysteryBoxes": [ { "row": 3, "col": 2 } ], // Rules. "bufferSlotCount": 5, "accessMode": 0, "completeBoxesThatRunOutOfTiles": false, // Boosters. -1 on an unlock level keeps the catalogue's own value. "shuffleCount": 3, "extraSlotCount": 2, "crateBusterCount": 2, "pickAnyCount": 2, "shuffleUnlockLevel": -1, "extraSlotUnlockLevel": -1, "crateBusterUnlockLevel": -1, "pickAnyUnlockLevel": -1, // Informational only. "difficultyBand": 2, "generatorSeed": 20260816 }

accessMode is 0 for the default rule (the column above the crate must be clear), 1 for any straight line to a grid edge, and 2 for any empty orthogonal neighbour.

Support

Common Issues

SymptomCause and fix
Everything renders pinkThe project is not using URP, or the render pipeline asset is not assigned. Set it in Project Settings > Graphics.
"The campaign cannot start"HexaFallCampaign.asset is missing from Resources/HexaFall/, or its level count is 0. Open the Manual Level Editor and press Save All.
A level says it is not balancedSome colour has more or fewer hexes on the board than its crates can hold. Press Auto-Balance Stack Depths.
Taps do nothing on deviceThe gameplay scene needs an EventSystem. The kit's gameplay UI installer authors one; re-run it from Tools > HLK > Gameplay UI.
A booster button is greyed outIt is either locked (the button shows the level it opens on) or empty (it shows 0). Both are set per level.
The generator reports "LAST-RESORT"That level could not be made winnable at the requested difficulty and a plain board was written instead. Widen the tray or buffer ranges, or lower the family shares.
A level is reported as FRAGILEIt has a winning line, but too few of the simulated playthroughs find it. Give the player more room: raise the buffer slots, drop a colour, or reduce the crates. This is the state that produces "this level is impossible" reports while every other check stays green.
The campaign report says a trend is FLAT for several bandsThe first and last fifty-level bands differ but the middle does not, so the campaign stops getting harder while the player is still playing it. Widen the ramp's first/last pair rather than the jitter.

Tips

  • Keep the golden opening level as level 1. It is the board the mechanic was derived from and the fixture the tests compare against.
  • Place wooden crates and mystery crates only where they are buried at the start — the generator enforces this, and hand-authored levels should too.
  • A crate's countdown can never ask for more crates than the level contains, or it will never open.
  • Re-run Validate All after any bulk edit. File existence is not validation.

Contact Us

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