FAILURE MAP
← Case archive

FA-86381 / Procedural level generation constraints / Open access

Level reachability flood fill: Doors are treated as walls · case 01

Rooms behind doors are reported unreachable.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The blocking test includes doors.

THE FAILURE

The blocking test includes doors.

Unsuccessful approach: Making doors depend on swimming still blocks non-swimmers at doors.

Case contract

grid rows of '#' wall, '.' floor, 'D' door (passable), '~' water (passable only when swim) and 'E' exit. From start [row, col], 4-neighbour flood fill. Returns {reachable: number of reached cells including start, exit: whether an E cell was reached}.

Why this case matters

Procedural generators silently emit unplayable or unfair levels when a single constraint check uses the wrong boundary, axis, neighborhood or update order; the defect is visible in exact generated geometry.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(grid, start, swim):
    h = len(grid)
    w = len(grid[0])
    sr, sc = start
    seen = {(sr, sc)}
    stack = [(sr, sc)]
    found = False
    while stack:
        r, c = stack.pop()
        if grid[r][c] == 'E':
            found = True
        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < h and 0 <= nc < w and (nr, nc) not in seen:
                t = grid[nr][nc]
                if t in '#D' or (t == '~' and not swim):
                    continue
                seen.add((nr, nc))
                stack.append((nr, nc))
    return {'reachable': len(seen), 'exit': found}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1', [['.E..', '.D..'], [0, 1], True], {'reachable': 8, 'exit': True}),
  ('fault site door passability #2',
   [['~.D#.', 'D....', '#.D#E'], [1, 4], True],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #1',
   [['D.~E.', '#~~.#', 'DD...'], [2, 3], False],
   {'reachable': 8, 'exit': True}),
  ('regression door passability #2',
   [['.##.', '.D#D', 'D...', '.D~.', '.#DE', '.~#.', '.~DD'], [3, 0], False],
   {'reachable': 20, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.'], [1, 0], False], {'reachable': 2, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1',
   [['~.D#.', 'D....', '#.D#E'], [1, 4], True],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #1',
   [['D.~E.', '#~~.#', 'DD...'], [2, 3], False],
   {'reachable': 8, 'exit': True}),
  ('regression door passability #2',
   [['.##.', '.D#D', 'D...', '.D~.', '.#DE', '.~#.', '.~DD'], [3, 0], False],
   {'reachable': 20, 'exit': True}),
  ('regression door passability #3',
   [['..', '.E', 'DD', '.#', '..', '.~', '..'], [6, 0], False],
   {'reachable': 12, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.'], [1, 0], False], {'reachable': 2, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1', [['E.D.', '...D'], [1, 0], True], {'reachable': 8, 'exit': True}),
  ('regression door passability #1',
   [['.##.', '.D#D', 'D...', '.D~.', '.#DE', '.~#.', '.~DD'], [3, 0], False],
   {'reachable': 20, 'exit': True}),
  ('regression door passability #2',
   [['~D.E..~', '.......'], [1, 5], False],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #3', [['E.D..'], [0, 3], False], {'reachable': 5, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.'], [1, 0], False], {'reachable': 2, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('regression door passability #1',
   [['..', '.E', 'DD', '.#', '..', '.~', '..'], [6, 0], False],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #2',
   [['~D.E..~', '.......'], [1, 5], False],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #3',
   [['.', 'E', 'D', '~', '~'], [1, 0], False],
   {'reachable': 3, 'exit': True}),
  ('regression door passability #4', [['....D', 'D...E'], [1, 4], False], {'reachable': 10, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.', '.', '.', '~'], [2, 0], True], {'reachable': 5, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1',
   [['#D~..', '.#D.~', '.#...', '....D', 'DD#..', '.D.~#', '~~E.D'], [0, 3], True],
   {'reachable': 30, 'exit': True}),
  ('regression door passability #1', [['E.D..'], [0, 3], False], {'reachable': 5, 'exit': True}),
  ('regression door passability #2',
   [['.D.~', 'E~.D', '~D..'], [0, 0], False],
   {'reachable': 9, 'exit': True}),
  ('regression door passability #3', [['.E...#', '...~.D'], [0, 0], False], {'reachable': 10, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['~.#D##E'], [0, 6], False], {'reachable': 1, 'exit': True})]]
for label, args, expected in cases[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
door corridor #1{'exit': False, 'reachable': 1}{'exit': True, 'reachable': 3}Failed
fault site door passability #1{'exit': True, 'reachable': 7}{'exit': True, 'reachable': 8}Failed
fault site door passability #2{'exit': True, 'reachable': 9}{'exit': True, 'reachable': 12}Failed
regression door passability #1{'exit': True, 'reachable': 6}{'exit': True, 'reachable': 8}Failed
regression door passability #2{'exit': False, 'reachable': 4}{'exit': True, 'reachable': 20}Failed
diagonal gap only #1{'exit': False, 'reachable': 1}{'exit': False, 'reachable': 1}Passed
walled-in start #1{'exit': True, 'reachable': 2}{'exit': True, 'reachable': 2}Passed
control #1{'exit': True, 'reachable': 2}{'exit': True, 'reachable': 2}Passed

SHA-256 / 6950689bd55eb9ccb1a814f583dc86f4da8aa9f67c77a350eafd015c3a4f4677

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(grid, start, swim):
    h = len(grid)
    w = len(grid[0])
    sr, sc = start
    seen = {(sr, sc)}
    stack = [(sr, sc)]
    found = False
    while stack:
        r, c = stack.pop()
        if grid[r][c] == 'E':
            found = True
        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < h and 0 <= nc < w and (nr, nc) not in seen:
                t = grid[nr][nc]
                if t == '#' or t == 'D' and not swim or (t == '~' and not swim):
                    continue
                seen.add((nr, nc))
                stack.append((nr, nc))
    return {'reachable': len(seen), 'exit': found}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1', [['.E..', '.D..'], [0, 1], True], {'reachable': 8, 'exit': True}),
  ('fault site door passability #2',
   [['~.D#.', 'D....', '#.D#E'], [1, 4], True],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #1',
   [['D.~E.', '#~~.#', 'DD...'], [2, 3], False],
   {'reachable': 8, 'exit': True}),
  ('regression door passability #2',
   [['.##.', '.D#D', 'D...', '.D~.', '.#DE', '.~#.', '.~DD'], [3, 0], False],
   {'reachable': 20, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.'], [1, 0], False], {'reachable': 2, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1',
   [['~.D#.', 'D....', '#.D#E'], [1, 4], True],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #1',
   [['D.~E.', '#~~.#', 'DD...'], [2, 3], False],
   {'reachable': 8, 'exit': True}),
  ('regression door passability #2',
   [['.##.', '.D#D', 'D...', '.D~.', '.#DE', '.~#.', '.~DD'], [3, 0], False],
   {'reachable': 20, 'exit': True}),
  ('regression door passability #3',
   [['..', '.E', 'DD', '.#', '..', '.~', '..'], [6, 0], False],
   {'reachable': 12, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.'], [1, 0], False], {'reachable': 2, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1', [['E.D.', '...D'], [1, 0], True], {'reachable': 8, 'exit': True}),
  ('regression door passability #1',
   [['.##.', '.D#D', 'D...', '.D~.', '.#DE', '.~#.', '.~DD'], [3, 0], False],
   {'reachable': 20, 'exit': True}),
  ('regression door passability #2',
   [['~D.E..~', '.......'], [1, 5], False],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #3', [['E.D..'], [0, 3], False], {'reachable': 5, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.'], [1, 0], False], {'reachable': 2, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('regression door passability #1',
   [['..', '.E', 'DD', '.#', '..', '.~', '..'], [6, 0], False],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #2',
   [['~D.E..~', '.......'], [1, 5], False],
   {'reachable': 12, 'exit': True}),
  ('regression door passability #3',
   [['.', 'E', 'D', '~', '~'], [1, 0], False],
   {'reachable': 3, 'exit': True}),
  ('regression door passability #4', [['....D', 'D...E'], [1, 4], False], {'reachable': 10, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['E', '.', '.', '.', '~'], [2, 0], True], {'reachable': 5, 'exit': True})],
 [('door corridor #1', [['.DE'], [0, 0], False], {'reachable': 3, 'exit': True}),
  ('fault site door passability #1',
   [['#D~..', '.#D.~', '.#...', '....D', 'DD#..', '.D.~#', '~~E.D'], [0, 3], True],
   {'reachable': 30, 'exit': True}),
  ('regression door passability #1', [['E.D..'], [0, 3], False], {'reachable': 5, 'exit': True}),
  ('regression door passability #2',
   [['.D.~', 'E~.D', '~D..'], [0, 0], False],
   {'reachable': 9, 'exit': True}),
  ('regression door passability #3', [['.E...#', '...~.D'], [0, 0], False], {'reachable': 10, 'exit': True}),
  ('diagonal gap only #1', [['.#', '#E'], [0, 0], False], {'reachable': 1, 'exit': False}),
  ('walled-in start #1', [['#.#', '#E#'], [0, 1], True], {'reachable': 2, 'exit': True}),
  ('control #1', [['~.#D##E'], [0, 6], False], {'reachable': 1, 'exit': True})]]
for label, args, expected in cases[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
door corridor #1{'exit': False, 'reachable': 1}{'exit': True, 'reachable': 3}Failed
fault site door passability #1{'exit': True, 'reachable': 8}{'exit': True, 'reachable': 8}Passed
fault site door passability #2{'exit': True, 'reachable': 12}{'exit': True, 'reachable': 12}Passed
regression door passability #1{'exit': True, 'reachable': 6}{'exit': True, 'reachable': 8}Failed
regression door passability #2{'exit': False, 'reachable': 4}{'exit': True, 'reachable': 20}Failed
diagonal gap only #1{'exit': False, 'reachable': 1}{'exit': False, 'reachable': 1}Passed
walled-in start #1{'exit': True, 'reachable': 2}{'exit': True, 'reachable': 2}Passed
control #1{'exit': True, 'reachable': 2}{'exit': True, 'reachable': 2}Passed

SHA-256 / 1ff8eedf54953b76209c2303c0dc60fc1e13f7abd17bc7314b450e8a1616ccde

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

Deterministic toy contract stipulated for this model; integer or exact arithmetic only, not a reproduction of any specific game engine. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:48.952311+00:00.

Case digest / e29bd5cbefb1db21e7c19e0ddeeac3de38e49d3392e9743162b2a7cc2b2b1b4f