Piranesi #3


How to build tools for Unity

Unity is an incredibly powerful game engine, but building custom editor UIs can be a real pain.

A webapp

I decided to try a data-driven approach: vibe-code the labyrinth generator in Javascript, export the map as JSON, and import it into Unity.

A component

The Unity component reads the JSON and places objects accordingly. It also decides which doors to block or show, so I don’t have to design a million pieces. Stole that idea from Lethal Company’s facility doors.

MST Algorithm

An MST (Minimum Spanning Tree) algorithm finds the cheapest way to connect all nodes in a graph without creating cycles. Think of it like connecting cities with roads using the least amount of pavement possible.

Nodes-First

I start by placing rooms on a grid, then use MST to figure out which rooms should connect. But MST only tells me what to connect—not how to draw the hallways between them. That’s where A* pathfinding comes in.

Here’s the process:

  1. Place rooms on the grid
  2. Use MST to determine which rooms connect
  3. Use A* to draw actual hallways between them

”Connectedness” slider

I modified the MST algorithm with a slider that controls how “expensive” connections can be:

  • 100% = Rooms connect to their nearest neighbors (cheap, compact)
  • 0% = Rooms connect to distant nodes (expensive, sprawling)

This creates a problem: sometimes hallways need to pass through other rooms. That’s impossible with flat geometry… unless I add verticality.

Deadly Stairs

The only enemy in the labyrinth is the tide—rising water that floods the lower levels. I wanted to make some areas more dangerous by forcing players into confined, maze-like spaces below ground level.

When the water rises, you need to find high ground (a room) to survive.

Piecing together a seamless labyrinth

Placing rooms, running pathfinding—that’s the easy part. The hard part is making a seamless interior that feels cohesive, not like a bunch of disconnected pieces.

This was the most important step: measuring everything precisely so I could stylize it later without gaps or overlaps.

Filling out the rooms

Fish, statues, urns, and journals

I vibe-coded a “Room Designer” tool—an infinite canvas where I can drag objects around and preview what gets placed in-engine.

There are four things that generate randomly:

  • Statues — the photo-snappable objectives
  • Urns — decorative fakes to throw you off
  • Journals — mysterious lore books
  • Fish — food (you gotta eat something)

Making them prefabs

I added prefabs for each object type, wrote some JSON parsing, and… voilà:

Next steps

There’s still a lot to do with just the labyrinth alone—not to mention the hunger mechanic, the shopkeeper, multiplayer (someday), and the tide itself. Making games is hard!

I need to steel myself and stop polishing the labyrinth until I have a hunger system working. Gotta get my head out of the gutter.