FAILURE MAP
← Case archive

FA-86831 / Procedural level generation constraints / Open access

Aligned stair placement: Entrance read as row, column · case 01

Stairs spawn next to the entrance on non-diagonal layouts.

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

ROOT CAUSE

The entrance coordinates are swapped.

VERIFIED REPAIR

Restore `abs(x - entrance[0]) + abs(y - entrance[1])` at the entrance axes step.

Unsuccessful approach: Chebyshev distance undercounts diagonal separation.

Case contract

Scan floor_a row by row (y), then column (x); choose the first cell where floor_a[y][x] == '.', the cell exists on floor_b and is '.' there, and the Manhattan distance to entrance [x, y] is at least min_dist. Returns [x, y] or None.

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(floor_a, floor_b, entrance, min_dist):
    for y in range(len(floor_a)):
        for x in range(len(floor_a[0])):
            if floor_a[y][x] != '.':
                continue
            if y >= len(floor_b) or x >= len(floor_b[0]) or floor_b[y][x] != '.':
                continue
            if abs(x - entrance[1]) + abs(y - entrance[0]) < min_dist:
                continue
            return [x, y]
    return None
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('fault site entrance axes #1',
   [['..', '..', '#.', '.#', '#.', '.#'], ['~.~', '~~~', '~#.', '~#.', '...', '##.'], [0, 4], 4],
   [1, 0]),
  ('regression entrance axes #1',
   [['#.#', '#..', '.##', '..#'], ['~~.#..', '...#~~', '#.#..#', '.....~', '~~#.~.'], [0, 2], 3],
   [2, 1]),
  ('partial repair boundary #1',
   [['...', '.#.', '...', '..#', '###', '..#'], ['~.#.~', '##~~#', '~~#..', '.~.~.'], [2, 4], 5],
   [1, 0]),
  ('partial repair boundary #2',
   [['..##.', '.##..', '.##..'], ['..~', '.##', '..~', '...', '.##', '...'], [3, 2], 5],
   [0, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('control #1', [['#.#.', '...#'], ['...#~', '.....'], [3, 1], 4], None)],
 [('fault site entrance axes #1', [['..#..'], ['#.#~', '#...', '.~~#', '~.#.'], [2, 0], 2], None),
  ('fault site entrance axes #2',
   [['#', '.', '.', '.', '.'], ['~.~~', '...#', '~.~#', '#~.#', '.#.#', '~..#'], [0, 3], 5],
   None),
  ('regression entrance axes #1',
   [['#.#', '#..', '.##', '..#'], ['~~.#..', '...#~~', '#.#..#', '.....~', '~~#.~.'], [0, 2], 3],
   [2, 1]),
  ('regression entrance axes #2',
   [['.....#', '..#.#.', '.#..#.', '..###.', '#.#..#'], ['.#.~~#', '.#.##.', '~~#~..', '......'], [0, 3], 5],
   [2, 0]),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('control #1', [['#.#.', '...#'], ['...#~', '.....'], [3, 1], 4], None),
  ('control #2', [['.', '#', '.', '#'], ['#.....'], [0, 1], 4], None)],
 [('regression entrance axes #1',
   [['.....#', '..#.#.', '.#..#.', '..###.', '#.#..#'], ['.#.~~#', '.#.##.', '~~#~..', '......'], [0, 3], 5],
   [2, 0]),
  ('fault site entrance axes #1', [['..', '.#', '.#'], ['~.', '..'], [0, 1], 1], [1, 0]),
  ('partial repair boundary #1', [['....', '...#', '#..#', '#..#', '##..'], ['.', '~'], [2, 3], 5], [0, 0]),
  ('regression entrance axes #2', [['.....', '#.###'], ['#.~..#', '.#.~##'], [0, 1], 2], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('control #1', [['.', '#', '.', '#'], ['#.....'], [0, 1], 4], None),
  ('control #2', [['##', '.#', '#.', '.#', '.#'], ['##.', '...', '.~#'], [0, 0], 5], None)],
 [('fault site entrance axes #1', [['......', '..##.#'], ['~##.#.', '~..#.~', '~...#.'], [3, 1], 6], None),
  ('regression entrance axes #1', [['.....', '#.###'], ['#.~..#', '.#.~##'], [0, 1], 2], [1, 0]),
  ('partial repair boundary #1',
   [['..#...', '#....#', '..#...', '..#...'], ['.~#~##', '~....#'], [1, 0], 2],
   [2, 1]),
  ('partial repair boundary #2',
   [['.#', '#.', '..', '#.'], ['.~.', '~..', '..#', '..#', '.#.'], [0, 0], 4],
   [1, 3]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('control #1',
   [['...##.', '..#.#.', '..#...', '#.....', '#.....'], ['#', '.', '.', '~'], [0, 2], 1],
   [0, 1]),
  ('control #2',
   [['#....', '..#..', '#...#', '#..#.', '.#.#.', '.#.#.'],
    ['#~..', '..~.', '..~.', '..#.', '##~~'],
    [1, 4],
    1],
   [2, 0])],
 [('fault site entrance axes #1', [['.#.#.', '..#..'], ['..~#.'], [2, 1], 5], None),
  ('fault site entrance axes #2', [['..', '..', '..', '#.', '..'], ['.', '.', '.'], [0, 3], 4], None),
  ('partial repair boundary #1',
   [['.#...#', '...##.', '...#..', '....#.', '..#..#', '......'],
    ['~..', '...', '#..', '...', '##~', '~##'],
    [3, 2],
    4],
   [0, 1]),
  ('partial repair boundary #2', [['....', '..##', '#.#.', '..##'], ['..~.~~', '~..#.#'], [3, 2], 5], [0, 0]),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('control #1', [['..', '##'], ['.', '.', '~', '~', '.'], [1, 0], 6], None),
  ('control #2',
   [['.#', '#.', '#.', '..', '..', '#.'], ['~..##', '#..#.', '#.#~.', '..~.~', '~~~..'], [0, 0], 5],
   None)]]
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
fault site entrance axes #1[1, 4][1, 0]Failed
regression entrance axes #1[0, 3][2, 1]Failed
partial repair boundary #1[1, 0][1, 0]Passed
partial repair boundary #2[0, 0][0, 0]Passed
first row candidate #1[1, 0][1, 0]Passed
water below #1NoneNonePassed
distance exactly min #1[2, 0][2, 0]Passed
control #1NoneNonePassed

SHA-256 / 8acfba267952bfbde223042f34362616259302ef6377bcf0b21f3c550e7b9b2f

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(floor_a, floor_b, entrance, min_dist):
    for y in range(len(floor_a)):
        for x in range(len(floor_a[0])):
            if floor_a[y][x] != '.':
                continue
            if y >= len(floor_b) or x >= len(floor_b[0]) or floor_b[y][x] != '.':
                continue
            if max(abs(x - entrance[0]), abs(y - entrance[1])) < min_dist:
                continue
            return [x, y]
    return None
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('fault site entrance axes #1',
   [['..', '..', '#.', '.#', '#.', '.#'], ['~.~', '~~~', '~#.', '~#.', '...', '##.'], [0, 4], 4],
   [1, 0]),
  ('regression entrance axes #1',
   [['#.#', '#..', '.##', '..#'], ['~~.#..', '...#~~', '#.#..#', '.....~', '~~#.~.'], [0, 2], 3],
   [2, 1]),
  ('partial repair boundary #1',
   [['...', '.#.', '...', '..#', '###', '..#'], ['~.#.~', '##~~#', '~~#..', '.~.~.'], [2, 4], 5],
   [1, 0]),
  ('partial repair boundary #2',
   [['..##.', '.##..', '.##..'], ['..~', '.##', '..~', '...', '.##', '...'], [3, 2], 5],
   [0, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('control #1', [['#.#.', '...#'], ['...#~', '.....'], [3, 1], 4], None)],
 [('fault site entrance axes #1', [['..#..'], ['#.#~', '#...', '.~~#', '~.#.'], [2, 0], 2], None),
  ('fault site entrance axes #2',
   [['#', '.', '.', '.', '.'], ['~.~~', '...#', '~.~#', '#~.#', '.#.#', '~..#'], [0, 3], 5],
   None),
  ('regression entrance axes #1',
   [['#.#', '#..', '.##', '..#'], ['~~.#..', '...#~~', '#.#..#', '.....~', '~~#.~.'], [0, 2], 3],
   [2, 1]),
  ('regression entrance axes #2',
   [['.....#', '..#.#.', '.#..#.', '..###.', '#.#..#'], ['.#.~~#', '.#.##.', '~~#~..', '......'], [0, 3], 5],
   [2, 0]),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('control #1', [['#.#.', '...#'], ['...#~', '.....'], [3, 1], 4], None),
  ('control #2', [['.', '#', '.', '#'], ['#.....'], [0, 1], 4], None)],
 [('regression entrance axes #1',
   [['.....#', '..#.#.', '.#..#.', '..###.', '#.#..#'], ['.#.~~#', '.#.##.', '~~#~..', '......'], [0, 3], 5],
   [2, 0]),
  ('fault site entrance axes #1', [['..', '.#', '.#'], ['~.', '..'], [0, 1], 1], [1, 0]),
  ('partial repair boundary #1', [['....', '...#', '#..#', '#..#', '##..'], ['.', '~'], [2, 3], 5], [0, 0]),
  ('regression entrance axes #2', [['.....', '#.###'], ['#.~..#', '.#.~##'], [0, 1], 2], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('control #1', [['.', '#', '.', '#'], ['#.....'], [0, 1], 4], None),
  ('control #2', [['##', '.#', '#.', '.#', '.#'], ['##.', '...', '.~#'], [0, 0], 5], None)],
 [('fault site entrance axes #1', [['......', '..##.#'], ['~##.#.', '~..#.~', '~...#.'], [3, 1], 6], None),
  ('regression entrance axes #1', [['.....', '#.###'], ['#.~..#', '.#.~##'], [0, 1], 2], [1, 0]),
  ('partial repair boundary #1',
   [['..#...', '#....#', '..#...', '..#...'], ['.~#~##', '~....#'], [1, 0], 2],
   [2, 1]),
  ('partial repair boundary #2',
   [['.#', '#.', '..', '#.'], ['.~.', '~..', '..#', '..#', '.#.'], [0, 0], 4],
   [1, 3]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('control #1',
   [['...##.', '..#.#.', '..#...', '#.....', '#.....'], ['#', '.', '.', '~'], [0, 2], 1],
   [0, 1]),
  ('control #2',
   [['#....', '..#..', '#...#', '#..#.', '.#.#.', '.#.#.'],
    ['#~..', '..~.', '..~.', '..#.', '##~~'],
    [1, 4],
    1],
   [2, 0])],
 [('fault site entrance axes #1', [['.#.#.', '..#..'], ['..~#.'], [2, 1], 5], None),
  ('fault site entrance axes #2', [['..', '..', '..', '#.', '..'], ['.', '.', '.'], [0, 3], 4], None),
  ('partial repair boundary #1',
   [['.#...#', '...##.', '...#..', '....#.', '..#..#', '......'],
    ['~..', '...', '#..', '...', '##~', '~##'],
    [3, 2],
    4],
   [0, 1]),
  ('partial repair boundary #2', [['....', '..##', '#.#.', '..##'], ['..~.~~', '~..#.#'], [3, 2], 5], [0, 0]),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('control #1', [['..', '##'], ['.', '.', '~', '~', '.'], [1, 0], 6], None),
  ('control #2',
   [['.#', '#.', '#.', '..', '..', '#.'], ['~..##', '#..#.', '#.#~.', '..~.~', '~~~..'], [0, 0], 5],
   None)]]
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
fault site entrance axes #1[1, 0][1, 0]Passed
regression entrance axes #1None[2, 1]Failed
partial repair boundary #1None[1, 0]Failed
partial repair boundary #2None[0, 0]Failed
first row candidate #1[1, 0][1, 0]Passed
water below #1NoneNonePassed
distance exactly min #1[2, 0][2, 0]Passed
control #1NoneNonePassed

SHA-256 / 74fe5d092c6b78b3993de19adce21063f4716776e7bcabdf98c4440ce4160dfb

3 / The verified repair

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

N = 1
observations = []
def solve(floor_a, floor_b, entrance, min_dist):
    for y in range(len(floor_a)):
        for x in range(len(floor_a[0])):
            if floor_a[y][x] != '.':
                continue
            if y >= len(floor_b) or x >= len(floor_b[0]) or floor_b[y][x] != '.':
                continue
            if abs(x - entrance[0]) + abs(y - entrance[1]) < min_dist:
                continue
            return [x, y]
    return None
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('fault site entrance axes #1',
   [['..', '..', '#.', '.#', '#.', '.#'], ['~.~', '~~~', '~#.', '~#.', '...', '##.'], [0, 4], 4],
   [1, 0]),
  ('regression entrance axes #1',
   [['#.#', '#..', '.##', '..#'], ['~~.#..', '...#~~', '#.#..#', '.....~', '~~#.~.'], [0, 2], 3],
   [2, 1]),
  ('partial repair boundary #1',
   [['...', '.#.', '...', '..#', '###', '..#'], ['~.#.~', '##~~#', '~~#..', '.~.~.'], [2, 4], 5],
   [1, 0]),
  ('partial repair boundary #2',
   [['..##.', '.##..', '.##..'], ['..~', '.##', '..~', '...', '.##', '...'], [3, 2], 5],
   [0, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('control #1', [['#.#.', '...#'], ['...#~', '.....'], [3, 1], 4], None)],
 [('fault site entrance axes #1', [['..#..'], ['#.#~', '#...', '.~~#', '~.#.'], [2, 0], 2], None),
  ('fault site entrance axes #2',
   [['#', '.', '.', '.', '.'], ['~.~~', '...#', '~.~#', '#~.#', '.#.#', '~..#'], [0, 3], 5],
   None),
  ('regression entrance axes #1',
   [['#.#', '#..', '.##', '..#'], ['~~.#..', '...#~~', '#.#..#', '.....~', '~~#.~.'], [0, 2], 3],
   [2, 1]),
  ('regression entrance axes #2',
   [['.....#', '..#.#.', '.#..#.', '..###.', '#.#..#'], ['.#.~~#', '.#.##.', '~~#~..', '......'], [0, 3], 5],
   [2, 0]),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('control #1', [['#.#.', '...#'], ['...#~', '.....'], [3, 1], 4], None),
  ('control #2', [['.', '#', '.', '#'], ['#.....'], [0, 1], 4], None)],
 [('regression entrance axes #1',
   [['.....#', '..#.#.', '.#..#.', '..###.', '#.#..#'], ['.#.~~#', '.#.##.', '~~#~..', '......'], [0, 3], 5],
   [2, 0]),
  ('fault site entrance axes #1', [['..', '.#', '.#'], ['~.', '..'], [0, 1], 1], [1, 0]),
  ('partial repair boundary #1', [['....', '...#', '#..#', '#..#', '##..'], ['.', '~'], [2, 3], 5], [0, 0]),
  ('regression entrance axes #2', [['.....', '#.###'], ['#.~..#', '.#.~##'], [0, 1], 2], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('control #1', [['.', '#', '.', '#'], ['#.....'], [0, 1], 4], None),
  ('control #2', [['##', '.#', '#.', '.#', '.#'], ['##.', '...', '.~#'], [0, 0], 5], None)],
 [('fault site entrance axes #1', [['......', '..##.#'], ['~##.#.', '~..#.~', '~...#.'], [3, 1], 6], None),
  ('regression entrance axes #1', [['.....', '#.###'], ['#.~..#', '.#.~##'], [0, 1], 2], [1, 0]),
  ('partial repair boundary #1',
   [['..#...', '#....#', '..#...', '..#...'], ['.~#~##', '~....#'], [1, 0], 2],
   [2, 1]),
  ('partial repair boundary #2',
   [['.#', '#.', '..', '#.'], ['.~.', '~..', '..#', '..#', '.#.'], [0, 0], 4],
   [1, 3]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('water below #1', [['.'], ['~'], [0, 0], 0], None),
  ('control #1',
   [['...##.', '..#.#.', '..#...', '#.....', '#.....'], ['#', '.', '.', '~'], [0, 2], 1],
   [0, 1]),
  ('control #2',
   [['#....', '..#..', '#...#', '#..#.', '.#.#.', '.#.#.'],
    ['#~..', '..~.', '..~.', '..#.', '##~~'],
    [1, 4],
    1],
   [2, 0])],
 [('fault site entrance axes #1', [['.#.#.', '..#..'], ['..~#.'], [2, 1], 5], None),
  ('fault site entrance axes #2', [['..', '..', '..', '#.', '..'], ['.', '.', '.'], [0, 3], 4], None),
  ('partial repair boundary #1',
   [['.#...#', '...##.', '...#..', '....#.', '..#..#', '......'],
    ['~..', '...', '#..', '...', '##~', '~##'],
    [3, 2],
    4],
   [0, 1]),
  ('partial repair boundary #2', [['....', '..##', '#.#.', '..##'], ['..~.~~', '~..#.#'], [3, 2], 5], [0, 0]),
  ('distance exactly min #1', [['...'], ['...'], [0, 0], 2], [2, 0]),
  ('first row candidate #1', [['..', '..'], ['#.', '..'], [0, 0], 1], [1, 0]),
  ('control #1', [['..', '##'], ['.', '.', '~', '~', '.'], [1, 0], 6], None),
  ('control #2',
   [['.#', '#.', '#.', '..', '..', '#.'], ['~..##', '#..#.', '#.#~.', '..~.~', '~~~..'], [0, 0], 5],
   None)]]
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
fault site entrance axes #1[1, 0][1, 0]Passed
regression entrance axes #1[2, 1][2, 1]Passed
partial repair boundary #1[1, 0][1, 0]Passed
partial repair boundary #2[0, 0][0, 0]Passed
first row candidate #1[1, 0][1, 0]Passed
water below #1NoneNonePassed
distance exactly min #1[2, 0][2, 0]Passed
control #1NoneNonePassed

SHA-256 / 63c78c22d3377a0ec1b3144ffde3f3893f1e84fb3e4e68a187735923fb6a3451

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:53.194469+00:00.

Case digest / 085d6d2de39f30d040b1cb2fa59acd7572057ea868c63e08c6dedbb000b19d23