Mathematical model of level generation

This document organizes the mathematics of the dungeon generator around one simple question: how do we build a map that is spatially valid, connected and interesting to explore?

The answer has three parts. First we define rooms and corridors in the plane. Then we represent the connections as a graph and measure its topology. Finally we choose which properties must be mandatory and which are only preferences.

This is the mathematical specification behind Tapiti's generator. Since the Rust implementation does not cover every idea of the model, the text distinguishes the reference model, the current behavior of the crate and the proposed extensions.

1. The problem in one sentence

A level is a network of rooms and passages, placed in space, that must respect geometric constraints and offer an exploration experience with a desired structure.

We use the following representation:

๐’Ÿ=(H,ฯ†,ฮฑ,ฮ›) \mathcal D = (H, \varphi, \alpha, \Lambda)

  • H=(V,E)H=(V,E)โ€‹ is the navigable graph: vertices are rooms or junctions; edges are corridor stretches between those points.
  • ฯ†\varphiโ€‹ is the geometric realization: it says where the rooms are and where the corridors run.
  • ฮฑ\alphaโ€‹ assigns roles to parts of the level, such as start, stairs, prize or ambush.
  • ฮ›\Lambdaโ€‹ gathers the generator's parameters, such as dimensions, clearances, shape weights and density.

The current generator builds a connected 2D floor. The representation separates topology โ€” what connects to what โ€” from geometry โ€” how those connections fit in the plane. This separation allows specifying the shape of a network without requiring it to already have coordinates.

Vocabulary and status

In this text, reference model identifies concepts preserved from the original mathematical specification; current crate indicates what exists in this Rust implementation; proposal identifies an extension not yet implemented. Topology profiles, keys, switches and exploration pacing are now part of the crate; multi-floor campaigns and mission objectives remain proposals.

2. Basic notation

SymbolMeaning
โ„2\mathbb R^2โ€‹the floor plane, in pixels
SiโŠ‚โ„2S_i\subset\mathbb R^2โ€‹region occupied by room iiโ€‹
โˆ‚Si\partial S_iโ€‹outline of room iiโ€‹
distโก(A,B)\operatorname{dist}(A,B)โ€‹smallest Euclidean distance between two sets
wwโ€‹corridor width
ฯƒ\sigmaโ€‹minimum clearance between regions that do not connect
โ„“s\ell_sโ€‹minimum length of the straight stretch right after a door
โ„“seg\ell_{seg}โ€‹minimum length of a corridor segment
โ„“min\ell_{min}โ€‹desired minimum distance between connected rooms
โŒŠxโŒ‹\lfloor x\rfloorโ€‹greatest integer less than or equal to xxโ€‹

A clearance is a distance between region borders, not between their centers. For example, requiring distโก(Si,Sj)โ‰ฅ2g\operatorname{dist}(S_i,S_j)\geq 2gโ€‹ means there are at least 2g2gโ€‹ pixels of space between the outlines of the two rooms.

3. Room geometry

3.1 Direction alphabet

Doors and corridor segments use a discrete set of directions:

ฮ˜m={2ฯ€km:k=0,โ€ฆ,mโˆ’1},mโˆˆ{4,8}. \Theta_m=\left\{\frac{2\pi k}{m}: k=0,\ldots,m-1\right\}, \qquad m\in\{4,8\}.

With m=4m=4โ€‹, the directions are horizontal and vertical. With m=8m=8โ€‹, the 45ยฐ diagonals are added. We call the first case rectilinear and the second octilinear.

A free curve could join any two points, but discrete directions make passages more predictable and make it easier to test their width and intersections. This is a deliberate simplification of the model.

3.2 Shape classes

Each room occupies a region SiS_iโ€‹ of a class ฮบi\kappa_iโ€‹:

๐’ฎ={๐—‹๐–พ๐–ผ๐—,๐–ฝ๐—‚๐—Œ๐–ผ,๐—ˆ๐–ผ๐—,๐–ซ,๐—Œ๐—๐–บ๐—‹}. \mathcal S=\{\textsf{rect},\textsf{disc},\textsf{oct},\textsf{L},\textsf{star}\}.

ClassMain parametersArea or construction
Rectanglewidth WWโ€‹, height HHโ€‹WHWHโ€‹
Discradius ฯ\rhoโ€‹ฯ€ฯ2\pi\rho^2โ€‹
Octagoncircumradius ฯ\rhoโ€‹4ฯ2sinโก(ฯ€/4)4\rho^2\sin(\pi/4)โ€‹
Lbox Wร—HW\times Hโ€‹, notch aร—ba\times bโ€‹, corner ccโ€‹WHโˆ’abWH-abโ€‹
Truncated starnumber of points nnโ€‹, radii and top width ฯ„\tauโ€‹computed by the polygon (shoelace) formula

A star has its points cut off. Without the cut, each point would be just a vertex and there would be no suitable stretch of edge to open a straight door.

In the reference model, a room is fitted into a usable rectangle ฮฒ\betaโ€‹ by a function

fitฮบโก(ฮฒ,ฮพ)โ†’SโІฮฒ, \operatorname{fit}_{\kappa}(\beta,\xi)\to S\subseteq\beta,

where ฮพ\xiโ€‹ represents random choices such as proportions and orientation. In the crate, the blocks of the scaffold also limit where rooms can be placed.

To keep doors aligned with the alphabet, the reference specification restricts the rotations of shapes to ฯ†โˆˆฮ˜m\varphi\in\Theta_mโ€‹. This is a modeling choice: continuous rotations would require also accepting walls whose normals do not belong to the corridor alphabet.

4. Doors and room capacity

A door is a pair p=(x,ฮธ)p=(x,\theta)โ€‹: the point xxโ€‹ on the room's outline and the direction ฮธ\thetaโ€‹ in which the corridor leaves.

On a polygon edge, not every point is admissible. The door must stay away from the corners and its exit must not cross the room itself. We define the inset

ฮน=w2+ฯƒ. \iota=\frac{w}{2}+\sigma.

For an edge of length LLโ€‹, the admissible points initially lie in the interval [ฮน,Lโˆ’ฮน][\iota,L-\iota]โ€‹. In the mathematical model, any point of that interval can be chosen; the implementation samples positions in portStep steps and also adjusts doors when it resolves some intersections.

A door's exit strip can be represented as

F(x,ฮธ)={x+su(ฮธ)+ru(ฮธ+ฯ€2):0โ‰คsโ‰คโ„“s, |r|โ‰คw/2}, F(x,\theta)=\{x+s\,u(\theta)+r\,u(\theta+\tfrac\pi2): 0\leq s\leq\ell_s,\ |r|\leq w/2\},

where u(ฮธ)=(cosโกฮธ,sinโกฮธ)u(\theta)=(\cos\theta,\sin\theta)โ€‹. Intuitively, FFโ€‹ is the rectangle the corridor occupies right after leaving the wall.

Two doors used in the same room must keep their strips apart:

distโก(F(pi),F(pj))โ‰ฅฯƒ(iโ‰ j). \operatorname{dist}(F(p_i),F(p_j))\geq\sigma\quad(i\ne j).

We call capacity of the room the largest number of doors that satisfies this condition:

capโก(S)=maxโก{|U|:U is a set of admissible, separated doors}. \operatorname{cap}(S)=\max\{|U|: U\text{ is a set of admissible, separated doors}\}.

For an edge with an admissible interval of length ฮป\lambdaโ€‹, the limit is โŒŠฮป/(w+ฯƒ)โŒ‹+1\lfloor\lambda/(w+\sigma)\rfloor+1โ€‹. On a disc of radius ฯ\rhoโ€‹ with equally spaced doors, the distance between neighboring positions is the chord 2ฯsinโก(ฯ€/q)2\rho\sin(\pi/q)โ€‹; all qqโ€‹ doors fit if that chord is at least w+ฯƒw+\sigmaโ€‹. This computation shows why the radius limits the number of doors, even when the parameter asks for more directions.

For example, on the same straight side, two doors cannot be closer than roughly w+ฯƒw+\sigmaโ€‹. Capacity therefore depends both on the room's size and on the corridors' width.

5. Corridors

5.1 A corridor as an occupied region

A corridor is made of connected segments. Each segment follows a direction in ฮ˜m\Theta_mโ€‹ and has a length of at least โ„“seg\ell_{seg}โ€‹. The segment leaving a door must also keep the door's direction for at least โ„“s\ell_sโ€‹.

If ฮณe\gamma_eโ€‹ is the center line of a segment eeโ€‹, its occupied strip is the neighborhood of that line with radius w/2w/2โ€‹. A corridor's region is the union of the strips of its segments and of the caps at bends and junctions. Collision checks therefore compare regions, not just center lines.

Between two doors, the specification considers three kinds of route:

TypeBendsDescription
I0straight segment between aligned doors facing each other
L1two rays that meet in front of the doors
Z/U2two exit stretches joined by an intermediate segment

For example, for a straight route between (pa,ฮธa)(p_a,\theta_a)โ€‹ and (pb,ฮธb)(p_b,\theta_b)โ€‹, the doors must face each other, pbโˆ’pap_b-p_aโ€‹ must be aligned with the exit direction, and the distance must allow the two minimum stretches:

ฮธbโ‰กฮธa+ฯ€(modโก2ฯ€),(pbโˆ’pa)ร—u(ฮธa)=0,(pbโˆ’pa)โ‹…u(ฮธa)โ‰ฅ2โ„“s. \theta_b\equiv\theta_a+\pi\pmod{2\pi},\qquad (p_b-p_a)\times u(\theta_a)=0,\qquad (p_b-p_a)\cdot u(\theta_a)\geq 2\ell_s.

L and Z routes impose similar conditions of alignment, direction and minimum length for each segment. In the Rust generator, direct routes follow the same I/L/Z family, with the bend limit controlled by maxBends.

For an L route, let ua=u(ฮธa)u_a=u(\theta_a)โ€‹, ub=u(ฮธb)u_b=u(\theta_b)โ€‹, d=pbโˆ’pad=p_b-p_aโ€‹. If uaร—ubโ‰ 0u_a\times u_b\neq0โ€‹, the rays meet at the parameters

t=dร—ubuaร—ub,s=dร—uauaร—ub. t=\frac{d\times u_b}{u_a\times u_b},\qquad s=\frac{d\times u_a}{u_a\times u_b}.

The route is feasible only if t,sโ‰ฅโ„“st,s\geq\ell_sโ€‹ and the bend formed by the directions is allowed. For Z, we choose an intermediate direction u(ฮด)u(\delta)โ€‹ and solve

pbโˆ’pa=taua+tcu(ฮด)โˆ’tbub,ta,tbโ‰ฅโ„“s,tcโ‰ฅโ„“seg. p_b-p_a=t_a u_a+t_c u(\delta)-t_bu_b, \qquad t_a,t_b\geq\ell_s,\quad t_c\geq\ell_{seg}.

The minus sign appears because ubu_bโ€‹ points out of the second room; the route's last segment reaches the door in the opposite direction. There are two vector equations in three lengths: for each intermediate direction there is a family of solutions. The specification fixes one length or a ratio between stretches and solves for the others.

5.3 Junctions

A junction connects three arms (T) or four arms (X). The arms share a meeting point, which is also a vertex of the navigable graph. This representation matters for counting paths and cycles: a T junction is a bifurcation, not a triangle of passages.

The reference specification also describes a conductance ฯ‰h\omega_hโ€‹ between the arms of a junction. It can model whether two arms behave as a single space or as partly coupled regions. The junction field appears in the parameters, but is marked in the code as unused by the generator; this interpretation is therefore an extension of the space model, not an effect the current crate produces.

5.4 Cost and weight of a route

A route can be geometrically valid and still be less desirable than another. To rank candidates, we use an aesthetic cost:

C(k)=cbb(k)+cโ„“โ„“(k)+c45n45(k)โˆ’cf๐Ÿfacing doors, C(k)=c_b b(k)+c_\ell\ell(k)+c_{45}n_{45}(k) -c_f\,\mathbf 1_{\text{facing doors}},

where b(k)b(k)โ€‹ is the number of bends, โ„“(k)\ell(k)โ€‹ the length and n45(k)n_{45}(k)โ€‹ the number of 45ยฐ bends. The indicator ๐Ÿ\mathbf 1โ€‹ is 1 when the condition is true and 0 when it is not.

The cost does not decide validity. Among valid candidates, the weight is

ฯ‰(k)=Mฮบaฮบbptype(k)eโˆ’C(k), \omega(k)=M_{\kappa_a\kappa_b}\,p_{type(k)}\,e^{-C(k)},

where MMโ€‹ is the compatibility between the room classes and ptype(k)p_{type(k)}โ€‹ is the weight of the route type. A zero weight forbids the link; a larger weight raises its chance in a weighted choice. This is the mechanism used to vary choices without abandoning the geometric constraints.

6. Navigable graph

6.1 The representation used for topology

The refined graph of the level is

H=(V,E),V=RโˆชJ, H=(V,E),\qquad V=R\cup J,

where RRโ€‹ is the set of rooms, JJโ€‹ the set of junctions, and each edge in EEโ€‹ is a corridor arm between a room and a junction, two junctions or two rooms. The graph may have parallel edges: two physically distinct passages between the same vertices remain two edges.

We use HHโ€‹ as the main representation for connectivity, cycles and independent routes. A projection that links every room of a junction to all the other rooms of that junction may be useful for certain "hops between rooms" measures, but it creates artificial connections if used to count cycles.

Example. Three rooms joined by a single T junction form a tree in HHโ€‹: three arms and three rooms, no cycle. If we project the T as links between every pair of rooms, a triangle appears. That triangle does not correspond to three independent passages; all of them use the same junction. This is why the clique expansion must not be used to compute ฮฒ\betaโ€‹ or edge-disjoint routes.

6.2 Connectivity

A connected level has a path between any pair of rooms. If c(H)c(H)โ€‹ is the number of connected components, the general condition is c(H)=1c(H)=1โ€‹ for a floor that contains a single playable region.

A bridge is an edge whose removal disconnects the graph. An articulation vertex is a vertex whose removal disconnects it. These two structures identify bottlenecks: places exploration has to pass through.

6.3 Number of cycles

The number of independent cycles, also called the cyclomatic number, is

ฮฒ(H)=|E|โˆ’|V|+c(H). \beta(H)=|E|-|V|+c(H).

For a connected floor, ฮฒ=|E|โˆ’|V|+1\beta=|E|-|V|+1โ€‹. A tree has ฮฒ=0\beta=0โ€‹. Adding a link between two already connected points raises ฮฒ\betaโ€‹ by 1.

Example. The path room A โ€” room B โ€” room C has 3 vertices and 2 edges, so ฮฒ=2โˆ’3+1=0\beta=2-3+1=0โ€‹. Adding a passage between A and C gives 3 edges and 3 vertices; then ฮฒ=3โˆ’3+1=1\beta=3-3+1=1โ€‹, corresponding to one independent cycle.

If HHโ€‹ is planar and connected, Euler's formula gives |V|โˆ’|E|+|F|=2|V|-|E|+|F|=2โ€‹. Hence ฮฒ=|F|โˆ’1\beta=|F|-1โ€‹: it is the number of bounded faces of the drawing. This interpretation depends on planarity; the cyclomatic number remains defined even when the face reading is not used.

6.4 Cycles do not guarantee alternative routes to the exit

The number of cycles describes the whole network, but not where the cycles are. To measure independent routes between start ssโ€‹ and stairs ttโ€‹, we use

ฮปH(s,t)=maximum number of paths from s to t that share no edges. \lambda_H(s,t)=\text{maximum number of paths from }s\text{ to }t \text{ that share no edges}.

By Menger's theorem, this number is also the minimum size of a set of edges whose removal separates ssโ€‹ from ttโ€‹.

So ฮฒ(H)>0\beta(H)>0โ€‹ does not imply ฮปH(s,t)>1\lambda_H(s,t)>1โ€‹. For example, consider the path sโˆ’aโˆ’ts-a-tโ€‹ and a wing in a cycle aโˆ’bโˆ’cโˆ’aa-b-c-aโ€‹. The graph has 5 vertices and 5 edges, so ฮฒ=5โˆ’5+1=1\beta=5-5+1=1โ€‹, but every route from ssโ€‹ to ttโ€‹ still uses the edge aโˆ’ta-tโ€‹: ฮปH(s,t)=1\lambda_H(s,t)=1โ€‹. By contrast, two routes sโˆ’aโˆ’ts-a-tโ€‹ and sโˆ’bโˆ’ts-b-tโ€‹ have ฮฒ=1\beta=1โ€‹ and ฮปH(s,t)=2\lambda_H(s,t)=2โ€‹. The level profile must specify "how many cycles exist" and "how many routes reach the exit" separately.

Other useful measures include:

MeasureDefinitionWhat it describes
Room distance droom(s,t)d_{room}(s,t)โ€‹shortest path counting each arrival at a room as 1 and passing through a junction as 0length of the main route in rooms crossed
Geometric distance dgeom(s,t)d_{geom}(s,t)โ€‹smallest sum of corridor lengths between start and exitminimum physical walk
Diameterlargest minimum distance between pairs of roomsperceived global size
Girth g(H)g(H)โ€‹size of the smallest cycle (defined as +โˆž+\inftyโ€‹ if there is no cycle)presence of short cycles
Degree d(v)d(v)โ€‹number of edges incident to vvโ€‹local number of options
Articulations and bridgesvertices/edges whose removal disconnects HHโ€‹structural bottlenecks
ฮปH(s,t)\lambda_H(s,t)โ€‹edge-disjoint routes between start and exitredundancy of the final route
ฮป2\lambda_2โ€‹second smallest eigenvalue of the Laplacian L=Dโˆ’AL=D-Aโ€‹global connectivity, in aggregate

6.5 When a level is valid

The constraints below separate different problems. Connectivity is about the network; clearance is about geometry; accessibility is about the game rules.

  • V1 โ€” Connectivity. All relevant navigable vertices belong to the same component of HHโ€‹.
  • V2 โ€” Clearances. Rooms keep the minimum distance 2g2gโ€‹; a corridor stays at least ฯƒ\sigmaโ€‹ from the rooms it does not connect to; two separate corridors keep the clearance, except at a valid junction. Between linked rooms, the direct distance โ„“min\ell_{min}โ€‹ is also required, so that rooms close to each other diagonally do not become nearly adjacent despite a long path.
  • V3 โ€” Doors. Each used door is admissible for its room, and the exit strips of the doors of the same room are separated by at least ฯƒ\sigmaโ€‹.
  • V4 โ€” Corridors. Directions, bends and lengths respect ฮ˜m\Theta_mโ€‹, โ„“s\ell_sโ€‹, โ„“seg\ell_{seg}โ€‹ and the bend limit.
  • V5 โ€” Start and exit. There is a start room and a distinct stairs room; the stairs respect the door limit and are at least minHops room hops from the start.
  • V6 โ€” Furniture. In the original specification, stones and crystals must also stay out of the exit strips and keep their distance from each other. This step belongs to the game's furniture and is not implemented by this crate's geometric generator.

A level must satisfy all the constraints that apply to its scope. A lower aesthetic cost cannot compensate for a violation of V1โ€“V5.

7. Cycle density

To normalize the number of cycles, the specification defines a reference ฮฒref\beta_{ref}โ€‹ and a density:

ฮดtarget={ฮฒโˆ—/ฮฒref,ฮฒref>0,0,ฮฒref=0.0โ‰คฮดtargetโ‰ค1. \delta_{target}= \begin{cases} \beta^*/\beta_{ref}, & \beta_{ref}>0,\\ 0, & \beta_{ref}=0. \end{cases} \qquad 0\leq\delta_{target}\leq1.

In the interface and in the code, this reference may appear under the name betaMax. The name must be read carefully: the value is obtained by a greedy strategy that adds the highest-weight valid actions until no options remain. This produces a maximal reference of the heuristic, not a proof of the global maximum among all possible configurations.

The target is rounded from ฮดtargetฮฒref\delta_{target}\beta_{ref}โ€‹. For example, if ฮฒref=8\beta_{ref}=8โ€‹ and ฮดtarget=0.25\delta_{target}=0.25โ€‹, the target will be about 2 cycles. The realized density is ฮดreal=ฮฒ(H)/ฮฒref\delta_{real}=\beta(H)/\beta_{ref}โ€‹ when ฮฒref>0\beta_{ref}>0โ€‹; it may differ from the target because of rounding, because an X action adds two cycles, or because ฮฒref\beta_{ref}โ€‹ comes from a heuristic, not a proven maximum. In some cases, ฮดreal\delta_{real}โ€‹ can even exceed 1. The target controls the approximate quantity; topology profiles are needed to control the location and function of those cycles.

For a connected graph, the average degree satisfies

โŸจdโŸฉ=2|E||V|=2(|V|โˆ’1+ฮฒ)|V|. \langle d\rangle=\frac{2|E|}{|V|} =\frac{2(|V|-1+\beta)}{|V|}.

This identity relates the number of cycles to the average degree, but does not determine the layout of the network.

8. Generation in the reference model

The process can be understood as six steps. The original specification describes this sequence; the Rust crate implements a variant, summarized in section 12.

  1. Scaffold. Create a grid of Cร—RgC\times R_gโ€‹ cells and combine them into blocks. Some cells may be dropped, as long as the remaining blocks stay connected.
  2. Rooms. Draw a shape class for each block and fit the region into the usable space, respecting limits and clearances.
  3. Candidates. Choose pairs of rooms to consider; for each pair, look for feasible doors and routes.
  4. Conflicts. Mark pairs of candidates that cannot coexist because of geometric collision or doors that are too close.
  5. Tree and cycles. First connect the rooms with a spanning tree. Then add links between already connected points until approaching the ฮฒ\betaโ€‹ target.
  6. Leaf rooms and roles. Use dropped cells for degree-1 rooms and assign roles such as start, stairs, prize or trap.

A tree guarantees connectivity without cycles. The second phase adds alternatives without removing existing connections.

8.1 Mixing room classes

A class distribution can consider both the block size and the classes of the neighboring blocks. Let N(i)N(i)โ€‹ be the set of blocks adjacent to iiโ€‹, nin_iโ€‹ the number of cells of iiโ€‹, and nฮบ(i)n_\kappa(i)โ€‹ how many neighbors have class ฮบ\kappaโ€‹. The sampling rule is

P(ฮบi=ฮบโˆฃฮบN(i))โˆwฮบ(ni)expโก(hnฮบ(i)). P(\kappa_i=\kappa\mid\kappa_{N(i)}) \propto w_\kappa(n_i)\exp\bigl(h\,n_\kappa(i)\bigr).

The weight wฮบ(ni)w_\kappa(n_i)โ€‹ can, for example, forbid stars in small blocks. The parameter hhโ€‹ controls homophily: h>0h>0โ€‹ favors neighbors of the same class; h<0h<0โ€‹ favors different classes. In the crate, this rule is sampled in four sweeps and then the maxOf quotas are applied.

8.2 Candidate room pairs

The reference specification considers proximity graphs built from the room centers:

  • RNG: a link between iiโ€‹ and jjโ€‹ is removed if another room is closer to both;
  • Gabriel: a link is removed if another room falls inside the disc whose diameter is the segment between the centers of iiโ€‹ and jjโ€‹;
  • Bounded Delaunay: consider Delaunay neighbors up to a maximum distance.

If cic_iโ€‹ is the center of room iiโ€‹ and dij=โˆฅciโˆ’cjโˆฅ2d_{ij}=\|c_i-c_j\|^2โ€‹, the RNG test keeps {i,j}\{i,j\}โ€‹ when there is no kkโ€‹ with maxโก(dik,djk)<dij\max(d_{ik},d_{jk})โ€‹. The Gabriel test keeps the link when there is no kkโ€‹ with โˆฅckโˆ’(ci+cj)/2โˆฅ2<dij/4\|c_k-(c_i+c_j)/2\|^2โ€‹. The Near variant used in the crate keeps pairs with โˆฅciโˆ’cjโˆฅโ‰คr\|c_i-c_j\|\leq rโ€‹.

These filters control which pairs enter the search. They do not by themselves guarantee that the rooms can be connected: doors and corridors without collisions must still be found.

8.3 Conflict graph

Let ๐’ž\mathcal Cโ€‹ be the set of candidate links. We build a conflict graph X=(๐’ž,FX)X=(\mathcal C,F_X)โ€‹, in which two candidates are joined in FXF_Xโ€‹ when they cannot be chosen together.

A conflict-free selection is an independent set of XXโ€‹. To form a connected level, we also require the selection to build a connected navigable graph. This formulation separates two questions:

  1. is each link valid on its own?
  2. can the chosen links coexist?

8.4 Tree, cycles and leaf rooms

The crate chooses a start room and grows a spanning tree. At each step, a candidate link must connect an already reached room to a new room. The choice is weighted by the candidates' weights. If the current list does not allow progress, the generator widens the set of proximity pairs and tries to continue.

After connecting the rooms, the generator builds a betaMax reference by filling a copy of the graph with the highest-weight valid actions. This search considers direct links and T/X junction actions. The reference is greedy: it depends on earlier choices and does not prove the global maximum.

In the real cycles phase, the target is ฮฒโˆ—=roundโก(ฮดtargetฮฒref)\beta^*=\operatorname{round}(\delta_{target}\beta_{ref})โ€‹, where delta is the crate's parameter. Valid actions are drawn until the target is reached or exceeded, or until no actions remain. A direct or T link adds one independent cycle; an X crossing can add two, since it closes a new path and splits the crossed corridor into two branches. So ฮฒโˆ—\beta^*โ€‹ is a target, not a guarantee of exact equality.

Leaf chambers are added afterwards: each is a room linked by a single corridor. In the graph, the operation adds one vertex and one edge, so ฮ”ฮฒ=0\Delta\beta=0โ€‹. It raises the number of dead ends without raising the number of cycles. The roles of start, stairs, boss, rest, ambush, trap, prize and empty room describe content. Keys, switches and locks are progression data, separate from the labels.

In the crate, the start is chosen among the live rooms. After the tree, the stairs are chosen among the leaves farthest from the start; if the minimum distance minHops is not reached, stage may try another seed up to the attempt limit.

9. Topology profiles

The topology parameter lets you ask explicitly for a topological intent. The crate implements mandatory requirements for branches, depth, independent routes to the exit, hub degree and minimum cycle length. If the geometry does not allow a requirement to be met, the generator records the limitation and the validator points out the violation.

We represent a profile as

ฮ =(Chard,๐ญ,๐ฐ), \Pi=(C_{hard},\mathbf t,\mathbf w),

where:

  • ChardC_{hard}โ€‹ is a set of mandatory conditions;
  • ๐ญ\mathbf tโ€‹ is the vector of target values for the graph measures;
  • ๐ฐ\mathbf wโ€‹ defines the relative importance of each target.

Let ฮฆ(H)\Phi(H)โ€‹ be the vector of metrics, for example

ฮฆ(H)=(ฮฒ,&nbsp;g(H),&nbsp;ฮปH(s,t),&nbsp;droom(s,t),&nbsp;dgeom(s,t),&nbsp;bridges,articulations,degrees,branches). \Phi(H)= (\beta,\ g(H),\ \lambda_H(s,t),\ d_{room}(s,t),\ d_{geom}(s,t),\ \text{bridges},\text{articulations},\text{degrees},\text{branches}).

The feasible set contains only levels that satisfy geometric validity and the coded mandatory conditions. The crate does not yet search for the best level according to a global scoring function. The expression below formalizes a possible extension to compare metrics with targets:

Jฮ (H)=โˆ‘iwiฯi(ฮฆi(H),ti), J_{\Pi}(H)=\sum_i w_i\,\rho_i(\Phi_i(H),t_i),

where ฯi\rho_iโ€‹ penalizes the distance from the target. The mandatory constraints filter the levels; the function Jฮ J_\Piโ€‹ would rank the remaining options. This global optimization remains outside the current crate.

9.1 Example profiles

Spine with optional wings. We choose a main path PPโ€‹ from ssโ€‹ to ttโ€‹. We remove the vertices of PPโ€‹ from HHโ€‹ and examine each remaining component CCโ€‹. We define its neighborhood on the spine by

โˆ‚PC={eโˆˆE:e has one end in C and the other in V(P)}. \partial_P C=\{e\in E:e\text{ has one end in }C\text{ and the other in }V(P)\}.

If |โˆ‚PC|=1|\partial_P C|=1โ€‹, CCโ€‹ is a simple side branch: a single edge links the component to the spine. If |โˆ‚PC|โ‰ฅ2|\partial_P C|\geq2โ€‹, CCโ€‹ offers a detour that returns to the spine โ€” a shortcut or cycle, not a simple branch. We count edges, not just contact vertices: two parallel passages to the same vertex of PPโ€‹ already form a second link and must not be classified as a simple branch.

Two routes to the exit. Require ฮปH(s,t)โ‰ฅ2\lambda_H(s,t)\geq2โ€‹. This guarantees that no single edge is enough to separate start and exit.

Explorable loop. Require a simple cycle CโІHC\subseteq Hโ€‹ with at least LloopL_{loop}โ€‹ edges. The condition ฮฒโ‰ฅ1\beta\geq1โ€‹ alone would allow the only cycle to be very small.

Hub. Require a room or junction hhโ€‹ with degree d(h)โ‰ฅdhubd(h)\geq d_{hub}โ€‹, or favor a degree distribution that concentrates several options in one region.

Intentional bottleneck. Require a bridge or articulation at a specified stretch of the main path. This can concentrate the level's pacing, as long as progression allows crossing it.

These requirements can coexist. For example, a profile can require a long spine, two branches with rewards and two alternative routes in the final stretch.

10. Progression with keys and switches

Topology answers "which places connect?". Progression answers "when can the player cross each connection?". To model locked doors and objectives, we extend the player's state:

q=(I,S,O), q=(I,S,O),

where IIโ€‹ is the inventory, SSโ€‹ the set of activated mechanisms and OOโ€‹ the completed objectives.

An edge can be crossed only if its condition is satisfied in qqโ€‹. The crate implements masks of up to eight keys and eight switches and checks the state space of location and inventory. A key is collected on entering the room; a switch is activated on entering it.

To keep each lock meaningful even when there are shortcuts, the generator splits the graph by successive cuts of the main path and applies the condition to all the edges that cross each cut. So it is not enough to place a key before a chosen door: every path that goes past that point must satisfy the condition. The validator walks states (v,I,S)(v,I,S)โ€‹ and requires the stairs to remain reachable.

The pacing.enabled field distributes rest, boss and ambush rooms along the main path and raises the preference for prizes in optional branches. These roles describe pacing and content; they do not create mission objectives.

The same model can extend to a multi-floor campaign: we assign each room a floor index and let stair or elevator edges connect vertices on different floors. Each floor has its own geometric realization ฯ†f\varphi_fโ€‹, but connectivity and progression are checked on the joint graph. This extension is not yet implemented in this crate.

11. Model parameters

The parameters can be grouped by function. The names in parentheses are those used in the crate when there is a direct match.

GroupParametersEffect
Scaffoldcolumns, rows, cell size, inset, large blocks, dropped fraction, irregularity and rotation (cols, rows, cellW, cellH, gap, big, drop, layoutJitter, rotateRooms)scale, fragmentation and orientation of rooms; irregularity is limited to preserve the minimum size
Shapesweights and quotas per class, minimum size for a star, homophily (weights, maxOf, starCells, homophily)variety and distribution of rooms
Doorsallowed directions, number of doors on discs, sampling step (m, discPorts, portStep)positions and directions of the connections
Corridorswidth, clearance, exit stretch, minimum segment, minimum distance, maximum bends (width, clear, exit, seg, minLen, maxBends)geometry of the passages
Weightsprobabilities per route type, including the W detour, bend/length/diagonal costs (pI, pL, pZ, pW, pT, pX, costBend, costLen, cost45, costFacing)preference among valid candidates
Topologyproximity, radius, density and profile (proximity, near, delta, topology)pairs considered, cycle target and network requirements
Progressionnumber of key and switch locks (progression)crossing conditions checked in the state graph
Pacingroles distributed along the main path (pacing)contrast between advancing, resting, combat and optional exploration
Start and exitstairs door limit and minimum distance in hops (stairsDoors, minHops)topological position of the stairs
Contentnumber of ambushes and leaf chambers; allowed classes and roles (ambush, leaves, leafClasses, leafRoles)distribution of existing functions
Mixingcompatibility matrix between classes (mix)allows or discourages connections between shapes
Junctionsoptional conductance (junction)reference parameter, not yet used by the generator

The profile ฮ \Piโ€‹ complements ฮ›\Lambdaโ€‹: the parameters control how the generator operates; the profile describes the structure you want to obtain.

12. What exists in the Rust crate

This table avoids confusing the reference specification with this repository's implementation.

ConceptStatus in the crate
Rooms and geometriesRectangles, discs, octagons, L shapes and stars; placement based on a grid of blocks.
Directions and routesModes with 4 or 8 directions; I/L/Z candidates, T branches and X crossings.
Main connectionTree growth over candidate room pairs; the generator tries other proximity relations if it runs out of connections.
CyclesLater choice of cycle actions up to the target derived from delta and the betaMax reference.
Start and stairsOne start and one stairs room per floor; the stairs are chosen among distant rooms, usually leaves.
Room contentMarking of start, stairs, boss, rest, ambush, trap, prize, key, switch or empty. The labels are not a mission system.
ProximityThe Rust enum includes RNG, Gabriel and radius-based Near. Delaunay appears in the reference specification, but not in the current enum.
Topology profilesRequirements for branches, depth, independent routes, hub and minimum cycle implemented; global profile scoring not yet implemented.
Stateful progressionKeys, switches, conditional doors and reachability checking implemented; mission objectives not yet implemented.
Exploration pacingRest, boss and ambush roles on the main path and a higher preference for prizes in optional branches.
Spatial flexibilityIrregular grid limited by minimum dimensions, shape rotation and W routes of up to six bends.
Connected multiple floorsEach current generation produces a single 2D map; the progression relationship between floors is not modeled here.

In the crate, the geometric and topological checks are spread mainly across generate.rs, validate.rs and metrics.rs. The validator is the reference for deciding whether a concrete output satisfies the coded conditions.

13. Summary

The model separates three questions:

  1. Does the geometry fit? Do rooms, doors and corridors respect widths and clearances?
  2. Does the network have the desired shape? Do the cycles, branches, bottlenecks and routes to the exit match the profile?
  3. Can the level be completed? If there are progression rules, does the exit remain reachable in the right state?

This separation keeps the mathematics clear. Geometry defines what is physically possible; the graph defines the navigation structure; profiles define the level's intent. The next natural step is to express intent as conditions on HHโ€‹, without confusing the global number of cycles with the availability of alternative routes at specific points.

Edit this page on GitHub