View: Multi-Page Single Page

Install & requirements

Import the package. The Core (generation / solving / rules / data / ScriptableObjects) has no package dependencies and works in any render pipeline.

The demo uses the Input System and TextMeshPro packages and ships on the Built-in pipeline. On URP/HDRP, run Unity's material converter on the demo materials — the generator itself is pipeline-agnostic. Requires Unity 6000.3+.

Assembly definitionsCore, Demo, and Editor are separate asmdefs, so the generator never pulls in the demo's packages.

No-code start

Pair puzzles (draw / pipe-rotate)

1

Open the generator

Window ▸ Living Failure ▸ Simple Connect ▸ Connect Generator.

2

Configure & generate

Pick Shape (Square/Hex), size, pairs and coverage. Leave Strict lines off to fill the board, or turn it on for clean no-self-touch routes. Click Generate (or a batch). Preview on the right; page with < >.

3

Save

Save Current (one puzzle) or Save Pack (the set) into your project.

Network puzzles (rotate, fountains)

1

Open the generator

Window ▸ Living Failure ▸ Simple Connect ▸ Network Generator.

2

Shape the network

Pick size and coverage, then dial in Branchiness (corridors ↔ bushy) and Junction bias (extra Ts and crosses). Optionally Allow loops (redundant routes) or Limit dead ends — 0 seals every loose end.

3

Pin fountains (optional)

Open the Fountains foldout and click cells to cycle their required pipe count: ·234? (random per board) — capped at what each cell can physically take. Or set Random fountains to scatter pins per board. A warning above the Generate button shows whenever fountains are active, so they never sneak into a pack.

4

Generate & save

Pinned cells show a blue frame in the preview, and the facts panel reports "N pinned — all satisfied". Save the puzzle or a pack, then play it in the demo's Network mode.

Code start

using SimpleConnect;

var settings = new GenerationSettings {
    Width = 7, Height = 7,
    Shape = GridShape.Hex,        // or GridShape.Square
    PairCount = 0,                // 0 = auto-pick a sensible count
    TargetCoverage = 0.9f,        // how much of the board the lines fill
    RequireUnique = true,
    // Fill defaults to CoverAll (fill the board). Set Fill = FillRule.Connect
    // for Strict lines (no self-touch, gaps allowed).
};

// One verified puzzle (uniqueness-checked):
ConnectPuzzleData puzzle = ConnectGenerator.GenerateVerified(settings);

// A pack of N (deterministic per seed):
List<ConnectPuzzleData> pack = ConnectGenerator.GenerateBatch(settings, 10);

// Off the main thread, with progress (ideal behind a loading screen):
var levels = await ConnectGenerator.GenerateBatchAsync(settings, 10,
    new System.Progress<int>(done => Debug.Log($"{done}/10")));

Network puzzles

var networkSettings = new NetworkGenerationSettings {
    Width = 9, Height = 9,
    Coverage = 0.9f,              // 1 = full grid; less scatters holes to weave around
    Branchiness = 0.5f,           // 0 = corridors, 1 = bushy
    DegreeBias = 0.4f,            // extra appetite for T/cross junctions
    RandomFountains = 2,          // scatter 2 exact-degree pins per board
    // AllowLoops = true,         // weld redundant routes (verdict stays honest)
    // MaxDeadEnds = 0,           // seal every tip: closed plumbing, no terminals
};
networkSettings.Fountains.Add(new Fountain(4, 4, 4));  // pin the centre as a 4-way feed

NetworkPuzzleData network = NetworkGenerator.GenerateVerified(networkSettings);
// network.IsUnique, network.Difficulty, network.FountainsSatisfied()

Playing a puzzle

A pipe for pair i is the path the player has drawn from its A endpoint: pipes[i] = [A, …]. Feed the set of pipes to the stateless rules API:

// Legal move for the active pair? (in bounds, not a wall, adjacent to the
// line's head, no crossing; Strict lines also forbid self-touch)
bool ok  = ConnectRules.IsLegalStep(puzzle, pipes, pairId, nextCell);

// Solved? (every pair joined end-to-end, no overlaps, board covered when required)
bool won = ConnectRules.IsSolved(puzzle, pipes);

For the rotate modes, the ready-made brains live in the demo assembly (SimpleConnect.Demo): NetworkGame.Load(puzzle, seed) scrambles every tile's rotation from a seed, Rotate(cell) is a tap, and Solved flips when every edge is mutual and the network is one connected piece. Or read the masks straight off NetworkPuzzleData (MaskAt / DegreeAt) and build your own.

TipTo see it wired end to end, open the demo scene (Demos) and read LevelGame + ConnectRules for draw mode, or NetworkGame + NetworkController for rotate.

Next steps