FAILURE MAP
← Case archive

FA-86711 / Procedural level generation constraints / Open access

Heightmap smoothing and biome classes: Smoothed heights round to nearest · case 01

Coastlines shift inland compared to the floor rule.

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

ROOT CAUSE

The window mean is rounded instead of floored.

VERIFIED REPAIR

Restore `v = total // cnt` at the mean rounding step.

Unsuccessful approach: Ceiling division raises every fractional mean.

Case contract

Each cell height becomes floor(mean) of the in-bounds cells in its 3x3 window (input values only). Class: '~' when v < sea, 's' beach when v < sea+2, 'g' when v < mountain, otherwise '^'. Returns strings per row.

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(heights, sea, mountain):
    h = len(heights)
    w = len(heights[0])
    out = []
    for r in range(h):
        row = []
        for c in range(w):
            total = 0
            cnt = 0
            for rr in range(max(0, r - 1), min(h, r + 2)):
                for cc in range(max(0, c - 1), min(w, c + 2)):
                    total += heights[rr][cc]
                    cnt += 1
            v = round(total / cnt)
            if v < sea:
                row.append('~')
            elif v < sea + 2:
                row.append('s')
            elif v < mountain:
                row.append('g')
            else:
                row.append('^')
        out.append(''.join(row))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression mean rounding #1', [[[3], [4], [0]], 4, 10], ['~', '~', '~']),
  ('regression mean rounding #2', [[[10, 11, 6, 11, 0], [9, 0, 9, 4, 4]], 5, 7], ['^^ss~', '^^ss~']),
  ('regression mean rounding #3',
   [[[5, 4, 2, 6, 4], [12, 10, 8, 2, 4], [4, 10, 11, 2, 6]], 2, 8],
   ['ggggg', 'ggggg', '^^ggs']),
  ('regression mean rounding #4', [[[6], [4], [8], [4], [8]], 5, 9], ['s', 's', 's', 's', 's']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('control #1', [[[0, 9], [7, 2]], 2, 11], ['gg', 'gg'])],
 [('regression mean rounding #1',
   [[[5, 4, 2, 6, 4], [12, 10, 8, 2, 4], [4, 10, 11, 2, 6]], 2, 8],
   ['ggggg', 'ggggg', '^^ggs']),
  ('regression mean rounding #2', [[[6], [4], [8], [4], [8]], 5, 9], ['s', 's', 's', 's', 's']),
  ('regression mean rounding #3', [[[9, 5, 6], [9, 0, 4]], 6, 10], ['~~~', '~~~']),
  ('regression mean rounding #4',
   [[[8, 6, 12, 10, 8], [6, 1, 1, 7, 5], [1, 6, 12, 6, 0], [3, 8, 3, 6, 0], [1, 7, 3, 2, 0]], 6, 9],
   ['~~sss', '~~sss', '~~~~~', '~~~~~', '~~~~~']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('control #1', [[[0, 9], [7, 2]], 2, 11], ['gg', 'gg']),
  ('control #2', [[[9], [8]], 6, 6], ['^', '^'])],
 [('regression mean rounding #1', [[[9, 5, 6], [9, 0, 4]], 6, 10], ['~~~', '~~~']),
  ('regression mean rounding #2',
   [[[8, 6, 12, 10, 8], [6, 1, 1, 7, 5], [1, 6, 12, 6, 0], [3, 8, 3, 6, 0], [1, 7, 3, 2, 0]], 6, 9],
   ['~~sss', '~~sss', '~~~~~', '~~~~~', '~~~~~']),
  ('regression mean rounding #3',
   [[[2, 9, 4, 10, 11], [7, 7, 11, 1, 10], [11, 5, 12, 1, 12], [9, 4, 1, 0, 2]], 6, 8],
   ['ssss^', 'sss^s', 'ss~~~', 'ss~~~']),
  ('regression mean rounding #4', [[[0, 1], [3, 5], [10, 1]], 3, 10], ['~~', 'ss', 'ss']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('control #1', [[[9], [8]], 6, 6], ['^', '^']),
  ('control #2', [[[5, 5], [10, 3], [7, 0]], 2, 10], ['gg', 'gg', 'gg'])],
 [('regression mean rounding #1',
   [[[2, 9, 4, 10, 11], [7, 7, 11, 1, 10], [11, 5, 12, 1, 12], [9, 4, 1, 0, 2]], 6, 8],
   ['ssss^', 'sss^s', 'ss~~~', 'ss~~~']),
  ('regression mean rounding #2', [[[0, 1], [3, 5], [10, 1]], 3, 10], ['~~', 'ss', 'ss']),
  ('regression mean rounding #3',
   [[[1, 2, 0, 4], [12, 1, 9, 7], [9, 3, 6, 5]], 2, 11],
   ['ggsg', 'gggg', 'gggg']),
  ('partial repair boundary #1',
   [[[0, 3], [6, 9], [0, 3], [3, 12], [7, 10]], 5, 6],
   ['~~', '~~', 'ss', 'ss', '^^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('control #1', [[[10, 11], [1, 0]], 3, 9], ['gg', 'gg']),
  ('control #2', [[[9, 7]], 2, 6], ['^^'])],
 [('regression mean rounding #1',
   [[[1, 2, 0, 4], [12, 1, 9, 7], [9, 3, 6, 5]], 2, 11],
   ['ggsg', 'gggg', 'gggg']),
  ('regression mean rounding #2',
   [[[4, 3, 3, 1], [4, 1, 10, 9], [2, 2, 10, 5], [0, 0, 7, 2]], 6, 8],
   ['~~~~', '~~~s', '~~~s', '~~~s']),
  ('partial repair boundary #1',
   [[[0, 3], [6, 9], [0, 3], [3, 12], [7, 10]], 5, 6],
   ['~~', '~~', 'ss', 'ss', '^^']),
  ('regression mean rounding #3',
   [[[10, 1, 2, 12, 9], [8, 10, 5, 4, 8], [4, 3, 4, 4, 8], [2, 5, 12, 8, 7]], 5, 7],
   ['^sss^', 'ssss^', 'sssss', '~ss^s']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('control #1', [[[1, 2, 10]], 6, 9], ['~~s']),
  ('control #2', [[[11, 0, 4, 12]], 2, 7], ['ggg^'])]]
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
regression mean rounding #1['s', '~', '~']['~', '~', '~']Failed
regression mean rounding #2['^^^ss', '^^^ss']['^^ss~', '^^ss~']Failed
regression mean rounding #3['^gggg', '^gggg', '^^ggg']['ggggg', 'ggggg', '^^ggs']Failed
regression mean rounding #4['s', 's', 's', 'g', 's']['s', 's', 's', 's', 's']Failed
corner cell average #1['gg', 'gg']['gg', 'gg']Passed
beach band edge #1['g']['g']Passed
single row #1['^s^']['^s^']Passed
control #1['gg', 'gg']['gg', 'gg']Passed

SHA-256 / 897537813f895e1970ecdf4517178996197dcfbd6c597025d04134f3de824731

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(heights, sea, mountain):
    h = len(heights)
    w = len(heights[0])
    out = []
    for r in range(h):
        row = []
        for c in range(w):
            total = 0
            cnt = 0
            for rr in range(max(0, r - 1), min(h, r + 2)):
                for cc in range(max(0, c - 1), min(w, c + 2)):
                    total += heights[rr][cc]
                    cnt += 1
            v = -(-total // cnt)
            if v < sea:
                row.append('~')
            elif v < sea + 2:
                row.append('s')
            elif v < mountain:
                row.append('g')
            else:
                row.append('^')
        out.append(''.join(row))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression mean rounding #1', [[[3], [4], [0]], 4, 10], ['~', '~', '~']),
  ('regression mean rounding #2', [[[10, 11, 6, 11, 0], [9, 0, 9, 4, 4]], 5, 7], ['^^ss~', '^^ss~']),
  ('regression mean rounding #3',
   [[[5, 4, 2, 6, 4], [12, 10, 8, 2, 4], [4, 10, 11, 2, 6]], 2, 8],
   ['ggggg', 'ggggg', '^^ggs']),
  ('regression mean rounding #4', [[[6], [4], [8], [4], [8]], 5, 9], ['s', 's', 's', 's', 's']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('control #1', [[[0, 9], [7, 2]], 2, 11], ['gg', 'gg'])],
 [('regression mean rounding #1',
   [[[5, 4, 2, 6, 4], [12, 10, 8, 2, 4], [4, 10, 11, 2, 6]], 2, 8],
   ['ggggg', 'ggggg', '^^ggs']),
  ('regression mean rounding #2', [[[6], [4], [8], [4], [8]], 5, 9], ['s', 's', 's', 's', 's']),
  ('regression mean rounding #3', [[[9, 5, 6], [9, 0, 4]], 6, 10], ['~~~', '~~~']),
  ('regression mean rounding #4',
   [[[8, 6, 12, 10, 8], [6, 1, 1, 7, 5], [1, 6, 12, 6, 0], [3, 8, 3, 6, 0], [1, 7, 3, 2, 0]], 6, 9],
   ['~~sss', '~~sss', '~~~~~', '~~~~~', '~~~~~']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('control #1', [[[0, 9], [7, 2]], 2, 11], ['gg', 'gg']),
  ('control #2', [[[9], [8]], 6, 6], ['^', '^'])],
 [('regression mean rounding #1', [[[9, 5, 6], [9, 0, 4]], 6, 10], ['~~~', '~~~']),
  ('regression mean rounding #2',
   [[[8, 6, 12, 10, 8], [6, 1, 1, 7, 5], [1, 6, 12, 6, 0], [3, 8, 3, 6, 0], [1, 7, 3, 2, 0]], 6, 9],
   ['~~sss', '~~sss', '~~~~~', '~~~~~', '~~~~~']),
  ('regression mean rounding #3',
   [[[2, 9, 4, 10, 11], [7, 7, 11, 1, 10], [11, 5, 12, 1, 12], [9, 4, 1, 0, 2]], 6, 8],
   ['ssss^', 'sss^s', 'ss~~~', 'ss~~~']),
  ('regression mean rounding #4', [[[0, 1], [3, 5], [10, 1]], 3, 10], ['~~', 'ss', 'ss']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('control #1', [[[9], [8]], 6, 6], ['^', '^']),
  ('control #2', [[[5, 5], [10, 3], [7, 0]], 2, 10], ['gg', 'gg', 'gg'])],
 [('regression mean rounding #1',
   [[[2, 9, 4, 10, 11], [7, 7, 11, 1, 10], [11, 5, 12, 1, 12], [9, 4, 1, 0, 2]], 6, 8],
   ['ssss^', 'sss^s', 'ss~~~', 'ss~~~']),
  ('regression mean rounding #2', [[[0, 1], [3, 5], [10, 1]], 3, 10], ['~~', 'ss', 'ss']),
  ('regression mean rounding #3',
   [[[1, 2, 0, 4], [12, 1, 9, 7], [9, 3, 6, 5]], 2, 11],
   ['ggsg', 'gggg', 'gggg']),
  ('partial repair boundary #1',
   [[[0, 3], [6, 9], [0, 3], [3, 12], [7, 10]], 5, 6],
   ['~~', '~~', 'ss', 'ss', '^^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('control #1', [[[10, 11], [1, 0]], 3, 9], ['gg', 'gg']),
  ('control #2', [[[9, 7]], 2, 6], ['^^'])],
 [('regression mean rounding #1',
   [[[1, 2, 0, 4], [12, 1, 9, 7], [9, 3, 6, 5]], 2, 11],
   ['ggsg', 'gggg', 'gggg']),
  ('regression mean rounding #2',
   [[[4, 3, 3, 1], [4, 1, 10, 9], [2, 2, 10, 5], [0, 0, 7, 2]], 6, 8],
   ['~~~~', '~~~s', '~~~s', '~~~s']),
  ('partial repair boundary #1',
   [[[0, 3], [6, 9], [0, 3], [3, 12], [7, 10]], 5, 6],
   ['~~', '~~', 'ss', 'ss', '^^']),
  ('regression mean rounding #3',
   [[[10, 1, 2, 12, 9], [8, 10, 5, 4, 8], [4, 3, 4, 4, 8], [2, 5, 12, 8, 7]], 5, 7],
   ['^sss^', 'ssss^', 'sssss', '~ss^s']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('control #1', [[[1, 2, 10]], 6, 9], ['~~s']),
  ('control #2', [[[11, 0, 4, 12]], 2, 7], ['ggg^'])]]
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
regression mean rounding #1['s', '~', '~']['~', '~', '~']Failed
regression mean rounding #2['^^^ss', '^^^ss']['^^ss~', '^^ss~']Failed
regression mean rounding #3['^gggg', '^^ggg', '^^^gg']['ggggg', 'ggggg', '^^ggs']Failed
regression mean rounding #4['s', 's', 's', 'g', 's']['s', 's', 's', 's', 's']Failed
corner cell average #1['gg', 'gg']['gg', 'gg']Passed
beach band edge #1['g']['g']Passed
single row #1['^s^']['^s^']Passed
control #1['gg', 'gg']['gg', 'gg']Passed

SHA-256 / 61cdb5545c54040c3c8b2ac4814a21bbf6d67fe948474a32a1cd196170b26ded

3 / The verified repair

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

N = 1
observations = []
def solve(heights, sea, mountain):
    h = len(heights)
    w = len(heights[0])
    out = []
    for r in range(h):
        row = []
        for c in range(w):
            total = 0
            cnt = 0
            for rr in range(max(0, r - 1), min(h, r + 2)):
                for cc in range(max(0, c - 1), min(w, c + 2)):
                    total += heights[rr][cc]
                    cnt += 1
            v = total // cnt
            if v < sea:
                row.append('~')
            elif v < sea + 2:
                row.append('s')
            elif v < mountain:
                row.append('g')
            else:
                row.append('^')
        out.append(''.join(row))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression mean rounding #1', [[[3], [4], [0]], 4, 10], ['~', '~', '~']),
  ('regression mean rounding #2', [[[10, 11, 6, 11, 0], [9, 0, 9, 4, 4]], 5, 7], ['^^ss~', '^^ss~']),
  ('regression mean rounding #3',
   [[[5, 4, 2, 6, 4], [12, 10, 8, 2, 4], [4, 10, 11, 2, 6]], 2, 8],
   ['ggggg', 'ggggg', '^^ggs']),
  ('regression mean rounding #4', [[[6], [4], [8], [4], [8]], 5, 9], ['s', 's', 's', 's', 's']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('control #1', [[[0, 9], [7, 2]], 2, 11], ['gg', 'gg'])],
 [('regression mean rounding #1',
   [[[5, 4, 2, 6, 4], [12, 10, 8, 2, 4], [4, 10, 11, 2, 6]], 2, 8],
   ['ggggg', 'ggggg', '^^ggs']),
  ('regression mean rounding #2', [[[6], [4], [8], [4], [8]], 5, 9], ['s', 's', 's', 's', 's']),
  ('regression mean rounding #3', [[[9, 5, 6], [9, 0, 4]], 6, 10], ['~~~', '~~~']),
  ('regression mean rounding #4',
   [[[8, 6, 12, 10, 8], [6, 1, 1, 7, 5], [1, 6, 12, 6, 0], [3, 8, 3, 6, 0], [1, 7, 3, 2, 0]], 6, 9],
   ['~~sss', '~~sss', '~~~~~', '~~~~~', '~~~~~']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('control #1', [[[0, 9], [7, 2]], 2, 11], ['gg', 'gg']),
  ('control #2', [[[9], [8]], 6, 6], ['^', '^'])],
 [('regression mean rounding #1', [[[9, 5, 6], [9, 0, 4]], 6, 10], ['~~~', '~~~']),
  ('regression mean rounding #2',
   [[[8, 6, 12, 10, 8], [6, 1, 1, 7, 5], [1, 6, 12, 6, 0], [3, 8, 3, 6, 0], [1, 7, 3, 2, 0]], 6, 9],
   ['~~sss', '~~sss', '~~~~~', '~~~~~', '~~~~~']),
  ('regression mean rounding #3',
   [[[2, 9, 4, 10, 11], [7, 7, 11, 1, 10], [11, 5, 12, 1, 12], [9, 4, 1, 0, 2]], 6, 8],
   ['ssss^', 'sss^s', 'ss~~~', 'ss~~~']),
  ('regression mean rounding #4', [[[0, 1], [3, 5], [10, 1]], 3, 10], ['~~', 'ss', 'ss']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('control #1', [[[9], [8]], 6, 6], ['^', '^']),
  ('control #2', [[[5, 5], [10, 3], [7, 0]], 2, 10], ['gg', 'gg', 'gg'])],
 [('regression mean rounding #1',
   [[[2, 9, 4, 10, 11], [7, 7, 11, 1, 10], [11, 5, 12, 1, 12], [9, 4, 1, 0, 2]], 6, 8],
   ['ssss^', 'sss^s', 'ss~~~', 'ss~~~']),
  ('regression mean rounding #2', [[[0, 1], [3, 5], [10, 1]], 3, 10], ['~~', 'ss', 'ss']),
  ('regression mean rounding #3',
   [[[1, 2, 0, 4], [12, 1, 9, 7], [9, 3, 6, 5]], 2, 11],
   ['ggsg', 'gggg', 'gggg']),
  ('partial repair boundary #1',
   [[[0, 3], [6, 9], [0, 3], [3, 12], [7, 10]], 5, 6],
   ['~~', '~~', 'ss', 'ss', '^^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('beach band edge #1', [[[5]], 3, 9], ['g']),
  ('control #1', [[[10, 11], [1, 0]], 3, 9], ['gg', 'gg']),
  ('control #2', [[[9, 7]], 2, 6], ['^^'])],
 [('regression mean rounding #1',
   [[[1, 2, 0, 4], [12, 1, 9, 7], [9, 3, 6, 5]], 2, 11],
   ['ggsg', 'gggg', 'gggg']),
  ('regression mean rounding #2',
   [[[4, 3, 3, 1], [4, 1, 10, 9], [2, 2, 10, 5], [0, 0, 7, 2]], 6, 8],
   ['~~~~', '~~~s', '~~~s', '~~~s']),
  ('partial repair boundary #1',
   [[[0, 3], [6, 9], [0, 3], [3, 12], [7, 10]], 5, 6],
   ['~~', '~~', 'ss', 'ss', '^^']),
  ('regression mean rounding #3',
   [[[10, 1, 2, 12, 9], [8, 10, 5, 4, 8], [4, 3, 4, 4, 8], [2, 5, 12, 8, 7]], 5, 7],
   ['^sss^', 'ssss^', 'sssss', '~ss^s']),
  ('single row #1', [[[0, 12, 0]], 3, 6], ['^s^']),
  ('corner cell average #1', [[[9, 9], [9, 0]], 3, 8], ['gg', 'gg']),
  ('control #1', [[[1, 2, 10]], 6, 9], ['~~s']),
  ('control #2', [[[11, 0, 4, 12]], 2, 7], ['ggg^'])]]
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
regression mean rounding #1['~', '~', '~']['~', '~', '~']Passed
regression mean rounding #2['^^ss~', '^^ss~']['^^ss~', '^^ss~']Passed
regression mean rounding #3['ggggg', 'ggggg', '^^ggs']['ggggg', 'ggggg', '^^ggs']Passed
regression mean rounding #4['s', 's', 's', 's', 's']['s', 's', 's', 's', 's']Passed
corner cell average #1['gg', 'gg']['gg', 'gg']Passed
beach band edge #1['g']['g']Passed
single row #1['^s^']['^s^']Passed
control #1['gg', 'gg']['gg', 'gg']Passed

SHA-256 / 6cfa0fa452018eabb0aa5a9bcfe1cadb8294fd9ddb6bccaeee9b1fb0504f99f6

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

Case digest / afd6767e267c4d90651ed700a5dd2673a5ec20c2e65388606494d09eb1eea039