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
- Import the package into a Unity 6 URP project.
- 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 aNullReferenceExceptionthat does not mention TextMesh Pro at all. - Let Package Manager finish resolving. The kit needs
com.unity.ugui,com.unity.purchasing,com.unity.mobile.notificationsand the built-incom.unity.modules.screencapture. - Open
Assets/HexaFall/Scenes/HexaFall_Level.unity. - 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
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
| Script | Responsibility |
|---|---|
HexaFallGame | Owns the level: taps, the flow of hexes into buffered crates, crate countdowns, win and lose. Also exposes the four booster effects. |
HexaFallGameManager | Binds the campaign to the board: which level loads, what happens on win or lose, and every gameplay sound cue. |
HexaFallLevelManager | Which level is selected and how far the player has got. Reads and writes the same keys the menu's level selector uses. |
HexaFallLevelBuilder | Assembles a whole playable level out of level data: board, tray, crates, buffer, frame and camera framing. |
HexaFallLevelData | The runtime level: board grids, tray grids and the variation feature lists. |
HexaFallJsonLevel | The on-disk mirror of a level. One JSON file per level. |
HexaFallCampaign | How many levels ship, where they live, and which palette and style they are played with. |
HexaFallSolver | Headless playthrough simulator. Measures how often a level is won across independent playthroughs, not merely whether it can be, before it is saved. |
HexaFallLevelGenerator | The generation engine the Auto Level Generator window is built on. |
Utility Scripts
| Script | Responsibility |
|---|---|
HexaFallBoard / HexaFallBoardModel | The board's visuals and its pure-C# model. The solver and the game share the model, so both obey the same rules. |
HexaFallTray | The tray grid and the accessibility rule that decides which crates are tappable. |
HexaFallBuffer | The row of parking slots, including the widening the Extra Slot booster performs. |
HexaFallBox | One collector crate: fill percentage, mystery concealment and the reveal lerp. |
HexaFallCrate | A wooden crate: its countdown, its shudder and its shatter. |
HexaFallGlyphMarker | The world-space "?" on a mystery crate. |
HexaFallMeshFactory / HexaFallTextureFactory | Build every mesh and texture in the game from the style asset. |
HexaFallCameraRig | Frames the board, buffer and tray, and applies shake presets. |
HexaFallHaptics | Android vibration and iOS Core Haptics, written from scratch. Safe on every platform. |
HexaFallPowerUpAdapter | Connects the four boosters to the reusable power-up framework. |
HexaFallLiveOpsAdapter | The only place the game talks to the backend: rewards, analytics and the leaderboard. |
Editor Scripts
| Script | Responsibility |
|---|---|
HexaFallLevelEditorWindow | The Manual Level Editor. |
HexaFallAutoLevelGeneratorWindow | The Auto Level Generator. |
HexaFallWelcomePopup | The first-run greeting. |
HexaFallLevelIO | Loads, saves, renumbers and validates the level set. Shared by both windows. |
HexaFallLevelDataEditor | Inspector 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
| Tool | What a click does |
|---|---|
| Select | Picks a cell to edit in the Selected Cell section below. |
| Colour | Puts a crate of the chosen colour in the cell. |
| Crate | Covers the cell with a wooden crate, or removes one. The number on it is how many crates must be collected before it opens. |
| Mystery | Conceals the cell's colour behind a "?" until it becomes reachable. |
| Cut-out | Cuts the cell out of the tray floor. Nothing can ever stand there. |
| Erase | Empties 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.
| Setting | Meaning |
|---|---|
| Difficulty curve | pow(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. |
| Colours | How many palette colours a level uses. |
| Board columns | Width of the hex board. |
| Tray rows / columns | Size of the crate grid. |
| Min / max stack depth | How deep the board's stacks may be. |
| Buffer slots | Parking slots. This one runs down with difficulty. |
| Cut-outs / crates / mystery from level | The campaign level each variation family is introduced on. |
| … share | How much of the eligible population each family covers, at the easiest and hardest levels. |
| Crate cost | How many crates must be collected before a wooden crate opens by itself. |
| Booster counts | Uses each level grants, per booster. |
| Attempts per level | Seeds tried before a level is loosened, and again before it falls back to a plain board. |
| Boxes – first / last level | The 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 / last | Tiles standing on the board at each end of the campaign, checked as a band on the level that was built. |
| Band, early / late | How 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 candidate | How 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
- The level's difficulty is read off the curve, and every setting is rolled inside its own min/max pair.
- The tray footprint is laid out and the cut-outs are cut from it, biased toward the chosen silhouette.
- 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.
- 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.
- 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.
- 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.
- After the configured number of attempts the level is loosened — its variation features cut to 40% — and tried again.
- 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.
| Booster | Kind | What it does | Unlocks |
|---|---|---|---|
| Shuffle | one press | Swaps every uncovered crate in the tray into a different cell, flying each along an arc. | level 1 |
| Extra Slot | one press | Adds one parking slot to the buffer for this level, and re-centres the row. | level 2 |
| Pick Any | armed | Takes 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 Buster | one press | Smashes 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
0and 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
- Open
Tools > Hexa Fall > Manual Level Editor. - Press + Add, or select a level and press Duplicate.
- Set the tray rows and columns, then paint crates with the Colour tool.
- Press Rebuild Board For This Tray so the board matches what you painted.
- 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.
- Press Save All.
Adding a colour
- Open
Settings/HexaFallPalette.assetand add an entry: an id character, a display name, a tint and a crate capacity. - Press Play. Materials and meshes are generated per colour on demand, so there is nothing to build by hand.
- 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
- Add a handler class to
HexaFallPowerUpAdapterimplementingIPowerUpEffectHandler, and register it inAwake. - Create a
PowerUpDefinitionasset underAssets/HexaFall/PowerUps/with the same id. - Set
RequiresTarget: off for a booster that acts on the level as a whole, on for one where the player picks the victim. - Raise
StarterMenuConfig.GameplayUiBoosterSlotCapacityso the authored bar has a slot for it, then re-run the gameplay UI installer.
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.
| Character | Meaning |
|---|---|
. | empty cell |
R, W, B… | a palette id: places that colour |
1-9, then A-Z | a count from 1 to 35 (stack depth, crate capacity) |
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
| Symptom | Cause and fix |
|---|---|
| Everything renders pink | The 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 balanced | Some colour has more or fewer hexes on the board than its crates can hold. Press Auto-Balance Stack Depths. |
| Taps do nothing on device | The 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 out | It 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 FRAGILE | It 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 bands | The 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!