Overview
Goods Sorting is a portrait drag-to-match shelf puzzle with 500 levels. Goods sit in three-slot boxes stacked in two to four columns; only the first rows of each column are on the shelf, the rest queue behind it. Drag a good into a free slot of another open box. Three matching goods clear a box, an emptied box also leaves the shelf, and the next queued box slides in. Chained boxes open after enough boxes have left. Clear every box to win; when no open box on the shelf has a free slot, the level is lost. The owner's original hand-made 3 × 17 shelf ships as level 500.
Getting Started
- Create or open a Unity 6000.0.62f1 project that uses the Universal Render Pipeline, the Input System package (
activeInputHandler= Input System or Both) and Unity UI. Import TextMesh Pro Essential Resources when prompted. - Import this package. Two roots appear:
Assets/_GoodsSorting(game, engine scene, tools, resources) andAssets/HyperCasualLiveOpsKit(menu, economy, LiveOps, boosters). - Assign a URP pipeline asset in Graphics/Quality settings and set Player → Color Space to Linear (the game was authored and tested in Linear; Gamma renders the shelf noticeably brighter).
Assets/_GoodsSorting/ProjectRenderSettingscontains the tested PC/Mobile pipeline and renderer assets. - Add
Assets/HyperCasualLiveOpsKit/StarterMenu/Scenes/HLK_MainMenu.unityfirst andAssets/_GoodsSorting/Scenes/Campaign.unitysecond to Build Settings. Play from the menu; the results overlay drives next level, replay and menu. - Open Tools → GoodsSorting → Documentation to reopen this guide inside the editor.
Folder Structure
| Path | Contents |
|---|---|
_GoodsSorting/Game | Original shelf game: Scripts (rules, input, boosters), Prefabs (Box, FillBox, Item, completion texts), Datas (goods sprite mapping, the authored level asset), Textures, Materials. |
_GoodsSorting/Engine | Hypercasual Game Engine core used by the shelf scene (camera switcher, lose/win panel prefab). |
_GoodsSorting/Scenes/Campaign.unity | The playable campaign scene: shelf, input, campaign bootstrap, camera fit and the authored kit gameplay overlay. |
_GoodsSorting/Integration | Kit bridge (settlement, analytics), booster adapter, campaign model/solver, runtime loader, camera fit and booster definitions (PowerUps). |
_GoodsSorting/Resources/Levels | Level_1.json … Level_500.json plus CampaignAuthoring.json (editor ownership metadata). Loaded by Resources.Load("Levels/Level_N"). |
_GoodsSorting/LevelTools | Game adapter, spatial editor, existing-level assessment, progression rules and the shipped campaign baseline (Data). |
_GoodsSorting/ProductionLevelTools | Shared level-tool framework: editor window, document/undo, seeded generation, staged publication. |
HyperCasualLiveOpsKit | Menu, economy, ads/IAP simulation, quests, battle pass, minigames, boosters, audio bank. See its own Documentation folder. |
Gameplay
- Move: press a good in an open, unchained box on the shelf and release it over a free slot of another open box. Chained boxes accept nothing and release nothing.
- Complete: a box holding three identical goods pops with a completion text and leaves the shelf.
- Empty: a box whose last good is moved away also leaves the shelf — its three free slots go with it.
- Queue: when a box leaves, everything above it in that column slides down and the next queued box appears.
- Chains: a chained box shows a number; every box that leaves the shelf counts every visible chain down by one. At zero the box opens.
- Loss: no free slot on any open box. A 1.5-second grace lets a booster rescue the shelf before the lose overlay.
- Win: no boxes left anywhere; the kit credits 50 coins once and shows the results overlay.
Scripts Reference
| Script | Role |
|---|---|
GameLevel / GameLevel.Boosters | Builds the shelf from a LevelData, applies moves (TryMove), completion/empty/chain rules, jam grace, events (OutcomeReached, MoveAttempted, BoxRemoved) and the three booster effects. |
InputManager | Mouse/touch drag; PointerBlocked gate for overlays; TapInterceptor for armed boosters. |
Box, FillBox, Item, ChainFeature | Scene entities: a box with three slots, a slot, a draggable good, the chain visual/counter. |
LevelData, ItemData | Authored level ScriptableObject (columns of boxes) and the goods-type → sprite mapping (37 types). |
GoodsJsonLevel, ShelfState, GoodsShelfSolver | Runtime level contract, pure rules model and bounded solver/replay used by runtime, editor and generator. |
GoodsSortingCampaign, GoodsSortingCampaignBootstrap | Load Resources/Levels/Level_N.json, convert to LevelData, select the level from the kit's selector and bind the level number. |
GoodsSortingCameraFit | Fits the orthographic camera to the shelf between HUD and booster bar; refits on resolution, safe-area and tray changes. |
GoodsSortingHlkBridge, GoodsSortingPowerUpAdapter | Kit settlement/analytics/audio cues and booster handler registration. |
Level Editor
Tools → GoodsSorting → Level Editor opens the shared level window with the shelf canvas. The left list selects a level; Duplicate/Delete/Up/Down and Undo (Ctrl+Z) edit the campaign; Validate + save publishes runtime JSON through staging only when every level validates and its witness replays.
- Paint goods: pick a good in the palette, left-click a slot to place it, right-click to clear. The
xcell erases. - Chains: in Chains mode click a box (left +1, right −1) or use Chain +/− on the selected box.
- Boxes / structure: Insert box, Remove box, Columns +/−, Visible rows +/−. The dimmed band above the shelf is the queue.
- Solve witness: edits clear the solution certificate; press Solve witness to let the bounded solver rebuild it (UNPROVEN means the search budget ran out, not that the level is impossible).
- Play saved level: launches the saved level in the Campaign scene.
Automatic Level Generator
Tools → GoodsSorting → Auto Level Generator opens the same window; the Saved generation request block holds count, seed, attempts per level, minimum formations, maximum repeat streak and append mode. Generate into editor builds the campaign in memory (deterministic for a seed), validates every level's solver witness, colour-normalised uniqueness and structural variety, then Validate + save publishes. Append keeps the existing prefix. The shipped LevelTools/Data/CampaignBaseline.json records the generated campaign so later manual edits can be told apart; ExistingLevels.json records how the owner's authored shelf was assessed and placed.
Boosters
| Booster | Effect |
|---|---|
| SHUFFLE | Every good on the open shelf swaps places (queue and chained boxes untouched); new matches may settle. |
| UNLOCK | Arm it, then tap a pulsing chained box; its chain breaks at once. |
| EXTRA TRAY | Adds an empty tray beside the shelf for this attempt, up to three; rescues a shelf that just jammed. |
Definitions live in _GoodsSorting/Integration/PowerUps; counts, unlock levels, copy and art are edited there. Each booster has its own AI-generated centre icon and explainer illustration under _GoodsSorting/Art/Boosters; swap those six PNGs to re-skin the bar without touching effects. See AI-DISCLOSURE.txt for their origin.
Level Variation
Chapters change one lever at a time: level 1 is a single drag, the queue appears at level 5, chains at 16, four columns at 36, then more goods types (up to 12), deeper queues, tighter free slots and more chains, with recovery levels every tenth level after 20. Structure is the column count, per-column queue depth silhouette, visible rows and chain layout — 490+ distinct formations across the 500 levels and never the same formation three times in a row. The frozen progression rules are encoded in GoodsProgression.
Customization Guide
- Goods art: replace the PNGs in
Game/Textures/Food(keep file names/meta) or editItemData.assetmappings. - Shelf art: Box prefab wood/chain textures in
Game/Textures. - Difficulty: change
GoodsProgression.Chapters(types, triples, free slots, hidden boxes, chains) and regenerate with a new seed, or hand-edit levels in the editor. - Boosters: counts/unlock levels in the PowerUp definition assets; effects in
GameLevel.Boosters.cs. - DEV shortcut panel: the orange
DEVbutton is deliberately visible in every build so you can try Choose Level (all 500 levels), test win/lose, banner/ad triggers and booster unlock/refill/reset. Before shipping your own store build, delete_GoodsSorting/Integration/GoodsSortingDevPanelPolicy.cs(or setStarterGameplayDevPanel.IsAvailable = false) so the kit's release gate hides it again. - Camera bands:
GoodsSortingCameraFit.topBand/bottomBandreserve HUD and booster space. - Economy/LiveOps: see the HyperCasualLiveOpsKit guide (rewards, ads, IAP, quests, pass, minigames).
Level Format
Each Level_N.json is a GoodsJsonLevel: index, formation key, lesson, visibleRows, columns (each a list of boxes with three items, 0 = empty, 1–37 = goods type, and a chain count) and the solver witness as flat triples from-box, type, to-box (box ids count column by column from the bottom of each queue).
{
"index": 3,
"formation": "c2-v3-d2.1-k0",
"lesson": "Match goods; an emptied box leaves",
"visibleRows": 3,
"columns": [
{ "boxes": [ { "items": [1, 2, 0], "chain": 0 }, { "items": [1, 1, 0], "chain": 0 } ] },
{ "boxes": [ { "items": [2, 2, 0], "chain": 0 } ] }
],
"witness": [0, 1, 1, 0, 2, 2]
}Support
Questions and bug reports: satisvizion@gmail.com. Please include the Unity version, the level number and the editor console output.
Licences and Notices
The packaged Third-Party Notices.txt records the verified dependency inventory and unresolved provenance. Owner confirmation of original supplied asset rights remains required.
Current delivery and examples
Unity 6000.0.62f1 / URP. Support: satisvizion@gmail.com.
Buyer roots: Assets/_GoodsSorting, Assets/HyperCasualLiveOpsKit. Internal production, build and upload folders are excluded. The kit is an owner-approved first-party asset.
Current campaign: 500 levels. Use the shipped Level Editor and Auto Level Generator menu entries: Tools/GoodsSorting/Documentation, Tools/GoodsSorting/Level Editor, Tools/GoodsSorting/Auto Level Generator.
Current complete level example
Assets/_GoodsSorting/Resources/Levels/Level_4.json
{
"index": 4,
"formation": "c2-v2-d2.2-k0",
"lesson": "Boxes queue behind the shelf",
"visibleRows": 2,
"columns": [
{
"boxes": [
{
"items": [
1,
2,
0
],
"chain": 0
},
{
"items": [
3,
3,
0
],
"chain": 0
}
]
},
{
"boxes": [
{
"items": [
1,
1,
0
],
"chain": 0
},
{
"items": [
2,
2,
3
],
"chain": 0
}
]
}
],
"witness": [
0,
1,
2,
3,
3,
1,
0,
2,
3
]
}Level fields
| Field | JSON type |
|---|---|
| index | int |
| formation | str |
| lesson | str |
| visibleRows | int |
| columns | list |
| witness | list |
Safe worked editing procedure
- Open Level 4 in the Level Editor and duplicate it into an unused slot.
- Use the editor’s supported controls for a small placement change; keep legal occupancy and required targets. Do not invent JSON fields.
- Run the shipped validator, correct any rule errors, save, then open the duplicate in gameplay and complete it.
- For generation, record the current seed, request a small append batch using the exposed controls, validate its solutions and confirm the previous campaign prefix is unchanged. Cancelling must leave the campaign unchanged.
Run these procedures in a clean import of the final candidate before claiming buyer acceptance; restore test additions afterward.
Current booster policy
{
"schemaVersion": 1,
"gameId": "goodssort",
"defaultProfileId": "default",
"initialGrant": 2,
"refillAmount": 1,
"baseCoinCost": 100,
"coinCostStep": 25,
"levelsPerPriceStep": 10,
"rewardedTimeoutSeconds": 90,
"boosters": [
{
"id": "goods_shuffle",
"unlockLevel": 2,
"rewardedPlacementId": "goods_refill_shuffle",
"reason": "Phase04 default first slot. Untargeted and always legal, so it teaches 'change the board' with no selection step."
},
{
"id": "goods_extra_tray",
"unlockLevel": 7,
"rewardedPlacementId": "goods_refill_extra_tray",
"reason": "Phase04 default second slot. Also untargeted and useful on any shelf, so it needs no mechanic prerequisite."
},
{
"id": "goods_unlock",
"unlockLevel": 16,
"rewardedPlacementId": "goods_refill_unlock",
"reason": "Justified deviation from the default third slot (12). UNLOCK can only target a chained box, and an independent scan of all 500 published levels finds ZERO chained boxes in levels 1-15, with the first at level 16. Introducing it earlier would give the player a booster with no legal target. Level 16 introduces chains, so its first use has a guaranteed opportunity. Round-001 finding GS-002; saved once rather than re-decided per run."
}
]
}Hosting, native-device tests and live-service verification are separately recorded in the delivery handoff. A local build is not proof of a hosted release.
Fonts
Unity-provided defaults only: TextMesh Pro default font for TMP text and LegacyRuntime.ttf for legacy Unity UI. Official TMP Essentials must be installed. Do not add custom font files or atlases. Any historical custom-font references above describe an older revision; they are not current dependencies.
Demo and publishing configuration
Current source verified on 2026-10-09. The Android download is a development demo with debug signing; WebGL is a LocalQA showcase. Ads are included as LiveOps provider adapters and test/local configuration; vendor SDKs and production credentials are not bundled in the buyer package. Native device and live store certification remain pending.
For product help, contact SatisVizion at satisvizion@gmail.com
See Third-Party Notices.txt in the package for the verified dependency and license inventory.