同一套契约,能否长出新的建筑?


Proc-compose 第二轮续跑报告:保留 Hearth 内核,让独立扩展通过公共接口生成斜向桥廊、Bezier 围墙、多边形建筑与连接图,再检查追溯、验证和再生成是否仍然成立。

2026-09-26 · attempt 0002 · gpt-6-astra / max · 原 session 续跑 · 第一轮完整报告 · 在线运行本轮 Python · 下载本轮库、示例与测试

179测试:原 134 + 新 45
88 / 88支持范围内新增输入通过
15 / 24本轮压力输入通过
1修改的内核模块

01 · 结论:扩展能力更可信,开放世界仍未完成

这轮的主要收获是证明第一轮的基础设施能承载明显不同的几何和组合方式。新组件在独立的 hearth_extensions 包内实现:折线/Bezier 曲线、曲线路径与支撑、多边形建筑及功能内饰、公共端点连接和图组织客户端。旧的房间模数建筑可以直接成为新建筑群中的一个节点。

实质进步

结构变化从规则房间图扩展到切角平面、斜向连接、曲线边界与分支/环形图。连接者读取公开端点,墙上灯具读取挂点,支撑根据已存在地形适配。新增内容沿用原来的事务、权限、实例链、语义保存和验证,而不是各做一套孤立生成器。

仍需继续

两个建筑群客户端仍显式摆放节点,入口方向以四个正交方向为主。没有通用空间布局求解、任意建筑体量融合或屋顶交接;功能内饰虽可用,视觉上仍较稀疏。这里的“可扩展”有代码与样本支持,“能生成任意城市且总是美观”没有。

下一步最有价值的是让高阶程序通过接口自动决定节点位置、连接方式和空间层级,同时扩大固定测试集。继续增加若干手工布局,不能独自证明库已获得开放式组合能力。

证据分三层:模型在本轮输出的语料与诊断、harness 的独立验收、制作报告时的原生/浏览器复验。正文不会把三者混为一谈。前一轮的网页通过记录也不作为本轮浏览器成功的证据。

维度第一轮第二轮增量
主体几何规则房间图、有界山墙屋顶13–25 格多边形厅堂、切角、坡屋顶/天窗
连接街道和平台周边通路公共端点之间的斜向桥/廊、转折、升高与实地支撑
边界规则围护与附属组件Bezier 采样、分段边界、挂点透传、灯具装配
高阶组合街道式聚落新旧建筑混合的分支图、三角连接图;位置仍显式给定
内核权限、事务、追溯、局部再生成只读 connect 与耦合再生成 replacements;只动一个内核文件
测试134179;原测试源码保持不变

02 · Live proc-gen:运行 Python、调参、查结构

浏览器通过 Pyodide + Web Worker 执行原始 Python 库,不向模型发请求。先选一个客户端并点击载入,修改代码或变量,再生成。首次需要下载 Python、NumPy 和库文件;聚落比单体更慢,可随时停止。所有有效结果都会经过库的验证、MCIO 导出/读回和结构查询对比。

下载本轮分支建筑群

实际注入 Python 的变量

“换 seed”保留当前代码和控件;“探索结构分布”会替换编辑器内容为原库的多边形单体采样入口,改变宽深、切角、入口、用途、层高、屋顶和天窗。下方公开完整采样函数;这是有限的单体采样策略,不声称均匀覆盖或穷尽整个库的表达空间,也不会隐藏失败后反复采样。

准备就绪。点击运行,开始真正的 Python 生成。

本轮分支建筑群预览

背景是原始实验渲染;运行后替换为当前 Python 结果。

剖切/隐藏只影响预览,不修改已验证的完整建筑或下载内容。单击可见方块查询,拖动则旋转。结构成员显示包含真实子结构与共享支撑。

选择一个方块,沿结构向上看

当前方块的真实结构记录
尚未生成
解析后的结构、策略和语义摘要
尚未生成
Python 输出与错误诊断
尚未运行

ZIP 保存 scene.litematic、scene.litematic.structure.json、可重放的 client.py 和生成元数据。结构记录不能丢:单独的 schematic 不包含这份语义关系图。库的源码哈希在运行前逐一校验;浏览器平台差异是否影响同 seed 的内容,见第 12 节实测。

“探索结构分布”实际调用的原始 Python 采样函数
def hall_scene(seed, environment_seed=None): rng = Scope(seed).stream('hall-intent') domain = Box((-12, -4, -12), (42, 65, 42)) es = seed if environment_seed is None else environment_seed field = gradient(.012, -.008, 4) + wave(.5, .1, .12, Scope(es).stream('hall-field').random() * 6) env = Scene(es, domain=domain) env.place('land', Terrain(domain, field)) env.finalize() s = env.fork(seed=seed) shape = Polygon.chamfered(rng.choice((13, 17, 21, 25)), rng.choice((13, 17, 21)), rng.choice((0, 2, 4))) s.place('hall', Pavilion(shape, '/land', rng.choice(('library', 'workshop', 'living')), ('north', 'south', 'east') if rng.choice((True, False)) else ('north', 'west'), height=rng.choice((5, 6, 7)), roof_run=rng.choice((2, 3)), lantern=rng.choice((True, False)))) return s.finalize()

下拉菜单用于打开示例代码,不是 library 内置家族选择器。任意客户端都可直接组合公共组件。固定 ENV_SEED 可以让结构变化与地形变化分开观察。

03 · 续跑任务与不可变来源

本轮要求先冻结既有接口并做扩展探针:独立实现斜向桥、曲线墙、建筑间连接;如果无法仅通过公共接口实现,先保留失败证据,再提出可复用的内核修正。原来的 R01–R30、环境适配、真实方块验证、seed 重放和自动 provenance 要继续成立。没有要求删掉原测试,也没有允许用家族 selector 代替组合库。

报告固定使用 runs/archive/proc-proc-compose-astra-max-kokemeow-attempt-0002 的归档副本,避免未来续跑污染本轮统计。源库未经浏览器特化修改。输入仍是两组、共 16 份美学参考;参考的实现不是库结构要求,也不计入新写代码行数。32 份参考文件已逐一核对哈希。

本轮实际发送的续跑 prompt
# Continue Hearth: prove extensibility through new compositions Continue implementing in this existing session and workspace. This is a new authorized development phase after your completed first delivery. Do not restart the project or stop merely because the original task was completed. Retain all original R01-R30 requirements and accepted design ideas unless a change below explicitly supersedes them. The first delivery is a useful executable architecture: shared component contracts, authority, transactions, automatic structural provenance, terrain adaptation, and paired persistence all work on its finite test set. An external report reran all 134 tests and executed the unchanged library in Pyodide. Eleven browser executions matched native semantic content, principal signatures, and glass queries. Six downloaded artifact pairs also preserved their complete structural nodes. Preserve this functionality and portability. The major remaining weakness is expressive breadth. Most shipped buildings use a small grid-room vocabulary with bays 9/11/13 and bounded gables. Settlement organization is an opposed street with spine/loop paths. Contact adaptation mostly chooses between two strategies. The 18 principal signatures in 24 building samples and 9 successes in 32 stress inputs are useful evidence, not proof of a broadly expressive architecture or distribution. Implement improvements, not just a proposal, more documentation, or more seed samples of the same narrow programs. Code length is not a target. Favor a clear, extensible library, lightweight high-level clients, working validation, and attractive generated results. ## 1. Test the existing abstraction before changing it Record a concise public API baseline and its module hashes before modifying the kernel. Implement new components in a separate extension package using documented public contracts. Use these as concrete probes: - A diagonal bridge with walkable circulation, railings, and endpoint/support adaptation. - A wall or boundary that follows a curve or spline and exposes useful attachment interfaces. - A corridor or walkway connecting two already placed buildings through their public ports, including a composition crossing water or uneven terrain. These are reusable component examples, not three new hardcoded building/environment families. Use shared geometric structures where helpful: splines or polylines, graphs, fields, local frames, spatial indexes, and constraint/effect records are all appropriate. Choose the representation deliberately; do not add structures just to check off their names. Start with the kernel unchanged. If an extension reveals a real missing capability, record the failing composition or contract test first. Then make the smallest coherent, general protocol improvement, documenting the API delta and why extension-only code was insufficient. Do not evade a limitation through private-state access, direct block-store mutation, client geometry repairs, handwritten provenance, or a kernel branch keyed to an example name. A self-authored extension is an extension exercise, not an independent audit. Describe its evidence honestly. The important result is whether clients and other components can use the new behavior through public interfaces without knowing its private geometry. ## 2. Broaden meaningful architectural composition Use these capabilities in lightweight new building and settlement compositions. Move beyond the same opposed street layout: let explicit graphs, environmental observations, public connections, and spatial constraints drive placement and circulation. Demonstrate materially different massing and spatial organization, not just colors, names, transforms, or extra decorations. Extend the shipped architectural vocabulary where needed rather than hiding large one-off generators behind a short wrapper. Keep environments compositional and generic. A flat site, shore, slope, or channel should arise from general operations/parameters rather than an enumerated environment selector. Generate and freeze the relevant environment before placing structures. Respect locked principal intent and edit permissions. Where adaptation fails, improve general contact or connection rules when justified; do not simply widen limits, remove validators, move locked buildings, flatten the whole terrain, or resample away difficult inputs. Keep authority directional and local, preserve existing consumers, maintain whole-object consistency, and validate tentative compositions before committing. New components must participate in automatic instance ownership, typed relationships, precise current-cell queries, transforms, replacement/deletion, and atomic rollback through the same infrastructure. ## 3. Verify and inspect actual results Keep every existing test. Retain the completed first-phase evidence and distinguish new results from it, for example under reports/extension-corpus and samples/extensions. Do not rewrite earlier evidence to make the new implementation look better. Add focused positive and deliberately broken cases for each new capability: disconnected endpoints, incompatible ports/frames, missing support, blocked headroom, permission overflow, stale ownership after replacement, and failed-candidate rollback. Validate actual blocks/NBT and relevant companion records rather than only declared plans. Exercise multiple seeds and independent environment/structure inputs, including parameter boundaries and compositions not used to implement the primitives. State the supported domain and sampling recipe before assessment. Retain all failures, incompatibilities, and budget exhaustion; separate input success from candidate acceptance. Track principal architectural signatures separately from contact adaptations and cosmetic variation. Render and inspect representative complete compositions from several sides and with interior or circulation cutaways. Correct visible problems through reusable rules. Show that bridges and corridors connect usable entrances and that curve-following geometry has coherent joins. Preserve semantic export/reload, deterministic scoped seeds, exact structural inspection, and the original public default and --seed/--output CLI contract. Run the full regression suite and the new assessment before claiming completion. Do not weaken tests to obtain a pass. Update ARCHITECTURE.md, GENERATOR.md, and the requirement/evidence ledger to describe the final implementation and real limitations. End with what improved, which interfaces changed, what still requires private knowledge or remains constrained, and actual test/render results. No new HTML report, viewer, deployment, or reference-generator reuse is needed in this phase.
继承的 16 张美学参考
mediterranean-villa 原始美学参考
exp8 / mediterranean-villa
merchant-manor 原始美学参考
exp8 / merchant-manor
red-roof-farmstead 原始美学参考
exp8 / red-roof-farmstead
root-house 原始美学参考
exp8 / root-house
sandstone-cottage 原始美学参考
exp8 / sandstone-cottage
stilt-water-cabin 原始美学参考
exp8 / stilt-water-cabin
stilted-manor 原始美学参考
exp8 / stilted-manor
stone-cottage 原始美学参考
exp8 / stone-cottage
ref-1 原始美学参考
lodge / ref-1
ref-2 原始美学参考
lodge / ref-2
ref-3 原始美学参考
lodge / ref-3
ref-4 原始美学参考
lodge / ref-4
ref-5 原始美学参考
lodge / ref-5
ref-6 原始美学参考
lodge / ref-6
ref-7 原始美学参考
lodge / ref-7
ref-8 原始美学参考
lodge / ref-8

续跑 prompt · 最初完整 prompt · 参考来源与哈希 · 本报告统计

04 · 本轮时间与使用量

72.9 min本轮开始至结束
86新增请求
89命令记录
9非零退出记录

UTC:2026-09-26T22:22:01.241109+00:00 → 2026-09-26T23:34:56.171887+00:00,包含生成与验收等生命周期。运行配置为 4 CPU / 8 GiB / 512 PID。模型与 scorer 最终退出码均为 0,完成后自动归档。非零命令包括开发排错,不等于最终失败。

字段本轮增量解释
Input13,560,759包含 cached input
Cached input13,190,272输入的子集
Uncached input370,487Input − Cached input
Output118,037包含 reasoning output
Reasoning output52,591输出的子集
Total13,678,796本轮 input + output

使用量取 attempt 0002 的 usage 增量字段,不把恢复的完整上下文日志再加一遍。两轮累计为 188 requests、26,175,259 total tokens;累计值不是这一次续跑的成本。本报告不估算费用。

全部命令,可筛选与排序
#退出码记录用时命令 / 输出
100
cat hearth/kernel/scene.py
cat hearth/kernel/scene.py
targets = [path] + list(dependents) recipes = {} for p in targets: if p in trial._recipes: recipes[p] = trial._recipes[p] elif p == path and component is not None: n = trial.nodes[p] recipes[p] = (component, n.parameters.get('arguments', {}), n.frame, n.bindings, n.parent, n.scope, n.complete) else: raise ContractError('replay-implementation', p, conditions='Reloaded branch needs an explicitly supplied component implementation') for p in targets: trial._remove_branch(p) for p in targets: comp, oldparams, frame, bindings, parent, scope, complete = recipes[p] if p == path and seed is not None: scope = scope.child('override', seed) trial._instantiate(p, component if p == path and component is not None else comp, params if p == path and params is not None else oldparams, frame, bindings, parent, scope, complete) trial._check(True) self._commit(trial) self.events.append({'kind': 'regenerated', 'targets': targets}) def describe_inputs(value): """Record declared public inputs without concrete-component dispatch.""" if value is None or isinstance(value, (str, int, float, bool)): return value if isinstance(value, (list, tuple)): return [describe_inputs(v) for v in value] if isinstance(value, dict): return {str(k): describe_inputs(v) for k, v in value.items()} if is_dataclass(value): return {'type': type(value).__module__ + '.' + type(value).__qualname__, 'inputs': {f.name: describe_inputs(getattr(value, f.name)) for f in fields(value)}} if callable(value): return {'program': value.__module__ + '.' + value.__qualname__} return {'type': type(value).__module__ + '.' + type(value).__qualname__, 'inputs': {k: describe_inputs(v) for k, v in vars(value).items() if not k.startswith('_')}}
200
cat hearth/kernel/validation.py cat hearth/composition.py cat hearth/space.py
cat hearth/kernel/validation.py cat hearth/composition.py cat hearth/space.py
r turns') object.__setattr__(self, 'turn', self.turn % 4) def vector(self, p: Pos) -> Pos: x, y, z = p for _ in range(self.turn % 4): x, z = -z, x return x, y, z def point(self, p: Pos) -> Pos: return tuple(a + b for a, b in zip(self.origin, self.vector(p))) def inverse(self, p: Pos) -> Pos: return Frame(turn=-self.turn).vector(tuple(a - b for a, b in zip(p, self.origin))) def box(self, box: Box) -> Box: return Box.enclosing(self.point(p) for p in box.corners()) def compose(self, other): return Frame(self.point(other.origin), (self.turn + other.turn) % 4) def state(self, state: str) -> str: from .blocks import parse, state_of name, props = parse(state) dirs = ['north', 'east', 'south', 'west'] rotated = {} for key, value in props.items(): if key in dirs: key = dirs[(dirs.index(key) + self.turn) % 4] if key == 'facing' and value in dirs: value = dirs[(dirs.index(value) + self.turn) % 4] if key in ('shape', 'orientation') and any(v in dirs for v in value.split('_')): from .blocks import SCHEMA tokens = [dirs[(dirs.index(v) + self.turn) % 4] if v in dirs else v for v in value.split('_')] value = '_'.join(tokens) allowed = SCHEMA[name.removeprefix('minecraft:')][0][key] if value not in allowed: matches = [candidate for candidate in allowed if sorted(candidate.split('_')) == sorted(tokens)] if matches: value = sorted(matches)[0] if key == 'axis' and value in ('x', 'z') and self.turn % 2: value = 'z' if value == 'x' else 'x' if key == 'rotation': value = str((int(value) + 4 * self.turn) % 16) rotated[key] = value return state_of(name, **rotated)
300
pwd cat /work/AGENTS.md cat hearth/kernel/contracts.py cat hearth/kernel/view.py
pwd cat /work/AGENTS.md cat hearth/kernel/contracts.py cat hearth/kernel/view.py
opy(p) raise ContractError('missing-port', host, conditions=key) def cost(self, path, tag=None): paths = [key for key, n in self.__scene.nodes.items() if (key == path or key.startswith(path + '/')) and (tag is None or (n.capability and tag in n.capability.tags))] occupied = sum(len(self.__scene.reverse.get(key, ())) for key in paths) replaced = sum(len(self.__scene.displaced.get(key, ())) for key in paths) return {'occupied': occupied, 'replaced': replaced, 'instances': len(paths)} def offers(self, host, kind=None): return tuple(copy.deepcopy(p) for p in self.__scene.nodes[host].contract.ports if kind is None or p.kind == kind) def capability(self, host): return copy.deepcopy(self.__scene.nodes[host].capability) def resolved_port(self, host, key): seen = set() while True: if (host, key) in seen: raise ContractError('port-cycle', host, conditions=key) seen.add((host, key)) port = self.port(host, key) if not port.delegate: return host, port child, key = port.delegate host = host + '/' + child def contract(self, path): if self.__trace: self.__trace.sources[path] = self.__scene.nodes[path].contract.envelope return copy.deepcopy(self.__scene.nodes[path].contract) def protected(self, box): if self.__trace: self.__trace.region(box) return any(r.kind in ('clear', 'protected') and any(box.contains(p) for p in r.cells) for n in self.__scene.nodes.values() for r in n.contract.rules) def obstacle_distance(self, p, radius=8): best = radius + 1 for q in Box(tuple(v - radius for v in p), tuple(v + radius for v in p)).cells(): if q in self.__scene.blocks and not passable(self.__scene.blocks[q].state): best = min(best, max(abs(a - b) for a, b in zip(p, q))) return best
400
python - <<'PY' from pathlib import Path import hashlib,json,subprocess root=Path('.') paths=subprocess.check_output(['rg','--files','hearth','extensi
python - <<'PY' from pathlib import Path import hashlib,json,subprocess root=Path('.') paths=subprocess.check_output(['rg','--files','hearth','extension_demo','examples','test','-g','*.py'],text=True).splitlines()+['generate.py','ARCHITECTURE.md','GENERATOR.md','pyproject.toml'] hashes={p:hashlib.sha256(Path(p).read_bytes()).hexdigest() for p in sorted(paths)} out=Path('reports/extensions-baseline');out.mkdir(parents=True,exist_ok=False) (out/'module-hashes.json').write_text(json.dumps({'phase':'first delivery, before extension phase changes','library_version':'1.1.0','sha256':hashes},indent=2)) (out/'public-api.md').write_text('''# Public API baseline before extension work\n\nVersion 1.1.0. The kernel is unchanged at this snapshot. `module-hashes.json` records source identities.\n\n* A component implements `capability()`, `negotiate(Context, parameters)`, and `realize(Context, Contract) -> Plan`. Leaves and composites use this protocol.\n* `Capability` advertises tags, executable domains, offers, assumptions, adaptation, guarantees and locked inputs. `Contract` holds an envelope, oriented `Port`s, scoped `Grant`s, `Rule`s, decisions and reads.\n* `Context` offers a read-only world-space `View`, local/world transforms, limits and scoped random streams. View provides states, owners, elevation with a height cap, actual support/water, contract/capability/port discovery and protection/clearance.\n* `Plan` submits writes, `Child` and `Choice` components and typed relationships. `Binding` grants a named host/port verb within an optional restriction. No component receives the mutable scene store.\n* `Scene.place/compose_choice/finalize/remove/regenerate` are atomic public operations. Inspection uses `inspect` and exact `cells`, with optional descendants/shared membership.\n* Rules register with `@validator`. Built-in actual-geometry rules include support, clearance, routes, lighting, enclosure and preservation. Extension validators can read the tentative scene.\n* Frames support integer translations and horizontal quarter turns. Continuous design geometry must voxelize before submitting effects.\n* Paired Litematica/JSON transport preserves identities, rules, explicit block properties, NBT and world/export transforms. Reload requires registered extension validators. Generation itself uses portable Python and no filesystem or native geometry engine.\n\nProbe policy: first implement diagonal circulation, curve-following boundaries and public-port connectors in `hearth_extensions`, without kernel edits. Record a concrete failing contract test before any general protocol change. This is a self-authored extension exercise, not an independent audit. Browser execution reported by the user is prior external evidence; this phase must not claim new browser execution unless actually run.\n''') print(f'Baseline saved: {len(hashes)} source/document hashes.') PY
Baseline saved: 45 source/document hashes.
500
cat hearth/components/landscape.py cat hearth/environment/fields.py cat hearth/environment/terrain.py cat test/conftest.py
cat hearth/components/landscape.py cat hearth/environment/fields.py cat hearth/environment/terrain.py cat test/conftest.py
nt', 'ground'), offers=('construction', 'planting'), guarantees=('frozen field inputs', 'actual 3D substrate')) def negotiate(self, ctx, parameters): ports = tuple(Port(k, k, Frame(self.area.lo), self.area, capacity=100000, grant=k) for k in ('construction', 'planting')) grants = (Grant('construction', self.area, ('excavate', 'fill', 'surface'), ('siteworks', 'path', 'pool'), self.edit_limit), Grant('planting', self.area, ('plant',), ('plant',), 0)) return Contract(self.area, ports, grants, decisions={'expression': self.field.expression(), 'water': self.water_level, 'edit_limit': self.edit_limit}) def realize(self, ctx, contract): plan = Plan() x0, bottom, z0 = self.area.lo x1, top, z1 = self.area.hi for x in range(x0, x1 + 1): for z in range(z0, z1 + 1): height = math.floor(self.field(x, z)) if not bottom <= height < top: raise ValueError(f'Terrain field exceeds negotiated vertical domain at {(x,z)}') for y in range(bottom, height + 1): material = 'stone' if y < height - 2 else ('dirt' if y < height else 'grass_block') if self.water_level is not None and height < self.water_level: material = 'gravel' if y == height else material plan.block((x, y, z), state_of(material), 'strata') if self.water_level is not None: for y in range(height + 1, self.water_level + 1): plan.block((x, y, z), state_of('water', level='0'), 'water-volume') return plan # Tests keep transient artifacts under test/ and remove them after each test. import sys import tempfile from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).parents[1])) @pytest.fixture def work(): with tempfile.TemporaryDirectory(dir=Path(__file__).parent, prefix='tmp-') as name: yield Path(name)
600
cat hearth/persistence.py cat hearth/blocks.py
cat hearth/persistence.py cat hearth/blocks.py
raise ValueError('Duplicate block property') props[key] = value return match[1], props def state_of(name: str, **properties) -> str: if not name.startswith('minecraft:'): name = 'minecraft:' + name return name + ('[' + ','.join(f'{k}={str(v).lower()}' for k, v in sorted(properties.items())) + ']' if properties else '') def canonical(state: str) -> str: name, props = parse(state) return state_of(name, **props) def blockstates_equivalent(left: str, right: str) -> bool: return parse(left) == parse(right) @lru_cache(maxsize=4096) def validate_state(state: str): name, props = parse(state) short = name.removeprefix('minecraft:') if short not in SCHEMA: raise ValueError(f'Unknown Java 1.21.1 block: {name}') domain = SCHEMA[short][0] for key, value in props.items(): if key not in domain or value not in domain[key]: raise ValueError(f'Invalid property {key}={value} for {name}') @lru_cache(maxsize=4096) def name_of(state: str) -> str: return parse(state)[0].removeprefix('minecraft:') def solid(state: str) -> bool: name = name_of(state) return name not in SOFT and not any(s in name for s in ('leaves', 'fence', 'pane', 'door', 'lantern', 'chain', 'flower_pot', 'potted_', 'carpet', 'bed', 'button')) def passable(state: str) -> bool: name = name_of(state) return name in SOFT - {'water'} or name.endswith('_door') or name.endswith('_carpet') def stairs(material='stone_brick', facing='north', half='bottom'): return state_of(material + '_stairs', facing=facing, half=half, shape='straight', waterlogged='false') def slab(material='stone_brick', half='bottom'): return state_of(material + '_slab', type=half, waterlogged='false') def log(material='spruce', axis='y'): return state_of(material + '_log', axis=axis) def leaves(material='spruce'): return state_of(material + '_leaves', distance='1', persistent='true', waterlogged='false')
700
sed -n '155,390p' hearth/kernel/scene.py
sed -n '155,390p' hearth/kernel/scene.py
error = SearchExhausted('search-budget', path, conditions=str(rejected)) error.attempts = len(rejected) error.candidates = [d.__dict__ for d in rejected] raise error accepted.sort(key=lambda item: (item[0], item[1])) feasible = [a for a in accepted if a[0] <= accepted[0][0] + choice.tolerance] chosen = scope.child(choice.key).choose(feasible, 'adaptation-selection') self.__dict__.update(chosen[2].__dict__) self.events.append({'kind': 'candidate-selection', 'component': path, 'attempts': len(accepted) + len(rejected), 'accepted': len(accepted), 'rejected': [d.__dict__ for d in rejected], 'scores': [(a[1], round(a[0], 4)) for a in accepted], 'chosen': chosen[1]}) def _retire(self, path): if self.reverse.get(path): raise ContractError('whole-object', path, conditions='Cannot retire occupied instance') node = self.nodes.get(path) if node: for binding in node.bindings: key = (binding.host, binding.port) self.port_uses[key] = max(0, self.port_uses.get(key, 0) - 1) if node: for shared_host, shared_port, point in node.shared_bindings: key = (shared_host, shared_port) self.port_uses[key] = max(0, self.port_uses.get(key, 0) - 1) self.members.pop(path, None) for children in self.members.values(): children.discard(path) self.nodes.pop(path, None) self.reverse.pop(path, None) self._recipes.pop(path, None) self.relations = {r for r in self.relations if r[0] != path and r[2] != path} self.dependencies = [d for d in self.dependencies if d['consumer'] != path and d['source'] != path] self.port_uses = {k: v for k, v in self.port_uses.items() if k[0] != path} def _check(self, final, completed_scope=None): errors = validate(self, final, completed_scope) if errors:
800
cat hearth/components/primitives.py
cat hearth/components/primitives.py
p.fill(Box((0, 0, z), (self.width - 1, self.height - 1, z)), self.glass, 'glazing') if self.shutters: from hearth.blocks import slab for x in (-1, self.width): for y in range(self.height): p.block((x, y, -1), state_of('spruce_trapdoor', facing='north', half='bottom', open='true', powered='false', waterlogged='false'), 'shutters') for x in range(self.width): p.block((x, -1, -1), slab('spruce', 'top'), 'sill') else: for x in range(self.width): p.block((x, self.height - 1, -1), state_of('spruce_trapdoor', facing='north', half='top', open='false', powered='false', waterlogged='false'), 'hood') return p @dataclass(frozen=True) class Pool: width: int = 7 depth: int = 6 def capability(self): return Capability('water.basin', ('pool', 'siteworks'), adaptations=('bounded excavation',), guarantees=('contained water',)) def negotiate(self, ctx, parameters): box = Box((0, -2, 0), (self.width - 1, 0, self.depth - 1)) water = tuple(Box((1, -1, 1), (self.width - 2, 0, self.depth - 2)).cells()) return Contract(box, rules=(Rule('pool', water),), decisions={'excavation_limit': box.volume}) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('smooth_sandstone'), 'basin') p.fill(Box((1, -1, 1), (self.width - 2, 0, self.depth - 2)), state_of('water', level='0'), 'water') return p @dataclass(frozen=True) class Assembly: name: str envelope: Box children: tuple[Child, ...] rules: tuple[Rule, ...] = () ports: tuple[Port, ...] = () def capability(self): return Capability(self.name, ('composite',)) def negotiate(self, ctx, parameters): return Contract(self.envelope, ports=self.ports, rules=self.rules) def realize(self, ctx, contract): return Plan(children=list(self.children))
900
sed -n '1,65p' hearth/components/interior.py sed -n '1,145p' hearth/components/roofs.py cat hearth/kernel/__init__.py
sed -n '1,65p' hearth/components/interior.py sed -n '1,145p' hearth/components/roofs.py cat hearth/kernel/__init__.py
children.append(Child('lantern', Light(), frame=Frame((1, 2, -2)))) return p @dataclass(frozen=True) class Gable: span: int steep: bool = True def capability(self): return Capability('wall.gable', ('wall', 'enclosure'), offers=('window',), adaptations=('abut existing upper wall',)) def negotiate(self, ctx, parameters): height = (self.span + 1) // 2 region = Box((1, 0, 0), (self.span - 2, height - 2, 0)) box = Box((0, -1, -1), (self.span - 1, height - 1, 0)) return Contract(box, (Port('infill', 'wall-installation', Frame((1, 0, 0)), region, 4, 'install', facts={'thickness': 1}),), (Grant('install', region, ('install',), ('window',), 30),)) def realize(self, ctx, contract): p = Plan() for x in range(self.span): step = min(x + 1, self.span - x) y = step if self.steep else (step + 1) // 2 for yy in range(y): if name_of(ctx.view.state(ctx.world((x, yy, 0)))) == 'air': p.block((x, yy, 0), log('spruce') if x in (0, self.span // 2, self.span - 1) else state_of('smooth_sandstone'), 'gable-infill') available = {w.point for w in p.writes} at = (self.span // 2 - 1, 0, 0) if self.steep and all((at[0] + x, y, 0) in available for x in range(2) for y in (0, 1)) and all(name_of(ctx.view.state(ctx.world((at[0] + x, 1, -1)))) == 'air' for x in range(2)): from hearth.kernel import Binding p.children.append(Child('window', Window(2, 2, False), frame=Frame(at), bindings=(Binding(ctx.path, 'infill'),))) return p # Public composition kernel, independent of architectural implementations. from .contracts import Binding, Capability, Child, Choice, Component, Contract, Domain, Grant, Plan, Port, Registry, Rule, Write from .errors import ContractError, Diagnostic, SearchExhausted, ValidationError from .scene import Context, Limits, Scene from .validation import validate, validator
1010
mkdir -p hearth_extensions reports/extension-corpus samples/extensions cat > hearth_extensions/geometry.py <<'PY' # Portable design geometry and deter
mkdir -p hearth_extensions reports/extension-corpus samples/extensions cat > hearth_extensions/geometry.py <<'PY' # Portable design geometry and deterministic voxelization shared by extension components. from dataclasses import dataclass import math from hearth.space import Box CARDINAL = ((1, 0), (-1, 0), (0, 1), (0, -1)) def lattice(value): """Round consistently across native Python and browser Python.""" return math.floor(value + 0.5) @dataclass(frozen=True) class Polyline: points: tuple[tuple[float, float], ...] def __post_init__(self): object.__setattr__(self, 'points', tuple(tuple(p) for p in self.points)) if len(self.points) < 2 or any(len(p) != 2 or not all(math.isfinite(v) for v in p) for p in self.points): raise ValueError('A finite polyline needs at least two two-dimensional points') if any(a == b for a, b in zip(self.points, self.points[1:])): raise ValueError('Repeated consecutive control points') @classmethod def bezier(cls, controls, segments=32): if len(controls) != 4 or not 4 <= segments <= 256: raise ValueError('Cubic curves require four controls and 4..256 samples') points = [] for i in range(segments + 1): t = i / segments weights = ((1 - t)**3, 3 * t * (1 - t)**2, 3 * t*t * (1 - t), t**3) points.append(tuple(sum(w * p[k] for w, p in zip(weights, controls)) for k in (0, 1))) return cls(tuple(points)) @property def length(self): return sum(math.dist(a, b) for a, b in zip(self.points, self.points[1:])) def nearest(self, point): """Return distance, arc length, tangent and projection with stable tie breaks.""" best, walked = None, 0.0 for index, (a, b) in enumerate(zip(self.points, self.points[1:])): dx, dz = b[0] - a[0], b[1] - a[1] length = math.hypot(dx, dz) t = max(0, min(1, ((point[0] - a[0]) * dx + (point[1] - a[1]) * dz) / length**2)) q = (a[0] + t * dx, a[1] + t * dz) item = (math.dist(point, q), walked + t * length, index, (dx / length, dz / length), q) if best is None or item[:3] < best[:3]: best = item walked += length return best[0], best[1], best[3], best[4] def cells(self): """Rasterize a connected cardinal chain, retaining explicit diagonal turns.""" result = [] for a, b in zip(self.points, self.points[1:]): count = max(1, math.ceil(math.dist(a, b) * 4)) for i in range(count + 1): target = tuple(lattice(a[k] + (b[k] - a[k]) * i / count) for k in (0, 1)) if not result: result.append(target) while result[-1] != target: x, z = result[-1] tx, tz = target candidates = [] if x != tx: candidates.append((x + (1 if tx > x else -1), z)) if z != tz: candidates.append((x, z + (1 if tz > z else -1))) result.append(min(candidates, key=lambda p: (self.nearest(p)[0], p))) return tuple(result) def ribbon(self, radius, caps=False): xmin = math.floor(min(p[0] for p in self.points) - radius) xmax = math.ceil(max(p[0] for p in self.points) + radius) zmin = math.floor(min(p[1] for p in self.points) - radius) zmax = math.ceil(max(p[1] for p in self.points) + radius) a, b = self.points[0], self.points[-1] start = (self.points[1][0] - a[0], self.points[1][1] - a[1]) end = (b[0] - self.points[-2][0], b[1] - self.points[-2][1]) result = [] for x in range(xmin, xmax + 1): for z in range(zmin, zmax + 1): if not caps and ((x-a[0])*start[0] + (z-a[1])*start[1] < 0 or (x-b[0])*end[0] + (z-b[1])*end[1] > 0): continue if self.nearest((x, z))[0] <= radius + 0.05: result.append((x, z)) return tuple(result) @dataclass(frozen=True) class Polygon: vertices: tuple[tuple[int, int], ...] def __post_init__(self): object.__setattr__(self, 'vertices', tuple(tuple(p) for p in self.vertices)) if len(self.vertices) < 3: raise ValueError('At least three polygon vertices required') @classmethod def chamfered(cls, width, depth, corner=0): if not 9 <= width <= 27 or not 9 <= depth <= 27 or not 0 <= corner <= min(width, depth)//3: raise ValueError('Footprint domain: dimensions 9..27, corner 0..one third') x, z, c = width-1, depth-1, corner return cls(((0,0),(x,0),(x,z),(0,z)) if not c else ((c,0),(x-c,0),(x,c),(x,z-c),(x-c,z),(c,z),(0,z-c),(0,c))) def cells(self): result = [] for x in range(min(p[0] for p in self.vertices), max(p[0] for p in self.vertices)+1): for z in range(min(p[1] for p in self.vertices), max(p[1] for p in self.vertices)+1): inside = False edge = False for a, b in zip(self.vertices, self.vertices[1:]+self.vertices[:1]): cross = (x-a[0])*(b[1]-a[1])-(z-a[1])*(b[0]-a[0]) if cross == 0 and min(a[0],b[0]) <= x <= max(a[0],b[0]) and min(a[1],b[1]) <= z <= max(a[1],b[1]): edge = True if (a[1] > z) != (b[1] > z) and x < (b[0]-a[0])*(z-a[1])/(b[1]-a[1])+a[0]: inside = not inside if edge or inside: result.append((x,z)) return tuple(result) def perimeter(cells, diagonal=False): points = set(cells) steps = tuple((x,z) for x in (-1,0,1) for z in (-1,0,1) if x or z) if diagonal else CARDINAL return tuple(sorted(p for p in points if any((p[0]+dx,p[1]+dz) not in points for dx,dz in steps))) def bounds2(points, low, high): return Box((min(p[0] for p in points), low, min(p[1] for p in points)), (max(p[0] for p in points), high, max(p[1] for p in points))) PY cat > hearth_extensions/interfaces.py <<'PY' # Public endpoint discovery and orientation checks shared by circulation components. from dataclasses import dataclass from hearth import Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Rule @dataclass(frozen=True) class Endpoint: host: str port: str def binding(self): return Binding(self.host, self.port, 'connect') def resolve(self, ctx): port = ctx.view.port(self.host, self.port) if port.kind not in ('access', 'public-access'): raise ContractError('endpoint-kind', ctx.path, port.frame.origin, 'Require an access or public-access port') at = ctx.local(port.frame.origin) turn = (port.frame.turn - ctx.frame.turn) % 4 outward = Frame(turn=turn).vector((0,0,-1)) return port, at, (outward[0], outward[2]) @dataclass(frozen=True) class EndpointContact: endpoint: Endpoint def capability(self): return Capability('extension.endpoint-contact', ('connection',), guarantees=('unchanged supported endpoint',)) def negotiate(self, ctx, parameters): port, at, direction = self.endpoint.resolve(ctx) box = ctx.frame.box(ctx.view.contract(self.endpoint.host).envelope) if False else None from hearth.space import Box return Contract(Box(at, at).expand(1), rules=(Rule('support', ((at[0],at[1]-1,at[2]),)), Rule('clear', (at,(at[0],at[1]+1,at[2]))))) def realize(self, ctx, contract): return Plan() PY cat > hearth_extensions/__init__.py <<'PY' # Components developed against Hearth's public protocol in the second development phase. from .geometry import Polyline, Polygon from .interfaces import Endpoint, EndpointContact PY cat > test/test_extension_protocol.py <<'PY' # A read-only endpoint consumer must not need the host's mutation authority. import pytest from hearth import Scene, Box from hearth.kernel import Capability, Contract, Port, Grant, Plan from hearth.space import Frame from hearth.blocks import state_of from hearth_extensions import Endpoint, EndpointContact class Landing: def capability(self): return Capability('test.landing', ('landing',)) def negotiate(self, ctx, parameters): return Contract(Box((-1,0,-1),(1,0,1)), ports=(Port('access','access',Frame((0,1,0)),Box((-1,0,-1),(1,2,1)),4,'resurface'),), grants=(Grant('resurface',Box((-1,0,-1),(1,0,1)),('surface',),('path',),9),)) def realize(self, ctx, contract): p=Plan() p.fill(contract.envelope,state_of('stone_bricks')) return p def test_read_only_connection_to_mutable_port(): s=Scene() s.place('landing',Landing()) endpoint=Endpoint('/landing','access') before=dict(s.blocks) s.place('consumer',EndpointContact(endpoint),bindings=(endpoint.binding(),)) assert s.blocks==before assert ('/consumer','connected_to','/landing') in s.relations s.finalize() PY python -m pytest -q test/test_extension_protocol.py > reports/extensions-baseline/failing-connect-probe.txt
1100
tail -n 17 reports/extensions-baseline/failing-connect-probe.txt
tail -n 17 reports/extensions-baseline/failing-connect-probe.txt
raise ContractError('port-capacity', path, port.frame.origin, binding.port) self.port_uses[use_key] = self.port_uses.get(use_key, 0) + 1 if binding.verb == 'install': if not port.region.contains(frame.origin): raise ContractError('port-alignment', path, frame.origin, 'Origin outside installation region') if port.frame.inverse(frame.origin)[0] % port.alignment or frame.turn % 4 != port.frame.turn % 4: raise ContractError('port-alignment', path, frame.origin, 'Outside facade bay grid') grant = next((g for g in host.contract.grants if g.key == port.grant), None) if grant: if binding.verb not in grant.verbs or (grant.tags and not set(cap.tags).intersection(grant.tags)): > raise ContractError('permission-kind', path, frame.origin, f'{cap.tags} cannot {binding.verb} {binding.host}') E hearth.kernel.errors.ContractError: permission-kind: /consumer at (0, 0, 0): ('connection',) cannot connect /landing hearth/kernel/scene.py:236: ContractError =========================== short test summary info ============================ FAILED test/test_extension_protocol.py::test_read_only_connection_to_mutable_port 1 failed in 0.06s
1200
cat > reports/extensions-baseline/api-delta.md <<'MD' # Protocol delta after the executable connection probe `test_read_only_connection_to_mutable_po
cat > reports/extensions-baseline/api-delta.md <<'MD' # Protocol delta after the executable connection probe `test_read_only_connection_to_mutable_port` failed against unchanged Hearth 1.1.0: `permission-kind` prevented a consumer from connecting to a landing that also offered a restricted resurfacing grant. See `failing-connect-probe.txt`. The extension submitted no writes and required actual support/headroom at the public endpoint. The general fix is in `Scene._instantiate`: `Binding(..., verb='connect')` now records a read-only connection, capacity use and dependency without acquiring a mutation grant, whether or not the port also has a grant. All other verbs retain their original checks. A connection never authorizes writing to the host. The extension cannot implement this using its own effects because binding permissions are enforced by the kernel before effects are applied; requesting unrelated mutation permission would misrepresent its authority. No component-name dispatch or signature change was added. The regression suite adds a negative case proving that a connected consumer cannot overwrite the landing. Old artifact structures and serialized contract schemas are unchanged. This is a self-authored extension/protocol exercise, not independent review. MD cat >> test/test_extension_protocol.py <<'PY' def test_connection_does_not_acquire_write_authority(): from hearth.kernel import ContractError class Bad(EndpointContact): def realize(self, ctx, contract): p=Plan() p.block((0,0,0),state_of('gold_block')) return p s=Scene() s.place('landing',Landing()) endpoint=Endpoint('/landing','access') before=dict(s.blocks) with pytest.raises(ContractError,match='write-authority'): s.place('bad',Bad(endpoint),bindings=(endpoint.binding(),)) assert s.blocks==before and '/bad' not in s.nodes PY yapf -i hearth_extensions/geometry.py hearth_extensions/interfaces.py hearth_extensions/__init__.py test/test_extension_protocol.py hearth/kernel/scene.py python -m pytest -q test/test_extension_protocol.py test/test_kernel.py test/test_contracts_provenance.py > reports/extension-corpus/kernel-regression.txt
1300
cat > hearth_extensions/circulation.py <<'PY' # Measured ribbon circulation, support grids and guard geometry through public contracts. from dataclass
cat > hearth_extensions/circulation.py <<'PY' # Measured ribbon circulation, support grids and guard geometry through public contracts. from dataclasses import dataclass import math from hearth import Box, Frame, Binding, ContractError from hearth.blocks import state_of, stairs, slab, log, solid, passable, name_of from hearth.kernel import Capability, Domain, Contract, Port, Grant, Plan, Rule, Child, validator, Diagnostic from .geometry import Polyline, CARDINAL, bounds2, perimeter, lattice from .interfaces import Endpoint @validator('extension.guard') def guard_rule(scene, node, rule): for p in rule.cells: if name_of(scene.view.state(p)) not in ('spruce_fence','spruce_log','stone_brick_wall'): yield Diagnostic('bridge-guard',node.path,p,'A required outer guard cell is absent') @validator('extension.span') def span_rule(scene, node, rule): supports=[node.frame.point(tuple(p)) for p in rule.data['anchors']] for p in rule.cells: if not supports or min(abs(p[0]-q[0])+abs(p[2]-q[2]) for q in supports)>rule.data['maximum']: yield Diagnostic('unsupported-span',node.path,p,'Deck exceeds declared supported horizontal span') @dataclass(frozen=True) class Surface: points: tuple role: str = 'deck' material: str = 'spruce_planks' def capability(self): return Capability('extension.'+self.role,('path','siteworks',self.role)) def negotiate(self,ctx,parameters): box=Box.enclosing(self.points) return Contract(box,rules=(Rule('support',self.points),)) def realize(self,ctx,contract): p=Plan() heights={(x,z):y for x,y,z in self.points} for x,y,z in self.points: uphill=next((face for dx,dz,face in ((1,0,'east'),(-1,0,'west'),(0,1,'south'),(0,-1,'north')) if heights.get((x+dx,z+dz),y)==y+1),None) p.block((x,y,z),stairs('spruce',uphill) if uphill else state_of(self.material),'walk-surface') return p @dataclass(frozen=True) class Trestles: columns: tuple maximum: int = 8 def capability(self): return Capability('extension.trestles',('siteworks','support'),adaptations=('posts to actual bed','stone shoes'),inputs={'maximum':Domain(2,8)}) def negotiate(self,ctx,parameters): cells=tuple((x,y,z) for x,bed,z,top,wet in self.columns for y in range(bed-1,top+1)) if any(top-bed>self.maximum for x,bed,z,top,wet in self.columns): raise ContractError('connection-support-height',ctx.path,conditions=f'Post exceeds {self.maximum}') return Contract(Box.enclosing(cells),rules=(Rule('support',cells),),decisions={'columns':self.columns}) def realize(self,ctx,contract): p=Plan() for x,bed,z,top,wet in self.columns: for y in range(bed+1,top+1): p.block((x,y,z),state_of('stone_bricks') if y==bed+1 or not wet else log(),'pier') return p @dataclass(frozen=True) class Guards: points: tuple covered: bool = False roof: tuple = () def capability(self): return Capability('extension.guards',('railing','roof' if self.covered else 'guard'),guarantees=('continuous outer guard',)) def negotiate(self,ctx,parameters): return Contract(Box.enclosing((*self.points,*self.roof)).expand(1),rules=(Rule('extension.guard',self.points),)) def realize(self,ctx,contract): p=Plan() occupied={(x,z) for x,y,z in self.points} for i,(x,y,z) in enumerate(self.points): connections={face:str((x+dx,z+dz) in occupied).lower() for dx,dz,face in ((1,0,'east'),(-1,0,'west'),(0,1,'south'),(0,-1,'north'))} p.block((x,y,z),state_of('spruce_fence',waterlogged='false',**connections),'guard') if self.covered: for yy in (y+1,y+2): p.block((x,yy,z),log() if i%5==0 else state_of('spruce_fence',waterlogged='false',**connections),'gallery-frame') for x,y,z in self.roof: p.block((x,y,z),slab('dark_oak','top'),'gallery-canopy') return p @dataclass(frozen=True) class Link: start: Endpoint end: Endpoint terrain: str via: tuple = () curve: Polyline | None = None width: int = 3 rise: int = 0 covered: bool = False max_post: int = 8 max_span: int = 6 max_length: int = 120 fill_limit: int = 800 def capability(self): return Capability('extension.gallery' if self.covered else 'extension.bridge',('connection','path','composite'),offers=('access',),adaptations=('bounded height profile','actual-bed trestles','supported deck reuse at endpoints'),guarantees=('both public endpoints reachable','two-cell headroom','outer guard'),inputs={'width':Domain(choices=(3,5)),'rise':Domain(0,3),'max_post':Domain(2,8),'max_span':Domain(3,6)},locked=('start','end','via','curve','width','covered')) def negotiate(self,ctx,parameters): pa,a,da=self.start.resolve(ctx) pb,b,db=self.end.resolve(ctx) required={(self.start.host,self.start.port),(self.end.host,self.end.port)} if not required.issubset({(v.host,v.port) for v in ctx.bindings if v.verb=='connect'}): raise ContractError('endpoint-binding',ctx.path,conditions='Both endpoints need explicit read-only connection bindings') points=((a[0],a[2]),(a[0]+3*da[0],a[2]+3*da[1]),*self.via,(b[0]+3*db[0],b[2]+3*db[1]),(b[0],b[2])) curve=self.curve or Polyline(tuple(points)) if curve.points[0]!=(a[0],a[2]) or curve.points[-1]!=(b[0],b[2]): raise ContractError('endpoint-disconnected',ctx.path,ctx.world(a),'Curve ends must match the negotiated public ports') for point,next_point,direction in ((curve.points[0],curve.points[1],da),(curve.points[-1],curve.points[-2],db)): delta=(next_point[0]-point[0],next_point[1]-point[1]) if delta[0]*direction[1]-delta[1]*direction[0]!=0 or delta[0]*direction[0]+delta[1]*direction[1]<=0: raise ContractError('endpoint-frame',ctx.path,ctx.world((int(point[0]),a[1],int(point[1]))),'First and last tangents must point out of the host') center=curve.cells() if len(set(center))!=len(center) or curve.length>self.max_length or curve.length<7: raise ContractError('connection-domain',ctx.path,conditions='Need a simple route of length 7..maximum') radius=self.width//2+1 deck=curve.ribbon(radius+.2) station={p:min(range(len(center)),key=lambda i:(math.dist(p,center[i]),i)) for p in deck} count=len(center) heights=[lattice((a[1]-1)*(1-i/(count-1))+(b[1]-1)*i/(count-1)+self.rise*math.sin(math.pi*i/(count-1))) for i in range(count)] beds={} waters={} endpoint_regions=(pa.region,pb.region) for x,z in deck: cap=max(a[1],b[1])+self.rise+2 bed=ctx.elevation(x,z,maximum=cap) water=ctx.water(x,z) beds[(x,z)]=bed waters[(x,z)]=water i=station[(x,z)] heights[i]=max(heights[i],bed,water+1 if water is not None else bed) # Minimal upward propagation, preserving fixed endpoint elevations. for i in range(1,count): heights[i]=max(heights[i],heights[i-1]-1) for i in range(count-2,-1,-1): heights[i]=max(heights[i],heights[i+1]-1) if heights[0]!=a[1]-1 or heights[-1]!=b[1]-1: raise ContractError('endpoint-grade',ctx.path,ctx.world(a),'Measured ground/water cannot meet the locked endpoint heights') outer=set(perimeter(deck)) guards=[] clear=[] all_deck=[] writes=[] for x,z in deck: i=station[(x,z)] y=heights[i] q=ctx.world((x,y,z)) host_region=any(region.contains(q) for region in endpoint_regions) is_guard=(x,z) in outer and 2<i<count-3 and not host_region all_deck.append((x,y,z)) if is_guard: guards.append((x,y+1,z)) else: clear.extend(((x,y+1,z),(x,y+2,z))) existing=ctx.view.state(q) if solid(existing) and host_region: continue writes.append((x,y,z)) anchors=[] for x,z in sorted(deck,key=lambda p:(station[p],p)): if any(abs(x-u)+abs(z-v)<=self.max_span for u,v in anchors): continue # Prefer the central route where possible, then cover wide diagonal corners. near=center[station[(x,z)]] anchor=near if near in beds else (x,z) if anchor in anchors: anchor=(x,z) anchors.append(anchor) columns=[] for x,z in anchors: top=heights[station[(x,z)]]-1 bed=min(beds[(x,z)],top) while not ctx.view.supports(ctx.world((x,bed,z))): bed-=1 if top-bed>self.max_post: raise ContractError('connection-support-height',ctx.path,ctx.world((x,top,z))) if not ctx.view.supports(ctx.world((x,bed-1,z))): raise ContractError('connection-bed',ctx.path,ctx.world((x,bed-1,z)),'Need two actual supporting bed cells') columns.append((x,bed,z,top,waters[(x,z)] is not None)) fill=sum(max(0,top-bed) for x,bed,z,top,wet in columns) if fill>self.fill_limit: raise ContractError('connection-fill-limit',ctx.path,conditions=f'{fill}>{self.fill_limit}') roof=tuple((x,y+5,z) for x,y,z in all_deck if self.covered and 3<station[(x,z)]<count-4) guard_points=tuple(guards) low=min(min(beds.values())-1,min(heights)) envelope=bounds2(deck,low,max(heights)+7).expand(1) center_route=tuple((x,heights[i]+1,z) for i,(x,z) in enumerate(center)) rules=(Rule('route',(a,*center_route,b),envelope,phase='complete'),Rule('support',tuple(all_deck)),Rule('clear',tuple(clear)),Rule('extension.span',tuple(all_deck),data={'anchors':[(x,0,z) for x,z in anchors],'maximum':self.max_span})) return Contract(envelope,ports=(Port('start','access',Frame(a),Box(a,a),8),Port('end','access',Frame(b),Box(b,b),8)),rules=rules,decisions={'curve':curve.points,'center':center,'profile':heights,'deck':all_deck,'writes':writes,'guards':guard_points,'columns':columns,'roof':roof,'fill':fill,'width':self.width,'covered':self.covered,'rise':self.rise,'endpoint_regions':[[r.lo,r.hi] for r in endpoint_regions]},reads=(envelope,)) def realize(self,ctx,contract): d=contract.decisions terrain=(Binding(self.terrain,'construction','fill',ctx.frame.box(contract.envelope)),) p=Plan(children=[Child('supports',Trestles(tuple(d['columns']),self.max_post),bindings=terrain),Child('deck',Surface(tuple(d['writes'])),bindings=terrain),Child('guards',Guards(tuple(d['guards']),self.covered,tuple(d['roof'])))]) p.relations.extend(((ctx.path,'connects',self.start.host),(ctx.path,'connects',self.end.host))) return p def connection(key,start,end,terrain,**parameters): """Create a fully bound link through public endpoint references.""" return Child(key,Link(start,end,terrain,**parameters),bindings=(start.binding(),end.binding())) PY cat > hearth_extensions/boundaries.py <<'PY' # Curve-following masonry with sampled installation sockets and grounded adaptation. from dataclasses import dataclass from hearth import Box,Frame,Binding,ContractError from hearth.kernel import Capability,Contract,Domain,Port,Grant,Plan,Rule,Child from hearth.blocks import state_of,slab from .geometry import Polyline,bounds2 @dataclass(frozen=True) class Boundary: curve: Polyline height: int = 2 spacing: int = 7 max_step: int = 1 def capability(self): return Capability('extension.curved-boundary',('boundary','siteworks','composite'),offers=('mount','end'),inputs={'height':Domain(1,5),'spacing':Domain(4,12)},adaptations=('terrain-following base','stepped coping'),guarantees=('continuous cardinal contour','grounded boundary','mount sockets')) def negotiate(self,ctx,parameters): center=self.curve.cells() if len(center)>220 or len(set(center))!=len(center): raise ContractError('boundary-domain',ctx.path,conditions='Simple open contour, at most 220 raster cells') levels=[ctx.elevation(x,z) for x,z in center] if any(abs(a-b)>self.max_step for a,b in zip(levels,levels[1:])): raise ContractError('boundary-grade',ctx.path,conditions='Adjacent wall foundations exceed step bound') ports=[] grants=[] for i in range(2,len(center)-2,self.spacing): x,z=center[i] y=levels[i]+self.height+2 x0,z0=center[max(0,i-1)];x1,z1=center[min(len(center)-1,i+1)] turn=0 if abs(x1-x0)>=abs(z1-z0) else 1 at=(x,y,z) key=f'mount-{i}' box=Box(at,at) ports.append(Port(key,'mount',Frame(at,turn),box,1,key,facts={'support':(x,y-1,z),'load':'small-fixture'})) grants.append(Grant(key,box,('install',),('fixture',),0)) supports=tuple((x,levels[i],z) for i,(x,z) in enumerate(center)) shell=tuple((x,y,z) for i,(x,z) in enumerate(center) for y in range(levels[i]+1,levels[i]+self.height+2)) box=Box.enclosing((*supports,*shell)).expand(2) return Contract(box,tuple(ports),tuple(grants),(Rule('support',supports),Rule('sealed',shell)),decisions={'center':center,'levels':levels,'height':self.height},reads=(box,)) def realize(self,ctx,contract): p=Plan() d=contract.decisions rng=ctx.rng('masonry') for i,(x,z) in enumerate(d['center']): for y in range(d['levels'][i]+1,d['levels'][i]+self.height+1): p.block((x,y,z),state_of(rng.choice(('stone_bricks','stone_bricks','mossy_stone_bricks'))),'contour-masonry') p.block((x,d['levels'][i]+self.height+1,z),slab('stone_brick','top'),'coping') return p @dataclass(frozen=True) class BoundaryLantern: def capability(self): return Capability('extension.boundary-lantern',('fixture','light'),guarantees=('mounted actual light',)) def negotiate(self,ctx,parameters): return Contract(Box((0,0,0),(0,1,0)),rules=(Rule('support',((0,-1,0),)),Rule('expected',((0,0,0),),data={'names':['lantern']})),atomic_object=True) def realize(self,ctx,contract): p=Plan() p.block((0,0,0),state_of('lantern',hanging='false',waterlogged='false'),'lamp') return p @dataclass(frozen=True) class IlluminateBoundary: host: str every: int = 1 def capability(self): return Capability('extension.boundary-lighting',('composite',)) def negotiate(self,ctx,parameters): ports=ctx.view.offers(self.host,'mount')[::self.every] if not ports: raise ContractError('missing-mounts',ctx.path) return Contract(Box.enclosing(ctx.local(p.frame.origin) for p in ports).expand(1)) def realize(self,ctx,contract): p=Plan() for port in ctx.view.offers(self.host,'mount')[::self.every]: frame=Frame(ctx.local(port.frame.origin),(port.frame.turn-ctx.frame.turn)%4) p.children.append(Child(port.key,BoundaryLantern(),frame=frame,bindings=(Binding(self.host,port.key),))) return p PY yapf -i hearth_extensions/circulation.py hearth_extensions/boundaries.py
1411
cat > hearth_extensions/sites.py <<'PY' # Accessible platforms with measured supports and oriented edge ports. from dataclasses import dataclass from
cat > hearth_extensions/sites.py <<'PY' # Accessible platforms with measured supports and oriented edge ports. from dataclasses import dataclass from hearth import Box,Frame,Binding,ContractError from hearth.kernel import Capability,Contract,Plan,Child,Port,Rule,Domain from hearth.blocks import state_of from hearth.adapters.site import Foundation,SiteLimits,survey from .geometry import Polygon,bounds2 from .circulation import Surface DIRECTIONS={'north':(0,-1,0),'east':(1,0,1),'south':(0,1,2),'west':(-1,0,3)} def edge_frames(width,depth,height): return {'north':Frame((width//2,height,0),0),'east':Frame((width-1,height,depth//2),1),'south':Frame((width//2,height,depth-1),2),'west':Frame((0,height,depth//2),3)} @dataclass(frozen=True) class Platform: terrain: str width: int = 9 depth: int = 9 freeboard: int = 1 def capability(self): return Capability('extension.platform',('platform','composite','habitable'),offers=('access',),inputs={'width':Domain(5,27),'depth':Domain(5,27),'freeboard':Domain(1,3)}) def negotiate(self,ctx,parameters): footprint=tuple((x,z) for x in range(self.width) for z in range(self.depth)) samples=survey(ctx,footprint) y=samples['floor']+self.freeboard-1 region=bounds2(footprint,min(v[0] for v in samples['samples'].values())-1,y+3) ports=tuple(Port(k,'access',f,f.box(Box((-2,-1,0),(2,1,0))),8) for k,f in edge_frames(self.width,self.depth,y+1).items()) return Contract(region,ports=ports,decisions={'floor':y,'footprint':footprint,'strategy':samples['strategy']},rules=(Rule('route',tuple(f.frame.origin for f in ports),region,phase='complete'),)) def realize(self,ctx,contract): d=contract.decisions p=Plan(children=[Child('foundation',Foundation(tuple(d['footprint']),d['floor'],d['strategy']),bindings=(Binding(self.terrain,'construction','fill'),)),Child('deck',Surface(tuple((x,d['floor'],z) for x,z in d['footprint']),role='platform'))]) return p PY cat >> hearth_extensions/__init__.py <<'PY' from .circulation import Link, connection from .boundaries import Boundary, BoundaryLantern, IlluminateBoundary from .sites import Platform PY cat > test/test_extension_geometry.py <<'PY' # Extension-only probes for non-cardinal circulation and curve interfaces. from dataclasses import replace import pytest from hearth import Scene,Box,Frame,Binding,ContractError from hearth.kernel import validate,Child,Plan from hearth.components.primitives import Volume from hearth.environment import Terrain,gradient,wave from hearth.blocks import state_of from hearth.persistence import export_scene,load_scene,semantic_digest from hearth_extensions import Polyline,Endpoint,Link,Boundary,IlluminateBoundary,Platform def bridge_scene(seed=0,water=3): s=Scene(seed,domain=Box((-8,-4,-8),(45,42,45))) s.place('land',Terrain(s.domain,gradient(.02,.01,1)+wave(.2,.1,.15,seed),water)) s.place('a',Platform('/land'),frame=Frame((0,0,0))) s.place('b',Platform('/land'),frame=Frame((18,0,27))) a,b=Endpoint('/a','south'),Endpoint('/b','north') s.place('link',Link(a,b,'/land',rise=1),bindings=(a.binding(),b.binding())) return s.finalize() def test_diagonal_bridge_actual_route_support_railings_and_reload(work): s=bridge_scene() assert any(n.type=='extension.trestles' for n in s.nodes.values()) assert len(set(x for x,z in s.nodes['/link'].contract.decisions['center']))>5 assert not validate(s,True) p=next(iter(s.cells('/link/deck'))) q=s.inspect(p) assert any('connect' in str(r) for r in s.inspect(p)['related']) or ('/link','connects','/a') in s.relations export_scene(s,work/'diagonal bridge.litematic') t=load_scene(work/'diagonal bridge.litematic') assert t.inspect(p)==q and semantic_digest(t)==semantic_digest(s) def test_curve_boundary_interfaces_and_external_attachment(): s=Scene(3,domain=Box((-5,-4,-5),(45,35,35))) s.place('land',Terrain(s.domain,gradient(.015,.01,3))) curve=Polyline.bezier(((0,0),(7,25),(28,-3),(37,20))) s.place('boundary',Boundary(curve)) s.place('lamps',IlluminateBoundary('/boundary')) s.finalize() ports=s.view.offers('/boundary','mount') assert len(ports)>3 p=ports[0].frame.origin q=s.inspect(p) assert q['chain'][1]['instance']=='/boundary' assert p in s.cells('/boundary',descendants=True) PY yapf -i hearth_extensions/sites.py hearth_extensions/__init__.py test/test_extension_geometry.py python -m pytest -q test/test_extension_geometry.py > reports/extension-corpus/first-geometry-probes.txt
1500
tail -n 55 reports/extension-corpus/first-geometry-probes.txt cat reports/extension-corpus/kernel-regression.txt
tail -n 55 reports/extension-corpus/first-geometry-probes.txt cat reports/extension-corpus/kernel-regression.txt
.F [100%] =================================== FAILURES =================================== ____________ test_curve_boundary_interfaces_and_external_attachment ____________ def test_curve_boundary_interfaces_and_external_attachment(): s = Scene(3, domain=Box((-5, -4, -5), (45, 35, 35))) s.place('land', Terrain(s.domain, gradient(.015, .01, 3))) curve = Polyline.bezier(((0, 0), (7, 25), (28, -3), (37, 20))) s.place('boundary', Boundary(curve)) s.place('lamps', IlluminateBoundary('/boundary')) s.finalize() ports = s.view.offers('/boundary', 'mount') assert len(ports) > 3 p = ports[0].frame.origin q = s.inspect(p) > assert q['chain'][1]['instance'] == '/boundary' ^^^^^^^^^^^^^^^^^^^^^^^^^ E KeyError: 'instance' test/test_extension_geometry.py:47: KeyError =========================== short test summary info ============================ FAILED test/test_extension_geometry.py::test_curve_boundary_interfaces_and_external_attachment 1 failed, 1 passed in 1.47s ........................... [100%] 27 passed in 0.52s
1600
sed -n '395,449p' hearth/kernel/scene.py sed -n '1,130p' test/test_kernel.py
sed -n '395,449p' hearth/kernel/scene.py sed -n '1,130p' test/test_kernel.py
xis='z') path = work / 'space name.litematic' export_scene(s, path) restored = load_scene(path) assert restored.inspect((14, 3, -5)) == s.inspect((14, 3, -5)) assert blockstates_equivalent('minecraft:oak_stairs[facing=north,half=bottom]', 'minecraft:oak_stairs[half=bottom,facing=north]') assert not blockstates_equivalent('minecraft:oak_log', 'minecraft:oak_log[axis=y]') import json meta = path.with_suffix('.litematic.structure.json') data = json.loads(meta.read_text()) data['digest'] = 'bad' meta.write_text(json.dumps(data)) with pytest.raises(ContractError, match='geometry-mismatch'): load_scene(path) def test_clearance_rollback_and_bounds(): s = Scene() s.place('stairs', Assembly('circulation', Box((0, 0, 0), (3, 5, 3)), (), (Rule('clear', ((1, 2, 1), (1, 3, 1))),))) with pytest.raises(ContractError, match='clearance'): s.place('decoration', Volume(Box((1, 3, 1), (1, 3, 1)), state_of('stone'))) assert set(s.nodes) == {'/stairs'} and not s.blocks @dataclass class Escaper: def capability(self): return Capability('bad', ()) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((1, 0, 0), state_of('stone')) return p with pytest.raises(ContractError, match='envelope'): s.place('bad', Escaper()) def test_seed_stability_and_regeneration(): from hearth.randomness import Scope a = Scope(123).child('house') before = a.stream('layout').getrandbits(64) Scope(123).child('failed').stream().random() assert before == a.stream('layout').getrandbits(64) s = Scene() s.place('beam', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('stone'))) s.regenerate('/beam', Volume(Box((0, 0, 0), (1, 0, 0)), state_of('oak_planks'))) assert s.inspect((2, 0, 0))['instance'] is None assert len(s.cells('/beam')) == 2
1700
cat > reports/extension-corpus/sampling-policy.json <<'JSON' { "phase": "extension", "version": 1, "root_seed": 0, "frozen_before_assessment": tru
cat > reports/extension-corpus/sampling-policy.json <<'JSON' { "phase": "extension", "version": 1, "root_seed": 0, "frozen_before_assessment": true, "connectors": {"environment_seeds": [0,7], "structure_seeds": [0,5], "count": 48, "policy": "Eight independently frozen generic terrain expressions, each copied for six width/rise/cover/curve decisions. Locked platforms and public endpoints. Gradients bounded by 0.035, waves 0..0.7, radial depression 0..2, optional water level 3. Width 3 or 5, rise 0..2, post height <=8, maximum unsupported taxicab deck span 6, fill <=800. No resampling."}, "boundaries": {"count": 16, "policy": "Four environment seeds by four independently seeded cubic controls, height 1..3 and socket spacing 4..10. Include a zero-curvature line. Maximum base change one block per raster step."}, "halls": {"count": 12, "policy": "Seeds 0..11, variable polygon widths/depths 13..25, chamfer 0..4, ceiling 5..7, hip or hip with lantern. Functions, entrances and proportions locked before site query."}, "compositions": {"count": 12, "policy": "Two lightweight public graph clients, seeds 0..5. One branching campus, one perimeter cluster. Preserve locked vertices and declared graph edges. Includes existing Hearth buildings substituted for polygon halls."}, "stress": {"count": 24, "policy": "Single locked endpoint pair per input. Independent environment seeds 2000..2023, gradients through 0.28, waves through 4, water through 12, profile rise 0..3. Retain every success and failure without resampling or widened bounds."}, "novel_compositions": "Focused tests additionally use an unsampled kinked polyline and a polygon footprint not used in the two shipped clients.", "metrics": ["input outcome", "candidate acceptance", "all diagnostics", "runtime", "actual edit cost", "principal geometry/topology signature", "contact signature"], "claims": "Self-authored finite extension exercise, not independent audit. Prior external Pyodide results are user-reported; this phase claims only execution actually performed here." } JSON python - <<'PY' from pathlib import Path p=Path('test/test_extension_geometry.py');s=p.read_text().replace("q['chain'][1]['instance']", "q['chain'][1]['id']");p.write_text(s) PY cat > hearth_extensions/halls.py <<'PY' # Polygon halls, public facade installation and concentric hipped roof components. from dataclasses import dataclass from hearth import Box,Frame,Binding,ContractError from hearth.kernel import Capability,Contract,Port,Grant,Rule,Plan,Child,Domain,Context from hearth.blocks import state_of,log,slab,stairs from hearth.adapters.site import survey,Foundation,Approach,SiteLimits from hearth.components.interior import Door,Light,Furniture from hearth.components.primitives import Window from .geometry import Polygon,CARDINAL,bounds2,perimeter from .sites import edge_frames from .circulation import Surface @dataclass(frozen=True) class PolygonShell: footprint: Polygon height: int = 5 entrances: tuple = ('north','south') def capability(self): return Capability('extension.polygon-shell',('wall','enclosure'),offers=('wall-installation',),guarantees=('continuous enclosure','protected floor support'),inputs={'height':Domain(5,7)}) def negotiate(self,ctx,parameters): footprint=self.footprint.cells() shell=perimeter(footprint,diagonal=True) xs=[x for x,z in footprint];zs=[z for x,z in footprint] width,depth=max(xs)+1,max(zs)+1 if min(xs)!=0 or min(zs)!=0: raise ContractError('polygon-origin',ctx.path,conditions='Normalize footprint minimum to (0,0)') frames=edge_frames(width,depth,0) ports=[];grants=[] for side,f in frames.items(): for role,offset,size,base in [('entry',0,1,0)] if side in self.entrances else []: at=f.compose(Frame((offset,base,0))) region=at.box(Box((0,0,0),(size-1,2,0))) if not all((p[0],p[2]) in shell for p in region.cells()): raise ContractError('polygon-entry',ctx.path,at.origin,'Requested cardinal entry is not on the footprint boundary') key='entry-'+side ports.append(Port(key,'wall-installation',at,region,1,key,facts={'thickness':1,'role':role,'side':side})) grants.append(Grant(key,region,('install',),('door',),3)) for i,offset in enumerate((-4,2)): at=f.compose(Frame((offset,1,0))) region=at.box(Box((0,0,0),(1,1,0))) if all((p[0],p[2]) in shell for p in region.cells()): key=f'window-{side}-{i}' ports.append(Port(key,'wall-installation',at,region,1,key,facts={'thickness':1,'role':'window','side':side})) grants.append(Grant(key,region,('install',),('window',),4)) blocks=tuple((x,y,z) for x,z in shell for y in range(self.height)) return Contract(bounds2(footprint,0,self.height-1),tuple(ports),tuple(grants),rules=(Rule('sealed',blocks),Rule('support',tuple((x,-1,z) for x,z in shell))),decisions={'shell':shell,'height':self.height}) def realize(self,ctx,contract): p=Plan() vertices=set(self.footprint.vertices) for x,z in contract.decisions['shell']: for y in range(self.height): frame=(x,z) in vertices or y==self.height-1 p.block((x,y,z),log() if frame else state_of('smooth_sandstone'),'frame' if frame else 'infill') return p @dataclass(frozen=True) class Facade: host: str shutters: bool = True def capability(self): return Capability('extension.facade-installations',('composite',)) def negotiate(self,ctx,parameters): box=ctx.view.contract(self.host).envelope return Contract(Box.enclosing(ctx.local(p) for p in box.corners()).expand(2)) def realize(self,ctx,contract): p=Plan() for port in ctx.view.offers(self.host,'wall-installation'): component=Door() if port.facts['role']=='entry' else Window(shutters=self.shutters) frame=Frame(ctx.local(port.frame.origin),(port.frame.turn-ctx.frame.turn)%4) p.children.append(Child(port.key,component,frame=frame,bindings=(Binding(self.host,port.key),))) return p @dataclass(frozen=True) class HipRoof: footprint: Polygon run: int = 2 lantern: bool = False material: str = 'deepslate_tile' def capability(self): return Capability('extension.hip-roof',('roof','composite'),adaptations=('polygon inset courses',),inputs={'run':Domain(choices=(1,2,3))},guarantees=('continuous concentric weather surface',)) def negotiate(self,ctx,parameters): points=set(self.footprint.cells()) points|={(x+dx,z+dz) for x,z in tuple(points) for dx,dz in CARDINAL} remaining=set(points) depths={} depth=0 while remaining: ring=perimeter(remaining) for p in ring: depths[p]=depth remaining-=set(ring) depth+=1 courses=tuple((x,depths[(x,z)]//self.run,z) for x,z in sorted(points)) peak=max(y for x,y,z in courses) cx=(min(x for x,z in points)+max(x for x,z in points))//2 cz=(min(z for x,z in points)+max(z for x,z in points))//2 return Contract(bounds2(points,-1,peak+7),rules=(Rule('sealed',courses),),decisions={'courses':courses,'peak':peak,'center':(cx,cz),'run':self.run,'lantern':self.lantern}) def realize(self,ctx,contract): p=Plan() d=contract.decisions heights={(x,z):y for x,y,z in d['courses']} for x,y,z in d['courses']: face=next((f for dx,dz,f in ((1,0,'east'),(-1,0,'west'),(0,1,'south'),(0,-1,'north')) if heights.get((x+dx,z+dz),y)>y),None) material='dark_oak' if y==0 else self.material p.block((x,y,z),stairs(material,face) if face else slab(material,'top'),'hip-course') if self.lantern: cx,cz=d['center'] p.children.append(Child('lantern',RoofLantern(),frame=Frame((cx-2,d['peak']+1,cz-2)))) return p @dataclass(frozen=True) class RoofLantern: def capability(self): return Capability('extension.roof-lantern',('roof','daylight','composite')) def negotiate(self,ctx,parameters): return Contract(Box((-1,0,-1),(5,5,5))) def realize(self,ctx,contract): p=Plan() for x in range(5): for z in range(5): p.block((x,0,z),state_of('spruce_planks'),'ring-beam') if x in (0,4) or z in (0,4): for y in (1,2): p.block((x,y,z),log() if x in (0,4) and z in (0,4) else state_of('glass'),'clerestory') p.children.append(Child('cap',HipRoof(Polygon.chamfered(9,9),run=2),frame=Frame((-2,3,-2)))) return p @dataclass(frozen=True) class Pavilion: footprint: Polygon terrain: str purpose: str = 'library' entrances: tuple = ('north','south') height: int = 5 roof_run: int = 2 lantern: bool = False limits: SiteLimits = SiteLimits() def capability(self): return Capability('extension.pavilion',('building','habitable','composite'),offers=('access',),adaptations=('polygon support grid','independently measured approaches'),guarantees=('connected entrances','furnished lit enclosed hall'),inputs={'height':Domain(5,7),'purpose':Domain(choices=('living','library','workshop','kitchen','bedroom','storage'))},locked=('footprint','purpose','entrances','height','roof_run','lantern')) def negotiate(self,ctx,parameters): points=self.footprint.cells() width=max(x for x,z in points)+1 depth=max(z for x,z in points)+1 if not 13<=width<=25 or not 13<=depth<=25 or not self.entrances: raise ContractError('hall-domain',ctx.path,conditions='Footprints 13..25, at least one declared entrance') measured=survey(ctx,points,self.limits) floor=measured['floor'] ports=[];approaches=[] frames=edge_frames(width,depth,0) low=min(v[0] for v in measured['samples'].values())-1 boxes=[bounds2(points,low,floor+self.height+23).expand(3)] targets=[(width//2,floor+1,depth//2)] for side in self.entrances: if side not in frames: raise ContractError('hall-entrance',ctx.path,conditions=side) f=frames[side] comp=Approach(0,floor,limits=self.limits) ac=comp.negotiate(Context(ctx.path,ctx.frame.compose(f),ctx.scope.child('approach-'+side),ctx.view,(),ctx.limits),{}) local=ac.transformed(f) port=local.ports[0] ports.append(Port(side,'access',Frame(port.frame.origin,f.turn),port.region,8,delegate=('approach-'+side,'street'))) approaches.append((side,f,comp)) boxes.append(local.envelope) targets.extend(((f.origin[0],floor+1,f.origin[2]),port.frame.origin)) envelope=Box.enclosing(p for box in boxes for p in box.corners()) interior=Box((1,floor+1,1),(width-2,floor+self.height-1,depth-2)) groups={'library':[['bookshelf'],['lectern']],'workshop':[['crafting_table'],['smithing_table']],'kitchen':[['smoker'],['furnace']],'bedroom':[['red_bed']],'living':[['spruce_stairs']],'storage':[['barrel']]} return Contract(envelope,tuple(ports),rules=(Rule('route',tuple(targets),envelope,phase='complete'),Rule('light',tuple(targets[:1]),interior,{'minimum':1},'complete'),Rule('furnishing',box=interior,data={'groups':groups[self.purpose]},phase='complete')),decisions={'floor':floor,'width':width,'depth':depth,'footprint':points,'vertices':self.footprint.vertices,'strategy':measured['strategy'],'entrances':self.entrances,'height':self.height,'purpose':self.purpose,'roof_run':self.roof_run,'lantern':self.lantern}) def realize(self,ctx,contract): d=contract.decisions;floor=d['floor'];w=d['width'];depth=d['depth'] p=Plan(children=[Child('foundation',Foundation(tuple(d['footprint']),floor,d['strategy'],self.limits),bindings=(Binding(self.terrain,'construction','fill'),)),Child('floor',Surface(tuple((x,floor,z) for x,z in d['footprint']),role='hall-floor')),Child('ceiling',Surface(tuple((x,floor+self.height+1,z) for x,z in d['footprint']),role='hall-ceiling')),Child('shell',PolygonShell(self.footprint,self.height,self.entrances),frame=Frame((0,floor+1,0))),Child('facade',Facade(ctx.path+'/shell'))]) for side in self.entrances: f=edge_frames(w,depth,0)[side] p.children.append(Child('approach-'+side,Approach(0,floor,limits=self.limits),frame=f,bindings=(Binding(self.terrain,'construction','surface'),))) p.children.append(Child('furnishings',Furniture(self.purpose,w-6,depth-6),frame=Frame((3,floor+1,3)))) for x in range(4,w-3,5): for z in range(4,depth-3,5): p.children.append(Child(f'light-{x}-{z}',Light(),frame=Frame((x,floor+self.height-1,z)))) p.children.append(Child('roof',HipRoof(self.footprint,self.roof_run,self.lantern),frame=Frame((0,floor+self.height+2,0)))) return p PY yapf -i hearth_extensions/halls.py test/test_extension_geometry.py
1812
cat >> hearth_extensions/__init__.py <<'PY' from .halls import Pavilion, PolygonShell, HipRoof, Facade PY cat >> test/test_extension_geometry.py <<'PY
cat >> hearth_extensions/__init__.py <<'PY' from .halls import Pavilion, PolygonShell, HipRoof, Facade PY cat >> test/test_extension_geometry.py <<'PY' @pytest.mark.parametrize('width,depth,corner,lantern',[(13,17,0,False),(17,21,3,True),(25,13,4,False)]) def test_polygon_hall_multiple_usable_ports(width,depth,corner,lantern,work): from hearth_extensions import Pavilion,Polygon s=Scene(2,domain=Box((-15,-4,-15),(42,60,42))) s.place('land',Terrain(s.domain,gradient(.025,-.018,4))) s.place('hall',Pavilion(Polygon.chamfered(width,depth,corner),'/land',entrances=('north','east','south','west'),lantern=lantern)) s.finalize() assert len(s.view.offers('/hall','access'))==4 glass=next(p for p,c in s.blocks.items() if c.state=='minecraft:glass' and '/facade/' in c.owner) assert [n['type'] for n in s.inspect(glass)['chain']][:3]==['window.shuttered','extension.polygon-shell','extension.pavilion'] export_scene(s,work/'hall.litematic') assert load_scene(work/'hall.litematic').inspect(glass)==s.inspect(glass) PY yapf -i hearth_extensions/halls.py hearth_extensions/__init__.py test/test_extension_geometry.py python -m pytest -q test/test_extension_geometry.py > reports/extension-corpus/geometry-probes-2.txt
1900
tail -n 65 reports/extension-corpus/geometry-probes-2.txt
tail -n 65 reports/extension-corpus/geometry-probes-2.txt
ucted hearth/kernel/scene.py:391: ValidationError ____________ test_polygon_hall_multiple_usable_ports[25-13-4-False] ____________ width = 25, depth = 13, corner = 4, lantern = False work = PosixPath('/work/generator/workspace/test/tmp-4esx4eff') @pytest.mark.parametrize('width,depth,corner,lantern', [(13, 17, 0, False), (17, 21, 3, True), (25, 13, 4, False)]) def test_polygon_hall_multiple_usable_ports(width, depth, corner, lantern, work): from hearth_extensions import Pavilion, Polygon s = Scene(2, domain=Box((-15, -4, -15), (42, 60, 42))) s.place('land', Terrain(s.domain, gradient(.025, -.018, 4))) > s.place('hall', Pavilion(Polygon.chamfered(width, depth, corner), '/land', entrances=('north', 'east', 'south', 'west'), lantern=lantern)) test/test_extension_geometry.py:56: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hearth/kernel/scene.py:149: in place candidate._check(False) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <hearth.kernel.scene.Scene object at 0x7bb84b46e690>, final = False completed_scope = None def _check(self, final, completed_scope=None): errors = validate(self, final, completed_scope) if errors: > raise ValidationError(errors) E hearth.kernel.errors.ValidationError: clearance: /hall/approach-north at (13, 7, -1): Protected player headroom is obstructed E clearance: /hall/approach-south at (11, 7, 13): Protected player headroom is obstructed hearth/kernel/scene.py:391: ValidationError =========================== short test summary info ============================ FAILED test/test_extension_geometry.py::test_polygon_hall_multiple_usable_ports[13-17-0-False] FAILED test/test_extension_geometry.py::test_polygon_hall_multiple_usable_ports[17-21-3-True] FAILED test/test_extension_geometry.py::test_polygon_hall_multiple_usable_ports[25-13-4-False] 3 failed, 2 passed in 2.60s
20013
python - <<'PY' from pathlib import Path p=Path('hearth_extensions/halls.py');s=p.read_text().replace('enumerate((-4, 2))','enumerate((-4, 3))');p.wri
python - <<'PY' from pathlib import Path p=Path('hearth_extensions/halls.py');s=p.read_text().replace('enumerate((-4, 2))','enumerate((-4, 3))');p.write_text(s) PY cat > hearth_extensions/graphs.py <<'PY' # Reusable campus graph composes arbitrary public building and circulation components. from dataclasses import dataclass from hearth import Box,Frame,ContractError from hearth.kernel import Capability,Contract,Port,Rule,Plan,Child,Context from .interfaces import Endpoint from .circulation import connection from .boundaries import Boundary,IlluminateBoundary @dataclass(frozen=True) class Vertex: key: str component: object frame: Frame @dataclass(frozen=True) class Edge: a: str a_port: str b: str b_port: str covered: bool = False via: tuple = () rise: int = 0 width: int = 3 @dataclass(frozen=True) class Campus: vertices: tuple[Vertex,...] edges: tuple[Edge,...] terrain: str envelope: Box boundary: object = None def capability(self): return Capability('extension.campus',('settlement','composite'),offers=('public-access',),guarantees=('declared graph connected','usable realized building connections'),locked=('vertices','edges')) def negotiate(self,ctx,parameters): keys={v.key for v in self.vertices} if len(keys)!=len(self.vertices) or not keys: raise ContractError('graph-vertices',ctx.path) connected={self.vertices[0].key} for edge in self.edges: if edge.a not in keys or edge.b not in keys or edge.a==edge.b: raise ContractError('graph-edge',ctx.path,conditions=str(edge)) while True: more={v for e in self.edges if e.a in connected or e.b in connected for v in (e.a,e.b)} if more<=connected: break connected|=more if connected!=keys: raise ContractError('graph-disconnected',ctx.path,conditions=str(sorted(keys-connected))) first=self.vertices[0] context=Context(ctx.path+'/'+first.key,ctx.frame.compose(first.frame),ctx.scope.child(first.key),ctx.view,(),ctx.limits) offered=first.component.negotiate(context,{}).transformed(first.frame).ports port=next((p for p in offered if p.kind in ('access','public-access')),None) if port is None: raise ContractError('graph-access',ctx.path,conditions='First vertex must expose usable access') gateway=Port('public','access',port.frame,port.region,port.capacity,delegate=(first.key,port.key)) return Contract(self.envelope,ports=(gateway,),decisions={'vertices':[v.key for v in self.vertices],'edges':[(e.a,e.a_port,e.b,e.b_port,e.covered,e.width) for e in self.edges]}) def realize(self,ctx,contract): p=Plan(children=[Child(v.key,v.component,frame=v.frame) for v in self.vertices]) p.children.append(Child('circulation',Connections(ctx.path,self.edges,self.terrain,self.envelope))) if self.boundary is not None: p.children.extend((Child('boundary',Boundary(self.boundary)),Child('boundary-lights',IlluminateBoundary(ctx.path+'/boundary',2)))) return p @dataclass(frozen=True) class Connections: parent: str edges: tuple[Edge,...] terrain: str envelope: Box def capability(self): return Capability('extension.connection-graph',('connection','composite')) def negotiate(self,ctx,parameters): targets=[] for edge in self.edges: for key,port in ((edge.a,edge.a_port),(edge.b,edge.b_port)): targets.append(ctx.local(ctx.view.port(self.parent+'/'+key,port).frame.origin)) return Contract(self.envelope,rules=(Rule('route',tuple(targets),self.envelope,phase='complete'),)) def realize(self,ctx,contract): p=Plan() for i,edge in enumerate(self.edges): a=Endpoint(self.parent+'/'+edge.a,edge.a_port) b=Endpoint(self.parent+'/'+edge.b,edge.b_port) p.children.append(connection(f'link-{i}',a,b,self.terrain,via=edge.via,covered=edge.covered,rise=edge.rise,width=edge.width)) return p PY cat > hearth_extensions/programs.py <<'PY' # Lightweight graph clients using frozen generic fields and interchangeable public buildings. from hearth import Scene,Box,Frame from hearth.randomness import Scope from hearth.environment import Terrain,gradient,wave,radial from hearth.components.building import Blueprint,RoomSpec,Building from hearth.persistence import semantic_digest from .geometry import Polygon,Polyline from .halls import Pavilion from .graphs import Campus,Vertex,Edge DOMAIN=Box((-18,-4,-18),(95,70,95)) def frozen_site(environment_seed=0,domain=DOMAIN): rng=Scope(environment_seed).stream('environment') field=gradient(rng.choice((-.012,0,.012)),rng.choice((-.009,.009)),5)+wave(.5,.07,.09,rng.random()*6)+radial(30,31,24,-3.8) scene=Scene(environment_seed,domain=domain) scene.place('land',Terrain(domain,field,water_level=3,edit_limit=2500)) return scene.finalize() def branching_campus(seed=0): rng=Scope(seed).stream('branching-graph') hub=Pavilion(Polygon.chamfered(17,17,4),'/land','library',('north','east','south','west'),height=6,lantern=True) west=Pavilion(Polygon.chamfered(13,rng.choice((13,17)),2),'/land','workshop',('north','south'),height=5) east=Pavilion(Polygon.chamfered(rng.choice((13,17)),13,2),'/land','kitchen',('west','south'),height=rng.choice((5,6))) rooms=[RoomSpec(0,0,0,'living'),RoomSpec(0,0,1,'bedroom')] if rng.choice((False,True)): rooms.append(RoomSpec(0,1,0,'storage')) lodge=Building(Blueprint(tuple(rooms),bay=9,porch=True),'/land') vertices=[Vertex('hall',hub,Frame((23,0,23))),Vertex('workshop',west,Frame((0,0,0))),Vertex('kitchen',east,Frame((51,0,0))),Vertex('lodge',lodge,Frame((48,0,51)))] edges=[Edge('hall','north','workshop','south',covered=True),Edge('hall','east','kitchen','west',rise=rng.choice((0,1))),Edge('hall','south','lodge','street',covered=True)] if rng.choice((False,True)): vertices.append(Vertex('archive',Pavilion(Polygon.chamfered(13,13,2),'/land','library',('east',)),Frame((0,0,51)))) edges.append(Edge('hall','west','archive','east',rise=1)) boundary=Polyline.bezier(((-9,10),(-12,90),(85,95),(84,5))) return Campus(tuple(vertices),tuple(edges),'/land',DOMAIN,boundary) def perimeter_cluster(seed=0): rng=Scope(seed).stream('perimeter-graph') widths=(rng.choice((17,21,25)),rng.choice((13,17)),rng.choice((13,17))) market=Pavilion(Polygon.chamfered(widths[0],13,2),'/land','workshop',('north','east','south'),height=5,roof_run=3) reading=Pavilion(Polygon.chamfered(widths[1],17,3),'/land','library',('north','south'),height=6,lantern=rng.choice((True,False))) dining=Pavilion(Polygon.chamfered(widths[2],13,2),'/land','living',('east','west'),height=5) vertices=(Vertex('market',market,Frame((0,0,0))),Vertex('reading',reading,Frame((50,0,10))),Vertex('dining',dining,Frame((20,0,57)))) edges=(Edge('market','east','reading','north',via=((40,-5),),covered=False,rise=1),Edge('reading','south','dining','east',covered=True),Edge('dining','west','market','south',via=((9,42),),rise=rng.choice((0,1)))) boundary=Polyline.bezier(((-6,25),(-2,86),(83,88),(83,20))) return Campus(vertices,edges,'/land',DOMAIN,boundary) def extension_scene(program=branching_campus,seed=0,environment_seed=0): environment=frozen_site(environment_seed) original=semantic_digest(environment) scene=environment.fork(seed=seed) scene.place('campus',program(seed)) scene.finalize() if semantic_digest(environment)!=original: raise AssertionError('Frozen input mutated') return scene PY yapf -i hearth_extensions/halls.py hearth_extensions/graphs.py hearth_extensions/programs.py python -m pytest -q test/test_extension_geometry.py > reports/extension-corpus/geometry-probes-3.txt python - <<'PY' > reports/extension-corpus/client-probes.txt from hearth_extensions.programs import * for program in (branching_campus,perimeter_cluster): for seed in (0,1): try: s=extension_scene(program,seed,seed) print(program.__name__,seed,'valid',len(s.blocks),flush=True) except Exception as e: print(program.__name__,seed,type(e).__name__,str(e),flush=True) PY
2100
cat reports/extension-corpus/geometry-probes-3.txt cat reports/extension-corpus/client-probes.txt
cat reports/extension-corpus/geometry-probes-3.txt cat reports/extension-corpus/client-probes.txt
..... [100%] 5 passed in 5.46s branching_campus 0 ContractError boundary-domain: /campus/boundary at None: Simple open contour, at most 220 raster cells branching_campus 1 ContractError boundary-domain: /campus/boundary at None: Simple open contour, at most 220 raster cells perimeter_cluster 0 ContractError boundary-grade: /campus/boundary at None: Adjacent wall foundations exceed step bound perimeter_cluster 1 ContractError boundary-grade: /campus/boundary at None: Adjacent wall foundations exceed step bound
2211
python - <<'PY' from dataclasses import replace from collections import Counter from hearth_extensions.programs import * for program in (branching_cam
python - <<'PY' from dataclasses import replace from collections import Counter from hearth_extensions.programs import * for program in (branching_campus,perimeter_cluster): c=program(0);pts=c.boundary.cells() print(program.__name__,'curve',len(pts),len(set(pts)),'repeat',[(p,n) for p,n in Counter(pts).items() if n>1][:8]) s=frozen_site(0).fork(seed=0);s.place('campus',replace(c,boundary=None)) rows=[(p,s.view.elevation(*p)) for p in pts] for (p,a),(q,b) in zip(rows,rows[1:]): if abs(a-b)>1: print('grade',p,a,q,b,s.inspect((p[0],a,p[1]))['instance'],s.inspect((q[0],b,q[1]))['instance']) PY
branching_campus curve 221 221 repeat [] Traceback (most recent call last): File "<stdin>", line 7, in <module> File "/work/generator/workspace/hearth/kernel/scene.py", line 149, in place candidate._check(False) File "/work/generator/workspace/hearth/kernel/scene.py", line 391, in _check raise ValidationError(errors) hearth.kernel.errors.ValidationError: clearance: /campus/circulation/link-0 at (29, 6, 22): Protected player headroom is obstructed clearance: /campus/circulation/link-0 at (33, 6, 22): Protected player headroom is obstructed clearance: /campus/circulation/link-1 at (40, 6, 29): Protected player headroom is obstructed clearance: /campus/circulation/link-1 at (40, 6, 33): Protected player headroom is obstructed clearance: /campus/circulation/link-2 at (29, 6, 40): Protected player headroom is obstructed clearance: /campus/circulation/link-2 at (33, 6, 40): Protected player headroom is obstructed
2300
sed -n '457,495p' hearth/kernel/scene.py
sed -n '457,495p' hearth/kernel/scene.py
self._commit(trial) def remove(self, path): trial = self._fork() trial._remove_branch(path) trial._check(False) self._commit(trial) def _remove_branch(self, path): paths = {k for k in self.nodes if k == path or k.startswith(path + '/')} affected = set() for k in sorted(paths, reverse=True): current = set(self.reverse[k]) | set(self.displaced.get(k, {})) for p in current: record = self.blocks.get(p) if record is None and self.erasures.get(p) not in paths: continue if record is not None and record.owner not in paths and self.operations[record.operation]['component'] not in paths: continue affected.add(p) if record is not None: self.reverse[record.owner].discard(p) self.erasures.pop(p, None) previous = self.displaced.get(k, {}).get(p) if previous and previous.owner in self.nodes and previous.owner not in paths: self.blocks[p] = previous self.reverse[previous.owner].add(p) else: self.blocks.pop(p, None) self.displaced.pop(k, None) for d in self.dependencies: if d['consumer'] not in paths and (d['source'] in paths or any(d['region'].contains(p) for p in affected)): self.nodes[d['consumer']].stale = True for k in sorted(paths, reverse=True): self.reverse_shared.pop(k, None) self.reverse[k].clear() self._retire(k) self.relations = {r for r in self.relations if r[0] in self.nodes and r[2] in self.nodes} for p, record in list(self.blocks.items()):
24011
cat >> hearth_extensions/boundaries.py <<'PY' @dataclass(frozen=True) class BoundaryChain: curve: Polyline height: int = 2 spacing: int
cat >> hearth_extensions/boundaries.py <<'PY' @dataclass(frozen=True) class BoundaryChain: curve: Polyline height: int = 2 spacing: int = 7 chunk: int = 96 def capability(self): return Capability('extension.boundary-chain',('boundary','composite'),offers=('mount',),guarantees=('continuous contour across component joins',)) def parts(self): cells=self.curve.cells() if len(set(cells))!=len(cells): raise ContractError('boundary-self-intersection',conditions='A simple open contour is required') count=max(1,(len(cells)+self.chunk-1)//self.chunk) size=(len(cells)+count-1)//count return tuple(Boundary(Polyline(cells[i:i+size]),self.height,self.spacing) for i in range(0,len(cells),size)) def negotiate(self,ctx,parameters): boxes=[];ports=[] for i,part in enumerate(self.parts()): local=part.negotiate(ctx,{}) boxes.append(local.envelope) for p in local.ports: ports.append(Port(f'segment-{i}-{p.key}',p.kind,p.frame,p.region,p.capacity,facts=p.facts,delegate=(f'segment-{i}',p.key))) return Contract(Box.enclosing(p for box in boxes for p in box.corners()),ports=tuple(ports),decisions={'segments':len(boxes),'curve':self.curve.points}) def realize(self,ctx,contract): return Plan(children=[Child(f'segment-{i}',part) for i,part in enumerate(self.parts())]) PY python - <<'PY' from pathlib import Path p=Path('hearth_extensions/graphs.py');s=p.read_text().replace('from .boundaries import Boundary, IlluminateBoundary','from .boundaries import BoundaryChain, IlluminateBoundary').replace('Boundary(self.boundary)','BoundaryChain(self.boundary)');p.write_text(s) p=Path('hearth_extensions/programs.py');s=p.read_text().replace('((-9, 10), (-12, 90), (85, 95), (84, 5))','((-12, 0), (-30, 120), (115, 120), (84, 0))').replace('((-6, 25), (-2, 86), (83, 88), (83, 20))','((-12, 0), (-30, 120), (115, 120), (84, 0))');p.write_text(s) PY yapf -i hearth_extensions/circulation.py hearth_extensions/boundaries.py hearth_extensions/graphs.py hearth_extensions/programs.py python - <<'PY' > reports/extension-corpus/client-probes-2.txt from hearth_extensions.programs import * for program in (branching_campus,perimeter_cluster): for seed in (0,1): try: s=extension_scene(program,seed,seed) print(program.__name__,seed,'valid',len(s.blocks),flush=True) except Exception as e: print(program.__name__,seed,type(e).__name__,str(e),flush=True) PY
25110
cat > test/test_extension_failures.py <<'PY' # Deliberate input and geometry damage for extension contracts and atomicity. from dataclasses import rep
cat > test/test_extension_failures.py <<'PY' # Deliberate input and geometry damage for extension contracts and atomicity. from dataclasses import replace import copy import pytest from hearth import Scene,Box,Frame,Binding,ContractError from hearth.kernel import validate,Child,Plan,Choice,Limits from hearth.blocks import state_of from hearth.components.primitives import Volume from hearth.environment import Terrain,gradient,wave from hearth.persistence import semantic_digest,export_scene,load_scene,encode from hearth_extensions import Polyline,Endpoint,Link,Boundary,IlluminateBoundary,Platform from hearth_extensions.boundaries import BoundaryChain from hearth_extensions.circulation import Trestles from test_extension_geometry import bridge_scene def snapshot(s): return (semantic_digest(s),copy.deepcopy(encode(s.nodes)),copy.deepcopy(encode(s.relations)),copy.deepcopy(encode(s.dependencies)),copy.deepcopy(encode(s.operations)),copy.deepcopy(s.reverse),copy.deepcopy(s.port_uses),copy.deepcopy(s.events)) def damage(s,p): record=s.blocks.pop(p) s.reverse[record.owner].remove(p) @pytest.mark.parametrize('kind',['support','guard','endpoint','headroom']) def test_broken_bridge_geometry_is_diagnosed(kind): s=bridge_scene() if kind=='support': p=s.nodes['/link/supports'].contract.rules[0].cells[0] damage(s,p) expected='support' elif kind=='guard': p=next(iter(s.cells('/link/guards'))) damage(s,p) expected='bridge-guard' elif kind=='endpoint': a=s.view.port('/a','south').frame.origin p=(a[0],a[1]-1,a[2]);damage(s,p) expected='reachability' else: p=next(r for r in s.nodes['/link'].contract.rules if r.kind=='clear').cells[len(s.nodes['/link'].contract.decisions['deck'])//2] before=snapshot(s) with pytest.raises(ContractError,match='clearance'): s.place('blocked',Volume(Box(p,p),state_of('stone'))) assert snapshot(s)==before return errors=validate(s,True) assert any(d.rule==expected and d.position is not None for d in errors) @pytest.mark.parametrize('fault',['endpoint','frame','kind']) def test_invalid_connections_rollback_every_index(fault): s=bridge_scene();s.remove('/link') a,b=Endpoint('/a','south'),Endpoint('/b','north') pa=s.view.port('/a','south').frame.origin pb=s.view.port('/b','north').frame.origin curve=Polyline(((pa[0],pa[2]),(pa[0]+3,pa[2]),(pb[0],pb[2]))) expected='endpoint-frame' if fault=='endpoint': curve=Polyline(((pa[0]+1,pa[2]),(pb[0],pb[2]))) expected='endpoint-disconnected' if fault=='kind': a=Endpoint('/land','construction') expected='endpoint-kind' before=snapshot(s) with pytest.raises(ContractError,match=expected): s.place('bad',Link(a,b,'/land',curve=curve),bindings=(a.binding(),b.binding())) assert snapshot(s)==before def test_connection_permission_overflow_is_atomic(): s=Scene(0,domain=Box((-3,-4,-3),(12,20,12))) s.place('land',Terrain(s.domain,gradient(base=0),water_level=5,edit_limit=1)) before=snapshot(s) columns=((2,0,2,4,True),(3,0,2,4,True)) with pytest.raises(ContractError,match='edit-limit'): s.place('piers',Trestles(columns),bindings=(Binding('/land','construction','fill'),)) assert snapshot(s)==before def test_connection_remove_and_regenerate_restore_water_and_membership(): s=bridge_scene();s.remove('/link') before=snapshot(s) a,b=Endpoint('/a','south'),Endpoint('/b','north') comp=Link(a,b,'/land',rise=1) s.place('link',comp,bindings=(a.binding(),b.binding())) old=s.cells('/link',True) s.regenerate('/link',replace(comp,covered=True,rise=0)) new=s.cells('/link',True) assert old!=new assert all(s.inspect(p)['instance'] in s.nodes for p in new) assert all(not s.inspect(p)['instance'] or not s.inspect(p)['instance'].startswith('/link') for p in old-new) s.remove('/link') assert semantic_digest(s)==before[0] assert not any('/link' in a or '/link' in c for a,b,c in s.relations) assert not any(k.startswith('/link') for k in s.nodes) def test_boundary_missing_coping_support_and_whole_removal(work): s=Scene(0,domain=Box((-5,-4,-5),(45,24,25))) s.place('land',Terrain(s.domain,gradient(base=3))) curve=Polyline.bezier(((0,0),(9,20),(26,0),(37,17))) s.place('boundary',BoundaryChain(curve)) s.place('lamps',IlluminateBoundary('/boundary')) before=snapshot(s) with pytest.raises(ContractError): s.remove('/boundary') assert snapshot(s)==before changed=Polyline.bezier(((0,1),(9,19),(26,1),(37,18))) s.regenerate('/boundary',BoundaryChain(changed),dependents=('/lamps',)) s.finalize() p=s.view.offers('/boundary','mount')[0].frame.origin assert p in s.cells('/boundary',True) export_scene(s,work/'curve.litematic') t=load_scene(work/'curve.litematic') assert t.inspect(p)==s.inspect(p) base=(p[0],p[1]-1,p[2]);damage(t,base) assert any(d.rule in ('support','enclosure') and d.position==base for d in validate(t,True)) def test_curve_boundary_rejects_incompatible_installation_frame(): from hearth_extensions import BoundaryLantern s=Scene(0,domain=Box((-3,-4,-3),(25,25,25))) s.place('land',Terrain(s.domain,gradient(base=3))) s.place('wall',Boundary(Polyline(((0,0),(20,8))))) port=s.view.offers('/wall','mount')[0] before=snapshot(s) with pytest.raises(ContractError,match='port-alignment'): s.place('bad-lamp',BoundaryLantern(),frame=Frame(port.frame.origin,port.frame.turn+1),bindings=(Binding('/wall',port.key),)) assert snapshot(s)==before def test_failed_choice_does_not_perturb_sibling_randomness(): s=bridge_scene();s.remove('/link') a,b=Endpoint('/a','south'),Endpoint('/b','north') before=snapshot(s) bad=Link(a,b,'/land',fill_limit=0) with pytest.raises(ContractError): s.compose_choice(Choice('link',(Child('attempt',bad,bindings=(a.binding(),b.binding())),),lambda v,p:0)) assert snapshot(s)==before good=Link(a,b,'/land',rise=1) s.place('link',good,bindings=(a.binding(),b.binding())) assert semantic_digest(s)==semantic_digest(bridge_scene()) PY python -m pytest -q test/test_extension_protocol.py test/test_extension_geometry.py test/test_extension_failures.py > reports/extension-corpus/focused-tests.txt
2600
cat reports/extension-corpus/client-probes-2.txt cat reports/extension-corpus/focused-tests.txt
cat reports/extension-corpus/client-probes-2.txt cat reports/extension-corpus/focused-tests.txt
achability: /campus/circulation/link-0 at (6, 5, 22): No walkable route with two blocks of headroom from entrance perimeter_cluster 0 valid 116962 perimeter_cluster 1 valid 127803 ...............F... [100%] =================================== FAILURES =================================== ______ test_connection_remove_and_regenerate_restore_water_and_membership ______ def test_connection_remove_and_regenerate_restore_water_and_membership(): s=bridge_scene();s.remove('/link') before=snapshot(s) a,b=Endpoint('/a','south'),Endpoint('/b','north') comp=Link(a,b,'/land',rise=1) s.place('link',comp,bindings=(a.binding(),b.binding())) old=s.cells('/link',True) > s.regenerate('/link',replace(comp,covered=True,rise=0)) test/test_extension_failures.py:89: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hearth/kernel/scene.py:518: in regenerate trial._check(True) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <hearth.kernel.scene.Scene object at 0x7a295aad3830>, final = True completed_scope = None def _check(self, final, completed_scope=None): errors = validate(self, final, completed_scope) if errors: > raise ValidationError(errors) E hearth.kernel.errors.ValidationError: unfinished: /a at None: Scope unfinished or dependent inputs stale E unfinished: /a/foundation at None: Scope unfinished or dependent inputs stale E unfinished: /b at None: Scope unfinished or dependent inputs stale E unfinished: /b/foundation at None: Scope unfinished or dependent inputs stale hearth/kernel/scene.py:391: ValidationError =========================== short test summary info ============================ FAILED test/test_extension_failures.py::test_connection_remove_and_regenerate_restore_water_and_membership 1 failed, 18 passed in 10.32s
2710
cat >> test/test_extension_protocol.py <<'PY' def test_atomic_multi_branch_replay_accepts_explicit_replacements(): from hearth.components.primit
cat >> test/test_extension_protocol.py <<'PY' def test_atomic_multi_branch_replay_accepts_explicit_replacements(): from hearth.components.primitives import Volume s=Scene() s.place('a',Volume(Box((0,0,0),(0,0,0)),state_of('stone'))) s.place('b',Volume(Box((3,0,0),(3,0,0)),state_of('stone'))) s.regenerate('/a',dependents=('/b',),replacements={'/b':Volume(Box((3,0,0),(4,0,0)),state_of('oak_planks'))}) assert len(s.cells('/b'))==2 assert s.inspect((0,0,0))['state']==state_of('stone') PY python -m pytest -q test/test_extension_protocol.py::test_atomic_multi_branch_replay_accepts_explicit_replacements > reports/extensions-baseline/failing-replay-probe.txt
28022
python - <<'PY' from pathlib import Path p=Path('test/test_extension_failures.py');s=p.read_text().replace("s.regenerate('/link',replace(comp,covered=
python - <<'PY' from pathlib import Path p=Path('test/test_extension_failures.py');s=p.read_text().replace("s.regenerate('/link',replace(comp,covered=True,rise=0))", "s.regenerate('/a', dependents=('/b','/link'), replacements={'/link':replace(comp,covered=True,rise=0)})");p.write_text(s) PY cat >> reports/extensions-baseline/api-delta.md <<'MD' ## Explicit replacements in a coupled replay The bridge replacement test exposed conservative host invalidation: removing contact output can invalidate earlier platform surveys even though their principal intent is unchanged. Replaying only the link correctly refuses to finalize stale platform observations. Replaying hosts and link together was possible, but the public API could only replace the first target, while the changed link must come after its hosts. The proposed `replacements` call failed before the change; its TypeError is retained in `failing-replay-probe.txt`, and the original stale-input result remains in `../extension-corpus/focused-tests.txt`. `Scene.regenerate(..., dependents=(...), replacements={path: component, ...})` now accepts explicit replacements for any named replay target. Targets remain explicitly ordered, retain their frames, scopes and bindings, and replay in one bounded transaction. Undeclared or duplicate targets fail. No automatic graph-wide update loop or stale-flag bypass was added. A link can be replaced while its unchanged hosts are recomputed first from their inputs. Reloaded branches may likewise supply their implementations explicitly through this mapping. Existing calls keep their previous behavior. MD yapf -i hearth/kernel/scene.py hearth_extensions/geometry.py test/test_extension_protocol.py test/test_extension_failures.py python -m pytest -q test/test_extension_protocol.py test/test_extension_geometry.py test/test_extension_failures.py test/test_kernel.py test/test_contracts_provenance.py > reports/extension-corpus/focused-tests-2.txt python - <<'PY' > reports/extension-corpus/client-probes-3.txt from hearth_extensions.programs import * for program in (branching_campus,perimeter_cluster): for seed in (0,1): try: s=extension_scene(program,seed,seed) print(program.__name__,seed,'valid',len(s.blocks),flush=True) except Exception as e: print(program.__name__,seed,type(e).__name__,str(e),flush=True) PY
2900
cat reports/extension-corpus/focused-tests-2.txt cat reports/extension-corpus/client-probes-3.txt cat reports/extension-corpus/campus-development.txt
cat reports/extension-corpus/focused-tests-2.txt cat reports/extension-corpus/client-probes-3.txt cat reports/extension-corpus/campus-development.txt
............................................. [100%] 45 passed in 10.60s branching_campus 0 valid 117534 branching_campus 1 valid 128715 perimeter_cluster 0 valid 116962 perimeter_cluster 1 valid 127803 samples/extensions/campus-development.litematic 73d0687f6604f727248d0f0cafc4d6a2f7885c77d5aae638ca6e117e9e4ebea5 117534 blocks 164 instances
30025
cat > examples/extension_generate.py <<'PY' # Explicit client selection for new graph compositions, preserving the original default CLI. import argpar
cat > examples/extension_generate.py <<'PY' # Explicit client selection for new graph compositions, preserving the original default CLI. import argparse from pathlib import Path from hearth.persistence import export_scene,semantic_digest from hearth_extensions.programs import extension_scene,branching_campus,perimeter_cluster PROGRAMS={'campus':branching_campus,'perimeter':perimeter_cluster} def main(): parser=argparse.ArgumentParser() parser.add_argument('program',choices=PROGRAMS) parser.add_argument('--seed',type=int,default=0) parser.add_argument('--environment-seed',type=int,default=0) parser.add_argument('--output',type=Path,default=Path('samples/extensions/composition.litematic')) args=parser.parse_args() scene=extension_scene(PROGRAMS[args.program],args.seed,args.environment_seed) export_scene(scene,args.output) print(args.output,semantic_digest(scene),len(scene.blocks),'blocks',len(scene.nodes),'instances') if __name__=='__main__': main() PY cat > examples/extension_views.py <<'PY' # Render extension artifact pairs and explicitly labeled geometry-only inspection sections. import argparse import json from pathlib import Path import subprocess import sys import hearth_extensions from hearth.persistence import load_scene,companion_path from examples.preview import render,CUTAWAY def views(seed,source,output,size=1100,sections=False): scene=load_scene(source) if scene.seed!=seed: raise ValueError('Explicit seed must match artifact') output.mkdir(parents=True,exist_ok=True) records=[] for label,azimuth,elevation in (('front',215,36),('rear',35,32),('side',120,27)): target=output/(label+'.png') render(source,target,azimuth,elevation,size,3.6) records.append({'source':str(source),'seed':seed,'label':label,'azimuth':azimuth,'elevation':elevation,'image':str(target)}) if sections: halls=[n for n in scene.nodes.values() if n.type=='extension.pavilion'] links=[n for n in scene.nodes.values() if n.type in ('extension.bridge','extension.gallery')] height=max(n.frame.origin[1]+n.contract.decisions['floor']+3 for n in halls) if halls else max(p[1] for n in links for p in scene.cells(n.path+'/deck'))+1 cuts=[('floor-cut','y',height,215,65)] if links: points=scene.cells(links[0].path+'/deck') cuts.append(('connection-section','x',(min(p[0] for p in points)+max(p[0] for p in points))//2,110,20)) offset=json.loads(companion_path(source).read_text())['offset'] for label,axis,world,azimuth,elevation in cuts: target=output/(label+'.litematic') limit=world-offset['xyz'.index(axis)] subprocess.run([sys.executable,str(CUTAWAY),'--input',str(source),'--output',str(target),'--axis',axis,'--max',str(limit),'--name',label],check=True) image=output/(label+'.png') render(target,image,azimuth,elevation,size,3.6) records.append({'source':str(source),'seed':seed,'label':label,'axis':axis,'world_cut':world,'export_local_cut':limit,'geometry_preview_only':True,'image':str(image)}) (output/'views.json').write_text(json.dumps(records,indent=2)) if __name__=='__main__': p=argparse.ArgumentParser() p.add_argument('--seed',type=int,default=0) p.add_argument('--input',type=Path,required=True) p.add_argument('--output',type=Path,required=True) p.add_argument('--size',type=int,default=1100) p.add_argument('--sections',action='store_true') a=p.parse_args() views(a.seed,a.input,a.output,a.size,a.sections) PY yapf -i examples/extension_generate.py examples/extension_views.py python -m examples.extension_generate campus --seed 0 --environment-seed 0 --output samples/extensions/campus-development.litematic > reports/extension-corpus/campus-development.txt python -m examples.extension_views --seed 0 --input samples/extensions/campus-development.litematic --output previews/extensions/development --size 1000 --sections > reports/extension-corpus/development-render.txt
31012
cat >> test/test_extension_geometry.py <<'PY' @pytest.mark.parametrize('turn',[0,1,2,3]) def test_extension_transforms_geometry_interfaces_claims_an
cat >> test/test_extension_geometry.py <<'PY' @pytest.mark.parametrize('turn',[0,1,2,3]) def test_extension_transforms_geometry_interfaces_claims_and_queries(turn,work): from hearth.blocks import blockstates_equivalent frame=Frame((7,3,-5),turn) base=bridge_scene() moved=bridge_scene(frame=frame) assert len(base.blocks)==len(moved.blocks) for point,cell in base.blocks.items(): q=frame.point(point) assert blockstates_equivalent(frame.state(cell.state),moved.inspect(q)['state']) assert moved.inspect(q)['instance']==cell.owner assert moved.view.port('/a','south').frame==frame.compose(base.view.port('/a','south').frame) assert moved.nodes['/link'].contract.rules[0].cells==tuple(frame.point(p) for p in base.nodes['/link'].contract.rules[0].cells) export_scene(moved,work/'rotated bridge.litematic') restored=load_scene(work/'rotated bridge.litematic') q=next(iter(moved.cells('/link/deck'))) assert restored.inspect(q)==moved.inspect(q) def test_untried_kinked_ribbon_and_asymmetric_polygon(): from hearth_extensions import Polygon,Pavilion # Endpoints share Z; a global endpoint clipping plane would sever this route. curve=Polyline(((4,8),(4,12),(13,16),(22,12),(22,8))) s=Scene(19,domain=Box((-8,-4,-8),(50,60,50))) s.place('land',Terrain(s.domain,gradient(base=2),water_level=3)) s.place('a',Platform('/land')) s.place('b',Platform('/land'),frame=Frame((18,0,0))) a,b=Endpoint('/a','south'),Endpoint('/b','south') s.place('link',Link(a,b,'/land',curve=curve,covered=True),bindings=(a.binding(),b.binding())) s.finalize() # A six-sided asymmetric footprint absent from the shipped clients. polygon=Polygon(((2,0),(18,0),(22,4),(22,16),(0,16),(0,3))) other=Scene(19,domain=Box((-10,-4,-10),(40,60,40))) other.place('land',Terrain(other.domain,gradient(.01,.02,3))) other.place('hall',Pavilion(polygon,'/land',entrances=('north','south'),height=7,roof_run=3)) other.finalize() PY cat >> test/test_extension_protocol.py <<'PY' def test_multi_branch_replay_rejects_undeclared_target_and_rolls_back(): from hearth.components.primitives import Volume from hearth.kernel import ContractError from hearth.persistence import semantic_digest s=Scene() s.place('a',Volume(Box((0,0,0),(0,0,0)),state_of('stone'))) before=semantic_digest(s) with pytest.raises(ContractError,match='replay-targets'): s.regenerate('/a',replacements={'/unknown':Landing()}) assert semantic_digest(s)==before and set(s.nodes)=={'/a'} PY yapf -i test/test_extension_geometry.py test/test_extension_protocol.py python -m pytest -q test/test_extension_geometry.py test/test_extension_protocol.py > reports/extension-corpus/transforms-and-novelty.txt
3200
tail -n 8 reports/extension-corpus/transforms-and-novelty.txt
tail -n 8 reports/extension-corpus/transforms-and-novelty.txt
.............. [100%] 14 passed in 11.88s
3300
sed -n '106,180p' hearth/components/landscape.py
sed -n '106,180p' hearth/components/landscape.py
: return False h = ctx.elevation(x, z) if name_of(ctx.state((x, h, z))) != 'grass_block': return False box = Box((x - 3, h + 1, z - 3), (x + 3, h + 16, z + 3)) return all(ctx.view.domain.contains(ctx.world(c)) for c in box.corners()) and ctx.view.clear(ctx.frame.box(box)) and not ctx.view.protected(ctx.frame.box(Box((x - 3, h, z - 3), (x + 3, h + 2, z + 3)))) chosen = scatter(ctx, candidates, legal, self.tree_minimum, self.tree_maximum, 'trees') for i, (x, z) in enumerate(chosen): y = ctx.elevation(x, z) + 1 h = ctx.scope.child(f'tree-{i}').choose((9, 11, 13, 15), 'height') p.children.append(Child(f'tree-{i}', Tree(h), frame=Frame((x, y, z)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) rng = ctx.rng('groundcover') for x in range(x0 + 1, x1): for z in range(z0 + 1, z1): if rng.random() > self.density or any(abs(x - a) <= 3 and abs(z - b) <= 3 for a, b in chosen): continue h = ctx.elevation(x, z) if name_of(ctx.state((x, h, z))) != 'grass_block': continue if name_of(ctx.state((x, h + 1, z))) != 'air': continue if ctx.view.protected(ctx.frame.box(Box((x, h + 1, z), (x, h + 2, z)))): continue p.children.append(Child(f'grass-{x}-{z}', Grass(), frame=Frame((x, h + 1, z)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) return p @dataclass(frozen=True) class FacadeGarden: width: int depth: int sides: tuple[str, ...] def capability(self): return Capability('facade.garden', ('decoration', 'plant'), adaptations=('avoid facade openings',), guarantees=('unobstructed doorways',)) def negotiate(self, ctx, parameters): return Contract(Box((-1, 0, -1), (self.width, 3, self.depth)))
3410
tail -n 16 reports/extension-corpus/first-assessment.log rg -n 'incompatible|defect|budget' reports/extension-corpus/first-assessment.log
tail -n 16 reports/extension-corpus/first-assessment.log rg -n 'incompatible|defect|budget' reports/extension-corpus/first-assessment.log
hall-4 validated hall-5 validated hall-6 validated hall-7 validated hall-8 validated hall-9 validated hall-10 validated hall-11 validated campus-0 validated campus-1 validated campus-2 validated campus-3 validated campus-4 validated campus-5 validated perimeter-0 validated perimeter-1 validated
350102
cat > hearth_extensions/assessment.py <<'PY' # Frozen extension inputs, actual principal/contact signatures and retained outcomes. import hashlib impo
cat > hearth_extensions/assessment.py <<'PY' # Frozen extension inputs, actual principal/contact signatures and retained outcomes. import hashlib import json import time from pathlib import Path from dataclasses import replace from collections import Counter from hearth import Scene,Box,Frame,Binding from hearth.kernel import ContractError,SearchExhausted,validate from hearth.environment import Terrain,gradient,wave,radial from hearth.randomness import Scope from hearth.persistence import semantic_digest,export_scene from hearth.blocks import solid from .geometry import Polyline,Polygon from .sites import Platform from .interfaces import Endpoint from .circulation import Link from .boundaries import BoundaryChain,IlluminateBoundary from .halls import Pavilion from .programs import frozen_site,branching_campus,perimeter_cluster PROBE_DOMAIN=Box((-8,-4,-8),(45,52,45)) def probe_expression(environment_seed): rng=Scope(environment_seed).stream('probe-field') return (gradient(rng.choice((-.025,0,.035)),rng.choice((0,.015)),2)+wave(rng.choice((0,.35,.7)),.11,.09,rng.random()*6)+radial(16,18,14,-rng.choice((0,1,2)))).clamp(-1,5),rng.choice((None,3)) def freeze_probe(environment_seed): field,water=probe_expression(environment_seed) s=Scene(environment_seed,domain=PROBE_DOMAIN) s.place('land',Terrain(s.domain,field,water)) return s.finalize() def connector_scene(environment,structure_seed): s=environment.fork(seed=structure_seed) rng=Scope(structure_seed).stream('connection-intent') s.place('a',Platform('/land')) s.place('b',Platform('/land'),frame=Frame((18,0,27))) a,b=Endpoint('/a','south'),Endpoint('/b','north') link=Link(a,b,'/land',via=((rng.choice((9,12,15)),rng.choice((16,18,20))),),width=rng.choice((3,5)),rise=rng.choice((0,1,2)),covered=rng.choice((True,False))) s.place('link',link,bindings=(a.binding(),b.binding())) return s.finalize() def boundary_scene(environment,structure_seed): rng=Scope(structure_seed).stream('boundary-intent') controls=((0,0),(8,rng.choice((0,10,23))),(28,rng.choice((0,5,18))),(37,18)) curve=Polyline(((0,0),(37,18))) if structure_seed==0 else Polyline.bezier(controls) s=environment.fork(seed=structure_seed) s.place('boundary',BoundaryChain(curve,height=rng.choice((1,2,3)),spacing=rng.choice((4,7,10)))) s.place('lights',IlluminateBoundary('/boundary')) return s.finalize() def hall_scene(seed,environment_seed=None): rng=Scope(seed).stream('hall-intent') domain=Box((-12,-4,-12),(42,65,42)) es=seed if environment_seed is None else environment_seed field=gradient(.012,-.008,4)+wave(.5,.1,.12,Scope(es).stream('hall-field').random()*6) env=Scene(es,domain=domain);env.place('land',Terrain(domain,field));env.finalize() s=env.fork(seed=seed) shape=Polygon.chamfered(rng.choice((13,17,21,25)),rng.choice((13,17,21)),rng.choice((0,2,4))) s.place('hall',Pavilion(shape,'/land',rng.choice(('library','workshop','living')),('north','south','east') if rng.choice((True,False)) else ('north','west'),height=rng.choice((5,6,7)),roof_run=rng.choice((2,3)),lantern=rng.choice((True,False)))) return s.finalize() def signatures(scene): """Measure current semantic geometry, omitting cosmetic material and contact height.""" halls=[];links=[];boundaries=[];organization=[] for path,node in sorted(scene.nodes.items()): d=node.contract.decisions if node.type=='extension.pavilion': footprint=sorted((node.frame.inverse(p)[0],node.frame.inverse(p)[2]) for p in scene.cells(path+'/floor')) halls.append({'footprint':footprint,'height':d['height'],'function':d['purpose'],'entrances':d['entrances'],'roof_run':d['roof_run'],'lantern':d['lantern']}) if node.type in ('extension.bridge','extension.gallery'): pts=[node.frame.inverse(p) for p in scene.cells(path+'/deck')] x0,z0=d['center'][0] links.append({'body':sorted((p[0]-x0,p[2]-z0) for p in pts),'width':d['width'],'covered':d['covered'],'rise':d['rise']}) if node.type=='extension.boundary-chain': pts=[node.frame.inverse(p) for p in scene.cells(path,True) if 'boundary-lantern' not in scene.nodes[scene.inspect(p)['instance']].type] x0=min(p[0] for p in pts);z0=min(p[2] for p in pts) boundaries.append(sorted(set((p[0]-x0,p[2]-z0) for p in pts))) if node.type=='extension.campus': vertex_keys=d['vertices'] vertices=[] for key in vertex_keys: v=scene.nodes[path+'/'+key] at=node.frame.inverse(v.frame.origin) vertices.append((at[0],at[2],v.capability.tags)) topology=sorted((vertex_keys.index(a),pa,vertex_keys.index(b),pb,covered,width) for a,pa,b,pb,covered,width in d['edges']) organization.append({'positions':vertices,'topology':topology}) from hearth.assessment import principal_signature legacy=principal_signature(scene)[1]['buildings'] principal={'halls':halls,'links':links,'boundaries':boundaries,'organization':organization,'legacy':legacy} contact=[];fill=0;replaced=0;excavated=0 for path,node in sorted(scene.nodes.items()): if node.type in ('extension.trestles','adapter.foundation','adapter.approach'): contact.append((node.type,node.contract.decisions)) fill+=len(scene.cells(path)) replaced+=len(scene.displaced.get(path,{})) excavated+=sum(solid(old.state) and (p not in scene.blocks or not solid(scene.blocks[p].state)) for p,old in scene.displaced.get(path,{}).items()) digest=lambda x:hashlib.sha256(json.dumps(x,sort_keys=True,default=list).encode()).hexdigest() return {'principal_signature':digest(principal),'structure':principal,'contact_signature':digest(contact),'contact_cells':fill,'contact_replacements':replaced,'excavated_solid_cells':excavated} def measured(label,recipe,inputs,artifact=None): start=time.perf_counter() row={'label':label,'inputs':inputs,'candidate_attempts':1,'accepted_candidates':0,'retries':0} try: scene=recipe();scene.finalize() row.update(status='validated',accepted_candidates=1,blocks=len(scene.blocks),instances=len(scene.nodes),digest=semantic_digest(scene),**signatures(scene)) if artifact: export_scene(scene,artifact) row['artifact']=str(artifact) except ContractError as exc: limits=('site-relief','support-height','connection-support-height','connection-fill-limit','boundary-grade','endpoint-grade','approach-detour','connection-domain') row.update(status='budget-exhausted' if isinstance(exc,SearchExhausted) else ('incompatible' if exc.diagnostic.rule in limits else 'defect'),diagnostic=exc.diagnostic.__dict__,all_diagnostics=[d.__dict__ for d in getattr(exc,'diagnostics',[exc.diagnostic])]) except Exception as exc: row.update(status='defect',diagnostic={'exception':type(exc).__name__,'message':str(exc)}) row['seconds']=round(time.perf_counter()-start,4) return row def run(output,root_seed=0,artifacts=False): output=Path(output);output.mkdir(parents=True,exist_ok=True) rows=[];frozen={};inputs=[] for es in range(root_seed*100,root_seed*100+8): frozen[es]=freeze_probe(es) field,water=probe_expression(es) inputs.append({'environment_seed':es,'expression':field.expression(),'water':water,'digest':semantic_digest(frozen[es])}) (output/'frozen-inputs.json').write_text(json.dumps(inputs,indent=2)) def record(label,fn,parameters,keep=False): path=Path('samples/extensions')/(label+'.litematic') if keep and artifacts else None row=measured(label,fn,parameters,path);rows.append(row) print(label,row['status'],flush=True) for i,es in enumerate(frozen): for bs in range(6): record(f'connector-{i}-{bs}',lambda e=frozen[es],b=bs:connector_scene(e,b),{'environment':inputs[i],'structure_seed':bs},(i,bs) in ((0,0),(1,2),(4,3),(7,5))) assert semantic_digest(frozen[es])==inputs[i]['digest'] for es in range(4): # Independent dry substrates use the same field expression with water omitted. field,_=probe_expression(es+root_seed*100) env=Scene(es,domain=PROBE_DOMAIN);env.place('land',Terrain(env.domain,field));env.finalize() for bs in range(4): record(f'boundary-{es}-{bs}',lambda e=env,b=bs:boundary_scene(e,b),{'environment_seed':es+root_seed*100,'expression':field.expression(),'structure_seed':bs},(es,bs) in ((0,1),(3,3))) for seed in range(12): record(f'hall-{seed}',lambda b=seed:hall_scene(b,root_seed*100+b),{'structure_seed':seed,'environment_seed':root_seed*100+seed},seed in (0,4,7)) for name,program in (('campus',branching_campus),('perimeter',perimeter_cluster)): for seed in range(6): environment=frozen_site(root_seed*100+seed) identity=semantic_digest(environment) def recipe(e=environment,b=seed,p=program): s=e.fork(seed=b);s.place('campus',p(b));return s.finalize() record(f'{name}-{seed}',recipe,{'program':name,'structure_seed':seed,'environment_seed':root_seed*100+seed,'frozen_digest':identity},seed in (0,3)) assert semantic_digest(environment)==identity for i in range(24): es=2000+root_seed*100+i;rng=Scope(es).stream('stress') field=(gradient(rng.choice((0,.12,.28)),rng.choice((0,-.12,.15)),2)+wave(rng.choice((0,2,4)),.13,.1,rng.random()*6)).clamp(-2,18) water=rng.choice((None,3,9,12)) env=Scene(es,domain=PROBE_DOMAIN);env.place('land',Terrain(env.domain,field,water));env.finalize() record(f'stress-{i:02}',lambda e=env,b=i%6:connector_scene(e,b),{'environment_seed':es,'structure_seed':i%6,'expression':field.expression(),'water':water}) (output/'results.json').write_text(json.dumps(rows,indent=2)) summary={} for name in ('connector','boundary','hall','campus','perimeter','stress'): part=[r for r in rows if r['label'].startswith(name+'-')];good=[r for r in part if r['status']=='validated'] summary[name]={'inputs':len(part),'outcomes':dict(Counter(r['status'] for r in part)),'candidate_attempts':sum(r['candidate_attempts'] for r in part),'accepted_candidates':sum(r['accepted_candidates'] for r in part),'retries':sum(r['retries'] for r in part),'principal_signatures':len({r['principal_signature'] for r in good}),'contact_signatures':len({r['contact_signature'] for r in good}),'contact_cells_range':[min((r['contact_cells'] for r in good),default=0),max((r['contact_cells'] for r in good),default=0)],'contact_replacement_range':[min((r['contact_replacements'] for r in good),default=0),max((r['contact_replacements'] for r in good),default=0)],'seconds':round(sum(r['seconds'] for r in part),3)} (output/'summary.json').write_text(json.dumps(summary,indent=2)) if artifacts: (Path('samples/extensions')/'replay-manifest.json').write_text(json.dumps([{k:r[k] for k in ('label','inputs','artifact','digest','status')} for r in rows if 'artifact' in r],indent=2)) return summary PY cat > examples/extension_assess.py <<'PY' # Rerun the retained extension sampling policy without altering first-phase evidence. import argparse import json from pathlib import Path from hearth_extensions.assessment import run if __name__=='__main__': p=argparse.ArgumentParser() p.add_argument('--seed',type=int,default=0) p.add_argument('--output',type=Path,default=Path('reports/extension-corpus/final')) p.add_argument('--artifacts',action='store_true') a=p.parse_args() print(json.dumps(run(a.output,a.seed,a.artifacts),indent=2)) PY yapf -i hearth_extensions/assessment.py hearth_extensions/graphs.py examples/extension_assess.py python -m examples.extension_assess --seed 0 --output reports/extension-corpus/first-assessment --artifacts > reports/extension-corpus/first-assessment.log
36017
python - <<'PY' import json from pathlib import Path for r in json.loads(Path('reports/extension-corpus/first-assessment/frozen-inputs.json').read_tex
python - <<'PY' import json from pathlib import Path for r in json.loads(Path('reports/extension-corpus/first-assessment/frozen-inputs.json').read_text()): print(r['environment_seed'],r['water']) PY python -m examples.extension_views --seed 0 --input samples/extensions/campus-0.litematic --output previews/extensions/campus-0 --size 1100 --sections > reports/extension-corpus/render-campus-0.txt
3706
python - <<'PY' from pathlib import Path p=Path('hearth/__init__.py');s=p.read_text().replace("'1.1.0'","'1.2.0'").replace('"1.1.0"','"1.2.0"');p.writ
python - <<'PY' from pathlib import Path p=Path('hearth/__init__.py');s=p.read_text().replace("'1.1.0'","'1.2.0'").replace('"1.1.0"','"1.2.0"');p.write_text(s) p=Path('pyproject.toml');s=p.read_text().replace('version = "1.1.0"','version = "1.2.0"');p.write_text(s) PY cat > examples/extension_inspection.py <<'PY' # Inspect real extension structures and verify the same public queries after reload. import argparse import json from pathlib import Path import hearth_extensions from hearth.persistence import load_scene,export_scene def inspect(source,seed,output): scene=load_scene(source) if scene.seed!=seed: raise ValueError('Explicit seed must match input artifact') queries=[] for tag in ('deck','window','fixture'): candidate=next((n for n in scene.nodes.values() if n.capability and tag in n.capability.tags and scene.cells(n.path)),None) if candidate is None: continue point=min(scene.cells(candidate.path)) queries.append({'tag':tag,'query':scene.inspect(point),'exact_cell_count':len(scene.cells(candidate.path)),'descendant_cell_count':len(scene.cells(candidate.path,True))}) export_scene(scene,output) restored=load_scene(output) for entry in queries: assert restored.inspect(entry['query']['position'])==entry['query'] assert len(restored.cells(entry['query']['instance']))==entry['exact_cell_count'] print(json.dumps({'source':str(source),'seed':seed,'verified_after_reload':True,'queries':queries},default=lambda v:sorted(v),indent=2)) if __name__=='__main__': p=argparse.ArgumentParser() p.add_argument('--seed',type=int,default=0) p.add_argument('--input',type=Path,required=True) p.add_argument('--output',type=Path,default=Path('samples/extensions/inspection.litematic')) a=p.parse_args();inspect(a.input,a.seed,a.output) PY yapf -i hearth/__init__.py examples/extension_inspection.py python -m examples.extension_inspection --seed 0 --input samples/extensions/campus-0.litematic --output samples/extensions/inspection.litematic > reports/extension-corpus/inspection.json
3800
tail -n 98 reports/extension-corpus/first-assessment.log
tail -n 98 reports/extension-corpus/first-assessment.log
}, "candidate_attempts": 16, "accepted_candidates": 16, "retries": 0, "principal_signatures": 4, "contact_signatures": 1, "contact_cells_range": [ 0, 0 ], "contact_replacement_range": [ 0, 0 ], "seconds": 2.7 }, "hall": { "inputs": 12, "outcomes": { "validated": 12 }, "candidate_attempts": 12, "accepted_candidates": 12, "retries": 0, "principal_signatures": 12, "contact_signatures": 12, "contact_cells_range": [ 38, 71 ], "contact_replacement_range": [ 6, 9 ], "seconds": 7.862 }, "campus": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 132, 206 ], "contact_replacement_range": [ 57, 126 ], "seconds": 25.332 }, "perimeter": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 82, 129 ], "contact_replacement_range": [ 21, 21 ], "seconds": 23.338 }, "stress": { "inputs": 24, "outcomes": { "incompatible": 9, "validated": 15 }, "candidate_attempts": 24, "accepted_candidates": 15, "retries": 0, "principal_signatures": 6, "contact_signatures": 15, "contact_cells_range": [ 62, 259 ], "contact_replacement_range": [ 0, 254 ], "seconds": 5.16 } }
39022
cat >> test/test_extension_geometry.py <<'PY' def test_graph_parent_substitutes_public_access_components(): from hearth_extensions.graphs import
cat >> test/test_extension_geometry.py <<'PY' def test_graph_parent_substitutes_public_access_components(): from hearth_extensions.graphs import Campus,Vertex,Edge from hearth_extensions import Pavilion,Polygon domain=Box((-12,-4,-12),(55,65,60)) variants=[] for component in (Platform('/land',13,13),Pavilion(Polygon.chamfered(13,13,2),'/land',entrances=('north','south'))): s=Scene(6,domain=domain) s.place('land',Terrain(domain,gradient(base=3),water_level=3)) campus=Campus((Vertex('a',component,Frame()),Vertex('b',Platform('/land'),Frame((25,0,29)))),(Edge('a','south','b','north'),),'/land',domain,landscape=False) s.place('group',campus) s.finalize() assert len(s.view.offers('/group','access'))==1 assert ('/group/circulation/link-0','connects','/group/a') in s.relations variants.append(semantic_digest(s)) assert variants[0]!=variants[1] @pytest.mark.parametrize('environment_seed,structure_seed',[(0,0),(1,5),(2,3),(3,2),(4,1),(5,4),(6,0),(7,5)]) def test_independent_extension_environment_structure_pairs(environment_seed,structure_seed): from hearth_extensions.assessment import freeze_probe,connector_scene frozen=freeze_probe(environment_seed) digest=semantic_digest(frozen) scene=connector_scene(frozen,structure_seed) assert semantic_digest(frozen)==digest assert not validate(scene,True) PY cat >> test/test_extension_protocol.py <<'PY' def test_importable_generation_has_no_new_native_dependency(): import subprocess,sys from pathlib import Path code=''' import sys,importlib.abc class NoNative(importlib.abc.MetaPathFinder): def find_spec(self, fullname, path=None, target=None): if fullname.split('.')[0] in ('numpy','mcio','scipy','shapely','ctypes'): raise RuntimeError('Unexpected native/transport dependency: '+fullname) sys.meta_path.insert(0,NoNative()) from hearth_extensions.assessment import hall_scene from hearth.persistence import semantic_digest scene=hall_scene(4,1) print(semantic_digest(scene)) ''' result=subprocess.run([sys.executable,'-c',code],cwd=Path(__file__).parents[1],capture_output=True,text=True) assert result.returncode==0,result.stderr assert len(result.stdout.strip())==64 PY yapf -i hearth_extensions/sites.py hearth_extensions/boundaries.py test/test_extension_geometry.py test/test_extension_protocol.py python -m pytest -q test/test_extension_geometry.py test/test_extension_protocol.py test/test_extension_failures.py > reports/extension-corpus/focused-final.txt
4000
cat reports/extension-corpus/focused-final.txt cat reports/extension-corpus/first-assessment/summary.json
cat reports/extension-corpus/focused-final.txt cat reports/extension-corpus/first-assessment/summary.json
": 6, "contact_signatures": 48, "contact_cells_range": [ 3, 108 ], "contact_replacement_range": [ 0, 100 ], "seconds": 13.111 }, "boundary": { "inputs": 16, "outcomes": { "validated": 16 }, "candidate_attempts": 16, "accepted_candidates": 16, "retries": 0, "principal_signatures": 4, "contact_signatures": 1, "contact_cells_range": [ 0, 0 ], "contact_replacement_range": [ 0, 0 ], "seconds": 2.7 }, "hall": { "inputs": 12, "outcomes": { "validated": 12 }, "candidate_attempts": 12, "accepted_candidates": 12, "retries": 0, "principal_signatures": 12, "contact_signatures": 12, "contact_cells_range": [ 38, 71 ], "contact_replacement_range": [ 6, 9 ], "seconds": 7.862 }, "campus": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 132, 206 ], "contact_replacement_range": [ 57, 126 ], "seconds": 25.332 }, "perimeter": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 82, 129 ], "contact_replacement_range": [ 21, 21 ], "seconds": 23.338 }, "stress": { "inputs": 24, "outcomes": { "incompatible": 9, "validated": 15 }, "candidate_attempts": 24, "accepted_candidates": 15, "retries": 0, "principal_signatures": 6, "contact_signatures": 15, "contact_cells_range": [ 62, 259 ], "contact_replacement_range": [ 0, 254 ], "seconds": 5.16 } }
410122
yapf -i hearth_extensions/circulation.py hearth_extensions/assessment.py python -m pytest -q test > reports/extension-corpus/full-regression.txt
yapf -i hearth_extensions/circulation.py hearth_extensions/assessment.py python -m pytest -q test > reports/extension-corpus/full-regression.txt
42045
cat > examples/extension_replay.py <<'PY' # Cross-process extension replay with full semantic graph and query comparisons. import argparse import json
cat > examples/extension_replay.py <<'PY' # Cross-process extension replay with full semantic graph and query comparisons. import argparse import json import os from pathlib import Path import subprocess import sys import tempfile CHILD = ''' import sys,json,hashlib from pathlib import Path from hearth_extensions.programs import extension_scene,perimeter_cluster from hearth_extensions.assessment import signatures from hearth.persistence import export_scene,load_scene,semantic_digest,encode scene=extension_scene(perimeter_cluster,int(sys.argv[1]),int(sys.argv[2])) p=next(p for p,c in sorted(scene.blocks.items()) if c.state=='minecraft:glass' and 'facade' in c.owner) query=scene.inspect(p) nodes=json.dumps(encode(scene.nodes),sort_keys=True,separators=(',',':')) output=Path(sys.argv[3]);export_scene(scene,output) restored=load_scene(output) assert restored.inspect(p)==query assert encode(restored.nodes)==encode(scene.nodes) print(json.dumps({'digest':semantic_digest(scene),'principal':signatures(scene)['principal_signature'],'nodes_digest':hashlib.sha256(nodes.encode()).hexdigest(),'nodes':len(scene.nodes),'glass_query':query},default=lambda v:sorted(v),sort_keys=True)) ''' def replay(seed,environment_seed,output): root=Path(__file__).resolve().parents[1] rows=[] with tempfile.TemporaryDirectory(dir=root/'test',prefix='tmp-extension-replay-') as temporary: for hash_seed in ('5','918273'): artifact=Path(temporary)/f'seed {seed} hash {hash_seed}.litematic' result=subprocess.run([sys.executable,'-c',CHILD,str(seed),str(environment_seed),str(artifact)],cwd=root,env=dict(os.environ,PYTHONHASHSEED=hash_seed),capture_output=True,text=True,check=True) rows.append({'PYTHONHASHSEED':hash_seed,'result':json.loads(result.stdout)}) if rows[0]['result']!=rows[1]['result']: raise AssertionError('Extension replay mismatch') output.parent.mkdir(parents=True,exist_ok=True) output.write_text(json.dumps({'verified':True,'seed':seed,'environment_seed':environment_seed,'runs':rows},indent=2)) print('Verified extension content, nodes, signatures, glass query and paired reload across two Python hash seeds.') if __name__=='__main__': p=argparse.ArgumentParser() p.add_argument('--seed',type=int,default=3) p.add_argument('--environment-seed',type=int,default=7) p.add_argument('--output',type=Path,default=Path('reports/extension-corpus/replay.json')) a=p.parse_args();replay(a.seed,a.environment_seed,a.output) PY yapf -i examples/extension_replay.py set -e python -m examples.extension_replay --seed 3 --environment-seed 7 --output reports/extension-corpus/replay.json > reports/extension-corpus/replay.log python -m examples.verify_replay --seed 0 --output reports/extension-corpus/original-default-replay.json > reports/extension-corpus/original-default-replay.log
430105
python -m examples.extension_assess --seed 0 --output reports/extension-corpus/final --artifacts > reports/extension-corpus/final-assessment.log
python -m examples.extension_assess --seed 0 --output reports/extension-corpus/final --artifacts > reports/extension-corpus/final-assessment.log
4400
pwd && rg --files reports/extension-corpus examples | sort
pwd && rg --files reports/extension-corpus examples | sort
ension_generate.cpython-312.pyc examples/__pycache__/extension_inspection.cpython-312.pyc examples/__pycache__/extension_replay.cpython-312.pyc examples/__pycache__/extension_views.cpython-312.pyc examples/__pycache__/preview.cpython-312.pyc examples/__pycache__/verify_replay.cpython-312.pyc examples/assess.py examples/building.py examples/courtyard.py examples/extension.py examples/extension_assess.py examples/extension_generate.py examples/extension_inspection.py examples/extension_replay.py examples/extension_views.py examples/gallery.py examples/inspection.py examples/preview.py examples/prototype.py examples/verify_replay.py reports/extension-corpus/campus-development.txt reports/extension-corpus/client-probes-2.txt reports/extension-corpus/client-probes-3.txt reports/extension-corpus/client-probes.txt reports/extension-corpus/development-render.txt reports/extension-corpus/final-assessment.log reports/extension-corpus/final/frozen-inputs.json reports/extension-corpus/final/results.json reports/extension-corpus/final/summary.json reports/extension-corpus/first-assessment.log reports/extension-corpus/first-assessment/frozen-inputs.json reports/extension-corpus/first-assessment/results.json reports/extension-corpus/first-assessment/summary.json reports/extension-corpus/first-geometry-probes.txt reports/extension-corpus/focused-final.txt reports/extension-corpus/focused-tests-2.txt reports/extension-corpus/focused-tests.txt reports/extension-corpus/full-regression.txt reports/extension-corpus/geometry-probes-2.txt reports/extension-corpus/geometry-probes-3.txt reports/extension-corpus/inspection.json reports/extension-corpus/kernel-regression.txt reports/extension-corpus/original-default-replay.json reports/extension-corpus/original-default-replay.log reports/extension-corpus/render-campus-0.txt reports/extension-corpus/replay.json reports/extension-corpus/replay.log reports/extension-corpus/sampling-policy.json reports/extension-corpus/transforms-and-novelty.txt
4500
cat ARCHITECTURE.md; cat reports/extensions-baseline/api-delta.md
cat ARCHITECTURE.md; cat reports/extensions-baseline/api-delta.md
ction, capacity use and dependency without acquiring a mutation grant, whether or not the port also has a grant. All other verbs retain their original checks. A connection never authorizes writing to the host. The extension cannot implement this using its own effects because binding permissions are enforced by the kernel before effects are applied; requesting unrelated mutation permission would misrepresent its authority. No component-name dispatch or signature change was added. The regression suite adds a negative case proving that a connected consumer cannot overwrite the landing. Old artifact structures and serialized contract schemas are unchanged. This is a self-authored extension/protocol exercise, not independent review. ## Explicit replacements in a coupled replay The bridge replacement test exposed conservative host invalidation: removing contact output can invalidate earlier platform surveys even though their principal intent is unchanged. Replaying only the link correctly refuses to finalize stale platform observations. Replaying hosts and link together was possible, but the public API could only replace the first target, while the changed link must come after its hosts. The proposed `replacements` call failed before the change; its TypeError is retained in `failing-replay-probe.txt`, and the original stale-input result remains in `../extension-corpus/focused-tests.txt`. `Scene.regenerate(..., dependents=(...), replacements={path: component, ...})` now accepts explicit replacements for any named replay target. Targets remain explicitly ordered, retain their frames, scopes and bindings, and replay in one bounded transaction. Undeclared or duplicate targets fail. No automatic graph-wide update loop or stale-flag bypass was added. A link can be replaced while its unchanged hosts are recomputed first from their inputs. Reloaded branches may likewise supply their implementations explicitly through this mapping. Existing calls keep their previous behavior.
4600
cat reports/extension-corpus/full-regression.txt reports/extension-corpus/final/summary.json reports/extension-corpus/replay.json reports/extension-co
cat reports/extension-corpus/full-regression.txt reports/extension-corpus/final/summary.json reports/extension-corpus/replay.json reports/extension-corpus/original-default-replay.json
"contained_by", "/campus/market" ], [ "/campus/market/light-4-4", "contained_by", "/campus/market" ], [ "/campus/market/light-4-9", "contained_by", "/campus/market" ], [ "/campus/market/light-9-4", "contained_by", "/campus/market" ], [ "/campus/market/light-9-9", "contained_by", "/campus/market" ], [ "/campus/market/roof", "contained_by", "/campus/market" ], [ "/campus/market/shell", "contained_by", "/campus/market" ], [ "/campus/reading", "contained_by", "/campus" ] ], "shared": [], "state": "minecraft:glass" }, "nodes": 385, "nodes_digest": "7f03bb1230508adee058ac19020c0702a9f7d19c241963db19b9a14e703450c5", "principal": "e582861768e396b4f060b4aabca0b55e914ddc89cbf104c85dc2411bcad265a7" } } ] }{ "verified": true, "runs": [ { "seed": 0, "PYTHONHASHSEED": "3", "digest": "e81b08063278b231b60eaa16e4120973ed688bb3fd7e6a8da439daa4e7f5caf9", "bounds": [ [ -49, -4, -23 ], [ 49, 32, 104 ] ], "blocks": 125475, "buildings": 5 }, { "seed": 0, "PYTHONHASHSEED": "8675309", "digest": "e81b08063278b231b60eaa16e4120973ed688bb3fd7e6a8da439daa4e7f5caf9", "bounds": [ [ -49, -4, -23 ], [ 49, 32, 104 ] ], "blocks": 125475, "buildings": 5 } ] }
4700
cat AGENTS.md /work/AGENTS.md; cat examples/extension_views.py; cat GENERATOR.md
cat AGENTS.md /work/AGENTS.md; cat examples/extension_views.py; cat GENERATOR.md
ervative; no implicit arbitrary auto-replan | | R20 | SHA-256 scope keys/purposes, overrides, copied environments; branch/order/retry and hash-seed replay tests | Genuine spatial dependencies may change descendants | | R21 | Configurable `Limits`, `SiteLimits`, effect envelopes and realized export bounds | Demonstration count bound is only in the CLI | | R22 | Initial design, kernel tests, prototype, buildings/extension, corpus/render stages | Generic defects and fixes recorded in development findings | | R23 | `test_kernel`, `test_contracts_provenance`: substitution, independent extension, authority, rollback, sharing, transforms, seeds | Custom validator registration also tested | | R24 | Glass chain, two identities, external attachment membership, updates/deletions/regeneration, shared cells, transport mismatch tests | Actual structure restored from companion, not inferred from materials | | R25 | 64 frozen pairings, compatible independent field/environment, protected outside cells, perturbation and stress records | Finite supported domain; 32 stress inputs retained without resampling | | R26 | Three short clients x eight seeds; settlement x eight seeds plus counts 3 and 6; later courtyard/gallery | Programs use public room/component APIs | | R27 | Actual blocks/NBT: schema, support, headroom/routes, pair consistency, enclosure, lights, furnishings, pools and path joins; deliberate damage tests | Physical/lighting model limitations above apply | | R28 | Structural/contact signatures, exterior views, circulation/furnishing cutaways, inspection notes | Modular aesthetic remains visible; no exhaustive beauty claim | | R29 | `generate.py`, importable scene builders, inspection example, verified one-region transport | Offline runtime uses bundled schema and installed/provided MCIO | | R30 | Library, docs, CLI, tests, extension, output pair, manifest, reports and labeled previews | Broader simulation, arbitrary entities, browser UI and city planner remain unfinished |
4800
sed -n '1,240p' hearth_extensions/assessment.py; cat reports/extension-corpus/sampling-policy.json
sed -n '1,240p' hearth_extensions/assessment.py; cat reports/extension-corpus/sampling-policy.json
hase": "extension", "version": 1, "root_seed": 0, "frozen_before_assessment": true, "connectors": {"environment_seeds": [0,7], "structure_seeds": [0,5], "count": 48, "policy": "Eight independently frozen generic terrain expressions, each copied for six width/rise/cover/curve decisions. Locked platforms and public endpoints. Gradients bounded by 0.035, waves 0..0.7, radial depression 0..2, optional water level 3. Width 3 or 5, rise 0..2, post height <=8, maximum unsupported taxicab deck span 6, fill <=800. No resampling."}, "boundaries": {"count": 16, "policy": "Four environment seeds by four independently seeded cubic controls, height 1..3 and socket spacing 4..10. Include a zero-curvature line. Maximum base change one block per raster step."}, "halls": {"count": 12, "policy": "Seeds 0..11, variable polygon widths/depths 13..25, chamfer 0..4, ceiling 5..7, hip or hip with lantern. Functions, entrances and proportions locked before site query."}, "compositions": {"count": 12, "policy": "Two lightweight public graph clients, seeds 0..5. One branching campus, one perimeter cluster. Preserve locked vertices and declared graph edges. Includes existing Hearth buildings substituted for polygon halls."}, "stress": {"count": 24, "policy": "Single locked endpoint pair per input. Independent environment seeds 2000..2023, gradients through 0.28, waves through 4, water through 12, profile rise 0..3. Retain every success and failure without resampling or widened bounds."}, "novel_compositions": "Focused tests additionally use an unsampled kinked polyline and a polygon footprint not used in the two shipped clients.", "metrics": ["input outcome", "candidate acceptance", "all diagnostics", "runtime", "actual edit cost", "principal geometry/topology signature", "contact signature"], "claims": "Self-authored finite extension exercise, not independent audit. Prior external Pyodide results are user-reported; this phase claims only execution actually performed here." }
4900
cat /work/AGENTS.md; cat examples/extension_views.py; cat examples/extension_inspection.py
cat /work/AGENTS.md; cat examples/extension_views.py; cat examples/extension_inspection.py
n__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path, required=True) p.add_argument('--output', type=Path, required=True) p.add_argument('--size', type=int, default=1100) p.add_argument('--sections', action='store_true') a = p.parse_args() views(a.seed, a.input, a.output, a.size, a.sections) # Inspect real extension structures and verify the same public queries after reload. import argparse import json from pathlib import Path import hearth_extensions from hearth.persistence import load_scene, export_scene def inspect(source, seed, output): scene = load_scene(source) if scene.seed != seed: raise ValueError('Explicit seed must match input artifact') queries = [] for tag in ('deck', 'window', 'fixture'): candidate = next((n for n in scene.nodes.values() if n.capability and tag in n.capability.tags and scene.cells(n.path)), None) if candidate is None: continue point = min(scene.cells(candidate.path)) queries.append({'tag': tag, 'query': scene.inspect(point), 'exact_cell_count': len(scene.cells(candidate.path)), 'descendant_cell_count': len(scene.cells(candidate.path, True))}) export_scene(scene, output) restored = load_scene(output) for entry in queries: assert restored.inspect(entry['query']['position']) == entry['query'] assert len(restored.cells(entry['query']['instance'])) == entry['exact_cell_count'] print(json.dumps({'source': str(source), 'seed': seed, 'verified_after_reload': True, 'queries': queries}, default=lambda v: sorted(v), indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path, required=True) p.add_argument('--output', type=Path, default=Path('samples/extensions/inspection.litematic')) a = p.parse_args() inspect(a.input, a.seed, a.output)
5000
rg --files previews/extensions samples/extensions; sed -n '1,150p' GENERATOR.md; sed -n '1,230p' hearth_extensions/programs.py
rg --files previews/extensions samples/extensions; sed -n '1,150p' GENERATOR.md; sed -n '1,230p' hearth_extensions/programs.py
outh', covered=True), Edge('hall', 'east', 'kitchen', 'west', rise=rng.choice((0, 1))), Edge('hall', 'south', 'lodge', 'street', covered=True)] if rng.choice((False, True)): vertices.append(Vertex('archive', Pavilion(Polygon.chamfered(13, 13, 2), '/land', 'library', ('east',)), Frame((0, 0, 51)))) edges.append(Edge('hall', 'west', 'archive', 'east', rise=1)) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(tuple(vertices), tuple(edges), '/land', DOMAIN, boundary) def perimeter_cluster(seed=0): rng = Scope(seed).stream('perimeter-graph') widths = (rng.choice((17, 21, 25)), rng.choice((13, 17)), rng.choice((13, 17))) market = Pavilion(Polygon.chamfered(widths[0], 13, 2), '/land', 'workshop', ('north', 'east', 'south'), height=5, roof_run=3) reading = Pavilion(Polygon.chamfered(widths[1], 17, 3), '/land', 'library', ('north', 'south'), height=6, lantern=rng.choice((True, False))) dining = Pavilion(Polygon.chamfered(widths[2], 13, 2), '/land', 'living', ('east', 'west'), height=5) vertices = (Vertex('market', market, Frame((0, 0, 0))), Vertex('reading', reading, Frame((50, 0, 10))), Vertex('dining', dining, Frame((20, 0, 57)))) edges = (Edge('market', 'east', 'reading', 'north', via=((40, -5),), covered=False, rise=1), Edge('reading', 'south', 'dining', 'east', covered=True), Edge('dining', 'west', 'market', 'south', via=((9, 42),), rise=rng.choice((0, 1)))) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(vertices, edges, '/land', DOMAIN, boundary) def extension_scene(program=branching_campus, seed=0, environment_seed=0): environment = frozen_site(environment_seed) original = semantic_digest(environment) scene = environment.fork(seed=seed) scene.place('campus', program(seed)) scene.finalize() if semantic_digest(environment) != original: raise AssertionError('Frozen input mutated') return scene
5109
python -m examples.extension_views --seed 5 --input samples/extensions/connector-7-5.litematic --output previews/extensions/wet-connector --sections >
python -m examples.extension_views --seed 5 --input samples/extensions/connector-7-5.litematic --output previews/extensions/wet-connector --sections > reports/extension-corpus/render-wet-connector.txt 2>&1
52019
python -m examples.extension_views --seed 3 --input samples/extensions/perimeter-3.litematic --output previews/extensions/perimeter-3 --sections > rep
python -m examples.extension_views --seed 3 --input samples/extensions/perimeter-3.litematic --output previews/extensions/perimeter-3 --sections > reports/extension-corpus/render-perimeter-3.txt 2>&1
5300
sed -n '1,280p' hearth_extensions/halls.py; sed -n '1,260p' hearth_extensions/graphs.py
sed -n '1,280p' hearth_extensions/halls.py; sed -n '1,260p' hearth_extensions/graphs.py
Error('graph-access', ctx.path, conditions='First vertex must expose usable access') gateway = Port('public', 'access', port.frame, port.region, port.capacity, delegate=(first.key, port.key)) return Contract(self.envelope, ports=(gateway,), decisions={'vertices': [v.key for v in self.vertices], 'edges': [(e.a, e.a_port, e.b, e.b_port, e.covered, e.width) for e in self.edges]}) def realize(self, ctx, contract): p = Plan(children=[Child(v.key, v.component, frame=v.frame) for v in self.vertices]) p.children.append(Child('circulation', Connections(ctx.path, self.edges, self.terrain, self.envelope))) if self.boundary is not None: p.children.extend((Child('boundary', BoundaryChain(self.boundary)), Child('boundary-lights', IlluminateBoundary(ctx.path + '/boundary', 2)))) if self.landscape: p.children.append(Child('landscape', Landscape(self.envelope, self.terrain, 8, 12, 0.025))) return p @dataclass(frozen=True) class Connections: parent: str edges: tuple[Edge, ...] terrain: str envelope: Box def capability(self): return Capability('extension.connection-graph', ('connection', 'composite')) def negotiate(self, ctx, parameters): targets = [] for edge in self.edges: for key, port in ((edge.a, edge.a_port), (edge.b, edge.b_port)): targets.append(ctx.local(ctx.view.port(self.parent + '/' + key, port).frame.origin)) return Contract(self.envelope, rules=(Rule('route', tuple(targets), self.envelope, phase='complete'),)) def realize(self, ctx, contract): p = Plan() for i, edge in enumerate(self.edges): a = Endpoint(self.parent + '/' + edge.a, edge.a_port) b = Endpoint(self.parent + '/' + edge.b, edge.b_port) p.children.append(connection(f'link-{i}', a, b, self.terrain, via=edge.via, covered=edge.covered, rise=edge.rise, width=edge.width)) return p
5400
sed -n '1,150p' examples/verify_replay.py; cat hearth_extensions/__init__.py; cat reports/extensions-baseline/module-hashes.json; sed -n '1,130p' hear
sed -n '1,150p' examples/verify_replay.py; cat hearth_extensions/__init__.py; cat reports/extensions-baseline/module-hashes.json; sed -n '1,130p' hearth/persistence.py; cat pyproject.toml; cat reports/extension-corpus/final-assessment.log
"contact_signatures": 48, "contact_cells_range": [ 3, 108 ], "contact_replacement_range": [ 0, 100 ], "seconds": 13.313 }, "boundary": { "inputs": 16, "outcomes": { "validated": 16 }, "candidate_attempts": 16, "accepted_candidates": 16, "retries": 0, "principal_signatures": 4, "contact_signatures": 16, "contact_cells_range": [ 0, 0 ], "contact_replacement_range": [ 0, 0 ], "seconds": 2.779 }, "hall": { "inputs": 12, "outcomes": { "validated": 12 }, "candidate_attempts": 12, "accepted_candidates": 12, "retries": 0, "principal_signatures": 12, "contact_signatures": 12, "contact_cells_range": [ 38, 71 ], "contact_replacement_range": [ 6, 9 ], "seconds": 8.02 }, "campus": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 132, 206 ], "contact_replacement_range": [ 232, 318 ], "seconds": 25.974 }, "perimeter": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 82, 129 ], "contact_replacement_range": [ 256, 451 ], "seconds": 24.337 }, "stress": { "inputs": 24, "outcomes": { "incompatible": 9, "validated": 15 }, "candidate_attempts": 24, "accepted_candidates": 15, "retries": 0, "principal_signatures": 6, "contact_signatures": 15, "contact_cells_range": [ 62, 259 ], "contact_replacement_range": [ 0, 254 ], "seconds": 5.268 } }
5505
python -m examples.extension_views --seed 3 --input samples/extensions/boundary-3-3.litematic --output previews/extensions/curve-boundary > reports/ex
python -m examples.extension_views --seed 3 --input samples/extensions/boundary-3-3.litematic --output previews/extensions/curve-boundary > reports/extension-corpus/render-curve-boundary.txt 2>&1
5607
python -m examples.extension_views --seed 4 --input samples/extensions/hall-4.litematic --output previews/extensions/hall-4 --sections > reports/exten
python -m examples.extension_views --seed 4 --input samples/extensions/hall-4.litematic --output previews/extensions/hall-4 --sections > reports/extension-corpus/render-hall-4.txt 2>&1
5700
sed -n '1,280p' hearth_extensions/circulation.py; sed -n '1,180p' test/test_extension_failures.py
sed -n '1,280p' hearth_extensions/circulation.py; sed -n '1,180p' test/test_extension_failures.py
20), (26, 0), (37, 17))) s.place('boundary', BoundaryChain(curve)) s.place('lamps', IlluminateBoundary('/boundary')) before = snapshot(s) with pytest.raises(ContractError): s.remove('/boundary') assert snapshot(s) == before changed = Polyline.bezier(((0, 1), (9, 19), (26, 1), (37, 18))) s.regenerate('/boundary', BoundaryChain(changed), dependents=('/lamps',)) s.finalize() p = s.view.offers('/boundary', 'mount')[0].frame.origin assert p in s.cells('/boundary', True) export_scene(s, work / 'curve.litematic') t = load_scene(work / 'curve.litematic') assert t.inspect(p) == s.inspect(p) base = (p[0], p[1] - 1, p[2]) damage(t, base) assert any(d.rule in ('support', 'enclosure') and d.position == base for d in validate(t, True)) def test_curve_boundary_rejects_incompatible_installation_frame(): from hearth_extensions import BoundaryLantern s = Scene(0, domain=Box((-3, -4, -3), (25, 25, 25))) s.place('land', Terrain(s.domain, gradient(base=3))) s.place('wall', Boundary(Polyline(((0, 0), (20, 8))))) port = s.view.offers('/wall', 'mount')[0] before = snapshot(s) with pytest.raises(ContractError, match='port-alignment'): s.place('bad-lamp', BoundaryLantern(), frame=Frame(port.frame.origin, port.frame.turn + 1), bindings=(Binding('/wall', port.key),)) assert snapshot(s) == before def test_failed_choice_does_not_perturb_sibling_randomness(): s = bridge_scene() s.remove('/link') a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') before = snapshot(s) bad = Link(a, b, '/land', fill_limit=0) with pytest.raises(ContractError): s.compose_choice(Choice('link', (Child('attempt', bad, bindings=(a.binding(), b.binding())),), lambda v, p: 0)) assert snapshot(s) == before good = Link(a, b, '/land', rise=1) s.place('link', good, bindings=(a.binding(), b.binding())) assert semantic_digest(s) == semantic_digest(bridge_scene())
5800
sed -n '130,280p' hearth/persistence.py; sed -n '150,310p' GENERATOR.md; cat test/test_extension_protocol.py
sed -n '130,280p' hearth/persistence.py; sed -n '150,310p' GENERATOR.md; cat test/test_extension_protocol.py
write-authority'): s.place('bad', Bad(endpoint), bindings=(endpoint.binding(),)) assert s.blocks == before and '/bad' not in s.nodes def test_atomic_multi_branch_replay_accepts_explicit_replacements(): from hearth.components.primitives import Volume s = Scene() s.place('a', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) s.place('b', Volume(Box((3, 0, 0), (3, 0, 0)), state_of('stone'))) s.regenerate('/a', dependents=('/b',), replacements={'/b': Volume(Box((3, 0, 0), (4, 0, 0)), state_of('oak_planks'))}) assert len(s.cells('/b')) == 2 assert s.inspect((0, 0, 0))['state'] == state_of('stone') def test_multi_branch_replay_rejects_undeclared_target_and_rolls_back(): from hearth.components.primitives import Volume from hearth.kernel import ContractError from hearth.persistence import semantic_digest s = Scene() s.place('a', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) before = semantic_digest(s) with pytest.raises(ContractError, match='replay-targets'): s.regenerate('/a', replacements={'/unknown': Landing()}) assert semantic_digest(s) == before and set(s.nodes) == {'/a'} def test_importable_generation_has_no_new_native_dependency(): import subprocess, sys from pathlib import Path code = ''' import sys,importlib.abc class NoNative(importlib.abc.MetaPathFinder): def find_spec(self, fullname, path=None, target=None): if fullname.split('.')[0] in ('numpy','mcio','scipy','shapely','ctypes'): raise RuntimeError('Unexpected native/transport dependency: '+fullname) sys.meta_path.insert(0,NoNative()) from hearth_extensions.assessment import hall_scene from hearth.persistence import semantic_digest scene=hall_scene(4,1) print(semantic_digest(scene)) ''' result = subprocess.run([sys.executable, '-c', code], cwd=Path(__file__).parents[1], capture_output=True, text=True) assert result.returncode == 0, result.stderr assert len(result.stdout.strip()) == 64
5900
cat examples/extension_assess.py; sed -n '1,240p' hearth_extensions/geometry.py; sed -n '1,230p' hearth_extensions/boundaries.py
cat examples/extension_assess.py; sed -n '1,240p' hearth_extensions/geometry.py; sed -n '1,230p' hearth_extensions/boundaries.py
4) p.children.append(Child(port.key, BoundaryLantern(), frame=frame, bindings=(Binding(self.host, port.key),))) return p @dataclass(frozen=True) class BoundaryChain: curve: Polyline height: int = 2 spacing: int = 7 chunk: int = 96 def capability(self): return Capability('extension.boundary-chain', ('boundary', 'composite'), offers=('mount',), inputs={'chunk': Domain(4, 220), 'height': Domain(1, 5), 'spacing': Domain(4, 12)}, guarantees=('continuous contour across component joins',)) def parts(self): cells = self.curve.cells() if len(set(cells)) != len(cells): raise ContractError('boundary-self-intersection', conditions='A simple open contour is required') count = max(1, (len(cells) + self.chunk - 1) // self.chunk) size = (len(cells) + count - 1) // count return tuple(Boundary(Polyline(cells[i:i + size]), self.height, self.spacing) for i in range(0, len(cells), size)) def negotiate(self, ctx, parameters): boxes = [] ports = [] last_height = None for i, part in enumerate(self.parts()): local = part.negotiate(ctx, {}) if last_height is not None and abs(local.decisions['levels'][0] - last_height) > part.max_step: raise ContractError('boundary-grade', ctx.path, conditions='Grade bound also applies at component joins') last_height = local.decisions['levels'][-1] boxes.append(local.envelope) for p in local.ports: ports.append(Port(f'segment-{i}-{p.key}', p.kind, p.frame, p.region, p.capacity, facts=p.facts, delegate=(f'segment-{i}', p.key))) return Contract(Box.enclosing(p for box in boxes for p in box.corners()), ports=tuple(ports), decisions={'segments': len(boxes), 'curve': self.curve.points}) def realize(self, ctx, contract): return Plan(children=[Child(f'segment-{i}', part) for i, part in enumerate(self.parts())])
60049
yapf -i examples/extension_audit.py && python -m examples.extension_audit --seed 0 --cli > reports/extension-corpus/artifact-audit.log 2>&1
yapf -i examples/extension_audit.py && python -m examples.extension_audit --seed 0 --cli > reports/extension-corpus/artifact-audit.log 2>&1
611280
sed -n '1,90p' hearth/kernel/contracts.py; cat reports/extension-corpus/artifact-audit.log; tail -8 reports/extension-corpus/render-hall-4.txt; sed -n
sed -n '1,90p' hearth/kernel/contracts.py; cat reports/extension-corpus/artifact-audit.log; tail -8 reports/extension-corpus/render-hall-4.txt; sed -n '1,80p' hearth_extensions/sites.py; git status --short
locks import state_of from hearth.adapters.site import Foundation, SiteLimits, survey from .geometry import Polygon, bounds2 from .circulation import Surface DIRECTIONS = {'north': (0, -1, 0), 'east': (1, 0, 1), 'south': (0, 1, 2), 'west': (-1, 0, 3)} def edge_frames(width, depth, height): return {'north': Frame((width // 2, height, 0), 0), 'east': Frame((width - 1, height, depth // 2), 1), 'south': Frame((width // 2, height, depth - 1), 2), 'west': Frame((0, height, depth // 2), 3)} @dataclass(frozen=True) class Platform: terrain: str width: int = 9 depth: int = 9 freeboard: int = 1 def capability(self): return Capability('extension.platform', ('platform', 'composite', 'access'), offers=('access',), inputs={'width': Domain(5, 27), 'depth': Domain(5, 27), 'freeboard': Domain(1, 3)}) def negotiate(self, ctx, parameters): footprint = tuple((x, z) for x in range(self.width) for z in range(self.depth)) samples = survey(ctx, footprint) y = samples['floor'] + self.freeboard - 1 region = bounds2(footprint, min(v[0] for v in samples['samples'].values()) - 1, y + 3) ports = tuple(Port(k, 'access', f, f.box(Box((-2, -1, 0), (2, 1, 0))), 8) for k, f in edge_frames(self.width, self.depth, y + 1).items()) return Contract(region, ports=ports, decisions={'floor': y, 'footprint': footprint, 'strategy': samples['strategy']}, rules=(Rule('route', tuple(f.frame.origin for f in ports), region, phase='complete'),)) def realize(self, ctx, contract): d = contract.decisions p = Plan(children=[Child('foundation', Foundation(tuple(d['footprint']), d['floor'], d['strategy']), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('deck', Surface(tuple((x, d['floor'], z) for x, z in d['footprint']), role='platform'))]) return p fatal: not a git repository (or any parent up to mount point /) Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
6200
rg -n 'class Furniture|def realize|self.purpose|chair' hearth/components/interior.py; sed -n '110,230p' hearth/components/interior.py; python - <<'PY'
rg -n 'class Furniture|def realize|self.purpose|chair' hearth/components/interior.py; sed -n '110,230p' hearth/components/interior.py; python - <<'PY' import json s=json.load(open('samples/extensions/hall-4.litematic.structure.json')) print(s['nodes']['/hall']['contract']['decisions']['purpose']) print(s['nodes']['/hall/furnishings']['contract']) PY
ide in self.windows: bays = (2, length - 4) if length >= 11 else ((1, length - 3) if length >= 9 else ((length - 2) // 2,)) for i, bay in enumerate(bays): if side in self.doors and abs(bay - length // 2) < 2: continue at = frame.compose(Frame((bay, 2, 0))) p.children.append(Child(f'window-{side}-{i}', self.window_component or Window(), frame=at, bindings=(Binding(wallpath, 'infill'),))) # Furnish the opposite half to the flight; clipping stays inside the furnishing component's declared domain. furniture = Furniture(self.purpose, w, d) if self.stair_up or self.stair_down: furniture = Furniture(self.purpose, w - 3, d) p.children.append(Child('furniture', furniture, frame=Frame((0, 1, 0)))) for i, (x, z) in enumerate(((2, d - 3), (w - 3, 2))): if self.stair_up and i == 1: x = w // 2 p.children.append(Child(f'light-{i}', self.light_component or Light(), frame=Frame((x, 4, z)))) from .landscape import FacadeGarden p.children.append(Child('facade-garden', FacadeGarden(w, d, tuple(s for s in self.windows if s not in self.doors)))) if self.stair_up: p.children.append(Child('stairs', Stair(), frame=Frame((w - 4, 1, 2)))) return p @dataclass(frozen=True) class Pattern: role: str envelope: Box writes: tuple def capability(self): return Capability('surface.' + self.role, (self.role,)) def negotiate(self, ctx, parameters): return Contract(self.envelope) def realize(self, ctx, contract): return Plan(writes=list(self.writes)) living {'$type': 'Contract', 'atomic_object': False, 'decisions': {}, 'envelope': {'$type': 'Box', 'hi': {'$tuple': [16, 8, 8]}, 'lo': {'$tuple': [4, 6, 4]}}, 'grants': {'$tuple': []}, 'ports': {'$tuple': []}, 'reads': {'$tuple': []}, 'rules': {'$tuple': []}}
6300
sed -n '1,109p' hearth/components/interior.py; cat test/test_extension_geometry.py
sed -n '1,109p' hearth/components/interior.py; cat test/test_extension_geometry.py
'/b', 'south') s.place('link', Link(a, b, '/land', curve=curve, covered=True), bindings=(a.binding(), b.binding())) s.finalize() # A six-sided asymmetric footprint absent from the shipped clients. polygon = Polygon(((2, 0), (18, 0), (22, 4), (22, 16), (0, 16), (0, 3))) other = Scene(19, domain=Box((-10, -4, -10), (40, 60, 40))) other.place('land', Terrain(other.domain, gradient(.01, .02, 3))) other.place('hall', Pavilion(polygon, '/land', entrances=('north', 'south'), height=7, roof_run=3)) other.finalize() def test_graph_parent_substitutes_public_access_components(): from hearth_extensions.graphs import Campus, Vertex, Edge from hearth_extensions import Pavilion, Polygon domain = Box((-12, -4, -12), (55, 65, 60)) variants = [] for component in (Platform('/land', 13, 13), Pavilion(Polygon.chamfered(13, 13, 2), '/land', entrances=('north', 'south'))): s = Scene(6, domain=domain) s.place('land', Terrain(domain, gradient(base=3), water_level=3)) campus = Campus((Vertex('a', component, Frame()), Vertex('b', Platform('/land'), Frame((25, 0, 29)))), (Edge('a', 'south', 'b', 'north'),), '/land', domain, landscape=False) s.place('group', campus) s.finalize() assert len(s.view.offers('/group', 'access')) == 1 assert ('/group/circulation/link-0', 'connects', '/group/a') in s.relations variants.append(semantic_digest(s)) assert variants[0] != variants[1] @pytest.mark.parametrize('environment_seed,structure_seed', [(0, 0), (1, 5), (2, 3), (3, 2), (4, 1), (5, 4), (6, 0), (7, 5)]) def test_independent_extension_environment_structure_pairs(environment_seed, structure_seed): from hearth_extensions.assessment import freeze_probe, connector_scene frozen = freeze_probe(environment_seed) digest = semantic_digest(frozen) scene = connector_scene(frozen, structure_seed) assert semantic_digest(frozen) == digest assert not validate(scene, True)
6400
python - <<'PY' from pathlib import Path import shutil,json old=Path('reports/extension-corpus/pre-interior-assessment') shutil.copytree('reports/exte
python - <<'PY' from pathlib import Path import shutil,json old=Path('reports/extension-corpus/pre-interior-assessment') shutil.copytree('reports/extension-corpus/final',old,dirs_exist_ok=True) shutil.copy2('reports/extension-corpus/full-regression.txt',old/'full-regression.txt') shutil.copy2('reports/extension-corpus/artifact-audit.json',old/'artifact-audit.json') manifest=json.loads(Path('samples/extensions/replay-manifest.json').read_text()) for r in manifest: p=Path(r['artifact']) q=p.parent/'pre-interior'/p.name q.parent.mkdir(exist_ok=True) shutil.copy2(p,q) shutil.copy2(Path(str(p)+'.structure.json'),Path(str(q)+'.structure.json')) r['artifact']=str(q) (old/'replay-manifest.json').write_text(json.dumps(manifest,indent=2)) print('Preserved previous 112 results, tests, audit and 13 artifact pairs.') PY
Preserved previous 112 results, tests, audit and 13 artifact pairs.
6507
yapf -i hearth_extensions/interiors.py hearth_extensions/halls.py hearth_extensions/boundaries.py hearth_extensions/assessment.py examples/extension_a
yapf -i hearth_extensions/interiors.py hearth_extensions/halls.py hearth_extensions/boundaries.py hearth_extensions/assessment.py examples/extension_assess.py && python -m pytest -q test/test_extension_geometry.py -k 'polygon or substitutes' > reports/extension-corpus/interior-first-tests.txt 2>&1
6600
cat reports/extension-corpus/interior-first-tests.txt
cat reports/extension-corpus/interior-first-tests.txt
..... [100%] 5 passed, 14 deselected in 6.70s
6713
yapf -i test/test_extension_interiors.py && python -m pytest -q test/test_extension_interiors.py > reports/extension-corpus/interior-tests.txt 2>&1
yapf -i test/test_extension_interiors.py && python -m pytest -q test/test_extension_interiors.py > reports/extension-corpus/interior-tests.txt 2>&1
6800
rg -n 'def clearance' hearth/kernel/view.py; cat reports/extension-corpus/interior-tests.txt; python - <<'PY' import json from pathlib import Path row
rg -n 'def clearance' hearth/kernel/view.py; cat reports/extension-corpus/interior-tests.txt; python - <<'PY' import json from pathlib import Path rows=json.loads(Path('reports/extension-corpus/final/results.json').read_text()) for r in rows: if r['status']!='validated': print(r['label'],r['diagnostic']) print('metrics') for group in ('connector','boundary','hall','campus','perimeter','stress'): rr=[r for r in rows if r['label'].startswith(group+'-') and r['status']=='validated'] print(group, [(k,min(r[k] for r in rr),max(r[k] for r in rr)) for k in ('sitework_occupied_cells','excavated_solid_cells')]) PY
achable_and_preserve_inventory[kitchen] FAILED test/test_extension_interiors.py::test_functional_bays_are_reachable_and_preserve_inventory[bedroom] FAILED test/test_extension_interiors.py::test_functional_bays_are_reachable_and_preserve_inventory[living] FAILED test/test_extension_interiors.py::test_functional_bays_are_reachable_and_preserve_inventory[storage] 6 failed, 3 passed in 3.79s stress-00 {'rule': 'support-height', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Bounded support depth exceeded'} stress-01 {'rule': 'site-relief', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Measured 7, permitted 5'} stress-04 {'rule': 'support-height', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Bounded support depth exceeded'} stress-07 {'rule': 'site-relief', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Measured 6, permitted 5'} stress-09 {'rule': 'support-height', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Bounded support depth exceeded'} stress-10 {'rule': 'support-height', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Bounded support depth exceeded'} stress-18 {'rule': 'site-relief', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Measured 6, permitted 5'} stress-19 {'rule': 'support-height', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Bounded support depth exceeded'} stress-22 {'rule': 'support-height', 'component': '/a', 'position': [0, 0, 0], 'conditions': 'Bounded support depth exceeded'} metrics connector [('sitework_occupied_cells', 294, 445), ('excavated_solid_cells', 0, 0)] boundary [('sitework_occupied_cells', 168, 224), ('excavated_solid_cells', 0, 0)] hall [('sitework_occupied_cells', 38, 71), ('excavated_solid_cells', 0, 0)] campus [('sitework_occupied_cells', 1374, 1593), ('excavated_solid_cells', 0, 0)] perimeter [('sitework_occupied_cells', 1539, 1597), ('excavated_solid_cells', 0, 0)] stress [('sitework_occupied_cells', 402, 599), ('excavated_solid_cells', 0, 0)]
6900
rg -n '^ def ' hearth/kernel/view.py
rg -n '^ def ' hearth/kernel/view.py
24: def __init__(self): 29: def point(self, p): 38: def region(self, box): 43: def bounds(self): 49: def __init__(self, scene, trace=None): 54: def version(self): 58: def domain(self): 62: def style(self): 65: def preference(self, name, point): 71: def state(self, p): 80: def owner(self, p): 86: def supports(self, p): 89: def clear(self, box): 92: def elevation(self, x, z, maximum=None): 100: def water(self, x, z): 108: def sample(self, x, z): 118: def port(self, host, key): 127: def cost(self, path, tag=None): 133: def offers(self, host, kind=None): 136: def capability(self, host): 139: def resolved_port(self, host, key): 151: def contract(self, path): 156: def protected(self, box): 161: def obstacle_distance(self, p, radius=8):
7009
yapf -i test/test_extension_interiors.py hearth_extensions/__init__.py && python -m pytest -q test/test_extension_interiors.py > reports/extension-cor
yapf -i test/test_extension_interiors.py hearth_extensions/__init__.py && python -m pytest -q test/test_extension_interiors.py > reports/extension-corpus/interior-tests-final.txt 2>&1
7100
cat reports/extension-corpus/interior-tests-final.txt
cat reports/extension-corpus/interior-tests-final.txt
......... [100%] 9 passed in 9.03s
720105
yapf -i hearth_extensions/assessment.py && python -m examples.extension_assess --seed 0 --output reports/extension-corpus/final --artifacts > reports/
yapf -i hearth_extensions/assessment.py && python -m examples.extension_assess --seed 0 --output reports/extension-corpus/final --artifacts > reports/extension-corpus/final-assessment.log 2>&1
7300
tail -8 reports/extension-corpus/full-regression.txt; tail -10 reports/extension-corpus/final-assessment.log
tail -8 reports/extension-corpus/full-regression.txt; tail -10 reports/extension-corpus/final-assessment.log
........................................................................ [ 40%] ........................................................................ [ 80%] ...................... 62, 259 ], "contact_replacement_range": [ 0, 254 ], "seconds": 5.065 } }
740128
python -m pytest -q test > reports/extension-corpus/full-regression.txt 2>&1
python -m pytest -q test > reports/extension-corpus/full-regression.txt 2>&1
7500
python - <<'PY' from pathlib import Path import shutil root=Path('previews/extensions') for name in ('campus-0','perimeter-3','hall-4'): dest=root/'p
python - <<'PY' from pathlib import Path import shutil root=Path('previews/extensions') for name in ('campus-0','perimeter-3','hall-4'): dest=root/'pre-interior'/name dest.parent.mkdir(exist_ok=True) shutil.move(str(root/name),str(dest)) shutil.copy2('reports/extension-corpus/artifact-audit.json','reports/extension-corpus/original-cli-and-pre-interior-audit.json') PY
76019
python -m examples.extension_views --seed 0 --input samples/extensions/campus-0.litematic --output previews/extensions/campus-0 --sections > reports/e
python -m examples.extension_views --seed 0 --input samples/extensions/campus-0.litematic --output previews/extensions/campus-0 --sections > reports/extension-corpus/render-campus-0.txt 2>&1
77021
python -m examples.extension_views --seed 3 --input samples/extensions/perimeter-3.litematic --output previews/extensions/perimeter-3 --sections > rep
python -m examples.extension_views --seed 3 --input samples/extensions/perimeter-3.litematic --output previews/extensions/perimeter-3 --sections > reports/extension-corpus/render-perimeter-3.txt 2>&1
78057
python -m examples.extension_audit --seed 0 --output reports/extension-corpus/artifact-audit.json > reports/extension-corpus/artifact-audit-final.log
python -m examples.extension_audit --seed 0 --output reports/extension-corpus/artifact-audit.json > reports/extension-corpus/artifact-audit-final.log 2>&1 && python -m examples.extension_replay --seed 3 --environment-seed 7 --output reports/extension-corpus/replay.json > reports/extension-corpus/replay.log 2>&1 && python -m examples.extension_inspection --seed 0 --input samples/extensions/campus-0.litematic --output samples/extensions/inspection.litematic > reports/extension-corpus/inspection.json
7900
cat reports/extension-corpus/full-regression.txt reports/extension-corpus/final/summary.json; python - <<'PY' import json from pathlib import Path row
cat reports/extension-corpus/full-regression.txt reports/extension-corpus/final/summary.json; python - <<'PY' import json from pathlib import Path rows=json.loads(Path('reports/extension-corpus/final/results.json').read_text()) print('omitted',sum(r.get('omitted_optional_furnishing_bays',0) for r in rows)) for group in ('hall','campus','perimeter'): subset=[r for r in rows if r['label'].startswith(group+'-') and r['status']=='validated'] print(group,'bays range',min(r['furnishing_bays'] for r in subset),max(r['furnishing_bays'] for r in subset)) print('audit',Path('reports/extension-corpus/artifact-audit-final.log').read_text()[-1600:]) PY
"contact_replacement_range": [ 0, 100 ], "seconds": 13.342 }, "boundary": { "inputs": 16, "outcomes": { "validated": 16 }, "candidate_attempts": 16, "accepted_candidates": 16, "retries": 0, "principal_signatures": 4, "contact_signatures": 16, "contact_cells_range": [ 0, 0 ], "contact_replacement_range": [ 0, 0 ], "seconds": 2.763 }, "hall": { "inputs": 12, "outcomes": { "validated": 12 }, "candidate_attempts": 12, "accepted_candidates": 12, "retries": 0, "principal_signatures": 12, "contact_signatures": 12, "contact_cells_range": [ 38, 71 ], "contact_replacement_range": [ 6, 9 ], "seconds": 8.403 }, "campus": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 132, 206 ], "contact_replacement_range": [ 232, 318 ], "seconds": 25.967 }, "perimeter": { "inputs": 6, "outcomes": { "validated": 6 }, "candidate_attempts": 6, "accepted_candidates": 6, "retries": 0, "principal_signatures": 6, "contact_signatures": 6, "contact_cells_range": [ 82, 129 ], "contact_replacement_range": [ 256, 451 ], "seconds": 24.688 }, "stress": { "inputs": 24, "outcomes": { "incompatible": 9, "validated": 15 }, "candidate_attempts": 24, "accepted_candidates": 15, "retries": 0, "principal_signatures": 6, "contact_signatures": 15, "contact_cells_range": [ 62, 259 ], "contact_replacement_range": [ 0, 254 ], "seconds": 5.065 } }omitted 0 hall bays range 2 8 campus bays range 8 12 perimeter bays range 9 11 audit
8007
python -m examples.extension_views --seed 4 --input samples/extensions/hall-4.litematic --output previews/extensions/hall-4 --sections > reports/exten
python -m examples.extension_views --seed 4 --input samples/extensions/hall-4.litematic --output previews/extensions/hall-4 --sections > reports/extension-corpus/render-hall-4.txt 2>&1
8100
cat /opt/tools/cutaway.py | head -100; sed -n '1,75p' examples/preview.py; python - <<'PY' import json from pathlib import Path for p in ['reports/ext
cat /opt/tools/cutaway.py | head -100; sed -n '1,75p' examples/preview.py; python - <<'PY' import json from pathlib import Path for p in ['reports/extension-corpus/artifact-audit.json','reports/extension-corpus/replay.json']: data=json.loads(Path(p).read_text()) print(p,data.get('verified'),len(data.get('artifacts',[])),[(r['result']['nodes'],r['result']['digest']) for r in data.get('runs',[])]) PY
or'] + building.frame.origin[1] offset = json.loads(companion_path(source).read_text())['offset'] cuts = [('floor-cut', 'y', floor + 4 - offset[1], 210, 64)] stair = next((n for n in scene.nodes.values() if n.type == 'circulation.stair'), None) if stair is not None: occupied = scene.cells(stair.path) # Cut beside the actual flight, including flights in a remote wing. axis = min((0, 2), key=lambda i: max(p[i] for p in occupied) - min(p[i] for p in occupied)) limit = max(p[axis] for p in occupied) + 1 - offset[axis] cuts.append(('stair-cut', 'xz'[axis // 2], limit, 110 if axis == 0 else 20, 26)) for label, axis, limit, azimuth, elevation in cuts: cut = output / (label + '.litematic') subprocess.run([sys.executable, str(CUTAWAY), '--input', str(source), '--output', str(cut), '--axis', axis, '--max', str(limit), '--name', label], check=True) target = output / (label + '.png') render(cut, target, azimuth, elevation, size, 3.2) records.append({'source': str(source), 'seed': seed, 'label': label, 'axis': axis, 'export_local_cut': limit, 'image': str(target), 'geometry_preview_only': True}) (output / 'views.json').write_text(json.dumps(records, indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path) p.add_argument('--output', type=Path, default=Path('previews/default')) p.add_argument('--size', type=int, default=1200) p.add_argument('--cutaways', action='store_true') a = p.parse_args() preview(a.seed, a.input, a.output, a.size, a.cutaways) reports/extension-corpus/artifact-audit.json True 13 [] reports/extension-corpus/replay.json True 0 [(395, 'd1fcbf2f4a2d54192a35864cdb4d03d822d9e4e7cb1dbf44edf2d769431e699a'), (395, 'd1fcbf2f4a2d54192a35864cdb4d03d822d9e4e7cb1dbf44edf2d769431e699a')]
8208
yapf -i examples/extension_views.py && python -m examples.extension_views --seed 4 --input samples/extensions/hall-4.litematic --output previews/exten
yapf -i examples/extension_views.py && python -m examples.extension_views --seed 4 --input samples/extensions/hall-4.litematic --output previews/extensions/hall-detail --sections --focus /hall > reports/extension-corpus/render-hall-detail.txt 2>&1
8300
python - <<'PY' from pathlib import Path import json s=json.loads(Path('reports/extension-corpus/final/results.json').read_text()) for group in ('conn
python - <<'PY' from pathlib import Path import json s=json.loads(Path('reports/extension-corpus/final/results.json').read_text()) for group in ('connector','boundary','hall','campus','perimeter','stress'): rows=[r for r in s if r['label'].startswith(group+'-') and r['status']=='validated'] print(group,'sitework',min(r['sitework_occupied_cells'] for r in rows),max(r['sitework_occupied_cells'] for r in rows),'seconds',sum(r['seconds'] for r in rows)) a=json.loads(Path('reports/extension-corpus/artifact-audit.json').read_text()) print('audit',len(a['artifacts']),sum(r['component_queries'] for r in a['artifacts']),sum(r['inventories'] for r in a['artifacts'])) print('counts',[ (r['label'],r['nodes'],r['blocks'],r['inventories']) for r in a['artifacts']]) PY
connector sitework 294 445 seconds 13.3416 boundary sitework 168 224 seconds 2.7629 hall sitework 38 71 seconds 8.403 campus sitework 1374 1593 seconds 25.9673 perimeter sitework 1539 1597 seconds 24.6875 stress sitework 402 599 seconds 4.7278 audit 13 1745 51 counts [('connector-0-0', 11, 19794, 0), ('connector-1-2', 11, 21330, 0), ('connector-4-3', 11, 18150, 0), ('connector-7-5', 11, 23835, 0), ('boundary-0-1', 12, 19631, 0), ('boundary-3-3', 12, 21656, 0), ('hall-0', 25, 26881, 2), ('hall-4', 31, 27184, 4), ('hall-7', 30, 27033, 3), ('campus-0', 446, 119395, 10), ('campus-3', 481, 140804, 12), ('perimeter-0', 381, 118811, 10), ('perimeter-3', 401, 139429, 10)]
8400
rg -n 'FAILED|FAILED:|Error|ContractError|write-authority|effect-envelope|child-envelope|boundary-domain|reachability|Traceback' reports/extension-cor
rg -n 'FAILED|FAILED:|Error|ContractError|write-authority|effect-envelope|child-envelope|boundary-domain|reachability|Traceback' reports/extension-corpus/*tests*.txt reports/extension-corpus/*probes*.txt reports/extensions-baseline/failing*.txt
undary_interfaces_and_external_attachment reports/extension-corpus/geometry-probes-2.txt:27:> raise ValidationError(errors) reports/extension-corpus/geometry-probes-2.txt:28:E hearth.kernel.errors.ValidationError: clearance: /hall/approach-north at (7, 7, -1): Protected player headroom is obstructed reports/extension-corpus/geometry-probes-2.txt:33:hearth/kernel/scene.py:391: ValidationError reports/extension-corpus/geometry-probes-2.txt:58:> raise ValidationError(errors) reports/extension-corpus/geometry-probes-2.txt:59:E hearth.kernel.errors.ValidationError: clearance: /hall/approach-north at (9, 7, -1): Protected player headroom is obstructed reports/extension-corpus/geometry-probes-2.txt:64:hearth/kernel/scene.py:391: ValidationError reports/extension-corpus/geometry-probes-2.txt:89:> raise ValidationError(errors) reports/extension-corpus/geometry-probes-2.txt:90:E hearth.kernel.errors.ValidationError: clearance: /hall/approach-north at (13, 7, -1): Protected player headroom is obstructed reports/extension-corpus/geometry-probes-2.txt:93:hearth/kernel/scene.py:391: ValidationError reports/extension-corpus/geometry-probes-2.txt:95:FAILED test/test_extension_geometry.py::test_polygon_hall_multiple_usable_ports[13-17-0-False] reports/extension-corpus/geometry-probes-2.txt:96:FAILED test/test_extension_geometry.py::test_polygon_hall_multiple_usable_ports[17-21-3-True] reports/extension-corpus/geometry-probes-2.txt:97:FAILED test/test_extension_geometry.py::test_polygon_hall_multiple_usable_ports[25-13-4-False] reports/extensions-baseline/failing-replay-probe.txt:11:E TypeError: Scene.regenerate() got an unexpected keyword argument 'replacements' reports/extensions-baseline/failing-replay-probe.txt:13:test/test_extension_protocol.py:59: TypeError reports/extensions-baseline/failing-replay-probe.txt:15:FAILED test/test_extension_protocol.py::test_atomic_multi_branch_replay_accepts_explicit_replacements
8500
python - <<'PY' from hearth import Scene, Box, Frame from hearth.environment import Terrain, gradient, radial from hearth_extensions import Polygon, P
python - <<'PY' from hearth import Scene, Box, Frame from hearth.environment import Terrain, gradient, radial from hearth_extensions import Polygon, Pavilion, Endpoint, Link from hearth.persistence import semantic_digest from pathlib import Path import json # Execute the new public example literally without transport. domain = Box((-12,-4,-12),(60,65,65)) environment = Scene(7,domain=domain) field = gradient(.012,-.008,3)+radial(19,22,14,-2) environment.place('land',Terrain(domain,field,water_level=3)) environment.finalize() scene = environment.fork(seed=23) shape = Polygon.chamfered(13,13,2) scene.place('reading',Pavilion(shape,'/land','library')) scene.place('workshop',Pavilion(shape,'/land','workshop'),frame=Frame((25,0,29))) a,b=Endpoint('/reading','south'),Endpoint('/workshop','north') scene.place('gallery',Link(a,b,'/land',covered=True),bindings=(a.binding(),b.binding())) scene.finalize() Path('reports/extension-corpus/documented-example.json').write_text(json.dumps({'seed':23,'environment_seed':7,'validated':True,'blocks':len(scene.blocks),'nodes':len(scene.nodes),'digest':semantic_digest(scene)},indent=2)) print('Documented composition validated',len(scene.blocks),'blocks') PY
Documented composition validated 47619 blocks
8600
python - <<'PY' from pathlib import Path import hashlib,json,re baseline=json.loads(Path('reports/extensions-baseline/module-hashes.json').read_text()
python - <<'PY' from pathlib import Path import hashlib,json,re baseline=json.loads(Path('reports/extensions-baseline/module-hashes.json').read_text())['sha256'] current={p:hashlib.sha256(Path(p).read_bytes()).hexdigest() for p in baseline} changed={p:{'before':baseline[p],'after':current[p]} for p in baseline if baseline[p]!=current[p]} allowed={'ARCHITECTURE.md','GENERATOR.md','hearth/__init__.py','hearth/kernel/scene.py','pyproject.toml'} assert set(changed)==allowed,changed newpaths=sorted([*Path('hearth_extensions').glob('*.py'),*Path('examples').glob('extension_*.py'),*Path('test').glob('test_extension_*.py')]) new={str(p):hashlib.sha256(p.read_bytes()).hexdigest() for p in newpaths} report={'library_version':'1.2.0','baseline_files':len(baseline),'unchanged_files':len(baseline)-len(changed),'changed':changed,'current_original_sha256':current,'new_source_sha256':new,'original_tests_unchanged':all(current[p]==baseline[p] for p in baseline if p.startswith('test/')),'original_default_cli_unchanged':current['generate.py']==baseline['generate.py'],'kernel_modules_changed':['hearth/kernel/scene.py'],'companion_format_changed':False} Path('reports/extension-corpus/api-final.json').write_text(json.dumps(report,indent=2)) print('Baseline audit:',len(baseline),'files;',len(changed),'expected changes;',len(new),'new source files') for p in changed: print(p) # Check local documentation links in the updated docs only. missing=[] for p in [Path('ARCHITECTURE.md'),Path('GENERATOR.md'),Path('hearth_extensions/README.md'),Path('reports/extension-corpus/ASSESSMENT.md'),Path('samples/extensions/README.md'),Path('previews/extensions/README.md')]: for ref in re.findall(r'\]\(([^)]+)\)',p.read_text()): if '://' in ref or ref.startswith('#'): continue target=ref.split('#')[0] if not (p.parent/target).exists(): missing.append([str(p),target]) print('Missing local links:',missing) assert not missing families=('campus-0','perimeter-3','wet-connector','curve-boundary','hall-4','hall-detail') counts={f:len(list((Path('previews/extensions')/f).glob('*.png'))) for f in families} print('Final render counts:',counts,'total',sum(counts.values())) PY
Baseline audit: 45 files; 5 expected changes; 21 new source files ARCHITECTURE.md GENERATOR.md hearth/__init__.py hearth/kernel/scene.py pyproject.toml Missing local links: [] Final render counts: {'campus-0': 5, 'perimeter-3': 5, 'wet-connector': 5, 'curve-boundary': 3, 'hall-4': 4, 'hall-detail': 4} total 26
8700
node -e "try { console.log(require.resolve('pyodide')) } catch (error) { console.log('Pyodide is not installed in the local Node module search path')
node -e "try { console.log(require.resolve('pyodide')) } catch (error) { console.log('Pyodide is not installed in the local Node module search path') }"; rg -n '_scene|ctx\._|\._state|scene\.blocks\[.*=' hearth_extensions examples/extension_*.py
,int(sys.argv[2])) examples/extension_replay.py:20:output=Path(sys.argv[3]);export_scene(scene,output) examples/extension_replay.py:21:restored=load_scene(output) examples/extension_generate.py:4:from hearth.persistence import export_scene, semantic_digest examples/extension_generate.py:5:from hearth_extensions.programs import extension_scene, branching_campus, perimeter_cluster examples/extension_generate.py:17: scene = extension_scene(PROGRAMS[args.program], args.seed, args.environment_seed) examples/extension_generate.py:18: export_scene(scene, args.output) hearth_extensions/assessment.py:12:from hearth.persistence import semantic_digest, export_scene hearth_extensions/assessment.py:37:def connector_scene(environment, structure_seed): hearth_extensions/assessment.py:48:def boundary_scene(environment, structure_seed): hearth_extensions/assessment.py:58:def hall_scene(seed, environment_seed=None): hearth_extensions/assessment.py:135: export_scene(scene, artifact) hearth_extensions/assessment.py:166: record(f'connector-{i}-{bs}', lambda e=frozen[es], b=bs: connector_scene(e, b), {'environment': inputs[i], 'structure_seed': bs}, (i, bs) in ((0, 0), (1, 2), (4, 3), (7, 5))) hearth_extensions/assessment.py:175: record(f'boundary-{es}-{bs}', lambda e=env, b=bs: boundary_scene(e, b), {'environment_seed': es + root_seed * 100, 'expression': field.expression(), 'structure_seed': bs}, (es, bs) in ((0, 1), (3, 3))) hearth_extensions/assessment.py:177: record(f'hall-{seed}', lambda b=seed: hall_scene(b, root_seed * 100 + b), {'structure_seed': seed, 'environment_seed': root_seed * 100 + seed}, seed in (0, 4, 7)) hearth_extensions/assessment.py:198: record(f'stress-{i:02}', lambda e=env, b=i % 6: connector_scene(e, b), {'environment_seed': es, 'structure_seed': i % 6, 'expression': field.expression(), 'water': water}) hearth_extensions/programs.py:52:def extension_scene(program=branching_campus, seed=0, environment_seed=0):
8800
python - <<'PY' from pathlib import Path import json,shutil,hashlib # Remove generated bytecode only from our runtime/test directories, never referenc
python - <<'PY' from pathlib import Path import json,shutil,hashlib # Remove generated bytecode only from our runtime/test directories, never references. for folder in ('hearth','hearth_extensions','extension_demo','examples','test'): for path in Path(folder).rglob('__pycache__'): shutil.rmtree(path) left=[str(p) for p in Path('test').iterdir() if p.is_dir() and p.name.startswith('tmp')] assert not left,left # Final source hashes should still describe the actual delivered implementation. a=json.loads(Path('reports/extension-corpus/api-final.json').read_text()) for p,digest in {**a['current_original_sha256'],**a['new_source_sha256']}.items(): assert hashlib.sha256(Path(p).read_bytes()).hexdigest()==digest,p r=json.loads(Path('reports/extension-corpus/artifact-audit.json').read_text()) assert r['verified'] and len(r['artifacts'])==13 stats=json.loads(Path('reports/extension-corpus/final/summary.json').read_text()) assert sum(v['inputs'] for v in stats.values())==112 assert sum(v['accepted_candidates'] for v in stats.values())==103 print('Final sources match audited hashes; test temporary directories cleaned; 13 pairs and 112 input records retained.') PY
Final sources match audited hashes; test temporary directories cleaned; 13 pairs and 112 input records retained.
8900
python - <<'PY' import json from pathlib import Path r=json.loads(Path('reports/extension-corpus/inspection.json').read_text()) print([(q['tag'],q['qu
python - <<'PY' import json from pathlib import Path r=json.loads(Path('reports/extension-corpus/inspection.json').read_text()) print([(q['tag'],q['query']['state'],q['query']['instance']) for q in r['queries']]) PY
[('deck', 'minecraft:spruce_planks', '/campus/circulation/link-0/deck'), ('window', 'minecraft:glass', '/campus/hall/facade/window-east-0'), ('fixture', 'minecraft:lantern[hanging=false,waterlogged=false]', '/campus/boundary-lights/segment-0-mount-16')]

原始 usage · 原始命令 · 镜像 sha256:b8a7738b1854ef200794229cb1209180c9fd6cc585745e68b23bb07e6faf49bc

05 · 结构先行:哪里保持不变,哪里真正扩展

flowchart TD
 A["Client: seeds, vertices, edges"] --> B["Pavilion / Link / BoundaryChain"]
 B --> C["capability - negotiate - realize"]
 C --> D["Frozen terrain and public ports"]
 C --> E["Kernel transactions and permissions"]
 E --> F["Blocks, contracts, provenance"]
 F --> G["Finalize, export and reload"]
拖动平移 · 滚轮缩放
新几何与客户端沿用原始组件协议;验证与追溯由公共内核承接。

新增 hearth_extensions 包负责几何、接口、场地、桥廊、围墙、厅堂、内饰和图组织;示例是薄客户端。原来的组件、环境、持久化、CLI 与原测试不需要重新实现。基线 45 个源码/文档文件中,40 个内容不变;5 个变更是两个文档、版本入口、项目元数据和 hearth/kernel/scene.py。

报告独立对比两个归档的结果
{ "baseline_files": 45, "changed": [ "ARCHITECTURE.md", "GENERATOR.md", "hearth/__init__.py", "hearth/kernel/scene.py", "pyproject.toml" ], "unchanged": 40, "original_tests_unchanged": true }
唯一内核模块的完整差异
--- attempt-0001/scene.py +++ attempt-0002/scene.py @@ -231,7 +231,7 @@ if port.frame.inverse(frame.origin)[0] % port.alignment or frame.turn % 4 != port.frame.turn % 4: raise ContractError('port-alignment', path, frame.origin, 'Outside facade bay grid') grant = next((g for g in host.contract.grants if g.key == port.grant), None) - if grant: + if grant and binding.verb != 'connect': if binding.verb not in grant.verbs or (grant.tags and not set(cap.tags).intersection(grant.tags)): raise ContractError('permission-kind', path, frame.origin, f'{cap.tags} cannot {binding.verb} {binding.host}') grants.append((Binding(effective_host, port.key, binding.verb, binding.region), grant)) @@ -496,16 +496,23 @@ if set(record.shared).intersection(paths): self.blocks[p] = replace(record, shared=tuple(s for s in record.shared if s not in paths)) - def regenerate(self, path, component=None, params=None, dependents=(), seed=None): + def regenerate(self, path, component=None, params=None, dependents=(), seed=None, replacements=None): trial = self._fork() targets = [path] + list(dependents) + updates = dict(replacements or {}) + if set(updates) - set(targets) or len(set(targets)) != len(targets): + raise ContractError('replay-targets', path, conditions='Replacements must name distinct explicit replay targets') + if component is not None: + if path in updates: + raise ContractError('replay-targets', path, conditions='Supply a root replacement only once') + updates[path] = component recipes = {} for p in targets: if p in trial._recipes: recipes[p] = trial._recipes[p] - elif p == path and component is not None: + elif p in updates: n = trial.nodes[p] - recipes[p] = (component, n.parameters.get('arguments', {}), n.frame, n.bindings, n.parent, n.scope, n.complete) + recipes[p] = (updates[p], n.parameters.get('arguments', {}), n.frame, n.bindings, n.parent, n.scope, n.complete) else: raise ContractError('replay-implementation', p, conditions='Reloaded branch needs an explicitly supplied component implementation') for p in targets: @@ -514,7 +521,7 @@ comp, oldparams, frame, bindings, parent, scope, complete = recipes[p] if p == path and seed is not None: scope = scope.child('override', seed) - trial._instantiate(p, component if p == path and component is not None else comp, params if p == path and params is not None else oldparams, frame, bindings, parent, scope, complete) + trial._instantiate(p, updates.get(p, comp), params if p == path and params is not None else oldparams, frame, bindings, parent, scope, complete) trial._check(True) self._commit(trial) self.events.append({'kind': 'regenerated', 'targets': targets})

这个结果比“无需改内核”更准确:确实有两个通用语义缺口,也留下了失败探针及新增负例。源码可比对,原功能的测试没有被删掉以换取通过。

06 · 两处内核修正与权限边界

只读连接不是宿主写权限

原来的端点可公开连接,但宿主可写 grant 只允许 resurfacing。将“连接成立”与“获准修改宿主”混在一起,导致合法连接被拒绝。新的 connect Binding 占用容量、记录关系和依赖,允许读取接口,但不授予宿主方块写权限。新增负例验证:拿到 connect 后仍不能越权写宿主。

耦合再生成的显式替换

连接依赖两端宿主。只替换连接程序会留下旧宿主,或者按旧 recipe 重放。现在可调用 regenerate(..., replacements={...}) 为后续目标显式提供替换配方,按依赖顺序重放。未知或重复目标拒绝;失败整体回滚。它没有绕过陈旧依赖检查,也不是任意修改内部状态。

公共组件 schema、结构 companion 格式保持兼容。扩展组件依然要声明占用、支撑、净空、连接、编辑预算和功能约束;遇到不合适地形可以给出可定位诊断,不能静默丢掉语义或隐藏失败后无限重抽。

07 · 一个玻璃方块,仍然能追到高阶组合

新组件继续由内核自动记录父子实例和操作来源。在线查看器实际调用 Scene.inspect,再通过 Scene.cells(..., descendants=True, shared=True) 查询某个祖先的成员,并非由网页猜测方块属于哪栋房子。选择桥、围墙灯或新厅堂玻璃,同样可以检查相关实例。

原实验的产物审计覆盖 13 对 schematic/companion:重新生成、保存、读回并检查节点、关系、依赖、操作、端口使用、被替换内容和逆向索引;共查询 1,745 个当前方块,并检查 51 个带 inventory 的方块。有限抽样查询与整份关系数据比较是不同的证据,不能表述成每个方块都手工审查。

默认旧聚落依然是 125,475 方块、782 节点,语义摘要 e81b08063278b231b60eaa16e4120973ed688bb3fd7e6a8da439daa4e7f5caf9。本轮也记录了环形群在不同 Python hash seed 下的一致摘要。浏览器新增验证见第 12 节。

08 · 曲线、几何和实地适配

抽象实际实现限制
Polyline / Bezier采样曲线、光栅化、局部方向与带状区域支持有界简单开放曲线,不能推断任意自交曲线可用
BoundaryChain长边界分段、接口透传,灯具通过挂点装配段长、坡度和支撑仍受合同约束
Link解析两个公开端点,生成带净空和护栏的桥/廊,按真实床面支撑路径长度、支撑高度、跨距、填充预算有界
Pavilion多边形平面、外壳、立面、屋顶和功能内饰分层组合宽深 13–25、层高 5–7 等有限实现域,入口仍正交
HallInterior / WorkBay保留入口与通路,分配可达功能位,保留工作设施和容器 NBT工作位布局仍紧凑且规则,尚非丰富室内设计系统

先冻结地形,再 fork 结构 seed。连接的支撑根据实际地形和水体调整,不能为了让特定房子成功而改写固定环境。48 个连接输入由 6 个固定结构意图 × 8 个独立环境构成;6 个主体签名不变,而 48 个接触签名不同,支持“保持主要意图,调整接触处”的解释。

开发中也暴露了通用几何问题:全局端点裁剪切坏弯折路线、宽桥口与窄接近区域冲突、长曲线超单段预算。最终分别按最近端点裁剪、保留端口口部宽度后向外展开、以及分段透传接口解决。

09 · 多样性有增长,但不要把样本数当类型数

本轮 112 个输入:103 通过,9 个不兼容。压力输入单列。
输入数与去除材料/接触高度后的主体签名数。跨环境重复不能当成新建筑类型。

支持范围内:连接 48/48,曲线边界 16/16,多边形单体 12/12,分支群 6/6,环形群 6/6。对应主体签名分别是 6、4、12、6、6。这个签名是结构测量方法,不是人类审美分类,也不代表真实可生成种类总数。报告不计算参数笛卡尔积,更不会用材质扰动抬高建筑种类。

不能声称压力成功率从 9/32 “提升到” 15/24。 两轮使用的压力输入分布不同。本轮 24 个压力样本里,9 个在平台场地协商阶段因 relief 或 support-height 被拒绝;既没有隐藏掉,也没有自动换 seed 直到成功。要比较稳健性进步,需要同一固定输入集上的成对复跑。

本轮 corpus 记录总计 112 次候选尝试,103 接受,0 retries。这个具体探针集没有大量搜索重试,不意味着库在所有复杂场景都能一次成功。主结构与接触签名、填充、替换、实际开挖和功能位计数全部保留在逐条记录里。

两个高阶图客户端的完整实现
# Lightweight graph clients using frozen generic fields and interchangeable public buildings. from hearth import Scene, Box, Frame from hearth.randomness import Scope from hearth.environment import Terrain, gradient, wave, radial from hearth.components.building import Blueprint, RoomSpec, Building from hearth.persistence import semantic_digest from .geometry import Polygon, Polyline from .halls import Pavilion from .graphs import Campus, Vertex, Edge DOMAIN = Box((-18, -4, -18), (95, 70, 95)) def frozen_site(environment_seed=0, domain=DOMAIN): rng = Scope(environment_seed).stream('environment') field = gradient(rng.choice((-.012, 0, .012)), rng.choice((-.009, .009)), 5) + wave(.5, .07, .09, rng.random() * 6) + radial(30, 31, 24, -3.8) scene = Scene(environment_seed, domain=domain) scene.place('land', Terrain(domain, field, water_level=3, edit_limit=2500)) return scene.finalize() def branching_campus(seed=0): rng = Scope(seed).stream('branching-graph') hub = Pavilion(Polygon.chamfered(17, 17, 4), '/land', 'library', ('north', 'east', 'south', 'west'), height=6, lantern=True) west = Pavilion(Polygon.chamfered(13, rng.choice((13, 17)), 2), '/land', 'workshop', ('north', 'south'), height=5) east = Pavilion(Polygon.chamfered(rng.choice((13, 17)), 13, 2), '/land', 'kitchen', ('west', 'south'), height=rng.choice((5, 6))) rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')] if rng.choice((False, True)): rooms.append(RoomSpec(0, 1, 0, 'storage')) lodge = Building(Blueprint(tuple(rooms), bay=9, porch=True), '/land') vertices = [Vertex('hall', hub, Frame((23, 0, 23))), Vertex('workshop', west, Frame((0, 0, 0))), Vertex('kitchen', east, Frame((51, 0, 0))), Vertex('lodge', lodge, Frame((48, 0, 51)))] edges = [Edge('hall', 'north', 'workshop', 'south', covered=True), Edge('hall', 'east', 'kitchen', 'west', rise=rng.choice((0, 1))), Edge('hall', 'south', 'lodge', 'street', covered=True)] if rng.choice((False, True)): vertices.append(Vertex('archive', Pavilion(Polygon.chamfered(13, 13, 2), '/land', 'library', ('east',)), Frame((0, 0, 51)))) edges.append(Edge('hall', 'west', 'archive', 'east', rise=1)) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(tuple(vertices), tuple(edges), '/land', DOMAIN, boundary) def perimeter_cluster(seed=0): rng = Scope(seed).stream('perimeter-graph') widths = (rng.choice((17, 21, 25)), rng.choice((13, 17)), rng.choice((13, 17))) market = Pavilion(Polygon.chamfered(widths[0], 13, 2), '/land', 'workshop', ('north', 'east', 'south'), height=5, roof_run=3) reading = Pavilion(Polygon.chamfered(widths[1], 17, 3), '/land', 'library', ('north', 'south'), height=6, lantern=rng.choice((True, False))) dining = Pavilion(Polygon.chamfered(widths[2], 13, 2), '/land', 'living', ('east', 'west'), height=5) vertices = (Vertex('market', market, Frame((0, 0, 0))), Vertex('reading', reading, Frame((50, 0, 10))), Vertex('dining', dining, Frame((20, 0, 57)))) edges = (Edge('market', 'east', 'reading', 'north', via=((40, -5),), covered=False, rise=1), Edge('reading', 'south', 'dining', 'east', covered=True), Edge('dining', 'west', 'market', 'south', via=((9, 42),), rise=rng.choice((0, 1)))) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(vertices, edges, '/land', DOMAIN, boundary) def extension_scene(program=branching_campus, seed=0, environment_seed=0): environment = frozen_site(environment_seed) original = semantic_digest(environment) scene = environment.fork(seed=seed) scene.place('campus', program(seed)) scene.finalize() if semantic_digest(environment) != original: raise AssertionError('Frozen input mutated') return scene

10 · 全部 112 个输入,保留成功与失败

直接来自本轮最终 reports/extension-corpus/final/results.json。展开单行可以看到固定环境表达式、seed、结构签名、接触编辑、候选数和诊断;可筛选 incompatible 或按列排序。

输入状态参数摘要方块组件候选通过候选秒主结构签名完整证据
connector-0-0validated{"environment": {"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.3780569371979411110.83061679aea0df093302
记录 / 诊断
{ "label": "connector-0-0", "inputs": { "environment": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "6e27d13a5925cf87e411c940c85265c4a1c6c5f608721dd3491ee7a7e7967cc4" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19794, "instances": 11, "digest": "cbf4e2d1e05d023ae4bd128e584e0d3336444a0b6dc73ddca10854ac588df2f7", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f8a42298a6d51c6679b0de0d3759161eaea1eda4d41a21cda08c2c2ed3074d54", "contact_cells": 19, "contact_replacements": 0, "sitework_occupied_cells": 355, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/connector-0-0.litematic", "seconds": 0.8306 }
connector-0-1validated{"environment": {"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.3780569371975711110.2239ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-0-1", "inputs": { "environment": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "6e27d13a5925cf87e411c940c85265c4a1c6c5f608721dd3491ee7a7e7967cc4" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19757, "instances": 11, "digest": "333376d063b9a4cb54d0dd977d822ebbc058d2333a7bd898bd2548766202fd2b", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "bbbf4b4c63239492425a9e73aafa35ec9eaf19a3f8e15d3b199ac3a81168ea92", "contact_cells": 28, "contact_replacements": 0, "sitework_occupied_cells": 319, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2239 }
connector-0-2validated{"environment": {"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.3780569372003811110.2622edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-0-2", "inputs": { "environment": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "6e27d13a5925cf87e411c940c85265c4a1c6c5f608721dd3491ee7a7e7967cc4" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20038, "instances": 11, "digest": "0f4c6a8d5c0a4ba949e8ed2e829a3fb757537ba2032cdf4e86d69dc7aece0a55", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "b25935b628c334de320b2c9a136a4427d3b646a6dcf21899115b8830be2a02c3", "contact_cells": 26, "contact_replacements": 0, "sitework_occupied_cells": 366, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2622 }
connector-0-3validated{"environment": {"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.3780569372002011110.2354bb67d480f17c284a
记录 / 诊断
{ "label": "connector-0-3", "inputs": { "environment": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "6e27d13a5925cf87e411c940c85265c4a1c6c5f608721dd3491ee7a7e7967cc4" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20020, "instances": 11, "digest": "0eb099c301aa1cfb7bb331b3f879f311ed425b4f7940e460edc993b0a7dc2e73", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "6ba3eb484acc32a92715bce8e4d1d7786c88413c21849f997848ba43fd050a39", "contact_cells": 23, "contact_replacements": 0, "sitework_occupied_cells": 359, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2354 }
connector-0-4validated{"environment": {"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.3780569371976011110.2226aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-0-4", "inputs": { "environment": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "6e27d13a5925cf87e411c940c85265c4a1c6c5f608721dd3491ee7a7e7967cc4" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19760, "instances": 11, "digest": "e81ca91746b42621780bce6938c58455ececf6efb9c503a493a81f60c7823d14", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "d8daedd96ac4cb289c9d295cc6b592cd311022e01d0a039d1741a45127c9982f", "contact_cells": 19, "contact_replacements": 0, "sitework_occupied_cells": 314, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2226 }
connector-0-5validated{"environment": {"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.3780569371992611110.2254bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-0-5", "inputs": { "environment": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "6e27d13a5925cf87e411c940c85265c4a1c6c5f608721dd3491ee7a7e7967cc4" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19926, "instances": 11, "digest": "dc24cb82428b56eed15cef10f2e3023234dead4d8b482cec33529625fec29cd5", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "6cbf27687eb07ffda674707312d45288d942c851e3f32db3fe162b5f07104ebf", "contact_cells": 24, "contact_replacements": 0, "sitework_occupied_cells": 311, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2254 }
connector-1-0validated{"environment": {"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014202108811110.23551679aea0df093302
记录 / 诊断
{ "label": "connector-1-0", "inputs": { "environment": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": null, "digest": "486b3a02bb384b49789f9471ccb78265a0528626e34b5d667057212675ac91ee" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21088, "instances": 11, "digest": "8484c65b43ac8091744c898b33775263e529427cc22f7cadeafd505ece1948bc", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "9f35fdbc5c3334c9510f6703cf4d2a32f6de2adf9ea03dfc51a05b658b86d0d2", "contact_cells": 4, "contact_replacements": 0, "sitework_occupied_cells": 340, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2355 }
connector-1-1validated{"environment": {"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014202104911110.2316ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-1-1", "inputs": { "environment": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": null, "digest": "486b3a02bb384b49789f9471ccb78265a0528626e34b5d667057212675ac91ee" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21049, "instances": 11, "digest": "b6a5f8891062f162cf711043b218ea1bb4189de409c59cdddcf6ffb9962d3135", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "fe8df2d23a27a0cdd6f2f3387cd62296bff4c99eb9619a5f058f5f5a7e8085b3", "contact_cells": 11, "contact_replacements": 0, "sitework_occupied_cells": 302, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2316 }
connector-1-2validated{"environment": {"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014202133011110.7189edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-1-2", "inputs": { "environment": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": null, "digest": "486b3a02bb384b49789f9471ccb78265a0528626e34b5d667057212675ac91ee" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21330, "instances": 11, "digest": "98e33b108d0a2ac348b494464cd80ddfeabfe90479e847458b6c1688c54a3a98", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "1af5ee703a9a8c4aac8bf0406f7485d21a381a45c9994c7423c53712aef60c51", "contact_cells": 9, "contact_replacements": 0, "sitework_occupied_cells": 349, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/connector-1-2.litematic", "seconds": 0.7189 }
connector-1-3validated{"environment": {"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014202131411110.2422bb67d480f17c284a
记录 / 诊断
{ "label": "connector-1-3", "inputs": { "environment": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": null, "digest": "486b3a02bb384b49789f9471ccb78265a0528626e34b5d667057212675ac91ee" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21314, "instances": 11, "digest": "c8e0bc9c802db7282798133634afbabf997c769620bf680397dfeddd484794f4", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "bb650a8621db038d4613a27f48ac87a91d362b30b9152933db5d72d859589e23", "contact_cells": 8, "contact_replacements": 0, "sitework_occupied_cells": 344, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2422 }
connector-1-4validated{"environment": {"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014202105311110.2264aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-1-4", "inputs": { "environment": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": null, "digest": "486b3a02bb384b49789f9471ccb78265a0528626e34b5d667057212675ac91ee" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21053, "instances": 11, "digest": "8e9b0ad70ba55a81e7b68ceace7ea83480ec5d5dd40d0c86747131ff42477221", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "ba68d12210cc0d1a130586f239e835b892c85b01914bf00b770fdee035a31bef", "contact_cells": 3, "contact_replacements": 0, "sitework_occupied_cells": 298, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2264 }
connector-1-5validated{"environment": {"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014202121811110.2344bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-1-5", "inputs": { "environment": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": null, "digest": "486b3a02bb384b49789f9471ccb78265a0528626e34b5d667057212675ac91ee" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21218, "instances": 11, "digest": "3400f127b12b67fd24297b9925b10d1485e3414cc328743bff0e1dba92929909", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "2bb131855e275db1898d9564e2b5efd70b5afd118ca5db371254af8ba7115273", "contact_cells": 7, "contact_replacements": 0, "sitework_occupied_cells": 294, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2344 }
connector-2-0validated{"environment": {"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.948774941964011110.22351679aea0df093302
记录 / 诊断
{ "label": "connector-2-0", "inputs": { "environment": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "4541f09377894707e3dde389a5e9ad60972273efc2ccf6017c9e31fc98559659" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19640, "instances": 11, "digest": "fd34f38f03d274c8e9ba055e308e8821312ac19c86ba54fbe16abff81d8bde1e", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f122ad4a67ff8c664e2a43e5471a96afd52074e1c4932bebf4e4c692d059d16f", "contact_cells": 37, "contact_replacements": 0, "sitework_occupied_cells": 373, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2235 }
connector-2-1validated{"environment": {"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.948774941960211110.2244ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-2-1", "inputs": { "environment": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "4541f09377894707e3dde389a5e9ad60972273efc2ccf6017c9e31fc98559659" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19602, "instances": 11, "digest": "7f202f7de0574a3e8972f9a4906689af079a03db96d132322ad69a858b872637", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "5a2188e7be78ec9619608b02300f72314a1d6df5b38041bb743d727e980bd083", "contact_cells": 45, "contact_replacements": 0, "sitework_occupied_cells": 336, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2244 }
connector-2-2validated{"environment": {"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.948774941988311110.2354edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-2-2", "inputs": { "environment": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "4541f09377894707e3dde389a5e9ad60972273efc2ccf6017c9e31fc98559659" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19883, "instances": 11, "digest": "3e6b9d09a5378831911a27a13e58090e35557804539807436b050080301752c3", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "bd6d57404a8e688e4c17c9edce0bdd9e9202aeabcc992bd15a45a13f4f4bcd31", "contact_cells": 43, "contact_replacements": 0, "sitework_occupied_cells": 383, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2354 }
connector-2-3validated{"environment": {"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.948774941986511110.2336bb67d480f17c284a
记录 / 诊断
{ "label": "connector-2-3", "inputs": { "environment": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "4541f09377894707e3dde389a5e9ad60972273efc2ccf6017c9e31fc98559659" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19865, "instances": 11, "digest": "6e350ad9c96bef0389c853642572febb293ca20755ee9f84468454dadbb47c6e", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "58fe5c2a1f891054fc51f68fe869888952fb2f0136aa4c8be43e9785f19bb953", "contact_cells": 40, "contact_replacements": 0, "sitework_occupied_cells": 376, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2336 }
connector-2-4validated{"environment": {"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.948774941960511110.2154aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-2-4", "inputs": { "environment": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "4541f09377894707e3dde389a5e9ad60972273efc2ccf6017c9e31fc98559659" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19605, "instances": 11, "digest": "cbc327351a6a61c6fed92cf7e2aa5a4aea2816b65bd3f329360d34f36c3e66b9", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "1fec3566901d77b7d4352edc5c219680ebc84be394a6e15d843fe88b442d228d", "contact_cells": 36, "contact_replacements": 0, "sitework_occupied_cells": 331, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2154 }
connector-2-5validated{"environment": {"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.948774941977111110.2249bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-2-5", "inputs": { "environment": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "4541f09377894707e3dde389a5e9ad60972273efc2ccf6017c9e31fc98559659" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19771, "instances": 11, "digest": "b6d21f11cf92d3c57bcbfb693bda382d65d8bdc90fe457a1437bcb9862e7bf3c", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "9f550a347c143d3f0da9b7cbdbd9de04cee56e849f8aace069bc043d478099fe", "contact_cells": 41, "contact_replacements": 0, "sitework_occupied_cells": 328, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2249 }
connector-3-0validated{"environment": {"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.538972407911110.23221679aea0df093302
记录 / 诊断
{ "label": "connector-3-0", "inputs": { "environment": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": 3, "digest": "f415ed4464e80df7fb7bfbff21ebb079c356e37444c364df2a34bb7074489e09" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 24079, "instances": 11, "digest": "e612d30848969cba1566132d6e6fa5c59c0f59d8e855fd6e2035de2dd5a8e4ce", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "773636c1fcccad3dba410a06fd5df035c1b3e30b82a71d82b4d1d7465d51087f", "contact_cells": 49, "contact_replacements": 49, "sitework_occupied_cells": 385, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2322 }
connector-3-1validated{"environment": {"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.538972404111110.2261ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-3-1", "inputs": { "environment": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": 3, "digest": "f415ed4464e80df7fb7bfbff21ebb079c356e37444c364df2a34bb7074489e09" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 24041, "instances": 11, "digest": "e2515d50da5bbbb26b09c053d1ac5647c65e6d784fb4568dee0f3d08044aea29", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "791200fe3ba203ece0dccd68df7bb67431271297fc93fcbf734cea2bb89ee552", "contact_cells": 56, "contact_replacements": 48, "sitework_occupied_cells": 347, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2261 }
connector-3-2validated{"environment": {"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.538972432111110.2378edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-3-2", "inputs": { "environment": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": 3, "digest": "f415ed4464e80df7fb7bfbff21ebb079c356e37444c364df2a34bb7074489e09" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 24321, "instances": 11, "digest": "53792adafcc913475d35264deaec2ae7ccf892b08751421cfde4c10edff5fbe7", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "55bf4c902ea9ff271c130a7953d6c926be6694ab9719dc95fb753c62e1fc04de", "contact_cells": 55, "contact_replacements": 50, "sitework_occupied_cells": 395, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2378 }
connector-3-3validated{"environment": {"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.538972430511110.2367bb67d480f17c284a
记录 / 诊断
{ "label": "connector-3-3", "inputs": { "environment": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": 3, "digest": "f415ed4464e80df7fb7bfbff21ebb079c356e37444c364df2a34bb7074489e09" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 24305, "instances": 11, "digest": "7618243f11c98100f58d08565bf1f979ed940f1f5eeff0fd98e6564229b49eec", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f49060eb4af80585c69f45dce30204f78d740a6add08058dad47173aa86a5095", "contact_cells": 52, "contact_replacements": 48, "sitework_occupied_cells": 388, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2367 }
connector-3-4validated{"environment": {"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.538972404511110.2254aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-3-4", "inputs": { "environment": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": 3, "digest": "f415ed4464e80df7fb7bfbff21ebb079c356e37444c364df2a34bb7074489e09" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 24045, "instances": 11, "digest": "304b3504b8ed2d821f20fc8c11eb87de7273f0b44dc76dd1ae377c439a83bede", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f6e9f32ecf293afdeb2e1471b6f1ec8c4df78a8b49dbe083481ee4714ed2f48a", "contact_cells": 48, "contact_replacements": 48, "sitework_occupied_cells": 343, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2254 }
connector-3-5validated{"environment": {"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.538972421011110.2288bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-3-5", "inputs": { "environment": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "water": 3, "digest": "f415ed4464e80df7fb7bfbff21ebb079c356e37444c364df2a34bb7074489e09" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 24210, "instances": 11, "digest": "0bbfb121afac684555a07e7ae4fed8e7485fbe5e96cd0610d927b3d35a071b2a", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "37f8f52db0dbe6bb81a99c0735508c96a753de421d34c530f77a97dc4d37ca6b", "contact_cells": 52, "contact_replacements": 48, "sitework_occupied_cells": 339, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2288 }
connector-4-0validated{"environment": {"environment_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [-0.025, 0, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 2.89964681792511110.22071679aea0df093302
记录 / 诊断
{ "label": "connector-4-0", "inputs": { "environment": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 2.8996468010194985 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": null, "digest": "53f76483fdaeaf1ab2687b4576c34175e1af4d317fa75a9a298fd000262823cf" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 17925, "instances": 11, "digest": "97fb9746dcd35d31295e798508e418bd8b259ef68665e5fe2e4d269ae44ccd24", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "a512021b3a222141f863ec8120b75fe83d6673c9ecc3d2d01aa22bf11cfd7977", "contact_cells": 25, "contact_replacements": 0, "sitework_occupied_cells": 361, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2207 }
connector-4-1validated{"environment": {"environment_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [-0.025, 0, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 2.89964681788611110.2157ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-4-1", "inputs": { "environment": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 2.8996468010194985 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": null, "digest": "53f76483fdaeaf1ab2687b4576c34175e1af4d317fa75a9a298fd000262823cf" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 17886, "instances": 11, "digest": "896b69fd63f4779dd946cd60c35a392b8efee0df25852bb34f5a425914ea5ed3", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "c9f78550a6041a8422aaf0a90ca37bddb8265c0af4c6822bde5b57e15ec4520b", "contact_cells": 32, "contact_replacements": 0, "sitework_occupied_cells": 323, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2157 }
connector-4-2validated{"environment": {"environment_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [-0.025, 0, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 2.89964681816611110.2266edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-4-2", "inputs": { "environment": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 2.8996468010194985 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": null, "digest": "53f76483fdaeaf1ab2687b4576c34175e1af4d317fa75a9a298fd000262823cf" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 18166, "instances": 11, "digest": "0af4d450ba9fa56735babe76d83e6167370dcd8e5e6808da0ed96824af7b376f", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "a2f557392a68ed8d383efa449ba80a1de0e2292115cc4d99da424acfd27c5738", "contact_cells": 29, "contact_replacements": 0, "sitework_occupied_cells": 369, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2266 }
connector-4-3validated{"environment": {"environment_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [-0.025, 0, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 2.89964681815011110.8202bb67d480f17c284a
记录 / 诊断
{ "label": "connector-4-3", "inputs": { "environment": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 2.8996468010194985 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": null, "digest": "53f76483fdaeaf1ab2687b4576c34175e1af4d317fa75a9a298fd000262823cf" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 18150, "instances": 11, "digest": "094123cd35dd67998b7bed9ee85ba0c78f76b165209e7d66456af0bffef9111a", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "b285da300b6e1a32573a5d493c3029a1469aacee6ab22cc2aee3bad2bfe8bdf8", "contact_cells": 28, "contact_replacements": 0, "sitework_occupied_cells": 364, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/connector-4-3.litematic", "seconds": 0.8202 }
connector-4-4validated{"environment": {"environment_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [-0.025, 0, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 2.89964681789111110.2141aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-4-4", "inputs": { "environment": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 2.8996468010194985 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": null, "digest": "53f76483fdaeaf1ab2687b4576c34175e1af4d317fa75a9a298fd000262823cf" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 17891, "instances": 11, "digest": "be3bb4314587225eda32a123796bf057f5e342482164e260409fe06325e10dc7", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "d748446323da5e260ec6acadf5b6c7b82ff64b88647163a5284b4ab4ef6d62c4", "contact_cells": 25, "contact_replacements": 0, "sitework_occupied_cells": 320, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2141 }
connector-4-5validated{"environment": {"environment_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [-0.025, 0, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 2.89964681805611110.2185bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-4-5", "inputs": { "environment": { "environment_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ -0.025, 0, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 2.8996468010194985 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": null, "digest": "53f76483fdaeaf1ab2687b4576c34175e1af4d317fa75a9a298fd000262823cf" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 18056, "instances": 11, "digest": "660d19ba7ebd00c5d258759c2ce259fee661267eb9c20367d493758d796ce837", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "72a8c141f6921f95c0df31214ad7b2cc537dc10b21688e4c4815b9438b7ea59a", "contact_cells": 29, "contact_replacements": 0, "sitework_occupied_cells": 316, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2185 }
connector-5-0validated{"environment": {"environment_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 2.52783459573262370411110.23831679aea0df093302
记录 / 诊断
{ "label": "connector-5-0", "inputs": { "environment": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 2.5278345957326787 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": 3, "digest": "1eb6ba099e8da7170e4b092f455c7b5db73e58d78e55465141623edcb554b290" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23704, "instances": 11, "digest": "766371d323d375133fecb48ff085c075640c87c8926c3f7cf2845137f4b363d5", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "63e13d780d5acb1f3d3cc1e32390f29d04daf4d629cb2496126ce29e36957e81", "contact_cells": 99, "contact_replacements": 99, "sitework_occupied_cells": 435, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2383 }
connector-5-1validated{"environment": {"environment_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 2.52783459573262366611110.2402ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-5-1", "inputs": { "environment": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 2.5278345957326787 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": 3, "digest": "1eb6ba099e8da7170e4b092f455c7b5db73e58d78e55465141623edcb554b290" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23666, "instances": 11, "digest": "66073cbe17c6d9d86efa6067728467db775b8064f9f02e559d9e0535cd843ba5", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f0059c8ca38abcf86945221aa6a9e5387f6df3818e8ea9218df22c70f7baeb14", "contact_cells": 108, "contact_replacements": 100, "sitework_occupied_cells": 399, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2402 }
connector-5-2validated{"environment": {"environment_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 2.52783459573262394611110.242edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-5-2", "inputs": { "environment": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 2.5278345957326787 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": 3, "digest": "1eb6ba099e8da7170e4b092f455c7b5db73e58d78e55465141623edcb554b290" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23946, "instances": 11, "digest": "055546354f6305c0d0f567584c80a8528b87768b1bf92eeaf154720abe333dc6", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "c229fb18fbd44666d068de2ece72f529a4838e09d15c740fde032ba417fec3a0", "contact_cells": 105, "contact_replacements": 100, "sitework_occupied_cells": 445, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.242 }
connector-5-3validated{"environment": {"environment_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 2.52783459573262393011110.2404bb67d480f17c284a
记录 / 诊断
{ "label": "connector-5-3", "inputs": { "environment": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 2.5278345957326787 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": 3, "digest": "1eb6ba099e8da7170e4b092f455c7b5db73e58d78e55465141623edcb554b290" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23930, "instances": 11, "digest": "6047050c06def853bc2e0a39e762be12ae8f218db4c104d5bd9521eb03b70450", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "eef0b5fc7564abeaf3956cb7a123ba190af74a45d4ab8d4266af1c612de74970", "contact_cells": 103, "contact_replacements": 99, "sitework_occupied_cells": 439, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2404 }
connector-5-4validated{"environment": {"environment_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 2.52783459573262367011110.2294aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-5-4", "inputs": { "environment": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 2.5278345957326787 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": 3, "digest": "1eb6ba099e8da7170e4b092f455c7b5db73e58d78e55465141623edcb554b290" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23670, "instances": 11, "digest": "1fab919b5fee9c0d1fe78e8ad5ad26b50c12fc7486107aeefa0f38e32035f2c1", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "56f85d8e24f372eb7209c1cb2c71208ff21bfc6d7e73eda60ea11a4363766427", "contact_cells": 99, "contact_replacements": 99, "sitework_occupied_cells": 394, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2294 }
connector-5-5validated{"environment": {"environment_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 2.52783459573262383511110.236bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-5-5", "inputs": { "environment": { "environment_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 2.5278345957326787 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, 0 ] } ] }, -1, 5 ] }, "water": 3, "digest": "1eb6ba099e8da7170e4b092f455c7b5db73e58d78e55465141623edcb554b290" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23835, "instances": 11, "digest": "9611bdabdabce6dd6638cdce0e15be40cf4d7a9570eba9d99e32547ca8f7be32", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "cde78a002f0c66bcbcd2419e29fe25ee70cf79512ff6383355eed107e11f4698", "contact_cells": 103, "contact_replacements": 99, "sitework_occupied_cells": 390, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.236 }
connector-6-0validated{"environment": {"environment_seed": 6, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.104312201984011110.23411679aea0df093302
记录 / 诊断
{ "label": "connector-6-0", "inputs": { "environment": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.104312202723488 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "754e80506928d88957e5eba2f413a511876fc5cd3834bc1081048c470b27ce3b" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19840, "instances": 11, "digest": "d068ec61b1e92b8e77e76946dc720139ca478bce0b5afa2afabb8e98774b0901", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "daafefc8a45805b016cf4e52b66ceb41674b7853575c1b97fec2755edd1a77c3", "contact_cells": 15, "contact_replacements": 0, "sitework_occupied_cells": 351, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2341 }
connector-6-1validated{"environment": {"environment_seed": 6, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.104312201980111110.2291ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-6-1", "inputs": { "environment": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.104312202723488 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "754e80506928d88957e5eba2f413a511876fc5cd3834bc1081048c470b27ce3b" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19801, "instances": 11, "digest": "03afe5e70d672f6c80a0da72bb4d61b1ebd5e4603525ae23b1cbffbfd8bd7a90", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "32a258ec4b97c731dd1bac0ad2688df3fd404c21b15ee54e8ff2cb6950203ea4", "contact_cells": 22, "contact_replacements": 0, "sitework_occupied_cells": 313, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2291 }
connector-6-2validated{"environment": {"environment_seed": 6, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.104312202008311110.24edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-6-2", "inputs": { "environment": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.104312202723488 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "754e80506928d88957e5eba2f413a511876fc5cd3834bc1081048c470b27ce3b" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20083, "instances": 11, "digest": "9d0431627bacb14bf59a353eab2b8e617a8531e5a40a906c3c39a4f774625c1b", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "6dbf08308856c10c10708e41369cf6c43c21dbf255d42750f864d915f2f0a445", "contact_cells": 21, "contact_replacements": 0, "sitework_occupied_cells": 361, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.24 }
connector-6-3validated{"environment": {"environment_seed": 6, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.104312202006611110.2447bb67d480f17c284a
记录 / 诊断
{ "label": "connector-6-3", "inputs": { "environment": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.104312202723488 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "754e80506928d88957e5eba2f413a511876fc5cd3834bc1081048c470b27ce3b" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20066, "instances": 11, "digest": "0a692c5de6e430efce7bbe50046dcc8263f60be44b619547c7dfd77cff060943", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "e7465d86d04138813aa5819dfbbf9f195dde9b0a197694d18835f223a9ea22b0", "contact_cells": 19, "contact_replacements": 0, "sitework_occupied_cells": 355, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2447 }
connector-6-4validated{"environment": {"environment_seed": 6, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.104312201980411110.2249aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-6-4", "inputs": { "environment": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.104312202723488 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "754e80506928d88957e5eba2f413a511876fc5cd3834bc1081048c470b27ce3b" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19804, "instances": 11, "digest": "3aac5820caad9758f336ddaab7f02444ebc210ee1e75249dd08b641e3c1d0647", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "58953b1d8aba006e0f4c64c3f0e6651ade79fd81e16345fba70f30d304bb2187", "contact_cells": 13, "contact_replacements": 0, "sitework_occupied_cells": 308, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2249 }
connector-6-5validated{"environment": {"environment_seed": 6, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.104312201997011110.2297bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-6-5", "inputs": { "environment": { "environment_seed": 6, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.104312202723488 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": null, "digest": "754e80506928d88957e5eba2f413a511876fc5cd3834bc1081048c470b27ce3b" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19970, "instances": 11, "digest": "12f1334f73eff1ad35044b12974079c616152f322d590d897950527d0d3e6524", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "1d77f3f98b8b479819d0975eaaae9f81ac733de8921c78565719f0cf868cac32", "contact_cells": 18, "contact_replacements": 0, "sitework_occupied_cells": 305, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2297 }
connector-7-0validated{"environment": {"environment_seed": 7, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 5.0240547632370411110.2331679aea0df093302
记录 / 诊断
{ "label": "connector-7-0", "inputs": { "environment": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 5.024054763940207 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": 3, "digest": "d0ae9ea7f5840076684b4d4574633b7e26ca677cba62e7842f064ac32d959f05" }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23704, "instances": 11, "digest": "5c6423866279fe1181cf5ca67ab7ae136c5bda9b535789e2b30ac69b681a4be5", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "18563cd78508722063a6f81352623ab44ad713307bf084923b1b03866b738c7c", "contact_cells": 78, "contact_replacements": 78, "sitework_occupied_cells": 414, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.233 }
connector-7-1validated{"environment": {"environment_seed": 7, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 5.0240547632366611110.2345ec5f44d0f6975515
记录 / 诊断
{ "label": "connector-7-1", "inputs": { "environment": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 5.024054763940207 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": 3, "digest": "d0ae9ea7f5840076684b4d4574633b7e26ca677cba62e7842f064ac32d959f05" }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23666, "instances": 11, "digest": "29f4eea5414f4afe490631709d2706e5e54a0d4706503307a19831799ae91899", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "c57ec1813919fd26b33f24b6e6c13bd4bed42f9e643c6ef2d273ce56a60ef34f", "contact_cells": 85, "contact_replacements": 77, "sitework_occupied_cells": 376, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2345 }
connector-7-2validated{"environment": {"environment_seed": 7, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 5.0240547632394611110.2642edbd467cdaa9e5c9
记录 / 诊断
{ "label": "connector-7-2", "inputs": { "environment": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 5.024054763940207 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": 3, "digest": "d0ae9ea7f5840076684b4d4574633b7e26ca677cba62e7842f064ac32d959f05" }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23946, "instances": 11, "digest": "2ae5feaa5cf784519d207f9c555660c94d0977783f092167001015b33fa91130", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "5c21b654ee0d9e0a99ac95d944c0af225512007d3653e83e41945351264d845f", "contact_cells": 84, "contact_replacements": 79, "sitework_occupied_cells": 424, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2642 }
connector-7-3validated{"environment": {"environment_seed": 7, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 5.0240547632393011110.2386bb67d480f17c284a
记录 / 诊断
{ "label": "connector-7-3", "inputs": { "environment": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 5.024054763940207 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": 3, "digest": "d0ae9ea7f5840076684b4d4574633b7e26ca677cba62e7842f064ac32d959f05" }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23930, "instances": 11, "digest": "00d57760a56b0853c5bcfd498a37cb8dcdd9e2549c7be1ef562e14822f681781", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "2ac2a114bf62da49c53d196acfdd6d5eec1b0d56fdfebec0f6371498d5d1b2a4", "contact_cells": 82, "contact_replacements": 78, "sitework_occupied_cells": 418, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2386 }
connector-7-4validated{"environment": {"environment_seed": 7, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 5.0240547632367011110.2279aa3186672b8bbfb0
记录 / 诊断
{ "label": "connector-7-4", "inputs": { "environment": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 5.024054763940207 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": 3, "digest": "d0ae9ea7f5840076684b4d4574633b7e26ca677cba62e7842f064ac32d959f05" }, "structure_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23670, "instances": 11, "digest": "dd1a085df0cd6faae4c7a418df1ec047810917c0de1618dbe788827c2cca1125", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "24449ce9963642273c66f5351c53cfbeaec08bba37dddcaf9c147e93412a8085", "contact_cells": 77, "contact_replacements": 77, "sitework_occupied_cells": 372, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2279 }
connector-7-5validated{"environment": {"environment_seed": 7, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 5.0240547632383511110.7655bd9a1df1c01caa35
记录 / 诊断
{ "label": "connector-7-5", "inputs": { "environment": { "environment_seed": 7, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 5.024054763940207 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "water": 3, "digest": "d0ae9ea7f5840076684b4d4574633b7e26ca677cba62e7842f064ac32d959f05" }, "structure_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23835, "instances": 11, "digest": "2a922979e22ba1c81b7f2433b1d411a338fa08454feec3b3bbf01194fbd22ceb", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "82155998ba0f821c14e0d143a08e790789e2abaaa16c646435384b7f43f5041e", "contact_cells": 81, "contact_replacements": 77, "sitework_occupied_cells": 368, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/connector-7-5.litematic", "seconds": 0.7655 }
boundary-0-0validated{"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.37805693729455747]}]}, {"1962910110.10482d3b23471d8dbc27
记录 / 诊断
{ "label": "boundary-0-0", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19629, "instances": 10, "digest": "37efb00d36dd40be3aef17c7a1168ade8085640e23709eaf0992f9a3ca917804", "principal_signature": "2d3b23471d8dbc275a640b3a7fe5524d9874c6d0478f50ddfd24c76e8e3a5c95", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 2, 1 ], [ 3, 1 ], [ 3, 2 ], [ 4, 2 ], [ 5, 2 ], [ 5, 3 ], [ 6, 3 ], [ 7, 3 ], [ 7, 4 ], [ 8, 4 ], [ 9, 4 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 11, 6 ], [ 12, 6 ], [ 13, 6 ], [ 13, 7 ], [ 14, 7 ], [ 15, 7 ], [ 15, 8 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 20, 9 ], [ 20, 10 ], [ 21, 10 ], [ 22, 10 ], [ 22, 11 ], [ 23, 11 ], [ 24, 11 ], [ 24, 12 ], [ 25, 12 ], [ 26, 12 ], [ 26, 13 ], [ 27, 13 ], [ 28, 13 ], [ 28, 14 ], [ 29, 14 ], [ 30, 14 ], [ 30, 15 ], [ 31, 15 ], [ 32, 15 ], [ 32, 16 ], [ 33, 16 ], [ 34, 16 ], [ 34, 17 ], [ 35, 17 ], [ 36, 17 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "4d2d885b8edfccd9884e48b523e32a6625d68eebcaac36fc5ceea650fc1d2f29", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1048 }
boundary-0-1validated{"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.37805693729455747]}]}, {"1963112110.57285f9baf7fbc79a28c
记录 / 诊断
{ "label": "boundary-0-1", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19631, "instances": 12, "digest": "0942b9d7c5e69060aea49b1e12a4ada8767f3c1928af70e9437cea4c0a7acc59", "principal_signature": "5f9baf7fbc79a28ca1c35befbc50cb3518a2cddd9883c9973cc9403b05bb8bc7", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 3, 6 ], [ 3, 7 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 9 ], [ 5, 10 ], [ 6, 10 ], [ 6, 11 ], [ 7, 11 ], [ 7, 12 ], [ 8, 12 ], [ 8, 13 ], [ 9, 13 ], [ 9, 14 ], [ 10, 14 ], [ 11, 14 ], [ 11, 15 ], [ 12, 15 ], [ 12, 16 ], [ 13, 16 ], [ 14, 16 ], [ 14, 17 ], [ 15, 17 ], [ 16, 17 ], [ 17, 17 ], [ 18, 17 ], [ 18, 18 ], [ 19, 18 ], [ 20, 18 ], [ 21, 18 ], [ 22, 18 ], [ 23, 18 ], [ 24, 18 ], [ 25, 18 ], [ 26, 18 ], [ 27, 18 ], [ 28, 18 ], [ 29, 18 ], [ 30, 18 ], [ 31, 18 ], [ 32, 18 ], [ 33, 18 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "5634ad54d5bf866711127978ba5e33843592fbd265c408bea39d4bc7dfe9865b", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/boundary-0-1.litematic", "seconds": 0.5728 }
boundary-0-2validated{"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.37805693729455747]}]}, {"1957310110.10310566589af2a10d9d
记录 / 诊断
{ "label": "boundary-0-2", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19573, "instances": 10, "digest": "3e99f76f020e52b0ff6f1bc8ed5cf7c48e594963986f772f073a6fad2e9cb40a", "principal_signature": "0566589af2a10d9dc9dee25fa727e1b60006270362243e21fb11488cdedf3c60", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], [ 5, 2 ], [ 6, 2 ], [ 7, 2 ], [ 7, 3 ], [ 8, 3 ], [ 9, 3 ], [ 9, 4 ], [ 10, 4 ], [ 11, 4 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 13, 6 ], [ 14, 6 ], [ 14, 7 ], [ 15, 7 ], [ 16, 7 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 19, 10 ], [ 20, 10 ], [ 21, 10 ], [ 21, 11 ], [ 22, 11 ], [ 22, 12 ], [ 23, 12 ], [ 24, 12 ], [ 24, 13 ], [ 25, 13 ], [ 25, 14 ], [ 26, 14 ], [ 27, 14 ], [ 27, 15 ], [ 28, 15 ], [ 29, 15 ], [ 29, 16 ], [ 30, 16 ], [ 31, 16 ], [ 31, 17 ], [ 32, 17 ], [ 33, 17 ], [ 34, 17 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 3 ] } ], "organization": [], "legacy": [] }, "contact_signature": "b965471a76af5c3117d38bc3b0a8ccc59bd30646eb752da4672c2b3baa088fb2", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 168, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1031 }
boundary-0-3validated{"environment_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.37805693729455747]}]}, {"1963112110.1086eca715671529239
记录 / 诊断
{ "label": "boundary-0-3", "inputs": { "environment_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.37805693729455747 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19631, "instances": 12, "digest": "88360e48feafb6a5eff56facb75a9d770d13c08b482496a3674d150f49f40415", "principal_signature": "6eca715671529239b41418e75ac65c5db2ec03c7ca2420c54af403c4121c6c6f", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 2, 2 ], [ 3, 2 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 5, 4 ], [ 6, 4 ], [ 7, 4 ], [ 8, 4 ], [ 8, 5 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 14, 5 ], [ 14, 6 ], [ 15, 6 ], [ 16, 6 ], [ 17, 6 ], [ 18, 6 ], [ 19, 6 ], [ 20, 6 ], [ 21, 6 ], [ 21, 7 ], [ 22, 7 ], [ 23, 7 ], [ 24, 7 ], [ 25, 7 ], [ 25, 8 ], [ 26, 8 ], [ 27, 8 ], [ 28, 8 ], [ 28, 9 ], [ 29, 9 ], [ 29, 10 ], [ 30, 10 ], [ 31, 10 ], [ 31, 11 ], [ 32, 11 ], [ 32, 12 ], [ 33, 12 ], [ 33, 13 ], [ 34, 13 ], [ 34, 14 ], [ 35, 14 ], [ 35, 15 ], [ 36, 15 ], [ 36, 16 ], [ 36, 17 ], [ 37, 17 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "8e11daff301695e905759bf8f8f0c2fcab4259342fe4b6b2e7a1879c46892b85", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.108 }
boundary-1-0validated{"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014200281]}]}, {"op":2093810110.1112d3b23471d8dbc27
记录 / 诊断
{ "label": "boundary-1-0", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20938, "instances": 10, "digest": "c5fadc30d07b8e533ed132f9340bc876aee4a4b2707d5f7ec9a36d7038d939a8", "principal_signature": "2d3b23471d8dbc275a640b3a7fe5524d9874c6d0478f50ddfd24c76e8e3a5c95", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 2, 1 ], [ 3, 1 ], [ 3, 2 ], [ 4, 2 ], [ 5, 2 ], [ 5, 3 ], [ 6, 3 ], [ 7, 3 ], [ 7, 4 ], [ 8, 4 ], [ 9, 4 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 11, 6 ], [ 12, 6 ], [ 13, 6 ], [ 13, 7 ], [ 14, 7 ], [ 15, 7 ], [ 15, 8 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 20, 9 ], [ 20, 10 ], [ 21, 10 ], [ 22, 10 ], [ 22, 11 ], [ 23, 11 ], [ 24, 11 ], [ 24, 12 ], [ 25, 12 ], [ 26, 12 ], [ 26, 13 ], [ 27, 13 ], [ 28, 13 ], [ 28, 14 ], [ 29, 14 ], [ 30, 14 ], [ 30, 15 ], [ 31, 15 ], [ 32, 15 ], [ 32, 16 ], [ 33, 16 ], [ 34, 16 ], [ 34, 17 ], [ 35, 17 ], [ 36, 17 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "111369ab1ff7b5441f5d77d70b50f75c70693957d223ec209525c4b1748b9e8a", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.111 }
boundary-1-1validated{"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014200281]}]}, {"op":2094012110.11285f9baf7fbc79a28c
记录 / 诊断
{ "label": "boundary-1-1", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20940, "instances": 12, "digest": "edd28f2cd305ede0fba0b05607e2ca91839c63904f9ceac33222e8ee6366f71f", "principal_signature": "5f9baf7fbc79a28ca1c35befbc50cb3518a2cddd9883c9973cc9403b05bb8bc7", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 3, 6 ], [ 3, 7 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 9 ], [ 5, 10 ], [ 6, 10 ], [ 6, 11 ], [ 7, 11 ], [ 7, 12 ], [ 8, 12 ], [ 8, 13 ], [ 9, 13 ], [ 9, 14 ], [ 10, 14 ], [ 11, 14 ], [ 11, 15 ], [ 12, 15 ], [ 12, 16 ], [ 13, 16 ], [ 14, 16 ], [ 14, 17 ], [ 15, 17 ], [ 16, 17 ], [ 17, 17 ], [ 18, 17 ], [ 18, 18 ], [ 19, 18 ], [ 20, 18 ], [ 21, 18 ], [ 22, 18 ], [ 23, 18 ], [ 24, 18 ], [ 25, 18 ], [ 26, 18 ], [ 27, 18 ], [ 28, 18 ], [ 29, 18 ], [ 30, 18 ], [ 31, 18 ], [ 32, 18 ], [ 33, 18 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "afc187c91b5df701c02342b32335f2ad643d49856cbd21e9aedc84db2b758cfd", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1128 }
boundary-1-2validated{"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014200281]}]}, {"op":2088210110.11370566589af2a10d9d
记录 / 诊断
{ "label": "boundary-1-2", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20882, "instances": 10, "digest": "2c0998da3b7b2d977facb8948923051e13105f97e1dbb8d3bb0aa9e27c0bb4e8", "principal_signature": "0566589af2a10d9dc9dee25fa727e1b60006270362243e21fb11488cdedf3c60", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], [ 5, 2 ], [ 6, 2 ], [ 7, 2 ], [ 7, 3 ], [ 8, 3 ], [ 9, 3 ], [ 9, 4 ], [ 10, 4 ], [ 11, 4 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 13, 6 ], [ 14, 6 ], [ 14, 7 ], [ 15, 7 ], [ 16, 7 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 19, 10 ], [ 20, 10 ], [ 21, 10 ], [ 21, 11 ], [ 22, 11 ], [ 22, 12 ], [ 23, 12 ], [ 24, 12 ], [ 24, 13 ], [ 25, 13 ], [ 25, 14 ], [ 26, 14 ], [ 27, 14 ], [ 27, 15 ], [ 28, 15 ], [ 29, 15 ], [ 29, 16 ], [ 30, 16 ], [ 31, 16 ], [ 31, 17 ], [ 32, 17 ], [ 33, 17 ], [ 34, 17 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 3 ] } ], "organization": [], "legacy": [] }, "contact_signature": "ed6b48f2601125651804812adcb10aa354440f9b7a1710358ae0803ec9088019", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 168, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1137 }
boundary-1-3validated{"environment_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0, 2]}, {"op": "wave", "args": [0, 0.11, 0.09, 4.510079014200281]}]}, {"op":2094012110.11176eca715671529239
记录 / 诊断
{ "label": "boundary-1-3", "inputs": { "environment_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.11, 0.09, 4.510079014200281 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20940, "instances": 12, "digest": "ae70432d6d2eeab96b5ae655caf72c955b599d8f78a4e991c551ea4fb21fad42", "principal_signature": "6eca715671529239b41418e75ac65c5db2ec03c7ca2420c54af403c4121c6c6f", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 2, 2 ], [ 3, 2 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 5, 4 ], [ 6, 4 ], [ 7, 4 ], [ 8, 4 ], [ 8, 5 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 14, 5 ], [ 14, 6 ], [ 15, 6 ], [ 16, 6 ], [ 17, 6 ], [ 18, 6 ], [ 19, 6 ], [ 20, 6 ], [ 21, 6 ], [ 21, 7 ], [ 22, 7 ], [ 23, 7 ], [ 24, 7 ], [ 25, 7 ], [ 25, 8 ], [ 26, 8 ], [ 27, 8 ], [ 28, 8 ], [ 28, 9 ], [ 29, 9 ], [ 29, 10 ], [ 30, 10 ], [ 31, 10 ], [ 31, 11 ], [ 32, 11 ], [ 32, 12 ], [ 33, 12 ], [ 33, 13 ], [ 34, 13 ], [ 34, 14 ], [ 35, 14 ], [ 35, 15 ], [ 36, 15 ], [ 36, 16 ], [ 36, 17 ], [ 37, 17 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "af6aeff8971e8aebdda7e79bfce291441afb42f5bd3371f0e5ea71534a647111", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1117 }
boundary-2-0validated{"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.9487749475373415]}]}, {"1945710110.10272d3b23471d8dbc27
记录 / 诊断
{ "label": "boundary-2-0", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19457, "instances": 10, "digest": "18a324563b484023118fc94dcbd9f71383aa7d1b2053f36965652bb28423b75e", "principal_signature": "2d3b23471d8dbc275a640b3a7fe5524d9874c6d0478f50ddfd24c76e8e3a5c95", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 2, 1 ], [ 3, 1 ], [ 3, 2 ], [ 4, 2 ], [ 5, 2 ], [ 5, 3 ], [ 6, 3 ], [ 7, 3 ], [ 7, 4 ], [ 8, 4 ], [ 9, 4 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 11, 6 ], [ 12, 6 ], [ 13, 6 ], [ 13, 7 ], [ 14, 7 ], [ 15, 7 ], [ 15, 8 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 20, 9 ], [ 20, 10 ], [ 21, 10 ], [ 22, 10 ], [ 22, 11 ], [ 23, 11 ], [ 24, 11 ], [ 24, 12 ], [ 25, 12 ], [ 26, 12 ], [ 26, 13 ], [ 27, 13 ], [ 28, 13 ], [ 28, 14 ], [ 29, 14 ], [ 30, 14 ], [ 30, 15 ], [ 31, 15 ], [ 32, 15 ], [ 32, 16 ], [ 33, 16 ], [ 34, 16 ], [ 34, 17 ], [ 35, 17 ], [ 36, 17 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "ae01923137b25b2f2933d308371b8d639dc89376b3d726518fb96729a7af5e44", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1027 }
boundary-2-1validated{"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.9487749475373415]}]}, {"1945912110.13355f9baf7fbc79a28c
记录 / 诊断
{ "label": "boundary-2-1", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19459, "instances": 12, "digest": "8063fafca7ab47e9dbfee18af0ac788b458752eba9eb6539662dc0ea353772ca", "principal_signature": "5f9baf7fbc79a28ca1c35befbc50cb3518a2cddd9883c9973cc9403b05bb8bc7", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 3, 6 ], [ 3, 7 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 9 ], [ 5, 10 ], [ 6, 10 ], [ 6, 11 ], [ 7, 11 ], [ 7, 12 ], [ 8, 12 ], [ 8, 13 ], [ 9, 13 ], [ 9, 14 ], [ 10, 14 ], [ 11, 14 ], [ 11, 15 ], [ 12, 15 ], [ 12, 16 ], [ 13, 16 ], [ 14, 16 ], [ 14, 17 ], [ 15, 17 ], [ 16, 17 ], [ 17, 17 ], [ 18, 17 ], [ 18, 18 ], [ 19, 18 ], [ 20, 18 ], [ 21, 18 ], [ 22, 18 ], [ 23, 18 ], [ 24, 18 ], [ 25, 18 ], [ 26, 18 ], [ 27, 18 ], [ 28, 18 ], [ 29, 18 ], [ 30, 18 ], [ 31, 18 ], [ 32, 18 ], [ 33, 18 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "11b2b08b42fd90aacfaaffc119ddbbf55633faab2a607ee2aef68d4825306956", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1335 }
boundary-2-2validated{"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.9487749475373415]}]}, {"1940110110.10470566589af2a10d9d
记录 / 诊断
{ "label": "boundary-2-2", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19401, "instances": 10, "digest": "e9eae29e297393a40a48e51f2149b8426cc61b3def369494fd3508c3badbc56a", "principal_signature": "0566589af2a10d9dc9dee25fa727e1b60006270362243e21fb11488cdedf3c60", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], [ 5, 2 ], [ 6, 2 ], [ 7, 2 ], [ 7, 3 ], [ 8, 3 ], [ 9, 3 ], [ 9, 4 ], [ 10, 4 ], [ 11, 4 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 13, 6 ], [ 14, 6 ], [ 14, 7 ], [ 15, 7 ], [ 16, 7 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 19, 10 ], [ 20, 10 ], [ 21, 10 ], [ 21, 11 ], [ 22, 11 ], [ 22, 12 ], [ 23, 12 ], [ 24, 12 ], [ 24, 13 ], [ 25, 13 ], [ 25, 14 ], [ 26, 14 ], [ 27, 14 ], [ 27, 15 ], [ 28, 15 ], [ 29, 15 ], [ 29, 16 ], [ 30, 16 ], [ 31, 16 ], [ 31, 17 ], [ 32, 17 ], [ 33, 17 ], [ 34, 17 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 3 ] } ], "organization": [], "legacy": [] }, "contact_signature": "4fff077a672f8fe97a56cddaf65a42a2d7dd385fb821c0c6cf434c30a05f863b", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 168, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1047 }
boundary-2-3validated{"environment_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.015, 2]}, {"op": "wave", "args": [0.35, 0.11, 0.09, 1.9487749475373415]}]}, {"1945912110.10616eca715671529239
记录 / 诊断
{ "label": "boundary-2-3", "inputs": { "environment_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.015, 2 ] }, { "op": "wave", "args": [ 0.35, 0.11, 0.09, 1.9487749475373415 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -2 ] } ] }, -1, 5 ] }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 19459, "instances": 12, "digest": "e92a37614c7e98b01dbaa60b061dd5fc4fece43bf5cd3f79db7e0626a4652add", "principal_signature": "6eca715671529239b41418e75ac65c5db2ec03c7ca2420c54af403c4121c6c6f", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 2, 2 ], [ 3, 2 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 5, 4 ], [ 6, 4 ], [ 7, 4 ], [ 8, 4 ], [ 8, 5 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 14, 5 ], [ 14, 6 ], [ 15, 6 ], [ 16, 6 ], [ 17, 6 ], [ 18, 6 ], [ 19, 6 ], [ 20, 6 ], [ 21, 6 ], [ 21, 7 ], [ 22, 7 ], [ 23, 7 ], [ 24, 7 ], [ 25, 7 ], [ 25, 8 ], [ 26, 8 ], [ 27, 8 ], [ 28, 8 ], [ 28, 9 ], [ 29, 9 ], [ 29, 10 ], [ 30, 10 ], [ 31, 10 ], [ 31, 11 ], [ 32, 11 ], [ 32, 12 ], [ 33, 12 ], [ 33, 13 ], [ 34, 13 ], [ 34, 14 ], [ 35, 14 ], [ 35, 15 ], [ 36, 15 ], [ 36, 16 ], [ 36, 17 ], [ 37, 17 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "5778edd214fc761706ffaf2e43916de78ab8fe7ea4cd0168ed585ecedbbd9132", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1061 }
boundary-3-0validated{"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.5389719292616382]}]},2165410110.11332d3b23471d8dbc27
记录 / 诊断
{ "label": "boundary-3-0", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21654, "instances": 10, "digest": "1b28af9ee46bc739fa5f8ba1854daeaa079129299ac396ec240b75316407ddd5", "principal_signature": "2d3b23471d8dbc275a640b3a7fe5524d9874c6d0478f50ddfd24c76e8e3a5c95", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 2, 1 ], [ 3, 1 ], [ 3, 2 ], [ 4, 2 ], [ 5, 2 ], [ 5, 3 ], [ 6, 3 ], [ 7, 3 ], [ 7, 4 ], [ 8, 4 ], [ 9, 4 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 11, 6 ], [ 12, 6 ], [ 13, 6 ], [ 13, 7 ], [ 14, 7 ], [ 15, 7 ], [ 15, 8 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 20, 9 ], [ 20, 10 ], [ 21, 10 ], [ 22, 10 ], [ 22, 11 ], [ 23, 11 ], [ 24, 11 ], [ 24, 12 ], [ 25, 12 ], [ 26, 12 ], [ 26, 13 ], [ 27, 13 ], [ 28, 13 ], [ 28, 14 ], [ 29, 14 ], [ 30, 14 ], [ 30, 15 ], [ 31, 15 ], [ 32, 15 ], [ 32, 16 ], [ 33, 16 ], [ 34, 16 ], [ 34, 17 ], [ 35, 17 ], [ 36, 17 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "f8b5008d41adf0fe5e94b50408b58f191f03eb5de73334ac17edf64fdd0be16c", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1133 }
boundary-3-1validated{"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.5389719292616382]}]},2165612110.125f9baf7fbc79a28c
记录 / 诊断
{ "label": "boundary-3-1", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21656, "instances": 12, "digest": "a2c19b8fc7f61ed5dec59df3832dbf9df8b0b1d9844275638c23bf5b1a1f4bae", "principal_signature": "5f9baf7fbc79a28ca1c35befbc50cb3518a2cddd9883c9973cc9403b05bb8bc7", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 3, 6 ], [ 3, 7 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 9 ], [ 5, 10 ], [ 6, 10 ], [ 6, 11 ], [ 7, 11 ], [ 7, 12 ], [ 8, 12 ], [ 8, 13 ], [ 9, 13 ], [ 9, 14 ], [ 10, 14 ], [ 11, 14 ], [ 11, 15 ], [ 12, 15 ], [ 12, 16 ], [ 13, 16 ], [ 14, 16 ], [ 14, 17 ], [ 15, 17 ], [ 16, 17 ], [ 17, 17 ], [ 18, 17 ], [ 18, 18 ], [ 19, 18 ], [ 20, 18 ], [ 21, 18 ], [ 22, 18 ], [ 23, 18 ], [ 24, 18 ], [ 25, 18 ], [ 26, 18 ], [ 27, 18 ], [ 28, 18 ], [ 29, 18 ], [ 30, 18 ], [ 31, 18 ], [ 32, 18 ], [ 33, 18 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "8bb177df266bb40129da886cf300a53dfdbdc3f40c68786bdbd157d5e6c52296", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.12 }
boundary-3-2validated{"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.5389719292616382]}]},2159810110.11430566589af2a10d9d
记录 / 诊断
{ "label": "boundary-3-2", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21598, "instances": 10, "digest": "aad010fae4c5373a6f1c3ffa3bdd26b8805ce05e8b94b1bf517b246c4ab065d0", "principal_signature": "0566589af2a10d9dc9dee25fa727e1b60006270362243e21fb11488cdedf3c60", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], [ 5, 2 ], [ 6, 2 ], [ 7, 2 ], [ 7, 3 ], [ 8, 3 ], [ 9, 3 ], [ 9, 4 ], [ 10, 4 ], [ 11, 4 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 13, 6 ], [ 14, 6 ], [ 14, 7 ], [ 15, 7 ], [ 16, 7 ], [ 16, 8 ], [ 17, 8 ], [ 17, 9 ], [ 18, 9 ], [ 19, 9 ], [ 19, 10 ], [ 20, 10 ], [ 21, 10 ], [ 21, 11 ], [ 22, 11 ], [ 22, 12 ], [ 23, 12 ], [ 24, 12 ], [ 24, 13 ], [ 25, 13 ], [ 25, 14 ], [ 26, 14 ], [ 27, 14 ], [ 27, 15 ], [ 28, 15 ], [ 29, 15 ], [ 29, 16 ], [ 30, 16 ], [ 31, 16 ], [ 31, 17 ], [ 32, 17 ], [ 33, 17 ], [ 34, 17 ], [ 34, 18 ], [ 35, 18 ], [ 36, 18 ], [ 37, 18 ] ], "section_heights": [ 3 ] } ], "organization": [], "legacy": [] }, "contact_signature": "9bb7eeba5b94c24d13441473cd61fdfa4f0cfcc778a268c0c32bdc233387b243", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 168, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.1143 }
boundary-3-3validated{"environment_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.035, 0.015, 2]}, {"op": "wave", "args": [0.7, 0.11, 0.09, 0.5389719292616382]}]},2165612110.63046eca715671529239
记录 / 诊断
{ "label": "boundary-3-3", "inputs": { "environment_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.035, 0.015, 2 ] }, { "op": "wave", "args": [ 0.7, 0.11, 0.09, 0.5389719292616382 ] } ] }, { "op": "radial", "args": [ 16, 18, 14, -1 ] } ] }, -1, 5 ] }, "structure_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 21656, "instances": 12, "digest": "186cab71238423e9665574cb48f0b49a22d921ba23a1742add4fa0827e9a4cb5", "principal_signature": "6eca715671529239b41418e75ac65c5db2ec03c7ca2420c54af403c4121c6c6f", "structure": { "halls": [], "links": [], "boundaries": [ { "plan": [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 2 ], [ 2, 2 ], [ 3, 2 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 5, 4 ], [ 6, 4 ], [ 7, 4 ], [ 8, 4 ], [ 8, 5 ], [ 9, 5 ], [ 10, 5 ], [ 11, 5 ], [ 12, 5 ], [ 13, 5 ], [ 14, 5 ], [ 14, 6 ], [ 15, 6 ], [ 16, 6 ], [ 17, 6 ], [ 18, 6 ], [ 19, 6 ], [ 20, 6 ], [ 21, 6 ], [ 21, 7 ], [ 22, 7 ], [ 23, 7 ], [ 24, 7 ], [ 25, 7 ], [ 25, 8 ], [ 26, 8 ], [ 27, 8 ], [ 28, 8 ], [ 28, 9 ], [ 29, 9 ], [ 29, 10 ], [ 30, 10 ], [ 31, 10 ], [ 31, 11 ], [ 32, 11 ], [ 32, 12 ], [ 33, 12 ], [ 33, 13 ], [ 34, 13 ], [ 34, 14 ], [ 35, 14 ], [ 35, 15 ], [ 36, 15 ], [ 36, 16 ], [ 36, 17 ], [ 37, 17 ], [ 37, 18 ] ], "section_heights": [ 4 ] } ], "organization": [], "legacy": [] }, "contact_signature": "0835ae7d5b81d72a069310c8e412d48f4ae9f6261a1e9f30ff345fb5ff77a936", "contact_cells": 0, "contact_replacements": 0, "sitework_occupied_cells": 224, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/boundary-3-3.litematic", "seconds": 0.6304 }
hall-0validated{"structure_seed": 0, "environment_seed": 0}2688125111.06096d6be8f4ba528852
记录 / 诊断
{ "label": "hall-0", "inputs": { "structure_seed": 0, "environment_seed": 0 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 26881, "instances": 25, "digest": "b107cd17bdb61b02ef13654e84ad0649f6d15744e0fe55b1545932efc2bf52f5", "principal_signature": "6d6be8f4ba528852fec10f2a379b4e82bc2e5649799dbff6bec0bcb7de69457b", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ] ], "height": 5, "function": "living", "entrances": [ "north", "west" ], "roof_run": 2, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "633b2d064de17cc9ad8eaf92a49a922454ab1566a588459c3bc32db99a48f8e4", "contact_cells": 38, "contact_replacements": 6, "sitework_occupied_cells": 38, "excavated_solid_cells": 0, "furnishing_bays": 2, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/hall-0.litematic", "seconds": 1.0609 }
hall-1validated{"structure_seed": 1, "environment_seed": 1}2761535110.568279761b45cf96b2a6
记录 / 诊断
{ "label": "hall-1", "inputs": { "structure_seed": 1, "environment_seed": 1 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27615, "instances": 35, "digest": "bd736dcfc7c9e37778a902fd6be6f69d1bd06b4771145e4920f7a8513a562304", "principal_signature": "79761b45cf96b2a6945acb6ea63b0765236111157157f3e7d32ad5aa5cc5e40e", "structure": { "halls": [ { "footprint": [ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 0, 15 ], [ 0, 16 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 19, 0 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 19, 12 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 20, 0 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ], [ 20, 11 ], [ 20, 12 ], [ 20, 13 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ] ], "height": 5, "function": "library", "entrances": [ "north", "west" ], "roof_run": 2, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "99becc16003056c3c59a3900a297c01815b017f845a41a710f7e4d2091b7dbf4", "contact_cells": 51, "contact_replacements": 6, "sitework_occupied_cells": 51, "excavated_solid_cells": 0, "furnishing_bays": 6, "omitted_optional_furnishing_bays": 0, "seconds": 0.5682 }
hall-2validated{"structure_seed": 2, "environment_seed": 2}2696625110.4415a2e2a45587c1117b
记录 / 诊断
{ "label": "hall-2", "inputs": { "structure_seed": 2, "environment_seed": 2 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 26966, "instances": 25, "digest": "e3b0ba855390a4bd406b79522d93ac232dd076043292ba2c62be6bf7f9c131bc", "principal_signature": "a2e2a45587c1117b300eaa69c341f9bb47ae66b6fcf85c58a48bec07e6ed066d", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ] ], "height": 5, "function": "living", "entrances": [ "north", "west" ], "roof_run": 3, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f7d293835c022e76cc80351d1d4454ffca55e0a0684a48a9d1f6112fa1eb9451", "contact_cells": 52, "contact_replacements": 6, "sitework_occupied_cells": 52, "excavated_solid_cells": 0, "furnishing_bays": 2, "omitted_optional_furnishing_bays": 0, "seconds": 0.4415 }
hall-3validated{"structure_seed": 3, "environment_seed": 3}2787038110.6619e2ec1d694e695a7
记录 / 诊断
{ "label": "hall-3", "inputs": { "structure_seed": 3, "environment_seed": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27870, "instances": 38, "digest": "714aa00722410148d90dedbaf0bcab255db8d1827b94c378c35bdc8d1e736489", "principal_signature": "9e2ec1d694e695a76b67d984bbfca23011011b2a7471e6bdd949921c5329cc23", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 19, 0 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 19, 12 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 20, 0 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ], [ 20, 11 ], [ 20, 12 ], [ 20, 13 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 21, 0 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 21, 6 ], [ 21, 7 ], [ 21, 8 ], [ 21, 9 ], [ 21, 10 ], [ 21, 11 ], [ 21, 12 ], [ 21, 13 ], [ 21, 14 ], [ 21, 15 ], [ 21, 16 ], [ 22, 0 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 22, 6 ], [ 22, 7 ], [ 22, 8 ], [ 22, 9 ], [ 22, 10 ], [ 22, 11 ], [ 22, 12 ], [ 22, 13 ], [ 22, 14 ], [ 22, 15 ], [ 22, 16 ], [ 23, 1 ], [ 23, 2 ], [ 23, 3 ], [ 23, 4 ], [ 23, 5 ], [ 23, 6 ], [ 23, 7 ], [ 23, 8 ], [ 23, 9 ], [ 23, 10 ], [ 23, 11 ], [ 23, 12 ], [ 23, 13 ], [ 23, 14 ], [ 23, 15 ], [ 24, 2 ], [ 24, 3 ], [ 24, 4 ], [ 24, 5 ], [ 24, 6 ], [ 24, 7 ], [ 24, 8 ], [ 24, 9 ], [ 24, 10 ], [ 24, 11 ], [ 24, 12 ], [ 24, 13 ], [ 24, 14 ] ], "height": 5, "function": "living", "entrances": [ "north", "west" ], "roof_run": 2, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "99dc537cc5ad49e093ac17122cc704e2526e27867ceb9ba99e0a5034fba1b1c5", "contact_cells": 51, "contact_replacements": 6, "sitework_occupied_cells": 51, "excavated_solid_cells": 0, "furnishing_bays": 7, "omitted_optional_furnishing_bays": 0, "seconds": 0.661 }
hall-4validated{"structure_seed": 4, "environment_seed": 4}2718431111.1369d99e9bd0014a8171
记录 / 诊断
{ "label": "hall-4", "inputs": { "structure_seed": 4, "environment_seed": 4 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27184, "instances": 31, "digest": "7c6c1c1522e9a8108d9d206117eaa38f2f0eaeeafb8fba78b7f2ceef072694ab", "principal_signature": "d99e9bd0014a8171b17a56b106a7add74c095802932bf3f9e7f74db7771b08d2", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ] ], "height": 5, "function": "living", "entrances": [ "north", "south", "east" ], "roof_run": 2, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "8412ba361b8a6e17616727492590a2a95152bd27345564094b9855a4b57b98d1", "contact_cells": 49, "contact_replacements": 9, "sitework_occupied_cells": 49, "excavated_solid_cells": 0, "furnishing_bays": 4, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/hall-4.litematic", "seconds": 1.1369 }
hall-5validated{"structure_seed": 5, "environment_seed": 5}2719231110.46933cda752f0d487ccc
记录 / 诊断
{ "label": "hall-5", "inputs": { "structure_seed": 5, "environment_seed": 5 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27192, "instances": 31, "digest": "47684771c217519c706f4dbcf3036d19d941fc8f9c962bcff78ace71b82c547e", "principal_signature": "3cda752f0d487ccc3d9feaaf18d130b99c48ca0428541394c8eeb9bb53228ff0", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 0, 15 ], [ 0, 16 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 2, 17 ], [ 2, 18 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ], [ 3, 19 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 4, 17 ], [ 4, 18 ], [ 4, 19 ], [ 4, 20 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 5, 17 ], [ 5, 18 ], [ 5, 19 ], [ 5, 20 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 6, 17 ], [ 6, 18 ], [ 6, 19 ], [ 6, 20 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 7, 17 ], [ 7, 18 ], [ 7, 19 ], [ 7, 20 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 8, 17 ], [ 8, 18 ], [ 8, 19 ], [ 8, 20 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 9, 17 ], [ 9, 18 ], [ 9, 19 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 10, 17 ], [ 10, 18 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 11, 17 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ] ], "height": 6, "function": "workshop", "entrances": [ "north", "south", "east" ], "roof_run": 3, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "82f708c92a71b33aff5c5dbdafb779007374f8701a2ef944a7df884b4a652fbd", "contact_cells": 54, "contact_replacements": 9, "sitework_occupied_cells": 54, "excavated_solid_cells": 0, "furnishing_bays": 4, "omitted_optional_furnishing_bays": 0, "seconds": 0.4693 }
hall-6validated{"structure_seed": 6, "environment_seed": 6}2830943110.739659079854d1df494a
记录 / 诊断
{ "label": "hall-6", "inputs": { "structure_seed": 6, "environment_seed": 6 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 28309, "instances": 43, "digest": "683351b1f548dbc7f87ddd6cd1d777019211b27a0b36c8b4f5fe5944d4ea2c99", "principal_signature": "59079854d1df494ae5175af9b9fa332ae4a9b9bc6fc8ad182939de7a05d117be", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 0, 15 ], [ 0, 16 ], [ 0, 17 ], [ 0, 18 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 2, 17 ], [ 2, 18 ], [ 2, 19 ], [ 2, 20 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ], [ 3, 19 ], [ 3, 20 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 4, 17 ], [ 4, 18 ], [ 4, 19 ], [ 4, 20 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 5, 17 ], [ 5, 18 ], [ 5, 19 ], [ 5, 20 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 6, 17 ], [ 6, 18 ], [ 6, 19 ], [ 6, 20 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 7, 17 ], [ 7, 18 ], [ 7, 19 ], [ 7, 20 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 8, 17 ], [ 8, 18 ], [ 8, 19 ], [ 8, 20 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 9, 17 ], [ 9, 18 ], [ 9, 19 ], [ 9, 20 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 10, 17 ], [ 10, 18 ], [ 10, 19 ], [ 10, 20 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 11, 17 ], [ 11, 18 ], [ 11, 19 ], [ 11, 20 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 12, 18 ], [ 12, 19 ], [ 12, 20 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 13, 18 ], [ 13, 19 ], [ 13, 20 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 14, 18 ], [ 14, 19 ], [ 14, 20 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 15, 19 ], [ 15, 20 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 16, 19 ], [ 16, 20 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 17, 19 ], [ 17, 20 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 18, 19 ], [ 18, 20 ], [ 19, 0 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 19, 12 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 19, 19 ], [ 19, 20 ], [ 20, 0 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ], [ 20, 11 ], [ 20, 12 ], [ 20, 13 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 20, 19 ], [ 20, 20 ], [ 21, 0 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 21, 6 ], [ 21, 7 ], [ 21, 8 ], [ 21, 9 ], [ 21, 10 ], [ 21, 11 ], [ 21, 12 ], [ 21, 13 ], [ 21, 14 ], [ 21, 15 ], [ 21, 16 ], [ 21, 17 ], [ 21, 18 ], [ 21, 19 ], [ 21, 20 ], [ 22, 0 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 22, 6 ], [ 22, 7 ], [ 22, 8 ], [ 22, 9 ], [ 22, 10 ], [ 22, 11 ], [ 22, 12 ], [ 22, 13 ], [ 22, 14 ], [ 22, 15 ], [ 22, 16 ], [ 22, 17 ], [ 22, 18 ], [ 22, 19 ], [ 22, 20 ], [ 23, 1 ], [ 23, 2 ], [ 23, 3 ], [ 23, 4 ], [ 23, 5 ], [ 23, 6 ], [ 23, 7 ], [ 23, 8 ], [ 23, 9 ], [ 23, 10 ], [ 23, 11 ], [ 23, 12 ], [ 23, 13 ], [ 23, 14 ], [ 23, 15 ], [ 23, 16 ], [ 23, 17 ], [ 23, 18 ], [ 23, 19 ], [ 24, 2 ], [ 24, 3 ], [ 24, 4 ], [ 24, 5 ], [ 24, 6 ], [ 24, 7 ], [ 24, 8 ], [ 24, 9 ], [ 24, 10 ], [ 24, 11 ], [ 24, 12 ], [ 24, 13 ], [ 24, 14 ], [ 24, 15 ], [ 24, 16 ], [ 24, 17 ], [ 24, 18 ] ], "height": 7, "function": "library", "entrances": [ "north", "south", "east" ], "roof_run": 2, "lantern": false } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "06b0b00dfef19267bdb809d6a6e2d2013a481755cd1c42e8de0ffe42ea30748b", "contact_cells": 63, "contact_replacements": 9, "sitework_occupied_cells": 63, "excavated_solid_cells": 0, "furnishing_bays": 8, "omitted_optional_furnishing_bays": 0, "seconds": 0.7396 }
hall-7validated{"structure_seed": 7, "environment_seed": 7}2703330111.1475498ba1fa5200d0f8
记录 / 诊断
{ "label": "hall-7", "inputs": { "structure_seed": 7, "environment_seed": 7 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27033, "instances": 30, "digest": "fd22ac860e196e121b68af63366c0076606c89e58a308efc32f19c11ab043d59", "principal_signature": "498ba1fa5200d0f8effe070dd41ed6c9c99bd5a17a3db27810ce32b199368e85", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ] ], "height": 6, "function": "living", "entrances": [ "north", "south", "east" ], "roof_run": 3, "lantern": false } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "5e986553dc6941be0f0199ef1c9d0e320130700eade9fb16fdcec82b6a25867c", "contact_cells": 60, "contact_replacements": 9, "sitework_occupied_cells": 60, "excavated_solid_cells": 0, "furnishing_bays": 3, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/hall-7.litematic", "seconds": 1.1475 }
hall-8validated{"structure_seed": 8, "environment_seed": 8}2713428110.451498addf1ca63debfc
记录 / 诊断
{ "label": "hall-8", "inputs": { "structure_seed": 8, "environment_seed": 8 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27134, "instances": 28, "digest": "ec0667b26a8bfcb865da574f61636069c7cdf40ef66ba45e6a6c9c61047d98b5", "principal_signature": "98addf1ca63debfc63129778daaee6ec78f918aadab322ca273720f8ab79ddac", "structure": { "halls": [ { "footprint": [ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 0, 15 ], [ 0, 16 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ] ], "height": 7, "function": "library", "entrances": [ "north", "west" ], "roof_run": 3, "lantern": false } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "c6f1e880454d0bb77a8f20627082ff549bac57fbe23078e602c0f3e93061bf52", "contact_cells": 46, "contact_replacements": 6, "sitework_occupied_cells": 46, "excavated_solid_cells": 0, "furnishing_bays": 3, "omitted_optional_furnishing_bays": 0, "seconds": 0.4514 }
hall-9validated{"structure_seed": 9, "environment_seed": 9}2777839110.6356e62e99895d521656
记录 / 诊断
{ "label": "hall-9", "inputs": { "structure_seed": 9, "environment_seed": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27778, "instances": 39, "digest": "83eb19aea234774fbb82103fbd41cf30f4930fa31a2eb2e68b6f3be322a9b83d", "principal_signature": "e62e99895d521656593bc1387f568c59e9ccef59d71ec4c30e1b70e0bf42956d", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 0, 15 ], [ 0, 16 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 2, 17 ], [ 2, 18 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ], [ 3, 19 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 4, 17 ], [ 4, 18 ], [ 4, 19 ], [ 4, 20 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 5, 17 ], [ 5, 18 ], [ 5, 19 ], [ 5, 20 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 6, 17 ], [ 6, 18 ], [ 6, 19 ], [ 6, 20 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 7, 17 ], [ 7, 18 ], [ 7, 19 ], [ 7, 20 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 8, 17 ], [ 8, 18 ], [ 8, 19 ], [ 8, 20 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 9, 17 ], [ 9, 18 ], [ 9, 19 ], [ 9, 20 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 10, 17 ], [ 10, 18 ], [ 10, 19 ], [ 10, 20 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 11, 17 ], [ 11, 18 ], [ 11, 19 ], [ 11, 20 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 12, 18 ], [ 12, 19 ], [ 12, 20 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 13, 18 ], [ 13, 19 ], [ 13, 20 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 14, 18 ], [ 14, 19 ], [ 14, 20 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 15, 19 ], [ 15, 20 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 16, 19 ], [ 16, 20 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 17, 19 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 19, 12 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ], [ 20, 11 ], [ 20, 12 ], [ 20, 13 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "west" ], "roof_run": 3, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "7f5eb6e370f5780edc432021eb80579abafb1516f3389cad52c046c84bf85f30", "contact_cells": 57, "contact_replacements": 6, "sitework_occupied_cells": 57, "excavated_solid_cells": 0, "furnishing_bays": 7, "omitted_optional_furnishing_bays": 0, "seconds": 0.6356 }
hall-10validated{"structure_seed": 10, "environment_seed": 10}2719432110.4914d2716b12f83ec0ef
记录 / 诊断
{ "label": "hall-10", "inputs": { "structure_seed": 10, "environment_seed": 10 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27194, "instances": 32, "digest": "abc68415cffd26e0bfc31a9545b06edbcd732a224dc35b363d4ae62bccfbb032", "principal_signature": "d2716b12f83ec0ef776051572fe14664ca487ca6474120362da157a6243aec07", "structure": { "halls": [ { "footprint": [ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "living", "entrances": [ "north", "south", "east" ], "roof_run": 3, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "9e02bf78485fe21086fb6e1b5e7a2195ef740018835b533e42cf44c7942abae3", "contact_cells": 58, "contact_replacements": 9, "sitework_occupied_cells": 58, "excavated_solid_cells": 0, "furnishing_bays": 3, "omitted_optional_furnishing_bays": 0, "seconds": 0.4914 }
hall-11validated{"structure_seed": 11, "environment_seed": 11}2767137110.59975a053564182bb391
记录 / 诊断
{ "label": "hall-11", "inputs": { "structure_seed": 11, "environment_seed": 11 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27671, "instances": 37, "digest": "5bfe4575581278256b26bdc5ed765b2da2289e7469659ccd4d89eff54d2981c1", "principal_signature": "5a053564182bb3915c3b9baad383618e91909168381bda2aba56a97734f05e48", "structure": { "halls": [ { "footprint": [ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 0, 15 ], [ 0, 16 ], [ 0, 17 ], [ 0, 18 ], [ 0, 19 ], [ 0, 20 ], [ 1, 0 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 2, 17 ], [ 2, 18 ], [ 2, 19 ], [ 2, 20 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 3, 17 ], [ 3, 18 ], [ 3, 19 ], [ 3, 20 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 4, 17 ], [ 4, 18 ], [ 4, 19 ], [ 4, 20 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 5, 17 ], [ 5, 18 ], [ 5, 19 ], [ 5, 20 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 6, 17 ], [ 6, 18 ], [ 6, 19 ], [ 6, 20 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 7, 17 ], [ 7, 18 ], [ 7, 19 ], [ 7, 20 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 8, 17 ], [ 8, 18 ], [ 8, 19 ], [ 8, 20 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 9, 17 ], [ 9, 18 ], [ 9, 19 ], [ 9, 20 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 10, 17 ], [ 10, 18 ], [ 10, 19 ], [ 10, 20 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 11, 17 ], [ 11, 18 ], [ 11, 19 ], [ 11, 20 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 12, 18 ], [ 12, 19 ], [ 12, 20 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 13, 18 ], [ 13, 19 ], [ 13, 20 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 14, 18 ], [ 14, 19 ], [ 14, 20 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 15, 19 ], [ 15, 20 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 16, 19 ], [ 16, 20 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south", "east" ], "roof_run": 3, "lantern": true } ], "links": [], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "2476b7bbcb6581506a42c9041c90de27394e65891011c88eb3c5bcaa8b295990", "contact_cells": 71, "contact_replacements": 9, "sitework_occupied_cells": 71, "excavated_solid_cells": 0, "furnishing_bays": 6, "omitted_optional_furnishing_bays": 0, "seconds": 0.5997 }
campus-0validated{"program": "campus", "structure_seed": 0, "environment_seed": 0, "frozen_digest": "c9de4c706492cbfd134b98f19fcc1538bc8367c20302347208851f705b1f1093"}119395446116.1514e40fe6ff2919877f
记录 / 诊断
{ "label": "campus-0", "inputs": { "program": "campus", "structure_seed": 0, "environment_seed": 0, "frozen_digest": "c9de4c706492cbfd134b98f19fcc1538bc8367c20302347208851f705b1f1093" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 119395, "instances": 446, "digest": "57d7f6afe22a301ac06f769c1c9c9962c53ea3fc878e7d494d2a5d0eef47c669", "principal_signature": "e40fe6ff2919877f7195099f22b1647ac40041c57944ba2e8c1f4488446b67f6", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "library", "entrances": [ "north", "east", "south", "west" ], "roof_run": 2, "lantern": true }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 6, "function": "kitchen", "entrances": [ "west", "south" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ -27, -4 ], [ -27, -3 ], [ -26, -6 ], [ -26, -5 ], [ -26, -4 ], [ -26, -3 ], [ -26, -2 ], [ -25, -6 ], [ -25, -5 ], [ -25, -4 ], [ -25, -3 ], [ -25, -2 ], [ -24, -6 ], [ -24, -5 ], [ -24, -4 ], [ -24, -3 ], [ -24, -2 ], [ -23, -6 ], [ -23, -5 ], [ -23, -4 ], [ -23, -3 ], [ -23, -2 ], [ -22, -6 ], [ -22, -5 ], [ -22, -4 ], [ -22, -3 ], [ -22, -2 ], [ -21, -6 ], [ -21, -5 ], [ -21, -4 ], [ -21, -3 ], [ -21, -2 ], [ -20, -6 ], [ -20, -5 ], [ -20, -4 ], [ -20, -3 ], [ -20, -2 ], [ -19, -6 ], [ -19, -5 ], [ -19, -4 ], [ -19, -3 ], [ -19, -2 ], [ -18, -5 ], [ -18, -4 ], [ -18, -3 ], [ -18, -2 ], [ -17, -5 ], [ -17, -4 ], [ -17, -3 ], [ -17, -2 ], [ -16, -5 ], [ -16, -4 ], [ -16, -3 ], [ -16, -2 ], [ -15, -5 ], [ -15, -4 ], [ -15, -3 ], [ -15, -2 ], [ -14, -5 ], [ -14, -4 ], [ -14, -3 ], [ -14, -2 ], [ -13, -5 ], [ -13, -4 ], [ -13, -3 ], [ -13, -2 ], [ -12, -5 ], [ -12, -4 ], [ -12, -3 ], [ -12, -2 ], [ -11, -5 ], [ -11, -4 ], [ -11, -3 ], [ -11, -2 ], [ -10, -5 ], [ -10, -4 ], [ -10, -3 ], [ -10, -2 ], [ -9, -5 ], [ -9, -4 ], [ -9, -3 ], [ -9, -2 ], [ -8, -5 ], [ -8, -4 ], [ -8, -3 ], [ -8, -2 ], [ -7, -5 ], [ -7, -4 ], [ -7, -3 ], [ -7, -2 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -6, -2 ], [ -6, -1 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -2, -5 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -1, -5 ], [ -1, -4 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ 0, -5 ], [ 0, -4 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -2 ], [ 1, -1 ], [ 2, -4 ], [ 2, -3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -10 ], [ 2, -9 ], [ 2, -8 ], [ 2, -7 ], [ 2, -6 ], [ 2, -5 ], [ 2, -4 ], [ 2, -3 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -18 ], [ 3, -17 ], [ 3, -16 ], [ 3, -15 ], [ 3, -14 ], [ 3, -13 ], [ 3, -12 ], [ 3, -11 ], [ 3, -10 ], [ 3, -9 ], [ 3, -8 ], [ 3, -7 ], [ 3, -6 ], [ 3, -5 ], [ 3, -4 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -26 ], [ 4, -25 ], [ 4, -24 ], [ 4, -23 ], [ 4, -22 ], [ 4, -21 ], [ 4, -20 ], [ 4, -19 ], [ 4, -18 ], [ 4, -17 ], [ 4, -16 ], [ 4, -15 ], [ 4, -14 ], [ 4, -13 ], [ 4, -12 ], [ 4, -11 ], [ 4, -10 ], [ 4, -9 ], [ 4, -8 ], [ 4, -7 ], [ 4, -6 ], [ 4, -5 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -27 ], [ 5, -26 ], [ 5, -25 ], [ 5, -24 ], [ 5, -23 ], [ 5, -22 ], [ 5, -21 ], [ 5, -20 ], [ 5, -19 ], [ 5, -18 ], [ 5, -17 ], [ 5, -16 ], [ 5, -15 ], [ 5, -14 ], [ 5, -13 ], [ 5, -12 ], [ 5, -11 ], [ 5, -10 ], [ 5, -9 ], [ 5, -8 ], [ 5, -7 ], [ 5, -6 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -27 ], [ 6, -26 ], [ 6, -25 ], [ 6, -24 ], [ 6, -23 ], [ 6, -22 ], [ 6, -21 ], [ 6, -20 ], [ 6, -19 ], [ 6, -18 ], [ 6, -17 ], [ 6, -16 ], [ 6, -15 ], [ 6, -14 ], [ 6, -13 ], [ 6, -12 ], [ 6, -11 ], [ 6, -10 ], [ 6, -9 ], [ 6, -8 ], [ 6, -7 ], [ 7, -26 ], [ 7, -25 ], [ 7, -24 ], [ 7, -23 ], [ 7, -22 ], [ 7, -21 ], [ 7, -20 ], [ 7, -19 ], [ 7, -18 ], [ 7, -17 ], [ 7, -16 ], [ 7, -15 ], [ 8, -26 ], [ 8, -25 ], [ 8, -24 ], [ 8, -23 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 23, 2 ], [ 23, 3 ] ], "width": 3, "covered": true, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 23, 23, [ "building", "habitable", "composite" ] ], [ 0, 0, [ "building", "habitable", "composite" ] ], [ 51, 0, [ "building", "habitable", "composite" ] ], [ 48, 51, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 2, "west", false, 3 ], [ 0, "north", 1, "south", true, 3 ], [ 0, "south", 3, "street", true, 3 ] ] } ], "legacy": [ { "rooms": [ [ 0, 0, 0, "room.living", [ "north" ], true, [ -1, 0, -1, 9, 6, 9 ] ], [ 0, 6, 0, "room.bedroom", [], false, [ -1, 0, -1, 9, 6, 9 ] ] ], "roofs": [ [ "z", 9, true, 206 ] ], "porch": true, "bay": 9 } ] }, "contact_signature": "aeabc44abe2324fbeed2ea71e006918856b3e6bcd99760b0aeb3e0c6c563b09d", "contact_cells": 189, "contact_replacements": 236, "sitework_occupied_cells": 1441, "excavated_solid_cells": 0, "furnishing_bays": 8, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/campus-0.litematic", "seconds": 6.1514 }
campus-1validated{"program": "campus", "structure_seed": 1, "environment_seed": 1, "frozen_digest": "c3a2a25f76b44a187da0c6b563c8b4ae3b363d9944fb83e17c117d0c122e9e29"}130816471112.99343a1c68e417282c46
记录 / 诊断
{ "label": "campus-1", "inputs": { "program": "campus", "structure_seed": 1, "environment_seed": 1, "frozen_digest": "c3a2a25f76b44a187da0c6b563c8b4ae3b363d9944fb83e17c117d0c122e9e29" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 130816, "instances": 471, "digest": "239ec63730fb730e3de4197e8fd71c693936176260e15eb29d15de48be66f5df", "principal_signature": "3a1c68e417282c460ae1f1f587606e6dc83b689e6333ab06cbcb5945275d1599", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "library", "entrances": [ "north", "east", "south", "west" ], "roof_run": 2, "lantern": true }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 6, "function": "kitchen", "entrances": [ "west", "south" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ -27, 0 ], [ -27, 1 ], [ -26, -2 ], [ -26, -1 ], [ -26, 0 ], [ -26, 1 ], [ -26, 2 ], [ -25, -2 ], [ -25, -1 ], [ -25, 0 ], [ -25, 1 ], [ -25, 2 ], [ -24, -2 ], [ -24, -1 ], [ -24, 0 ], [ -24, 1 ], [ -24, 2 ], [ -23, -2 ], [ -23, -1 ], [ -23, 0 ], [ -23, 1 ], [ -23, 2 ], [ -22, -2 ], [ -22, -1 ], [ -22, 0 ], [ -22, 1 ], [ -21, -2 ], [ -21, -1 ], [ -21, 0 ], [ -21, 1 ], [ -20, -2 ], [ -20, -1 ], [ -20, 0 ], [ -20, 1 ], [ -19, -2 ], [ -19, -1 ], [ -19, 0 ], [ -19, 1 ], [ -18, -3 ], [ -18, -2 ], [ -18, -1 ], [ -18, 0 ], [ -18, 1 ], [ -17, -3 ], [ -17, -2 ], [ -17, -1 ], [ -17, 0 ], [ -17, 1 ], [ -16, -3 ], [ -16, -2 ], [ -16, -1 ], [ -16, 0 ], [ -16, 1 ], [ -15, -3 ], [ -15, -2 ], [ -15, -1 ], [ -15, 0 ], [ -15, 1 ], [ -14, -3 ], [ -14, -2 ], [ -14, -1 ], [ -14, 0 ], [ -13, -3 ], [ -13, -2 ], [ -13, -1 ], [ -13, 0 ], [ -12, -3 ], [ -12, -2 ], [ -12, -1 ], [ -12, 0 ], [ -11, -3 ], [ -11, -2 ], [ -11, -1 ], [ -11, 0 ], [ -10, -4 ], [ -10, -3 ], [ -10, -2 ], [ -10, -1 ], [ -10, 0 ], [ -9, -4 ], [ -9, -3 ], [ -9, -2 ], [ -9, -1 ], [ -9, 0 ], [ -8, -4 ], [ -8, -3 ], [ -8, -2 ], [ -8, -1 ], [ -8, 0 ], [ -7, -4 ], [ -7, -3 ], [ -7, -2 ], [ -7, -1 ], [ -7, 0 ], [ -6, -4 ], [ -6, -3 ], [ -6, -2 ], [ -6, -1 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -2, -5 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -1, -5 ], [ -1, -4 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ 0, -5 ], [ 0, -4 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -2 ], [ 1, -1 ], [ 2, -4 ], [ 2, -3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ 1, -3 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -15 ], [ 2, -14 ], [ 2, -13 ], [ 2, -12 ], [ 2, -11 ], [ 2, -10 ], [ 2, -9 ], [ 2, -8 ], [ 2, -7 ], [ 2, -6 ], [ 2, -5 ], [ 2, -4 ], [ 2, -3 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -26 ], [ 3, -25 ], [ 3, -24 ], [ 3, -23 ], [ 3, -22 ], [ 3, -21 ], [ 3, -20 ], [ 3, -19 ], [ 3, -18 ], [ 3, -17 ], [ 3, -16 ], [ 3, -15 ], [ 3, -14 ], [ 3, -13 ], [ 3, -12 ], [ 3, -11 ], [ 3, -10 ], [ 3, -9 ], [ 3, -8 ], [ 3, -7 ], [ 3, -6 ], [ 3, -5 ], [ 3, -4 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -27 ], [ 4, -26 ], [ 4, -25 ], [ 4, -24 ], [ 4, -23 ], [ 4, -22 ], [ 4, -21 ], [ 4, -20 ], [ 4, -19 ], [ 4, -18 ], [ 4, -17 ], [ 4, -16 ], [ 4, -15 ], [ 4, -14 ], [ 4, -13 ], [ 4, -12 ], [ 4, -11 ], [ 4, -10 ], [ 4, -9 ], [ 4, -8 ], [ 4, -7 ], [ 4, -6 ], [ 4, -5 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -27 ], [ 5, -26 ], [ 5, -25 ], [ 5, -24 ], [ 5, -23 ], [ 5, -22 ], [ 5, -21 ], [ 5, -20 ], [ 5, -19 ], [ 5, -18 ], [ 5, -17 ], [ 5, -16 ], [ 5, -15 ], [ 5, -14 ], [ 5, -13 ], [ 5, -12 ], [ 5, -11 ], [ 5, -10 ], [ 5, -9 ], [ 5, -8 ], [ 5, -7 ], [ 5, -6 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -26 ], [ 6, -25 ], [ 6, -24 ], [ 6, -23 ], [ 6, -22 ], [ 6, -21 ], [ 6, -20 ], [ 6, -19 ], [ 6, -18 ], [ 6, -17 ], [ 6, -16 ], [ 6, -15 ], [ 6, -14 ], [ 6, -13 ], [ 6, -12 ], [ 6, -11 ], [ 6, -10 ], [ 7, -26 ], [ 7, -25 ], [ 7, -24 ], [ 7, -23 ], [ 7, -22 ] ], "width": 3, "covered": false, "rise": 0 }, { "body": [ [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 23, 2 ], [ 23, 3 ] ], "width": 3, "covered": true, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 23, 23, [ "building", "habitable", "composite" ] ], [ 0, 0, [ "building", "habitable", "composite" ] ], [ 51, 0, [ "building", "habitable", "composite" ] ], [ 48, 51, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 2, "west", false, 3 ], [ 0, "north", 1, "south", true, 3 ], [ 0, "south", 3, "street", true, 3 ] ] } ], "legacy": [ { "rooms": [ [ 0, 0, 0, "room.living", [ "north" ], true, [ -1, 0, -1, 9, 6, 9 ] ], [ 0, 6, 0, "room.bedroom", [], false, [ -1, 0, -1, 9, 6, 9 ] ] ], "roofs": [ [ "z", 9, true, 206 ] ], "porch": true, "bay": 9 } ] }, "contact_signature": "3f42fd36b33ee57fc0cdfb01ad4d9a1fdb930e9289d8144adba4af9b554f8bd9", "contact_cells": 142, "contact_replacements": 266, "sitework_occupied_cells": 1394, "excavated_solid_cells": 0, "furnishing_bays": 9, "omitted_optional_furnishing_bays": 0, "seconds": 2.9934 }
campus-2validated{"program": "campus", "structure_seed": 2, "environment_seed": 2, "frozen_digest": "b4a5cfece31dabd3a5c906942b6c466c8652fae8b8b942c315bdeeb75a05bac7"}135681445113.3908b3f476c61f53a5cb
记录 / 诊断
{ "label": "campus-2", "inputs": { "program": "campus", "structure_seed": 2, "environment_seed": 2, "frozen_digest": "b4a5cfece31dabd3a5c906942b6c466c8652fae8b8b942c315bdeeb75a05bac7" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 135681, "instances": 445, "digest": "f0013fc51f4593a014e444274692d640bf5f05a0b6e7e9f4dae61d1721e42e6c", "principal_signature": "b3f476c61f53a5cb2e11c503abbca402f786fe4df81cd116943d73fffd6e8c55", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "library", "entrances": [ "east" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "library", "entrances": [ "north", "east", "south", "west" ], "roof_run": 2, "lantern": true }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "kitchen", "entrances": [ "west", "south" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ -27, 0 ], [ -27, 1 ], [ -26, -2 ], [ -26, -1 ], [ -26, 0 ], [ -26, 1 ], [ -26, 2 ], [ -25, -2 ], [ -25, -1 ], [ -25, 0 ], [ -25, 1 ], [ -25, 2 ], [ -24, -2 ], [ -24, -1 ], [ -24, 0 ], [ -24, 1 ], [ -24, 2 ], [ -23, -2 ], [ -23, -1 ], [ -23, 0 ], [ -23, 1 ], [ -23, 2 ], [ -22, -2 ], [ -22, -1 ], [ -22, 0 ], [ -22, 1 ], [ -21, -2 ], [ -21, -1 ], [ -21, 0 ], [ -21, 1 ], [ -20, -2 ], [ -20, -1 ], [ -20, 0 ], [ -20, 1 ], [ -19, -2 ], [ -19, -1 ], [ -19, 0 ], [ -19, 1 ], [ -18, -3 ], [ -18, -2 ], [ -18, -1 ], [ -18, 0 ], [ -18, 1 ], [ -17, -3 ], [ -17, -2 ], [ -17, -1 ], [ -17, 0 ], [ -17, 1 ], [ -16, -3 ], [ -16, -2 ], [ -16, -1 ], [ -16, 0 ], [ -16, 1 ], [ -15, -3 ], [ -15, -2 ], [ -15, -1 ], [ -15, 0 ], [ -15, 1 ], [ -14, -3 ], [ -14, -2 ], [ -14, -1 ], [ -14, 0 ], [ -13, -3 ], [ -13, -2 ], [ -13, -1 ], [ -13, 0 ], [ -12, -3 ], [ -12, -2 ], [ -12, -1 ], [ -12, 0 ], [ -11, -3 ], [ -11, -2 ], [ -11, -1 ], [ -11, 0 ], [ -10, -4 ], [ -10, -3 ], [ -10, -2 ], [ -10, -1 ], [ -10, 0 ], [ -9, -4 ], [ -9, -3 ], [ -9, -2 ], [ -9, -1 ], [ -9, 0 ], [ -8, -4 ], [ -8, -3 ], [ -8, -2 ], [ -8, -1 ], [ -8, 0 ], [ -7, -4 ], [ -7, -3 ], [ -7, -2 ], [ -7, -1 ], [ -7, 0 ], [ -6, -4 ], [ -6, -3 ], [ -6, -2 ], [ -6, -1 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -2, -5 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -1, -5 ], [ -1, -4 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ 0, -5 ], [ 0, -4 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -2 ], [ 1, -1 ], [ 2, -4 ], [ 2, -3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ 1, -6 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -26 ], [ 2, -25 ], [ 2, -24 ], [ 2, -23 ], [ 2, -22 ], [ 2, -21 ], [ 2, -20 ], [ 2, -19 ], [ 2, -18 ], [ 2, -17 ], [ 2, -16 ], [ 2, -15 ], [ 2, -14 ], [ 2, -13 ], [ 2, -12 ], [ 2, -11 ], [ 2, -10 ], [ 2, -9 ], [ 2, -8 ], [ 2, -7 ], [ 2, -6 ], [ 2, -5 ], [ 2, -4 ], [ 2, -3 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -27 ], [ 3, -26 ], [ 3, -25 ], [ 3, -24 ], [ 3, -23 ], [ 3, -22 ], [ 3, -21 ], [ 3, -20 ], [ 3, -19 ], [ 3, -18 ], [ 3, -17 ], [ 3, -16 ], [ 3, -15 ], [ 3, -14 ], [ 3, -13 ], [ 3, -12 ], [ 3, -11 ], [ 3, -10 ], [ 3, -9 ], [ 3, -8 ], [ 3, -7 ], [ 3, -6 ], [ 3, -5 ], [ 3, -4 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -27 ], [ 4, -26 ], [ 4, -25 ], [ 4, -24 ], [ 4, -23 ], [ 4, -22 ], [ 4, -21 ], [ 4, -20 ], [ 4, -19 ], [ 4, -18 ], [ 4, -17 ], [ 4, -16 ], [ 4, -15 ], [ 4, -14 ], [ 4, -13 ], [ 4, -12 ], [ 4, -11 ], [ 4, -10 ], [ 4, -9 ], [ 4, -8 ], [ 4, -7 ], [ 4, -6 ], [ 4, -5 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -26 ], [ 5, -25 ], [ 5, -24 ], [ 5, -23 ], [ 5, -22 ], [ 5, -21 ], [ 5, -20 ], [ 5, -19 ], [ 5, -18 ], [ 5, -17 ], [ 5, -16 ], [ 5, -15 ], [ 5, -14 ], [ 5, -13 ], [ 5, -12 ], [ 5, -11 ], [ 5, -10 ], [ 5, -9 ], [ 5, -8 ], [ 5, -7 ], [ 5, -6 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -26 ], [ 6, -25 ], [ 6, -24 ], [ 6, -23 ], [ 6, -22 ], [ 6, -21 ], [ 6, -20 ], [ 6, -19 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 23, 2 ], [ 23, 3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -6, 20 ], [ -6, 21 ], [ -6, 22 ], [ -6, 23 ], [ -6, 24 ], [ -6, 25 ], [ -6, 26 ], [ -6, 27 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -5, 2 ], [ -5, 3 ], [ -5, 4 ], [ -5, 5 ], [ -5, 6 ], [ -5, 7 ], [ -5, 8 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -5, 17 ], [ -5, 18 ], [ -5, 19 ], [ -5, 20 ], [ -5, 21 ], [ -5, 22 ], [ -5, 23 ], [ -5, 24 ], [ -5, 25 ], [ -5, 26 ], [ -5, 27 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -4, 3 ], [ -4, 4 ], [ -4, 5 ], [ -4, 6 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -4, 15 ], [ -4, 16 ], [ -4, 17 ], [ -4, 18 ], [ -4, 19 ], [ -4, 20 ], [ -4, 21 ], [ -4, 22 ], [ -4, 23 ], [ -4, 24 ], [ -4, 25 ], [ -4, 26 ], [ -4, 27 ], [ -4, 28 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -3, 3 ], [ -3, 4 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -3, 13 ], [ -3, 14 ], [ -3, 15 ], [ -3, 16 ], [ -3, 17 ], [ -3, 18 ], [ -3, 19 ], [ -3, 20 ], [ -3, 21 ], [ -3, 22 ], [ -3, 23 ], [ -3, 24 ], [ -3, 25 ], [ -3, 26 ], [ -3, 27 ], [ -3, 28 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -2, 12 ], [ -2, 13 ], [ -2, 14 ], [ -2, 15 ], [ -2, 16 ], [ -2, 17 ], [ -2, 18 ], [ -2, 19 ], [ -2, 20 ], [ -2, 21 ], [ -2, 22 ], [ -2, 23 ], [ -2, 24 ], [ -2, 25 ], [ -2, 26 ], [ -2, 27 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ] ], "width": 3, "covered": false, "rise": 1 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 23, 23, [ "building", "habitable", "composite" ] ], [ 0, 0, [ "building", "habitable", "composite" ] ], [ 51, 0, [ "building", "habitable", "composite" ] ], [ 48, 51, [ "building", "habitable", "composite" ] ], [ 0, 51, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 2, "west", false, 3 ], [ 0, "north", 1, "south", true, 3 ], [ 0, "south", 3, "street", true, 3 ], [ 0, "west", 4, "east", false, 3 ] ] } ], "legacy": [ { "rooms": [ [ 0, 0, 0, "room.living", [ "north" ], true, [ -1, 0, -1, 9, 6, 9 ] ], [ 0, 6, 0, "room.bedroom", [], false, [ -1, 0, -1, 9, 6, 9 ] ] ], "roofs": [ [ "z", 9, true, 206 ] ], "porch": true, "bay": 9 } ] }, "contact_signature": "51105a5b68d8ec0e3cef92d63841505771ed41c176e2a19b5dc6c4b6b4c4a3ca", "contact_cells": 206, "contact_replacements": 305, "sitework_occupied_cells": 1593, "excavated_solid_cells": 0, "furnishing_bays": 12, "omitted_optional_furnishing_bays": 0, "seconds": 3.3908 }
campus-3validated{"program": "campus", "structure_seed": 3, "environment_seed": 3, "frozen_digest": "f395c726e571771b586a1126621b72b0a3f8ee2e213dcc58e137e196dd4a0cd6"}140804481117.15463e7cc9eb351fabde
记录 / 诊断
{ "label": "campus-3", "inputs": { "program": "campus", "structure_seed": 3, "environment_seed": 3, "frozen_digest": "f395c726e571771b586a1126621b72b0a3f8ee2e213dcc58e137e196dd4a0cd6" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 140804, "instances": 481, "digest": "08bd8998f146ed84a9611d14a2879c638447d57fd04b623e0385b8a2955e8acc", "principal_signature": "3e7cc9eb351fabded0e49ab462db6cb3677d251b9df4805b7d2ba8ec039c1e50", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "library", "entrances": [ "north", "east", "south", "west" ], "roof_run": 2, "lantern": true }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 6, "function": "kitchen", "entrances": [ "west", "south" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ -27, 0 ], [ -27, 1 ], [ -26, -2 ], [ -26, -1 ], [ -26, 0 ], [ -26, 1 ], [ -26, 2 ], [ -25, -2 ], [ -25, -1 ], [ -25, 0 ], [ -25, 1 ], [ -25, 2 ], [ -24, -2 ], [ -24, -1 ], [ -24, 0 ], [ -24, 1 ], [ -24, 2 ], [ -23, -2 ], [ -23, -1 ], [ -23, 0 ], [ -23, 1 ], [ -23, 2 ], [ -22, -2 ], [ -22, -1 ], [ -22, 0 ], [ -22, 1 ], [ -21, -2 ], [ -21, -1 ], [ -21, 0 ], [ -21, 1 ], [ -20, -2 ], [ -20, -1 ], [ -20, 0 ], [ -20, 1 ], [ -19, -2 ], [ -19, -1 ], [ -19, 0 ], [ -19, 1 ], [ -18, -3 ], [ -18, -2 ], [ -18, -1 ], [ -18, 0 ], [ -18, 1 ], [ -17, -3 ], [ -17, -2 ], [ -17, -1 ], [ -17, 0 ], [ -17, 1 ], [ -16, -3 ], [ -16, -2 ], [ -16, -1 ], [ -16, 0 ], [ -16, 1 ], [ -15, -3 ], [ -15, -2 ], [ -15, -1 ], [ -15, 0 ], [ -15, 1 ], [ -14, -3 ], [ -14, -2 ], [ -14, -1 ], [ -14, 0 ], [ -13, -3 ], [ -13, -2 ], [ -13, -1 ], [ -13, 0 ], [ -12, -3 ], [ -12, -2 ], [ -12, -1 ], [ -12, 0 ], [ -11, -3 ], [ -11, -2 ], [ -11, -1 ], [ -11, 0 ], [ -10, -4 ], [ -10, -3 ], [ -10, -2 ], [ -10, -1 ], [ -10, 0 ], [ -9, -4 ], [ -9, -3 ], [ -9, -2 ], [ -9, -1 ], [ -9, 0 ], [ -8, -4 ], [ -8, -3 ], [ -8, -2 ], [ -8, -1 ], [ -8, 0 ], [ -7, -4 ], [ -7, -3 ], [ -7, -2 ], [ -7, -1 ], [ -7, 0 ], [ -6, -4 ], [ -6, -3 ], [ -6, -2 ], [ -6, -1 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -2, -5 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -1, -5 ], [ -1, -4 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ 0, -5 ], [ 0, -4 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -2 ], [ 1, -1 ], [ 2, -4 ], [ 2, -3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ 1, -3 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -15 ], [ 2, -14 ], [ 2, -13 ], [ 2, -12 ], [ 2, -11 ], [ 2, -10 ], [ 2, -9 ], [ 2, -8 ], [ 2, -7 ], [ 2, -6 ], [ 2, -5 ], [ 2, -4 ], [ 2, -3 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -26 ], [ 3, -25 ], [ 3, -24 ], [ 3, -23 ], [ 3, -22 ], [ 3, -21 ], [ 3, -20 ], [ 3, -19 ], [ 3, -18 ], [ 3, -17 ], [ 3, -16 ], [ 3, -15 ], [ 3, -14 ], [ 3, -13 ], [ 3, -12 ], [ 3, -11 ], [ 3, -10 ], [ 3, -9 ], [ 3, -8 ], [ 3, -7 ], [ 3, -6 ], [ 3, -5 ], [ 3, -4 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -27 ], [ 4, -26 ], [ 4, -25 ], [ 4, -24 ], [ 4, -23 ], [ 4, -22 ], [ 4, -21 ], [ 4, -20 ], [ 4, -19 ], [ 4, -18 ], [ 4, -17 ], [ 4, -16 ], [ 4, -15 ], [ 4, -14 ], [ 4, -13 ], [ 4, -12 ], [ 4, -11 ], [ 4, -10 ], [ 4, -9 ], [ 4, -8 ], [ 4, -7 ], [ 4, -6 ], [ 4, -5 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -27 ], [ 5, -26 ], [ 5, -25 ], [ 5, -24 ], [ 5, -23 ], [ 5, -22 ], [ 5, -21 ], [ 5, -20 ], [ 5, -19 ], [ 5, -18 ], [ 5, -17 ], [ 5, -16 ], [ 5, -15 ], [ 5, -14 ], [ 5, -13 ], [ 5, -12 ], [ 5, -11 ], [ 5, -10 ], [ 5, -9 ], [ 5, -8 ], [ 5, -7 ], [ 5, -6 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -26 ], [ 6, -25 ], [ 6, -24 ], [ 6, -23 ], [ 6, -22 ], [ 6, -21 ], [ 6, -20 ], [ 6, -19 ], [ 6, -18 ], [ 6, -17 ], [ 6, -16 ], [ 6, -15 ], [ 6, -14 ], [ 6, -13 ], [ 6, -12 ], [ 6, -11 ], [ 6, -10 ], [ 7, -26 ], [ 7, -25 ], [ 7, -24 ], [ 7, -23 ], [ 7, -22 ] ], "width": 3, "covered": false, "rise": 0 }, { "body": [ [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 19, 0 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 20, 0 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 21, 0 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 22, 0 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 23, 1 ], [ 23, 2 ] ], "width": 3, "covered": true, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 23, 23, [ "building", "habitable", "composite" ] ], [ 0, 0, [ "building", "habitable", "composite" ] ], [ 51, 0, [ "building", "habitable", "composite" ] ], [ 48, 51, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 2, "west", false, 3 ], [ 0, "north", 1, "south", true, 3 ], [ 0, "south", 3, "street", true, 3 ] ] } ], "legacy": [ { "rooms": [ [ 0, 0, 0, "room.living", [ "north", "south" ], true, [ -1, 0, -1, 9, 6, 8 ] ], [ 0, 6, 0, "room.bedroom", [], false, [ -1, 0, -1, 9, 6, 9 ] ], [ 0, 0, 9, "room.storage", [ "north" ], false, [ -1, 0, 0, 9, 6, 9 ] ] ], "roofs": [ [ "z", 9, true, 185 ], [ "z", 9, true, 202 ] ], "porch": true, "bay": 9 } ] }, "contact_signature": "2c65d4264fb5680a19f579075b7917a82705679900c5589e544cf5a4a63ac080", "contact_cells": 132, "contact_replacements": 318, "sitework_occupied_cells": 1374, "excavated_solid_cells": 0, "furnishing_bays": 9, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/campus-3.litematic", "seconds": 7.1546 }
campus-4validated{"program": "campus", "structure_seed": 4, "environment_seed": 4, "frozen_digest": "4381e277f3b7f18711470ebbecf0297994c6a02ca8f7f44867a8b1d786c60e91"}120401455112.9845b1941ea089972d0c
记录 / 诊断
{ "label": "campus-4", "inputs": { "program": "campus", "structure_seed": 4, "environment_seed": 4, "frozen_digest": "4381e277f3b7f18711470ebbecf0297994c6a02ca8f7f44867a8b1d786c60e91" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 120401, "instances": 455, "digest": "9b6b21676ecc13c02c17eadbdba4845cb029c55df51782dcb5f3e2b92109e76b", "principal_signature": "b1941ea089972d0c0ad6652ec18d3351d485cab682ff996819d1ef22dbcaee0b", "structure": { "halls": [ { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "library", "entrances": [ "north", "east", "south", "west" ], "roof_run": 2, "lantern": true }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "kitchen", "entrances": [ "west", "south" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ -27, -4 ], [ -27, -3 ], [ -26, -6 ], [ -26, -5 ], [ -26, -4 ], [ -26, -3 ], [ -26, -2 ], [ -25, -6 ], [ -25, -5 ], [ -25, -4 ], [ -25, -3 ], [ -25, -2 ], [ -24, -6 ], [ -24, -5 ], [ -24, -4 ], [ -24, -3 ], [ -24, -2 ], [ -23, -6 ], [ -23, -5 ], [ -23, -4 ], [ -23, -3 ], [ -23, -2 ], [ -22, -6 ], [ -22, -5 ], [ -22, -4 ], [ -22, -3 ], [ -22, -2 ], [ -21, -6 ], [ -21, -5 ], [ -21, -4 ], [ -21, -3 ], [ -21, -2 ], [ -20, -6 ], [ -20, -5 ], [ -20, -4 ], [ -20, -3 ], [ -20, -2 ], [ -19, -6 ], [ -19, -5 ], [ -19, -4 ], [ -19, -3 ], [ -19, -2 ], [ -18, -5 ], [ -18, -4 ], [ -18, -3 ], [ -18, -2 ], [ -17, -5 ], [ -17, -4 ], [ -17, -3 ], [ -17, -2 ], [ -16, -5 ], [ -16, -4 ], [ -16, -3 ], [ -16, -2 ], [ -15, -5 ], [ -15, -4 ], [ -15, -3 ], [ -15, -2 ], [ -14, -5 ], [ -14, -4 ], [ -14, -3 ], [ -14, -2 ], [ -13, -5 ], [ -13, -4 ], [ -13, -3 ], [ -13, -2 ], [ -12, -5 ], [ -12, -4 ], [ -12, -3 ], [ -12, -2 ], [ -11, -5 ], [ -11, -4 ], [ -11, -3 ], [ -11, -2 ], [ -10, -5 ], [ -10, -4 ], [ -10, -3 ], [ -10, -2 ], [ -9, -5 ], [ -9, -4 ], [ -9, -3 ], [ -9, -2 ], [ -8, -5 ], [ -8, -4 ], [ -8, -3 ], [ -8, -2 ], [ -7, -5 ], [ -7, -4 ], [ -7, -3 ], [ -7, -2 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -6, -2 ], [ -6, -1 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -2, -5 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -1, -5 ], [ -1, -4 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ 0, -5 ], [ 0, -4 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -2 ], [ 1, -1 ], [ 2, -4 ], [ 2, -3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -10 ], [ 2, -9 ], [ 2, -8 ], [ 2, -7 ], [ 2, -6 ], [ 2, -5 ], [ 2, -4 ], [ 2, -3 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -18 ], [ 3, -17 ], [ 3, -16 ], [ 3, -15 ], [ 3, -14 ], [ 3, -13 ], [ 3, -12 ], [ 3, -11 ], [ 3, -10 ], [ 3, -9 ], [ 3, -8 ], [ 3, -7 ], [ 3, -6 ], [ 3, -5 ], [ 3, -4 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -26 ], [ 4, -25 ], [ 4, -24 ], [ 4, -23 ], [ 4, -22 ], [ 4, -21 ], [ 4, -20 ], [ 4, -19 ], [ 4, -18 ], [ 4, -17 ], [ 4, -16 ], [ 4, -15 ], [ 4, -14 ], [ 4, -13 ], [ 4, -12 ], [ 4, -11 ], [ 4, -10 ], [ 4, -9 ], [ 4, -8 ], [ 4, -7 ], [ 4, -6 ], [ 4, -5 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -27 ], [ 5, -26 ], [ 5, -25 ], [ 5, -24 ], [ 5, -23 ], [ 5, -22 ], [ 5, -21 ], [ 5, -20 ], [ 5, -19 ], [ 5, -18 ], [ 5, -17 ], [ 5, -16 ], [ 5, -15 ], [ 5, -14 ], [ 5, -13 ], [ 5, -12 ], [ 5, -11 ], [ 5, -10 ], [ 5, -9 ], [ 5, -8 ], [ 5, -7 ], [ 5, -6 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -27 ], [ 6, -26 ], [ 6, -25 ], [ 6, -24 ], [ 6, -23 ], [ 6, -22 ], [ 6, -21 ], [ 6, -20 ], [ 6, -19 ], [ 6, -18 ], [ 6, -17 ], [ 6, -16 ], [ 6, -15 ], [ 6, -14 ], [ 6, -13 ], [ 6, -12 ], [ 6, -11 ], [ 6, -10 ], [ 6, -9 ], [ 6, -8 ], [ 6, -7 ], [ 7, -26 ], [ 7, -25 ], [ 7, -24 ], [ 7, -23 ], [ 7, -22 ], [ 7, -21 ], [ 7, -20 ], [ 7, -19 ], [ 7, -18 ], [ 7, -17 ], [ 7, -16 ], [ 7, -15 ], [ 8, -26 ], [ 8, -25 ], [ 8, -24 ], [ 8, -23 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 23, 2 ], [ 23, 3 ] ], "width": 3, "covered": true, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 23, 23, [ "building", "habitable", "composite" ] ], [ 0, 0, [ "building", "habitable", "composite" ] ], [ 51, 0, [ "building", "habitable", "composite" ] ], [ 48, 51, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 2, "west", false, 3 ], [ 0, "north", 1, "south", true, 3 ], [ 0, "south", 3, "street", true, 3 ] ] } ], "legacy": [ { "rooms": [ [ 0, 0, 0, "room.living", [ "north", "south" ], true, [ -1, 0, -1, 9, 6, 8 ] ], [ 0, 6, 0, "room.bedroom", [], false, [ -1, 0, -1, 9, 6, 9 ] ], [ 0, 0, 9, "room.storage", [ "north" ], false, [ -1, 0, 0, 9, 6, 9 ] ] ], "roofs": [ [ "z", 9, true, 185 ], [ "z", 9, true, 202 ] ], "porch": true, "bay": 9 } ] }, "contact_signature": "e86ac05075887fde8f0f347d8ec2b7a8e9d09d200dcb3dce8a04e0ed8f37c089", "contact_cells": 188, "contact_replacements": 232, "sitework_occupied_cells": 1440, "excavated_solid_cells": 0, "furnishing_bays": 9, "omitted_optional_furnishing_bays": 0, "seconds": 2.9845 }
campus-5validated{"program": "campus", "structure_seed": 5, "environment_seed": 5, "frozen_digest": "bc0d58f7d3fe6423fb60ffaa90eaed8b8778bec0ccab6ff6752268af82911311"}132004433113.292620965234f43f2b80
记录 / 诊断
{ "label": "campus-5", "inputs": { "program": "campus", "structure_seed": 5, "environment_seed": 5, "frozen_digest": "bc0d58f7d3fe6423fb60ffaa90eaed8b8778bec0ccab6ff6752268af82911311" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 132004, "instances": 433, "digest": "be004788f8ba191cc25c76e1a7a9b599bd813332118baed62368c08331bb85c4", "principal_signature": "20965234f43f2b80da94e9422091e4eb4cad751785726407323d90732bc10557", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "library", "entrances": [ "east" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ] ], "height": 6, "function": "library", "entrances": [ "north", "east", "south", "west" ], "roof_run": 2, "lantern": true }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "kitchen", "entrances": [ "west", "south" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 0, 14 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 2, 16 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ -27, 0 ], [ -27, 1 ], [ -26, -2 ], [ -26, -1 ], [ -26, 0 ], [ -26, 1 ], [ -26, 2 ], [ -25, -2 ], [ -25, -1 ], [ -25, 0 ], [ -25, 1 ], [ -25, 2 ], [ -24, -2 ], [ -24, -1 ], [ -24, 0 ], [ -24, 1 ], [ -24, 2 ], [ -23, -2 ], [ -23, -1 ], [ -23, 0 ], [ -23, 1 ], [ -23, 2 ], [ -22, -2 ], [ -22, -1 ], [ -22, 0 ], [ -22, 1 ], [ -21, -2 ], [ -21, -1 ], [ -21, 0 ], [ -21, 1 ], [ -20, -2 ], [ -20, -1 ], [ -20, 0 ], [ -20, 1 ], [ -19, -2 ], [ -19, -1 ], [ -19, 0 ], [ -19, 1 ], [ -18, -3 ], [ -18, -2 ], [ -18, -1 ], [ -18, 0 ], [ -18, 1 ], [ -17, -3 ], [ -17, -2 ], [ -17, -1 ], [ -17, 0 ], [ -17, 1 ], [ -16, -3 ], [ -16, -2 ], [ -16, -1 ], [ -16, 0 ], [ -16, 1 ], [ -15, -3 ], [ -15, -2 ], [ -15, -1 ], [ -15, 0 ], [ -15, 1 ], [ -14, -3 ], [ -14, -2 ], [ -14, -1 ], [ -14, 0 ], [ -13, -3 ], [ -13, -2 ], [ -13, -1 ], [ -13, 0 ], [ -12, -3 ], [ -12, -2 ], [ -12, -1 ], [ -12, 0 ], [ -11, -3 ], [ -11, -2 ], [ -11, -1 ], [ -11, 0 ], [ -10, -4 ], [ -10, -3 ], [ -10, -2 ], [ -10, -1 ], [ -10, 0 ], [ -9, -4 ], [ -9, -3 ], [ -9, -2 ], [ -9, -1 ], [ -9, 0 ], [ -8, -4 ], [ -8, -3 ], [ -8, -2 ], [ -8, -1 ], [ -8, 0 ], [ -7, -4 ], [ -7, -3 ], [ -7, -2 ], [ -7, -1 ], [ -7, 0 ], [ -6, -4 ], [ -6, -3 ], [ -6, -2 ], [ -6, -1 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -2, -5 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -1, -5 ], [ -1, -4 ], [ -1, -3 ], [ -1, -2 ], [ -1, -1 ], [ 0, -5 ], [ 0, -4 ], [ 0, -3 ], [ 0, -2 ], [ 0, -1 ], [ 1, -5 ], [ 1, -4 ], [ 1, -3 ], [ 1, -2 ], [ 1, -1 ], [ 2, -4 ], [ 2, -3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ 1, -3 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -15 ], [ 2, -14 ], [ 2, -13 ], [ 2, -12 ], [ 2, -11 ], [ 2, -10 ], [ 2, -9 ], [ 2, -8 ], [ 2, -7 ], [ 2, -6 ], [ 2, -5 ], [ 2, -4 ], [ 2, -3 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -26 ], [ 3, -25 ], [ 3, -24 ], [ 3, -23 ], [ 3, -22 ], [ 3, -21 ], [ 3, -20 ], [ 3, -19 ], [ 3, -18 ], [ 3, -17 ], [ 3, -16 ], [ 3, -15 ], [ 3, -14 ], [ 3, -13 ], [ 3, -12 ], [ 3, -11 ], [ 3, -10 ], [ 3, -9 ], [ 3, -8 ], [ 3, -7 ], [ 3, -6 ], [ 3, -5 ], [ 3, -4 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -27 ], [ 4, -26 ], [ 4, -25 ], [ 4, -24 ], [ 4, -23 ], [ 4, -22 ], [ 4, -21 ], [ 4, -20 ], [ 4, -19 ], [ 4, -18 ], [ 4, -17 ], [ 4, -16 ], [ 4, -15 ], [ 4, -14 ], [ 4, -13 ], [ 4, -12 ], [ 4, -11 ], [ 4, -10 ], [ 4, -9 ], [ 4, -8 ], [ 4, -7 ], [ 4, -6 ], [ 4, -5 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -27 ], [ 5, -26 ], [ 5, -25 ], [ 5, -24 ], [ 5, -23 ], [ 5, -22 ], [ 5, -21 ], [ 5, -20 ], [ 5, -19 ], [ 5, -18 ], [ 5, -17 ], [ 5, -16 ], [ 5, -15 ], [ 5, -14 ], [ 5, -13 ], [ 5, -12 ], [ 5, -11 ], [ 5, -10 ], [ 5, -9 ], [ 5, -8 ], [ 5, -7 ], [ 5, -6 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -26 ], [ 6, -25 ], [ 6, -24 ], [ 6, -23 ], [ 6, -22 ], [ 6, -21 ], [ 6, -20 ], [ 6, -19 ], [ 6, -18 ], [ 6, -17 ], [ 6, -16 ], [ 6, -15 ], [ 6, -14 ], [ 6, -13 ], [ 6, -12 ], [ 6, -11 ], [ 6, -10 ], [ 7, -26 ], [ 7, -25 ], [ 7, -24 ], [ 7, -23 ], [ 7, -22 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 23, 2 ], [ 23, 3 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -7, 23 ], [ -7, 24 ], [ -7, 25 ], [ -7, 26 ], [ -7, 27 ], [ -6, 10 ], [ -6, 11 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -6, 17 ], [ -6, 18 ], [ -6, 19 ], [ -6, 20 ], [ -6, 21 ], [ -6, 22 ], [ -6, 23 ], [ -6, 24 ], [ -6, 25 ], [ -6, 26 ], [ -6, 27 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -5, 2 ], [ -5, 3 ], [ -5, 4 ], [ -5, 5 ], [ -5, 6 ], [ -5, 7 ], [ -5, 8 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -5, 17 ], [ -5, 18 ], [ -5, 19 ], [ -5, 20 ], [ -5, 21 ], [ -5, 22 ], [ -5, 23 ], [ -5, 24 ], [ -5, 25 ], [ -5, 26 ], [ -5, 27 ], [ -5, 28 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -4, 3 ], [ -4, 4 ], [ -4, 5 ], [ -4, 6 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -4, 15 ], [ -4, 16 ], [ -4, 17 ], [ -4, 18 ], [ -4, 19 ], [ -4, 20 ], [ -4, 21 ], [ -4, 22 ], [ -4, 23 ], [ -4, 24 ], [ -4, 25 ], [ -4, 26 ], [ -4, 27 ], [ -4, 28 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -3, 3 ], [ -3, 4 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -3, 13 ], [ -3, 14 ], [ -3, 15 ], [ -3, 16 ], [ -3, 17 ], [ -3, 18 ], [ -3, 19 ], [ -3, 20 ], [ -3, 21 ], [ -3, 22 ], [ -3, 23 ], [ -3, 24 ], [ -3, 25 ], [ -3, 26 ], [ -3, 27 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -2, 12 ], [ -2, 13 ], [ -2, 14 ], [ -2, 15 ], [ -2, 16 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ], [ -1, 3 ] ], "width": 3, "covered": false, "rise": 1 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 23, 23, [ "building", "habitable", "composite" ] ], [ 0, 0, [ "building", "habitable", "composite" ] ], [ 51, 0, [ "building", "habitable", "composite" ] ], [ 48, 51, [ "building", "habitable", "composite" ] ], [ 0, 51, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 2, "west", false, 3 ], [ 0, "north", 1, "south", true, 3 ], [ 0, "south", 3, "street", true, 3 ], [ 0, "west", 4, "east", false, 3 ] ] } ], "legacy": [ { "rooms": [ [ 0, 0, 0, "room.living", [ "north" ], true, [ -1, 0, -1, 9, 6, 9 ] ], [ 0, 6, 0, "room.bedroom", [], false, [ -1, 0, -1, 9, 6, 9 ] ] ], "roofs": [ [ "z", 9, true, 206 ] ], "porch": true, "bay": 9 } ] }, "contact_signature": "5840147396f8a10233584cdd97528cd794743d3fbb544c1c60151f56b11b9b32", "contact_cells": 178, "contact_replacements": 268, "sitework_occupied_cells": 1566, "excavated_solid_cells": 0, "furnishing_bays": 11, "omitted_optional_furnishing_bays": 0, "seconds": 3.2926 }
perimeter-0validated{"program": "perimeter", "structure_seed": 0, "environment_seed": 0, "frozen_digest": "c9de4c706492cbfd134b98f19fcc1538bc8367c20302347208851f705b1f1093"}118811381116.2366f3a699cf9668e9f3
记录 / 诊断
{ "label": "perimeter-0", "inputs": { "program": "perimeter", "structure_seed": 0, "environment_seed": 0, "frozen_digest": "c9de4c706492cbfd134b98f19fcc1538bc8367c20302347208851f705b1f1093" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 118811, "instances": 381, "digest": "22887c97876a46d4f89083ba0fb12dec9c81f034b5cc6835fb559d7a377cabf4", "principal_signature": "f3a699cf9668e9f3ce9e696e21659aea24e6b26d987b7dd967fd5245c594e982", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "living", "entrances": [ "east", "west" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 19, 0 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 19, 12 ], [ 20, 0 ], [ 20, 1 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ], [ 20, 11 ], [ 20, 12 ], [ 21, 0 ], [ 21, 1 ], [ 21, 2 ], [ 21, 3 ], [ 21, 4 ], [ 21, 5 ], [ 21, 6 ], [ 21, 7 ], [ 21, 8 ], [ 21, 9 ], [ 21, 10 ], [ 21, 11 ], [ 21, 12 ], [ 22, 0 ], [ 22, 1 ], [ 22, 2 ], [ 22, 3 ], [ 22, 4 ], [ 22, 5 ], [ 22, 6 ], [ 22, 7 ], [ 22, 8 ], [ 22, 9 ], [ 22, 10 ], [ 22, 11 ], [ 22, 12 ], [ 23, 1 ], [ 23, 2 ], [ 23, 3 ], [ 23, 4 ], [ 23, 5 ], [ 23, 6 ], [ 23, 7 ], [ 23, 8 ], [ 23, 9 ], [ 23, 10 ], [ 23, 11 ], [ 24, 2 ], [ 24, 3 ], [ 24, 4 ], [ 24, 5 ], [ 24, 6 ], [ 24, 7 ], [ 24, 8 ], [ 24, 9 ], [ 24, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "east", "south" ], "roof_run": 3, "lantern": false }, { "footprint": [ [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ] ], "height": 6, "function": "library", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": true } ], "links": [ { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -2 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -3 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -4 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -5 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -6 ], [ 6, -5 ], [ 6, -4 ], [ 6, -3 ], [ 6, -2 ], [ 6, -1 ], [ 6, 0 ], [ 7, -7 ], [ 7, -6 ], [ 7, -5 ], [ 7, -4 ], [ 7, -3 ], [ 7, -2 ], [ 8, -8 ], [ 8, -7 ], [ 8, -6 ], [ 8, -5 ], [ 8, -4 ], [ 8, -3 ], [ 9, -9 ], [ 9, -8 ], [ 9, -7 ], [ 9, -6 ], [ 9, -5 ], [ 9, -4 ], [ 10, -11 ], [ 10, -10 ], [ 10, -9 ], [ 10, -8 ], [ 10, -7 ], [ 10, -6 ], [ 10, -5 ], [ 11, -12 ], [ 11, -11 ], [ 11, -10 ], [ 11, -9 ], [ 11, -8 ], [ 11, -7 ], [ 11, -6 ], [ 12, -13 ], [ 12, -12 ], [ 12, -11 ], [ 12, -10 ], [ 12, -9 ], [ 12, -8 ], [ 12, -7 ], [ 13, -13 ], [ 13, -12 ], [ 13, -11 ], [ 13, -10 ], [ 13, -9 ], [ 13, -8 ], [ 14, -13 ], [ 14, -12 ], [ 14, -11 ], [ 14, -10 ], [ 14, -9 ], [ 14, -8 ], [ 15, -12 ], [ 15, -11 ], [ 15, -10 ], [ 15, -9 ], [ 15, -8 ], [ 16, -11 ], [ 16, -10 ], [ 16, -9 ], [ 16, -8 ], [ 16, -7 ], [ 17, -11 ], [ 17, -10 ], [ 17, -9 ], [ 17, -8 ], [ 17, -7 ], [ 17, -6 ], [ 18, -10 ], [ 18, -9 ], [ 18, -8 ], [ 18, -7 ], [ 18, -6 ], [ 19, -9 ], [ 19, -8 ], [ 19, -7 ], [ 19, -6 ], [ 19, -5 ], [ 20, -9 ], [ 20, -8 ], [ 20, -7 ], [ 20, -6 ], [ 20, -5 ], [ 20, -4 ], [ 21, -8 ], [ 21, -7 ], [ 21, -6 ], [ 21, -5 ], [ 21, -4 ], [ 22, -8 ], [ 22, -7 ], [ 22, -6 ], [ 22, -5 ], [ 22, -4 ], [ 22, -3 ], [ 23, -7 ], [ 23, -6 ], [ 23, -5 ], [ 23, -4 ], [ 23, -3 ], [ 24, -6 ], [ 24, -5 ], [ 24, -4 ], [ 24, -3 ], [ 24, -2 ], [ 25, -6 ], [ 25, -5 ], [ 25, -4 ], [ 25, -3 ], [ 25, -2 ], [ 25, -1 ], [ 26, -5 ], [ 26, -4 ], [ 26, -3 ], [ 26, -2 ], [ 26, -1 ], [ 27, -4 ], [ 27, -3 ], [ 27, -2 ], [ 27, -1 ], [ 27, 0 ], [ 28, -4 ], [ 28, -3 ], [ 28, -2 ], [ 28, -1 ], [ 28, 0 ], [ 28, 1 ], [ 29, -3 ], [ 29, -2 ], [ 29, -1 ], [ 29, 0 ], [ 29, 1 ], [ 30, -3 ], [ 30, -2 ], [ 30, -1 ], [ 30, 0 ], [ 30, 1 ], [ 31, -2 ], [ 31, -1 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -20, 34 ], [ -20, 35 ], [ -20, 36 ], [ -19, 33 ], [ -19, 34 ], [ -19, 35 ], [ -19, 36 ], [ -18, 31 ], [ -18, 32 ], [ -18, 33 ], [ -18, 34 ], [ -18, 35 ], [ -18, 36 ], [ -18, 37 ], [ -17, 29 ], [ -17, 30 ], [ -17, 31 ], [ -17, 32 ], [ -17, 33 ], [ -17, 34 ], [ -17, 35 ], [ -17, 36 ], [ -17, 37 ], [ -16, 27 ], [ -16, 28 ], [ -16, 29 ], [ -16, 30 ], [ -16, 31 ], [ -16, 32 ], [ -16, 33 ], [ -16, 34 ], [ -16, 35 ], [ -16, 36 ], [ -15, 26 ], [ -15, 27 ], [ -15, 28 ], [ -15, 29 ], [ -15, 30 ], [ -15, 31 ], [ -15, 32 ], [ -15, 33 ], [ -15, 34 ], [ -14, 24 ], [ -14, 25 ], [ -14, 26 ], [ -14, 27 ], [ -14, 28 ], [ -14, 29 ], [ -14, 30 ], [ -14, 31 ], [ -14, 32 ], [ -13, 22 ], [ -13, 23 ], [ -13, 24 ], [ -13, 25 ], [ -13, 26 ], [ -13, 27 ], [ -13, 28 ], [ -13, 29 ], [ -13, 30 ], [ -12, 20 ], [ -12, 21 ], [ -12, 22 ], [ -12, 23 ], [ -12, 24 ], [ -12, 25 ], [ -12, 26 ], [ -12, 27 ], [ -12, 28 ], [ -11, 18 ], [ -11, 19 ], [ -11, 20 ], [ -11, 21 ], [ -11, 22 ], [ -11, 23 ], [ -11, 24 ], [ -11, 25 ], [ -11, 26 ], [ -11, 27 ], [ -10, 17 ], [ -10, 18 ], [ -10, 19 ], [ -10, 20 ], [ -10, 21 ], [ -10, 22 ], [ -10, 23 ], [ -10, 24 ], [ -10, 25 ], [ -9, 15 ], [ -9, 16 ], [ -9, 17 ], [ -9, 18 ], [ -9, 19 ], [ -9, 20 ], [ -9, 21 ], [ -9, 22 ], [ -9, 23 ], [ -8, 13 ], [ -8, 14 ], [ -8, 15 ], [ -8, 16 ], [ -8, 17 ], [ -8, 18 ], [ -8, 19 ], [ -8, 20 ], [ -8, 21 ], [ -7, 11 ], [ -7, 12 ], [ -7, 13 ], [ -7, 14 ], [ -7, 15 ], [ -7, 16 ], [ -7, 17 ], [ -7, 18 ], [ -7, 19 ], [ -7, 20 ], [ -6, 10 ], [ -6, 11 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -6, 17 ], [ -6, 18 ], [ -5, 8 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -4, 6 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -3, 4 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ -1, 7 ], [ -1, 8 ], [ -1, 9 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 3 ], [ 2, 4 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -11, -23 ], [ -11, -22 ], [ -11, -21 ], [ -11, -20 ], [ -10, -31 ], [ -10, -30 ], [ -10, -29 ], [ -10, -28 ], [ -10, -27 ], [ -10, -26 ], [ -10, -25 ], [ -10, -24 ], [ -10, -23 ], [ -10, -22 ], [ -10, -21 ], [ -10, -20 ], [ -10, -19 ], [ -10, -18 ], [ -10, -17 ], [ -9, -39 ], [ -9, -38 ], [ -9, -37 ], [ -9, -36 ], [ -9, -35 ], [ -9, -34 ], [ -9, -33 ], [ -9, -32 ], [ -9, -31 ], [ -9, -30 ], [ -9, -29 ], [ -9, -28 ], [ -9, -27 ], [ -9, -26 ], [ -9, -25 ], [ -9, -24 ], [ -9, -23 ], [ -9, -22 ], [ -9, -21 ], [ -9, -20 ], [ -9, -19 ], [ -9, -18 ], [ -9, -17 ], [ -9, -16 ], [ -9, -15 ], [ -9, -14 ], [ -9, -13 ], [ -8, -45 ], [ -8, -44 ], [ -8, -43 ], [ -8, -42 ], [ -8, -41 ], [ -8, -40 ], [ -8, -39 ], [ -8, -38 ], [ -8, -37 ], [ -8, -36 ], [ -8, -35 ], [ -8, -34 ], [ -8, -33 ], [ -8, -32 ], [ -8, -31 ], [ -8, -30 ], [ -8, -29 ], [ -8, -28 ], [ -8, -27 ], [ -8, -26 ], [ -8, -25 ], [ -8, -24 ], [ -8, -23 ], [ -8, -22 ], [ -8, -21 ], [ -8, -20 ], [ -8, -19 ], [ -8, -18 ], [ -8, -17 ], [ -8, -16 ], [ -8, -15 ], [ -8, -14 ], [ -8, -13 ], [ -8, -12 ], [ -8, -11 ], [ -8, -10 ], [ -7, -47 ], [ -7, -46 ], [ -7, -45 ], [ -7, -44 ], [ -7, -43 ], [ -7, -42 ], [ -7, -41 ], [ -7, -40 ], [ -7, -39 ], [ -7, -38 ], [ -7, -37 ], [ -7, -36 ], [ -7, -35 ], [ -7, -34 ], [ -7, -33 ], [ -7, -32 ], [ -7, -31 ], [ -7, -30 ], [ -7, -29 ], [ -7, -28 ], [ -7, -27 ], [ -7, -26 ], [ -7, -25 ], [ -7, -24 ], [ -7, -23 ], [ -7, -22 ], [ -7, -21 ], [ -7, -20 ], [ -7, -19 ], [ -7, -18 ], [ -7, -17 ], [ -7, -16 ], [ -7, -15 ], [ -7, -14 ], [ -7, -13 ], [ -7, -12 ], [ -7, -11 ], [ -7, -10 ], [ -7, -9 ], [ -7, -8 ], [ -7, -7 ], [ -7, -6 ], [ -6, -47 ], [ -6, -46 ], [ -6, -45 ], [ -6, -44 ], [ -6, -43 ], [ -6, -42 ], [ -6, -41 ], [ -6, -40 ], [ -6, -39 ], [ -6, -38 ], [ -6, -37 ], [ -6, -36 ], [ -6, -35 ], [ -6, -34 ], [ -6, -33 ], [ -6, -32 ], [ -6, -31 ], [ -6, -30 ], [ -6, -29 ], [ -6, -28 ], [ -6, -27 ], [ -6, -18 ], [ -6, -17 ], [ -6, -16 ], [ -6, -15 ], [ -6, -14 ], [ -6, -13 ], [ -6, -12 ], [ -6, -11 ], [ -6, -10 ], [ -6, -9 ], [ -6, -8 ], [ -6, -7 ], [ -6, -6 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -5, -47 ], [ -5, -46 ], [ -5, -45 ], [ -5, -44 ], [ -5, -43 ], [ -5, -42 ], [ -5, -41 ], [ -5, -40 ], [ -5, -39 ], [ -5, -38 ], [ -5, -37 ], [ -5, -36 ], [ -5, -35 ], [ -5, -15 ], [ -5, -14 ], [ -5, -13 ], [ -5, -12 ], [ -5, -11 ], [ -5, -10 ], [ -5, -9 ], [ -5, -8 ], [ -5, -7 ], [ -5, -6 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -4, -45 ], [ -4, -44 ], [ -4, -43 ], [ -4, -11 ], [ -4, -10 ], [ -4, -9 ], [ -4, -8 ], [ -4, -7 ], [ -4, -6 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -3, -8 ], [ -3, -7 ], [ -3, -6 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ] ], "width": 3, "covered": false, "rise": 1 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 0, 0, [ "building", "habitable", "composite" ] ], [ 50, 10, [ "building", "habitable", "composite" ] ], [ 20, 57, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 1, "north", false, 3 ], [ 1, "south", 2, "east", true, 3 ], [ 2, "west", 0, "south", false, 3 ] ] } ], "legacy": [] }, "contact_signature": "5255043918bf189f60db4e3ac77c40e2acc466d160b568a983fb9604ea89b7ab", "contact_cells": 129, "contact_replacements": 256, "sitework_occupied_cells": 1580, "excavated_solid_cells": 0, "furnishing_bays": 10, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/perimeter-0.litematic", "seconds": 6.2366 }
perimeter-1validated{"program": "perimeter", "structure_seed": 1, "environment_seed": 1, "frozen_digest": "c3a2a25f76b44a187da0c6b563c8b4ae3b363d9944fb83e17c117d0c122e9e29"}129892408112.846360f3a4b9fafdbb7b
记录 / 诊断
{ "label": "perimeter-1", "inputs": { "program": "perimeter", "structure_seed": 1, "environment_seed": 1, "frozen_digest": "c3a2a25f76b44a187da0c6b563c8b4ae3b363d9944fb83e17c117d0c122e9e29" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 129892, "instances": 408, "digest": "0972c3dc195a4c3366fa7915c940a030aa420aaa677700e18e1463e600b70c7c", "principal_signature": "60f3a4b9fafdbb7ba9794ba9b9b996f1f9908a7f2513f0d72942f96a82c36f02", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "living", "entrances": [ "east", "west" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "east", "south" ], "roof_run": 3, "lantern": false }, { "footprint": [ [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ] ], "height": 6, "function": "library", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": true } ], "links": [ { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -4 ], [ 6, -3 ], [ 6, -2 ], [ 6, -1 ], [ 6, 0 ], [ 7, -5 ], [ 7, -4 ], [ 7, -3 ], [ 7, -2 ], [ 7, -1 ], [ 8, -6 ], [ 8, -5 ], [ 8, -4 ], [ 8, -3 ], [ 8, -2 ], [ 8, -1 ], [ 9, -7 ], [ 9, -6 ], [ 9, -5 ], [ 9, -4 ], [ 9, -3 ], [ 9, -2 ], [ 10, -7 ], [ 10, -6 ], [ 10, -5 ], [ 10, -4 ], [ 10, -3 ], [ 11, -8 ], [ 11, -7 ], [ 11, -6 ], [ 11, -5 ], [ 11, -4 ], [ 12, -9 ], [ 12, -8 ], [ 12, -7 ], [ 12, -6 ], [ 12, -5 ], [ 12, -4 ], [ 13, -10 ], [ 13, -9 ], [ 13, -8 ], [ 13, -7 ], [ 13, -6 ], [ 13, -5 ], [ 14, -10 ], [ 14, -9 ], [ 14, -8 ], [ 14, -7 ], [ 14, -6 ], [ 15, -11 ], [ 15, -10 ], [ 15, -9 ], [ 15, -8 ], [ 15, -7 ], [ 16, -12 ], [ 16, -11 ], [ 16, -10 ], [ 16, -9 ], [ 16, -8 ], [ 16, -7 ], [ 17, -13 ], [ 17, -12 ], [ 17, -11 ], [ 17, -10 ], [ 17, -9 ], [ 17, -8 ], [ 18, -13 ], [ 18, -12 ], [ 18, -11 ], [ 18, -10 ], [ 18, -9 ], [ 19, -13 ], [ 19, -12 ], [ 19, -11 ], [ 19, -10 ], [ 19, -9 ], [ 19, -8 ], [ 20, -12 ], [ 20, -11 ], [ 20, -10 ], [ 20, -9 ], [ 20, -8 ], [ 21, -11 ], [ 21, -10 ], [ 21, -9 ], [ 21, -8 ], [ 21, -7 ], [ 22, -11 ], [ 22, -10 ], [ 22, -9 ], [ 22, -8 ], [ 22, -7 ], [ 22, -6 ], [ 23, -10 ], [ 23, -9 ], [ 23, -8 ], [ 23, -7 ], [ 23, -6 ], [ 24, -9 ], [ 24, -8 ], [ 24, -7 ], [ 24, -6 ], [ 24, -5 ], [ 25, -9 ], [ 25, -8 ], [ 25, -7 ], [ 25, -6 ], [ 25, -5 ], [ 25, -4 ], [ 26, -8 ], [ 26, -7 ], [ 26, -6 ], [ 26, -5 ], [ 26, -4 ], [ 27, -8 ], [ 27, -7 ], [ 27, -6 ], [ 27, -5 ], [ 27, -4 ], [ 27, -3 ], [ 28, -7 ], [ 28, -6 ], [ 28, -5 ], [ 28, -4 ], [ 28, -3 ], [ 29, -6 ], [ 29, -5 ], [ 29, -4 ], [ 29, -3 ], [ 29, -2 ], [ 30, -6 ], [ 30, -5 ], [ 30, -4 ], [ 30, -3 ], [ 30, -2 ], [ 30, -1 ], [ 31, -5 ], [ 31, -4 ], [ 31, -3 ], [ 31, -2 ], [ 31, -1 ], [ 32, -4 ], [ 32, -3 ], [ 32, -2 ], [ 32, -1 ], [ 32, 0 ], [ 33, -4 ], [ 33, -3 ], [ 33, -2 ], [ 33, -1 ], [ 33, 0 ], [ 33, 1 ], [ 34, -3 ], [ 34, -2 ], [ 34, -1 ], [ 34, 0 ], [ 34, 1 ], [ 35, -3 ], [ 35, -2 ], [ 35, -1 ], [ 35, 0 ], [ 35, 1 ], [ 36, -2 ], [ 36, -1 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -17, 34 ], [ -17, 35 ], [ -17, 36 ], [ -16, 32 ], [ -16, 33 ], [ -16, 34 ], [ -16, 35 ], [ -16, 36 ], [ -15, 30 ], [ -15, 31 ], [ -15, 32 ], [ -15, 33 ], [ -15, 34 ], [ -15, 35 ], [ -15, 36 ], [ -15, 37 ], [ -14, 28 ], [ -14, 29 ], [ -14, 30 ], [ -14, 31 ], [ -14, 32 ], [ -14, 33 ], [ -14, 34 ], [ -14, 35 ], [ -14, 36 ], [ -14, 37 ], [ -13, 26 ], [ -13, 27 ], [ -13, 28 ], [ -13, 29 ], [ -13, 30 ], [ -13, 31 ], [ -13, 32 ], [ -13, 33 ], [ -13, 34 ], [ -13, 35 ], [ -13, 36 ], [ -12, 24 ], [ -12, 25 ], [ -12, 26 ], [ -12, 27 ], [ -12, 28 ], [ -12, 29 ], [ -12, 30 ], [ -12, 31 ], [ -12, 32 ], [ -12, 33 ], [ -11, 22 ], [ -11, 23 ], [ -11, 24 ], [ -11, 25 ], [ -11, 26 ], [ -11, 27 ], [ -11, 28 ], [ -11, 29 ], [ -11, 30 ], [ -11, 31 ], [ -10, 20 ], [ -10, 21 ], [ -10, 22 ], [ -10, 23 ], [ -10, 24 ], [ -10, 25 ], [ -10, 26 ], [ -10, 27 ], [ -10, 28 ], [ -10, 29 ], [ -9, 17 ], [ -9, 18 ], [ -9, 19 ], [ -9, 20 ], [ -9, 21 ], [ -9, 22 ], [ -9, 23 ], [ -9, 24 ], [ -9, 25 ], [ -9, 26 ], [ -9, 27 ], [ -8, 15 ], [ -8, 16 ], [ -8, 17 ], [ -8, 18 ], [ -8, 19 ], [ -8, 20 ], [ -8, 21 ], [ -8, 22 ], [ -8, 23 ], [ -8, 24 ], [ -8, 25 ], [ -7, 13 ], [ -7, 14 ], [ -7, 15 ], [ -7, 16 ], [ -7, 17 ], [ -7, 18 ], [ -7, 19 ], [ -7, 20 ], [ -7, 21 ], [ -7, 22 ], [ -7, 23 ], [ -6, 11 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -6, 17 ], [ -6, 18 ], [ -6, 19 ], [ -6, 20 ], [ -6, 21 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -5, 17 ], [ -5, 18 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -4, 15 ], [ -4, 16 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -3, 13 ], [ -3, 14 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -2, 12 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ -1, 7 ], [ -1, 8 ], [ -1, 9 ], [ -1, 10 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -11, -27 ], [ -11, -26 ], [ -11, -25 ], [ -11, -24 ], [ -11, -23 ], [ -11, -22 ], [ -11, -21 ], [ -11, -20 ], [ -10, -45 ], [ -10, -44 ], [ -10, -43 ], [ -10, -42 ], [ -10, -41 ], [ -10, -40 ], [ -10, -39 ], [ -10, -38 ], [ -10, -37 ], [ -10, -36 ], [ -10, -35 ], [ -10, -34 ], [ -10, -33 ], [ -10, -32 ], [ -10, -31 ], [ -10, -30 ], [ -10, -29 ], [ -10, -28 ], [ -10, -27 ], [ -10, -26 ], [ -10, -25 ], [ -10, -24 ], [ -10, -23 ], [ -10, -22 ], [ -10, -21 ], [ -10, -20 ], [ -10, -19 ], [ -10, -18 ], [ -10, -17 ], [ -9, -47 ], [ -9, -46 ], [ -9, -45 ], [ -9, -44 ], [ -9, -43 ], [ -9, -42 ], [ -9, -41 ], [ -9, -40 ], [ -9, -39 ], [ -9, -38 ], [ -9, -37 ], [ -9, -36 ], [ -9, -35 ], [ -9, -34 ], [ -9, -33 ], [ -9, -32 ], [ -9, -31 ], [ -9, -30 ], [ -9, -29 ], [ -9, -28 ], [ -9, -27 ], [ -9, -26 ], [ -9, -25 ], [ -9, -24 ], [ -9, -23 ], [ -9, -22 ], [ -9, -21 ], [ -9, -20 ], [ -9, -19 ], [ -9, -18 ], [ -9, -17 ], [ -9, -16 ], [ -9, -15 ], [ -9, -14 ], [ -9, -13 ], [ -8, -47 ], [ -8, -46 ], [ -8, -45 ], [ -8, -44 ], [ -8, -43 ], [ -8, -42 ], [ -8, -41 ], [ -8, -40 ], [ -8, -39 ], [ -8, -38 ], [ -8, -37 ], [ -8, -36 ], [ -8, -35 ], [ -8, -34 ], [ -8, -33 ], [ -8, -32 ], [ -8, -31 ], [ -8, -30 ], [ -8, -29 ], [ -8, -28 ], [ -8, -27 ], [ -8, -26 ], [ -8, -25 ], [ -8, -24 ], [ -8, -23 ], [ -8, -22 ], [ -8, -21 ], [ -8, -20 ], [ -8, -19 ], [ -8, -18 ], [ -8, -17 ], [ -8, -16 ], [ -8, -15 ], [ -8, -14 ], [ -8, -13 ], [ -8, -12 ], [ -8, -11 ], [ -8, -10 ], [ -7, -47 ], [ -7, -46 ], [ -7, -45 ], [ -7, -44 ], [ -7, -43 ], [ -7, -42 ], [ -7, -41 ], [ -7, -40 ], [ -7, -39 ], [ -7, -38 ], [ -7, -37 ], [ -7, -36 ], [ -7, -35 ], [ -7, -34 ], [ -7, -33 ], [ -7, -32 ], [ -7, -31 ], [ -7, -30 ], [ -7, -29 ], [ -7, -28 ], [ -7, -27 ], [ -7, -26 ], [ -7, -25 ], [ -7, -24 ], [ -7, -23 ], [ -7, -22 ], [ -7, -21 ], [ -7, -20 ], [ -7, -19 ], [ -7, -18 ], [ -7, -17 ], [ -7, -16 ], [ -7, -15 ], [ -7, -14 ], [ -7, -13 ], [ -7, -12 ], [ -7, -11 ], [ -7, -10 ], [ -7, -9 ], [ -7, -8 ], [ -7, -7 ], [ -7, -6 ], [ -6, -45 ], [ -6, -44 ], [ -6, -43 ], [ -6, -42 ], [ -6, -41 ], [ -6, -40 ], [ -6, -39 ], [ -6, -18 ], [ -6, -17 ], [ -6, -16 ], [ -6, -15 ], [ -6, -14 ], [ -6, -13 ], [ -6, -12 ], [ -6, -11 ], [ -6, -10 ], [ -6, -9 ], [ -6, -8 ], [ -6, -7 ], [ -6, -6 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -5, -15 ], [ -5, -14 ], [ -5, -13 ], [ -5, -12 ], [ -5, -11 ], [ -5, -10 ], [ -5, -9 ], [ -5, -8 ], [ -5, -7 ], [ -5, -6 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -4, -11 ], [ -4, -10 ], [ -4, -9 ], [ -4, -8 ], [ -4, -7 ], [ -4, -6 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -3, -8 ], [ -3, -7 ], [ -3, -6 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 0, 0, [ "building", "habitable", "composite" ] ], [ 50, 10, [ "building", "habitable", "composite" ] ], [ 20, 57, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 1, "north", false, 3 ], [ 1, "south", 2, "east", true, 3 ], [ 2, "west", 0, "south", false, 3 ] ] } ], "legacy": [] }, "contact_signature": "63191d3a3b662a4ff0418decb1d26dd789366d33f66ac13a18440258aa9b8c73", "contact_cells": 84, "contact_replacements": 428, "sitework_occupied_cells": 1541, "excavated_solid_cells": 0, "furnishing_bays": 10, "omitted_optional_furnishing_bays": 0, "seconds": 2.8463 }
perimeter-2validated{"program": "perimeter", "structure_seed": 2, "environment_seed": 2, "frozen_digest": "b4a5cfece31dabd3a5c906942b6c466c8652fae8b8b942c315bdeeb75a05bac7"}133387365112.9576c38c92478be9a7c4
记录 / 诊断
{ "label": "perimeter-2", "inputs": { "program": "perimeter", "structure_seed": 2, "environment_seed": 2, "frozen_digest": "b4a5cfece31dabd3a5c906942b6c466c8652fae8b8b942c315bdeeb75a05bac7" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 133387, "instances": 365, "digest": "366003046690470ac0b6b4247401fa6d8922504bfb1afefd9c2f1b48cc7f8560", "principal_signature": "c38c92478be9a7c427d0b340edd9b8238928cf3df2c71f897bb46bc8e78d0778", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ] ], "height": 5, "function": "living", "entrances": [ "east", "west" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "east", "south" ], "roof_run": 3, "lantern": false }, { "footprint": [ [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ] ], "height": 6, "function": "library", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -4 ], [ 6, -3 ], [ 6, -2 ], [ 6, -1 ], [ 6, 0 ], [ 7, -4 ], [ 7, -3 ], [ 7, -2 ], [ 7, -1 ], [ 7, 0 ], [ 8, -5 ], [ 8, -4 ], [ 8, -3 ], [ 8, -2 ], [ 8, -1 ], [ 9, -6 ], [ 9, -5 ], [ 9, -4 ], [ 9, -3 ], [ 9, -2 ], [ 9, -1 ], [ 10, -6 ], [ 10, -5 ], [ 10, -4 ], [ 10, -3 ], [ 10, -2 ], [ 11, -7 ], [ 11, -6 ], [ 11, -5 ], [ 11, -4 ], [ 11, -3 ], [ 12, -7 ], [ 12, -6 ], [ 12, -5 ], [ 12, -4 ], [ 12, -3 ], [ 13, -8 ], [ 13, -7 ], [ 13, -6 ], [ 13, -5 ], [ 13, -4 ], [ 14, -8 ], [ 14, -7 ], [ 14, -6 ], [ 14, -5 ], [ 14, -4 ], [ 15, -9 ], [ 15, -8 ], [ 15, -7 ], [ 15, -6 ], [ 15, -5 ], [ 16, -10 ], [ 16, -9 ], [ 16, -8 ], [ 16, -7 ], [ 16, -6 ], [ 16, -5 ], [ 17, -10 ], [ 17, -9 ], [ 17, -8 ], [ 17, -7 ], [ 17, -6 ], [ 18, -11 ], [ 18, -10 ], [ 18, -9 ], [ 18, -8 ], [ 18, -7 ], [ 19, -11 ], [ 19, -10 ], [ 19, -9 ], [ 19, -8 ], [ 19, -7 ], [ 20, -12 ], [ 20, -11 ], [ 20, -10 ], [ 20, -9 ], [ 20, -8 ], [ 21, -13 ], [ 21, -12 ], [ 21, -11 ], [ 21, -10 ], [ 21, -9 ], [ 21, -8 ], [ 22, -13 ], [ 22, -12 ], [ 22, -11 ], [ 22, -10 ], [ 22, -9 ], [ 23, -13 ], [ 23, -12 ], [ 23, -11 ], [ 23, -10 ], [ 23, -9 ], [ 23, -8 ], [ 24, -12 ], [ 24, -11 ], [ 24, -10 ], [ 24, -9 ], [ 24, -8 ], [ 25, -12 ], [ 25, -11 ], [ 25, -10 ], [ 25, -9 ], [ 25, -8 ], [ 25, -7 ], [ 26, -11 ], [ 26, -10 ], [ 26, -9 ], [ 26, -8 ], [ 26, -7 ], [ 27, -11 ], [ 27, -10 ], [ 27, -9 ], [ 27, -8 ], [ 27, -7 ], [ 27, -6 ], [ 28, -10 ], [ 28, -9 ], [ 28, -8 ], [ 28, -7 ], [ 28, -6 ], [ 29, -10 ], [ 29, -9 ], [ 29, -8 ], [ 29, -7 ], [ 29, -6 ], [ 29, -5 ], [ 30, -9 ], [ 30, -8 ], [ 30, -7 ], [ 30, -6 ], [ 30, -5 ], [ 31, -9 ], [ 31, -8 ], [ 31, -7 ], [ 31, -6 ], [ 31, -5 ], [ 31, -4 ], [ 32, -8 ], [ 32, -7 ], [ 32, -6 ], [ 32, -5 ], [ 32, -4 ], [ 33, -8 ], [ 33, -7 ], [ 33, -6 ], [ 33, -5 ], [ 33, -4 ], [ 33, -3 ], [ 34, -7 ], [ 34, -6 ], [ 34, -5 ], [ 34, -4 ], [ 34, -3 ], [ 35, -7 ], [ 35, -6 ], [ 35, -5 ], [ 35, -4 ], [ 35, -3 ], [ 35, -2 ], [ 36, -6 ], [ 36, -5 ], [ 36, -4 ], [ 36, -3 ], [ 36, -2 ], [ 37, -6 ], [ 37, -5 ], [ 37, -4 ], [ 37, -3 ], [ 37, -2 ], [ 37, -1 ], [ 38, -5 ], [ 38, -4 ], [ 38, -3 ], [ 38, -2 ], [ 38, -1 ], [ 39, -5 ], [ 39, -4 ], [ 39, -3 ], [ 39, -2 ], [ 39, -1 ], [ 39, 0 ], [ 40, -4 ], [ 40, -3 ], [ 40, -2 ], [ 40, -1 ], [ 40, 0 ], [ 41, -4 ], [ 41, -3 ], [ 41, -2 ], [ 41, -1 ], [ 41, 0 ], [ 42, -3 ], [ 42, -2 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -22, 34 ], [ -22, 35 ], [ -22, 36 ], [ -21, 33 ], [ -21, 34 ], [ -21, 35 ], [ -21, 36 ], [ -20, 31 ], [ -20, 32 ], [ -20, 33 ], [ -20, 34 ], [ -20, 35 ], [ -20, 36 ], [ -20, 37 ], [ -19, 30 ], [ -19, 31 ], [ -19, 32 ], [ -19, 33 ], [ -19, 34 ], [ -19, 35 ], [ -19, 36 ], [ -19, 37 ], [ -18, 28 ], [ -18, 29 ], [ -18, 30 ], [ -18, 31 ], [ -18, 32 ], [ -18, 33 ], [ -18, 34 ], [ -18, 35 ], [ -18, 36 ], [ -17, 26 ], [ -17, 27 ], [ -17, 28 ], [ -17, 29 ], [ -17, 30 ], [ -17, 31 ], [ -17, 32 ], [ -17, 33 ], [ -17, 34 ], [ -16, 25 ], [ -16, 26 ], [ -16, 27 ], [ -16, 28 ], [ -16, 29 ], [ -16, 30 ], [ -16, 31 ], [ -16, 32 ], [ -15, 23 ], [ -15, 24 ], [ -15, 25 ], [ -15, 26 ], [ -15, 27 ], [ -15, 28 ], [ -15, 29 ], [ -15, 30 ], [ -15, 31 ], [ -14, 22 ], [ -14, 23 ], [ -14, 24 ], [ -14, 25 ], [ -14, 26 ], [ -14, 27 ], [ -14, 28 ], [ -14, 29 ], [ -13, 20 ], [ -13, 21 ], [ -13, 22 ], [ -13, 23 ], [ -13, 24 ], [ -13, 25 ], [ -13, 26 ], [ -13, 27 ], [ -13, 28 ], [ -12, 18 ], [ -12, 19 ], [ -12, 20 ], [ -12, 21 ], [ -12, 22 ], [ -12, 23 ], [ -12, 24 ], [ -12, 25 ], [ -12, 26 ], [ -11, 17 ], [ -11, 18 ], [ -11, 19 ], [ -11, 20 ], [ -11, 21 ], [ -11, 22 ], [ -11, 23 ], [ -11, 24 ], [ -10, 15 ], [ -10, 16 ], [ -10, 17 ], [ -10, 18 ], [ -10, 19 ], [ -10, 20 ], [ -10, 21 ], [ -10, 22 ], [ -10, 23 ], [ -9, 14 ], [ -9, 15 ], [ -9, 16 ], [ -9, 17 ], [ -9, 18 ], [ -9, 19 ], [ -9, 20 ], [ -9, 21 ], [ -8, 12 ], [ -8, 13 ], [ -8, 14 ], [ -8, 15 ], [ -8, 16 ], [ -8, 17 ], [ -8, 18 ], [ -8, 19 ], [ -8, 20 ], [ -7, 10 ], [ -7, 11 ], [ -7, 12 ], [ -7, 13 ], [ -7, 14 ], [ -7, 15 ], [ -7, 16 ], [ -7, 17 ], [ -7, 18 ], [ -6, 9 ], [ -6, 10 ], [ -6, 11 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -5, 7 ], [ -5, 8 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -4, 6 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -3, 4 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ -1, 7 ], [ -1, 8 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 3 ], [ 2, 4 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -12, -45 ], [ -12, -44 ], [ -12, -43 ], [ -12, -42 ], [ -12, -41 ], [ -12, -40 ], [ -12, -39 ], [ -11, -47 ], [ -11, -46 ], [ -11, -45 ], [ -11, -44 ], [ -11, -43 ], [ -11, -42 ], [ -11, -41 ], [ -11, -40 ], [ -11, -39 ], [ -11, -38 ], [ -11, -37 ], [ -11, -36 ], [ -11, -35 ], [ -11, -34 ], [ -11, -33 ], [ -11, -32 ], [ -11, -31 ], [ -11, -30 ], [ -11, -29 ], [ -11, -28 ], [ -11, -27 ], [ -11, -26 ], [ -11, -25 ], [ -11, -24 ], [ -11, -23 ], [ -11, -22 ], [ -11, -21 ], [ -11, -20 ], [ -10, -47 ], [ -10, -46 ], [ -10, -45 ], [ -10, -44 ], [ -10, -43 ], [ -10, -42 ], [ -10, -41 ], [ -10, -40 ], [ -10, -39 ], [ -10, -38 ], [ -10, -37 ], [ -10, -36 ], [ -10, -35 ], [ -10, -34 ], [ -10, -33 ], [ -10, -32 ], [ -10, -31 ], [ -10, -30 ], [ -10, -29 ], [ -10, -28 ], [ -10, -27 ], [ -10, -26 ], [ -10, -25 ], [ -10, -24 ], [ -10, -23 ], [ -10, -22 ], [ -10, -21 ], [ -10, -20 ], [ -10, -19 ], [ -10, -18 ], [ -10, -17 ], [ -9, -47 ], [ -9, -46 ], [ -9, -45 ], [ -9, -44 ], [ -9, -43 ], [ -9, -42 ], [ -9, -41 ], [ -9, -40 ], [ -9, -39 ], [ -9, -38 ], [ -9, -37 ], [ -9, -36 ], [ -9, -35 ], [ -9, -34 ], [ -9, -33 ], [ -9, -32 ], [ -9, -31 ], [ -9, -30 ], [ -9, -29 ], [ -9, -28 ], [ -9, -27 ], [ -9, -26 ], [ -9, -25 ], [ -9, -24 ], [ -9, -23 ], [ -9, -22 ], [ -9, -21 ], [ -9, -20 ], [ -9, -19 ], [ -9, -18 ], [ -9, -17 ], [ -9, -16 ], [ -9, -15 ], [ -9, -14 ], [ -9, -13 ], [ -8, -45 ], [ -8, -44 ], [ -8, -43 ], [ -8, -42 ], [ -8, -41 ], [ -8, -40 ], [ -8, -39 ], [ -8, -38 ], [ -8, -37 ], [ -8, -36 ], [ -8, -35 ], [ -8, -34 ], [ -8, -33 ], [ -8, -32 ], [ -8, -31 ], [ -8, -30 ], [ -8, -29 ], [ -8, -28 ], [ -8, -27 ], [ -8, -26 ], [ -8, -25 ], [ -8, -24 ], [ -8, -23 ], [ -8, -22 ], [ -8, -21 ], [ -8, -20 ], [ -8, -19 ], [ -8, -18 ], [ -8, -17 ], [ -8, -16 ], [ -8, -15 ], [ -8, -14 ], [ -8, -13 ], [ -8, -12 ], [ -8, -11 ], [ -8, -10 ], [ -7, -27 ], [ -7, -26 ], [ -7, -25 ], [ -7, -24 ], [ -7, -23 ], [ -7, -22 ], [ -7, -21 ], [ -7, -20 ], [ -7, -19 ], [ -7, -18 ], [ -7, -17 ], [ -7, -16 ], [ -7, -15 ], [ -7, -14 ], [ -7, -13 ], [ -7, -12 ], [ -7, -11 ], [ -7, -10 ], [ -7, -9 ], [ -7, -8 ], [ -7, -7 ], [ -7, -6 ], [ -6, -18 ], [ -6, -17 ], [ -6, -16 ], [ -6, -15 ], [ -6, -14 ], [ -6, -13 ], [ -6, -12 ], [ -6, -11 ], [ -6, -10 ], [ -6, -9 ], [ -6, -8 ], [ -6, -7 ], [ -6, -6 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -5, -15 ], [ -5, -14 ], [ -5, -13 ], [ -5, -12 ], [ -5, -11 ], [ -5, -10 ], [ -5, -9 ], [ -5, -8 ], [ -5, -7 ], [ -5, -6 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -4, -11 ], [ -4, -10 ], [ -4, -9 ], [ -4, -8 ], [ -4, -7 ], [ -4, -6 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -3, -8 ], [ -3, -7 ], [ -3, -6 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 0, 0, [ "building", "habitable", "composite" ] ], [ 50, 10, [ "building", "habitable", "composite" ] ], [ 20, 57, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 1, "north", false, 3 ], [ 1, "south", 2, "east", true, 3 ], [ 2, "west", 0, "south", false, 3 ] ] } ], "legacy": [] }, "contact_signature": "9c583721416171e3f5287609c3ed91e70463abd51915e80ec359ad9013a6fe36", "contact_cells": 98, "contact_replacements": 451, "sitework_occupied_cells": 1597, "excavated_solid_cells": 0, "furnishing_bays": 9, "omitted_optional_furnishing_bays": 0, "seconds": 2.9576 }
perimeter-3validated{"program": "perimeter", "structure_seed": 3, "environment_seed": 3, "frozen_digest": "f395c726e571771b586a1126621b72b0a3f8ee2e213dcc58e137e196dd4a0cd6"}139429401116.9349dc5e4ede0de86cca
记录 / 诊断
{ "label": "perimeter-3", "inputs": { "program": "perimeter", "structure_seed": 3, "environment_seed": 3, "frozen_digest": "f395c726e571771b586a1126621b72b0a3f8ee2e213dcc58e137e196dd4a0cd6" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 139429, "instances": 401, "digest": "1465dd9a72154609307fbbe293cd606f366ef25bd738b9e83bef2d5fc269a335", "principal_signature": "dc5e4ede0de86cca2834e313e719ec763b65c80603933d0a40cd32e9860be46f", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "living", "entrances": [ "east", "west" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "east", "south" ], "roof_run": 3, "lantern": false }, { "footprint": [ [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ] ], "height": 6, "function": "library", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": false } ], "links": [ { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -4 ], [ 6, -3 ], [ 6, -2 ], [ 6, -1 ], [ 6, 0 ], [ 7, -5 ], [ 7, -4 ], [ 7, -3 ], [ 7, -2 ], [ 7, -1 ], [ 8, -6 ], [ 8, -5 ], [ 8, -4 ], [ 8, -3 ], [ 8, -2 ], [ 8, -1 ], [ 9, -7 ], [ 9, -6 ], [ 9, -5 ], [ 9, -4 ], [ 9, -3 ], [ 9, -2 ], [ 10, -7 ], [ 10, -6 ], [ 10, -5 ], [ 10, -4 ], [ 10, -3 ], [ 11, -8 ], [ 11, -7 ], [ 11, -6 ], [ 11, -5 ], [ 11, -4 ], [ 12, -9 ], [ 12, -8 ], [ 12, -7 ], [ 12, -6 ], [ 12, -5 ], [ 12, -4 ], [ 13, -10 ], [ 13, -9 ], [ 13, -8 ], [ 13, -7 ], [ 13, -6 ], [ 13, -5 ], [ 14, -10 ], [ 14, -9 ], [ 14, -8 ], [ 14, -7 ], [ 14, -6 ], [ 15, -11 ], [ 15, -10 ], [ 15, -9 ], [ 15, -8 ], [ 15, -7 ], [ 16, -12 ], [ 16, -11 ], [ 16, -10 ], [ 16, -9 ], [ 16, -8 ], [ 16, -7 ], [ 17, -13 ], [ 17, -12 ], [ 17, -11 ], [ 17, -10 ], [ 17, -9 ], [ 17, -8 ], [ 18, -13 ], [ 18, -12 ], [ 18, -11 ], [ 18, -10 ], [ 18, -9 ], [ 19, -13 ], [ 19, -12 ], [ 19, -11 ], [ 19, -10 ], [ 19, -9 ], [ 19, -8 ], [ 20, -12 ], [ 20, -11 ], [ 20, -10 ], [ 20, -9 ], [ 20, -8 ], [ 21, -11 ], [ 21, -10 ], [ 21, -9 ], [ 21, -8 ], [ 21, -7 ], [ 22, -11 ], [ 22, -10 ], [ 22, -9 ], [ 22, -8 ], [ 22, -7 ], [ 23, -10 ], [ 23, -9 ], [ 23, -8 ], [ 23, -7 ], [ 23, -6 ], [ 24, -10 ], [ 24, -9 ], [ 24, -8 ], [ 24, -7 ], [ 24, -6 ], [ 25, -9 ], [ 25, -8 ], [ 25, -7 ], [ 25, -6 ], [ 25, -5 ], [ 26, -9 ], [ 26, -8 ], [ 26, -7 ], [ 26, -6 ], [ 26, -5 ], [ 26, -4 ], [ 27, -8 ], [ 27, -7 ], [ 27, -6 ], [ 27, -5 ], [ 27, -4 ], [ 28, -7 ], [ 28, -6 ], [ 28, -5 ], [ 28, -4 ], [ 28, -3 ], [ 29, -7 ], [ 29, -6 ], [ 29, -5 ], [ 29, -4 ], [ 29, -3 ], [ 30, -6 ], [ 30, -5 ], [ 30, -4 ], [ 30, -3 ], [ 30, -2 ], [ 31, -6 ], [ 31, -5 ], [ 31, -4 ], [ 31, -3 ], [ 31, -2 ], [ 32, -5 ], [ 32, -4 ], [ 32, -3 ], [ 32, -2 ], [ 32, -1 ], [ 33, -5 ], [ 33, -4 ], [ 33, -3 ], [ 33, -2 ], [ 33, -1 ], [ 33, 0 ], [ 34, -4 ], [ 34, -3 ], [ 34, -2 ], [ 34, -1 ], [ 34, 0 ], [ 35, -4 ], [ 35, -3 ], [ 35, -2 ], [ 35, -1 ], [ 35, 0 ], [ 36, -3 ], [ 36, -2 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -16, 34 ], [ -16, 35 ], [ -16, 36 ], [ -15, 32 ], [ -15, 33 ], [ -15, 34 ], [ -15, 35 ], [ -15, 36 ], [ -14, 30 ], [ -14, 31 ], [ -14, 32 ], [ -14, 33 ], [ -14, 34 ], [ -14, 35 ], [ -14, 36 ], [ -14, 37 ], [ -13, 28 ], [ -13, 29 ], [ -13, 30 ], [ -13, 31 ], [ -13, 32 ], [ -13, 33 ], [ -13, 34 ], [ -13, 35 ], [ -13, 36 ], [ -13, 37 ], [ -12, 25 ], [ -12, 26 ], [ -12, 27 ], [ -12, 28 ], [ -12, 29 ], [ -12, 30 ], [ -12, 31 ], [ -12, 32 ], [ -12, 33 ], [ -12, 34 ], [ -12, 35 ], [ -12, 36 ], [ -11, 23 ], [ -11, 24 ], [ -11, 25 ], [ -11, 26 ], [ -11, 27 ], [ -11, 28 ], [ -11, 29 ], [ -11, 30 ], [ -11, 31 ], [ -11, 32 ], [ -11, 33 ], [ -10, 21 ], [ -10, 22 ], [ -10, 23 ], [ -10, 24 ], [ -10, 25 ], [ -10, 26 ], [ -10, 27 ], [ -10, 28 ], [ -10, 29 ], [ -10, 30 ], [ -10, 31 ], [ -9, 18 ], [ -9, 19 ], [ -9, 20 ], [ -9, 21 ], [ -9, 22 ], [ -9, 23 ], [ -9, 24 ], [ -9, 25 ], [ -9, 26 ], [ -9, 27 ], [ -9, 28 ], [ -9, 29 ], [ -8, 16 ], [ -8, 17 ], [ -8, 18 ], [ -8, 19 ], [ -8, 20 ], [ -8, 21 ], [ -8, 22 ], [ -8, 23 ], [ -8, 24 ], [ -8, 25 ], [ -8, 26 ], [ -7, 14 ], [ -7, 15 ], [ -7, 16 ], [ -7, 17 ], [ -7, 18 ], [ -7, 19 ], [ -7, 20 ], [ -7, 21 ], [ -7, 22 ], [ -7, 23 ], [ -7, 24 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -6, 17 ], [ -6, 18 ], [ -6, 19 ], [ -6, 20 ], [ -6, 21 ], [ -6, 22 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -5, 17 ], [ -5, 18 ], [ -5, 19 ], [ -5, 20 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -4, 15 ], [ -4, 16 ], [ -4, 17 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -3, 13 ], [ -3, 14 ], [ -3, 15 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -2, 12 ], [ -2, 13 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ -1, 7 ], [ -1, 8 ], [ -1, 9 ], [ -1, 10 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -11, -27 ], [ -11, -26 ], [ -11, -25 ], [ -11, -24 ], [ -11, -23 ], [ -11, -22 ], [ -11, -21 ], [ -11, -20 ], [ -10, -46 ], [ -10, -45 ], [ -10, -44 ], [ -10, -43 ], [ -10, -42 ], [ -10, -41 ], [ -10, -40 ], [ -10, -39 ], [ -10, -38 ], [ -10, -37 ], [ -10, -36 ], [ -10, -35 ], [ -10, -34 ], [ -10, -33 ], [ -10, -32 ], [ -10, -31 ], [ -10, -30 ], [ -10, -29 ], [ -10, -28 ], [ -10, -27 ], [ -10, -26 ], [ -10, -25 ], [ -10, -24 ], [ -10, -23 ], [ -10, -22 ], [ -10, -21 ], [ -10, -20 ], [ -10, -19 ], [ -10, -18 ], [ -10, -17 ], [ -9, -48 ], [ -9, -47 ], [ -9, -46 ], [ -9, -45 ], [ -9, -44 ], [ -9, -43 ], [ -9, -42 ], [ -9, -41 ], [ -9, -40 ], [ -9, -39 ], [ -9, -38 ], [ -9, -37 ], [ -9, -36 ], [ -9, -35 ], [ -9, -34 ], [ -9, -33 ], [ -9, -32 ], [ -9, -31 ], [ -9, -30 ], [ -9, -29 ], [ -9, -28 ], [ -9, -27 ], [ -9, -26 ], [ -9, -25 ], [ -9, -24 ], [ -9, -23 ], [ -9, -22 ], [ -9, -21 ], [ -9, -20 ], [ -9, -19 ], [ -9, -18 ], [ -9, -17 ], [ -9, -16 ], [ -9, -15 ], [ -9, -14 ], [ -9, -13 ], [ -8, -48 ], [ -8, -47 ], [ -8, -46 ], [ -8, -45 ], [ -8, -44 ], [ -8, -43 ], [ -8, -42 ], [ -8, -41 ], [ -8, -40 ], [ -8, -39 ], [ -8, -38 ], [ -8, -37 ], [ -8, -36 ], [ -8, -35 ], [ -8, -34 ], [ -8, -33 ], [ -8, -32 ], [ -8, -31 ], [ -8, -30 ], [ -8, -29 ], [ -8, -28 ], [ -8, -27 ], [ -8, -26 ], [ -8, -25 ], [ -8, -24 ], [ -8, -23 ], [ -8, -22 ], [ -8, -21 ], [ -8, -20 ], [ -8, -19 ], [ -8, -18 ], [ -8, -17 ], [ -8, -16 ], [ -8, -15 ], [ -8, -14 ], [ -8, -13 ], [ -8, -12 ], [ -8, -11 ], [ -8, -10 ], [ -7, -48 ], [ -7, -47 ], [ -7, -46 ], [ -7, -45 ], [ -7, -44 ], [ -7, -43 ], [ -7, -42 ], [ -7, -41 ], [ -7, -40 ], [ -7, -39 ], [ -7, -38 ], [ -7, -37 ], [ -7, -36 ], [ -7, -35 ], [ -7, -34 ], [ -7, -33 ], [ -7, -32 ], [ -7, -31 ], [ -7, -30 ], [ -7, -29 ], [ -7, -28 ], [ -7, -27 ], [ -7, -26 ], [ -7, -25 ], [ -7, -24 ], [ -7, -23 ], [ -7, -22 ], [ -7, -21 ], [ -7, -20 ], [ -7, -19 ], [ -7, -18 ], [ -7, -17 ], [ -7, -16 ], [ -7, -15 ], [ -7, -14 ], [ -7, -13 ], [ -7, -12 ], [ -7, -11 ], [ -7, -10 ], [ -7, -9 ], [ -7, -8 ], [ -7, -7 ], [ -7, -6 ], [ -6, -46 ], [ -6, -45 ], [ -6, -44 ], [ -6, -43 ], [ -6, -42 ], [ -6, -41 ], [ -6, -40 ], [ -6, -18 ], [ -6, -17 ], [ -6, -16 ], [ -6, -15 ], [ -6, -14 ], [ -6, -13 ], [ -6, -12 ], [ -6, -11 ], [ -6, -10 ], [ -6, -9 ], [ -6, -8 ], [ -6, -7 ], [ -6, -6 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -5, -15 ], [ -5, -14 ], [ -5, -13 ], [ -5, -12 ], [ -5, -11 ], [ -5, -10 ], [ -5, -9 ], [ -5, -8 ], [ -5, -7 ], [ -5, -6 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -4, -11 ], [ -4, -10 ], [ -4, -9 ], [ -4, -8 ], [ -4, -7 ], [ -4, -6 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -3, -8 ], [ -3, -7 ], [ -3, -6 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 0, 0, [ "building", "habitable", "composite" ] ], [ 50, 10, [ "building", "habitable", "composite" ] ], [ 20, 57, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 1, "north", false, 3 ], [ 1, "south", 2, "east", true, 3 ], [ 2, "west", 0, "south", false, 3 ] ] } ], "legacy": [] }, "contact_signature": "4c0ca82d3c8a81ec67c90ed8b9cc0be8b29716b32044bb69020393b99c24ea70", "contact_cells": 82, "contact_replacements": 311, "sitework_occupied_cells": 1539, "excavated_solid_cells": 0, "furnishing_bays": 10, "omitted_optional_furnishing_bays": 0, "artifact": "samples/extensions/perimeter-3.litematic", "seconds": 6.9349 }
perimeter-4validated{"program": "perimeter", "structure_seed": 4, "environment_seed": 4, "frozen_digest": "4381e277f3b7f18711470ebbecf0297994c6a02ca8f7f44867a8b1d786c60e91"}119090380112.7834d5714c63e4f5ee2
记录 / 诊断
{ "label": "perimeter-4", "inputs": { "program": "perimeter", "structure_seed": 4, "environment_seed": 4, "frozen_digest": "4381e277f3b7f18711470ebbecf0297994c6a02ca8f7f44867a8b1d786c60e91" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 119090, "instances": 380, "digest": "a46da3c856586696ab83272aa0a873f06b362f6970f860a9e769e671b6059dfa", "principal_signature": "4d5714c63e4f5ee2f2787a8f2169b84d7d578cc261fd9977c8bbb71f86ef3f3f", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "living", "entrances": [ "east", "west" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "east", "south" ], "roof_run": 3, "lantern": false }, { "footprint": [ [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ] ], "height": 6, "function": "library", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": true } ], "links": [ { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -5 ], [ 6, -4 ], [ 6, -3 ], [ 6, -2 ], [ 6, -1 ], [ 6, 0 ], [ 7, -6 ], [ 7, -5 ], [ 7, -4 ], [ 7, -3 ], [ 7, -2 ], [ 7, -1 ], [ 8, -6 ], [ 8, -5 ], [ 8, -4 ], [ 8, -3 ], [ 8, -2 ], [ 9, -7 ], [ 9, -6 ], [ 9, -5 ], [ 9, -4 ], [ 9, -3 ], [ 9, -2 ], [ 10, -8 ], [ 10, -7 ], [ 10, -6 ], [ 10, -5 ], [ 10, -4 ], [ 10, -3 ], [ 11, -9 ], [ 11, -8 ], [ 11, -7 ], [ 11, -6 ], [ 11, -5 ], [ 11, -4 ], [ 12, -9 ], [ 12, -8 ], [ 12, -7 ], [ 12, -6 ], [ 12, -5 ], [ 13, -10 ], [ 13, -9 ], [ 13, -8 ], [ 13, -7 ], [ 13, -6 ], [ 13, -5 ], [ 14, -11 ], [ 14, -10 ], [ 14, -9 ], [ 14, -8 ], [ 14, -7 ], [ 14, -6 ], [ 15, -12 ], [ 15, -11 ], [ 15, -10 ], [ 15, -9 ], [ 15, -8 ], [ 15, -7 ], [ 16, -13 ], [ 16, -12 ], [ 16, -11 ], [ 16, -10 ], [ 16, -9 ], [ 16, -8 ], [ 17, -13 ], [ 17, -12 ], [ 17, -11 ], [ 17, -10 ], [ 17, -9 ], [ 18, -13 ], [ 18, -12 ], [ 18, -11 ], [ 18, -10 ], [ 18, -9 ], [ 18, -8 ], [ 19, -12 ], [ 19, -11 ], [ 19, -10 ], [ 19, -9 ], [ 19, -8 ], [ 20, -11 ], [ 20, -10 ], [ 20, -9 ], [ 20, -8 ], [ 20, -7 ], [ 21, -11 ], [ 21, -10 ], [ 21, -9 ], [ 21, -8 ], [ 21, -7 ], [ 21, -6 ], [ 22, -10 ], [ 22, -9 ], [ 22, -8 ], [ 22, -7 ], [ 22, -6 ], [ 23, -9 ], [ 23, -8 ], [ 23, -7 ], [ 23, -6 ], [ 23, -5 ], [ 24, -9 ], [ 24, -8 ], [ 24, -7 ], [ 24, -6 ], [ 24, -5 ], [ 24, -4 ], [ 25, -8 ], [ 25, -7 ], [ 25, -6 ], [ 25, -5 ], [ 25, -4 ], [ 26, -8 ], [ 26, -7 ], [ 26, -6 ], [ 26, -5 ], [ 26, -4 ], [ 26, -3 ], [ 27, -7 ], [ 27, -6 ], [ 27, -5 ], [ 27, -4 ], [ 27, -3 ], [ 28, -6 ], [ 28, -5 ], [ 28, -4 ], [ 28, -3 ], [ 28, -2 ], [ 29, -6 ], [ 29, -5 ], [ 29, -4 ], [ 29, -3 ], [ 29, -2 ], [ 29, -1 ], [ 30, -5 ], [ 30, -4 ], [ 30, -3 ], [ 30, -2 ], [ 30, -1 ], [ 31, -4 ], [ 31, -3 ], [ 31, -2 ], [ 31, -1 ], [ 31, 0 ], [ 32, -4 ], [ 32, -3 ], [ 32, -2 ], [ 32, -1 ], [ 32, 0 ], [ 32, 1 ], [ 33, -3 ], [ 33, -2 ], [ 33, -1 ], [ 33, 0 ], [ 33, 1 ], [ 34, -3 ], [ 34, -2 ], [ 34, -1 ], [ 34, 0 ], [ 34, 1 ], [ 35, -2 ], [ 35, -1 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -16, 34 ], [ -16, 35 ], [ -16, 36 ], [ -15, 32 ], [ -15, 33 ], [ -15, 34 ], [ -15, 35 ], [ -15, 36 ], [ -14, 30 ], [ -14, 31 ], [ -14, 32 ], [ -14, 33 ], [ -14, 34 ], [ -14, 35 ], [ -14, 36 ], [ -14, 37 ], [ -13, 28 ], [ -13, 29 ], [ -13, 30 ], [ -13, 31 ], [ -13, 32 ], [ -13, 33 ], [ -13, 34 ], [ -13, 35 ], [ -13, 36 ], [ -13, 37 ], [ -12, 25 ], [ -12, 26 ], [ -12, 27 ], [ -12, 28 ], [ -12, 29 ], [ -12, 30 ], [ -12, 31 ], [ -12, 32 ], [ -12, 33 ], [ -12, 34 ], [ -12, 35 ], [ -12, 36 ], [ -11, 23 ], [ -11, 24 ], [ -11, 25 ], [ -11, 26 ], [ -11, 27 ], [ -11, 28 ], [ -11, 29 ], [ -11, 30 ], [ -11, 31 ], [ -11, 32 ], [ -11, 33 ], [ -10, 21 ], [ -10, 22 ], [ -10, 23 ], [ -10, 24 ], [ -10, 25 ], [ -10, 26 ], [ -10, 27 ], [ -10, 28 ], [ -10, 29 ], [ -10, 30 ], [ -10, 31 ], [ -9, 18 ], [ -9, 19 ], [ -9, 20 ], [ -9, 21 ], [ -9, 22 ], [ -9, 23 ], [ -9, 24 ], [ -9, 25 ], [ -9, 26 ], [ -9, 27 ], [ -9, 28 ], [ -9, 29 ], [ -8, 16 ], [ -8, 17 ], [ -8, 18 ], [ -8, 19 ], [ -8, 20 ], [ -8, 21 ], [ -8, 22 ], [ -8, 23 ], [ -8, 24 ], [ -8, 25 ], [ -8, 26 ], [ -7, 14 ], [ -7, 15 ], [ -7, 16 ], [ -7, 17 ], [ -7, 18 ], [ -7, 19 ], [ -7, 20 ], [ -7, 21 ], [ -7, 22 ], [ -7, 23 ], [ -7, 24 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -6, 17 ], [ -6, 18 ], [ -6, 19 ], [ -6, 20 ], [ -6, 21 ], [ -6, 22 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -5, 17 ], [ -5, 18 ], [ -5, 19 ], [ -5, 20 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -4, 15 ], [ -4, 16 ], [ -4, 17 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -3, 13 ], [ -3, 14 ], [ -3, 15 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -2, 12 ], [ -2, 13 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ -1, 7 ], [ -1, 8 ], [ -1, 9 ], [ -1, 10 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 3 ], [ 2, 4 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -11, -27 ], [ -11, -26 ], [ -11, -25 ], [ -11, -24 ], [ -11, -23 ], [ -11, -22 ], [ -11, -21 ], [ -11, -20 ], [ -10, -45 ], [ -10, -44 ], [ -10, -43 ], [ -10, -42 ], [ -10, -41 ], [ -10, -40 ], [ -10, -39 ], [ -10, -38 ], [ -10, -37 ], [ -10, -36 ], [ -10, -35 ], [ -10, -34 ], [ -10, -33 ], [ -10, -32 ], [ -10, -31 ], [ -10, -30 ], [ -10, -29 ], [ -10, -28 ], [ -10, -27 ], [ -10, -26 ], [ -10, -25 ], [ -10, -24 ], [ -10, -23 ], [ -10, -22 ], [ -10, -21 ], [ -10, -20 ], [ -10, -19 ], [ -10, -18 ], [ -10, -17 ], [ -9, -47 ], [ -9, -46 ], [ -9, -45 ], [ -9, -44 ], [ -9, -43 ], [ -9, -42 ], [ -9, -41 ], [ -9, -40 ], [ -9, -39 ], [ -9, -38 ], [ -9, -37 ], [ -9, -36 ], [ -9, -35 ], [ -9, -34 ], [ -9, -33 ], [ -9, -32 ], [ -9, -31 ], [ -9, -30 ], [ -9, -29 ], [ -9, -28 ], [ -9, -27 ], [ -9, -26 ], [ -9, -25 ], [ -9, -24 ], [ -9, -23 ], [ -9, -22 ], [ -9, -21 ], [ -9, -20 ], [ -9, -19 ], [ -9, -18 ], [ -9, -17 ], [ -9, -16 ], [ -9, -15 ], [ -9, -14 ], [ -9, -13 ], [ -8, -47 ], [ -8, -46 ], [ -8, -45 ], [ -8, -44 ], [ -8, -43 ], [ -8, -42 ], [ -8, -41 ], [ -8, -40 ], [ -8, -39 ], [ -8, -38 ], [ -8, -37 ], [ -8, -36 ], [ -8, -35 ], [ -8, -34 ], [ -8, -33 ], [ -8, -32 ], [ -8, -31 ], [ -8, -30 ], [ -8, -29 ], [ -8, -28 ], [ -8, -27 ], [ -8, -26 ], [ -8, -25 ], [ -8, -24 ], [ -8, -23 ], [ -8, -22 ], [ -8, -21 ], [ -8, -20 ], [ -8, -19 ], [ -8, -18 ], [ -8, -17 ], [ -8, -16 ], [ -8, -15 ], [ -8, -14 ], [ -8, -13 ], [ -8, -12 ], [ -8, -11 ], [ -8, -10 ], [ -7, -47 ], [ -7, -46 ], [ -7, -45 ], [ -7, -44 ], [ -7, -43 ], [ -7, -42 ], [ -7, -41 ], [ -7, -40 ], [ -7, -39 ], [ -7, -38 ], [ -7, -37 ], [ -7, -36 ], [ -7, -35 ], [ -7, -34 ], [ -7, -33 ], [ -7, -32 ], [ -7, -31 ], [ -7, -30 ], [ -7, -29 ], [ -7, -28 ], [ -7, -27 ], [ -7, -26 ], [ -7, -25 ], [ -7, -24 ], [ -7, -23 ], [ -7, -22 ], [ -7, -21 ], [ -7, -20 ], [ -7, -19 ], [ -7, -18 ], [ -7, -17 ], [ -7, -16 ], [ -7, -15 ], [ -7, -14 ], [ -7, -13 ], [ -7, -12 ], [ -7, -11 ], [ -7, -10 ], [ -7, -9 ], [ -7, -8 ], [ -7, -7 ], [ -7, -6 ], [ -6, -45 ], [ -6, -44 ], [ -6, -43 ], [ -6, -42 ], [ -6, -41 ], [ -6, -40 ], [ -6, -39 ], [ -6, -18 ], [ -6, -17 ], [ -6, -16 ], [ -6, -15 ], [ -6, -14 ], [ -6, -13 ], [ -6, -12 ], [ -6, -11 ], [ -6, -10 ], [ -6, -9 ], [ -6, -8 ], [ -6, -7 ], [ -6, -6 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -5, -15 ], [ -5, -14 ], [ -5, -13 ], [ -5, -12 ], [ -5, -11 ], [ -5, -10 ], [ -5, -9 ], [ -5, -8 ], [ -5, -7 ], [ -5, -6 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -4, -11 ], [ -4, -10 ], [ -4, -9 ], [ -4, -8 ], [ -4, -7 ], [ -4, -6 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -3, -8 ], [ -3, -7 ], [ -3, -6 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ] ], "width": 3, "covered": false, "rise": 1 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 0, 0, [ "building", "habitable", "composite" ] ], [ 50, 10, [ "building", "habitable", "composite" ] ], [ 20, 57, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 1, "north", false, 3 ], [ 1, "south", 2, "east", true, 3 ], [ 2, "west", 0, "south", false, 3 ] ] } ], "legacy": [] }, "contact_signature": "e51f684e08c0d5fd31e44619e9015d533774fda81d49688cc6c37c8171aa2a6f", "contact_cells": 119, "contact_replacements": 278, "sitework_occupied_cells": 1573, "excavated_solid_cells": 0, "furnishing_bays": 10, "omitted_optional_furnishing_bays": 0, "seconds": 2.783 }
perimeter-5validated{"program": "perimeter", "structure_seed": 5, "environment_seed": 5, "frozen_digest": "bc0d58f7d3fe6423fb60ffaa90eaed8b8778bec0ccab6ff6752268af82911311"}130476362112.9291f11c4dcf39decdfd
记录 / 诊断
{ "label": "perimeter-5", "inputs": { "program": "perimeter", "structure_seed": 5, "environment_seed": 5, "frozen_digest": "bc0d58f7d3fe6423fb60ffaa90eaed8b8778bec0ccab6ff6752268af82911311" }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 130476, "instances": 362, "digest": "fe421c10854281aa614cdcfc1653ebdd554f598f33abce697cc45e1637d5cec9", "principal_signature": "f11c4dcf39decdfd1d08f028ce9e5e233b85d1b320168f4a09e034d7b99dd1a7", "structure": { "halls": [ { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ] ], "height": 5, "function": "living", "entrances": [ "east", "west" ], "roof_run": 2, "lantern": false }, { "footprint": [ [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 14, 0 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 15, 0 ], [ 15, 1 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 16, 0 ], [ 16, 1 ], [ 16, 2 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 17, 0 ], [ 17, 1 ], [ 17, 2 ], [ 17, 3 ], [ 17, 4 ], [ 17, 5 ], [ 17, 6 ], [ 17, 7 ], [ 17, 8 ], [ 17, 9 ], [ 17, 10 ], [ 17, 11 ], [ 17, 12 ], [ 18, 0 ], [ 18, 1 ], [ 18, 2 ], [ 18, 3 ], [ 18, 4 ], [ 18, 5 ], [ 18, 6 ], [ 18, 7 ], [ 18, 8 ], [ 18, 9 ], [ 18, 10 ], [ 18, 11 ], [ 18, 12 ], [ 19, 1 ], [ 19, 2 ], [ 19, 3 ], [ 19, 4 ], [ 19, 5 ], [ 19, 6 ], [ 19, 7 ], [ 19, 8 ], [ 19, 9 ], [ 19, 10 ], [ 19, 11 ], [ 20, 2 ], [ 20, 3 ], [ 20, 4 ], [ 20, 5 ], [ 20, 6 ], [ 20, 7 ], [ 20, 8 ], [ 20, 9 ], [ 20, 10 ] ], "height": 5, "function": "workshop", "entrances": [ "north", "east", "south" ], "roof_run": 3, "lantern": false }, { "footprint": [ [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 0, 8 ], [ 0, 9 ], [ 0, 10 ], [ 0, 11 ], [ 0, 12 ], [ 0, 13 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 2, 12 ], [ 2, 13 ], [ 2, 14 ], [ 2, 15 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 3, 14 ], [ 3, 15 ], [ 3, 16 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 4, 15 ], [ 4, 16 ], [ 5, 0 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 5, 15 ], [ 5, 16 ], [ 6, 0 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 6, 15 ], [ 6, 16 ], [ 7, 0 ], [ 7, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 7, 16 ], [ 8, 0 ], [ 8, 1 ], [ 8, 2 ], [ 8, 3 ], [ 8, 4 ], [ 8, 5 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 8, 16 ], [ 9, 0 ], [ 9, 1 ], [ 9, 2 ], [ 9, 3 ], [ 9, 4 ], [ 9, 5 ], [ 9, 6 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 9, 16 ], [ 10, 0 ], [ 10, 1 ], [ 10, 2 ], [ 10, 3 ], [ 10, 4 ], [ 10, 5 ], [ 10, 6 ], [ 10, 7 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 0 ], [ 11, 1 ], [ 11, 2 ], [ 11, 3 ], [ 11, 4 ], [ 11, 5 ], [ 11, 6 ], [ 11, 7 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 0 ], [ 12, 1 ], [ 12, 2 ], [ 12, 3 ], [ 12, 4 ], [ 12, 5 ], [ 12, 6 ], [ 12, 7 ], [ 12, 8 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 0 ], [ 13, 1 ], [ 13, 2 ], [ 13, 3 ], [ 13, 4 ], [ 13, 5 ], [ 13, 6 ], [ 13, 7 ], [ 13, 8 ], [ 13, 9 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 1 ], [ 14, 2 ], [ 14, 3 ], [ 14, 4 ], [ 14, 5 ], [ 14, 6 ], [ 14, 7 ], [ 14, 8 ], [ 14, 9 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 15, 2 ], [ 15, 3 ], [ 15, 4 ], [ 15, 5 ], [ 15, 6 ], [ 15, 7 ], [ 15, 8 ], [ 15, 9 ], [ 15, 10 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 16, 3 ], [ 16, 4 ], [ 16, 5 ], [ 16, 6 ], [ 16, 7 ], [ 16, 8 ], [ 16, 9 ], [ 16, 10 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ] ], "height": 6, "function": "library", "entrances": [ "north", "south" ], "roof_run": 2, "lantern": true } ], "links": [ { "body": [ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 3, -2 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ], [ 3, 2 ], [ 4, -3 ], [ 4, -2 ], [ 4, -1 ], [ 4, 0 ], [ 4, 1 ], [ 4, 2 ], [ 5, -4 ], [ 5, -3 ], [ 5, -2 ], [ 5, -1 ], [ 5, 0 ], [ 5, 1 ], [ 6, -4 ], [ 6, -3 ], [ 6, -2 ], [ 6, -1 ], [ 6, 0 ], [ 7, -5 ], [ 7, -4 ], [ 7, -3 ], [ 7, -2 ], [ 7, -1 ], [ 8, -6 ], [ 8, -5 ], [ 8, -4 ], [ 8, -3 ], [ 8, -2 ], [ 8, -1 ], [ 9, -7 ], [ 9, -6 ], [ 9, -5 ], [ 9, -4 ], [ 9, -3 ], [ 9, -2 ], [ 10, -7 ], [ 10, -6 ], [ 10, -5 ], [ 10, -4 ], [ 10, -3 ], [ 11, -8 ], [ 11, -7 ], [ 11, -6 ], [ 11, -5 ], [ 11, -4 ], [ 12, -9 ], [ 12, -8 ], [ 12, -7 ], [ 12, -6 ], [ 12, -5 ], [ 12, -4 ], [ 13, -10 ], [ 13, -9 ], [ 13, -8 ], [ 13, -7 ], [ 13, -6 ], [ 13, -5 ], [ 14, -10 ], [ 14, -9 ], [ 14, -8 ], [ 14, -7 ], [ 14, -6 ], [ 15, -11 ], [ 15, -10 ], [ 15, -9 ], [ 15, -8 ], [ 15, -7 ], [ 16, -12 ], [ 16, -11 ], [ 16, -10 ], [ 16, -9 ], [ 16, -8 ], [ 16, -7 ], [ 17, -13 ], [ 17, -12 ], [ 17, -11 ], [ 17, -10 ], [ 17, -9 ], [ 17, -8 ], [ 18, -13 ], [ 18, -12 ], [ 18, -11 ], [ 18, -10 ], [ 18, -9 ], [ 19, -13 ], [ 19, -12 ], [ 19, -11 ], [ 19, -10 ], [ 19, -9 ], [ 19, -8 ], [ 20, -12 ], [ 20, -11 ], [ 20, -10 ], [ 20, -9 ], [ 20, -8 ], [ 21, -11 ], [ 21, -10 ], [ 21, -9 ], [ 21, -8 ], [ 21, -7 ], [ 22, -11 ], [ 22, -10 ], [ 22, -9 ], [ 22, -8 ], [ 22, -7 ], [ 23, -10 ], [ 23, -9 ], [ 23, -8 ], [ 23, -7 ], [ 23, -6 ], [ 24, -10 ], [ 24, -9 ], [ 24, -8 ], [ 24, -7 ], [ 24, -6 ], [ 25, -9 ], [ 25, -8 ], [ 25, -7 ], [ 25, -6 ], [ 25, -5 ], [ 26, -9 ], [ 26, -8 ], [ 26, -7 ], [ 26, -6 ], [ 26, -5 ], [ 26, -4 ], [ 27, -8 ], [ 27, -7 ], [ 27, -6 ], [ 27, -5 ], [ 27, -4 ], [ 28, -8 ], [ 28, -7 ], [ 28, -6 ], [ 28, -5 ], [ 28, -4 ], [ 28, -3 ], [ 29, -7 ], [ 29, -6 ], [ 29, -5 ], [ 29, -4 ], [ 29, -3 ], [ 30, -6 ], [ 30, -5 ], [ 30, -4 ], [ 30, -3 ], [ 30, -2 ], [ 31, -6 ], [ 31, -5 ], [ 31, -4 ], [ 31, -3 ], [ 31, -2 ], [ 32, -5 ], [ 32, -4 ], [ 32, -3 ], [ 32, -2 ], [ 32, -1 ], [ 33, -5 ], [ 33, -4 ], [ 33, -3 ], [ 33, -2 ], [ 33, -1 ], [ 34, -4 ], [ 34, -3 ], [ 34, -2 ], [ 34, -1 ], [ 34, 0 ], [ 35, -4 ], [ 35, -3 ], [ 35, -2 ], [ 35, -1 ], [ 35, 0 ], [ 35, 1 ], [ 36, -3 ], [ 36, -2 ], [ 36, -1 ], [ 36, 0 ], [ 36, 1 ], [ 37, -3 ], [ 37, -2 ], [ 37, -1 ], [ 37, 0 ], [ 37, 1 ], [ 38, -2 ], [ 38, -1 ] ], "width": 3, "covered": false, "rise": 1 }, { "body": [ [ -19, 34 ], [ -19, 35 ], [ -19, 36 ], [ -18, 33 ], [ -18, 34 ], [ -18, 35 ], [ -18, 36 ], [ -17, 31 ], [ -17, 32 ], [ -17, 33 ], [ -17, 34 ], [ -17, 35 ], [ -17, 36 ], [ -17, 37 ], [ -16, 29 ], [ -16, 30 ], [ -16, 31 ], [ -16, 32 ], [ -16, 33 ], [ -16, 34 ], [ -16, 35 ], [ -16, 36 ], [ -16, 37 ], [ -15, 27 ], [ -15, 28 ], [ -15, 29 ], [ -15, 30 ], [ -15, 31 ], [ -15, 32 ], [ -15, 33 ], [ -15, 34 ], [ -15, 35 ], [ -15, 36 ], [ -14, 25 ], [ -14, 26 ], [ -14, 27 ], [ -14, 28 ], [ -14, 29 ], [ -14, 30 ], [ -14, 31 ], [ -14, 32 ], [ -14, 33 ], [ -14, 34 ], [ -13, 23 ], [ -13, 24 ], [ -13, 25 ], [ -13, 26 ], [ -13, 27 ], [ -13, 28 ], [ -13, 29 ], [ -13, 30 ], [ -13, 31 ], [ -13, 32 ], [ -12, 21 ], [ -12, 22 ], [ -12, 23 ], [ -12, 24 ], [ -12, 25 ], [ -12, 26 ], [ -12, 27 ], [ -12, 28 ], [ -12, 29 ], [ -12, 30 ], [ -11, 19 ], [ -11, 20 ], [ -11, 21 ], [ -11, 22 ], [ -11, 23 ], [ -11, 24 ], [ -11, 25 ], [ -11, 26 ], [ -11, 27 ], [ -11, 28 ], [ -10, 18 ], [ -10, 19 ], [ -10, 20 ], [ -10, 21 ], [ -10, 22 ], [ -10, 23 ], [ -10, 24 ], [ -10, 25 ], [ -10, 26 ], [ -9, 16 ], [ -9, 17 ], [ -9, 18 ], [ -9, 19 ], [ -9, 20 ], [ -9, 21 ], [ -9, 22 ], [ -9, 23 ], [ -9, 24 ], [ -8, 14 ], [ -8, 15 ], [ -8, 16 ], [ -8, 17 ], [ -8, 18 ], [ -8, 19 ], [ -8, 20 ], [ -8, 21 ], [ -8, 22 ], [ -7, 12 ], [ -7, 13 ], [ -7, 14 ], [ -7, 15 ], [ -7, 16 ], [ -7, 17 ], [ -7, 18 ], [ -7, 19 ], [ -7, 20 ], [ -6, 10 ], [ -6, 11 ], [ -6, 12 ], [ -6, 13 ], [ -6, 14 ], [ -6, 15 ], [ -6, 16 ], [ -6, 17 ], [ -6, 18 ], [ -6, 19 ], [ -5, 8 ], [ -5, 9 ], [ -5, 10 ], [ -5, 11 ], [ -5, 12 ], [ -5, 13 ], [ -5, 14 ], [ -5, 15 ], [ -5, 16 ], [ -5, 17 ], [ -4, 6 ], [ -4, 7 ], [ -4, 8 ], [ -4, 9 ], [ -4, 10 ], [ -4, 11 ], [ -4, 12 ], [ -4, 13 ], [ -4, 14 ], [ -4, 15 ], [ -3, 4 ], [ -3, 5 ], [ -3, 6 ], [ -3, 7 ], [ -3, 8 ], [ -3, 9 ], [ -3, 10 ], [ -3, 11 ], [ -3, 12 ], [ -3, 13 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -2, 6 ], [ -2, 7 ], [ -2, 8 ], [ -2, 9 ], [ -2, 10 ], [ -2, 11 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ -1, 7 ], [ -1, 8 ], [ -1, 9 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 3 ], [ 2, 4 ] ], "width": 3, "covered": true, "rise": 0 }, { "body": [ [ -11, -27 ], [ -11, -26 ], [ -11, -25 ], [ -11, -24 ], [ -11, -23 ], [ -11, -22 ], [ -11, -21 ], [ -11, -20 ], [ -10, -45 ], [ -10, -44 ], [ -10, -43 ], [ -10, -42 ], [ -10, -41 ], [ -10, -40 ], [ -10, -39 ], [ -10, -38 ], [ -10, -37 ], [ -10, -36 ], [ -10, -35 ], [ -10, -34 ], [ -10, -33 ], [ -10, -32 ], [ -10, -31 ], [ -10, -30 ], [ -10, -29 ], [ -10, -28 ], [ -10, -27 ], [ -10, -26 ], [ -10, -25 ], [ -10, -24 ], [ -10, -23 ], [ -10, -22 ], [ -10, -21 ], [ -10, -20 ], [ -10, -19 ], [ -10, -18 ], [ -10, -17 ], [ -9, -47 ], [ -9, -46 ], [ -9, -45 ], [ -9, -44 ], [ -9, -43 ], [ -9, -42 ], [ -9, -41 ], [ -9, -40 ], [ -9, -39 ], [ -9, -38 ], [ -9, -37 ], [ -9, -36 ], [ -9, -35 ], [ -9, -34 ], [ -9, -33 ], [ -9, -32 ], [ -9, -31 ], [ -9, -30 ], [ -9, -29 ], [ -9, -28 ], [ -9, -27 ], [ -9, -26 ], [ -9, -25 ], [ -9, -24 ], [ -9, -23 ], [ -9, -22 ], [ -9, -21 ], [ -9, -20 ], [ -9, -19 ], [ -9, -18 ], [ -9, -17 ], [ -9, -16 ], [ -9, -15 ], [ -9, -14 ], [ -9, -13 ], [ -8, -47 ], [ -8, -46 ], [ -8, -45 ], [ -8, -44 ], [ -8, -43 ], [ -8, -42 ], [ -8, -41 ], [ -8, -40 ], [ -8, -39 ], [ -8, -38 ], [ -8, -37 ], [ -8, -36 ], [ -8, -35 ], [ -8, -34 ], [ -8, -33 ], [ -8, -32 ], [ -8, -31 ], [ -8, -30 ], [ -8, -29 ], [ -8, -28 ], [ -8, -27 ], [ -8, -26 ], [ -8, -25 ], [ -8, -24 ], [ -8, -23 ], [ -8, -22 ], [ -8, -21 ], [ -8, -20 ], [ -8, -19 ], [ -8, -18 ], [ -8, -17 ], [ -8, -16 ], [ -8, -15 ], [ -8, -14 ], [ -8, -13 ], [ -8, -12 ], [ -8, -11 ], [ -8, -10 ], [ -7, -47 ], [ -7, -46 ], [ -7, -45 ], [ -7, -44 ], [ -7, -43 ], [ -7, -42 ], [ -7, -41 ], [ -7, -40 ], [ -7, -39 ], [ -7, -38 ], [ -7, -37 ], [ -7, -36 ], [ -7, -35 ], [ -7, -34 ], [ -7, -33 ], [ -7, -32 ], [ -7, -31 ], [ -7, -30 ], [ -7, -29 ], [ -7, -28 ], [ -7, -27 ], [ -7, -26 ], [ -7, -25 ], [ -7, -24 ], [ -7, -23 ], [ -7, -22 ], [ -7, -21 ], [ -7, -20 ], [ -7, -19 ], [ -7, -18 ], [ -7, -17 ], [ -7, -16 ], [ -7, -15 ], [ -7, -14 ], [ -7, -13 ], [ -7, -12 ], [ -7, -11 ], [ -7, -10 ], [ -7, -9 ], [ -7, -8 ], [ -7, -7 ], [ -7, -6 ], [ -6, -45 ], [ -6, -44 ], [ -6, -43 ], [ -6, -42 ], [ -6, -41 ], [ -6, -40 ], [ -6, -39 ], [ -6, -18 ], [ -6, -17 ], [ -6, -16 ], [ -6, -15 ], [ -6, -14 ], [ -6, -13 ], [ -6, -12 ], [ -6, -11 ], [ -6, -10 ], [ -6, -9 ], [ -6, -8 ], [ -6, -7 ], [ -6, -6 ], [ -6, -5 ], [ -6, -4 ], [ -6, -3 ], [ -5, -15 ], [ -5, -14 ], [ -5, -13 ], [ -5, -12 ], [ -5, -11 ], [ -5, -10 ], [ -5, -9 ], [ -5, -8 ], [ -5, -7 ], [ -5, -6 ], [ -5, -5 ], [ -5, -4 ], [ -5, -3 ], [ -5, -2 ], [ -5, -1 ], [ -5, 0 ], [ -5, 1 ], [ -4, -11 ], [ -4, -10 ], [ -4, -9 ], [ -4, -8 ], [ -4, -7 ], [ -4, -6 ], [ -4, -5 ], [ -4, -4 ], [ -4, -3 ], [ -4, -2 ], [ -4, -1 ], [ -4, 0 ], [ -4, 1 ], [ -4, 2 ], [ -3, -8 ], [ -3, -7 ], [ -3, -6 ], [ -3, -5 ], [ -3, -4 ], [ -3, -3 ], [ -3, -2 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ -3, 2 ], [ -2, -4 ], [ -2, -3 ], [ -2, -2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ -1, -1 ], [ -1, 0 ], [ -1, 1 ] ], "width": 3, "covered": false, "rise": 1 } ], "boundaries": [ { "plan": [ [ 0, 20 ], [ 0, 21 ], [ 0, 22 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 1, 10 ], [ 1, 11 ], [ 1, 12 ], [ 1, 13 ], [ 1, 14 ], [ 1, 15 ], [ 1, 16 ], [ 1, 17 ], [ 1, 18 ], [ 1, 19 ], [ 1, 20 ], [ 1, 22 ], [ 1, 23 ], [ 1, 24 ], [ 1, 25 ], [ 1, 26 ], [ 1, 27 ], [ 1, 28 ], [ 1, 29 ], [ 1, 30 ], [ 1, 31 ], [ 1, 32 ], [ 1, 33 ], [ 1, 34 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 34 ], [ 2, 35 ], [ 2, 36 ], [ 2, 37 ], [ 2, 38 ], [ 2, 39 ], [ 2, 40 ], [ 3, 40 ], [ 3, 41 ], [ 3, 42 ], [ 3, 43 ], [ 3, 44 ], [ 3, 45 ], [ 4, 45 ], [ 4, 46 ], [ 4, 47 ], [ 4, 48 ], [ 5, 48 ], [ 5, 49 ], [ 5, 50 ], [ 5, 51 ], [ 6, 51 ], [ 6, 52 ], [ 6, 53 ], [ 6, 54 ], [ 7, 54 ], [ 7, 55 ], [ 7, 56 ], [ 8, 56 ], [ 8, 57 ], [ 8, 58 ], [ 9, 58 ], [ 9, 59 ], [ 9, 60 ], [ 10, 60 ], [ 10, 61 ], [ 10, 62 ], [ 11, 62 ], [ 11, 63 ], [ 11, 64 ], [ 12, 64 ], [ 12, 65 ], [ 13, 65 ], [ 13, 66 ], [ 13, 67 ], [ 14, 67 ], [ 14, 68 ], [ 15, 68 ], [ 15, 69 ], [ 15, 70 ], [ 16, 70 ], [ 16, 71 ], [ 17, 71 ], [ 17, 72 ], [ 18, 72 ], [ 18, 73 ], [ 19, 73 ], [ 19, 74 ], [ 20, 74 ], [ 20, 75 ], [ 21, 75 ], [ 21, 76 ], [ 22, 76 ], [ 22, 77 ], [ 23, 77 ], [ 23, 78 ], [ 24, 78 ], [ 24, 79 ], [ 25, 79 ], [ 25, 80 ], [ 26, 80 ], [ 27, 80 ], [ 27, 81 ], [ 28, 81 ], [ 28, 82 ], [ 29, 82 ], [ 30, 82 ], [ 30, 83 ], [ 31, 83 ], [ 31, 84 ], [ 32, 84 ], [ 33, 84 ], [ 33, 85 ], [ 34, 85 ], [ 35, 85 ], [ 35, 86 ], [ 36, 86 ], [ 37, 86 ], [ 37, 87 ], [ 38, 87 ], [ 39, 87 ], [ 40, 87 ], [ 40, 88 ], [ 41, 88 ], [ 42, 88 ], [ 43, 88 ], [ 43, 89 ], [ 44, 89 ], [ 45, 89 ], [ 46, 89 ], [ 47, 89 ], [ 48, 89 ], [ 48, 90 ], [ 49, 90 ], [ 50, 90 ], [ 51, 90 ], [ 52, 90 ], [ 53, 90 ], [ 54, 90 ], [ 55, 90 ], [ 56, 90 ], [ 57, 90 ], [ 58, 90 ], [ 59, 90 ], [ 60, 90 ], [ 61, 89 ], [ 61, 90 ], [ 62, 89 ], [ 63, 89 ], [ 64, 89 ], [ 65, 89 ], [ 66, 88 ], [ 66, 89 ], [ 67, 88 ], [ 68, 88 ], [ 69, 87 ], [ 69, 88 ], [ 70, 87 ], [ 71, 87 ], [ 72, 86 ], [ 72, 87 ], [ 73, 86 ], [ 74, 85 ], [ 74, 86 ], [ 75, 85 ], [ 76, 84 ], [ 76, 85 ], [ 77, 84 ], [ 78, 83 ], [ 78, 84 ], [ 79, 82 ], [ 79, 83 ], [ 80, 82 ], [ 81, 81 ], [ 81, 82 ], [ 82, 80 ], [ 82, 81 ], [ 83, 79 ], [ 83, 80 ], [ 84, 79 ], [ 85, 78 ], [ 85, 79 ], [ 86, 77 ], [ 86, 78 ], [ 87, 75 ], [ 87, 76 ], [ 87, 77 ], [ 88, 74 ], [ 88, 75 ], [ 89, 73 ], [ 89, 74 ], [ 90, 72 ], [ 90, 73 ], [ 91, 70 ], [ 91, 71 ], [ 91, 72 ], [ 92, 69 ], [ 92, 70 ], [ 93, 68 ], [ 93, 69 ], [ 94, 66 ], [ 94, 67 ], [ 94, 68 ], [ 95, 64 ], [ 95, 65 ], [ 95, 66 ], [ 96, 62 ], [ 96, 63 ], [ 96, 64 ], [ 97, 59 ], [ 97, 60 ], [ 97, 61 ], [ 97, 62 ], [ 98, 0 ], [ 98, 1 ], [ 98, 2 ], [ 98, 56 ], [ 98, 57 ], [ 98, 58 ], [ 98, 59 ], [ 99, 2 ], [ 99, 3 ], [ 99, 4 ], [ 99, 5 ], [ 99, 6 ], [ 99, 7 ], [ 99, 53 ], [ 99, 54 ], [ 99, 55 ], [ 99, 56 ], [ 100, 7 ], [ 100, 8 ], [ 100, 9 ], [ 100, 10 ], [ 100, 11 ], [ 100, 12 ], [ 100, 49 ], [ 100, 50 ], [ 100, 51 ], [ 100, 52 ], [ 100, 53 ], [ 101, 12 ], [ 101, 13 ], [ 101, 14 ], [ 101, 15 ], [ 101, 16 ], [ 101, 17 ], [ 101, 18 ], [ 101, 19 ], [ 101, 43 ], [ 101, 44 ], [ 101, 45 ], [ 101, 46 ], [ 101, 47 ], [ 101, 48 ], [ 101, 49 ], [ 102, 19 ], [ 102, 20 ], [ 102, 21 ], [ 102, 22 ], [ 102, 23 ], [ 102, 24 ], [ 102, 25 ], [ 102, 26 ], [ 102, 27 ], [ 102, 28 ], [ 102, 29 ], [ 102, 30 ], [ 102, 31 ], [ 102, 32 ], [ 102, 33 ], [ 102, 34 ], [ 102, 35 ], [ 102, 36 ], [ 102, 37 ], [ 102, 38 ], [ 102, 39 ], [ 102, 40 ], [ 102, 41 ], [ 102, 42 ], [ 102, 43 ] ], "section_heights": [ 3 ] } ], "organization": [ { "positions": [ [ 0, 0, [ "building", "habitable", "composite" ] ], [ 50, 10, [ "building", "habitable", "composite" ] ], [ 20, 57, [ "building", "habitable", "composite" ] ] ], "topology": [ [ 0, "east", 1, "north", false, 3 ], [ 1, "south", 2, "east", true, 3 ], [ 2, "west", 0, "south", false, 3 ] ] } ], "legacy": [] }, "contact_signature": "77b588da798daaed99af70e6e0ea3d96976ed8c0dd332db209b05fd436688b98", "contact_cells": 83, "contact_replacements": 362, "sitework_occupied_cells": 1552, "excavated_solid_cells": 0, "furnishing_bays": 11, "omitted_optional_furnishing_bays": 0, "seconds": 2.9291 }
stress-00incompatible{"environment_seed": 2000, "structure_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, -0.12, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 5.127977154011788]}]}, -2, 18——100.0383
记录 / 诊断
{ "label": "stress-00", "inputs": { "environment_seed": 2000, "structure_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, -0.12, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 5.127977154011788 ] } ] }, -2, 18 ] }, "water": 12 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" }, "all_diagnostics": [ { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" } ], "seconds": 0.0383 }
stress-01incompatible{"environment_seed": 2001, "structure_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, 0.15, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 5.5323998011380935]}]}, -2,——100.0381
记录 / 诊断
{ "label": "stress-01", "inputs": { "environment_seed": 2001, "structure_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0.15, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 5.5323998011380935 ] } ] }, -2, 18 ] }, "water": null }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "site-relief", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Measured 7, permitted 5" }, "all_diagnostics": [ { "rule": "site-relief", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Measured 7, permitted 5" } ], "seconds": 0.0381 }
stress-02validated{"environment_seed": 2002, "structure_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, -0.12, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 4.736375910500318]}]}, -2,2538011110.2556edbd467cdaa9e5c9
记录 / 诊断
{ "label": "stress-02", "inputs": { "environment_seed": 2002, "structure_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.12, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 4.736375910500318 ] } ] }, -2, 18 ] }, "water": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 25380, "instances": 11, "digest": "56a113eafd951bdff55268e2728469082fe270762c181fd54c9180bee2eadce8", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "26c3acecc35900ad539f1b4cbc45357997eee4428d10105aeb7d28899929eda0", "contact_cells": 120, "contact_replacements": 115, "sitework_occupied_cells": 460, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2556 }
stress-03validated{"environment_seed": 2003, "structure_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, 0.15, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 5.447432368230461]}]}, -2, 4245711110.3608bb67d480f17c284a
记录 / 诊断
{ "label": "stress-03", "inputs": { "environment_seed": 2003, "structure_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0.15, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 5.447432368230461 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 42457, "instances": 11, "digest": "8909158d9eb47a8aca338070d3b1aba7de47ccb21266a75fb30f55bfd68b7378", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "bc40a50cedada960552f0914de90a59ed9fdd5e3fca45e0f4e37176c826a64f3", "contact_cells": 224, "contact_replacements": 196, "sitework_occupied_cells": 560, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3608 }
stress-04incompatible{"environment_seed": 2004, "structure_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, 0, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 4.852006635563001]}]}, -2, 18]——100.0375
记录 / 诊断
{ "label": "stress-04", "inputs": { "environment_seed": 2004, "structure_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 4.852006635563001 ] } ] }, -2, 18 ] }, "water": 12 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" }, "all_diagnostics": [ { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" } ], "seconds": 0.0375 }
stress-05validated{"environment_seed": 2005, "structure_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, 0, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 3.1088324431440615]}]}, -2, 182615111110.2687bd9a1df1c01caa35
记录 / 诊断
{ "label": "stress-05", "inputs": { "environment_seed": 2005, "structure_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 3.1088324431440615 ] } ] }, -2, 18 ] }, "water": null }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 26151, "instances": 11, "digest": "b976f7678578559581a53ccbd88437f12c2a5ff64ac0f3b2fda5e59422247b3c", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "d0350bd53f00143c0c229712f6fc97011ec3c9027464992564dbf7c012f2a4f7", "contact_cells": 153, "contact_replacements": 0, "sitework_occupied_cells": 440, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2687 }
stress-06validated{"environment_seed": 2006, "structure_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, 0, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 3.259766955719241]}]}, -2, 18]4399211110.36691679aea0df093302
记录 / 诊断
{ "label": "stress-06", "inputs": { "environment_seed": 2006, "structure_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 3.259766955719241 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 43992, "instances": 11, "digest": "c7b1286f112523b254d25bc9981f3a986c1a81f92fe80f8dd95c2fae2d8d74ab", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "5df40bcd464b9191b9bc9379ef36374fbf298f10d80d386d5246cc0002b935f8", "contact_cells": 222, "contact_replacements": 222, "sitework_occupied_cells": 558, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3669 }
stress-07incompatible{"environment_seed": 2007, "structure_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, -0.12, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 3.8208811336060533]}]}, -2——100.0371
记录 / 诊断
{ "label": "stress-07", "inputs": { "environment_seed": 2007, "structure_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, -0.12, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 3.8208811336060533 ] } ] }, -2, 18 ] }, "water": 12 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "site-relief", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Measured 6, permitted 5" }, "all_diagnostics": [ { "rule": "site-relief", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Measured 6, permitted 5" } ], "seconds": 0.0371 }
stress-08validated{"environment_seed": 2008, "structure_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.15, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 5.3468683245721005]}]}, -2, 182758011110.2824edbd467cdaa9e5c9
记录 / 诊断
{ "label": "stress-08", "inputs": { "environment_seed": 2008, "structure_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.15, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 5.3468683245721005 ] } ] }, -2, 18 ] }, "water": null }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 27580, "instances": 11, "digest": "0dc6cc248181f72b1a310f2981f6d13364ba06b5af56fa98990b9365ca67d882", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "6f8a51823b275fac0e454b60e768bbfbeb4479d8474d432b6012fc4525ae41f2", "contact_cells": 76, "contact_replacements": 65, "sitework_occupied_cells": 416, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2824 }
stress-09incompatible{"environment_seed": 2009, "structure_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, -0.12, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 4.043361591583398]}]}, -2,——100.0373
记录 / 诊断
{ "label": "stress-09", "inputs": { "environment_seed": 2009, "structure_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.12, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 4.043361591583398 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" }, "all_diagnostics": [ { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" } ], "seconds": 0.0373 }
stress-10incompatible{"environment_seed": 2010, "structure_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, 0.15, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 1.458550053272991]}]}, -2, ——100.0391
记录 / 诊断
{ "label": "stress-10", "inputs": { "environment_seed": 2010, "structure_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0.15, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 1.458550053272991 ] } ] }, -2, 18 ] }, "water": 12 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" }, "all_diagnostics": [ { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" } ], "seconds": 0.0391 }
stress-11validated{"environment_seed": 2011, "structure_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, -0.12, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 3.7543484663529205]}]}, -22046811110.2373bd9a1df1c01caa35
记录 / 诊断
{ "label": "stress-11", "inputs": { "environment_seed": 2011, "structure_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.12, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 3.7543484663529205 ] } ] }, -2, 18 ] }, "water": null }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 20468, "instances": 11, "digest": "cebdd423d64873707d44cdcf44541b8810fcb1930dcfb6b24c20f84090113e05", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "3e306b0ed1a7b911a181ebc0b76c0cb9a526e88e756f975c5de99917764ac39f", "contact_cells": 173, "contact_replacements": 0, "sitework_occupied_cells": 460, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2373 }
stress-12validated{"environment_seed": 2012, "structure_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, 0, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 2.160106859800824]}]}, -2, 18]3446611110.32131679aea0df093302
记录 / 诊断
{ "label": "stress-12", "inputs": { "environment_seed": 2012, "structure_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 2.160106859800824 ] } ] }, -2, 18 ] }, "water": null }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 34466, "instances": 11, "digest": "9d37150bee3847a5ae27276b99f13173b35e70c80d1e9bf82e7ebfc75a3bde82", "principal_signature": "1679aea0df093302e454f6ccf6703881cd06b629f120de87f789490160b6e89c", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 8 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 11 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "b7ba70092cec7a2642a423b42faf0b7779929cfcaa22ee44d70dc67b70d3373e", "contact_cells": 120, "contact_replacements": 4, "sitework_occupied_cells": 456, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3213 }
stress-13validated{"environment_seed": 2013, "structure_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, 0.15, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 4.2240852806150215]}]}, -2,4234711110.3477ec5f44d0f6975515
记录 / 诊断
{ "label": "stress-13", "inputs": { "environment_seed": 2013, "structure_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0.15, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 4.2240852806150215 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 42347, "instances": 11, "digest": "12e9d61f2cd03b86e16ada86a5519834cd15d61fbaba84976400da6264469fc0", "principal_signature": "ec5f44d0f6975515fc21a20289be497aaea90dc95032d9492d4c586b62478b8a", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 2 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "c27f36c598b0752385e5b02a9d87df8d03a409220c38ef23658e0c7fdbdd03ca", "contact_cells": 210, "contact_replacements": 186, "sitework_occupied_cells": 501, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3477 }
stress-14validated{"environment_seed": 2014, "structure_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 3.926160249756597]}]}, -2, 18]}, 2394611110.2413edbd467cdaa9e5c9
记录 / 诊断
{ "label": "stress-14", "inputs": { "environment_seed": 2014, "structure_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 3.926160249756597 ] } ] }, -2, 18 ] }, "water": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 23946, "instances": 11, "digest": "7f01712919736a2677f37fd093109462134aca7d27398b8c61db81a54b7e573a", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "39e1a134477a9ac10fc52ee9e3ac5be458d6309f7c1d4e39c89a70688daf6b47", "contact_cells": 62, "contact_replacements": 57, "sitework_occupied_cells": 402, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2413 }
stress-15validated{"environment_seed": 2015, "structure_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, -0.12, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 2.6696511722425527]}]}, -22875411110.2953bb67d480f17c284a
记录 / 诊断
{ "label": "stress-15", "inputs": { "environment_seed": 2015, "structure_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, -0.12, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 2.6696511722425527 ] } ] }, -2, 18 ] }, "water": null }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 28754, "instances": 11, "digest": "cabed212a02b37edf8963b521faa26ee09db54fb741f1a9bbab868bee129bad4", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "c4f9c949b6940d94dab311716e87f7af57cd6bd159f0ad80a2bb9f62a632b4c9", "contact_cells": 119, "contact_replacements": 0, "sitework_occupied_cells": 455, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2953 }
stress-16validated{"environment_seed": 2016, "structure_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.15, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 3.4778405659596]}]}, -2, 18]},4123411110.3379aa3186672b8bbfb0
记录 / 诊断
{ "label": "stress-16", "inputs": { "environment_seed": 2016, "structure_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.15, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 3.4778405659596 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 41234, "instances": 11, "digest": "a529c2695f288429695edaccb1f8878fcbb1e3206e813e7034e569a324a7fcc1", "principal_signature": "aa3186672b8bbfb02f76a87372d76faf204f808fbb90cbf61060dff477b89633", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 2, 11 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 3, 12 ], [ 3, 13 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 4, 13 ], [ 4, 14 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 5, 14 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": false, "rise": 0 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "7df86e05d24d6f6e597a944faebf3459c1fe628d6fc4b36f0bd7096c4280af7d", "contact_cells": 241, "contact_replacements": 241, "sitework_occupied_cells": 536, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3379 }
stress-17validated{"environment_seed": 2017, "structure_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, -0.12, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 4.183807193908317]}]}, -2,3254511110.2908bd9a1df1c01caa35
记录 / 诊断
{ "label": "stress-17", "inputs": { "environment_seed": 2017, "structure_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, -0.12, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 4.183807193908317 ] } ] }, -2, 18 ] }, "water": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 32545, "instances": 11, "digest": "b1129bd1faf746c5a75ebc2959af14ae7be6465ddb4b46db6ca3c78fadaa630e", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "f33a1eba875cd5ff95d5ac91edc05f93330f12c22b7a05a808d5f96da33a0436", "contact_cells": 150, "contact_replacements": 29, "sitework_occupied_cells": 437, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.2908 }
stress-18incompatible{"environment_seed": 2018, "structure_seed": 0, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, -0.12, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 3.8090902219637175]}]}, -2——100.0366
记录 / 诊断
{ "label": "stress-18", "inputs": { "environment_seed": 2018, "structure_seed": 0, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, -0.12, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 3.8090902219637175 ] } ] }, -2, 18 ] }, "water": 3 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "site-relief", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Measured 6, permitted 5" }, "all_diagnostics": [ { "rule": "site-relief", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Measured 6, permitted 5" } ], "seconds": 0.0366 }
stress-19incompatible{"environment_seed": 2019, "structure_seed": 1, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, 0, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 4.293290339558134]}]}, -2, 18]——100.0375
记录 / 诊断
{ "label": "stress-19", "inputs": { "environment_seed": 2019, "structure_seed": 1, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, 0, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 4.293290339558134 ] } ] }, -2, 18 ] }, "water": 12 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" }, "all_diagnostics": [ { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" } ], "seconds": 0.0375 }
stress-20validated{"environment_seed": 2020, "structure_seed": 2, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0, 0.15, 2]}, {"op": "wave", "args": [2, 0.13, 0.1, 0.531082071818544]}]}, -2, 18]4144211110.3601edbd467cdaa9e5c9
记录 / 诊断
{ "label": "stress-20", "inputs": { "environment_seed": 2020, "structure_seed": 2, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0, 0.15, 2 ] }, { "op": "wave", "args": [ 2, 0.13, 0.1, 0.531082071818544 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 41442, "instances": 11, "digest": "aea280f32f2943962d77be3bc9e2ec63c6e24f08b2b8011a8bd40a57b31ee765", "principal_signature": "edbd467cdaa9e5c99188ce608595f7b100a222db2bba8bf1a5d03f3051b464b8", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 1, 9 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 2, 10 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 3, 10 ], [ 3, 11 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 4, 11 ], [ 4, 12 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 5, 12 ], [ 5, 13 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 6, 13 ], [ 6, 14 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 7, 14 ], [ 7, 15 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 8, 14 ], [ 8, 15 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 9, 15 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 10, 15 ], [ 10, 16 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 11, 16 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 12, 17 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 13, 17 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "d54341de843572a14156545e952a3345c6994d11189226a847c03c35a80acb5b", "contact_cells": 259, "contact_replacements": 254, "sitework_occupied_cells": 599, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3601 }
stress-21validated{"environment_seed": 2021, "structure_seed": 3, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, 0.15, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 4.996091372713126]}]}, -2, 4809711110.3893bb67d480f17c284a
记录 / 诊断
{ "label": "stress-21", "inputs": { "environment_seed": 2021, "structure_seed": 3, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0.15, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 4.996091372713126 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 48097, "instances": 11, "digest": "dc1c090b8874c47dbee2688f6a76614526db3c1d8da79745de79672e7a17a719", "principal_signature": "bb67d480f17c284a7717d74afb5e28ddc517006546c5e763fba9b9e49cb0e8e3", "structure": { "halls": [], "links": [ { "body": [ [ -3, 3 ], [ -3, 4 ], [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -2, 5 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ -1, 6 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 0, 6 ], [ 0, 7 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], [ 1, 8 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 2, 8 ], [ 2, 9 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 3, 9 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 4, 10 ], [ 5, 4 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 5, 10 ], [ 5, 11 ], [ 6, 4 ], [ 6, 5 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 6, 11 ], [ 6, 12 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 7, 12 ], [ 7, 13 ], [ 8, 6 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 8, 13 ], [ 9, 7 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 9, 14 ], [ 10, 8 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 9 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 11, 15 ], [ 12, 9 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 12, 16 ], [ 13, 10 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 13, 16 ], [ 14, 10 ], [ 14, 11 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 14, 17 ], [ 15, 11 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 15, 17 ], [ 15, 18 ], [ 16, 12 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 12 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 13 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 13 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 14 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ], [ 21, 15 ], [ 21, 16 ] ], "width": 5, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "ebc2a713446f72ec0b986486061c398c0b7d5c2c6731838b996c7446c933403f", "contact_cells": 226, "contact_replacements": 161, "sitework_occupied_cells": 562, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3893 }
stress-22incompatible{"environment_seed": 2022, "structure_seed": 4, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.12, -0.12, 2]}, {"op": "wave", "args": [4, 0.13, 0.1, 0.6846606616314093]}]}, -2——100.036
记录 / 诊断
{ "label": "stress-22", "inputs": { "environment_seed": 2022, "structure_seed": 4, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.12, -0.12, 2 ] }, { "op": "wave", "args": [ 4, 0.13, 0.1, 0.6846606616314093 ] } ] }, -2, 18 ] }, "water": 9 }, "candidate_attempts": 1, "accepted_candidates": 0, "retries": 0, "status": "incompatible", "diagnostic": { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" }, "all_diagnostics": [ { "rule": "support-height", "component": "/a", "position": [ 0, 0, 0 ], "conditions": "Bounded support depth exceeded" } ], "seconds": 0.036 }
stress-23validated{"environment_seed": 2023, "structure_seed": 5, "expression": {"op": "clamp", "args": [{"op": "add", "args": [{"op": "gradient", "args": [0.28, 0.15, 2]}, {"op": "wave", "args": [0, 0.13, 0.1, 0.6595355529528357]}]}, -2,4319911110.3724bd9a1df1c01caa35
记录 / 诊断
{ "label": "stress-23", "inputs": { "environment_seed": 2023, "structure_seed": 5, "expression": { "op": "clamp", "args": [ { "op": "add", "args": [ { "op": "gradient", "args": [ 0.28, 0.15, 2 ] }, { "op": "wave", "args": [ 0, 0.13, 0.1, 0.6595355529528357 ] } ] }, -2, 18 ] }, "water": 3 }, "candidate_attempts": 1, "accepted_candidates": 1, "retries": 0, "status": "validated", "blocks": 43199, "instances": 11, "digest": "e82026f5ac9966affa808b4c554e2f82ce41ae8424e480e2626a61954c7ea408", "principal_signature": "bd9a1df1c01caa357fc14f5775b9d73f24cb0bd735abdc4de10d5e3e10905937", "structure": { "halls": [], "links": [ { "body": [ [ -2, 1 ], [ -2, 2 ], [ -2, 3 ], [ -2, 4 ], [ -1, 1 ], [ -1, 2 ], [ -1, 3 ], [ -1, 4 ], [ -1, 5 ], [ 0, 1 ], [ 0, 2 ], [ 0, 3 ], [ 0, 4 ], [ 0, 5 ], [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ], [ 2, 7 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ], [ 3, 6 ], [ 3, 7 ], [ 3, 8 ], [ 4, 4 ], [ 4, 5 ], [ 4, 6 ], [ 4, 7 ], [ 4, 8 ], [ 4, 9 ], [ 5, 5 ], [ 5, 6 ], [ 5, 7 ], [ 5, 8 ], [ 5, 9 ], [ 6, 6 ], [ 6, 7 ], [ 6, 8 ], [ 6, 9 ], [ 6, 10 ], [ 7, 6 ], [ 7, 7 ], [ 7, 8 ], [ 7, 9 ], [ 7, 10 ], [ 7, 11 ], [ 8, 7 ], [ 8, 8 ], [ 8, 9 ], [ 8, 10 ], [ 8, 11 ], [ 8, 12 ], [ 9, 8 ], [ 9, 9 ], [ 9, 10 ], [ 9, 11 ], [ 9, 12 ], [ 9, 13 ], [ 10, 9 ], [ 10, 10 ], [ 10, 11 ], [ 10, 12 ], [ 10, 13 ], [ 10, 14 ], [ 11, 10 ], [ 11, 11 ], [ 11, 12 ], [ 11, 13 ], [ 11, 14 ], [ 12, 10 ], [ 12, 11 ], [ 12, 12 ], [ 12, 13 ], [ 12, 14 ], [ 12, 15 ], [ 13, 11 ], [ 13, 12 ], [ 13, 13 ], [ 13, 14 ], [ 13, 15 ], [ 14, 12 ], [ 14, 13 ], [ 14, 14 ], [ 14, 15 ], [ 14, 16 ], [ 15, 12 ], [ 15, 13 ], [ 15, 14 ], [ 15, 15 ], [ 15, 16 ], [ 16, 13 ], [ 16, 14 ], [ 16, 15 ], [ 16, 16 ], [ 16, 17 ], [ 16, 18 ], [ 17, 13 ], [ 17, 14 ], [ 17, 15 ], [ 17, 16 ], [ 17, 17 ], [ 17, 18 ], [ 18, 14 ], [ 18, 15 ], [ 18, 16 ], [ 18, 17 ], [ 18, 18 ], [ 19, 14 ], [ 19, 15 ], [ 19, 16 ], [ 19, 17 ], [ 19, 18 ], [ 20, 15 ], [ 20, 16 ], [ 20, 17 ], [ 20, 18 ] ], "width": 3, "covered": true, "rise": 1 } ], "boundaries": [], "organization": [], "legacy": [] }, "contact_signature": "4c70c55393aa0a67a732a5f42f966584c1dcac11467443e827fc811a157cc425", "contact_cells": 115, "contact_replacements": 10, "sitework_occupied_cells": 402, "excavated_solid_cells": 0, "furnishing_bays": 0, "omitted_optional_furnishing_bays": 0, "seconds": 0.3724 }

汇总 JSON · 完整逐条结果 · 冻结环境

12 · 验收与报告独立复验

Harness 的五项检查

命令退出码用时 / s结果
default011.814通过
seed-0-a011.407通过
seed-0-b011.396通过
seed-107.08通过
tests0129.006通过

完整 suite 为 179 个测试,涵盖原行为与新增几何、变换、权限失败、连接、功能位、读回和再生成。报告在隔离、无网络、无凭据的原镜像副本中再次执行,输出如下。首次复验漏配 MCIO 的 import 路径而产生 22 个导入失败;修正复验环境后重新执行,没有改生成器或删除测试。

原生独立测试原始日志
........................................................................ [ 40%] ........................................................................ [ 80%] ................................... [100%] 179 passed in 133.17s (0:02:13)

本轮真实浏览器生成与下载复验

16 / 16浏览器与原生结果一致
8 / 8下载建筑与结构记录读回一致
23 / 23浏览器交互检查通过
0浏览器页面异常

本机浏览器实测单体与边界 Python 执行约 1.65–3.36 秒,分支建筑群约 18.59 秒,环形群约 19.28 秒,均包含生成与导出读回,不包含首次运行时下载和渲染。这是当前设备上的观察,不是性能保证。

使用新归档的原始 Python 包,运行手动厅堂、斜桥、曲线边界、两个建筑群和随机结构入口。检查 seed 重放、结构参数确实生效、实际方块查询、下载后原生读回、剖切不改导出、错误可见、停止及恢复。有限向量的浏览器/原生一致性不能推广到所有 seed。

browser-verification.json
{ "samples": [ { "label": "hall-0", "seed": "0", "digest": "59e1430a41528e7d14d96fe98b2d7a91a3abf5aceac9fa022bcd51724240847d", "signature": "81ea09ec692c6ce969d9b8a690a89e1ee2bfd8eb4482a0938799c1f2a77a389b", "blocks": 27282, "components": 34, "python_s": 3.0895, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "hall-replay", "seed": "0", "digest": "59e1430a41528e7d14d96fe98b2d7a91a3abf5aceac9fa022bcd51724240847d", "signature": "81ea09ec692c6ce969d9b8a690a89e1ee2bfd8eb4482a0938799c1f2a77a389b", "blocks": 27282, "components": 34, "python_s": 3.0491000010000002, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "hall-width25", "seed": "0", "digest": "103c8899d45b3b1b7295d2745106c770842a845dc4d5fe2febf6a23414db7040", "signature": "3b6c389201162e274ae29ce92549d81c43e84383fd4ebe47814c62c2520e5eca", "blocks": 27803, "components": 40, "python_s": 3.313899999, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "hall-shape", "seed": "0", "digest": "9715c2e9091aafb910c7a9eece69b5b538e4579b9a9dce49e52463c04521a525", "signature": "db6c4e82dccfc8c143807f78b9d2417da22d149d2001e65b92486bc0dd61cac6", "blocks": 27755, "components": 38, "python_s": 3.2384999999999984, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "hall-environment5", "seed": "0", "digest": "b781bf8c7e0e936f93d6650e87e52a0d159c0fba11af9bb3144c8fc89cda29e6", "signature": "db6c4e82dccfc8c143807f78b9d2417da22d149d2001e65b92486bc0dd61cac6", "blocks": 27765, "components": 38, "python_s": 3.2917999999999985, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "large-seed", "seed": "9223372036854775807", "digest": "18b3f14832b05dd7e883d6e5abc8a0a3be2c669b2bcd7615a938b1eabf2ad17f", "signature": "db6c4e82dccfc8c143807f78b9d2417da22d149d2001e65b92486bc0dd61cac6", "blocks": 27765, "components": 38, "python_s": 3.245899999999999, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "connector-covered", "seed": "0", "digest": "4259710491293323c3f6b0aea50ab298505e9a3a3f5fcda9a384544a31909116", "signature": "36ed770d7338cddf866cbd112fe0f0b376291b1e14c87a4f4ff41a3b5accebf2", "blocks": 19928, "components": 11, "python_s": 2.0187000010000027, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "connector-wide", "seed": "0", "digest": "f4691a721806746675b80d36ec41873a0621cf7ea51aa8df0f35223c303c9c01", "signature": "102d7936c9406f96ed47d5fbad7b6e1643379bd44a88050b8abe20d9a56d9f44", "blocks": 19799, "components": 11, "python_s": 2.043900001000001, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "boundary-10", "seed": "0", "digest": "83a86fda8d892a00be79cd3f45fb57a53283a1077d6f4477e751ce65db19a478", "signature": "6d0587c91c577967d10ec222644e700e223aec948883b417d9b9843d1e83f01e", "blocks": 19575, "components": 12, "python_s": 1.6450000000000031, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "boundary-23", "seed": "0", "digest": "769ae7f190015ef8882f4a927bc0abb6a5d5ca67ed8993ca9d356fac4e4302e3", "signature": "4eee8624bb42e4f63e3d65fcb5631ef91a21cb739a7c747ef51221d862bf06ab", "blocks": 19575, "components": 12, "python_s": 1.6669999999999945, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "campus-0", "seed": "0", "digest": "57d7f6afe22a301ac06f769c1c9c9962c53ea3fc878e7d494d2a5d0eef47c669", "signature": "e40fe6ff2919877f7195099f22b1647ac40041c57944ba2e8c1f4488446b67f6", "blocks": 119395, "components": 446, "python_s": 18.594200000999997, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "perimeter-3-7", "seed": "3", "digest": "d1fcbf2f4a2d54192a35864cdb4d03d822d9e4e7cb1dbf44edf2d769431e699a", "signature": "e582861768e396b4f060b4aabca0b55e914ddc89cbf104c85dc2411bcad265a7", "blocks": 132838, "components": 395, "python_s": 19.278800000999993, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "explore-17", "seed": "17", "digest": "55660718d3a47bb574e2cbbb6f2f798bcac2249c778965f2ac1d5f46e5ea318d", "signature": "f0b113deabced909ba038a91c2c2d6e77cd5903228692e85f357e0ccc5f61628", "blocks": 26768, "components": 25, "python_s": 2.6266999999999996, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "explore-18", "seed": "18", "digest": "4d7ab3ec1c6a10b0499cd4ebdb7b76a0eeff85dd493233e01eccf772af1e53e9", "signature": "d4db8c5a6ef23b7bec797413993ad9b0c9ca128b3fd4f5ccc5dab34d32be90ed", "blocks": 27269, "components": 33, "python_s": 2.9387000000000114, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "custom-python", "seed": "4", "digest": "d12e14ab6f048cbc13c10a583a7b58c4227493fbf5acda804b3e78ef48fd3b69", "signature": "d99e9bd0014a8171b17a56b106a7add74c095802932bf3f9e7f74db7771b08d2", "blocks": 27086, "components": 31, "python_s": 2.827299999999994, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } }, { "label": "after-cancel", "seed": "0", "digest": "9715c2e9091aafb910c7a9eece69b5b538e4579b9a9dce49e52463c04521a525", "signature": "db6c4e82dccfc8c143807f78b9d2417da22d149d2001e65b92486bc0dd61cac6", "blocks": 27755, "components": 38, "python_s": 3.3641999999999994, "runtime": { "python": "3.12.7", "numpy": "2.0.2", "platform": "Emscripten" } } ], "checks": { "seed_replay": true, "real_glass_ancestry": true, "ancestor_membership": true, "width_changes_structure": true, "shape_controls_change_structure": true, "environment_keeps_structure": true, "exact_integer_seed": true, "bend_changes_structure": true, "original_perimeter_digest": true, "explore_button_runs_sampler": true, "seed_button_preserves_client": true, "explore_changes_structure": true, "edited_python_executed": true, "cutaway_preserves_content": true, "pointer_queries_real_block": true, "mobile_no_horizontal_overflow": true, "invalid_seed_rejected": true, "error_visible": true, "stale_export_disabled": true, "cancel_stops_worker": true, "recovery_after_cancel": true, "mermaid_rendered": true, "charts_rendered": true }, "page_errors": [], "reviewed_at": "2026-09-27T03:50:48.653Z" }
native-browser-comparison.json
{ "samples": [ { "label": "hall-0", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 1.5539056429988705, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "hall-replay", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 1.487864183000056, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "hall-width25", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 1.6368600230052834, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "hall-shape", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 1.6343052349984646, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "hall-environment5", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 1.593248933000723, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "large-seed", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 1.5941087579994928, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "connector-covered", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 0.990013374001137, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "connector-wide", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 0.9883708790002856, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "boundary-10", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 0.8173881039983826, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "boundary-23", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 0.8126298660063185, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "campus-0", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 9.082773257003282, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "perimeter-3-7", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 9.993604011993739, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "explore-17", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 1.4336201789992629, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "explore-18", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 1.4512149929942098, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "custom-python", "checks": { "digest": true, "signature": true, "sample_query": true, "download_digest": true, "download_all_nodes": true, "download_relations": true, "download_dependencies": true, "download_operations": true, "download_port_uses": true, "download_displaced": true, "download_erasures": true, "download_query": true }, "native_seconds": 1.4004626050009392, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } }, { "label": "after-cancel", "checks": { "digest": true, "signature": true, "sample_query": true }, "native_seconds": 1.6096793539909413, "native_runtime": { "python": "3.12.13", "numpy": "2.5.3", "platform": "Linux" } } ], "cutaway_download_unchanged": true, "passed": true, "scope": "Finite cross-platform content, actual downloaded files, full structural nodes and glass query. No exhaustive seed claim." }

公网复验已通过:在已发布 URL 上重新运行多边形建筑,生成 27,282 方块,摘要与本地一致;实际查询得到 window.shuttered → extension.polygon-shell → extension.pavilion,并成功下载 ZIP,页面异常为 0。公网页面验收记录。

完整 harness 报告 · 独立测试日志。浏览器端下载 Python 运行时和纹理,首次打开需要联网;生成过程不调用模型。worker 中执行的是编辑器中的 Python,不把 Python 翻译成预制 JavaScript 模型。

13 · 开发失败与修复:哪些没有被藏起来

问题修复意义
连接需要读取受限端口内核区分 connect 与编辑授权独立扩展揭示公共协议缺口
仅换连接 recipe,宿主仍陈旧显式 replacements 与有序原子重放耦合修改不通过绕过依赖来解决
三格入口和窗户装饰碰撞立面窗口留白规则修正通用构造而非单个 seed
长曲线超预算BoundaryChain 分段并透传挂点高阶组合增加范围,低阶预算仍有效
端点裁剪破坏弯折路线只裁剪最近端点保留折线回归用例
宽连接吞掉窄接近口读取端口区域后逐渐展开根据环境接口调形
宽厅堂内部太空加入功能位分配,保护通路完善使用逻辑,但美学仍需观察
测试误用 chain.instance/View.clearance纠正为既有 id/View.clear测试自身错误,不包装成生成器缺陷
本轮完整 development findings

Extension development findings

The original library was retained. reports/extensions-baseline/ records the public protocol and 45 original module/test/program/document hashes before kernel changes. New components were developed in hearth_extensions/; no reference implementation was invoked or modified.

Evidence Finding Resolution
../extensions-baseline/failing-connect-probe.txt A read-only endpoint consumer was rejected because a landing also offered a restricted resurfacing grant A connect binding consumes capacity and records relationships/dependencies but never acquires mutation authority. A negative test rejects attempted host writes.
first-geometry-probes.txt The new test incorrectly expected chain entries to use instance Corrected the test to the existing public id key; no protocol change or weakened assertion.
geometry-probes-2.txt Window shutters intruded into a three-wide entrance approach The shared polygon facade grid moves the second window bay outward. All three shape variants then preserve approach headroom.
client-probes.txt A requested curve exceeded one segment's 220-cell domain; another contour ran too close to occupied approach geometry Added BoundaryChain using forwarded public mount interfaces and bounded segments. The client declares a perimeter outside its buildings. No locked building was moved and the per-segment limit was retained.
client-probes-2.txt Global endpoint clipping planes severed a bent route, including same-Z endpoints The shared ribbon geometry applies caps only at their own nearest endpoint. A separate kinked polyline test prevents regression.
Endpoint integration during client development Broad connector mouths could overlap narrow host approach margins A connector reads the port region, retains the offered mouth width, and flares to body width after the first stations. Host ownership stays unchanged.
focused-tests.txt Link-only regeneration correctly left surveyed endpoint hosts stale Exposed the need to replay hosts first while replacing the later connector. The kernel continued to reject stale completion.
../extensions-baseline/failing-replay-probe.txt The proposed public call could not replace a target later in a coupled replay Added the optional explicit replacements mapping. Unknown/duplicate targets reject; ordered replay remains one atomic transaction. No stale-flag bypass.
previews/extensions/development/ The new organization was readable but the landscape sparse Reused the existing public landscape component inside the graph composition with declared minimum counts.
first-assessment/ First complete 112-input batch, all supported inputs valid; nine bounded stress failures Retained all outcomes. Corrected the contact metric to include actual boundary support coordinates and distinguished current sitework cells from edit records. This was a metric refinement, not a new architectural type count.
previews/extensions/pre-interior/ and pre-interior-assessment/ Close cutaways showed small inherited furniture groupings in broad halls Added public WorkBay and HallInterior components: scaled allocation, interaction ports, actual inventory/support checks and protected central aisles. Locked architecture and terrain stay intact.
interior-tests.txt The new test used a nonexistent View.clearance convenience name Corrected it to the existing View.clear(port.region) API. The six actual generation/validation cases had already succeeded.
interior-tests-final.txt, full-regression.txt, final/ Final interior and complete regressions pass; same 112 principal inputs retain the same outcome counts 179 full tests, 88/88 supported inputs, 15/24 stress inputs, nine retained incompatibilities. No optional furnishing omissions.

Only hearth/kernel/scene.py changed within the original kernel. The change was necessary in both cases because authority negotiation and coordinated replay are kernel responsibilities; extension-only code could not legitimately bypass them. Original source/test hashes and the final delta are compared in api-final.json. All original tests, examples, concrete components, environment code, persistence code and the default CLI remain unchanged. The public component/plan/contract schemas and companion format are unchanged; the library version is 1.2.0.

The extension does not inspect private host fields or mutate shared storage. Read-only public contracts and ports guide composition; effects return through the kernel. Its actual-geometry custom validators use the standard registration extension point. Analysis code reads public node records to measure signatures. Destructive mutations appear only in deliberate negative tests.

Later assessment conveniences add --samples so new runs retain separate artifact destinations and use the full explicit root environment seed for boundary replay. --focus is a preview-only crop through the supplied proc slicer, selected from a public contract envelope. It never changes a valid source scene or claims that the incomplete geometry slice has its semantic metadata.

The original 134-test, 64-pair and stress evidence is not rewritten. The new exercise also does not reinterpret the user's external browser report as validation of new code. Remaining constraints, sample denominators, timing and rendering limits are stated in ASSESSMENT.md and the package guide.

模型的完整 assessment(与报告复验区分)

Extension-phase assessment

This is a self-authored implementation and finite extension exercise, not an independent audit. It supplements the unchanged first-phase evidence in reports/ASSESSMENT.md and reports/final-corpus/. All original tests remain present and unchanged.

Executed checks

  • Full regression: 179 passed in 128.25 seconds. This includes all 134 original tests and 45 new protocol, geometry, failure and interior cases. No skipped/removed old tests.
  • Artifact audit: 13/13 selected pairs regenerated and reloaded identically. It compares complete nodes, structural relations, dependencies, operations, port uses, displacement records, inventories and reverse indexes, with 1,745 current-cell queries, one per nonempty component. There are 51 inventory-bearing blocks across these samples.
  • New hash-seed replay: perimeter program, structure seed 3/environment seed 7, PYTHONHASHSEED=5 and 918273, identical semantic geometry, principal signature, all 395 nodes, and the same real window/shell/pavilion query. Semantic digest: d1fcbf2f4a2d54192a35864cdb4d03d822d9e4e7cb1dbf44edf2d769431e699a.
  • Original default replay: two unchanged CLI seed-zero runs with PYTHONHASHSEED=3 and 8675309, both retaining the first-delivery semantic digest e81b08063278b231b60eaa16e4120973ed688bb3fd7e6a8da439daa4e7f5caf9.
  • Original CLI check, original_cli entries: no-argument generation writes output.litematic in a temporary working directory, 125,475 blocks/782 nodes; seed 1 writes an absolute path containing spaces, 90,100 blocks/527 nodes. Both validate and reload. This file's artifact rows describe the preserved pre-interior revision, not the final samples.
  • Headless inspection: deck, glass and mounted light queries and exact membership survive a fresh export/reload. The original output.litematic pair was not replaced by the new clients.

The import guard test executes generation without allowing imports of numpy, MCIO, scipy, shapely or ctypes. That establishes the native pure-Python dependency boundary. The user's report of eleven prior browser runs and six prior downloaded pairs concerns the earlier revision; no new Pyodide execution or browser artifact download was performed here.

Sampling and outcomes

sampling-policy.json was recorded before assessment. The root seed is 0. The original field generator, parameter recipe and explicit seeds are in every result row. Eight connector terrains are frozen independently before six structure seeds are placed on copies. Four independent dry terrains receive four curve choices each. Other hall, graph and stress inputs are also generated/finalized before structure placement. Zero wave/gradient values and straight curves provide degenerate inputs from the same operations. A separate test uses a kinked route and asymmetric polygon absent from the shipped clients. No named environment-family selector or seed-specific adaptation exists.

The interior refinement policy reran exactly the same principal inputs after visual inspection. It did not move buildings, reshape terrain or relax contact limits.

Group Valid inputs / inputs Accepted complete candidates / attempts Incompatible Retries Exhausted / defects Principal signatures Contact signatures Seconds
Diagonal/bending connectors 48/48 48/48 0 0 0/0 6 48 13.342
Curve boundaries 16/16 16/16 0 0 0/0 4 16 2.763
Polygon halls 12/12 12/12 0 0 0/0 12 12 8.403
Branching campus 6/6 6/6 0 0 0/0 6 6 25.967
Perimeter circuit 6/6 6/6 0 0 0/0 6 6 24.688
Bounded stress 15/24 15/24 9 0 0/0 6 15 5.065

Thus 88/88 supported-domain inputs validated and 15/24 (62.5%) stress inputs validated. All 112 rows are retained in final/results.json, with summary.json and independently recorded frozen inputs. Each input proposes one complete locked composition; input success and candidate acceptance have the same denominators here. These numbers do not conceal retries of full candidates. Deterministic profile propagation and feasible furnishing allocation happen within each candidate and are not counted as extra accepted builds. No resampling was used to replace difficult stress inputs.

Times total 80.228 seconds across measured rows. They include selected artifact export/reload and exclude terrain-freezing time outside those rows, rendering and the later audit. They were measured on this host during development and are not isolated performance benchmarks.

Retained stress incompatibilities

The stress recipe uses gradients through 0.28, waves through 4, water levels through 12 and locked platform positions. All nine rejections occur at /a during its public site survey:

Input Environment seed Rule Constraint
stress-00 2000 support-height Existing maximum bed-to-floor support depth 8 exceeded
stress-01 2001 site-relief Measured 7, permitted 5
stress-04 2004 support-height Depth bound exceeded
stress-07 2007 site-relief Measured 6, permitted 5
stress-09 2009 support-height Depth bound exceeded
stress-10 2010 support-height Depth bound exceeded
stress-18 2018 site-relief Measured 6, permitted 5
stress-19 2019 support-height Depth bound exceeded
stress-22 2022 support-height Depth bound exceeded

Those are established incompatibilities with the requested component policy, not proofs that no other engineering technique could work. The second phase's 24-input stress recipe differs from the first phase's 32 inputs, so 62.5% is not a comparative improvement claim over 9/32. All failures remain replayable from their generating expressions, parameters and seeds.

Actual costs and observed diversity

Group Current foundation/approach/trestle cells Sitework displacement records All current sitework/deck cells
Connector 3..108 0..100 294..445
Boundary 0 0 168..224
Hall 38..71 6..9 38..71
Campus 132..206 232..318 1,374..1,593
Perimeter 82..129 256..451 1,539..1,597
Successful stress 62..259 0..254 402..599

These are actual current cells and retained displacement records, rather than estimates from boxes. The broad sitework count includes above-ground boundary masonry and decks; it is not excavation volume. No solid cell was excavated to non-solid state in this new corpus. Original pool excavation tests remain in the full suite. Boundary support signatures record actual substrate coordinates even though the boundary itself writes no footing/fill cells.

Principal signatures use realized polygon footprints, height, function and entrance topology, hip/lantern intent, legacy room/storey/roof structure, ribbon plan/width/cover, contour shape/height, and graph placement/connectivity. They exclude names, materials, global transforms and measured foundation heights. Contact profiles and supports have separate signatures. Furniture bay counts are reported separately and never inflate the principal signatures: halls have 2..8 bays, branching campuses 8..12 total, and perimeter circuits 9..11 total. All requested optional bays fit in this corpus; recorded optional omissions total 0. Required counts were never relaxed.

The 48 connector runs intentionally repeat six principal connection intents across eight independent environments. Six principal and 48 contact signatures are the expected separation, not a claim of 48 architectural types. The halls span broad/chamfered and asymmetric tested shapes beyond the old bay grid; the graph programs change organization, counts and massing. The finite signature counts do not estimate or enumerate the space of possible combinations.

Visual evidence and limits

Preview notes label sources, seeds, camera angles and cutaways. There are 26 final images: three exterior views for each of five representative artifacts, floor/connection sections where applicable, and four focused hall views. Historical development and pre-interior views are retained separately. Geometry-only cuts have no trustworthy structural companion; all identity/NBT checks use the full original pairs.

Inspection found that the old small furnishing grouping underfilled wider halls. HallInterior now allocates functional stations around protected aisles; close views show their distribution and clear doors. Other views show open/covered diagonal links, actual-bed contact across water, the branching and circuit organizations, broad hip roofs and continuous stepped curve masonry. The final reports do not omit the earlier failures or the nine final stress rejections.

Remaining limits are real: discrete movement and light models, a bounded-span support approximation, no arbitrary roof junction solver, simple open curves, cardinal entrance frames, finite footprint domains, explicit graph placement and coarse explicit co-regeneration. Landscapes retain broad open lawns and furnishings use compact stations; this is not an exhaustive claim of aesthetic quality. The connector's point endpoint offers are not substitutes for broad platform junctions. New clients use public interfaces throughout, but future architectural techniques still require implementing components. No browser rerun, viewer, deployment or autonomous city planner is included.

Replay

python -m pytest -q test python -m examples.extension_assess --seed 0 --output reports/extension-reassessment --artifacts --samples samples/extension-reassessment python -m examples.extension_audit --seed 0 --manifest samples/extension-reassessment/replay-manifest.json --output reports/extension-reassessment/artifact-audit.json --cli python -m examples.extension_replay --seed 3 --environment-seed 7 --output reports/extension-reassessment/replay.json

The first-assessment/ directory retains the first completed new batch. pre-interior-assessment/ retains the later complete pre-refinement batch, its tests/audit and a manifest pointing to 13 matching historical pairs in samples/extensions/pre-interior/. Their old result-row artifact paths describe their original run destinations; use the preserved manifest to locate those exact historical pairs. The new final report and samples/extensions/replay-manifest.json describe the delivered revision.

14 · 原始需求继续生效

以下台账来自交付文档。第二轮没有另造一套较弱要求:原始自动 provenance、合理接口、高阶轻客户端、环境泛化、真实验证和可重放仍适用。但“台账里写了支持”不是穷尽性证明,应结合负例、代码和上面的实际样本判断。

ID Implemented API/module and evidence Qualification
R01 kernel/*, initial design, seven foundation tests before content; thin CLI Executable foundation, not placeholder interfaces
R02 Independent implementation; supplied snapshots unchanged; reference images used as aesthetic goals No reference generator invoked or imported
R03 Blueprint, room graph programs, Choice, roof planner, spine/loop paths; finite signatures Room grid and roof primitives are bounded, openly documented
R04 Module table in architecture; kernel has no component imports; transport separate Browser host adapter not implemented
R05 Capability, executable Domain, Contract, Port, Grant, rules and read-only View Free-form descriptive assumptions complement executable checks
R06 Plan/Child/Choice, registry, composition operations, forwarded ports; extension/nested tests New primitives can extend beyond the shipped grid vocabulary
R07 Scoped authority, whole-object replacement, shared support; tree/grass/pool/window/clearance tests No universal priority or same-state sharing shortcut
R08 Fork/validate/commit kernel, plans and automatic read traces; rollback snapshots Trusted Python components, not a hostile-code sandbox
R09 Open/complete scopes, ancestor-aware obligations, finalization; unfinished/light and late-edit tests Standalone landing-to-public-path is an enclosing obligation
R10 Automatic nodes/operation owners, real window/wall instances; inspection and cross-scope attachment tests No per-voxel client owner maps or post-hoc tagging
R11 Structural graph, dependency graph, operations/displacement records; update/share/removal tests Historic actors may remain in history, never as current owners
R12 inspect, owner/shared reverse indexes, semantic descendant index; regeneration and deletion tests Headless queries delivered; no clickable viewer
R13 Paired JSON/Litematica, version/digest/offset checks, actual reload validation; mismatch/NBT tests Pairing integrity is not cryptographic authenticity
R14 General field algebra, masks, transforms, strata, water and constrained scattering No environment-family dispatch; finite shipped operations are extensible
R15 Domain/version-aware 3D view, elevation cap, support/water/slope/clearance/style/preferences Unknown space errors; no simulation of every Minecraft behavior
R16 Foundation, approach, window-depth and roof-abutment components Universal roof-junction/flashing solver not implemented
R17 Frozen terrain, measured site survey, bounded complete candidates, joint tentative validation Fixed principal intent; failures beyond bounds are retained
R18 Hard checks then actual effect cost/exposure score, seeded near-best choice, rejection records Search-budget negative test; no claim of exhaustive feasibility
R19 Automatic/declared input dependencies, stale flags, explicit atomic co-regeneration Dependency updates are conservative; no implicit arbitrary auto-replan
R20 SHA-256 scope keys/purposes, overrides, copied environments; branch/order/retry and hash-seed replay tests Genuine spatial dependencies may change descendants
R21 Configurable Limits, SiteLimits, effect envelopes and realized export bounds Demonstration count bound is only in the CLI
R22 Initial design, kernel tests, prototype, buildings/extension, corpus/render stages Generic defects and fixes recorded in development findings
R23 test_kernel, test_contracts_provenance: substitution, independent extension, authority, rollback, sharing, transforms, seeds Custom validator registration also tested
R24 Glass chain, two identities, external attachment membership, updates/deletions/regeneration, shared cells, transport mismatch tests Actual structure restored from companion, not inferred from materials
R25 64 frozen pairings, compatible independent field/environment, protected outside cells, perturbation and stress records Finite supported domain; 32 stress inputs retained without resampling
R26 Three short clients x eight seeds; settlement x eight seeds plus counts 3 and 6; later courtyard/gallery Programs use public room/component APIs
R27 Actual blocks/NBT: schema, support, headroom/routes, pair consistency, enclosure, lights, furnishings, pools and path joins; deliberate damage tests Physical/lighting model limitations above apply
R28 Structural/contact signatures, exterior views, circulation/furnishing cutaways, inspection notes Modular aesthetic remains visible; no exhaustive beauty claim
R29 generate.py, importable scene builders, inspection example, verified one-region transport Offline runtime uses bundled schema and installed/provided MCIO
R30 Library, docs, CLI, tests, extension, output pair, manifest, reports and labeled previews Broader simulation, arbitrary entities, browser UI and city planner remain unfinished

The first-phase ledger above remains applicable. This supplemental ledger maps every requirement to the new work or its explicit regression evidence; qualifications from both phases apply.

ID Extension-phase API and evidence Remaining boundary
R01 Pre-change API/hash baseline; unchanged-kernel probe; separate extension modules and focused tests before client expansion Self-authored exercise
R02 New package, geometry and graph clients; original snapshots untouched No reference code reused
R03 Polygon, Pavilion, HipRoof, Link, Campus; actual massing/topology signatures Finite vocabularies and explicit graph placements
R04 hearth_extensions imports public kernel/services; generation, CLI, assessment and previews separate No new browser runtime claimed
R05 Endpoint kind/frame/width/capacity checks; fixture grants; domain/grade/fill/span contracts Point endpoint offers are not broad landing replacements
R06 BoundaryChain, Campus, HallInterior; forwarded mounts/access; platform/pavilion substitution test Arbitrary concave layouts remain outside assessed domain
R07 Read-only connection negative write test; scoped terrain edits; overflow, protected aisle and whole-removal tests New connectors do not acquire host resurfacing permission
R08 Full geometry/graph/index rollback snapshots in test_extension_failures Same trusted-component boundary
R09 Final graph routes and reachable interior stations; late blockers rejected Open galleries deliberately lack enclosed-room obligations
R10 Actual trestle/deck/window/shell/bay/lamp children; headless inspection output No hand-authored ancestry
R11 Two endpoint associations, attachment vs containment, separate input reads and operation records Existing semantic graph model retained
R12 Exact current cells across replacement/removal; transform and audit queries No viewer added
R13 New manifest audit compares regenerated nodes, graphs, inventories and queries with reloaded pairs Validator package import required; bare geometry remains untrusted
R14 General field expressions plus curves, polygon masks and explicit connection graphs Simple discrete geometry, not a general mesh engine
R15 Frozen 3D support/water/occupancy queries along routes and contour bases Unknown space still errors
R16 Trestles, bounded route profile, endpoint mouth transitions, terrain-following boundary Finite engineering strategies
R17 Frozen environments, locked endpoints/vertices, local grants, atomic link and campus placement No moving locked buildings to hide failures
R18 Feasible profile propagation and furnishing-domain construction; stress diagnostics retained One locked complete candidate per assessed input; no exhaustive search claim
R19 Explicit regenerate(..., replacements=...); coupled host/link and boundary/lamp replay tests Conservative coarse invalidation remains
R20 Scoped streams, hash-seed subprocess replay, failed-choice stability; baseline default digest retained Real constraints may affect dependent branches
R21 Existing limits plus route length, span, fill, per-segment contour and bounded furnishing domains Library count is not fixed to demo size
R22 Baseline -> failing probe -> protocol delta -> components -> new clients -> corpus -> inspected refinement Development failures retained
R23 New extension protocol/geometry/failure/interior tests plus all unchanged original tests Extension is not an external audit
R24 Shared endpoint ownership, deletion/replacement, transforms, every-node audit, mounted-light and window chains Companion format remains version 1
R25 64 new independent environment/structure connector and boundary pairings; novel kink/polygon test; 24 stress rows Not a proof over all parameter combinations
R26 Original 3 clients x seeds 0-7 and count boundaries retained; two new graph clients x seeds 0-5 and 12 polygon halls New graphs add to, not replace, original corpus
R27 Actual route/headroom/support/guard/frame/fixture/interior tests, damage cases, inventory reload Discrete movement, lighting and bounded-span model
R28 New principal/contact signatures, multi-angle views, floor/connection sections; shared interior refinement Open lawns and modular material language remain visible
R29 Original generate.py unchanged; no-argument, seed-1, spaced paths and hash-seed replay checked Transport dependencies unchanged
R30 Separate docs/reports/samples/previews, replay manifests and runnable batches Browser rerun, autonomous city planner and broader simulation remain unfinished

15 · 完整源码、文档与复现

本轮共 63 个 Python 文件、6,107 行(包括库、示例与测试,不含参考代码)。不把行数当质量指标;它用来说明交付规模。每个源码文件可查看、下载并核对 SHA-256。运行库和报告适配层分开保留,后者负责 Worker、渲染传输和 UI,并不改写生成算法。

轻量多边形建筑客户端
from hearth import Scene, Box from hearth.environment import Terrain, gradient, wave from hearth.randomness import Scope from hearth_extensions import Polygon, Pavilion domain = Box((-12, -4, -12), (42, 65, 42)) environment_seed = int(ENV_SEED) phase = Scope(environment_seed).stream('hall-field').random() * 6 field = gradient(.012, -.008, 4) + wave(.5, .1, .12, phase) environment = Scene(environment_seed, domain=domain) environment.place('land', Terrain(domain, field)) environment.finalize() scene = environment.fork(seed=SEED) scene.place('hall', Pavilion( Polygon.chamfered(WIDTH, DEPTH, CHAMFER), '/land', purpose='library', entrances=('north', 'south', 'east'), height=HEIGHT, roof_run=2, lantern=LANTERN)) scene.finalize()
所有源码索引,可检索与排序
路径行数SHA-256
generate.py21d0ca8be7fa4af0e1d345130b23e12e509f82d9eccb136131cd77f1d2fc12fc48
hearth/__init__.py58cea431504ba8ba6deefbc705285b8d8e6a83f464b04d0d586ee31f4557b1bce
hearth/adapters/__init__.py26e2eea2e63bf34d477cc63f4fe9a362572a74709e28dcb2e97053943b7366fcd
hearth/adapters/site.py137a7e96c49d9697b041b9bfc5d646943397ee00cc91068377fa36f3d20b73b4a69
hearth/assessment.py163a6fe7486ff08c1c437af971ca62237424d42af53c392410948dd0b1d83dc9e64
hearth/blocks.py83dd43b62cde7bdce81de699632c14bb1e2d2e3e59f8e67bce383784f2b7a27596
hearth/components/__init__.py47243a6a3e85c60cc69ae7549354ce6e3637b3f13581d388f2ee46d77af08dcce
hearth/components/building.py1583491fdfeb23615a5868dd9cecdac20772dff7835176690ec71753a65a24298d0
hearth/components/constraints.py19aed416b50228cce52fc7eeca409bc8fa3c9cc5f85260f779cff0ad67ecdad631
hearth/components/interior.py210d88ff1187e9f4378a01a7a73365d6d7354951422d16f2ee2e92d6c642487e384
hearth/components/landscape.py253527e59621cad693abbc140acdac96f26f7eab697149809c08e7ea04a24a5a12c
hearth/components/primitives.py191efe13b95273d37da4299f54020b688b138ef3813b0ba8e7b4208b799dfcd04d9
hearth/components/roofs.py1250f8e5978a38dc7fe30b0223434998617dc6e581c257acc2b942f9626a344c8fa
hearth/composition.py610df1a52c9a42534744a86a74e5f75f5deaff5a46d1d1c9990e9c716854c017e5
hearth/environment/__init__.py3effbea4c76ce63a5ffafe37c146ce6d4ee95eed2afa1d30644ed640b7a96521e
hearth/environment/fields.py790dff276c440e3d7b45f5a01934c776354e2b92b48a989bc7c2464deafbbcd5a4
hearth/environment/terrain.py42f65c149259433a59ac81fe7102b4953408664d8ddbfa3141dcb57f9526eb0e7b
hearth/kernel/__init__.py5586df3f13a38e77633d20f7660bbf850c68f6d8b1f8b0bf2131a6ab36f0ecd5a
hearth/kernel/contracts.py15044e4f063d9d194d74295a569eeed8f57474afb201fe7d71d9719a4441d7c125e
hearth/kernel/errors.py32c10cc183e92621cf96ab340f8b22bd846d76f1d4ca5a73e846c6bb23fe4daca5
hearth/kernel/scene.py542f665e73a9de68b85d668c592d3beaea518206bf5db0fa5e1281f076e76a50524
hearth/kernel/validation.py220adafa1997fe4b664dbfe1634ce0c9c99d328306a8e23649d7bc201af0c3b75f7
hearth/kernel/view.py166bdb8856fcdf5b25989835721716cb479acb60c3bafcdb4cb1e7c53debf7e9885
hearth/persistence.py194ffd2d9a5a9f4c7aa1651a38dfdfc33f6c7957c8ea6ccca1bfde56e3e9384022b
hearth/programs.py1750255bb4fc30382706411195083406fd36bc95edb75f578c813e92926f9366179
hearth/randomness.py218523ae185dfbc40a89c7391a4eef8c0c9733435b36c5622c6a2c49b2d1236622
hearth/space.py109a6c1123e38a8b74e88ef116488eeadaec0b5a95edef8ae9f82ee517242ac9a2c
hearth_extensions/__init__.py84b12150c91fa1a6b062a77b3cabf2d29fd20e2c074f3d916d5df4ac5fad5661a
hearth_extensions/assessment.py208b520074aa2934b07ec85993c09afa6bc7eacdffe261687b30cc4ecc3457ad568
hearth_extensions/boundaries.py1257a4c5378e67927c41d1d4586e19992c58e0af44eb136d30f88722beae4b93756
hearth_extensions/circulation.py22714e88794cc1426bcd7a066ba4f9935edb72483eb49127ce3df1ef6cc6e8d8030
hearth_extensions/geometry.py1330c13bcf449e2be6caa0354c355c398c5278c1e23a974051e950d917477712197
hearth_extensions/graphs.py994a043204c986930092e4e6e442833d627a0569cd0464a6f076cc7d2225148c30
hearth_extensions/halls.py211ec8e49856f7a883973defbd43ae6ed4e24339e9ba1f0994b352199a713e82d9d
hearth_extensions/interfaces.py38d29568f08b7e9770c8b75efcbd8223da28f536b6089587b5efe9cd66f7e4ddda
hearth_extensions/interiors.py116fe9ccafd2e97baae88ae4cda0e40112f6d8e1a2ed69deadbcee3e895432d5a85
hearth_extensions/programs.py60ab3cf8354eff6031154da44e2f84fdad1c2731e2da5d938b1c53862932b3e048
hearth_extensions/sites.py3838b6747d8440c20909f96e99d62166c173538cfbd9ec592b365045b899fd7597
examples/__init__.py12f4de7abf0cbb4b2e630934f9c5e25ce49e6c2faec6e7473ebef685630b39770
examples/assess.py13da568047fda3729a393207c18ff1a7d5f9d9a44e6a0f213af2fa9eeae54720f8
examples/building.py13d61f26e255b040a465f19dac7dfc4d35cae74227208a473ccd3d85918481e25d
examples/courtyard.py255bebd698b6103738cf1aef02a65f7e92e523d29c7d5c05729796ebca55ebd12c
examples/extension.py27710712abce4af003237ef5f9d6ce150d7529fc0757165626fc1adad6a1d12267
examples/extension_assess.py14bcdd7a707f976f59a1a673983478e57e84a917f391b9ab4cab60234bddbbeefb
examples/extension_audit.py94d811c9172608ffe63ad9fe3d1358654798ba1f683ccf84581c0591db25d1264f
examples/extension_generate.py23b73a30afbfa230ab7b18c332a2aafb0270100afb7b3761f2b7e26904417552b3
examples/extension_inspection.py348a7283213516ef6da51c658d61756ead5042f2271fc6af05ef3966788a292ee7
examples/extension_replay.py499c4535beb585bde85a08f26a04fd74a3315fcca59da47f2fb3e32afd80d0fbe3
examples/extension_views.py6330a98598cd927b511496a21ee901828422921f7a7f9f2492f7369968b576b9e4
examples/gallery.py250f53e6b3eed341aa3386fcc223ca427a36b063ab27d2b5a45b5ac79beb45003d
examples/inspection.py28bc0612174362638dbb1dc22275b3537cd96717d7810fb1b89efdcb0d5eb49a7b
examples/preview.py624e574388487b1e94c164a26f8677edcc911b552f956ea0908bf9131182b4886e
examples/prototype.py339be9027d041fd317cd747eb5fa10e3d7e3de54230fe906f70230bc4d2bee3c85
examples/verify_replay.py354f7562d3978540bd3afbd714e7d90043a2ff6e98cc3591c92771e30ac6e19524
extension_demo/__init__.py3859ca7747843afa7f468ddf6bbfbc5755c6553f7c64edadaf912d53b19edda558
test/conftest.py13ee46bb8f7372a8a96af034dfcf6aa532762226dc4acefdf24b512272e19d313d
test/test_contracts_provenance.py2798680544efe88f9f76ca1d266fb87fb7f19eb811c0c10f34116e4c4e0df192404
test/test_extension_failures.py149eb0e02acb78342d587ba3edbbedb25a917fe96941c475246be13b2869df378da
test/test_extension_geometry.py1281b6c4cf7c16d69c7ca61bb33565df1b3300d9f20ff1cd2b8b794c4568f703dc6
test/test_extension_interiors.py701a8a580e98808eaafb392a32a3ecf22205a3acf31901e8f28778fcc7d74d5074
test/test_extension_protocol.py931e8d5ccbc00f1ef9728471e6bd2b9be257bcdaedee066ec8108bfec018dc990f
test/test_geometry_environment.py243616a57ff81522418e3db15d685bad8325d398eb07faed3cd78413067301e0b40
test/test_kernel.py122c6d7ea542a7c27241baff94b6ad26c7e75a87962cf902a4d2fc7bc4093db7914
generate.py · 21 行 · 原文件
# Generate, validate and export the default complete Hearth settlement. import argparse from pathlib import Path from hearth.programs import settlement_scene from hearth.persistence import export_scene, semantic_digest def main(): parser = argparse.ArgumentParser(description='Generate a contract-composed Minecraft Java 1.21.1 settlement.') parser.add_argument('--seed', type=int, default=0, help='Explicit integer seed, default 0') parser.add_argument('--output', type=Path, default=Path('output.litematic')) parser.add_argument('--count', type=int, choices=range(3, 7), help='Optional explicit building count, 3 through 6') args = parser.parse_args() scene = settlement_scene(args.seed, args.count) export_scene(scene, args.output) print(f'Validated {sum(n.type=="building.rooms" for n in scene.nodes.values())} buildings, {len(scene.blocks)} blocks, {len(scene.nodes)} components.') print(f'{args.output} | semantic SHA256 {semantic_digest(scene)}') if __name__ == '__main__': main()
hearth/__init__.py · 5 行 · 原文件
# Hearth public library entry points. from .kernel import Binding, Child, ContractError, Limits, Scene from .space import Box, Frame __version__ = '1.2.0'
hearth/adapters/__init__.py · 2 行 · 原文件
# Reusable environmental contact and circulation adapters. from .site import Foundation, Approach, SiteLimits, survey
hearth/adapters/site.py · 137 行 · 原文件
# Measured, bounded support and access strategies independent of terrain recipes. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, log, stairs, name_of, solid from hearth.kernel import Capability, Contract, Port, Grant, Rule, Plan, ContractError @dataclass(frozen=True) class SiteLimits: relief: int = 5 support_height: int = 8 approach_length: int = 12 fill_volume: int = 1600 excavation_volume: int = 300 bed_thickness: int = 2 def survey(ctx, footprint, limits=SiteLimits()): samples = {} for x, z in sorted(footprint): wx, _, wz = ctx.world((x, 0, z)) obs = ctx.view.sample(wx, wz) if obs.support_depth < limits.bed_thickness: raise ContractError('substrate-depth', ctx.path, (wx, obs.elevation, wz), f'Require {limits.bed_thickness} contiguous solid bed cells, found {obs.support_depth}') samples[(x, z)] = (obs.elevation - ctx.frame.origin[1], None if obs.water is None else obs.water - ctx.frame.origin[1], obs.support_depth) heights = [v[0] for v in samples.values()] relief = max(heights) - min(heights) if relief > limits.relief: raise ContractError('site-relief', ctx.path, ctx.frame.origin, f'Measured {relief}, permitted {limits.relief}') surface = max(max(v[0], v[1] if v[1] is not None else v[0]) for v in samples.values()) floor = surface + 1 if floor - min(heights) > limits.support_height: raise ContractError('support-height', ctx.path, ctx.frame.origin, 'Bounded support depth exceeded') wet = any(v[1] is not None and v[1] >= v[0] for v in samples.values()) strategies = ['piers'] if wet or relief >= 3 else ['stepped', 'piers'] strategy = ctx.scope.choose(strategies, 'adaptation') return {'floor': floor, 'relief': relief, 'wet': wet, 'strategy': strategy, 'samples': samples, 'feasible_strategies': strategies} @dataclass(frozen=True) class Foundation: footprint: tuple[tuple[int, int], ...] floor: int strategy: str limits: SiteLimits = SiteLimits() @classmethod def rectangular(cls, width, depth, floor, strategy='stepped', limits=SiteLimits()): """Create a rectangular contact component without client voxel operations.""" if width < 1 or depth < 1: raise ValueError('Positive footprint dimensions required') return cls(tuple((x, z) for x in range(width) for z in range(depth)), floor, strategy, limits) def capability(self): return Capability('adapter.foundation', ('siteworks', 'support'), offers=('support',), assumptions=('actual bed within bounded depth',), adaptations=('stepped perimeter', 'piers to bed'), guarantees=('grounded support grid',)) def negotiate(self, ctx, parameters): positions = set(self.footprint) supports = [] columns = [] for x, z in sorted(positions): boundary = any((x + dx, z + dz) not in positions for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1))) grid = (x % 4 == 0 and z % 4 == 0) # Piers include perimeter every third cell and all corners. edge_pier = boundary and (x % 3 == 0 or z % 3 == 0 or sum((x + dx, z + dz) not in positions for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1))) >= 2) if not (grid or (boundary if self.strategy == 'stepped' else edge_pier)): continue wx, _, wz = ctx.world((x, 0, z)) bed = ctx.view.elevation(wx, wz) - ctx.frame.origin[1] if self.floor - bed > self.limits.support_height: raise ContractError('support-height', ctx.path, ctx.world((x, bed, z))) supports.extend((x, bed - k, z) for k in range(self.limits.bed_thickness)) columns.append((x, bed, z, self.floor - 1)) count = sum(max(0, top - bed) for x, bed, z, top in columns) if count > self.limits.fill_volume: raise ContractError('fill-volume', ctx.path, conditions=f'{count} > {self.limits.fill_volume}') for x, bed, z, top in columns: supports.extend((x, y, z) for y in range(bed + 1, top + 1)) box = Box.enclosing([(x, bed - self.limits.bed_thickness + 1, z) for x, bed, z, top in columns] + [(x, self.floor - 1, z) for x, bed, z, top in columns]) return Contract(box, rules=(Rule('support', tuple(supports)),), decisions={'columns': columns, 'strategy': self.strategy, 'fill': count, 'excavation': 0}, reads=(box,)) def realize(self, ctx, contract): p = Plan() for x, bed, z, top in contract.decisions['columns']: for y in range(bed + 1, top + 1): material = log('spruce') if self.strategy == 'piers' and y > bed + 1 else state_of('stone_bricks') p.block((x, y, z), material, 'contact') return p @dataclass(frozen=True) class Approach: center: int floor: int porch: int = 0 limits: SiteLimits = SiteLimits() def capability(self): return Capability('adapter.approach', ('siteworks', 'access'), offers=('street', 'surface'), adaptations=('stairs', 'landing', 'bounded fill'), guarantees=('two-block headroom', 'entrance connection')) def negotiate(self, ctx, parameters): rows = [] for step in range(1, self.limits.approach_length + 1): z = -self.porch - step wx, _, wz = ctx.world((self.center, 0, z)) ground = max(max(ctx.view.elevation(ctx.world((x, 0, z))[0], ctx.world((x, 0, z))[2]), (ctx.view.water(ctx.world((x, 0, z))[0], ctx.world((x, 0, z))[2]) or -10000) + 1) - ctx.frame.origin[1] for x in range(self.center - 1, self.center + 2)) y = max(ground, self.floor - step + 1) rows.append((z, y)) if y == ground: break else: raise ContractError('approach-detour', ctx.path, ctx.frame.origin, 'Cannot meet terrain within length bound') cells = [] support = [] for z, y in rows: cells.extend((x, y + k, z) for x in range(self.center - 1, self.center + 2) for k in (1, 2)) support.extend((x, y, z) for x in range(self.center - 1, self.center + 2)) low = min(ctx.view.elevation(*((lambda p: (p[0], p[2]))(ctx.world((x, 0, z))))) - ctx.frame.origin[1] for z, y in rows for x in range(self.center - 1, self.center + 2)) box = Box((self.center - 1, low, rows[-1][0]), (self.center + 1, max(y for z, y in rows) + 3, -self.porch - 1)) end = (self.center, rows[-1][1] + 1, rows[-1][0]) region = Box((self.center - 1, rows[-1][1], rows[-1][0]), (self.center + 1, self.floor + 2, min(-self.porch - 1, rows[-1][0] + 1))) port = Port('street', 'access', Frame(end), region, 10, 'surface') grant = Grant('surface', region, ('surface',), ('path',), 18) route = tuple((self.center, y + 1, z) for z, y in rows) return Contract(box, (port,), (grant,), (Rule('clear', tuple(cells)), Rule('support', tuple(support)), Rule('route', route, box.expand(1), phase='complete')), decisions={'rows': rows, 'end': end}, reads=(box,)) def realize(self, ctx, contract): p = Plan() rows = contract.decisions['rows'] for index, (z, y) in enumerate(rows): for x in range(self.center - 1, self.center + 2): wx, _, wz = ctx.world((x, 0, z)) bed = ctx.view.elevation(wx, wz) - ctx.frame.origin[1] for yy in range(bed + 1, y): p.block((x, yy, z), state_of('cobblestone'), 'step-footing') p.block((x, y, z), stairs('stone_brick', 'south') if index and rows[index - 1][1] > y else state_of('stone_bricks'), 'treads') return p
hearth/assessment.py · 163 行 · 原文件
# Reproducible corpus inputs, structural measurements and retained diagnostics. import hashlib import json import time from pathlib import Path from hearth.randomness import Scope from hearth.programs import PROGRAMS, building_scene, settlement_scene from hearth import Scene, Box from hearth.environment import Terrain from hearth.components.building import adapted from hearth.environment import gradient, wave, radial, constant from hearth.kernel import ContractError, SearchExhausted from hearth.persistence import semantic_digest, export_scene from hearth.blocks import name_of def adaptation_expression(environment_seed): rng = Scope(environment_seed).stream('frozen-environment') # Degenerate coefficients deliberately include exact flat ground. sx = rng.choice((-.045, 0, .045)) sz = rng.choice((-.035, 0, .035)) amplitude = rng.choice((0, .4, .8)) expression = gradient(sx, sz, 4) + wave(amplitude, .13, .11, rng.random() * 6) if environment_seed >= 8: mask = radial(8, 9, 28, .7).transformed(dx=2, dz=-1, scale=1.2) expression = expression.blend(gradient(-sz, sx, 4) + wave(.6, .07, .19), mask) else: expression = expression + radial(7, 8, 22, rng.choice((0, .4, .7))) expression = expression.clamp(2, 7) water = rng.choice((None, 5, 6)) return expression, water def freeze_environment(seed): expression, water = adaptation_expression(seed) scene = Scene(seed, domain=Box((-8, -4, -18), (34, 64, 34))) scene.place('land', Terrain(scene.domain, expression, water)) return scene.finalize() def adapt_frozen(environment, design, building_seed): scene = environment.fork(seed=building_seed) scene.compose_choice(adapted('building', design, '/land')) return scene.finalize() def principal_signature(scene): buildings = [] for path, node in sorted(scene.nodes.items()): if node.type != 'building.rooms': continue decision = node.contract.decisions # Realized node topology plus occupied envelope per room, normalized to building. rooms = [] roofs = [] for child, part in sorted(scene.nodes.items()): if not child.startswith(path + '/'): continue if part.type.startswith('room.'): origin = node.frame.inverse(part.frame.origin) occupied = scene.cells(child, True) relative = [part.frame.inverse(p) for p in occupied] bounds = [min(p[i] for p in relative) for i in range(3)] + [max(p[i] for p in relative) for i in range(3)] rooms.append([origin[0], origin[1] - decision['floor'], origin[2], part.type, part.contract.decisions['doors'], part.contract.decisions['stair_up'], bounds]) if part.type == 'roof.gable': roofs.append([part.contract.decisions['axis'], part.contract.decisions['span'], part.contract.decisions['steep'], len(scene.cells(child, True))]) buildings.append({'rooms': rooms, 'roofs': roofs, 'porch': decision['porch'], 'bay': decision['bay']}) layout = [] for node in scene.nodes.values(): if node.type == 'landscape.paths': pts = node.contract.decisions['waypoints'] layout.append({'points': [(p[0], p[-1]) for p in pts], 'links': node.contract.decisions['links']}) data = {'buildings': buildings, 'organization': layout} return hashlib.sha256(json.dumps(data, sort_keys=True, default=list).encode()).hexdigest(), data def contact_metrics(scene): foundations = [n for n in scene.nodes.values() if n.type == 'adapter.foundation'] data = [n.contract.decisions for n in foundations] edit_paths = {key for key, n in scene.nodes.items() if n.capability and set(n.capability.tags).intersection(('siteworks', 'path'))} occupied = sum(len(scene.cells(key)) for key in edit_paths) replacements = sum(len(scene.displaced.get(key, {})) for key in edit_paths) from hearth.blocks import solid, AIR excavated = sum(solid(old.state) and not solid(scene.blocks[p].state if p in scene.blocks else AIR) for key in edit_paths for p, old in scene.displaced.get(key, {}).items()) return {'fill': sum(d['fill'] for d in data), 'excavation': excavated, 'sitework_occupied_cells': occupied, 'replaced_cells': replacements, 'new_sitework_cells': occupied - replacements, 'strategies': [d['strategy'] for d in data], 'signature': hashlib.sha256(json.dumps(data, sort_keys=True).encode()).hexdigest()} def measured(label, recipe, inputs, output=None): start = time.perf_counter() result = {'label': label, 'inputs': inputs, 'attempts': 1, 'retries': 0} try: scene = recipe() scene.finalize() signature, structure = principal_signature(scene) choices = [e for e in scene.events if e['kind'] == 'candidate-selection'] if choices: result['attempts'] = sum(e['attempts'] for e in choices) result.update(status='validated', blocks=len(scene.blocks), components=len(scene.nodes), digest=semantic_digest(scene), principal_signature=signature, structure=structure, contact=contact_metrics(scene), accepted_candidates=sum(e['accepted'] for e in choices) if choices else 1, candidates=choices) # Hash independently frozen terrain before placement using persisted field input and current unchanged bed cells. if output: export_scene(scene, output) result['artifact'] = str(output) except SearchExhausted as exc: result.update(status='budget-exhausted', diagnostic=str(exc), accepted_candidates=0, attempts=getattr(exc, 'attempts', 1), candidates=getattr(exc, 'candidates', [])) except (ContractError, ValueError) as exc: result.update(status='incompatible' if isinstance(exc, ContractError) and exc.diagnostic.rule in ('site-relief', 'support-height', 'fill-volume', 'approach-detour') else 'defect', diagnostic=str(exc), accepted_candidates=0, attempts=getattr(exc, 'attempts', 1), candidates=getattr(exc, 'candidates', [])) result['seconds'] = round(time.perf_counter() - start, 4) return result def run_corpus(output: Path, seed=0, artifacts=False): output.mkdir(parents=True, exist_ok=True) rows = [] specs = [] environments = {} for env in range(16): expression, water = adaptation_expression(env + seed * 100) frozen = freeze_environment(env + seed * 100) environments[env + seed * 100] = frozen digest = semantic_digest(frozen) for build in range(4): specs.append({'environment_seed': env + seed * 100, 'building_seed': build, 'expression': expression.expression(), 'water': water, 'frozen_environment_digest': digest, 'environment_domain': [list(frozen.domain.lo), list(frozen.domain.hi)], 'held_out': env >= 8}) (output / 'adaptation-inputs.json').write_text(json.dumps(specs, indent=2)) for i, spec in enumerate(specs): expression, water = adaptation_expression(spec['environment_seed']) bs = spec['building_seed'] recipe = lambda e=environments[spec['environment_seed']], b=bs: adapt_frozen(e, PROGRAMS['dwelling'](b), b) artifact = Path('samples') / f'adaptation-{i:02d}.litematic' if artifacts and i in (0, 8, 35, 60) else None row = measured(f'adaptation-{i:02d}', recipe, spec, artifact) if semantic_digest(environments[spec['environment_seed']]) != spec['frozen_environment_digest']: raise AssertionError('Frozen environment mutated') rows.append(row) print(row['label'], row['status'], flush=True) for name, program in PROGRAMS.items(): for bs in range(8): artifact = Path('samples') / f'{name}-{bs}.litematic' if artifacts and bs in (0, 1, 6) else None row = measured(f'{name}-{bs}', lambda p=program, b=bs: building_scene(p(b), b), {'program': name, 'seed': bs}, artifact) rows.append(row) print(row['label'], row['status'], flush=True) for bs, count in [(s, None) for s in range(8)] + [(0, 3), (0, 6)]: label = f'settlement-{bs}-{count or "seeded"}' artifact = Path('samples') / (label + '.litematic') if artifacts and ((bs == 1 and count is None) or count in (3, 6)) else None row = measured(label, lambda b=bs, c=count: settlement_scene(b, c), {'program': 'settlement', 'seed': bs, 'count': count}, artifact) rows.append(row) print(label, row['status'], flush=True) for i in range(32): es = 1000 + seed * 100 + i rng = Scope(es).stream('stress') expression = (gradient(rng.choice((0, .12, .28, .45)), rng.choice((0, -.15, .2)), 4) + wave(rng.choice((0, 2, 5)), .13, .17, rng.random() * 6)).clamp(-2, 20) water = rng.choice((None, 5, 12)) bs = i % 8 row = measured(f'stress-{i:02d}', lambda e=expression, w=water, b=bs: building_scene(PROGRAMS['dwelling'](b), b, e, w), {'environment_seed': es, 'building_seed': bs, 'expression': expression.expression(), 'water': water}) rows.append(row) print(row['label'], row['status'], flush=True) (output / 'results.json').write_text(json.dumps(rows, indent=2)) summary = {} for name, subset in [('adaptation', rows[:64]), ('buildings', rows[64:88]), ('settlements', rows[88:98]), ('stress', rows[98:])]: good = [r for r in subset if r['status'] == 'validated'] summary[name] = {'inputs': len(subset), 'validated': len(good), 'incompatible': sum(r['status'] == 'incompatible' for r in subset), 'defects': sum(r['status'] == 'defect' for r in subset), 'budget_exhausted': sum(r['status'] == 'budget-exhausted' for r in subset), 'candidate_attempts': sum(r['attempts'] for r in subset), 'accepted_candidates': sum(r['accepted_candidates'] for r in subset), 'retries': sum(r['retries'] for r in subset), 'seconds': round(sum(r['seconds'] for r in subset), 3), 'observed_principal_signatures': len({r['principal_signature'] for r in good}), 'observed_contact_signatures': len({r['contact']['signature'] for r in good}), 'fill_range': [min((r['contact']['fill'] for r in good), default=0), max((r['contact']['fill'] for r in good), default=0)]} (output / 'summary.json').write_text(json.dumps(summary, indent=2)) manifest = [{'artifact': r['artifact'], 'inputs': r['inputs'], 'digest': r['digest'], 'status': r['status']} for r in rows if 'artifact' in r] (Path('samples') / 'replay-manifest.json').write_text(json.dumps(manifest, indent=2)) return summary
hearth/blocks.py · 83 行 · 原文件
# Canonical blockstates and a deliberately conservative physical model. import json import re from functools import lru_cache from pathlib import Path SCHEMA = json.loads((Path(__file__).parent / 'data' / 'blockstates-1.21.1.json').read_text()) AIR = 'minecraft:air' LIGHTS = {'lantern': 15, 'torch': 14, 'wall_torch': 14, 'glowstone': 15, 'sea_lantern': 15, 'shroomlight': 15, 'ochre_froglight': 15, 'pearlescent_froglight': 15, 'verdant_froglight': 15} SOFT = {'air', 'cave_air', 'water', 'short_grass', 'fern', 'dead_bush', 'dandelion', 'poppy', 'cornflower', 'allium', 'azure_bluet', 'oxeye_daisy', 'lily_of_the_valley', 'blue_orchid', 'torch', 'wall_torch', 'vine', 'snow', 'lily_pad', 'tall_grass', 'large_fern', 'sunflower', 'rose_bush', 'peony', 'lilac', 'wheat', 'carrots', 'potatoes'} @lru_cache(maxsize=4096) def parse(state: str): match = re.fullmatch(r'(minecraft:[a-z0-9_]+)(?:\[([^\]]+)\])?', state) if not match: raise ValueError(f'Invalid blockstate syntax: {state}') props = {} if match[2]: for part in match[2].split(','): key, value = part.split('=') if key in props: raise ValueError('Duplicate block property') props[key] = value return match[1], props def state_of(name: str, **properties) -> str: if not name.startswith('minecraft:'): name = 'minecraft:' + name return name + ('[' + ','.join(f'{k}={str(v).lower()}' for k, v in sorted(properties.items())) + ']' if properties else '') def canonical(state: str) -> str: name, props = parse(state) return state_of(name, **props) def blockstates_equivalent(left: str, right: str) -> bool: return parse(left) == parse(right) @lru_cache(maxsize=4096) def validate_state(state: str): name, props = parse(state) short = name.removeprefix('minecraft:') if short not in SCHEMA: raise ValueError(f'Unknown Java 1.21.1 block: {name}') domain = SCHEMA[short][0] for key, value in props.items(): if key not in domain or value not in domain[key]: raise ValueError(f'Invalid property {key}={value} for {name}') @lru_cache(maxsize=4096) def name_of(state: str) -> str: return parse(state)[0].removeprefix('minecraft:') def solid(state: str) -> bool: name = name_of(state) return name not in SOFT and not any(s in name for s in ('leaves', 'fence', 'pane', 'door', 'lantern', 'chain', 'flower_pot', 'potted_', 'carpet', 'bed', 'button')) def passable(state: str) -> bool: name = name_of(state) return name in SOFT - {'water'} or name.endswith('_door') or name.endswith('_carpet') def stairs(material='stone_brick', facing='north', half='bottom'): return state_of(material + '_stairs', facing=facing, half=half, shape='straight', waterlogged='false') def slab(material='stone_brick', half='bottom'): return state_of(material + '_slab', type=half, waterlogged='false') def log(material='spruce', axis='y'): return state_of(material + '_log', axis=axis) def leaves(material='spruce'): return state_of(material + '_leaves', distance='1', persistent='true', waterlogged='false')
hearth/components/__init__.py · 4 行 · 原文件
# Public architectural components and their explicit intent records. from .building import Blueprint, Building, RoomSpec, adapted from .interior import Room, Light, Furniture, Door, Stair from .primitives import Wall, Window, Tree, Grass, Pool, Assembly
hearth/components/building.py · 158 行 · 原文件
# Room-graph building composition and shared facade/roof planning. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.kernel import Capability, Contract, Domain, Port, Plan, Child, Choice, Binding, Rule, ContractError from hearth.adapters.site import survey, Foundation, Approach, SiteLimits from .interior import Room from .roofs import Roof, Porch @dataclass(frozen=True) class RoomSpec: x: int z: int level: int purpose: str @dataclass(frozen=True) class Blueprint: rooms: tuple[RoomSpec, ...] bay: int = 11 porch: bool = True roof_axis: str = 'auto' roof_material: str = 'deepslate_tile' steep: bool = True window_component: object = None light_component: object = None def normalized(self): return tuple(sorted(self.rooms, key=lambda r: (r.level, r.z, r.x, r.purpose))) @property def footprint(self): return tuple(sorted((r.x * self.bay + x, r.z * self.bay + z) for r in self.rooms if r.level == 0 for x in range(self.bay) for z in range(self.bay))) @property def contact_footprint(self): return tuple(sorted(set(self.footprint) | ({(x, z) for x in range(self.bay) for z in range(-3, 0)} if self.porch else set()))) def validate(self): cells = {(r.x, r.z, r.level) for r in self.rooms} if len(cells) != len(self.rooms) or (0, 0, 0) not in cells or min(min(r.x, r.z, r.level) for r in self.rooms) < 0: raise ValueError('Unique nonnegative rooms and entrance room (0,0,0) required') if self.bay not in (9, 11, 13): raise ValueError('Supported room bays: 9, 11, 13') for x, z, level in cells: if level and (x, z, level - 1) not in cells: raise ValueError('Upper rooms require a supporting lower room') reached = {(0, 0, 0)} while True: more = {p for p in cells if any(sum(abs(a - b) for a, b in zip(p, q)) == 1 for q in reached)} if more <= reached: break reached |= more if reached != cells: raise ValueError('Room adjacency graph disconnected') @dataclass(frozen=True) class Building: design: Blueprint terrain: str site_limits: SiteLimits = SiteLimits() support_strategy: str | None = None def capability(self): return Capability('building.rooms', ('building', 'habitable', 'composite'), offers=('entrance', 'street', 'attachment'), assumptions=('known ground', 'bounded relief'), adaptations=('foundation', 'approach', 'roof junction'), guarantees=('locked room graph', 'internal reachability', 'furnishing', 'lighting'), inputs={'design.bay': Domain(choices=(9, 11, 13)), 'room_graph': 'connected integer grid with supported levels', 'relief_limit': self.site_limits.relief, 'support_height_limit': self.site_limits.support_height, 'frame.turn': Domain(choices=(0, 1, 2, 3))}, locked=('design.rooms', 'design.bay', 'design.roof_axis', 'design.porch', 'frame.x', 'frame.z')) def negotiate(self, ctx, parameters): self.design.validate() b = self.design.bay rooms = self.design.normalized() measured = survey(ctx, self.design.contact_footprint, self.site_limits) if self.support_strategy is not None: if self.support_strategy not in measured['feasible_strategies']: raise ContractError('contact-strategy', ctx.path, ctx.frame.origin, 'Requested strategy incompatible with measured water/relief') measured['strategy'] = self.support_strategy floor = measured['floor'] height = max(r.level for r in rooms) * 6 width = (max(r.x for r in rooms) + 1) * b depth = (max(r.z for r in rooms) + 1) * b minimum = min(v[0] for v in measured['samples'].values()) front = self.site_limits.approach_length + (3 if self.design.porch else 0) box = Box((-1, min(minimum - self.site_limits.bed_thickness + 1, 0), -front), (width, floor + height + b + 12, depth)) points = tuple((r.x * b + b // 2, floor + r.level * 6 + 1, r.z * b + b // 2) for r in rooms) entrance = (b // 2, floor + 1, 0) route = Rule('route', (entrance,) + points, box, phase='complete') port = Port('entrance', 'access', Frame(entrance), Box(entrance, (entrance[0], entrance[1] + 1, entrance[2])), 10) decisions = {'floor': floor, 'relief': measured['relief'], 'wet': measured['wet'], 'foundation': measured['strategy'], 'rooms': [(r.x, r.z, r.level, r.purpose) for r in rooms], 'bay': b, 'roof_axis': self.design.roof_axis, 'porch': self.design.porch, 'roof_material': self.design.roof_material, 'steep': self.design.steep} approach = Approach(b // 2, floor, 3 if self.design.porch else 0, self.site_limits).negotiate(ctx, {}) access = approach.ports[0] street = Port('street', access.kind, access.frame, access.region, access.capacity, facts={'external_connection_required': True}, delegate=('approach', 'street')) return Contract(box, ports=(port, street), rules=(route,), decisions=decisions, reads=(Box((0, minimum, 0), (width - 1, floor, depth - 1)),)) def realize(self, ctx, contract): p = Plan() b = self.design.bay floor = contract.decisions['floor'] rooms = self.design.normalized() cells = {(r.x, r.z, r.level) for r in rooms} p.children.append(Child('foundation', Foundation(self.design.contact_footprint, floor, contract.decisions['foundation'], self.site_limits), bindings=(Binding(self.terrain, 'construction', 'fill', ctx.frame.box(contract.envelope)),))) # A spanning tree of vertical access: one flight per upper horizontal component. stair_columns = set() for level in sorted({r.level for r in rooms if r.level}): remaining = {(x, z) for x, z, l in cells if l == level} while remaining: seed = min(remaining) connected = {seed} while True: expanded = {v for v in remaining if any(abs(v[0] - q[0]) + abs(v[1] - q[1]) == 1 for q in connected)} if expanded <= connected: break connected |= expanded root = min(connected) stair_columns.add((root[0], root[1], level - 1)) remaining -= connected for r in rooms: adjacent = {'north': (r.x, r.z - 1, r.level), 'south': (r.x, r.z + 1, r.level), 'west': (r.x - 1, r.z, r.level), 'east': (r.x + 1, r.z, r.level)} doors = tuple(side for side, q in adjacent.items() if q in cells or (side == 'north' and (r.x, r.z, r.level) == (0, 0, 0))) windows = tuple(side for side, q in adjacent.items() if q not in cells) key = f'room-{r.x}-{r.z}-{r.level}' room = Room(r.purpose, b, b, doors, windows, (r.x, r.z, r.level + 1) in cells, (r.x, r.z, r.level) in stair_columns, (r.x, r.z, r.level - 1) in stair_columns, self.design.window_component, self.design.light_component) p.children.append(Child(key, room, frame=Frame((r.x * b, floor + r.level * 6, r.z * b)))) if self.design.porch: p.children.append(Child('porch', Porch(b), frame=Frame((0, floor, 0)))) p.children.append(Child('approach', Approach(b // 2, floor, 3 if self.design.porch else 0, self.site_limits), bindings=(Binding(self.terrain, 'construction', 'surface', ctx.frame.box(contract.envelope)),))) # Rectangular roof runs are derived from exposed top rooms, not a building family. top = {(r.x, r.z, r.level) for r in rooms if (r.x, r.z, r.level + 1) not in cells} groups = [] while top: x, z, l = min(top, key=lambda v: (v[2], v[1], v[0])) axis = self.design.roof_axis if axis == 'auto': axis = 'x' if (x + 1, z, l) in top else 'z' run = [(x, z, l)] while ((run[-1][0] + (axis == 'x'), run[-1][1] + (axis == 'z'), l)) in top: run.append((run[-1][0] + (axis == 'x'), run[-1][1] + (axis == 'z'), l)) top -= set(run) groups.append((x, z, l, axis, len(run))) for i, (x, z, l, axis, length) in enumerate(groups): w = b * (length if axis == 'x' else 1) d = b * (length if axis == 'z' else 1) p.children.append(Child(f'roof-{i}', Roof(w, d, axis, self.design.roof_material, self.design.steep), frame=Frame((x * b, floor + l * 6 + 7, z * b)))) return p def contact_quality(view, path): """Score actual candidate sitework plus exposed-support proportions.""" facts = view.contract(path).decisions cost = view.cost(path, 'siteworks') exposure = 0.4 if facts['foundation'] == 'piers' and not facts['wet'] and facts['relief'] < 2 else 0 return cost['occupied'] / 100 + cost['replaced'] / 50 + exposure def adapted(key, design, terrain, frame=Frame(), limits=SiteLimits()): """Compare complete bounded support alternatives with the principal design locked.""" candidates = tuple(Child(key, Building(design, terrain, limits, strategy), frame=frame) for strategy in ('stepped', 'piers')) return Choice(key, candidates, contact_quality)
hearth/components/constraints.py · 19 行 · 原文件
# Reusable hard preservation and clearance components. from dataclasses import dataclass from hearth.kernel import Capability, Contract, Plan, Rule from hearth.space import Box @dataclass(frozen=True) class Preserve: region: Box def capability(self): return Capability('constraint.preserve', ('constraint', 'protected-region'), guarantees=('immutable existing region',)) def negotiate(self, ctx, parameters): cells = tuple(self.region.cells()) return Contract(self.region, rules=(Rule('protected', cells, self.region, {'states': [ctx.view.state(ctx.world(p)) for p in cells]}),)) def realize(self, ctx, contract): return Plan()
hearth/components/interior.py · 210 行 · 原文件
# Usable doors, lights and furnished rooms assembled as semantic children. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, stairs, slab, log from hearth.kernel import Capability, Contract, Domain, Grant, Port, Rule, Plan, Child, Binding, ContractError from .primitives import Volume, Wall, Window @dataclass(frozen=True) class Door: material: str = 'spruce' def capability(self): return Capability('opening.door', ('door', 'access'), guarantees=('paired halves', 'support', 'operable exit')) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('support', ((0, -1, 0),)),), atomic_object=True) def realize(self, ctx, contract): p = Plan() for y, half in enumerate(('lower', 'upper')): p.block((0, y, 0), state_of(self.material + '_door', facing='north', half=half, hinge='left', open='false', powered='false')) return p @dataclass(frozen=True) class Light: hanging: bool = True def capability(self): return Capability('light.lantern', ('light', 'room-light'), guarantees=('actual light source',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('expected', ((0, 0, 0),), data={'names': ['lantern']}),)) def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('lantern', hanging=str(self.hanging).lower(), waterlogged='false')) if self.hanging: p.block((0, 1, 0), state_of('chain', axis='y', waterlogged='false')) return p @dataclass(frozen=True) class Furniture: purpose: str = 'living' width: int = 11 depth: int = 11 def capability(self): return Capability('furniture.' + self.purpose, ('furniture', self.purpose), guarantees=('usable function',)) def negotiate(self, ctx, parameters): if self.purpose not in ('living', 'bedroom', 'workshop', 'library', 'kitchen', 'storage'): raise ContractError('room-function', ctx.path, conditions=self.purpose) return Contract(Box((1, 0, 1), (self.width - 2, 2, self.depth - 2))) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth inventory = {'id': 'minecraft:barrel', 'Items': [{'Slot': 0, 'id': 'minecraft:bread', 'count': 6}, {'Slot': 1, 'id': 'minecraft:torch', 'count': 12}]} p.block((1, 0, d - 2), state_of('barrel', facing='north', open='false'), 'supplies', nbt=inventory) if self.purpose == 'bedroom': for z, part in ((2, 'foot'), (3, 'head')): p.block((2, 0, z), state_of('red_bed', facing='south', part=part, occupied='false'), 'bed') p.block((2, 0, d - 3), state_of('bookshelf')) elif self.purpose == 'library': for x in (2, 3, w - 3): for y in range(2): p.block((x, y, d - 2), state_of('bookshelf')) p.block((2, 0, 2), state_of('lectern', facing='south', has_book='false', powered='false')) elif self.purpose == 'workshop': p.block((2, 0, 2), state_of('crafting_table')) p.block((3, 0, 2), state_of('smithing_table')) p.block((2, 0, d - 3), state_of('anvil', facing='north')) elif self.purpose == 'kitchen': p.block((2, 0, 2), state_of('smoker', facing='south', lit='false')) p.block((3, 0, 2), state_of('furnace', facing='south', lit='false')) p.block((2, 0, d - 3), state_of('crafting_table')) else: for z in (2, 3): p.block((2, 0, z), stairs('spruce', 'east'), 'bench') p.block((w - 3, 0, d - 1 - z), stairs('spruce', 'west'), 'bench') p.block((3, 0, 2), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false')) p.block((3, 1, 2), state_of('spruce_pressure_plate', powered='false'), 'table') # Rugs avoid the central circulation cross and door landings. for x in (3, 4): for z in (d - 4, d - 3): p.block((x, 0, z), state_of('red_carpet'), 'rug') return p @dataclass(frozen=True) class Stair: rise: int = 6 width: int = 2 def capability(self): return Capability('circulation.stair', ('stairs', 'vertical-access'), guarantees=('walkable flight', 'two-block headroom')) def negotiate(self, ctx, parameters): points = tuple((x, i + 1, i) for i in range(self.rise) for x in range(self.width)) clear = tuple((x, i + k, i) for i in range(self.rise) for x in range(self.width) for k in (1, 2, 3)) support = tuple((x, i, i) for i in range(self.rise) for x in range(self.width)) box = Box((0, 0, -1), (self.width - 1, self.rise + 2, self.rise)) return Contract(box, rules=(Rule('support', support), Rule('clear', clear), Rule('route', points, box, phase='complete'))) def realize(self, ctx, contract): p = Plan() for i in range(self.rise): for x in range(self.width): for y in range(max(0, i - 1), i): p.block((x, y, i), state_of('spruce_planks'), 'stringer') p.block((x, i, i), stairs('spruce', 'south'), 'tread') return p @dataclass(frozen=True) class Room: purpose: str width: int = 11 depth: int = 11 doors: tuple[str, ...] = ('north',) windows: tuple[str, ...] = ('north', 'east', 'south', 'west') upper_open: bool = False stair_up: bool = False stair_down: bool = False window_component: object = None light_component: object = None def capability(self): return Capability('room.' + self.purpose, ('room', 'habitable', 'composite'), offers=('access',), guarantees=('lit', 'furnished', 'reachable', 'enclosed'), adaptations=('facade grid', 'substitutable windows and lights'), inputs={'width': Domain(choices=(9, 11, 13)), 'depth': Domain(choices=(9, 11, 13)), 'purpose': Domain(choices=('living', 'bedroom', 'library', 'workshop', 'kitchen', 'storage'))}, locked=('purpose', 'width', 'depth', 'doors', 'stair_up', 'stair_down')) def negotiate(self, ctx, parameters): w, d = self.width, self.depth if w not in (9, 11, 13) or d not in (9, 11, 13): raise ContractError('room-domain', ctx.path) doors = {'north': (w // 2, 1, 0), 'south': (w // 2, 1, d - 1), 'west': (0, 1, d // 2), 'east': (w - 1, 1, d // 2)} points = [doors[k] for k in self.doors] + [(w // 2, 1, d // 2)] if not self.doors: points = [(w // 2, 1, d // 2)] interior = Box((1, 1, 1), (w - 2, 5, d - 2)) boundary = [] for x in range(w): for z in range(d): # Upper landing leaves only the required stair slot open. if not (self.stair_down and x in (w - 4, w - 3) and 2 <= z <= 7): boundary.append((x, 0, z)) if not (self.stair_up and x in (w - 4, w - 3) and 2 <= z <= 7): boundary.append((x, 6, z)) function = {'bedroom': [['red_bed'], ['barrel']], 'workshop': [['crafting_table'], ['smithing_table']], 'library': [['bookshelf'], ['lectern']], 'kitchen': [['smoker'], ['furnace']], 'living': [['spruce_stairs'], ['barrel']], 'storage': [['barrel']]} rules = (Rule('route', tuple(points), Box((0, 1, 0), (w - 1, 8, d - 1)), phase='complete'), Rule('light', tuple(points), Box((0, 1, 0), (w - 1, 5, d - 1)), {'minimum': 1}, 'complete'), Rule('furnishing', box=interior, data={'groups': function[self.purpose]}, phase='complete'), Rule('sealed', tuple(boundary), phase='complete')) ports = tuple(Port(side, 'access', Frame(p), Box(p, (p[0], p[1] + 1, p[2])), 10) for side, p in doors.items() if side in self.doors) return Contract(Box((-1, 0, -1), (w, 9, d)), ports=ports, rules=rules, decisions={'purpose': self.purpose, 'doors': self.doors, 'windows': self.windows, 'stair_up': self.stair_up, 'stair_down': self.stair_down}) def realize(self, ctx, contract): w, d = self.width, self.depth p = Plan() floor = Plan() for x in range(w): for z in range(d): if not (self.stair_down and x in (w - 4, w - 3) and 2 <= z <= 7): floor.block((x, 0, z), state_of('spruce_planks')) p.children.append(Child('floor', Pattern('floor', Box((0, 0, 0), (w - 1, 0, d - 1)), tuple(floor.writes)))) if not self.upper_open: p.children.append(Child('ceiling', Volume(Box((0, 6, 0), (w - 1, 6, d - 1)), state_of('spruce_planks'), 'ceiling'))) walls = {'north': (Frame((0, 1, 0)), w), 'south': (Frame((w - 1, 1, d - 1), 2), w), 'east': (Frame((w - 1, 1, 1), 1), d - 2), 'west': (Frame((0, 1, d - 2), 3), d - 2)} for side, (frame, length) in walls.items(): wallpath = ctx.path + '/wall-' + side p.children.append(Child('wall-' + side, Wall(length, 5), frame=frame)) if side in self.doors: at = frame.compose(Frame((length // 2, 0, 0))) p.children.append(Child('door-' + side, Door(), frame=at, bindings=(Binding(wallpath, 'infill'),))) if side in self.windows: bays = (2, length - 4) if length >= 11 else ((1, length - 3) if length >= 9 else ((length - 2) // 2,)) for i, bay in enumerate(bays): if side in self.doors and abs(bay - length // 2) < 2: continue at = frame.compose(Frame((bay, 2, 0))) p.children.append(Child(f'window-{side}-{i}', self.window_component or Window(), frame=at, bindings=(Binding(wallpath, 'infill'),))) # Furnish the opposite half to the flight; clipping stays inside the furnishing component's declared domain. furniture = Furniture(self.purpose, w, d) if self.stair_up or self.stair_down: furniture = Furniture(self.purpose, w - 3, d) p.children.append(Child('furniture', furniture, frame=Frame((0, 1, 0)))) for i, (x, z) in enumerate(((2, d - 3), (w - 3, 2))): if self.stair_up and i == 1: x = w // 2 p.children.append(Child(f'light-{i}', self.light_component or Light(), frame=Frame((x, 4, z)))) from .landscape import FacadeGarden p.children.append(Child('facade-garden', FacadeGarden(w, d, tuple(s for s in self.windows if s not in self.doors)))) if self.stair_up: p.children.append(Child('stairs', Stair(), frame=Frame((w - 4, 1, 2)))) return p @dataclass(frozen=True) class Pattern: role: str envelope: Box writes: tuple def capability(self): return Capability('surface.' + self.role, (self.role,)) def negotiate(self, ctx, parameters): return Contract(self.envelope) def realize(self, ctx, contract): return Plan(writes=list(self.writes))
hearth/components/landscape.py · 253 行 · 原文件
# Public paths, planted borders, lamps and constrained landscape compositions. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, stairs, slab, log, leaves, name_of from hearth.kernel import Capability, Contract, Port, Grant, Rule, Plan, Child, Binding, ContractError from hearth.composition import scatter from .primitives import Tree, Grass from .interior import Light @dataclass(frozen=True) class PathNetwork: waypoints: tuple[tuple[int, int], ...] links: tuple[tuple[int, int], ...] width: int = 3 gateway: tuple | None = None def capability(self): return Capability('landscape.paths', ('path', 'connection'), offers=('public-access',), adaptations=('terrain treads', 'bounded retaining edges'), guarantees=('connected public routes',)) def _points(self): points = set() for a, b in self.links: x, z = self.waypoints[a][0], self.waypoints[a][-1] xx, zz = self.waypoints[b][0], self.waypoints[b][-1] dx = 1 if xx >= x else -1 dz = 1 if zz >= z else -1 offsets = range(-(self.width // 2), self.width // 2 + 1) if x != xx: for px in range(x, xx + dx, dx): for offset in offsets: points.add((px, z + offset)) if z != zz: for pz in range(z, zz + dz, dz): for offset in offsets: points.add((xx + offset, pz)) if x == xx and z == zz: for ox in offsets: for oz in offsets: points.add((x + ox, z + oz)) return sorted(points) def negotiate(self, ctx, parameters): points = [] for x, z in self._points(): hint = min(self.waypoints, key=lambda q: abs(q[0] - x) + abs(q[-1] - z)) maximum = hint[1] + ctx.frame.origin[1] if len(hint) == 3 else None wx, _, wz = ctx.world((x, 0, z)) h = ctx.view.elevation(wx, wz, maximum=maximum) - ctx.frame.origin[1] points.append((x, h, z)) if not points: raise ContractError('empty-path', ctx.path) box = Box.enclosing(points).expand(2) targets = [] surface = {(x, z): y for x, y, z in points} for q in self.waypoints: x, z = q[0], q[-1] targets.append((x, surface[(x, z)] + 1, z)) clears = tuple((x, y + k, z) for x, y, z in points for k in (1, 2)) public = self.gateway or targets[0] interface = Box((public[0] - 1, public[1] - 1, public[2]), (public[0] + 1, public[1] + 1, public[2])) return Contract(box, ports=(Port('public', 'public-access', Frame(public), interface, 10000, 'join'),), grants=(Grant('join', interface, ('surface',), ('path',), 9),), rules=(Rule('support', tuple(points)), Rule('clear', clears), Rule('route', tuple(targets), box, phase='complete')), decisions={'surface': points, 'waypoints': self.waypoints, 'links': self.links}, reads=(box,)) def realize(self, ctx, contract): p = Plan() rng = ctx.rng('materials') heights = {(x, z): y for x, y, z in contract.decisions['surface']} for x, y, z in contract.decisions['surface']: uphill = [] for dx, dz, face in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north')): if heights.get((x + dx, z + dz), y) > y: uphill.append(face) material = stairs('stone_brick', uphill[0]) if uphill else state_of(rng.choice(('stone_bricks', 'stone_bricks', 'andesite', 'cobblestone', 'mossy_stone_bricks'))) p.block((x, y, z), material, 'paving') return p @dataclass(frozen=True) class Planter: width: int = 3 flowers: tuple[str, ...] = ('cornflower', 'azure_bluet', 'allium') def capability(self): return Capability('garden.planter', ('decoration', 'plant'), guarantees=('grounded bed',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (self.width - 1, 1, 1)), rules=(Rule('support', tuple((x, -1, z) for x in range(self.width) for z in range(2))),)) def realize(self, ctx, contract): p = Plan() rng = ctx.rng('flowers') for x in range(self.width): p.block((x, 0, 0), state_of('dirt'), 'soil') p.block((x, 1, 0), state_of(rng.choice(self.flowers)), 'flower') p.block((x, 0, 1), state_of('spruce_trapdoor', facing='south', half='bottom', open='true', powered='false', waterlogged='false'), 'edging') return p @dataclass(frozen=True) class LampPost: def capability(self): return Capability('landscape.lamppost', ('light', 'outdoor-light', 'composite')) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (1, 4, 0)), rules=(Rule('support', ((0, -1, 0),)),)) def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('stone_bricks')) for y in range(1, 4): p.block((0, y, 0), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false')) p.block((0, 4, 0), slab('spruce')) p.block((1, 4, 0), slab('spruce')) p.children.append(Child('lantern', Light(), frame=Frame((1, 2, 0)))) return p @dataclass(frozen=True) class Landscape: area: Box terrain: str tree_minimum: int = 6 tree_maximum: int = 14 density: float = 0.08 def capability(self): return Capability('landscape.scatter', ('landscape', 'composite'), adaptations=('clearance-aware scattering',), guarantees=('minimum tree count', 'preserved routes')) def negotiate(self, ctx, parameters): return Contract(self.area, decisions={'minimum_trees': self.tree_minimum, 'maximum_trees': self.tree_maximum, 'density': self.density}) def realize(self, ctx, contract): p = Plan() x0, _, z0 = self.area.lo x1, _, z1 = self.area.hi candidates = [(x, z) for x in range(x0 + 4, x1 - 3, 4) for z in range(z0 + 4, z1 - 3, 4)] def legal(q, accepted): x, z = q if any(abs(x - a) + abs(z - b) < 10 for a, b in accepted): return False h = ctx.elevation(x, z) if name_of(ctx.state((x, h, z))) != 'grass_block': return False box = Box((x - 3, h + 1, z - 3), (x + 3, h + 16, z + 3)) return all(ctx.view.domain.contains(ctx.world(c)) for c in box.corners()) and ctx.view.clear(ctx.frame.box(box)) and not ctx.view.protected(ctx.frame.box(Box((x - 3, h, z - 3), (x + 3, h + 2, z + 3)))) chosen = scatter(ctx, candidates, legal, self.tree_minimum, self.tree_maximum, 'trees') for i, (x, z) in enumerate(chosen): y = ctx.elevation(x, z) + 1 h = ctx.scope.child(f'tree-{i}').choose((9, 11, 13, 15), 'height') p.children.append(Child(f'tree-{i}', Tree(h), frame=Frame((x, y, z)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) rng = ctx.rng('groundcover') for x in range(x0 + 1, x1): for z in range(z0 + 1, z1): if rng.random() > self.density or any(abs(x - a) <= 3 and abs(z - b) <= 3 for a, b in chosen): continue h = ctx.elevation(x, z) if name_of(ctx.state((x, h, z))) != 'grass_block': continue if name_of(ctx.state((x, h + 1, z))) != 'air': continue if ctx.view.protected(ctx.frame.box(Box((x, h + 1, z), (x, h + 2, z)))): continue p.children.append(Child(f'grass-{x}-{z}', Grass(), frame=Frame((x, h + 1, z)), bindings=(Binding(self.terrain, 'planting', 'plant'),))) return p @dataclass(frozen=True) class FacadeGarden: width: int depth: int sides: tuple[str, ...] def capability(self): return Capability('facade.garden', ('decoration', 'plant'), adaptations=('avoid facade openings',), guarantees=('unobstructed doorways',)) def negotiate(self, ctx, parameters): return Contract(Box((-1, 0, -1), (self.width, 3, self.depth))) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth frames = {'north': Frame((0, 0, -1)), 'south': Frame((w - 1, 0, d), 2), 'east': Frame((w, 0, 0), 1), 'west': Frame((-1, 0, d - 1), 3)} for side in self.sides: f = frames[side] length = w if side in ('north', 'south') else d for y in range(1, 4): q = f.point((1, y, 0)) if name_of(ctx.view.state(ctx.world(q))) == 'air': p.block(q, leaves('oak'), 'climber') for x in (2, length - 3): q = f.point((x, 0, 0)) above = f.point((x, 1, 0)) if name_of(ctx.view.state(ctx.world(q))) == 'air' and name_of(ctx.view.state(ctx.world(above))) == 'air': p.block(q, slab('spruce', 'top'), 'flower-shelf') p.block(above, state_of('potted_poppy' if x == 2 else 'potted_fern'), 'pot') return p @dataclass(frozen=True) class Well: def capability(self): return Capability('square.well', ('amenity', 'composite'), guarantees=('contained water', 'grounded cover')) def negotiate(self, ctx, parameters): basin = tuple((x, 1, z) for x in range(1, 3) for z in range(1, 3)) return Contract(Box((-1, 0, -1), (4, 6, 4)), rules=(Rule('support', tuple((x, -1, z) for x in range(4) for z in range(4))), Rule('pool', basin), Rule('support', tuple((x, y, z) for x, z in ((0, 0), (3, 3)) for y in range(2, 6))))) def realize(self, ctx, contract): p = Plan() p.fill(Box((0, 0, 0), (3, 1, 3)), state_of('stone_bricks'), 'basin') p.fill(Box((1, 1, 1), (2, 1, 2)), state_of('water', level='0'), 'water') for x, z in ((0, 0), (3, 3)): p.fill(Box((x, 2, z), (x, 5, z)), log(), 'post') for x in range(-1, 5): for z in range(-1, 5): p.block((x, 5 if x in (-1, 4) else 6, z), slab('dark_oak'), 'shelter') return p @dataclass(frozen=True) class Terrace: width: int = 10 depth: int = 10 def capability(self): return Capability('site.terrace', ('siteworks', 'composite'), adaptations=('small local fill', 'retaining border'), guarantees=('level civic amenity pad',)) def negotiate(self, ctx, parameters): heights = [ctx.view.elevation(ctx.world((x, 0, z))[0], ctx.world((x, 0, z))[2]) - ctx.frame.origin[1] for x in range(self.width) for z in range(self.depth)] top = max(heights) if top - min(heights) > 3: raise ContractError('terrace-relief', ctx.path, conditions='Small terrace limit is 3') region = Box((0, top, 0), (self.width - 1, top + 2, self.depth - 1)) return Contract(Box((0, min(heights), 0), (self.width - 1, top + 8, self.depth - 1)), ports=(Port('entrance', 'public-access', Frame((0, top + 1, self.depth // 2)), region, 10, 'paving'),), grants=(Grant('paving', region, ('surface',), ('path',), 32),), decisions={'height': top, 'fill': sum(top - h for h in heights), 'excavation': 0}) def realize(self, ctx, contract): p = Plan() top = contract.decisions['height'] for x in range(self.width): for z in range(self.depth): wx, _, wz = ctx.world((x, 0, z)) bed = ctx.view.elevation(wx, wz) - ctx.frame.origin[1] for y in range(bed, top + 1): material = 'cobblestone' if y < top else ('stone_bricks' if x in (0, self.width - 1) or z in (0, self.depth - 1) else 'andesite') p.block((x, y, z), state_of(material), 'terrace-paving') p.children.append(Child('well', Well(), frame=Frame((3, top + 1, 3)))) for i, x in enumerate((1, self.width - 2)): p.children.append(Child(f'planter-{i}', Planter(2), frame=Frame((x if i == 0 else x - 1, top + 1, 1)))) return p
hearth/components/primitives.py · 191 行 · 原文件
# Small architectural components with executable contracts. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import AIR, state_of, log, leaves, name_of from hearth.kernel import Capability, Contract, Domain, Grant, Port, Rule, Plan, Child, Binding, ContractError @dataclass(frozen=True) class Volume: box: Box material: str role: str = 'masonry' def capability(self): return Capability('volume.' + self.role, (self.role,)) def negotiate(self, ctx, parameters): return Contract(self.box) def realize(self, ctx, contract): plan = Plan() plan.fill(self.box, self.material) return plan @dataclass(frozen=True) class Grass: tall: bool = False def capability(self): return Capability('plant.grass', ('plant',), offers=('replacement',), assumptions=('substrate',)) def negotiate(self, ctx, parameters): box = Box((0, 0, 0), (0, int(self.tall), 0)) return Contract(box, (Port('replacement', 'planting', Frame(), box, grant='replace'),), (Grant('replace', box, ('plant',), ('tree',), 2, True),), (Rule('support', ((0, -1, 0),)),), atomic_object=True) def realize(self, ctx, contract): plan = Plan() if self.tall: for y, half in enumerate(('lower', 'upper')): plan.block((0, y, 0), state_of('tall_grass', half=half)) else: plan.block((0, 0, 0), state_of('short_grass')) return plan @dataclass(frozen=True) class Tree: height: int = 10 radius: int = 3 def capability(self): return Capability('plant.conifer', ('plant', 'tree'), {'height': Domain(5, 18), 'radius': Domain(1, 4)}, assumptions=('substrate',), adaptations=('prune canopy against obstacles within accepted radius',)) def negotiate(self, ctx, parameters): h, r = parameters.get('height', self.height), parameters.get('radius', self.radius) if not 5 <= h <= 18 or not 1 <= r <= 4: raise ContractError('tree-domain', ctx.path) return Contract(Box((-r, 0, -r), (r, h, r)), rules=(Rule('support', ((0, -1, 0),)), Rule('expected', ((0, 0, 0),), data={'names': ['spruce_log']})), decisions={'height': h, 'radius': r}, reads=(Box((-r, -1, -r), (r, h, r)),)) def realize(self, ctx, contract): p = Plan() h = contract.decisions['height'] radius = contract.decisions['radius'] for y in range(h): p.block((0, y, 0), log()) for y in range(3, h + 1): if y % 3 == 0 and y != h: continue r = min(radius, max(0, (h - y + 1) // 2)) if y % 3 == 0: r = max(0, r - 1) for x in range(-r, r + 1): for z in range(-r, r + 1): if abs(x) + abs(z) > r + 1 or (x == 0 and z == 0 and y < h): continue q = ctx.world((x, y, z)) if ctx.view.domain and not ctx.view.domain.contains(q): continue if name_of(ctx.view.state(q)) == 'air': p.block((x, y, z), leaves()) return p @dataclass(frozen=True) class Wall: width: int = 9 height: int = 5 thickness: int = 1 infill: str | None = None timber: str = 'spruce' def capability(self): return Capability('wall.framed', ('wall', 'enclosure'), offers=('window', 'door'), assumptions=('floor below',), guarantees=('frame preserved', 'sealed infill'), inputs={'width': Domain(5, 64), 'height': Domain(4, 12), 'thickness': Domain(1, 3), 'frame.turn': Domain(choices=(0, 1, 2, 3))}, locked=('width', 'height', 'thickness', 'infill')) def negotiate(self, ctx, parameters): w, h, t = self.width, self.height, self.thickness if not 5 <= w <= 64 or not 4 <= h <= 12 or not 1 <= t <= 3: raise ContractError('wall-domain', ctx.path) box = Box((0, 0, 0), (w - 1, h - 1, t - 1)) install = Box((1, 0, 0), (w - 2, h - 2, t - 1)) ports = (Port('infill', 'wall-installation', Frame((1, 0, 0)), install, 20, 'install', 1, {'thickness': t, 'sill': 1, 'margin': 1}),) grants = (Grant('install', install, ('install',), ('window', 'door'), w * h * t),) boundary = tuple(box.cells()) frame = tuple((x, y, z) for x in (0, w - 1) for y in range(-1, h) for z in range(t)) return Contract(box, ports, grants, (Rule('support', frame), Rule('sealed', boundary, phase='complete')), decisions={'width': w, 'height': h, 'thickness': t}) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, self.infill or ctx.view.style['infill']) for x in (0, self.width - 1): p.fill(Box((x, 0, 0), (x, self.height - 1, self.thickness - 1)), log(self.timber)) p.fill(Box((0, self.height - 1, 0), (self.width - 1, self.height - 1, self.thickness - 1)), log(self.timber, 'x')) return p @dataclass(frozen=True) class Window: width: int = 2 height: int = 2 shutters: bool = True glass: str = 'minecraft:glass' def capability(self): return Capability('window.shuttered' if self.shutters else 'window.lattice', ('window', 'sealed-opening'), offers=('daylight',), adaptations=('depth reveal',), guarantees=('sealed opening', 'frame margins')) def negotiate(self, ctx, parameters): if not ctx.bindings: raise ContractError('window-host', ctx.path) port = ctx.view.port(ctx.bindings[0].host, ctx.bindings[0].port) depth = port.facts['thickness'] box = Box((-1, -1, -1), (self.width, self.height - 1, depth - 1)) inner = Box((0, 0, 0), (self.width - 1, self.height - 1, depth - 1)) if not all(port.region.contains(ctx.world(q)) for q in inner.corners()): raise ContractError('window-margins', ctx.path, ctx.frame.origin, 'Opening crosses excluded framing') return Contract(box, rules=(Rule('sealed', tuple(inner.cells())),), decisions={'depth': depth}) def realize(self, ctx, contract): p = Plan() d = contract.decisions['depth'] for z in range(d): p.fill(Box((0, 0, z), (self.width - 1, self.height - 1, z)), self.glass, 'glazing') if self.shutters: from hearth.blocks import slab for x in (-1, self.width): for y in range(self.height): p.block((x, y, -1), state_of('spruce_trapdoor', facing='north', half='bottom', open='true', powered='false', waterlogged='false'), 'shutters') for x in range(self.width): p.block((x, -1, -1), slab('spruce', 'top'), 'sill') else: for x in range(self.width): p.block((x, self.height - 1, -1), state_of('spruce_trapdoor', facing='north', half='top', open='false', powered='false', waterlogged='false'), 'hood') return p @dataclass(frozen=True) class Pool: width: int = 7 depth: int = 6 def capability(self): return Capability('water.basin', ('pool', 'siteworks'), adaptations=('bounded excavation',), guarantees=('contained water',)) def negotiate(self, ctx, parameters): box = Box((0, -2, 0), (self.width - 1, 0, self.depth - 1)) water = tuple(Box((1, -1, 1), (self.width - 2, 0, self.depth - 2)).cells()) return Contract(box, rules=(Rule('pool', water),), decisions={'excavation_limit': box.volume}) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('smooth_sandstone'), 'basin') p.fill(Box((1, -1, 1), (self.width - 2, 0, self.depth - 2)), state_of('water', level='0'), 'water') return p @dataclass(frozen=True) class Assembly: name: str envelope: Box children: tuple[Child, ...] rules: tuple[Rule, ...] = () ports: tuple[Port, ...] = () def capability(self): return Capability(self.name, ('composite',)) def negotiate(self, ctx, parameters): return Contract(self.envelope, ports=self.ports, rules=self.rules) def realize(self, ctx, contract): return Plan(children=list(self.children))
hearth/components/roofs.py · 125 行 · 原文件
# Pitched roof surfaces and open porch attachments with explicit overlap policy. from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of, stairs, slab, log, name_of from hearth.kernel import Capability, Contract, Grant, Port, Rule, Plan, Child from .interior import Light from .primitives import Window @dataclass(frozen=True) class Roof: width: int depth: int axis: str = 'z' material: str = 'deepslate_tile' steep: bool = True def capability(self): return Capability('roof.gable', ('roof', 'enclosure'), offers=('junction',), adaptations=('abut taller wall', 'merge shared eaves'), guarantees=('pitched weather skin',)) def negotiate(self, ctx, parameters): span = self.width if self.axis == 'z' else self.depth height = (span + 2) // 2 + 2 box = Box((-1, -1, -1), (self.width, height, self.depth)) return Contract(box, (Port('junction', 'roof-seam', Frame(), box, 100, 'junction'),), (Grant('junction', box, ('join',), ('roof',), box.volume),), decisions={'axis': self.axis, 'span': span, 'steep': self.steep, 'material': self.material}) def realize(self, ctx, contract): p = Plan() w, d = self.width, self.depth span = w if self.axis == 'z' else d length = d if self.axis == 'z' else w for cross in range(-1, span + 1): step = min(cross + 1, span - cross) y = step if self.steep else (step + 1) // 2 face = ('east' if cross < span / 2 else 'west') if self.axis == 'z' else ('south' if cross < span / 2 else 'north') for along in range(-1, length + 1): x, z = (cross, along) if self.axis == 'z' else (along, cross) q = ctx.world((x, y, z)) existing = name_of(ctx.view.state(q)) if existing != 'air': # Negotiated abutment is only to actual masonry/roof boundaries. continue trim = along in (-1, length) material = 'dark_oak' if trim else self.material p.block((x, y, z), stairs(material, face), 'roof-course') for end in (0, length - 1): frame = Frame((0, 0, end)) if self.axis == 'z' else Frame((end, 0, span - 1), 3) p.children.append(Child(f'gable-{end}', Gable(span, self.steep), frame=frame)) for cross in (-1, span): for along in range(length): x, z = (cross, along) if self.axis == 'z' else (along, cross) if name_of(ctx.view.state(ctx.world((x, -1, z)))) == 'air': p.block((x, -1, z), slab('spruce', 'top'), 'eave') mid = span // 2 peak = min(mid + 1, span - mid) if self.steep else (min(mid + 1, span - mid) + 1) // 2 for along in range(-1, length + 1): x, z = (mid, along) if self.axis == 'z' else (along, mid) if name_of(ctx.view.state(ctx.world((x, peak + 1, z)))) == 'air': p.block((x, peak + 1, z), slab('dark_oak'), 'ridge') for along in (-1, length): x, z = (mid, along) if self.axis == 'z' else (along, mid) if name_of(ctx.view.state(ctx.world((x, peak + 2, z)))) == 'air': p.block((x, peak + 2, z), state_of('dark_oak_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'finial') return p @dataclass(frozen=True) class Porch: width: int depth: int = 3 def capability(self): return Capability('attachment.porch', ('attachment', 'access', 'composite'), guarantees=('open sheltered access',)) def negotiate(self, ctx, parameters): center = self.width // 2 clear = tuple((x, y, z) for x in range(center - 1, center + 2) for y in (1, 2) for z in range(-self.depth, 0)) return Contract(Box((0, 0, -self.depth), (self.width - 1, 6, -1)), rules=(Rule('clear', clear),)) def realize(self, ctx, contract): p = Plan() w = self.width d = self.depth p.fill(Box((0, 0, -d), (w - 1, 0, -1)), state_of('spruce_planks'), 'deck') for x in (0, w - 1): p.fill(Box((x, 1, -d), (x, 4, -d)), log(), 'post') for z in range(-d, 0): y = 4 + (z + d) // 2 for x in range(w): p.block((x, y, z), slab('dark_oak') if z % 2 else stairs('dark_oak', 'south'), 'canopy') for x in range(w): if abs(x - w // 2) > 1: p.block((x, 1, -d), state_of('spruce_fence', north='false', south='false', east=str(x < w - 1).lower(), west=str(x > 0).lower(), waterlogged='false'), 'balustrade') p.children.append(Child('lantern', Light(), frame=Frame((1, 2, -2)))) return p @dataclass(frozen=True) class Gable: span: int steep: bool = True def capability(self): return Capability('wall.gable', ('wall', 'enclosure'), offers=('window',), adaptations=('abut existing upper wall',)) def negotiate(self, ctx, parameters): height = (self.span + 1) // 2 region = Box((1, 0, 0), (self.span - 2, height - 2, 0)) box = Box((0, -1, -1), (self.span - 1, height - 1, 0)) return Contract(box, (Port('infill', 'wall-installation', Frame((1, 0, 0)), region, 4, 'install', facts={'thickness': 1}),), (Grant('install', region, ('install',), ('window',), 30),)) def realize(self, ctx, contract): p = Plan() for x in range(self.span): step = min(x + 1, self.span - x) y = step if self.steep else (step + 1) // 2 for yy in range(y): if name_of(ctx.view.state(ctx.world((x, yy, 0)))) == 'air': p.block((x, yy, 0), log('spruce') if x in (0, self.span // 2, self.span - 1) else state_of('smooth_sandstone'), 'gable-infill') available = {w.point for w in p.writes} at = (self.span // 2 - 1, 0, 0) if self.steep and all((at[0] + x, y, 0) in available for x in range(2) for y in (0, 1)) and all(name_of(ctx.view.state(ctx.world((at[0] + x, 1, -1)))) == 'air' for x in range(2)): from hearth.kernel import Binding p.children.append(Child('window', Window(2, 2, False), frame=Frame(at), bindings=(Binding(ctx.path, 'infill'),))) return p
hearth/composition.py · 61 行 · 原文件
# High-level selection, arrangement, repetition, scattering and encapsulation. from dataclasses import dataclass from hearth.kernel import Capability, Contract, Plan, Child, ContractError, Rule from hearth.space import Box, Frame @dataclass(frozen=True) class Network: name: str envelope: Box recipe: object tags: tuple = ('composite',) rules: tuple[Rule, ...] = () def capability(self): return Capability(self.name, self.tags) def negotiate(self, ctx, parameters): return Contract(self.envelope, rules=self.rules) def realize(self, ctx, contract): return self.recipe(ctx) def encapsulate(name, envelope, recipe, tags=('composite',), rules=()): return Network(name, envelope, recipe, tags, rules) def attach(key, component, host, port, frame, verb='install', region=None): from hearth.kernel import Binding return Child(key, component, frame=frame, bindings=(Binding(host, port, verb, region),)) def arrange(components, origins, prefix='item'): components, origins = tuple(components), tuple(origins) if len(components) != len(origins): raise ValueError('One placement per component is required') return tuple(Child(f'{prefix}-{i}', c, frame=Frame(tuple(p))) for i, (c, p) in enumerate(zip(components, origins))) def repeat(component, origins, prefix='repeat'): return arrange([component for _ in origins], origins, prefix) def scatter(ctx, candidates, predicate, minimum, maximum, purpose='scatter'): candidates = sorted(set(candidates)) ctx.rng(purpose).shuffle(candidates) accepted = [] for p in candidates: if predicate(p, accepted): accepted.append(p) if len(accepted) >= maximum: break if len(accepted) < minimum: raise ContractError('scatter-minimum', ctx.path, conditions=f'Accepted {len(accepted)}, required {minimum}; finite candidate set exhausted') return tuple(accepted) def constrain(condition, rule, context, position=None, reason=''): if not condition: raise ContractError(rule, context.path, position, reason)
hearth/environment/__init__.py · 3 行 · 原文件
# Public environment operations. from .fields import Field, constant, gradient, radial, wave from .terrain import Terrain
hearth/environment/fields.py · 79 行 · 原文件
# Serializable scalar-field expressions; recognizable terrain emerges from parameters. from dataclasses import dataclass import math @dataclass(frozen=True) class Field: op: str args: tuple def __call__(self, x, z): a = self.args if self.op == 'constant': return a[0] if self.op == 'gradient': return a[0] * x + a[1] * z + a[2] if self.op == 'wave': return a[0] * math.sin(x * a[1] + a[3]) * math.cos(z * a[2] + a[3]) if self.op == 'radial': return a[3] * max(0, 1 - math.hypot(x - a[0], z - a[1]) / a[2]) if self.op == 'add': return a[0](x, z) + a[1](x, z) if self.op == 'multiply': return a[0](x, z) * a[1](x, z) if self.op == 'blend': mask = min(1, max(0, a[2](x, z))) return (1 - mask) * a[0](x, z) + mask * a[1](x, z) if self.op == 'transform': return a[0]((x - a[1]) / a[3], (z - a[2]) / a[3]) if self.op == 'clamp': return max(a[1], min(a[2], a[0](x, z))) raise ValueError(self.op) def __add__(self, other): return Field('add', (self, as_field(other))) def __mul__(self, other): return Field('multiply', (self, as_field(other))) def blend(self, other, mask): return Field('blend', (self, as_field(other), as_field(mask))) def transformed(self, dx=0, dz=0, scale=1): if scale <= 0: raise ValueError('Scale must be positive') return Field('transform', (self, dx, dz, scale)) def clamp(self, low, high): return Field('clamp', (self, low, high)) def expression(self): return {'op': self.op, 'args': [a.expression() if isinstance(a, Field) else a for a in self.args]} def as_field(value): return value if isinstance(value, Field) else constant(value) def constant(value=0): return Field('constant', (value,)) def gradient(x=0, z=0, base=0): return Field('gradient', (x, z, base)) def wave(amplitude=1, frequency_x=0.1, frequency_z=0.1, phase=0): return Field('wave', (amplitude, frequency_x, frequency_z, phase)) def radial(x, z, radius, amplitude): if radius <= 0: raise ValueError('Radius must be positive') return Field('radial', (x, z, radius, amplitude)) def from_expression(expression): """Restore only declared field operations, never execute a serialized program.""" return Field(expression['op'], tuple(from_expression(a) if isinstance(a, dict) and 'op' in a else a for a in expression['args']))
hearth/environment/terrain.py · 42 行 · 原文件
# Frozen field sampling, strata and water under scoped edit interfaces. import math from dataclasses import dataclass from hearth.space import Box, Frame from hearth.blocks import state_of from hearth.kernel import Capability, Contract, Grant, Port, Plan, Rule from .fields import Field @dataclass(frozen=True) class Terrain: area: Box field: Field water_level: int | None = None edit_limit: int = 2500 def capability(self): return Capability('terrain.field', ('environment', 'ground'), offers=('construction', 'planting'), guarantees=('frozen field inputs', 'actual 3D substrate')) def negotiate(self, ctx, parameters): ports = tuple(Port(k, k, Frame(self.area.lo), self.area, capacity=100000, grant=k) for k in ('construction', 'planting')) grants = (Grant('construction', self.area, ('excavate', 'fill', 'surface'), ('siteworks', 'path', 'pool'), self.edit_limit), Grant('planting', self.area, ('plant',), ('plant',), 0)) return Contract(self.area, ports, grants, decisions={'expression': self.field.expression(), 'water': self.water_level, 'edit_limit': self.edit_limit}) def realize(self, ctx, contract): plan = Plan() x0, bottom, z0 = self.area.lo x1, top, z1 = self.area.hi for x in range(x0, x1 + 1): for z in range(z0, z1 + 1): height = math.floor(self.field(x, z)) if not bottom <= height < top: raise ValueError(f'Terrain field exceeds negotiated vertical domain at {(x,z)}') for y in range(bottom, height + 1): material = 'stone' if y < height - 2 else ('dirt' if y < height else 'grass_block') if self.water_level is not None and height < self.water_level: material = 'gravel' if y == height else material plan.block((x, y, z), state_of(material), 'strata') if self.water_level is not None: for y in range(height + 1, self.water_level + 1): plan.block((x, y, z), state_of('water', level='0'), 'water-volume') return plan
hearth/kernel/__init__.py · 5 行 · 原文件
# Public composition kernel, independent of architectural implementations. from .contracts import Binding, Capability, Child, Choice, Component, Contract, Domain, Grant, Plan, Port, Registry, Rule, Write from .errors import ContractError, Diagnostic, SearchExhausted, ValidationError from .scene import Context, Limits, Scene from .validation import validate, validator
hearth/kernel/contracts.py · 150 行 · 原文件
# Serializable contracts, binding requests and pure candidate plans. from dataclasses import dataclass, field from typing import Any, Protocol from hearth.space import Box, Frame, Pos @dataclass(frozen=True) class Domain: minimum: float | None = None maximum: float | None = None choices: tuple = () def accepts(self, value): return (not self.choices or value in self.choices) and (self.minimum is None or value >= self.minimum) and (self.maximum is None or value <= self.maximum) @dataclass(frozen=True) class Capability: name: str tags: tuple[str, ...] parameters: dict[str, Domain] = field(default_factory=dict) offers: tuple[str, ...] = () assumptions: tuple[str, ...] = () adaptations: tuple[str, ...] = () guarantees: tuple[str, ...] = () version: str = '1' inputs: dict = field(default_factory=dict) locked: tuple[str, ...] = () @dataclass(frozen=True) class Rule: kind: str cells: tuple[Pos, ...] = () box: Box | None = None data: dict = field(default_factory=dict) phase: str = 'invariant' def transformed(self, frame): return Rule(self.kind, tuple(frame.point(p) for p in self.cells), frame.box(self.box) if self.box else None, self.data, self.phase) @dataclass(frozen=True) class Grant: key: str box: Box verbs: tuple[str, ...] tags: tuple[str, ...] = () limit: int = 100000 whole: bool = False @dataclass(frozen=True) class Port: key: str kind: str frame: Frame region: Box capacity: int = 1 grant: str | None = None alignment: int = 1 facts: dict = field(default_factory=dict) delegate: tuple[str, str] | None = None @dataclass(frozen=True) class Contract: envelope: Box ports: tuple[Port, ...] = () grants: tuple[Grant, ...] = () rules: tuple[Rule, ...] = () decisions: dict = field(default_factory=dict) reads: tuple[Box, ...] = () atomic_object: bool = False def transformed(self, frame): return Contract(frame.box(self.envelope), tuple(Port(p.key, p.kind, frame.compose(p.frame), frame.box(p.region), p.capacity, p.grant, p.alignment, p.facts, p.delegate) for p in self.ports), tuple(Grant(g.key, frame.box(g.box), g.verbs, g.tags, g.limit, g.whole) for g in self.grants), tuple(r.transformed(frame) for r in self.rules), self.decisions, tuple(frame.box(b) for b in self.reads), self.atomic_object) @dataclass(frozen=True) class Binding: host: str port: str verb: str = 'install' region: Box | None = None @dataclass(frozen=True) class Write: point: Pos state: str operation: str = 'realize' preserve_owner: bool = False nbt: dict | None = None @dataclass(frozen=True) class Child: key: str component: Any params: dict = field(default_factory=dict) frame: Frame = Frame() bindings: tuple[Binding, ...] = () seed: int | None = None @dataclass(frozen=True) class Choice: key: str candidates: tuple[Child, ...] score: Any tolerance: float = 0.5 @dataclass class Plan: writes: list[Write] = field(default_factory=list) children: list[Child] = field(default_factory=list) relations: list[tuple[str, str, str]] = field(default_factory=list) def block(self, point, state, operation='realize', **kwargs): self.writes.append(Write(tuple(point), state, operation, **kwargs)) def fill(self, box, state, operation='fill'): self.writes.extend(Write(p, state, operation) for p in box.cells()) class Component(Protocol): def capability(self) -> Capability: ... def negotiate(self, context, parameters: dict) -> Contract: ... def realize(self, context, contract: Contract) -> Plan: ... class Registry: def __init__(self): self.entries = {} def register(self, component): self.entries[component.capability().name] = component return component def select(self, *tags): return tuple(self.entries[k] for k in sorted(self.entries) if set(tags) <= set(self.entries[k].capability().tags))
hearth/kernel/errors.py · 32 行 · 原文件
# Structured, stable diagnostics for failed contracts and searches. from dataclasses import dataclass @dataclass(frozen=True) class Diagnostic: rule: str component: str position: tuple | None conditions: str def __str__(self): return f'{self.rule}: {self.component} at {self.position}: {self.conditions}' class ContractError(ValueError): def __init__(self, rule, component='/', position=None, conditions=''): self.diagnostic = Diagnostic(rule, component, position, conditions) super().__init__(str(self.diagnostic)) class ValidationError(ContractError): def __init__(self, diagnostics): self.diagnostics = diagnostics self.diagnostic = diagnostics[0] ValueError.__init__(self, '\n'.join(map(str, diagnostics[:12]))) class SearchExhausted(ContractError): pass
hearth/kernel/scene.py · 542 行 · 原文件
# Transaction kernel, automatic ownership and separate semantic/dependency graphs. import copy from dataclasses import dataclass, field, replace, is_dataclass, fields from hearth.blocks import AIR, canonical, validate_state from hearth.space import Box, Frame from hearth.randomness import Scope from .contracts import Binding, Capability, Child, Choice, Contract, Domain, Plan from .errors import ContractError, ValidationError, SearchExhausted from .view import View, ReadTrace from .validation import validate @dataclass(frozen=True) class Limits: dimension: int = 512 blocks: int = 1000000 depth: int = 40 search: int = 24 instances: int = 10000 export_volume: int = 16000000 @dataclass(frozen=True) class Cell: state: str owner: str operation: str nbt: dict | None = None shared: tuple[str, ...] = () @dataclass class Node: path: str type: str version: str parameters: dict frame: Frame scope: Scope contract: Contract parent: str | None primary: str | None = None complete: bool = True stale: bool = False bindings: tuple = () capability: Capability | None = None shared_bindings: tuple = () @dataclass(frozen=True) class Context: path: str frame: Frame scope: Scope view: View bindings: tuple[Binding, ...] limits: Limits def rng(self, purpose='plan'): return self.scope.stream(purpose) def world(self, p): return self.frame.point(p) def local(self, p): return self.frame.inverse(p) def elevation(self, x, z, maximum=None): world = self.world((x, 0, z)) cap = None if maximum is None else maximum + self.frame.origin[1] return self.view.elevation(world[0], world[2], maximum=cap) - self.frame.origin[1] def water(self, x, z): world = self.world((x, 0, z)) level = self.view.water(world[0], world[2]) return None if level is None else level - self.frame.origin[1] def state(self, point): return self.view.state(self.world(point)) class Scene: def __init__(self, seed=0, limits=None, domain=None, style=None, preferences=None): if not isinstance(seed, int): raise TypeError('Seed must be an integer') self.seed = seed self.style = dict(style or {"timber": "spruce", "infill": "minecraft:smooth_sandstone", "roof": "deepslate_tile"}) self.preferences = dict(preferences or {}) self.limits = limits or Limits() self.domain = domain self.blocks = {} self.nodes = {} self.reverse = {} self.reverse_shared = {} self.relations = set() self.members = {} self.dependencies = [] self.operations = {} self.displaced = {} self.erasures = {} self.port_uses = {} self.version = 0 self.completed = False self._recipes = {} self.events = [] @property def view(self): return View(self) def _fork(self): other = copy.copy(self) other.blocks = self.blocks.copy() other.nodes = {p: copy.copy(n) for p, n in self.nodes.items()} other.reverse = {k: set(v) for k, v in self.reverse.items()} other.reverse_shared = {k: set(v) for k, v in self.reverse_shared.items()} other.relations = set(self.relations) other.members = {k: set(v) for k, v in self.members.items()} other.dependencies = list(self.dependencies) other.operations = copy.deepcopy(self.operations) other.displaced = {k: dict(v) for k, v in self.displaced.items()} other.erasures = dict(self.erasures) other.port_uses = dict(self.port_uses) other._recipes = self._recipes.copy() other.events = list(self.events) return other def fork(self, seed=None): """Copy a frozen composition; an optional seed controls future placements only.""" result = self._fork() if seed is not None: if not isinstance(seed, int): raise TypeError('Seed must be an integer') result.seed = seed return result def _commit(self, candidate): candidate.version += 1 candidate.completed = False self.__dict__.update(candidate.__dict__) def place(self, key, component, params=None, frame=Frame(), bindings=(), seed=None, complete=True): if not isinstance(key, str) or not key or any(c in key for c in '/#'): raise ContractError('instance-key', conditions='Keys must be nonempty and exclude / and #') candidate = self._fork() path = '/' + key candidate._instantiate(path, component, params or {}, frame, tuple(bindings), None, Scope(self.seed).child(key, seed), complete) candidate._check(False) self._commit(candidate) return path def compose_choice(self, choice): trial = self._fork() trial._select_child('', choice, Frame(), Scope(self.seed)) trial._check(False) self._commit(trial) return '/' + choice.key def choose(self, key, candidates, score=lambda scene, path: 0): accepted, failed = [], [] for index, child in enumerate(candidates): if index >= self.limits.search: break trial = self._fork() try: path = trial.place(key, child.component, child.params, child.frame, child.bindings, child.seed) accepted.append((score(trial, path), index, trial, path)) except ContractError as exc: failed.append(str(exc)) if not accepted: raise SearchExhausted('search-budget', '/' + key, conditions=f'No validated candidate within budget {self.limits.search}; failures={failed}') accepted.sort(key=lambda item: (item[0], item[1])) best_score = accepted[0][0] best = [c for c in accepted if c[0] <= best_score + 0.1] chosen = Scope(self.seed).child(key).choose(best, 'alternatives') self._commit(chosen[2]) self.events.append({'kind': 'search', 'key': key, 'accepted': len(accepted), 'rejected': len(failed), 'failures': failed}) return chosen[3] def _instantiate(self, path, component, params, frame, bindings, parent, scope, complete=True): if path in self.nodes: raise ContractError('duplicate-instance', path) if len(self.nodes) >= self.limits.instances: raise ContractError('instance-budget', path) if len(path.split('/')) > self.limits.depth: raise ContractError('recursion-budget', path) cap = component.capability() for key, value in params.items(): if key not in cap.parameters or not cap.parameters[key].accepts(value): raise ContractError('parameter-domain', path, conditions=f'{key}={value!r}') for key, domain in cap.inputs.items(): if not isinstance(domain, Domain): continue value = frame if key.startswith('frame.') else component parts = key.split('.')[1:] if key.startswith('frame.') else key.split('.') for part in parts: if part.startswith('_') or not hasattr(value, part): raise ContractError('capability-input', path, conditions=key) value = getattr(value, part) if not domain.accepts(value): raise ContractError('input-domain', path, conditions=f'{key}={value!r}') trace = ReadTrace() ctx = Context(path, frame, scope, View(self, trace), bindings, self.limits) local = component.negotiate(ctx, dict(params)) contract = local.transformed(frame) if max(contract.envelope.size) > self.limits.dimension: raise ContractError('dimension-budget', path) if parent and not all(self.nodes[parent].contract.envelope.contains(p) for p in contract.envelope.corners()): raise ContractError('child-envelope', path, contract.envelope.lo, f'Exceeds accepted parent {parent}') self.nodes[path] = Node(path, cap.name, cap.version, {"construction": describe_inputs(component), "arguments": dict(params)}, frame, scope, contract, parent, complete=False, bindings=bindings, capability=cap) self.displaced[path] = {} self.reverse[path] = set() self._recipes[path] = (component, params, frame, bindings, parent, scope, complete) if parent: self.relations.add((path, 'contained_by', parent)) self.members.setdefault(parent, set()).add(path) grants = [] for binding in bindings: if binding.host not in self.nodes: raise ContractError('missing-host', path, conditions=binding.host) effective_host, port = self.view.resolved_port(binding.host, binding.port) host = self.nodes[effective_host] use_key = (binding.host, binding.port) if self.port_uses.get(use_key, 0) >= port.capacity: raise ContractError('port-capacity', path, port.frame.origin, binding.port) self.port_uses[use_key] = self.port_uses.get(use_key, 0) + 1 if binding.verb == 'install': if not port.region.contains(frame.origin): raise ContractError('port-alignment', path, frame.origin, 'Origin outside installation region') if port.frame.inverse(frame.origin)[0] % port.alignment or frame.turn % 4 != port.frame.turn % 4: raise ContractError('port-alignment', path, frame.origin, 'Outside facade bay grid') grant = next((g for g in host.contract.grants if g.key == port.grant), None) if grant and binding.verb != 'connect': if binding.verb not in grant.verbs or (grant.tags and not set(cap.tags).intersection(grant.tags)): raise ContractError('permission-kind', path, frame.origin, f'{cap.tags} cannot {binding.verb} {binding.host}') grants.append((Binding(effective_host, port.key, binding.verb, binding.region), grant)) elif binding.verb != 'connect': raise ContractError('no-write-grant', path) kind = 'attached_to' if binding.verb == 'install' else ('connected_to' if binding.verb == 'connect' else 'supported_by') self.relations.add((path, kind, binding.host)) if kind == 'attached_to': self.members.setdefault(binding.host, set()).add(path) if kind == 'attached_to' and self.nodes[path].primary is None: self.nodes[path].primary = binding.host self.dependencies.append({'consumer': path, 'source': binding.host, 'version': self.version, 'region': binding.region or port.region.intersection(contract.envelope.expand(1)) or contract.envelope, 'reason': binding.verb}) for region in contract.reads: self.dependencies.append({'consumer': path, 'source': 'environment', 'version': self.version, 'region': region, 'reason': 'spatial-query'}) plan = component.realize(ctx, local) if trace.bounds: self.dependencies.append({'consumer': path, 'source': 'environment', 'version': self.version, 'region': trace.bounds, 'reason': 'observed-spatial-input'}) for source, region in sorted(trace.sources.items()): if source != path: self.dependencies.append({'consumer': path, 'source': source, 'version': self.version, 'region': region, 'reason': 'observed-interface-input'}) if not isinstance(plan, Plan): raise TypeError('Components return Plan effect sets') existing_consumers = set(self.nodes) - {path} final_writes = {} for write in plan.writes: p = frame.point(write.point) final_writes[p] = write protected_rules = [(n.path, r.box) for n in self.nodes.values() for r in n.contract.rules if r.kind == "protected" and r.box] retired = set() counts = {} for p, write in final_writes.items(): if not contract.envelope.contains(p): raise ContractError('envelope', path, p, 'Realization exceeds negotiated bounds') for protector, region in protected_rules: if region.contains(p) and protector != path: raise ContractError('protected-region', path, p, 'Immutable region held by ' + protector) old = self.blocks.get(p) if old and old.shared and not write.preserve_owner: raise ContractError('shared-consumer', path, p, 'Shared support requires explicit consumer rebinding') if old and write.preserve_owner and old.state.split('[')[0] != write.state.split('[')[0]: raise ContractError('property-update', path, p, 'Property adjustment must retain block type') if old and old.owner != path: authorization = next(((b, g) for b, g in grants if b.host == old.owner and g.box.contains(p) and (b.region is None or b.region.contains(p))), None) if authorization is None: raise ContractError('write-authority', path, p, f'Owned by {old.owner}; no scoped grant') binding, grant = authorization count_key = (binding.host, grant.key) counts[count_key] = counts.get(count_key, 0) + 1 if counts[count_key] > grant.limit: raise ContractError('edit-limit', path, p, f'Limit {grant.limit}') if self.nodes[old.owner].contract.atomic_object and not write.preserve_owner: if not grant.whole or not self.reverse[old.owner].issubset(final_writes): raise ContractError('whole-object', path, p, f'Partial replacement of {old.owner}') retired.add(old.owner) if old and old.owner != path: self.displaced[path].setdefault(p, old) if old: self.reverse[old.owner].discard(p) try: world_state = frame.state(write.state) validate_state(world_state) except ValueError as exc: raise ContractError('blockstate', path, p, str(exc)) from exc opid = path + '#' + write.operation operation = self.operations.setdefault(opid, {'component': path, 'name': write.operation, 'writes': 0, 'replaced': set()}) operation['writes'] += 1 if old: operation['replaced'].add(old.owner) if world_state == AIR: self.blocks.pop(p, None) self.erasures[p] = path else: self.erasures.pop(p, None) owner = old.owner if old and write.preserve_owner else path self.blocks[p] = Cell(canonical(world_state), owner, opid, write.nbt, old.shared if old and write.preserve_owner else ()) self.reverse[owner].add(p) for dependency in self.dependencies: consumer = dependency["consumer"] if consumer in existing_consumers and consumer != parent and not path.startswith(consumer + "/") and any(dependency["region"].contains(p) for p in final_writes): # Binding consumers remain valid only if their actual invariants hold. self.events.append({"kind": "revalidated-input", "consumer": consumer, "cause": path, "version": self.version}) for old in retired: self._retire(old) for child in plan.children: if isinstance(child, Choice): self._select_child(path, child, frame, scope) continue if not child.key or any(c in child.key for c in '/#'): raise ContractError('instance-key', path, conditions=child.key) self._instantiate(path + '/' + child.key, child.component, child.params, frame.compose(child.frame), child.bindings, path, scope.child(child.key, child.seed)) for port in contract.ports: if port.delegate: target, actual = self.view.resolved_port(path, port.key) if actual.frame != port.frame or actual.region != port.region or actual.kind != port.kind: raise ContractError('forwarded-interface', path, port.frame.origin, 'Realized child changed the negotiated public interface') self.relations.add((path, 'exposes', target)) for source, kind, target in plan.relations: if source not in self.nodes or target not in self.nodes: raise ContractError("dangling-relation", path, conditions=f"{source} {kind} {target}") self.relations.add((source, kind, target)) self.nodes[path].complete = complete if len(self.blocks) > self.limits.blocks: raise ContractError('block-budget', path) def _select_child(self, parent, choice, frame, scope): accepted = [] rejected = [] path = parent + '/' + choice.key for i, option in enumerate(choice.candidates[:self.limits.search]): trial = self._fork() try: trial._instantiate(path, option.component, option.params, frame.compose(option.frame), option.bindings, parent or None, scope.child(choice.key, option.seed).child(f'alternative-{i}')) trial._check(False, completed_scope=path) accepted.append((choice.score(trial.view, path), i, trial)) except ContractError as exc: rejected.append(exc.diagnostic) if not accepted: rules = {d.rule for d in rejected} if len(rules) == 1 and len(choice.candidates) <= self.limits.search: error = ContractError(next(iter(rules)), path, conditions='All declared alternatives violate the same condition: ' + str(rejected[0])) else: error = SearchExhausted('search-budget', path, conditions=str(rejected)) error.attempts = len(rejected) error.candidates = [d.__dict__ for d in rejected] raise error accepted.sort(key=lambda item: (item[0], item[1])) feasible = [a for a in accepted if a[0] <= accepted[0][0] + choice.tolerance] chosen = scope.child(choice.key).choose(feasible, 'adaptation-selection') self.__dict__.update(chosen[2].__dict__) self.events.append({'kind': 'candidate-selection', 'component': path, 'attempts': len(accepted) + len(rejected), 'accepted': len(accepted), 'rejected': [d.__dict__ for d in rejected], 'scores': [(a[1], round(a[0], 4)) for a in accepted], 'chosen': chosen[1]}) def _retire(self, path): if self.reverse.get(path): raise ContractError('whole-object', path, conditions='Cannot retire occupied instance') node = self.nodes.get(path) if node: for binding in node.bindings: key = (binding.host, binding.port) self.port_uses[key] = max(0, self.port_uses.get(key, 0) - 1) if node: for shared_host, shared_port, point in node.shared_bindings: key = (shared_host, shared_port) self.port_uses[key] = max(0, self.port_uses.get(key, 0) - 1) self.members.pop(path, None) for children in self.members.values(): children.discard(path) self.nodes.pop(path, None) self.reverse.pop(path, None) self._recipes.pop(path, None) self.relations = {r for r in self.relations if r[0] != path and r[2] != path} self.dependencies = [d for d in self.dependencies if d['consumer'] != path and d['source'] != path] self.port_uses = {k: v for k, v in self.port_uses.items() if k[0] != path} def _check(self, final, completed_scope=None): errors = validate(self, final, completed_scope) if errors: raise ValidationError(errors) def finalize(self): self._check(True) self.completed = True return self def finish_scope(self, path): trial = self._fork() trial.nodes[path].complete = True trial._check(True) self._commit(trial) def descendants(self, path): result = set() pending = [path] while pending: current = pending.pop() if current in result: continue result.add(current) pending.extend(sorted(self.members.get(current, ()))) return frozenset(result) def cells(self, path, descendants=False, shared=False): paths = [path] if descendants: paths = list(self.descendants(path)) return frozenset(p for k in paths for p in (self.reverse.get(k, set()) | (self.reverse_shared.get(k, set()) if shared else set()))) def inspect(self, point): point = tuple(point) record = self.blocks.get(point) if not record: return {'position': point, 'state': AIR, 'instance': None, 'chain': [], 'related': [], 'operation': None} chain, seen = [], set() path = record.owner while path and path not in seen: seen.add(path) node = self.nodes[path] chain.append({'id': path, 'type': node.type}) path = node.primary or node.parent related = sorted(r for r in self.relations if r[0] in seen or r[2] in seen) return {'position': point, 'state': record.state, 'instance': record.owner, 'chain': chain, 'related': related, 'operation': self.operations.get(record.operation), 'shared': record.shared, 'nbt': record.nbt} def share(self, point, participant, host, port): trial = self._fork() p = tuple(point) record = trial.blocks[p] offered = trial.view.port(host, port) if record.owner != host or offered.kind != 'shared-support' or not offered.region.contains(p) or participant not in trial.nodes: raise ContractError('shared-authority', participant, p) if participant in record.shared: return use_key = (host, port) if trial.port_uses.get(use_key, 0) >= offered.capacity: raise ContractError('port-capacity', participant, p) trial.port_uses[use_key] = trial.port_uses.get(use_key, 0) + 1 trial.reverse_shared.setdefault(participant, set()).add(p) from .contracts import Rule node = trial.nodes[participant] node.shared_bindings = node.shared_bindings + ((host, port, p),) node.contract = replace(node.contract, rules=node.contract.rules + (Rule('support', (p,)),)) trial.blocks[p] = replace(record, shared=tuple(sorted(set(record.shared + (participant,))))) trial.relations.add((participant, 'shares_support', host)) trial._check(False) self._commit(trial) def remove(self, path): trial = self._fork() trial._remove_branch(path) trial._check(False) self._commit(trial) def _remove_branch(self, path): paths = {k for k in self.nodes if k == path or k.startswith(path + '/')} affected = set() for k in sorted(paths, reverse=True): current = set(self.reverse[k]) | set(self.displaced.get(k, {})) for p in current: record = self.blocks.get(p) if record is None and self.erasures.get(p) not in paths: continue if record is not None and record.owner not in paths and self.operations[record.operation]['component'] not in paths: continue affected.add(p) if record is not None: self.reverse[record.owner].discard(p) self.erasures.pop(p, None) previous = self.displaced.get(k, {}).get(p) if previous and previous.owner in self.nodes and previous.owner not in paths: self.blocks[p] = previous self.reverse[previous.owner].add(p) else: self.blocks.pop(p, None) self.displaced.pop(k, None) for d in self.dependencies: if d['consumer'] not in paths and (d['source'] in paths or any(d['region'].contains(p) for p in affected)): self.nodes[d['consumer']].stale = True for k in sorted(paths, reverse=True): self.reverse_shared.pop(k, None) self.reverse[k].clear() self._retire(k) self.relations = {r for r in self.relations if r[0] in self.nodes and r[2] in self.nodes} for p, record in list(self.blocks.items()): if set(record.shared).intersection(paths): self.blocks[p] = replace(record, shared=tuple(s for s in record.shared if s not in paths)) def regenerate(self, path, component=None, params=None, dependents=(), seed=None, replacements=None): trial = self._fork() targets = [path] + list(dependents) updates = dict(replacements or {}) if set(updates) - set(targets) or len(set(targets)) != len(targets): raise ContractError('replay-targets', path, conditions='Replacements must name distinct explicit replay targets') if component is not None: if path in updates: raise ContractError('replay-targets', path, conditions='Supply a root replacement only once') updates[path] = component recipes = {} for p in targets: if p in trial._recipes: recipes[p] = trial._recipes[p] elif p in updates: n = trial.nodes[p] recipes[p] = (updates[p], n.parameters.get('arguments', {}), n.frame, n.bindings, n.parent, n.scope, n.complete) else: raise ContractError('replay-implementation', p, conditions='Reloaded branch needs an explicitly supplied component implementation') for p in targets: trial._remove_branch(p) for p in targets: comp, oldparams, frame, bindings, parent, scope, complete = recipes[p] if p == path and seed is not None: scope = scope.child('override', seed) trial._instantiate(p, updates.get(p, comp), params if p == path and params is not None else oldparams, frame, bindings, parent, scope, complete) trial._check(True) self._commit(trial) self.events.append({'kind': 'regenerated', 'targets': targets}) def describe_inputs(value): """Record declared public inputs without concrete-component dispatch.""" if value is None or isinstance(value, (str, int, float, bool)): return value if isinstance(value, (list, tuple)): return [describe_inputs(v) for v in value] if isinstance(value, dict): return {str(k): describe_inputs(v) for k, v in value.items()} if is_dataclass(value): return {'type': type(value).__module__ + '.' + type(value).__qualname__, 'inputs': {f.name: describe_inputs(getattr(value, f.name)) for f in fields(value)}} if callable(value): return {'program': value.__module__ + '.' + value.__qualname__} return {'type': type(value).__module__ + '.' + type(value).__qualname__, 'inputs': {k: describe_inputs(v) for k, v in vars(value).items() if not k.startswith('_')}}
hearth/kernel/validation.py · 220 行 · 原文件
# Extensible actual-geometry validators and bounded player movement. from collections import deque from hearth.blocks import AIR, LIGHTS, name_of, parse, passable, solid, validate_state from hearth.kernel.errors import Diagnostic from hearth.space import Box VALIDATORS = {} def validator(name): def register(fn): VALIDATORS[name] = fn return fn return register def state(scene, p): record = scene.blocks.get(tuple(p)) return record.state if record else AIR def fail(kind, node, point, message): return Diagnostic(kind, node.path, point, message) @validator('protected') def protected(scene, node, rule): from hearth.blocks import blockstates_equivalent for p, expected in zip(rule.cells, rule.data['states']): if not blockstates_equivalent(state(scene, p), expected): yield fail('protected-region', node, p, 'Preserved geometry changed') @validator('support') def support(scene, node, rule): for p in rule.cells: if not solid(state(scene, p)): yield fail('support', node, p, 'Required actual load-bearing cell is missing') @validator('clear') def clear(scene, node, rule): for p in rule.cells: if not passable(state(scene, p)): yield fail('clearance', node, p, 'Protected player headroom is obstructed') @validator('sealed') def sealed(scene, node, rule): for p in rule.cells: if name_of(state(scene, p)) in ('air', 'water'): yield fail('enclosure', node, p, 'Enclosed boundary has a gap') @validator('expected') def expected(scene, node, rule): allowed = set(rule.data['names']) for p in rule.cells: if name_of(state(scene, p)) not in allowed: yield fail('expected-geometry', node, p, f'Expected one of {sorted(allowed)}') @validator('pool') def pool(scene, node, rule): for x, y, z in rule.cells: if name_of(state(scene, (x, y, z))) != 'water': yield fail('pool-water', node, (x, y, z), 'Pool water missing') for q in ((x, y - 1, z), (x - 1, y, z), (x + 1, y, z), (x, y, z - 1), (x, y, z + 1)): if not solid(state(scene, q)) and name_of(state(scene, q)) != 'water': yield fail('pool-containment', node, q, 'Basin leaks') def standable(scene, p): x, y, z = p return passable(state(scene, p)) and passable(state(scene, (x, y + 1, z))) and solid(state(scene, (x, y - 1, z))) def reachable(scene, start, box): if not standable(scene, start): return set() reached = {start} queue = deque([start]) while queue: x, y, z = queue.popleft() for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1)): for dy in (0, 1, -1): q = (x + dx, y + dy, z + dz) if q not in reached and box.contains(q) and standable(scene, q): # Ascending requires clearance above the lower step as well. high = (x, y + 2, z) if dy == 1 else (q[0], q[1] + 2, q[2]) if dy and not passable(state(scene, high)): continue reached.add(q) queue.append(q) return reached @validator('route') def route(scene, node, rule): if not rule.cells or rule.box is None: yield fail('route-contract', node, None, 'Route needs start, targets and bounded search region') return reached = reachable(scene, rule.cells[0], rule.box) for p in rule.cells: if p not in reached: yield fail('reachability', node, p, 'No walkable route with two blocks of headroom from entrance') @validator('light') def light(scene, node, rule): sources = [p for p in rule.box.cells() if name_of(state(scene, p)) in LIGHTS] if not sources: yield fail('lighting', node, rule.box.lo, 'Completed room has no actual light source') return # Propagate actual sources through transmissive cells, with one unit attenuation. levels = {p: LIGHTS[name_of(state(scene, p))] for p in sources} queue = deque(sources) domain = rule.box.expand(1) while queue: p = queue.popleft() level = levels[p] - 1 if level < rule.data.get('minimum', 1): continue for dx, dy, dz in ((1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)): q = (p[0] + dx, p[1] + dy, p[2] + dz) if not domain.contains(q) or levels.get(q, 0) >= level: continue material = state(scene, q) if passable(material) or 'glass' in name_of(material) or name_of(material) == 'chain': levels[q] = level queue.append(q) for p in rule.cells: if levels.get(p, 0) < rule.data.get('minimum', 1): yield fail('lighting', node, p, 'Actual source attenuation/occlusion leaves required location dark') @validator('furnishing') def furnishing(scene, node, rule): names = {name_of(state(scene, p)) for p in rule.box.cells()} for group in rule.data['groups']: if not names.intersection(group): yield fail('furnishing', node, rule.box.lo, f'Missing functional furnishing: {group}') def validate(scene, final=False, completed_scope=None): diagnostics = [] for p, record in scene.blocks.items(): try: validate_state(record.state) except ValueError as exc: diagnostics.append(Diagnostic('blockstate', record.owner, p, str(exc))) continue if p not in scene.reverse.get(record.owner, set()): diagnostics.append(Diagnostic('reverse-index', record.owner, p, 'Current cell absent from reverse index')) if record.owner not in scene.nodes: diagnostics.append(Diagnostic('ownership', record.owner, p, 'Owner missing')) if record.nbt is not None: if record.nbt.get('id') != 'minecraft:' + name_of(record.state): diagnostics.append(Diagnostic('block-entity', record.owner, p, 'Block entity type mismatches actual block')) slots = set() for item in record.nbt.get('Items', []): if not 0 <= item.get('Slot', -1) < 27 or item['Slot'] in slots or not 1 <= item.get('count', 0) <= 64 or not item.get('id', '').startswith('minecraft:'): diagnostics.append(Diagnostic('inventory', record.owner, p, 'Invalid or duplicate inventory slot/item count')) slots.add(item.get('Slot')) name, props = parse(record.state) if name.endswith('_door') and not name.endswith('_trapdoor'): dy = 1 if props.get('half') == 'lower' else -1 q = (p[0], p[1] + dy, p[2]) other, op = parse(state(scene, q)) if other != name or op.get('half') == props.get('half') or any(op.get(k) != props.get(k) for k in ('facing', 'hinge', 'open', 'powered')): diagnostics.append(Diagnostic('door-pair', record.owner, p, 'Door halves absent or inconsistent')) if name.endswith('_bed'): direction = {'north': (0, -1), 'south': (0, 1), 'east': (1, 0), 'west': (-1, 0)}[props['facing']] sign = 1 if props['part'] == 'foot' else -1 q = (p[0] + direction[0] * sign, p[1], p[2] + direction[1] * sign) other, op = parse(state(scene, q)) if name != other or op.get('part') == props['part'] or op.get('facing') != props['facing']: diagnostics.append(Diagnostic('bed-pair', record.owner, p, 'Bed halves inconsistent')) if name_of(record.state) in ('sunflower', 'rose_bush', 'peony', 'lilac', 'tall_grass', 'large_fern'): dy = 1 if props.get('half') == 'lower' else -1 q = (p[0], p[1] + dy, p[2]) other, op = parse(state(scene, q)) if other != name or op.get('half') == props.get('half'): diagnostics.append(Diagnostic('plant-pair', record.owner, p, 'Tall plant halves inconsistent')) for owner, points in scene.reverse.items(): for p in points: if p not in scene.blocks or scene.blocks[p].owner != owner: diagnostics.append(Diagnostic('reverse-index', owner, p, 'Obsolete current membership')) for node in scene.nodes.values(): for port in node.contract.ports: if port.delegate and (node.complete or final): try: _, actual = scene.view.resolved_port(node.path, port.key) if (port.frame, port.region, port.kind) != (actual.frame, actual.region, actual.kind): diagnostics.append(Diagnostic('forwarded-interface', node.path, port.frame.origin, 'Child interface changed without parent renegotiation')) except (KeyError, ValueError): diagnostics.append(Diagnostic('forwarded-interface', node.path, port.frame.origin, 'Delegated port missing')) for parent in (node.parent, node.primary): if parent is not None and parent not in scene.nodes: diagnostics.append(Diagnostic('structure-graph', node.path, None, 'Current structural parent missing: ' + parent)) if final and (not node.complete or node.stale): diagnostics.append(Diagnostic('unfinished', node.path, None, 'Scope unfinished or dependent inputs stale')) for rule in node.contract.rules: if rule.phase == 'complete' and not final: scope = node closed = True while scope: closed = closed and scope.complete scope = scene.nodes.get(scope.parent) if completed_scope and (node.path == completed_scope or node.path.startswith(completed_scope + '/')): closed = node.complete if not closed: continue if rule.kind not in VALIDATORS: diagnostics.append(Diagnostic('unknown-validator', node.path, None, rule.kind)) else: diagnostics.extend(VALIDATORS[rule.kind](scene, node, rule)) return diagnostics
hearth/kernel/view.py · 166 行 · 原文件
# Read-only, domain-aware environmental observations. from dataclasses import dataclass from types import MappingProxyType import copy from hearth.blocks import AIR, solid, name_of, passable from hearth.kernel.errors import ContractError from hearth.space import Box @dataclass(frozen=True) class Observation: version: int region: Box elevation: int water: int | None material: str slope: int support_depth: int class ReadTrace: """Coalesce actual environmental reads and interface dependencies for one candidate.""" def __init__(self): self.low = None self.high = None self.sources = {} def point(self, p): if self.low is None: self.low = list(p) self.high = list(p) else: for i in range(3): self.low[i] = min(self.low[i], p[i]) self.high[i] = max(self.high[i], p[i]) def region(self, box): self.point(box.lo) self.point(box.hi) @property def bounds(self): return None if self.low is None else Box(tuple(self.low), tuple(self.high)) class View: def __init__(self, scene, trace=None): self.__scene = scene self.__trace = trace @property def version(self): return self.__scene.version @property def domain(self): return self.__scene.domain @property def style(self): return MappingProxyType(self.__scene.style) def preference(self, name, point): if self.domain and not self.domain.contains(point): raise ContractError("unknown-space", position=point) field = self.__scene.preferences.get(name) return None if field is None else field(point[0], point[2]) def state(self, p): p = tuple(p) if self.__trace: self.__trace.point(p) if self.domain and not self.domain.contains(p): raise ContractError('unknown-space', position=p, conditions='Outside explicit environment domain') record = self.__scene.blocks.get(p) return record.state if record else AIR def owner(self, p): if self.__trace: self.__trace.point(p) record = self.__scene.blocks.get(tuple(p)) return record.owner if record else None def supports(self, p): return solid(self.state(p)) def clear(self, box): return all(passable(self.state(p)) for p in box.cells()) def elevation(self, x, z, maximum=None): if self.domain is None: raise ContractError('unknown-space', position=(x, 0, z), conditions='No environmental domain') for y in range(self.domain.hi[1] if maximum is None else min(maximum, self.domain.hi[1]), self.domain.lo[1] - 1, -1): if self.supports((x, y, z)): return y raise ContractError('missing-substrate', position=(x, self.domain.lo[1], z), conditions='No actual solid substrate') def water(self, x, z): if self.domain is None: raise ContractError('unknown-space', position=(x, 0, z)) for y in range(self.domain.hi[1], self.domain.lo[1] - 1, -1): if name_of(self.state((x, y, z))) == 'water': return y return None def sample(self, x, z): y = self.elevation(x, z) heights = [self.elevation(x + dx, z + dz) for dx, dz in ((1, 0), (-1, 0), (0, 1), (0, -1)) if self.domain.contains((x + dx, y, z + dz))] depth = 0 for yy in range(y, self.domain.lo[1] - 1, -1): if not self.supports((x, yy, z)): break depth += 1 return Observation(self.version, Box((x, self.domain.lo[1], z), (x, self.domain.hi[1], z)), y, self.water(x, z), self.state((x, y, z)), max([abs(h - y) for h in heights] or [0]), depth) def port(self, host, key): node = self.__scene.nodes[host] for p in node.contract.ports: if p.key == key: if self.__trace: self.__trace.sources[host] = p.region return copy.deepcopy(p) raise ContractError('missing-port', host, conditions=key) def cost(self, path, tag=None): paths = [key for key, n in self.__scene.nodes.items() if (key == path or key.startswith(path + '/')) and (tag is None or (n.capability and tag in n.capability.tags))] occupied = sum(len(self.__scene.reverse.get(key, ())) for key in paths) replaced = sum(len(self.__scene.displaced.get(key, ())) for key in paths) return {'occupied': occupied, 'replaced': replaced, 'instances': len(paths)} def offers(self, host, kind=None): return tuple(copy.deepcopy(p) for p in self.__scene.nodes[host].contract.ports if kind is None or p.kind == kind) def capability(self, host): return copy.deepcopy(self.__scene.nodes[host].capability) def resolved_port(self, host, key): seen = set() while True: if (host, key) in seen: raise ContractError('port-cycle', host, conditions=key) seen.add((host, key)) port = self.port(host, key) if not port.delegate: return host, port child, key = port.delegate host = host + '/' + child def contract(self, path): if self.__trace: self.__trace.sources[path] = self.__scene.nodes[path].contract.envelope return copy.deepcopy(self.__scene.nodes[path].contract) def protected(self, box): if self.__trace: self.__trace.region(box) return any(r.kind in ('clear', 'protected') and any(box.contains(p) for p in r.cells) for n in self.__scene.nodes.values() for r in n.contract.rules) def obstacle_distance(self, p, radius=8): best = radius + 1 for q in Box(tuple(v - radius for v in p), tuple(v + radius for v in p)).cells(): if q in self.__scene.blocks and not passable(self.__scene.blocks[q].state): best = min(best, max(abs(a - b) for a, b in zip(p, q))) return best
hearth/persistence.py · 194 行 · 原文件
# One-region Litematica transport paired with verified structural records. import hashlib import json import sys from dataclasses import fields, is_dataclass from pathlib import Path from . import __version__ from .blocks import canonical, AIR from .space import Box, Frame from .randomness import Scope from .kernel import contracts from .kernel.scene import Scene, Node, Cell, Limits from .kernel.errors import ContractError FORMAT_VERSION = 1 TYPES = {c.__name__: c for c in (Box, Frame, Scope, Node, Cell, Limits, contracts.Contract, contracts.Rule, contracts.Port, contracts.Grant, contracts.Binding, contracts.Capability, contracts.Domain)} def encode(value): if is_dataclass(value): return {'$type': type(value).__name__, **{f.name: encode(getattr(value, f.name)) for f in fields(value)}} if isinstance(value, tuple): return {'$tuple': [encode(v) for v in value]} if isinstance(value, set): return {'$set': [encode(v) for v in sorted(value)]} if isinstance(value, dict): return {k: encode(v) for k, v in value.items()} if isinstance(value, list): return [encode(v) for v in value] return value def decode(value): if isinstance(value, list): return [decode(v) for v in value] if isinstance(value, dict): if '$tuple' in value: return tuple(decode(v) for v in value['$tuple']) if '$set' in value: return set(decode(v) for v in value['$set']) if '$type' in value: return TYPES[value['$type']](**{k: decode(v) for k, v in value.items() if k != '$type'}) return {k: decode(v) for k, v in value.items()} return value def semantic_digest(scene): digest = hashlib.sha256() for p, c in sorted(scene.blocks.items()): digest.update(json.dumps([p, canonical(c.state), c.nbt], sort_keys=True, separators=(',', ':')).encode()) return digest.hexdigest() def companion_path(path: Path): return path.with_suffix(path.suffix + '.structure.json') def _mcio(): try: import mcio except ImportError: sys.path.insert(0, '/work/generator/MCIO') from mcio.sketch import LitematicCanvas from mcio.schematic import load_schematic from mcio.nbt import tag from mcio.nbt.nbt import File return LitematicCanvas, load_schematic, tag, File def _to_nbt(value, tag, key=''): if isinstance(value, dict): return tag.Compound({k: _to_nbt(v, tag, k) for k, v in value.items()}) if isinstance(value, list): if not value: return tag.List[tag.Compound]([]) items = [_to_nbt(v, tag) for v in value] return tag.List[type(items[0])](items) if isinstance(value, str): return tag.String(value) if isinstance(value, int): return tag.Byte(value) if key == 'Slot' else tag.Int(value) raise TypeError(type(value)) def _plain(value): if isinstance(value, dict): return {str(k): _plain(v) for k, v in value.items()} if isinstance(value, (list, tuple)): return [_plain(v) for v in value] if isinstance(value, str): return str(value) return int(value) def export_scene(scene, path: Path, verify=True): path = Path(path) scene.finalize() bounds = Box.enclosing(scene.blocks) if max(bounds.size) > scene.limits.dimension: raise ContractError('export-bounds', conditions=str(bounds)) if bounds.volume > scene.limits.export_volume: raise ContractError('export-volume', conditions=f'{bounds.volume} > {scene.limits.export_volume}') canvas_type, _, tag, nbtfile = _mcio() sx, sy, sz = bounds.size canvas = canvas_type((sy, sz, sx)) offset = bounds.lo block_entities = [] for p, cell in sorted(scene.blocks.items()): x, y, z = tuple(v - o for v, o in zip(p, offset)) canvas.block((y, z, x), cell.state) if cell.nbt is not None: block_entities.append(_to_nbt({**cell.nbt, 'x': x, 'y': y, 'z': z}, tag)) schematic = canvas.to_litematica(name='Hearth', author='Hearth procedural library', description='Contract-composed settlement; structural identity in companion JSON', minecraft_data_version=3955) nbt = schematic.write_to_nbt() nbt['Regions']['Hearth']['TileEntities'] = tag.List[tag.Compound](block_entities) nbt['Regions']['Hearth']['Entities'] = tag.List[tag.Compound]([]) path.parent.mkdir(parents=True, exist_ok=True) temporary = path.with_suffix(path.suffix + '.tmp') nbtfile(nbt).save(temporary) owners = sorted(scene.nodes) operations = sorted(scene.operations) owner_id, op_id = {v: i for i, v in enumerate(owners)}, {v: i for i, v in enumerate(operations)} data = {'format': 'hearth.structure', 'version': FORMAT_VERSION, 'implementation': __version__, 'minecraft_data_version': 3955, 'digest': semantic_digest(scene), 'offset': offset, 'size': bounds.size, 'seed': scene.seed, 'style': scene.style, 'preferences': {k: v.expression() for k, v in scene.preferences.items()}, 'domain': encode(scene.domain), 'limits': encode(scene.limits), 'scene_version': scene.version, 'nodes': encode(scene.nodes), 'relations': encode(scene.relations), 'dependencies': encode(scene.dependencies), 'operations': encode(scene.operations), 'erasures': [[list(p), owner] for p, owner in sorted(scene.erasures.items())], 'displaced': {k: [[list(p), encode(c)] for p, c in sorted(v.items())] for k, v in scene.displaced.items()}, 'events': encode(scene.events), 'port_uses': [[*k, v] for k, v in sorted(scene.port_uses.items())], 'owners': owners, 'operation_ids': operations, 'cells': [[*p, owner_id[c.owner], op_id[c.operation], list(c.shared)] for p, c in sorted(scene.blocks.items())]} target = companion_path(path) temporary_meta = target.with_suffix('.json.tmp') temporary_meta.write_text(json.dumps(data, sort_keys=True, separators=(',', ':'))) temporary.replace(path) temporary_meta.replace(target) if verify: restored = load_scene(path) if semantic_digest(restored) != semantic_digest(scene): raise ContractError('roundtrip', conditions='Semantic geometry differs') return path def load_scene(path: Path): path = Path(path) meta = companion_path(path) if not meta.exists(): raise ContractError('untrusted-structure', conditions='Missing companion; geometry cannot reconstruct semantic identity') data = json.loads(meta.read_text()) if data.get('format') != 'hearth.structure' or data.get('version') != FORMAT_VERSION: raise ContractError('untrusted-structure', conditions='Unknown companion format/version') _, load, _, nbtfile = _mcio() loaded = load(path) nbt = nbtfile.load_regardless_of_gzipped(filename=path) regions = nbt['Regions'] if len(regions) != 1 or int(nbt['MinecraftDataVersion']) != 3955: raise ContractError('transport', conditions='Require one Java 1.21.1 region') region = next(iter(regions.values())) if list(loaded.size_yzx) != [data['size'][1], data['size'][2], data['size'][0]]: raise ContractError('geometry-mismatch', conditions='Export dimensions changed') if region['Entities']: raise ContractError('geometry-mismatch', conditions='Unexpected entities') inventories = {} for entry in region['TileEntities']: item = _plain(entry) p = tuple(item.pop(k) + data['offset'][i] for i, k in enumerate(('x', 'y', 'z'))) inventories[p] = item from .environment.fields import from_expression scene = Scene(data['seed'], decode(data['limits']), decode(data['domain']), data.get('style'), {k: from_expression(v) for k, v in data.get('preferences', {}).items()}) scene.nodes = decode(data['nodes']) scene.relations = decode(data['relations']) for child, kind, parent in scene.relations: if kind in ('contained_by', 'attached_to'): scene.members.setdefault(parent, set()).add(child) scene.dependencies = decode(data['dependencies']) scene.operations = decode(data['operations']) scene.erasures = {tuple(p): owner for p, owner in data.get('erasures', [])} scene.events = decode(data['events']) scene.displaced = {k: {tuple(p): decode(c) for p, c in v} for k, v in data.get('displaced', {}).items()} scene.version = data['scene_version'] scene.port_uses = {(a, b): n for a, b, n in data['port_uses']} ownership = {tuple(row[:3]): row[3:] for row in data['cells']} scene.reverse = {k: set() for k in scene.nodes} ids = loaded.read_flat(0, loaded.volume).reshape(loaded.size_yzx) import numpy as np for y, z, x in np.argwhere(ids != 0): block = canonical(loaded.palette[int(ids[y, z, x])]) if block == AIR: continue p = tuple(int(v) + o for v, o in zip((x, y, z), data['offset'])) if p not in ownership: raise ContractError('geometry-mismatch', position=p, conditions='Unrecorded block') owner, op, shared = ownership[p] owner = data['owners'][owner] scene.blocks[p] = Cell(block, owner, data['operation_ids'][op], inventories.get(p), tuple(shared)) scene.reverse[owner].add(p) for participant in shared: scene.reverse_shared.setdefault(participant, set()).add(p) if set(ownership) != set(scene.blocks) or set(inventories) - set(scene.blocks) or semantic_digest(scene) != data['digest']: raise ContractError('geometry-mismatch', conditions='Schematic and structural companion are not a matching semantic pair') scene.finalize() return scene
hearth/programs.py · 175 行 · 原文件
# Lightweight high-level room-graph programs and settlement intent. from hearth import Scene, Box, Frame from hearth.randomness import Scope from hearth.kernel import Capability, Contract, Plan, Child, Binding, Rule, Port from hearth.environment import Terrain, gradient, wave, radial from hearth.components.building import Blueprint, Building, RoomSpec, adapted from hearth.components.landscape import PathNetwork, Landscape, LampPost, Terrace from hearth.components.primitives import Window from hearth.composition import encapsulate def dwelling(seed): rng = Scope(seed).child('dwelling').stream('layout') rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')] if rng.choice((True, False)): rooms.append(RoomSpec(0, 1, 0, 'kitchen')) if rng.choice((True, False)): rooms.append(RoomSpec(1, 0, 0, 'library')) return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), porch=True, roof_axis='auto', steep=True) def atelier(seed): rng = Scope(seed).child('atelier').stream('layout') rooms = [RoomSpec(0, 0, 0, 'workshop'), RoomSpec(1, 0, 0, 'storage')] if rng.choice((True, False)): rooms.append(RoomSpec(1, 0, 1, 'bedroom')) if rng.choice((True, False)): rooms.append(RoomSpec(0, 1, 0, 'kitchen')) return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), porch=rng.choice((True, False)), roof_axis='x', roof_material='brick', steep=rng.choice((True, False)), window_component=Window(shutters=False)) def commons(seed): rng = Scope(seed).child('commons').stream('layout') rooms = [RoomSpec(0, 0, 0, 'library'), RoomSpec(0, 1, 0, 'living'), RoomSpec(1, 1, 0, 'kitchen')] for level in range(1, rng.choice((2, 3))): rooms.append(RoomSpec(0, 1, level, 'bedroom' if level == 1 else 'library')) if rng.choice((True, False)): rooms.append(RoomSpec(1, 0, 0, 'storage')) return Blueprint(tuple(rooms), bay=rng.choice((9, 11)), porch=True, roof_axis='z') PROGRAMS = {'dwelling': dwelling, 'atelier': atelier, 'commons': commons} def building_scene(design, seed=0, field=None, water=None): design.validate() b = design.bay width = (max(r.x for r in design.rooms) + 1) * b depth = (max(r.z for r in design.rooms) + 1) * b domain = Box((-8, -4, -18), (width + 8, 64, depth + 8)) scene = Scene(seed, domain=domain) expression = field if field is not None else gradient(base=4) + wave(.8, .1, .11, Scope(seed).stream('environment').random() * 6) scene.place('land', Terrain(domain, expression, water)) # Encapsulation preserves the public building instance as the selected child. choice = adapted('building', design, '/land') scene.compose_choice(choice) return scene.finalize() class Settlement: def __init__(self, designs, domain, terrain): self.designs = tuple(designs) self.domain = domain self.terrain = terrain def capability(self): return Capability('settlement.village', ('settlement', 'composite'), offers=('public-access',), guarantees=('building entrances connected',)) def negotiate(self, ctx, parameters): gateway = (0, ctx.elevation(0, -12) + 1, -12) interface = Box((-1, gateway[1] - 1, -12), (1, gateway[1] + 1, -12)) port = Port('public', 'public-access', Frame(gateway), interface, 10000, delegate=('connections', 'public')) return Contract(self.domain, ports=(port,), decisions={'buildings': len(self.designs), 'arrangement': 'opposed street with staggered frontage', 'circulation': ctx.scope.choose(('spine', 'loop'), 'circulation'), 'gateway': gateway}) def realize(self, ctx, contract): p = Plan() for i, design in enumerate(self.designs): row = i // 2 left = i % 2 == 0 z = row * 38 + ctx.scope.child(f'plot-{i}').choose((-2, 0, 2), 'frontage') origin = (-16, 0, z - design.bay // 2) if left else (16, 0, z + design.bay // 2) p.children.append(adapted(f'plot-{i}', design, self.terrain, Frame(origin, 1 if left else 3))) p.children.append(Child('square', Terrace(), frame=Frame((5, 0, 10)), bindings=(Binding(self.terrain, 'construction', 'fill'),))) p.children.append(Child('connections', SettlementConnections(len(self.designs), self.domain, self.terrain, contract.decisions['circulation'], contract.decisions['gateway']))) p.children.append(Child('landscape', Landscape(self.domain, self.terrain, 8, 12, 0.045))) return p class SettlementConnections: def __init__(self, count, domain, terrain, mode='spine', gateway=None): self.count = count self.domain = domain self.terrain = terrain self.mode = mode self.gateway = gateway def capability(self): return Capability('settlement.connections', ('connection', 'composite')) def negotiate(self, ctx, parameters): parent = ctx.path.rsplit('/', 1)[0] targets = tuple(ctx.local(ctx.view.port(f'{parent}/plot-{i}', 'street').frame.origin) for i in range(self.count)) targets = targets + (ctx.local(ctx.view.port(parent + '/square', 'entrance').frame.origin), self.gateway) interface = Box((self.gateway[0] - 1, self.gateway[1] - 1, self.gateway[2]), (self.gateway[0] + 1, self.gateway[1] + 1, self.gateway[2])) port = Port('public', 'public-access', Frame(self.gateway), interface, 10000, delegate=('paths', 'public')) return Contract(self.domain, ports=(port,), rules=(Rule('route', targets, self.domain, phase='complete'),)) def realize(self, ctx, contract): parent = ctx.path.rsplit('/', 1)[0] points = [] links = [] bindings = [Binding(self.terrain, 'construction', 'surface')] for i in range(self.count): host = f'{parent}/plot-{i}' port = ctx.view.port(host, 'street') x, y, z = ctx.local(port.frame.origin) lane = (-3 if x < 0 else 3) if self.mode == 'loop' else 0 points.extend(((x, y, z), (lane, ctx.elevation(lane, z) + 1, z))) links.append((2 * i, 2 * i + 1)) bindings.append(Binding(host, 'street', 'surface')) if i and self.mode == 'spine': links.append((2 * i - 1, 2 * i + 1)) if self.mode == 'loop': low = min(q[2] for q in points) high = max(q[2] for q in points) base = len(points) for x, z in ((-3, low), (-3, high), (3, high), (3, low)): points.append((x, ctx.elevation(x, z) + 1, z)) links.extend((base + i, base + (i + 1) % 4) for i in range(4)) square = ctx.local(ctx.view.port(parent + '/square', 'entrance').frame.origin) lane = 3 if self.mode == 'loop' else 0 points.extend((square, (lane, ctx.elevation(lane, square[2]) + 1, square[2]))) links.append((len(points) - 2, len(points) - 1)) if self.mode == 'spine': links.append((1, len(points) - 1)) points.append(self.gateway) links.append((1, len(points) - 1)) bindings.append(Binding(parent + '/square', 'entrance', 'surface')) p = Plan(children=[Child('paths', PathNetwork(tuple(points), tuple(links), gateway=self.gateway), bindings=tuple(bindings))]) for i in range(self.count): p.relations.append((ctx.path + '/paths', 'connects', f'{parent}/plot-{i}')) for i, z in enumerate(sorted({q[-1] for q in points[:self.count * 2]})): x = 5 if i % 2 else -5 y = ctx.elevation(x, z + 4) + 1 p.children.append(Child(f'lamp-{i}', LampPost(), frame=Frame((x, y, z + 4)))) return p def settlement_scene(seed=0, count=None): scope = Scope(seed) rng = scope.stream('settlement-layout') if count is None: count = rng.choice((3, 4, 5)) if count < 1: raise ValueError('A settlement needs at least one building') designs = [] for i in range(count): local = scope.child(f'building-{i}').stream('room-graph') rooms = [RoomSpec(0, 0, 0, local.choice(('living', 'workshop', 'library')))] for x, z in local.sample(((1, 0), (0, 1)), local.choice((0, 1, 2))): rooms.append(RoomSpec(x, z, 0, local.choice(('storage', 'kitchen', 'living')))) if local.choice((True, True, False)): column = local.choice(rooms) for level in range(1, local.choice((2, 2, 3))): rooms.append(RoomSpec(column.x, column.z, level, 'bedroom' if level == 1 else 'library')) designs.append(Blueprint(tuple(rooms), bay=local.choice((9, 11)), porch=local.choice((True, True, False)), roof_axis=local.choice(('auto', 'x', 'z')), roof_material=local.choice(('deepslate_tile', 'brick')), steep=local.choice((True, True, False)))) rows = (count + 1) // 2 domain = Box((-49, -4, -23), (49, 64, (rows - 1) * 38 + 28)) field = gradient(.012, -.009, 4.8) + wave(.7, .075, .09, rng.random() * 6) + radial(-36, rows * 12, 26, 1.1) scene = Scene(seed, domain=domain) scene.place('land', Terrain(domain, field, edit_limit=20000)) scene.place('village', Settlement(designs, domain, '/land')) return scene.finalize()
hearth/randomness.py · 21 行 · 原文件
# Stateless hierarchical scopes, with explicitly local random streams. import hashlib import json import random from dataclasses import dataclass @dataclass(frozen=True) class Scope: seed: int key: tuple[str, ...] = () def child(self, key: str, override: int | None = None): return Scope(self.seed, self.key + (key,)) if override is None else Scope(override, (key,)) def stream(self, purpose: str = 'plan') -> random.Random: payload = json.dumps([self.seed, self.key, purpose], separators=(',', ':')).encode() return random.Random(int.from_bytes(hashlib.sha256(payload).digest(), 'big')) def choose(self, values, purpose='plan'): return self.stream(purpose).choice(tuple(values))
hearth/space.py · 109 行 · 原文件
# Integer geometry and explicit local-to-world transforms. from dataclasses import dataclass from itertools import product from typing import Iterable Pos = tuple[int, int, int] @dataclass(frozen=True) class Box: lo: Pos hi: Pos def __post_init__(self): object.__setattr__(self, 'lo', tuple(self.lo)) object.__setattr__(self, 'hi', tuple(self.hi)) if any(not isinstance(v, int) for v in (*self.lo, *self.hi)): raise TypeError('Box coordinates must be integers') if any(a > b for a, b in zip(self.lo, self.hi)): raise ValueError('Inverted box') def contains(self, p: Pos) -> bool: return all(a <= v <= b for a, v, b in zip(self.lo, p, self.hi)) def cells(self) -> Iterable[Pos]: return product(*(range(a, b + 1) for a, b in zip(self.lo, self.hi))) def corners(self): return product(*zip(self.lo, self.hi)) def intersection(self, other): low = tuple(max(a, b) for a, b in zip(self.lo, other.lo)) high = tuple(min(a, b) for a, b in zip(self.hi, other.hi)) return None if any(a > b for a, b in zip(low, high)) else Box(low, high) def expand(self, n: int): return Box(tuple(v - n for v in self.lo), tuple(v + n for v in self.hi)) @property def size(self): return tuple(b - a + 1 for a, b in zip(self.lo, self.hi)) @property def volume(self): x, y, z = self.size return x * y * z @classmethod def enclosing(cls, points): points = list(points) if not points: raise ValueError('No realized geometry') return cls(tuple(min(p[i] for p in points) for i in range(3)), tuple(max(p[i] for p in points) for i in range(3))) @dataclass(frozen=True) class Frame: origin: Pos = (0, 0, 0) turn: int = 0 def __post_init__(self): object.__setattr__(self, 'origin', tuple(self.origin)) if not isinstance(self.turn, int) or any(not isinstance(v, int) for v in self.origin): raise TypeError('Frames use integer coordinates and quarter turns') object.__setattr__(self, 'turn', self.turn % 4) def vector(self, p: Pos) -> Pos: x, y, z = p for _ in range(self.turn % 4): x, z = -z, x return x, y, z def point(self, p: Pos) -> Pos: return tuple(a + b for a, b in zip(self.origin, self.vector(p))) def inverse(self, p: Pos) -> Pos: return Frame(turn=-self.turn).vector(tuple(a - b for a, b in zip(p, self.origin))) def box(self, box: Box) -> Box: return Box.enclosing(self.point(p) for p in box.corners()) def compose(self, other): return Frame(self.point(other.origin), (self.turn + other.turn) % 4) def state(self, state: str) -> str: from .blocks import parse, state_of name, props = parse(state) dirs = ['north', 'east', 'south', 'west'] rotated = {} for key, value in props.items(): if key in dirs: key = dirs[(dirs.index(key) + self.turn) % 4] if key == 'facing' and value in dirs: value = dirs[(dirs.index(value) + self.turn) % 4] if key in ('shape', 'orientation') and any(v in dirs for v in value.split('_')): from .blocks import SCHEMA tokens = [dirs[(dirs.index(v) + self.turn) % 4] if v in dirs else v for v in value.split('_')] value = '_'.join(tokens) allowed = SCHEMA[name.removeprefix('minecraft:')][0][key] if value not in allowed: matches = [candidate for candidate in allowed if sorted(candidate.split('_')) == sorted(tokens)] if matches: value = sorted(matches)[0] if key == 'axis' and value in ('x', 'z') and self.turn % 2: value = 'z' if value == 'x' else 'x' if key == 'rotation': value = str((int(value) + 4 * self.turn) % 16) rotated[key] = value return state_of(name, **rotated)
hearth_extensions/__init__.py · 8 行 · 原文件
# Components developed against Hearth's public protocol in the second development phase. from .geometry import Polyline, Polygon from .interfaces import Endpoint, EndpointContact from .circulation import Link, connection from .boundaries import Boundary, BoundaryLantern, IlluminateBoundary from .sites import Platform from .halls import Pavilion, PolygonShell, HipRoof, Facade from .interiors import HallInterior, WorkBay
hearth_extensions/assessment.py · 208 行 · 原文件
# Frozen extension inputs, actual principal/contact signatures and retained outcomes. import hashlib import json import time from pathlib import Path from dataclasses import replace from collections import Counter from hearth import Scene, Box, Frame, Binding from hearth.kernel import ContractError, SearchExhausted, validate from hearth.environment import Terrain, gradient, wave, radial from hearth.randomness import Scope from hearth.persistence import semantic_digest, export_scene from hearth.blocks import solid from .geometry import Polyline, Polygon from .sites import Platform from .interfaces import Endpoint from .circulation import Link from .boundaries import BoundaryChain, IlluminateBoundary from .halls import Pavilion from .programs import frozen_site, branching_campus, perimeter_cluster PROBE_DOMAIN = Box((-8, -4, -8), (45, 52, 45)) def probe_expression(environment_seed): rng = Scope(environment_seed).stream('probe-field') return (gradient(rng.choice((-.025, 0, .035)), rng.choice((0, .015)), 2) + wave(rng.choice((0, .35, .7)), .11, .09, rng.random() * 6) + radial(16, 18, 14, -rng.choice((0, 1, 2)))).clamp(-1, 5), rng.choice((None, 3)) def freeze_probe(environment_seed): field, water = probe_expression(environment_seed) s = Scene(environment_seed, domain=PROBE_DOMAIN) s.place('land', Terrain(s.domain, field, water)) return s.finalize() def connector_scene(environment, structure_seed): s = environment.fork(seed=structure_seed) rng = Scope(structure_seed).stream('connection-intent') s.place('a', Platform('/land')) s.place('b', Platform('/land'), frame=Frame((18, 0, 27))) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') link = Link(a, b, '/land', via=((rng.choice((9, 12, 15)), rng.choice((16, 18, 20))),), width=rng.choice((3, 5)), rise=rng.choice((0, 1, 2)), covered=rng.choice((True, False))) s.place('link', link, bindings=(a.binding(), b.binding())) return s.finalize() def boundary_scene(environment, structure_seed): rng = Scope(structure_seed).stream('boundary-intent') controls = ((0, 0), (8, rng.choice((0, 10, 23))), (28, rng.choice((0, 5, 18))), (37, 18)) curve = Polyline(((0, 0), (37, 18))) if structure_seed == 0 else Polyline.bezier(controls) s = environment.fork(seed=structure_seed) s.place('boundary', BoundaryChain(curve, height=rng.choice((1, 2, 3)), spacing=rng.choice((4, 7, 10)))) s.place('lights', IlluminateBoundary('/boundary')) return s.finalize() def hall_scene(seed, environment_seed=None): rng = Scope(seed).stream('hall-intent') domain = Box((-12, -4, -12), (42, 65, 42)) es = seed if environment_seed is None else environment_seed field = gradient(.012, -.008, 4) + wave(.5, .1, .12, Scope(es).stream('hall-field').random() * 6) env = Scene(es, domain=domain) env.place('land', Terrain(domain, field)) env.finalize() s = env.fork(seed=seed) shape = Polygon.chamfered(rng.choice((13, 17, 21, 25)), rng.choice((13, 17, 21)), rng.choice((0, 2, 4))) s.place('hall', Pavilion(shape, '/land', rng.choice(('library', 'workshop', 'living')), ('north', 'south', 'east') if rng.choice((True, False)) else ('north', 'west'), height=rng.choice((5, 6, 7)), roof_run=rng.choice((2, 3)), lantern=rng.choice((True, False)))) return s.finalize() def signatures(scene): """Measure current semantic geometry, omitting cosmetic material and contact height.""" halls = [] links = [] boundaries = [] organization = [] for path, node in sorted(scene.nodes.items()): d = node.contract.decisions if node.type == 'extension.pavilion': footprint = sorted((node.frame.inverse(p)[0], node.frame.inverse(p)[2]) for p in scene.cells(path + '/floor')) halls.append({'footprint': footprint, 'height': d['height'], 'function': d['purpose'], 'entrances': d['entrances'], 'roof_run': d['roof_run'], 'lantern': d['lantern']}) if node.type in ('extension.bridge', 'extension.gallery'): pts = [node.frame.inverse(p) for p in scene.cells(path + '/deck')] x0, z0 = d['center'][0] links.append({'body': sorted((p[0] - x0, p[2] - z0) for p in pts), 'width': d['width'], 'covered': d['covered'], 'rise': d['rise']}) if node.type == 'extension.boundary-chain': pts = [node.frame.inverse(p) for p in scene.cells(path, True) if 'boundary-lantern' not in scene.nodes[scene.inspect(p)['instance']].type] x0 = min(p[0] for p in pts) z0 = min(p[2] for p in pts) columns = {} for x, y, z in pts: columns.setdefault((x, z), []).append(y) boundaries.append({'plan': sorted(set((p[0] - x0, p[2] - z0) for p in pts)), 'section_heights': sorted({max(ys) - min(ys) + 1 for ys in columns.values()})}) if node.type == 'extension.campus': vertex_keys = d['vertices'] vertices = [] for key in vertex_keys: v = scene.nodes[path + '/' + key] at = node.frame.inverse(v.frame.origin) vertices.append((at[0], at[2], v.capability.tags)) topology = sorted((vertex_keys.index(a), pa, vertex_keys.index(b), pb, covered, width) for a, pa, b, pb, covered, width in d['edges']) organization.append({'positions': vertices, 'topology': topology}) from hearth.assessment import principal_signature legacy = principal_signature(scene)[1]['buildings'] principal = {'halls': halls, 'links': links, 'boundaries': boundaries, 'organization': organization, 'legacy': legacy} contact = [] fill = 0 replaced = 0 excavated = 0 edit_occupied = 0 for path, node in sorted(scene.nodes.items()): if node.type in ('extension.trestles', 'adapter.foundation', 'adapter.approach'): contact.append((node.type, node.contract.decisions)) fill += len(scene.cells(path)) if node.type == 'extension.curved-boundary': contact.append((node.type, [node.frame.inverse(p) for r in node.contract.rules if r.kind == 'support' for p in r.cells])) if node.capability and set(node.capability.tags).intersection(('siteworks', 'path')): edit_occupied += len(scene.cells(path)) replaced += len(scene.displaced.get(path, {})) excavated += sum(solid(old.state) and (p not in scene.blocks or not solid(scene.blocks[p].state)) for p, old in scene.displaced.get(path, {}).items()) digest = lambda x: hashlib.sha256(json.dumps(x, sort_keys=True, default=list).encode()).hexdigest() interiors = [n for n in scene.nodes.values() if n.type == 'extension.hall-interior'] return {'principal_signature': digest(principal), 'structure': principal, 'contact_signature': digest(contact), 'contact_cells': fill, 'contact_replacements': replaced, 'sitework_occupied_cells': edit_occupied, 'excavated_solid_cells': excavated, 'furnishing_bays': sum(n.contract.decisions['placed_bays'] for n in interiors), 'omitted_optional_furnishing_bays': sum(n.contract.decisions['omitted_optional'] for n in interiors)} def measured(label, recipe, inputs, artifact=None): start = time.perf_counter() row = {'label': label, 'inputs': inputs, 'candidate_attempts': 1, 'accepted_candidates': 0, 'retries': 0} try: scene = recipe() scene.finalize() row.update(status='validated', accepted_candidates=1, blocks=len(scene.blocks), instances=len(scene.nodes), digest=semantic_digest(scene), **signatures(scene)) if artifact: export_scene(scene, artifact) row['artifact'] = str(artifact) except ContractError as exc: limits = ('site-relief', 'support-height', 'connection-support-height', 'connection-fill-limit', 'boundary-grade', 'endpoint-grade', 'approach-detour', 'connection-domain') row.update(status='budget-exhausted' if isinstance(exc, SearchExhausted) else ('incompatible' if exc.diagnostic.rule in limits else 'defect'), diagnostic=exc.diagnostic.__dict__, all_diagnostics=[d.__dict__ for d in getattr(exc, 'diagnostics', [exc.diagnostic])]) except Exception as exc: row.update(status='defect', diagnostic={'exception': type(exc).__name__, 'message': str(exc)}) row['seconds'] = round(time.perf_counter() - start, 4) return row def run(output, root_seed=0, artifacts=False, sample_output=Path('samples/extensions')): output = Path(output) output.mkdir(parents=True, exist_ok=True) rows = [] frozen = {} inputs = [] for es in range(root_seed * 100, root_seed * 100 + 8): frozen[es] = freeze_probe(es) field, water = probe_expression(es) inputs.append({'environment_seed': es, 'expression': field.expression(), 'water': water, 'digest': semantic_digest(frozen[es])}) (output / 'frozen-inputs.json').write_text(json.dumps(inputs, indent=2)) def record(label, fn, parameters, keep=False): path = Path(sample_output) / (label + '.litematic') if keep and artifacts else None row = measured(label, fn, parameters, path) rows.append(row) print(label, row['status'], flush=True) for i, es in enumerate(frozen): for bs in range(6): record(f'connector-{i}-{bs}', lambda e=frozen[es], b=bs: connector_scene(e, b), {'environment': inputs[i], 'structure_seed': bs}, (i, bs) in ((0, 0), (1, 2), (4, 3), (7, 5))) assert semantic_digest(frozen[es]) == inputs[i]['digest'] for es in range(4): # Independent dry substrates use the same field expression with water omitted. field, _ = probe_expression(es + root_seed * 100) env = Scene(es + root_seed * 100, domain=PROBE_DOMAIN) env.place('land', Terrain(env.domain, field)) env.finalize() for bs in range(4): record(f'boundary-{es}-{bs}', lambda e=env, b=bs: boundary_scene(e, b), {'environment_seed': es + root_seed * 100, 'expression': field.expression(), 'structure_seed': bs}, (es, bs) in ((0, 1), (3, 3))) for seed in range(12): record(f'hall-{seed}', lambda b=seed: hall_scene(b, root_seed * 100 + b), {'structure_seed': seed, 'environment_seed': root_seed * 100 + seed}, seed in (0, 4, 7)) for name, program in (('campus', branching_campus), ('perimeter', perimeter_cluster)): for seed in range(6): environment = frozen_site(root_seed * 100 + seed) identity = semantic_digest(environment) def recipe(e=environment, b=seed, p=program): s = e.fork(seed=b) s.place('campus', p(b)) return s.finalize() record(f'{name}-{seed}', recipe, {'program': name, 'structure_seed': seed, 'environment_seed': root_seed * 100 + seed, 'frozen_digest': identity}, seed in (0, 3)) assert semantic_digest(environment) == identity for i in range(24): es = 2000 + root_seed * 100 + i rng = Scope(es).stream('stress') field = (gradient(rng.choice((0, .12, .28)), rng.choice((0, -.12, .15)), 2) + wave(rng.choice((0, 2, 4)), .13, .1, rng.random() * 6)).clamp(-2, 18) water = rng.choice((None, 3, 9, 12)) env = Scene(es, domain=PROBE_DOMAIN) env.place('land', Terrain(env.domain, field, water)) env.finalize() record(f'stress-{i:02}', lambda e=env, b=i % 6: connector_scene(e, b), {'environment_seed': es, 'structure_seed': i % 6, 'expression': field.expression(), 'water': water}) (output / 'results.json').write_text(json.dumps(rows, indent=2)) summary = {} for name in ('connector', 'boundary', 'hall', 'campus', 'perimeter', 'stress'): part = [r for r in rows if r['label'].startswith(name + '-')] good = [r for r in part if r['status'] == 'validated'] summary[name] = {'inputs': len(part), 'outcomes': dict(Counter(r['status'] for r in part)), 'candidate_attempts': sum(r['candidate_attempts'] for r in part), 'accepted_candidates': sum(r['accepted_candidates'] for r in part), 'retries': sum(r['retries'] for r in part), 'principal_signatures': len({r['principal_signature'] for r in good}), 'contact_signatures': len({r['contact_signature'] for r in good}), 'contact_cells_range': [min((r['contact_cells'] for r in good), default=0), max((r['contact_cells'] for r in good), default=0)], 'contact_replacement_range': [min((r['contact_replacements'] for r in good), default=0), max((r['contact_replacements'] for r in good), default=0)], 'seconds': round(sum(r['seconds'] for r in part), 3)} (output / 'summary.json').write_text(json.dumps(summary, indent=2)) if artifacts: (Path(sample_output) / 'replay-manifest.json').write_text(json.dumps([{k: r[k] for k in ('label', 'inputs', 'artifact', 'digest', 'status')} for r in rows if 'artifact' in r], indent=2)) return summary
hearth_extensions/boundaries.py · 125 行 · 原文件
# Curve-following masonry with sampled installation sockets and grounded adaptation. from dataclasses import dataclass from hearth import Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Domain, Port, Grant, Plan, Rule, Child from hearth.blocks import state_of, slab from .geometry import Polyline, bounds2 @dataclass(frozen=True) class Boundary: curve: Polyline height: int = 2 spacing: int = 7 max_step: int = 1 def capability(self): return Capability('extension.curved-boundary', ('boundary', 'siteworks', 'composite'), offers=('mount',), inputs={'height': Domain(1, 5), 'spacing': Domain(4, 12), 'max_step': Domain(0, 1)}, adaptations=('terrain-following base', 'stepped coping'), guarantees=('continuous cardinal contour', 'grounded boundary', 'mount sockets')) def negotiate(self, ctx, parameters): center = self.curve.cells() if len(center) > 220 or len(set(center)) != len(center): raise ContractError('boundary-domain', ctx.path, conditions='Simple open contour, at most 220 raster cells') levels = [ctx.elevation(x, z) for x, z in center] if any(abs(a - b) > self.max_step for a, b in zip(levels, levels[1:])): raise ContractError('boundary-grade', ctx.path, conditions='Adjacent wall foundations exceed step bound') ports = [] grants = [] for i in range(2, len(center) - 2, self.spacing): x, z = center[i] y = levels[i] + self.height + 2 x0, z0 = center[max(0, i - 1)] x1, z1 = center[min(len(center) - 1, i + 1)] turn = 0 if abs(x1 - x0) >= abs(z1 - z0) else 1 at = (x, y, z) key = f'mount-{i}' box = Box(at, at) ports.append(Port(key, 'mount', Frame(at, turn), box, 1, key, facts={'support': (x, y - 1, z), 'load': 'small-fixture'})) grants.append(Grant(key, box, ('install',), ('fixture',), 0)) supports = tuple((x, levels[i], z) for i, (x, z) in enumerate(center)) shell = tuple((x, y, z) for i, (x, z) in enumerate(center) for y in range(levels[i] + 1, levels[i] + self.height + 2)) box = Box.enclosing((*supports, *shell)).expand(2) return Contract(box, tuple(ports), tuple(grants), (Rule('support', supports), Rule('sealed', shell)), decisions={'center': center, 'levels': levels, 'height': self.height}, reads=(box,)) def realize(self, ctx, contract): p = Plan() d = contract.decisions rng = ctx.rng('masonry') for i, (x, z) in enumerate(d['center']): for y in range(d['levels'][i] + 1, d['levels'][i] + self.height + 1): p.block((x, y, z), state_of(rng.choice(('stone_bricks', 'stone_bricks', 'mossy_stone_bricks'))), 'contour-masonry') p.block((x, d['levels'][i] + self.height + 1, z), slab('stone_brick', 'top'), 'coping') return p @dataclass(frozen=True) class BoundaryLantern: def capability(self): return Capability('extension.boundary-lantern', ('fixture', 'light'), guarantees=('mounted actual light',)) def negotiate(self, ctx, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('support', ((0, -1, 0),)), Rule('expected', ((0, 0, 0),), data={'names': ['lantern']})), atomic_object=True) def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('lantern', hanging='false', waterlogged='false'), 'lamp') return p @dataclass(frozen=True) class IlluminateBoundary: host: str every: int = 1 def capability(self): return Capability('extension.boundary-lighting', ('composite',)) def negotiate(self, ctx, parameters): ports = ctx.view.offers(self.host, 'mount')[::self.every] if not ports: raise ContractError('missing-mounts', ctx.path) return Contract(Box.enclosing(ctx.local(p.frame.origin) for p in ports).expand(1)) def realize(self, ctx, contract): p = Plan() for port in ctx.view.offers(self.host, 'mount')[::self.every]: frame = Frame(ctx.local(port.frame.origin), (port.frame.turn - ctx.frame.turn) % 4) p.children.append(Child(port.key, BoundaryLantern(), frame=frame, bindings=(Binding(self.host, port.key),))) return p @dataclass(frozen=True) class BoundaryChain: curve: Polyline height: int = 2 spacing: int = 7 chunk: int = 96 def capability(self): return Capability('extension.boundary-chain', ('boundary', 'composite'), offers=('mount',), inputs={'chunk': Domain(4, 220), 'height': Domain(1, 5), 'spacing': Domain(4, 12)}, guarantees=('continuous contour across component joins',)) def parts(self): cells = self.curve.cells() if len(set(cells)) != len(cells): raise ContractError('boundary-self-intersection', conditions='A simple open contour is required') count = max(1, (len(cells) + self.chunk - 1) // self.chunk) size = (len(cells) + count - 1) // count return tuple(Boundary(Polyline(cells[i:i + size]), self.height, self.spacing) for i in range(0, len(cells), size)) def negotiate(self, ctx, parameters): boxes = [] ports = [] last_height = None for i, part in enumerate(self.parts()): local = part.negotiate(ctx, {}) if last_height is not None and abs(local.decisions['levels'][0] - last_height) > part.max_step: raise ContractError('boundary-grade', ctx.path, conditions='Grade bound also applies at component joins') last_height = local.decisions['levels'][-1] boxes.append(local.envelope) for p in local.ports: ports.append(Port(f'segment-{i}-{p.key}', p.kind, p.frame, p.region, p.capacity, facts=p.facts, delegate=(f'segment-{i}', p.key))) return Contract(Box.enclosing(p for box in boxes for p in box.corners()), ports=tuple(ports), decisions={'segments': len(boxes), 'curve': self.curve.points}) def realize(self, ctx, contract): return Plan(children=[Child(f'segment-{i}', part) for i, part in enumerate(self.parts())])
hearth_extensions/circulation.py · 227 行 · 原文件
# Measured ribbon circulation, support grids and guard geometry through public contracts. from dataclasses import dataclass import math from hearth import Box, Frame, Binding, ContractError from hearth.blocks import state_of, stairs, slab, log, solid, passable, name_of from hearth.kernel import Capability, Domain, Contract, Port, Grant, Plan, Rule, Child, validator, Diagnostic from .geometry import Polyline, CARDINAL, bounds2, perimeter, lattice from .interfaces import Endpoint @validator('extension.guard') def guard_rule(scene, node, rule): for p in rule.cells: if name_of(scene.view.state(p)) not in ('spruce_fence', 'spruce_log', 'stone_brick_wall'): yield Diagnostic('bridge-guard', node.path, p, 'A required outer guard cell is absent') @validator('extension.span') def span_rule(scene, node, rule): supports = [node.frame.point(tuple(p)) for p in rule.data['anchors']] for p in rule.cells: if not supports or min(abs(p[0] - q[0]) + abs(p[2] - q[2]) for q in supports) > rule.data['maximum']: yield Diagnostic('unsupported-span', node.path, p, 'Deck exceeds declared supported horizontal span') @dataclass(frozen=True) class Surface: points: tuple role: str = 'deck' material: str = 'spruce_planks' def capability(self): tags = ('surface', self.role) + (('path', 'siteworks') if self.role in ('deck', 'platform') else ()) return Capability('extension.' + self.role, tags) def negotiate(self, ctx, parameters): box = Box.enclosing(self.points) return Contract(box, rules=(Rule('support', self.points),)) def realize(self, ctx, contract): p = Plan() heights = {(x, z): y for x, y, z in self.points} for x, y, z in self.points: uphill = next((face for dx, dz, face in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north')) if heights.get((x + dx, z + dz), y) == y + 1), None) p.block((x, y, z), stairs('spruce', uphill) if uphill else state_of(self.material), 'walk-surface') return p @dataclass(frozen=True) class Trestles: columns: tuple maximum: int = 8 def capability(self): return Capability('extension.trestles', ('siteworks', 'support'), adaptations=('posts to actual bed', 'stone shoes'), inputs={'maximum': Domain(2, 8)}) def negotiate(self, ctx, parameters): cells = tuple((x, y, z) for x, bed, z, top, wet in self.columns for y in range(bed - 1, top + 1)) if any(top - bed > self.maximum for x, bed, z, top, wet in self.columns): raise ContractError('connection-support-height', ctx.path, conditions=f'Post exceeds {self.maximum}') return Contract(Box.enclosing(cells), rules=(Rule('support', cells),), decisions={'columns': self.columns}) def realize(self, ctx, contract): p = Plan() for x, bed, z, top, wet in self.columns: for y in range(bed + 1, top + 1): p.block((x, y, z), state_of('stone_bricks') if y == bed + 1 or not wet else log(), 'pier') return p @dataclass(frozen=True) class Guards: points: tuple covered: bool = False roof: tuple = () def capability(self): return Capability('extension.guards', ('railing', 'roof' if self.covered else 'guard'), guarantees=('continuous outer guard',)) def negotiate(self, ctx, parameters): return Contract(Box.enclosing((*self.points, *self.roof)).expand(1), rules=(Rule('extension.guard', self.points),)) def realize(self, ctx, contract): p = Plan() occupied = {(x, z) for x, y, z in self.points} for i, (x, y, z) in enumerate(self.points): connections = {face: str((x + dx, z + dz) in occupied).lower() for dx, dz, face in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north'))} p.block((x, y, z), state_of('spruce_fence', waterlogged='false', **connections), 'guard') if self.covered: for yy in (y + 1, y + 2): p.block((x, yy, z), log() if i % 5 == 0 else state_of('spruce_fence', waterlogged='false', **connections), 'gallery-frame') for x, y, z in self.roof: p.block((x, y, z), slab('dark_oak', 'top'), 'gallery-canopy') return p @dataclass(frozen=True) class Link: start: Endpoint end: Endpoint terrain: str via: tuple = () curve: Polyline | None = None width: int = 3 rise: int = 0 covered: bool = False max_post: int = 8 max_span: int = 6 max_length: int = 120 fill_limit: int = 800 def capability(self): return Capability('extension.gallery' if self.covered else 'extension.bridge', ('connection', 'path', 'composite'), offers=('access',), adaptations=('bounded height profile', 'actual-bed trestles', 'supported deck reuse at endpoints'), guarantees=('both public endpoints reachable', 'two-cell headroom', 'outer guard'), inputs={'width': Domain(choices=(3, 5)), 'rise': Domain(0, 3), 'max_post': Domain(2, 8), 'max_span': Domain(3, 6)}, locked=('start', 'end', 'via', 'curve', 'width', 'covered')) def negotiate(self, ctx, parameters): pa, a, da = self.start.resolve(ctx) pb, b, db = self.end.resolve(ctx) required = {(self.start.host, self.start.port), (self.end.host, self.end.port)} if not required.issubset({(v.host, v.port) for v in ctx.bindings if v.verb == 'connect'}): raise ContractError('endpoint-binding', ctx.path, conditions='Both endpoints need explicit read-only connection bindings') points = ((a[0], a[2]), (a[0] + 3 * da[0], a[2] + 3 * da[1]), *self.via, (b[0] + 3 * db[0], b[2] + 3 * db[1]), (b[0], b[2])) curve = self.curve or Polyline(tuple(points)) if curve.points[0] != (a[0], a[2]) or curve.points[-1] != (b[0], b[2]): raise ContractError('endpoint-disconnected', ctx.path, ctx.world(a), 'Curve ends must match the negotiated public ports') for point, next_point, direction in ((curve.points[0], curve.points[1], da), (curve.points[-1], curve.points[-2], db)): delta = (next_point[0] - point[0], next_point[1] - point[1]) if delta[0] * direction[1] - delta[1] * direction[0] != 0 or delta[0] * direction[0] + delta[1] * direction[1] <= 0: raise ContractError('endpoint-frame', ctx.path, ctx.world((int(point[0]), a[1], int(point[1]))), 'First and last tangents must point out of the host') if curve.length > self.max_length or curve.length < 7: raise ContractError('connection-domain', ctx.path, conditions='Route length exceeds the negotiated preparation budget') center = curve.cells() if len(set(center)) != len(center): raise ContractError('connection-domain', ctx.path, conditions='Need a simple route of length 7..maximum') radius = self.width // 2 + 1 deck = curve.ribbon(radius + .2) station = {p: min(range(len(center)), key=lambda i: (math.dist(p, center[i]), i)) for p in deck} count = len(center) # Preserve the host's offered mouth width, then flare to the body width. mouth_widths = [] for port in (pa, pb): horizontal = [port.frame.inverse(q)[0] for q in port.region.corners()] mouth_widths.append(max(horizontal) - min(horizontal) + 1) if min(mouth_widths) < 3: raise ContractError('endpoint-width', ctx.path, ctx.world(a), 'Connection needs an offered mouth at least three cells wide') deck = tuple(p for p in deck if (station[p] >= 3 or abs(pa.frame.inverse(ctx.world((p[0], a[1], p[1])))[0]) <= mouth_widths[0] // 2) and (station[p] < count - 3 or abs(pb.frame.inverse(ctx.world((p[0], b[1], p[1])))[0]) <= mouth_widths[1] // 2)) heights = [lattice((a[1] - 1) * (1 - i / (count - 1)) + (b[1] - 1) * i / (count - 1) + self.rise * math.sin(math.pi * i / (count - 1))) for i in range(count)] beds = {} waters = {} endpoint_regions = (pa.region, pb.region) for x, z in deck: cap = max(a[1], b[1]) + self.rise + 2 bed = ctx.elevation(x, z, maximum=cap) water = ctx.water(x, z) beds[(x, z)] = bed waters[(x, z)] = water i = station[(x, z)] heights[i] = max(heights[i], bed, water + 1 if water is not None else bed) # Minimal upward propagation, preserving fixed endpoint elevations. for i in range(1, count): heights[i] = max(heights[i], heights[i - 1] - 1) for i in range(count - 2, -1, -1): heights[i] = max(heights[i], heights[i + 1] - 1) if heights[0] != a[1] - 1 or heights[-1] != b[1] - 1: raise ContractError('endpoint-grade', ctx.path, ctx.world(a), 'Measured ground/water cannot meet the locked endpoint heights') outer = set(perimeter(deck)) guards = [] clear = [] all_deck = [] writes = [] for x, z in deck: i = station[(x, z)] y = heights[i] q = ctx.world((x, y, z)) host_region = any(region.contains(q) for region in endpoint_regions) is_guard = (x, z) in outer and 2 < i < count - 3 and not host_region all_deck.append((x, y, z)) if is_guard: guards.append((x, y + 1, z)) else: clear.extend(((x, y + 1, z), (x, y + 2, z))) existing = ctx.view.state(q) if solid(existing) and host_region: continue writes.append((x, y, z)) anchors = [] for x, z in sorted(deck, key=lambda p: (station[p], p)): if any(abs(x - u) + abs(z - v) <= self.max_span for u, v in anchors): continue # Prefer the central route where possible, then cover wide diagonal corners. near = center[station[(x, z)]] anchor = near if near in beds else (x, z) if anchor in anchors: anchor = (x, z) anchors.append(anchor) columns = [] for x, z in anchors: top = heights[station[(x, z)]] - 1 bed = min(beds[(x, z)], top) while not ctx.view.supports(ctx.world((x, bed, z))): bed -= 1 if top - bed > self.max_post: raise ContractError('connection-support-height', ctx.path, ctx.world((x, top, z))) if not ctx.view.supports(ctx.world((x, bed - 1, z))): raise ContractError('connection-bed', ctx.path, ctx.world((x, bed - 1, z)), 'Need two actual supporting bed cells') columns.append((x, bed, z, top, waters[(x, z)] is not None)) fill = sum(max(0, top - bed) for x, bed, z, top, wet in columns) if fill > self.fill_limit: raise ContractError('connection-fill-limit', ctx.path, conditions=f'{fill}>{self.fill_limit}') roof = tuple((x, y + 5, z) for x, y, z in all_deck if self.covered and 3 < station[(x, z)] < count - 4) guard_points = tuple(guards) low = min(min(beds.values()) - 1, min(heights)) envelope = bounds2(deck, low, max(heights) + 7).expand(1) center_route = tuple((x, heights[i] + 1, z) for i, (x, z) in enumerate(center)) rules = (Rule('route', (a, *center_route, b), envelope, phase='complete'), Rule('support', tuple(all_deck)), Rule('clear', tuple(clear)), Rule('extension.span', tuple(all_deck), data={'anchors': [(x, 0, z) for x, z in anchors], 'maximum': self.max_span})) return Contract(envelope, ports=(Port('start', 'access', Frame(a), Box(a, a), 8), Port('end', 'access', Frame(b), Box(b, b), 8)), rules=rules, decisions={'curve': curve.points, 'center': center, 'profile': heights, 'deck': all_deck, 'writes': writes, 'guards': guard_points, 'columns': columns, 'roof': roof, 'fill': fill, 'width': self.width, 'covered': self.covered, 'rise': self.rise, 'endpoint_regions': [[r.lo, r.hi] for r in endpoint_regions]}, reads=(envelope,)) def realize(self, ctx, contract): d = contract.decisions terrain = (Binding(self.terrain, 'construction', 'fill', ctx.frame.box(contract.envelope)),) p = Plan(children=[Child('supports', Trestles(tuple(d['columns']), self.max_post), bindings=terrain), Child('deck', Surface(tuple(d['writes'])), bindings=terrain), Child('guards', Guards(tuple(d['guards']), self.covered, tuple(d['roof'])))]) p.relations.extend(((ctx.path, 'connects', self.start.host), (ctx.path, 'connects', self.end.host))) return p def connection(key, start, end, terrain, **parameters): """Create a fully bound link through public endpoint references.""" return Child(key, Link(start, end, terrain, **parameters), bindings=(start.binding(), end.binding()))
hearth_extensions/geometry.py · 133 行 · 原文件
# Portable design geometry and deterministic voxelization shared by extension components. from dataclasses import dataclass import math from hearth.space import Box CARDINAL = ((1, 0), (-1, 0), (0, 1), (0, -1)) def lattice(value): """Round consistently across native Python and browser Python.""" return math.floor(value + 0.5) @dataclass(frozen=True) class Polyline: points: tuple[tuple[float, float], ...] def __post_init__(self): object.__setattr__(self, 'points', tuple(tuple(p) for p in self.points)) if len(self.points) < 2 or any(len(p) != 2 or not all(math.isfinite(v) for v in p) for p in self.points): raise ValueError('A finite polyline needs at least two two-dimensional points') if any(a == b for a, b in zip(self.points, self.points[1:])): raise ValueError('Repeated consecutive control points') @classmethod def bezier(cls, controls, segments=32): if len(controls) != 4 or not 4 <= segments <= 256: raise ValueError('Cubic curves require four controls and 4..256 samples') points = [] for i in range(segments + 1): t = i / segments weights = ((1 - t)**3, 3 * t * (1 - t)**2, 3 * t * t * (1 - t), t**3) points.append(tuple(sum(w * p[k] for w, p in zip(weights, controls)) for k in (0, 1))) return cls(tuple(points)) @property def length(self): return sum(math.dist(a, b) for a, b in zip(self.points, self.points[1:])) def nearest(self, point): """Return distance, arc length, tangent and projection with stable tie breaks.""" best, walked = None, 0.0 for index, (a, b) in enumerate(zip(self.points, self.points[1:])): dx, dz = b[0] - a[0], b[1] - a[1] length = math.hypot(dx, dz) t = max(0, min(1, ((point[0] - a[0]) * dx + (point[1] - a[1]) * dz) / length**2)) q = (a[0] + t * dx, a[1] + t * dz) item = (math.dist(point, q), walked + t * length, index, (dx / length, dz / length), q) if best is None or item[:3] < best[:3]: best = item walked += length return best[0], best[1], best[3], best[4] def cells(self): """Rasterize a connected cardinal chain, retaining explicit diagonal turns.""" result = [] for a, b in zip(self.points, self.points[1:]): count = max(1, math.ceil(math.dist(a, b) * 4)) for i in range(count + 1): target = tuple(lattice(a[k] + (b[k] - a[k]) * i / count) for k in (0, 1)) if not result: result.append(target) while result[-1] != target: x, z = result[-1] tx, tz = target candidates = [] if x != tx: candidates.append((x + (1 if tx > x else -1), z)) if z != tz: candidates.append((x, z + (1 if tz > z else -1))) result.append(min(candidates, key=lambda p: (self.nearest(p)[0], p))) return tuple(result) def ribbon(self, radius, caps=False): xmin = math.floor(min(p[0] for p in self.points) - radius) xmax = math.ceil(max(p[0] for p in self.points) + radius) zmin = math.floor(min(p[1] for p in self.points) - radius) zmax = math.ceil(max(p[1] for p in self.points) + radius) a, b = self.points[0], self.points[-1] start = (self.points[1][0] - a[0], self.points[1][1] - a[1]) end = (b[0] - self.points[-2][0], b[1] - self.points[-2][1]) result = [] for x in range(xmin, xmax + 1): for z in range(zmin, zmax + 1): distance, station, _, _ = self.nearest((x, z)) if not caps and ((station <= 1e-9 and (x - a[0]) * start[0] + (z - a[1]) * start[1] < 0) or (station >= self.length - 1e-9 and (x - b[0]) * end[0] + (z - b[1]) * end[1] > 0)): continue if distance <= radius + 0.05: result.append((x, z)) return tuple(result) @dataclass(frozen=True) class Polygon: vertices: tuple[tuple[int, int], ...] def __post_init__(self): object.__setattr__(self, 'vertices', tuple(tuple(p) for p in self.vertices)) if len(self.vertices) < 3: raise ValueError('At least three polygon vertices required') @classmethod def chamfered(cls, width, depth, corner=0): if not 9 <= width <= 27 or not 9 <= depth <= 27 or not 0 <= corner <= min(width, depth) // 3: raise ValueError('Footprint domain: dimensions 9..27, corner 0..one third') x, z, c = width - 1, depth - 1, corner return cls(((0, 0), (x, 0), (x, z), (0, z)) if not c else ((c, 0), (x - c, 0), (x, c), (x, z - c), (x - c, z), (c, z), (0, z - c), (0, c))) def cells(self): result = [] for x in range(min(p[0] for p in self.vertices), max(p[0] for p in self.vertices) + 1): for z in range(min(p[1] for p in self.vertices), max(p[1] for p in self.vertices) + 1): inside = False edge = False for a, b in zip(self.vertices, self.vertices[1:] + self.vertices[:1]): cross = (x - a[0]) * (b[1] - a[1]) - (z - a[1]) * (b[0] - a[0]) if cross == 0 and min(a[0], b[0]) <= x <= max(a[0], b[0]) and min(a[1], b[1]) <= z <= max(a[1], b[1]): edge = True if (a[1] > z) != (b[1] > z) and x < (b[0] - a[0]) * (z - a[1]) / (b[1] - a[1]) + a[0]: inside = not inside if edge or inside: result.append((x, z)) return tuple(result) def perimeter(cells, diagonal=False): points = set(cells) steps = tuple((x, z) for x in (-1, 0, 1) for z in (-1, 0, 1) if x or z) if diagonal else CARDINAL return tuple(sorted(p for p in points if any((p[0] + dx, p[1] + dz) not in points for dx, dz in steps))) def bounds2(points, low, high): return Box((min(p[0] for p in points), low, min(p[1] for p in points)), (max(p[0] for p in points), high, max(p[1] for p in points)))
hearth_extensions/graphs.py · 99 行 · 原文件
# Reusable campus graph composes arbitrary public building and circulation components. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Port, Rule, Plan, Child, Context from .interfaces import Endpoint from .circulation import connection from .boundaries import BoundaryChain, IlluminateBoundary from hearth.components.landscape import Landscape @dataclass(frozen=True) class Vertex: key: str component: object frame: Frame @dataclass(frozen=True) class Edge: a: str a_port: str b: str b_port: str covered: bool = False via: tuple = () rise: int = 0 width: int = 3 @dataclass(frozen=True) class Campus: vertices: tuple[Vertex, ...] edges: tuple[Edge, ...] terrain: str envelope: Box boundary: object = None landscape: bool = True def capability(self): return Capability('extension.campus', ('settlement', 'composite'), offers=('public-access',), guarantees=('declared graph connected', 'usable realized building connections'), locked=('vertices', 'edges')) def negotiate(self, ctx, parameters): keys = {v.key for v in self.vertices} if len(keys) != len(self.vertices) or not keys: raise ContractError('graph-vertices', ctx.path) connected = {self.vertices[0].key} for edge in self.edges: if edge.a not in keys or edge.b not in keys or edge.a == edge.b: raise ContractError('graph-edge', ctx.path, conditions=str(edge)) while True: more = {v for e in self.edges if e.a in connected or e.b in connected for v in (e.a, e.b)} if more <= connected: break connected |= more if connected != keys: raise ContractError('graph-disconnected', ctx.path, conditions=str(sorted(keys - connected))) first = self.vertices[0] context = Context(ctx.path + '/' + first.key, ctx.frame.compose(first.frame), ctx.scope.child(first.key), ctx.view, (), ctx.limits) offered = first.component.negotiate(context, {}).transformed(first.frame).ports port = next((p for p in offered if p.kind in ('access', 'public-access')), None) if port is None: raise ContractError('graph-access', ctx.path, conditions='First vertex must expose usable access') gateway = Port('public', 'access', port.frame, port.region, port.capacity, delegate=(first.key, port.key)) return Contract(self.envelope, ports=(gateway,), decisions={'vertices': [v.key for v in self.vertices], 'edges': [(e.a, e.a_port, e.b, e.b_port, e.covered, e.width) for e in self.edges]}) def realize(self, ctx, contract): p = Plan(children=[Child(v.key, v.component, frame=v.frame) for v in self.vertices]) p.children.append(Child('circulation', Connections(ctx.path, self.edges, self.terrain, self.envelope))) if self.boundary is not None: p.children.extend((Child('boundary', BoundaryChain(self.boundary)), Child('boundary-lights', IlluminateBoundary(ctx.path + '/boundary', 2)))) if self.landscape: p.children.append(Child('landscape', Landscape(self.envelope, self.terrain, 8, 12, 0.025))) return p @dataclass(frozen=True) class Connections: parent: str edges: tuple[Edge, ...] terrain: str envelope: Box def capability(self): return Capability('extension.connection-graph', ('connection', 'composite')) def negotiate(self, ctx, parameters): targets = [] for edge in self.edges: for key, port in ((edge.a, edge.a_port), (edge.b, edge.b_port)): targets.append(ctx.local(ctx.view.port(self.parent + '/' + key, port).frame.origin)) return Contract(self.envelope, rules=(Rule('route', tuple(targets), self.envelope, phase='complete'),)) def realize(self, ctx, contract): p = Plan() for i, edge in enumerate(self.edges): a = Endpoint(self.parent + '/' + edge.a, edge.a_port) b = Endpoint(self.parent + '/' + edge.b, edge.b_port) p.children.append(connection(f'link-{i}', a, b, self.terrain, via=edge.via, covered=edge.covered, rise=edge.rise, width=edge.width)) return p
hearth_extensions/halls.py · 211 行 · 原文件
# Polygon halls, public facade installation and concentric hipped roof components. from dataclasses import dataclass from hearth import Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Port, Grant, Rule, Plan, Child, Domain, Context from hearth.blocks import state_of, log, slab, stairs from hearth.adapters.site import survey, Foundation, Approach, SiteLimits from hearth.components.interior import Door, Light from hearth.components.primitives import Window from .geometry import Polygon, CARDINAL, bounds2, perimeter from .sites import edge_frames from .circulation import Surface from .interiors import HallInterior, FUNCTION_GROUPS @dataclass(frozen=True) class PolygonShell: footprint: Polygon height: int = 5 entrances: tuple = ('north', 'south') def capability(self): return Capability('extension.polygon-shell', ('wall', 'enclosure'), offers=('wall-installation',), guarantees=('continuous enclosure', 'protected floor support'), inputs={'height': Domain(5, 7)}) def negotiate(self, ctx, parameters): footprint = self.footprint.cells() shell = perimeter(footprint, diagonal=True) xs = [x for x, z in footprint] zs = [z for x, z in footprint] width, depth = max(xs) + 1, max(zs) + 1 if min(xs) != 0 or min(zs) != 0: raise ContractError('polygon-origin', ctx.path, conditions='Normalize footprint minimum to (0,0)') frames = edge_frames(width, depth, 0) ports = [] grants = [] for side, f in frames.items(): for role, offset, size, base in [('entry', 0, 1, 0)] if side in self.entrances else []: at = f.compose(Frame((offset, base, 0))) region = at.box(Box((0, 0, 0), (size - 1, 2, 0))) if not all((p[0], p[2]) in shell for p in region.cells()): raise ContractError('polygon-entry', ctx.path, at.origin, 'Requested cardinal entry is not on the footprint boundary') key = 'entry-' + side ports.append(Port(key, 'wall-installation', at, region, 1, key, facts={'thickness': 1, 'role': role, 'side': side})) grants.append(Grant(key, region, ('install',), ('door',), 3)) for i, offset in enumerate((-4, 3)): at = f.compose(Frame((offset, 1, 0))) region = at.box(Box((0, 0, 0), (1, 1, 0))) if all((p[0], p[2]) in shell for p in region.cells()): key = f'window-{side}-{i}' ports.append(Port(key, 'wall-installation', at, region, 1, key, facts={'thickness': 1, 'role': 'window', 'side': side})) grants.append(Grant(key, region, ('install',), ('window',), 4)) blocks = tuple((x, y, z) for x, z in shell for y in range(self.height)) return Contract(bounds2(footprint, 0, self.height - 1), tuple(ports), tuple(grants), rules=(Rule('sealed', blocks), Rule('support', tuple((x, -1, z) for x, z in shell))), decisions={'shell': shell, 'height': self.height}) def realize(self, ctx, contract): p = Plan() vertices = set(self.footprint.vertices) for x, z in contract.decisions['shell']: for y in range(self.height): frame = (x, z) in vertices or y == self.height - 1 p.block((x, y, z), log() if frame else state_of('smooth_sandstone'), 'frame' if frame else 'infill') return p @dataclass(frozen=True) class Facade: host: str shutters: bool = True def capability(self): return Capability('extension.facade-installations', ('composite',)) def negotiate(self, ctx, parameters): box = ctx.view.contract(self.host).envelope return Contract(Box.enclosing(ctx.local(p) for p in box.corners()).expand(2)) def realize(self, ctx, contract): p = Plan() for port in ctx.view.offers(self.host, 'wall-installation'): component = Door() if port.facts['role'] == 'entry' else Window(shutters=self.shutters) frame = Frame(ctx.local(port.frame.origin), (port.frame.turn - ctx.frame.turn) % 4) p.children.append(Child(port.key, component, frame=frame, bindings=(Binding(self.host, port.key),))) return p @dataclass(frozen=True) class HipRoof: footprint: Polygon run: int = 2 lantern: bool = False material: str = 'deepslate_tile' def capability(self): return Capability('extension.hip-roof', ('roof', 'composite'), adaptations=('polygon inset courses',), inputs={'run': Domain(choices=(1, 2, 3))}, guarantees=('continuous concentric weather surface',)) def negotiate(self, ctx, parameters): points = set(self.footprint.cells()) points |= {(x + dx, z + dz) for x, z in tuple(points) for dx, dz in CARDINAL} remaining = set(points) depths = {} depth = 0 while remaining: ring = perimeter(remaining) for p in ring: depths[p] = depth remaining -= set(ring) depth += 1 courses = tuple((x, depths[(x, z)] // self.run, z) for x, z in sorted(points)) peak = max(y for x, y, z in courses) cx = (min(x for x, z in points) + max(x for x, z in points)) // 2 cz = (min(z for x, z in points) + max(z for x, z in points)) // 2 return Contract(bounds2(points, -1, peak + (15 if self.lantern else 7)), rules=(Rule('sealed', courses),), decisions={'courses': courses, 'peak': peak, 'center': (cx, cz), 'run': self.run, 'lantern': self.lantern}) def realize(self, ctx, contract): p = Plan() d = contract.decisions heights = {(x, z): y for x, y, z in d['courses']} for x, y, z in d['courses']: face = next((f for dx, dz, f in ((1, 0, 'east'), (-1, 0, 'west'), (0, 1, 'south'), (0, -1, 'north')) if heights.get((x + dx, z + dz), y) > y), None) material = 'dark_oak' if y == 0 else self.material p.block((x, y, z), stairs(material, face) if face else slab(material, 'top'), 'hip-course') if self.lantern: cx, cz = d['center'] p.children.append(Child('lantern', RoofLantern(), frame=Frame((cx - 2, d['peak'] + 1, cz - 2)))) return p @dataclass(frozen=True) class RoofLantern: def capability(self): return Capability('extension.roof-lantern', ('roof', 'daylight', 'composite')) def negotiate(self, ctx, parameters): return Contract(Box((-1, -3, -1), (5, 13, 5))) def realize(self, ctx, contract): p = Plan() for x in range(5): for z in range(5): bed = ctx.elevation(x, z, maximum=0) if bed < -4: raise ContractError('lantern-support', ctx.path, ctx.world((x, bed, z))) for y in range(bed + 1, 1): p.block((x, y, z), state_of('spruce_planks'), 'ring-beam') if x in (0, 4) or z in (0, 4): for y in (1, 2): p.block((x, y, z), log() if x in (0, 4) and z in (0, 4) else state_of('glass'), 'clerestory') p.children.append(Child('cap', HipRoof(Polygon(((0, 0), (4, 0), (4, 4), (0, 4))), run=2), frame=Frame((0, 3, 0)))) return p @dataclass(frozen=True) class Pavilion: footprint: Polygon terrain: str purpose: str = 'library' entrances: tuple = ('north', 'south') height: int = 5 roof_run: int = 2 lantern: bool = False limits: SiteLimits = SiteLimits() def capability(self): return Capability('extension.pavilion', ('building', 'habitable', 'composite'), offers=('access',), adaptations=('polygon support grid', 'independently measured approaches'), guarantees=('connected entrances', 'furnished lit enclosed hall'), inputs={'height': Domain(5, 7), 'purpose': Domain(choices=('living', 'library', 'workshop', 'kitchen', 'bedroom', 'storage'))}, locked=('footprint', 'purpose', 'entrances', 'height', 'roof_run', 'lantern')) def negotiate(self, ctx, parameters): points = self.footprint.cells() width = max(x for x, z in points) + 1 depth = max(z for x, z in points) + 1 if not 13 <= width <= 25 or not 13 <= depth <= 25 or not self.entrances: raise ContractError('hall-domain', ctx.path, conditions='Footprints 13..25, at least one declared entrance') measured = survey(ctx, points, self.limits) floor = measured['floor'] ports = [] approaches = [] frames = edge_frames(width, depth, 0) low = min(v[0] for v in measured['samples'].values()) - 1 roof = HipRoof(self.footprint, self.roof_run, self.lantern).negotiate(ctx, {}) boxes = [bounds2(points, low, floor + self.height + 3).expand(3), Frame((0, floor + self.height + 2, 0)).box(roof.envelope)] targets = [(width // 2, floor + 1, depth // 2)] for side in self.entrances: if side not in frames: raise ContractError('hall-entrance', ctx.path, conditions=side) f = frames[side] comp = Approach(0, floor, limits=self.limits) ac = comp.negotiate(Context(ctx.path, ctx.frame.compose(f), ctx.scope.child('approach-' + side), ctx.view, (), ctx.limits), {}) local = ac.transformed(f) port = local.ports[0] ports.append(Port(side, 'access', Frame(port.frame.origin, f.turn), port.region, 8, delegate=('approach-' + side, 'street'))) approaches.append((side, f, comp)) boxes.append(local.envelope) targets.extend(((f.origin[0], floor + 1, f.origin[2]), port.frame.origin)) envelope = Box.enclosing(p for box in boxes for p in box.corners()) interior = Box((1, floor + 1, 1), (width - 2, floor + self.height - 1, depth - 2)) return Contract(envelope, tuple(ports), rules=(Rule('route', tuple(targets), envelope, phase='complete'), Rule('light', tuple(targets[:1]), interior, {'minimum': 1}, 'complete'), Rule('furnishing', box=interior, data={'groups': FUNCTION_GROUPS[self.purpose]}, phase='complete')), decisions={'floor': floor, 'width': width, 'depth': depth, 'footprint': points, 'vertices': self.footprint.vertices, 'strategy': measured['strategy'], 'entrances': self.entrances, 'height': self.height, 'purpose': self.purpose, 'roof_run': self.roof_run, 'lantern': self.lantern}) def realize(self, ctx, contract): d = contract.decisions floor = d['floor'] w = d['width'] depth = d['depth'] p = Plan(children=[Child('foundation', Foundation(tuple(d['footprint']), floor, d['strategy'], self.limits), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('floor', Surface(tuple((x, floor, z) for x, z in d['footprint']), role='hall-floor')), Child('ceiling', Surface(tuple((x, floor + self.height + 1, z) for x, z in d['footprint']), role='hall-ceiling')), Child('shell', PolygonShell(self.footprint, self.height, self.entrances), frame=Frame((0, floor + 1, 0))), Child('facade', Facade(ctx.path + '/shell'))]) for side in self.entrances: f = edge_frames(w, depth, 0)[side] p.children.append(Child('approach-' + side, Approach(0, floor, limits=self.limits), frame=f, bindings=(Binding(self.terrain, 'construction', 'surface'),))) p.children.append(Child('furnishings', HallInterior(self.footprint, self.purpose), frame=Frame((0, floor + 1, 0)))) for x in range(4, w - 3, 5): for z in range(4, depth - 3, 5): p.children.append(Child(f'light-{x}-{z}', Light(), frame=Frame((x, floor + self.height - 1, z)))) p.children.append(Child('roof', HipRoof(self.footprint, self.roof_run, self.lantern), frame=Frame((0, floor + self.height + 2, 0)))) return p
hearth_extensions/interfaces.py · 38 行 · 原文件
# Public endpoint discovery and orientation checks shared by circulation components. from dataclasses import dataclass from hearth import Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Rule @dataclass(frozen=True) class Endpoint: host: str port: str def binding(self): return Binding(self.host, self.port, 'connect') def resolve(self, ctx): port = ctx.view.port(self.host, self.port) if port.kind not in ('access', 'public-access'): raise ContractError('endpoint-kind', ctx.path, port.frame.origin, 'Require an access or public-access port') at = ctx.local(port.frame.origin) turn = (port.frame.turn - ctx.frame.turn) % 4 outward = Frame(turn=turn).vector((0, 0, -1)) return port, at, (outward[0], outward[2]) @dataclass(frozen=True) class EndpointContact: endpoint: Endpoint def capability(self): return Capability('extension.endpoint-contact', ('connection',), guarantees=('unchanged supported endpoint',)) def negotiate(self, ctx, parameters): port, at, direction = self.endpoint.resolve(ctx) from hearth.space import Box return Contract(Box(at, at).expand(1), rules=(Rule('support', ((at[0], at[1] - 1, at[2]),)), Rule('clear', (at, (at[0], at[1] + 1, at[2]))))) def realize(self, ctx, contract): return Plan()
hearth_extensions/interiors.py · 116 行 · 原文件
# Functional furnishing stations arranged around protected circulation in polygon interiors. from dataclasses import dataclass from hearth import Box, Frame, ContractError from hearth.kernel import Capability, Contract, Domain, Port, Rule, Plan, Child from hearth.blocks import state_of, stairs, passable from .geometry import Polygon, perimeter, bounds2 FUNCTION_GROUPS = {'library': [['bookshelf'], ['lectern']], 'workshop': [['crafting_table'], ['smithing_table']], 'kitchen': [['smoker'], ['furnace']], 'bedroom': [['red_bed']], 'living': [['spruce_stairs']], 'storage': [['barrel']]} @dataclass(frozen=True) class WorkBay: purpose: str def capability(self): return Capability('extension.work-bay', ('furniture', self.purpose), offers=('interaction',), inputs={'purpose': Domain(choices=tuple(FUNCTION_GROUPS))}, guarantees=('functionally furnished', 'supported', 'clear interaction space')) def negotiate(self, ctx, parameters): interaction = ((0, 0, 2), (1, 0, 2)) support = tuple((x, -1, z) for x in range(2) for z in range(3)) clear = tuple((x, y, 2) for x in range(2) for y in range(2)) area = Box((0, 0, 0), (1, 1, 1)) return Contract(Box((0, -1, 0), (1, 1, 2)), ports=(Port('use', 'interaction', Frame(interaction[0]), Box(interaction[0], (1, 1, 2)), 4),), rules=(Rule('support', support), Rule('clear', clear), Rule('furnishing', box=area, data={'groups': FUNCTION_GROUPS[self.purpose]}, phase='complete')), atomic_object=True) def realize(self, ctx, contract): plan = Plan() barrel = state_of('barrel', facing='south', open='false') inventory = {'id': 'minecraft:barrel', 'Items': [{'Slot': 0, 'id': 'minecraft:bread', 'count': 6}, {'Slot': 1, 'id': 'minecraft:torch', 'count': 12}]} plan.block((1, 0, 0), barrel, 'supplies', nbt=inventory) if self.purpose == 'library': for y in range(2): plan.block((0, y, 0), state_of('bookshelf'), 'shelving') plan.block((0, 0, 1), state_of('lectern', facing='south', has_book='false', powered='false'), 'reading') plan.block((1, 0, 1), stairs('spruce', 'north'), 'seat') elif self.purpose in ('workshop', 'kitchen'): a, b = ('crafting_table', 'smithing_table') if self.purpose == 'workshop' else ('smoker', 'furnace') properties = {'facing': 'south', 'lit': 'false'} if self.purpose == 'kitchen' else {} plan.block((0, 0, 0), state_of(a, **properties), 'workstation') plan.block((0, 0, 1), state_of(b, **properties), 'workstation') plan.block((1, 0, 1), stairs('spruce', 'north'), 'seat') elif self.purpose == 'bedroom': for z, part in ((0, 'head'), (1, 'foot')): plan.block((0, 0, z), state_of('red_bed', facing='north', part=part, occupied='false'), 'bed') plan.block((1, 0, 1), state_of('red_carpet'), 'bedside') elif self.purpose == 'living': plan.block((0, 0, 0), stairs('spruce', 'south'), 'seat') plan.block((1, 0, 1), stairs('spruce', 'north'), 'seat') plan.block((0, 0, 1), state_of('spruce_fence', north='false', south='false', east='false', west='false', waterlogged='false'), 'table') plan.block((0, 1, 1), state_of('spruce_pressure_plate', powered='false'), 'table') else: for x, y, z in ((0, 0, 0), (0, 1, 0), (0, 0, 1)): plan.block((x, y, z), barrel, 'storage', nbt=inventory) return plan @dataclass(frozen=True) class HallInterior: footprint: Polygon purpose: str minimum: int = 2 maximum: int = 8 area_per_bay: int = 42 def capability(self): return Capability('extension.hall-interior', ('interior', 'furniture', 'composite'), inputs={'purpose': Domain(choices=tuple(FUNCTION_GROUPS)), 'minimum': Domain(1, 8), 'maximum': Domain(1, 12), 'area_per_bay': Domain(16, 100)}, adaptations=('fit functional bays around a circulation cross',), guarantees=('accessible furnishing stations', 'protected three-cell central aisles')) def negotiate(self, ctx, parameters): footprint = set(self.footprint.cells()) inside = footprint - set(perimeter(footprint, diagonal=True)) width = max(x for x, z in footprint) + 1 depth = max(z for x, z in footprint) + 1 cx, cz = width // 2, depth // 2 if self.minimum > self.maximum: raise ContractError('interior-domain', ctx.path, conditions='Minimum exceeds maximum') aisle = {(x, z) for x, z in inside if abs(x - cx) <= 1 or abs(z - cz) <= 1} candidates = [] rng = ctx.rng('planning') for x, z in sorted(inside): for turn in range(4): frame = Frame((x, 0, z), turn) cells = {(frame.point((u, 0, v))[0], frame.point((u, 0, v))[2]) for u in range(2) for v in range(3)} body = {(frame.point((u, 0, v))[0], frame.point((u, 0, v))[2]) for u in range(2) for v in range(2)} if not cells <= inside or body & aisle: continue front = frame.point((0, 0, 2)) if (front[0] - x) * (cx - x) + (front[2] - z) * (cz - z) <= 0: continue if not all(passable(ctx.state((u, y, v))) for u, v in cells for y in range(2)): continue quadrant = (x < cx, z < cz) candidates.append((frame, cells, body, quadrant, rng.random())) wanted = min(self.maximum, max(self.minimum, len(inside) // self.area_per_bay)) selected = [] used = set() while candidates and len(selected) < wanted: def score(item): frame, cells, body, quadrant, tie = item x, _, z = frame.origin separation = min((abs(x - v[0].origin[0]) + abs(z - v[0].origin[2]) for v in selected), default=width + depth) balance = sum(v[3] == quadrant for v in selected) return (balance, -separation, min(x, z, width - 1 - x, depth - 1 - z), tie, frame.origin, frame.turn) choice = min(candidates, key=score) selected.append(choice) used |= choice[1] candidates = [v for v in candidates if not v[1] & used and all(abs(v[0].origin[0] - old[0].origin[0]) + abs(v[0].origin[2] - old[0].origin[2]) >= 4 for old in selected)] if len(selected) < self.minimum: raise ContractError('interior-capacity', ctx.path, conditions=f'{len(selected)} bays fit; {self.minimum} required') targets = ((cx, 0, cz), *(v[0].point((0, 0, 2)) for v in selected)) clear = tuple((x, y, z) for x, z in sorted(aisle) for y in (0, 1)) envelope = bounds2(footprint, -1, 2) return Contract(envelope, rules=(Rule('clear', clear), Rule('route', targets, envelope, phase='complete')), decisions={'frames': [(v[0].origin, v[0].turn) for v in selected], 'requested_bays': wanted, 'placed_bays': len(selected), 'minimum_bays': self.minimum, 'omitted_optional': wanted - len(selected), 'purpose': self.purpose}) def realize(self, ctx, contract): return Plan(children=[Child(f'bay-{i}', WorkBay(self.purpose), frame=Frame(tuple(origin), turn)) for i, (origin, turn) in enumerate(contract.decisions['frames'])])
hearth_extensions/programs.py · 60 行 · 原文件
# Lightweight graph clients using frozen generic fields and interchangeable public buildings. from hearth import Scene, Box, Frame from hearth.randomness import Scope from hearth.environment import Terrain, gradient, wave, radial from hearth.components.building import Blueprint, RoomSpec, Building from hearth.persistence import semantic_digest from .geometry import Polygon, Polyline from .halls import Pavilion from .graphs import Campus, Vertex, Edge DOMAIN = Box((-18, -4, -18), (95, 70, 95)) def frozen_site(environment_seed=0, domain=DOMAIN): rng = Scope(environment_seed).stream('environment') field = gradient(rng.choice((-.012, 0, .012)), rng.choice((-.009, .009)), 5) + wave(.5, .07, .09, rng.random() * 6) + radial(30, 31, 24, -3.8) scene = Scene(environment_seed, domain=domain) scene.place('land', Terrain(domain, field, water_level=3, edit_limit=2500)) return scene.finalize() def branching_campus(seed=0): rng = Scope(seed).stream('branching-graph') hub = Pavilion(Polygon.chamfered(17, 17, 4), '/land', 'library', ('north', 'east', 'south', 'west'), height=6, lantern=True) west = Pavilion(Polygon.chamfered(13, rng.choice((13, 17)), 2), '/land', 'workshop', ('north', 'south'), height=5) east = Pavilion(Polygon.chamfered(rng.choice((13, 17)), 13, 2), '/land', 'kitchen', ('west', 'south'), height=rng.choice((5, 6))) rooms = [RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')] if rng.choice((False, True)): rooms.append(RoomSpec(0, 1, 0, 'storage')) lodge = Building(Blueprint(tuple(rooms), bay=9, porch=True), '/land') vertices = [Vertex('hall', hub, Frame((23, 0, 23))), Vertex('workshop', west, Frame((0, 0, 0))), Vertex('kitchen', east, Frame((51, 0, 0))), Vertex('lodge', lodge, Frame((48, 0, 51)))] edges = [Edge('hall', 'north', 'workshop', 'south', covered=True), Edge('hall', 'east', 'kitchen', 'west', rise=rng.choice((0, 1))), Edge('hall', 'south', 'lodge', 'street', covered=True)] if rng.choice((False, True)): vertices.append(Vertex('archive', Pavilion(Polygon.chamfered(13, 13, 2), '/land', 'library', ('east',)), Frame((0, 0, 51)))) edges.append(Edge('hall', 'west', 'archive', 'east', rise=1)) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(tuple(vertices), tuple(edges), '/land', DOMAIN, boundary) def perimeter_cluster(seed=0): rng = Scope(seed).stream('perimeter-graph') widths = (rng.choice((17, 21, 25)), rng.choice((13, 17)), rng.choice((13, 17))) market = Pavilion(Polygon.chamfered(widths[0], 13, 2), '/land', 'workshop', ('north', 'east', 'south'), height=5, roof_run=3) reading = Pavilion(Polygon.chamfered(widths[1], 17, 3), '/land', 'library', ('north', 'south'), height=6, lantern=rng.choice((True, False))) dining = Pavilion(Polygon.chamfered(widths[2], 13, 2), '/land', 'living', ('east', 'west'), height=5) vertices = (Vertex('market', market, Frame((0, 0, 0))), Vertex('reading', reading, Frame((50, 0, 10))), Vertex('dining', dining, Frame((20, 0, 57)))) edges = (Edge('market', 'east', 'reading', 'north', via=((40, -5),), covered=False, rise=1), Edge('reading', 'south', 'dining', 'east', covered=True), Edge('dining', 'west', 'market', 'south', via=((9, 42),), rise=rng.choice((0, 1)))) boundary = Polyline.bezier(((-12, 0), (-30, 120), (115, 120), (84, 0))) return Campus(vertices, edges, '/land', DOMAIN, boundary) def extension_scene(program=branching_campus, seed=0, environment_seed=0): environment = frozen_site(environment_seed) original = semantic_digest(environment) scene = environment.fork(seed=seed) scene.place('campus', program(seed)) scene.finalize() if semantic_digest(environment) != original: raise AssertionError('Frozen input mutated') return scene
hearth_extensions/sites.py · 38 行 · 原文件
# Accessible platforms with measured supports and oriented edge ports. from dataclasses import dataclass from hearth import Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Child, Port, Rule, Domain from hearth.blocks import state_of from hearth.adapters.site import Foundation, SiteLimits, survey from .geometry import Polygon, bounds2 from .circulation import Surface DIRECTIONS = {'north': (0, -1, 0), 'east': (1, 0, 1), 'south': (0, 1, 2), 'west': (-1, 0, 3)} def edge_frames(width, depth, height): return {'north': Frame((width // 2, height, 0), 0), 'east': Frame((width - 1, height, depth // 2), 1), 'south': Frame((width // 2, height, depth - 1), 2), 'west': Frame((0, height, depth // 2), 3)} @dataclass(frozen=True) class Platform: terrain: str width: int = 9 depth: int = 9 freeboard: int = 1 def capability(self): return Capability('extension.platform', ('platform', 'composite', 'access'), offers=('access',), inputs={'width': Domain(5, 27), 'depth': Domain(5, 27), 'freeboard': Domain(1, 3)}) def negotiate(self, ctx, parameters): footprint = tuple((x, z) for x in range(self.width) for z in range(self.depth)) samples = survey(ctx, footprint) y = samples['floor'] + self.freeboard - 1 region = bounds2(footprint, min(v[0] for v in samples['samples'].values()) - 1, y + 3) ports = tuple(Port(k, 'access', f, f.box(Box((-2, -1, 0), (2, 1, 0))), 8) for k, f in edge_frames(self.width, self.depth, y + 1).items()) return Contract(region, ports=ports, decisions={'floor': y, 'footprint': footprint, 'strategy': samples['strategy']}, rules=(Rule('route', tuple(f.frame.origin for f in ports), region, phase='complete'),)) def realize(self, ctx, contract): d = contract.decisions p = Plan(children=[Child('foundation', Foundation(tuple(d['footprint']), d['floor'], d['strategy']), bindings=(Binding(self.terrain, 'construction', 'fill'),)), Child('deck', Surface(tuple((x, d['floor'], z) for x, z in d['footprint']), role='platform'))]) return p
examples/__init__.py · 1 行 · 原文件
# Runnable public-API examples and explicit assessment tools.
examples/assess.py · 13 行 · 原文件
# Explicit finite batch output, never an unnoticed unit-test side effect. import argparse import json from pathlib import Path from hearth.assessment import run_corpus if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('reports/corpus')) p.add_argument('--artifacts', action='store_true') a = p.parse_args() print(json.dumps(run_corpus(a.output, a.seed, a.artifacts), indent=2))
examples/building.py · 13 行 · 原文件
# Run any of the three short room-composition programs with an explicit seed. import argparse from pathlib import Path from hearth.programs import PROGRAMS, building_scene from hearth.persistence import export_scene if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('program', choices=PROGRAMS) p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/building.litematic')) a = p.parse_args() export_scene(building_scene(PROGRAMS[a.program](a.seed), a.seed), a.output)
examples/courtyard.py · 25 行 · 原文件
# New composition written after the core abstractions; no library changes needed. import argparse from pathlib import Path from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene from hearth.randomness import Scope from hearth.persistence import export_scene def build(seed): rng = Scope(seed).stream('courtyard') ring = ((0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 1)) functions = ('living', 'library', 'workshop', 'storage', 'kitchen', 'bedroom', 'bedroom', 'storage') rooms = [RoomSpec(x, z, 0, purpose) for (x, z), purpose in zip(ring, functions)] for x, z in rng.sample(((0, 0), (2, 0), (0, 2), (2, 2)), rng.choice((1, 2))): rooms.append(RoomSpec(x, z, 1, 'bedroom')) return building_scene(Blueprint(tuple(rooms), bay=9, porch=True, roof_axis='auto'), seed) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/courtyard.litematic')) a = p.parse_args() export_scene(build(a.seed), a.output)
examples/extension.py · 27 行 · 原文件
# Substitute independent lighting and encapsulate an independently packaged room. import argparse from pathlib import Path from hearth import Scene, Box, Frame from hearth.kernel import Registry from hearth.components.interior import Light from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene from hearth.persistence import export_scene from extension_demo import Pendant, ReadingSuite def build(seed): registry = Registry() registry.register(Light()) registry.register(Pendant()) lights = registry.select('room-light') design = Blueprint((RoomSpec(0, 0, 0, 'library'), RoomSpec(0, 0, 1, 'bedroom')), light_component=lights[seed % len(lights)]) return building_scene(design, seed) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/extension.litematic')) a = p.parse_args() export_scene(build(a.seed), a.output)
examples/extension_assess.py · 14 行 · 原文件
# Rerun the retained extension sampling policy without altering first-phase evidence. import argparse import json from pathlib import Path from hearth_extensions.assessment import run if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('reports/extension-corpus/final')) p.add_argument('--artifacts', action='store_true') p.add_argument('--samples', type=Path, default=Path('samples/extensions')) a = p.parse_args() print(json.dumps(run(a.output, a.seed, a.artifacts, a.samples), indent=2))
examples/extension_audit.py · 94 行 · 原文件
# Replay the frozen extension manifest and compare complete structural records and actual NBT. import argparse import json from pathlib import Path import subprocess import sys import tempfile from hearth import Scene from hearth.environment import Terrain from hearth.environment.fields import from_expression from hearth.persistence import load_scene, semantic_digest, encode from hearth_extensions.assessment import PROBE_DOMAIN, freeze_probe, connector_scene, boundary_scene, hall_scene from hearth_extensions.programs import extension_scene, branching_campus, perimeter_cluster def replay(row): """Reconstruct one explicit assessment recipe from its recorded inputs. Args: row (dict): A selected row in the extension replay manifest. Returns: Scene: A validated, freshly generated scene without filesystem output. """ inputs = row['inputs'] seed = inputs['structure_seed'] group = row['label'].split('-')[0] if group == 'connector': environment = freeze_probe(inputs['environment']['environment_seed']) if semantic_digest(environment) != inputs['environment']['digest']: raise AssertionError('Frozen terrain changed') return connector_scene(environment, seed) if group == 'boundary': environment = Scene(inputs['environment_seed'], domain=PROBE_DOMAIN) environment.place('land', Terrain(PROBE_DOMAIN, from_expression(inputs['expression']))) environment.finalize() return boundary_scene(environment, seed) if group == 'hall': return hall_scene(seed, inputs['environment_seed']) programs = {'campus': branching_campus, 'perimeter': perimeter_cluster} return extension_scene(programs[inputs['program']], seed, inputs['environment_seed']) def audit(seed: int, manifest: Path, output: Path, cli: bool = False): """Check replay identity, structural graphs, queries, inventories and optional original CLI. Args: seed (int): Root assessment seed, used to verify the selected manifest. manifest (Path): Explicit batch artifact manifest. output (Path): Audit report destination. cli (bool): Also exercise the unchanged no-argument and seed-1 CLI in a temporary directory. Returns: dict: Completed audit with every selected input and result. """ entries = json.loads(manifest.read_text()) if entries[0]['inputs']['environment']['environment_seed'] != seed * 100: raise ValueError('Root seed does not match the selected assessment manifest') rows = [] for row in entries: native = replay(row) restored = load_scene(Path(row['artifact'])) assert semantic_digest(native) == row['digest'] == semantic_digest(restored), row['label'] for field in ('nodes', 'relations', 'dependencies', 'operations', 'port_uses', 'displaced'): assert encode(getattr(native, field)) == encode(getattr(restored, field)), (row['label'], field) assert native.reverse == restored.reverse, row['label'] assert {p: c.nbt for p, c in native.blocks.items()} == {p: c.nbt for p, c in restored.blocks.items()} points = [min(native.cells(n)) for n in sorted(native.nodes) if native.cells(n)] for point in points: assert native.inspect(point) == restored.inspect(point), (row['label'], point) rows.append({'label': row['label'], 'digest': row['digest'], 'nodes': len(native.nodes), 'blocks': len(native.blocks), 'component_queries': len(points), 'inventories': sum(c.nbt is not None for c in native.blocks.values()), 'verified': True}) cli_rows = [] if cli: root = Path(__file__).resolve().parents[1] with tempfile.TemporaryDirectory(dir=root / 'test', prefix='tmp-extension-cli-') as directory: temporary = Path(directory) for name, arguments, filename in (('default', [], 'output.litematic'), ('seed-1', ['--seed', '1', '--output', str(temporary / 'explicit path with spaces.litematic')], 'explicit path with spaces.litematic')): subprocess.run([sys.executable, str(root / 'generate.py'), *arguments], cwd=temporary, check=True) scene = load_scene(temporary / filename) cli_rows.append({'command': name, 'seed': scene.seed, 'blocks': len(scene.blocks), 'nodes': len(scene.nodes), 'digest': semantic_digest(scene), 'verified': True}) result = {'root_seed': seed, 'manifest': str(manifest), 'verified': True, 'artifacts': rows, 'original_cli': cli_rows} output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps(result, indent=2)) return result if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--manifest', type=Path, default=Path('samples/extensions/replay-manifest.json')) parser.add_argument('--output', type=Path, default=Path('reports/extension-corpus/artifact-audit.json')) parser.add_argument('--cli', action='store_true') args = parser.parse_args() audit(args.seed, args.manifest, args.output, args.cli)
examples/extension_generate.py · 23 行 · 原文件
# Explicit client selection for new graph compositions, preserving the original default CLI. import argparse from pathlib import Path from hearth.persistence import export_scene, semantic_digest from hearth_extensions.programs import extension_scene, branching_campus, perimeter_cluster PROGRAMS = {'campus': branching_campus, 'perimeter': perimeter_cluster} def main(): parser = argparse.ArgumentParser() parser.add_argument('program', choices=PROGRAMS) parser.add_argument('--seed', type=int, default=0) parser.add_argument('--environment-seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('samples/extensions/composition.litematic')) args = parser.parse_args() scene = extension_scene(PROGRAMS[args.program], args.seed, args.environment_seed) export_scene(scene, args.output) print(args.output, semantic_digest(scene), len(scene.blocks), 'blocks', len(scene.nodes), 'instances') if __name__ == '__main__': main()
examples/extension_inspection.py · 34 行 · 原文件
# Inspect real extension structures and verify the same public queries after reload. import argparse import json from pathlib import Path import hearth_extensions from hearth.persistence import load_scene, export_scene def inspect(source, seed, output): scene = load_scene(source) if scene.seed != seed: raise ValueError('Explicit seed must match input artifact') queries = [] for tag in ('deck', 'window', 'fixture'): candidate = next((n for n in scene.nodes.values() if n.capability and tag in n.capability.tags and scene.cells(n.path)), None) if candidate is None: continue point = min(scene.cells(candidate.path)) queries.append({'tag': tag, 'query': scene.inspect(point), 'exact_cell_count': len(scene.cells(candidate.path)), 'descendant_cell_count': len(scene.cells(candidate.path, True))}) export_scene(scene, output) restored = load_scene(output) for entry in queries: assert restored.inspect(entry['query']['position']) == entry['query'] assert len(restored.cells(entry['query']['instance'])) == entry['exact_cell_count'] print(json.dumps({'source': str(source), 'seed': seed, 'verified_after_reload': True, 'queries': queries}, default=lambda v: sorted(v), indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path, required=True) p.add_argument('--output', type=Path, default=Path('samples/extensions/inspection.litematic')) a = p.parse_args() inspect(a.input, a.seed, a.output)
examples/extension_replay.py · 49 行 · 原文件
# Cross-process extension replay with full semantic graph and query comparisons. import argparse import json import os from pathlib import Path import subprocess import sys import tempfile CHILD = ''' import sys,json,hashlib from pathlib import Path from hearth_extensions.programs import extension_scene,perimeter_cluster from hearth_extensions.assessment import signatures from hearth.persistence import export_scene,load_scene,semantic_digest,encode scene=extension_scene(perimeter_cluster,int(sys.argv[1]),int(sys.argv[2])) p=next(p for p,c in sorted(scene.blocks.items()) if c.state=='minecraft:glass' and 'facade' in c.owner) query=scene.inspect(p) nodes=json.dumps(encode(scene.nodes),sort_keys=True,separators=(',',':')) output=Path(sys.argv[3]);export_scene(scene,output) restored=load_scene(output) assert restored.inspect(p)==query assert encode(restored.nodes)==encode(scene.nodes) print(json.dumps({'digest':semantic_digest(scene),'principal':signatures(scene)['principal_signature'],'nodes_digest':hashlib.sha256(nodes.encode()).hexdigest(),'nodes':len(scene.nodes),'glass_query':query},default=lambda v:sorted(v),sort_keys=True)) ''' def replay(seed, environment_seed, output): root = Path(__file__).resolve().parents[1] rows = [] with tempfile.TemporaryDirectory(dir=root / 'test', prefix='tmp-extension-replay-') as temporary: for hash_seed in ('5', '918273'): artifact = Path(temporary) / f'seed {seed} hash {hash_seed}.litematic' result = subprocess.run([sys.executable, '-c', CHILD, str(seed), str(environment_seed), str(artifact)], cwd=root, env=dict(os.environ, PYTHONHASHSEED=hash_seed), capture_output=True, text=True, check=True) rows.append({'PYTHONHASHSEED': hash_seed, 'result': json.loads(result.stdout)}) if rows[0]['result'] != rows[1]['result']: raise AssertionError('Extension replay mismatch') output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps({'verified': True, 'seed': seed, 'environment_seed': environment_seed, 'runs': rows}, indent=2)) print('Verified extension content, nodes, signatures, glass query and paired reload across two Python hash seeds.') if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=3) p.add_argument('--environment-seed', type=int, default=7) p.add_argument('--output', type=Path, default=Path('reports/extension-corpus/replay.json')) a = p.parse_args() replay(a.seed, a.environment_seed, a.output)
examples/extension_views.py · 63 行 · 原文件
# Render extension artifact pairs and explicitly labeled geometry-only inspection sections. import argparse import json from pathlib import Path import subprocess import sys import hearth_extensions from hearth.persistence import load_scene, companion_path from examples.preview import render, CUTAWAY def views(seed, source, output, size=1100, sections=False, focus=None): scene = load_scene(source) if scene.seed != seed: raise ValueError('Explicit seed must match artifact') output.mkdir(parents=True, exist_ok=True) records = [] offset = list(json.loads(companion_path(source).read_text())['offset']) render_source = source if focus: box = scene.view.contract(focus).envelope for index, axis in enumerate('xyz'): for keep_above, limit in ((False, box.hi[index]), (True, box.lo[index] - 1)): target = output / f'focus-{axis}-{int(keep_above)}.litematic' command = [sys.executable, str(CUTAWAY), '--input', str(render_source), '--output', str(target), '--axis', axis, '--max', str(limit - offset[index]), '--name', 'focus-preview'] if keep_above: command.append('--keep-above') subprocess.run(command, check=True) if keep_above: offset[index] = limit + 1 render_source = target for label, azimuth, elevation in (('front', 215, 36), ('rear', 35, 32), ('side', 120, 27)): target = output / (label + '.png') render(render_source, target, azimuth, elevation, size, 3.6) records.append({'source': str(source), 'seed': seed, 'label': label, 'azimuth': azimuth, 'elevation': elevation, 'image': str(target), 'focus': focus, 'geometry_preview_only': focus is not None}) if sections: halls = [n for n in scene.nodes.values() if n.type == 'extension.pavilion'] links = [n for n in scene.nodes.values() if n.type in ('extension.bridge', 'extension.gallery')] height = max(n.frame.origin[1] + n.contract.decisions['floor'] + 3 for n in halls) if halls else max(p[1] for n in links for p in scene.cells(n.path + '/deck')) + 1 cuts = [('floor-cut', 'y', height, 215, 65)] if links: points = scene.cells(links[0].path + '/deck') cuts.append(('connection-section', 'x', (min(p[0] for p in points) + max(p[0] for p in points)) // 2, 110, 20)) for label, axis, world, azimuth, elevation in cuts: target = output / (label + '.litematic') limit = world - offset['xyz'.index(axis)] subprocess.run([sys.executable, str(CUTAWAY), '--input', str(render_source), '--output', str(target), '--axis', axis, '--max', str(limit), '--name', label], check=True) image = output / (label + '.png') render(target, image, azimuth, elevation, size, 3.6) records.append({'source': str(source), 'seed': seed, 'label': label, 'axis': axis, 'world_cut': world, 'export_local_cut': limit, 'geometry_preview_only': True, 'image': str(image), 'focus': focus}) (output / 'views.json').write_text(json.dumps(records, indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path, required=True) p.add_argument('--output', type=Path, required=True) p.add_argument('--size', type=int, default=1100) p.add_argument('--sections', action='store_true') p.add_argument('--focus', help='Optional public component path for a geometry-only detail crop') a = p.parse_args() views(a.seed, a.input, a.output, a.size, a.sections, a.focus)
examples/gallery.py · 25 行 · 原文件
# A later client composes a public gallery with connected reading and work rooms. import argparse from pathlib import Path from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene from hearth.randomness import Scope from hearth.persistence import export_scene from extension_demo import Pendant def build(seed): rng = Scope(seed).stream('gallery-layout') length = rng.choice((2, 3)) rooms = [RoomSpec(0, z, 0, 'library' if z % 2 else 'living') for z in range(length)] rooms.append(RoomSpec(1, length - 1, 0, 'workshop')) rooms.append(RoomSpec(0, length - 1, 1, 'bedroom')) return building_scene(Blueprint(tuple(rooms), bay=9, roof_axis='z', light_component=Pendant()), seed) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/gallery.litematic')) a = p.parse_args() export_scene(build(a.seed), a.output)
examples/inspection.py · 28 行 · 原文件
# Generate a real glass query, highlight membership, export and repeat after reload. import argparse import json from pathlib import Path from hearth.programs import dwelling, building_scene from hearth.persistence import export_scene, load_scene from hearth.blocks import name_of def demonstrate(seed, output): scene = building_scene(dwelling(seed), seed) point = next(p for p, c in sorted(scene.blocks.items()) if name_of(c.state) == 'glass' and 'room-' in c.owner) query = scene.inspect(point) print(json.dumps(query, default=lambda v: sorted(v), indent=2)) print('Exact current component cells:', sorted(scene.cells(query['instance']))) export_scene(scene, output) restored = load_scene(output) assert restored.inspect(point) == query print('Reloaded query identical; world coordinate:', point) return query if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('samples/inspection.litematic')) a = p.parse_args() demonstrate(a.seed, a.output)
examples/preview.py · 62 行 · 原文件
# Render labeled exterior views and geometry-only slices with the optional proc tools. import argparse import json from pathlib import Path import subprocess import sys from hearth.persistence import export_scene, load_scene, companion_path from hearth.programs import settlement_scene RENDER = Path('/opt/tools/render_schematic.mjs') CUTAWAY = Path('/opt/tools/cutaway.py') VITE = Path('/work/generator/MCRender/node_modules/.bin/vite-node') def render(source, target, azimuth, elevation, size, radius): subprocess.run(['xvfb-run', '-a', str(VITE), '--script', str(RENDER), '--', '--input', str(source), '--output', str(target), '--size', str(size), '--azimuth', str(azimuth), '--elevation', str(elevation), '--radius', str(radius), '--fov', '30', '--ambient', '0.8'], check=True) def preview(seed, source, output, size=1200, cutaways=False): output.mkdir(parents=True, exist_ok=True) if source is None: source = output / 'source.litematic' export_scene(settlement_scene(seed), source) scene = load_scene(source) if scene.seed != seed: raise ValueError(f'--seed {seed} does not match the input artifact seed {scene.seed}') views = [('front', 210, 28, 3.5), ('rear', 30, 26, 3.5)] records = [] for label, azimuth, elevation, radius in views: target = output / (label + '.png') render(source, target, azimuth, elevation, size, radius) records.append({'source': str(source), 'seed': seed, 'label': label, 'image': str(target), 'azimuth': azimuth, 'elevation': elevation}) if cutaways: building = next(n for n in scene.nodes.values() if n.type == 'building.rooms') floor = building.contract.decisions['floor'] + building.frame.origin[1] offset = json.loads(companion_path(source).read_text())['offset'] cuts = [('floor-cut', 'y', floor + 4 - offset[1], 210, 64)] stair = next((n for n in scene.nodes.values() if n.type == 'circulation.stair'), None) if stair is not None: occupied = scene.cells(stair.path) # Cut beside the actual flight, including flights in a remote wing. axis = min((0, 2), key=lambda i: max(p[i] for p in occupied) - min(p[i] for p in occupied)) limit = max(p[axis] for p in occupied) + 1 - offset[axis] cuts.append(('stair-cut', 'xz'[axis // 2], limit, 110 if axis == 0 else 20, 26)) for label, axis, limit, azimuth, elevation in cuts: cut = output / (label + '.litematic') subprocess.run([sys.executable, str(CUTAWAY), '--input', str(source), '--output', str(cut), '--axis', axis, '--max', str(limit), '--name', label], check=True) target = output / (label + '.png') render(cut, target, azimuth, elevation, size, 3.2) records.append({'source': str(source), 'seed': seed, 'label': label, 'axis': axis, 'export_local_cut': limit, 'image': str(target), 'geometry_preview_only': True}) (output / 'views.json').write_text(json.dumps(records, indent=2)) if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--input', type=Path) p.add_argument('--output', type=Path, default=Path('previews/default')) p.add_argument('--size', type=int, default=1200) p.add_argument('--cutaways', action='store_true') a = p.parse_args() preview(a.seed, a.input, a.output, a.size, a.cutaways)
examples/prototype.py · 33 行 · 原文件
# Run the small terrain, planting and attached-window composition before full buildings. import argparse from pathlib import Path from hearth import Scene, Box, Frame, Binding from hearth.environment import Terrain, gradient, wave from hearth.components.primitives import Wall, Window, Grass, Tree from hearth.adapters.site import Foundation from hearth.composition import encapsulate from hearth.kernel import Plan, Child from hearth.persistence import export_scene def build(seed=0): scene = Scene(seed, domain=Box((-8, -3, -8), (20, 24, 20))) scene.place('land', Terrain(scene.domain, gradient(base=2) + wave(0.6, 0.2, 0.2))) def facade(ctx): return Plan(children=[Child('wall', Wall(thickness=2)), Child('window', Window(), frame=Frame((3, 1, 0)), bindings=(Binding(ctx.path + '/wall', 'infill'),))]) scene.place('footing', Foundation.rectangular(9, 2, 4), bindings=(Binding('/land', 'construction', 'fill'),)) scene.place('facade', encapsulate('facade', Box((-1, 0, -2), (10, 6, 3)), facade), frame=Frame((0, 4, 0))) y = scene.view.elevation(13, 9) + 1 scene.place('grass', Grass(True), frame=Frame((13, y, 9)), bindings=(Binding('/land', 'planting', 'plant'),)) scene.place('tree', Tree(), frame=Frame((13, y, 9)), bindings=(Binding('/land', 'planting', 'plant'), Binding('/grass', 'replacement', 'plant'))) return scene.finalize() if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--seed', type=int, default=0) parser.add_argument('--output', type=Path, default=Path('samples/prototype.litematic')) args = parser.parse_args() export_scene(build(args.seed), args.output)
examples/verify_replay.py · 35 行 · 原文件
# Explicit cross-process hash-seed replay and paired metadata verification. import argparse import json import os from pathlib import Path import subprocess import sys import tempfile from hearth.persistence import load_scene, semantic_digest from hearth.space import Box def verify(seed, output): root = Path(__file__).resolve().parents[1] rows = [] with tempfile.TemporaryDirectory(dir=root / 'test', prefix='tmp-replay-') as temporary: for hash_seed in ('3', '8675309'): path = Path(temporary) / f'seed {seed} hash {hash_seed}.litematic' env = dict(os.environ, PYTHONHASHSEED=hash_seed) subprocess.run([sys.executable, str(root / 'generate.py'), '--seed', str(seed), '--output', str(path)], check=True, cwd=root, env=env) scene = load_scene(path) rows.append({'seed': seed, 'PYTHONHASHSEED': hash_seed, 'digest': semantic_digest(scene), 'bounds': [Box.enclosing(scene.blocks).lo, Box.enclosing(scene.blocks).hi], 'blocks': len(scene.blocks), 'buildings': sum(n.type == 'building.rooms' for n in scene.nodes.values())}) if rows[0]['digest'] != rows[1]['digest'] or rows[0]['bounds'] != rows[1]['bounds']: raise AssertionError('Cross-process replay mismatch') output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps({'verified': True, 'runs': rows}, indent=2)) return rows if __name__ == '__main__': p = argparse.ArgumentParser() p.add_argument('--seed', type=int, default=0) p.add_argument('--output', type=Path, default=Path('reports/replay.json')) a = p.parse_args() verify(a.seed, a.output)
extension_demo/__init__.py · 38 行 · 原文件
# Independent component package; imports only Hearth's public protocols and components. from dataclasses import dataclass from hearth.kernel import Capability, Contract, Plan, Child, Rule, Port from hearth.space import Box, Frame from hearth.blocks import state_of, slab from hearth.components.interior import Room @dataclass(frozen=True) class Pendant: def capability(self): return Capability('extension.pendant', ('light', 'room-light'), guarantees=('actual light source',)) def negotiate(self, context, parameters): return Contract(Box((0, 0, 0), (0, 1, 0)), rules=(Rule('expected', ((0, 0, 0),), data={'names': ['ochre_froglight']}),)) def realize(self, context, contract): plan = Plan() plan.block((0, 0, 0), state_of('ochre_froglight', axis='y')) plan.block((0, 1, 0), slab('dark_oak')) return plan @dataclass(frozen=True) class ReadingSuite: width: int = 11 def capability(self): return Capability('extension.reading-suite', ('room', 'habitable', 'composite'), offers=('access',), guarantees=('lit', 'furnished', 'enclosed', 'reachable')) def negotiate(self, context, parameters): entry = (self.width // 2, 1, 0) port = Port('north', 'access', Frame(entry), Box(entry, (entry[0], 2, 0)), 10, delegate=('reading-room', 'north')) return Contract(Box((-1, 0, -1), (self.width, 9, self.width)), ports=(port,)) def realize(self, context, contract): return Plan(children=[Child('reading-room', Room('library', self.width, self.width, light_component=Pendant()))])
test/conftest.py · 13 行 · 原文件
# Tests keep transient artifacts under test/ and remove them after each test. import sys import tempfile from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).parents[1])) @pytest.fixture def work(): with tempfile.TemporaryDirectory(dir=Path(__file__).parent, prefix='tmp-') as name: yield Path(name)
test/test_contracts_provenance.py · 279 行 · 原文件
# Mutation, sharing, phases, rotations, extension and synchronized provenance tests. from dataclasses import dataclass, replace import json import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Grant, Port, Rule, Plan, Child, Limits, SearchExhausted from hearth.blocks import state_of from hearth.components.primitives import Volume, Assembly, Window, Wall, Grass, Tree, Pool from hearth.kernel.scene import Cell from hearth.persistence import export_scene, load_scene, semantic_digest from hearth.randomness import Scope from hearth.composition import encapsulate, repeat, arrange, scatter from extension_demo import Pendant, ReadingSuite @dataclass(frozen=True) class Editable: def capability(self): return Capability('editable', ('support',)) def negotiate(self, c, p): b = Box((0, 0, 0), (0, 0, 0)) return Contract(b, (Port('edit', 'adjust', Frame(), b, 10, 'edit'), Port('shared', 'shared-support', Frame(), b, 4)), (Grant('edit', b, ('adjust', 'excavate'), ('editor',), 1),)) def realize(self, c, b): p = Plan() p.block((0, 0, 0), state_of('oak_log', axis='y')) return p @dataclass(frozen=True) class Editor: material: str preserve: bool = True def capability(self): return Capability('editor', ('editor',)) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((0, 0, 0), self.material, preserve_owner=self.preserve) return p def test_adjustment_membership_history_deletion_and_reload(work): s = Scene() s.place('owner', Editable()) s.place('adjust', Editor(state_of('oak_log', axis='x')), bindings=(Binding('/owner', 'edit', 'adjust'),)) q = s.inspect((0, 0, 0)) assert q['instance'] == '/owner' and q['operation']['component'] == '/adjust' assert s.cells('/adjust') == frozenset() export_scene(s, work / 'adjust.litematic') r = load_scene(work / 'adjust.litematic') assert r.inspect((0, 0, 0)) == q s.remove('/adjust') assert s.inspect((0, 0, 0))['state'] == state_of('oak_log', axis='y') s.place('erase', Editor(state_of('air'), False), bindings=(Binding('/owner', 'edit', 'excavate'),)) assert s.inspect((0, 0, 0))['instance'] is None and not s.cells('/owner') s.remove('/erase') assert s.cells('/owner') == {(0, 0, 0)} def test_identical_blocks_do_not_grant_sharing_and_explicit_shared_support(): s = Scene() s.place('support', Editable()) s.place('bridge', Assembly('bridge', Box((0, 0, 0), (2, 2, 2)), ())) with pytest.raises(ContractError, match='write-authority'): s.place('intruder', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('oak_log', axis='y'))) s.share((0, 0, 0), '/bridge', '/support', 'shared') assert s.cells('/bridge', shared=True) == {(0, 0, 0)} assert ('/bridge', 'shares_support', '/support') in s.inspect((0, 0, 0))['related'] with pytest.raises(ContractError, match='support'): s.remove('/support') s.remove('/bridge') assert not s.inspect((0, 0, 0))['shared'] def test_partial_tall_plant_replacement_atomicity(): from hearth.environment import Terrain, constant s = Scene(domain=Box((-2, -2, -2), (4, 15, 4))) s.place('terrain', Terrain(s.domain, constant(0))) s.place('grass', Grass(True), frame=Frame((0, 1, 0))) @dataclass class Pruner: def capability(self): return Capability('pruner', ('tree',)) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((0, 0, 0), state_of('oak_log', axis='y')) return p snapshot = (semantic_digest(s), set(s.nodes), set(s.relations), dict(s.port_uses), list(s.dependencies)) with pytest.raises(ContractError, match='whole-object'): s.place('prune', Pruner(), frame=Frame((0, 1, 0)), bindings=(Binding('/grass', 'replacement', 'plant'),)) assert snapshot == (semantic_digest(s), set(s.nodes), set(s.relations), dict(s.port_uses), list(s.dependencies)) @pytest.mark.parametrize('turn', range(4)) def test_rotated_attachment_ports_claims_membership(turn, work): frame = Frame((-13, 5, 17), turn) def compose(c): return Plan(children=[Child('base', Volume(Box((0, -1, 0), (8, -1, 2)), state_of('stone'))), Child('wall', Wall(thickness=3)), Child('a', Window(), frame=Frame((2, 1, 0)), bindings=(Binding(c.path + '/wall', 'infill'),)), Child('b', Window(shutters=False), frame=Frame((6, 1, 0)), bindings=(Binding(c.path + '/wall', 'infill'),))]) s = Scene(31) s.place('house', encapsulate('house', Box((-1, -1, -2), (10, 8, 4)), compose), frame=frame) a, b = frame.point((2, 1, 0)), frame.point((6, 1, 0)) assert s.inspect(a)['instance'] != s.inspect(b)['instance'] assert [n['type'] for n in s.inspect(a)['chain']] == ['window.shuttered', 'wall.framed', 'house'] assert s.nodes['/house/wall'].contract.ports[0].frame.turn == turn assert all(s.nodes['/house/a'].contract.envelope.contains(p) for p in s.cells('/house/a')) export_scene(s, work / 'rotated.litematic') assert load_scene(work / 'rotated.litematic').inspect(a) == s.inspect(a) def test_completion_obligation_and_late_decoration(): s = Scene() b = Box((0, 0, 0), (3, 4, 3)) s.place('unfinished', Assembly('room', b, (), (Rule('light', ((1, 1, 1),), b, phase='complete'),)), complete=False) with pytest.raises(ContractError): s.finalize() s.place('lamp', Pendant(), frame=Frame((1, 2, 1))) s.finish_scope('/unfinished') s.finalize() with pytest.raises(ContractError, match='lighting'): s.remove('/lamp') def test_extension_low_level_composite_and_nested_protocol(): s = Scene(4) room = ReadingSuite() wrapper = encapsulate('independent-suite', Box((-2, 0, -2), (14, 11, 14)), lambda c: Plan(children=[Child('suite', room)])) s.place('hall', wrapper) s.finalize() assert any(n.type == 'extension.pendant' for n in s.nodes.values()) assert any(n.type == 'extension.reading-suite' for n in s.nodes.values()) def test_independent_order_and_failed_alternative_streams(): @dataclass class Seeded: def capability(self): return Capability('seeded', ()) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (2, 0, 0))) def realize(self, c, b): p = Plan() p.block((c.rng('geometry').randrange(3), 0, 0), state_of('stone')) return p a, b = Scene(81), Scene(81) for scene, order in ((a, ('one', 'two')), (b, ('two', 'one'))): for key in order: scene.place(key, Seeded(), frame=Frame((10 if key == 'two' else 0, 0, 0))) assert semantic_digest(a) == semantic_digest(b) before = a.cells('/one') with pytest.raises(SearchExhausted): a.choose('failed', [Child('x', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('dirt')))]) a.place('planter', Seeded(), frame=Frame((20, 0, 0))) assert a.cells('/one') == before c = Scene(81) c.place('one', Seeded(), seed=123) assert c.nodes['/one'].scope.seed == 123 def test_regeneration_restores_displaced_terrain_and_no_stale_cells(): from hearth.environment import Terrain, constant s = Scene(domain=Box((-2, -3, -2), (12, 20, 12))) s.place('land', Terrain(s.domain, constant(0))) before = semantic_digest(s) s.place('pool', Pool(), frame=Frame((1, 0, 1)), bindings=(Binding('/land', 'construction', 'excavate'),)) s.remove('/pool') assert semantic_digest(s) == before assert not any('/pool' in (a, c) for a, b, c in s.relations) def test_edit_limits_unknown_space_and_budget(): from hearth.environment import Terrain, constant s = Scene(domain=Box((-3, -3, -3), (12, 20, 12))) s.place('land', Terrain(s.domain, constant(0), edit_limit=1)) with pytest.raises(ContractError, match='edit-limit'): s.place('pool', Pool(), bindings=(Binding('/land', 'construction', 'excavate'),)) with pytest.raises(ContractError, match='unknown-space'): s.view.state((100, 1, 1)) s = Scene(limits=Limits(blocks=1)) with pytest.raises(ContractError, match='block-budget'): s.place('large', Volume(Box((0, 0, 0), (3, 0, 0)), state_of('stone'))) assert not s.nodes and not s.blocks def test_attachment_membership_across_encapsulation_boundaries(): s = Scene() s.place('house', Assembly('house', Box((-2, -1, -2), (12, 8, 5)), (Child('base', Volume(Box((0, -1, 0), (8, -1, 0)), state_of('stone'))), Child('wall', Wall())))) s.place('facade-window', Window(), frame=Frame((3, 1, 0)), bindings=(Binding('/house/wall', 'infill'),)) assert s.cells('/facade-window') <= s.cells('/house/wall', descendants=True) assert s.cells('/facade-window') <= s.cells('/house', descendants=True) assert s.inspect((3, 1, 0))['chain'][-1]['id'] == '/house' with pytest.raises(ContractError): s.remove('/house') s.regenerate('/house', dependents=('/facade-window',)) assert s.inspect((3, 1, 0))['instance'] == '/facade-window' def test_public_readonly_contracts_and_protected_preference(): from hearth.components.constraints import Preserve from hearth.environment import Terrain, constant s = Scene(domain=Box((-3, -3, -3), (12, 20, 12)), preferences={'planting': constant(100)}) s.place('land', Terrain(s.domain, constant(0))) s.place('reserve', Preserve(Box((1, -2, 1), (3, 1, 3)))) assert s.view.preference('planting', (2, 0, 2)) == 100 with pytest.raises(ContractError, match='protected-region'): s.place('pool', Pool(), bindings=(Binding('/land', 'construction', 'excavate'),)) original = s.nodes['/land'].contract.decisions['water'] public = s.view.contract('/land') public.decisions['water'] = 99 assert s.nodes['/land'].contract.decisions['water'] == original def test_explicit_candidate_budget_exhaustion(): from hearth.kernel import Choice s = Scene(limits=Limits(search=1)) s.place('occupied', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) choice = Choice('choice', (Child('bad', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('dirt'))), Child('valid', Volume(Box((3, 0, 0), (3, 0, 0)), state_of('stone')))), lambda view, path: 0) with pytest.raises(SearchExhausted, match='search-budget'): s.compose_choice(choice) assert '/choice' not in s.nodes s.limits = replace(s.limits, search=2) s.compose_choice(choice) assert s.cells('/choice') == {(3, 0, 0)} def test_validator_extension_and_negotiated_domain(): from hearth.kernel import validator, Diagnostic @validator('test.actual-stone') def actual_stone(scene, node, rule): for p in rule.cells: if scene.inspect(p)['state'] != 'minecraft:stone': yield Diagnostic('test.actual-stone', node.path, p, 'Need actual stone') s = Scene() s.place('rule', Assembly('rule', Box((0, 0, 0), (0, 0, 0)), (Child('stone', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))),), (Rule('test.actual-stone', ((0, 0, 0),)),))) with pytest.raises(ContractError, match='test.actual-stone'): s.remove('/rule/stone') with pytest.raises(ContractError, match='input-domain'): s.place('bad-wall', Wall(width=100)) def test_forwarded_interfaces_discharge_after_scope_construction(): from hearth.kernel import Choice later = Assembly('later', Box((0, 0, 0), (0, 0, 0)), (Child('solid', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))),), ports=(Port('access', 'access', Frame(), Box((0, 0, 0), (0, 0, 0))),)) choice = Choice('first', (Child('one', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))), Child('two', Volume(Box((1, 0, 0), (1, 0, 0)), state_of('stone')))), lambda v, p: 0) wrapper = Assembly('wrapper', Box((0, 0, 0), (3, 1, 1)), (choice, Child('later', later, frame=Frame((3, 0, 0)))), ports=(Port('access', 'access', Frame((3, 0, 0)), Box((3, 0, 0), (3, 0, 0)), delegate=('later', 'access')),)) s = Scene() s.place('root', wrapper) s.finalize() assert s.view.port('/root', 'access').frame.origin == (3, 0, 0) def test_dense_export_budget_is_explicit(work): s = Scene(limits=Limits(export_volume=10)) s.place('line', Volume(Box((0, 0, 0), (10, 0, 0)), state_of('stone'))) with pytest.raises(ContractError, match='export-volume'): export_scene(s, work / 'too large.litematic') assert not (work / 'too large.litematic').exists()
test/test_extension_failures.py · 149 行 · 原文件
# Deliberate input and geometry damage for extension contracts and atomicity. from dataclasses import replace import copy import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import validate, Child, Plan, Choice, Limits from hearth.blocks import state_of from hearth.components.primitives import Volume from hearth.environment import Terrain, gradient, wave from hearth.persistence import semantic_digest, export_scene, load_scene, encode from hearth_extensions import Polyline, Endpoint, Link, Boundary, IlluminateBoundary, Platform from hearth_extensions.boundaries import BoundaryChain from hearth_extensions.circulation import Trestles from test_extension_geometry import bridge_scene def snapshot(s): return (semantic_digest(s), copy.deepcopy(encode(s.nodes)), copy.deepcopy(encode(s.relations)), copy.deepcopy(encode(s.dependencies)), copy.deepcopy(encode(s.operations)), copy.deepcopy(s.reverse), copy.deepcopy(s.port_uses), copy.deepcopy(s.events)) def damage(s, p): record = s.blocks.pop(p) s.reverse[record.owner].remove(p) @pytest.mark.parametrize('kind', ['support', 'guard', 'endpoint', 'headroom']) def test_broken_bridge_geometry_is_diagnosed(kind): s = bridge_scene() if kind == 'support': p = s.nodes['/link/supports'].contract.rules[0].cells[0] damage(s, p) expected = 'support' elif kind == 'guard': p = next(iter(s.cells('/link/guards'))) damage(s, p) expected = 'bridge-guard' elif kind == 'endpoint': a = s.view.port('/a', 'south').frame.origin p = (a[0], a[1] - 1, a[2]) damage(s, p) expected = 'reachability' else: p = next(r for r in s.nodes['/link'].contract.rules if r.kind == 'clear').cells[len(s.nodes['/link'].contract.decisions['deck']) // 2] before = snapshot(s) with pytest.raises(ContractError, match='clearance'): s.place('blocked', Volume(Box(p, p), state_of('stone'))) assert snapshot(s) == before return errors = validate(s, True) assert any(d.rule == expected and d.position is not None for d in errors) @pytest.mark.parametrize('fault', ['endpoint', 'frame', 'kind']) def test_invalid_connections_rollback_every_index(fault): s = bridge_scene() s.remove('/link') a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') pa = s.view.port('/a', 'south').frame.origin pb = s.view.port('/b', 'north').frame.origin curve = Polyline(((pa[0], pa[2]), (pa[0] + 3, pa[2]), (pb[0], pb[2]))) expected = 'endpoint-frame' if fault == 'endpoint': curve = Polyline(((pa[0] + 1, pa[2]), (pb[0], pb[2]))) expected = 'endpoint-disconnected' if fault == 'kind': a = Endpoint('/land', 'construction') expected = 'endpoint-kind' before = snapshot(s) with pytest.raises(ContractError, match=expected): s.place('bad', Link(a, b, '/land', curve=curve), bindings=(a.binding(), b.binding())) assert snapshot(s) == before def test_connection_permission_overflow_is_atomic(): s = Scene(0, domain=Box((-3, -4, -3), (12, 20, 12))) s.place('land', Terrain(s.domain, gradient(base=0), water_level=5, edit_limit=1)) before = snapshot(s) columns = ((2, 0, 2, 4, True), (3, 0, 2, 4, True)) with pytest.raises(ContractError, match='edit-limit'): s.place('piers', Trestles(columns), bindings=(Binding('/land', 'construction', 'fill'),)) assert snapshot(s) == before def test_connection_remove_and_regenerate_restore_water_and_membership(): s = bridge_scene() s.remove('/link') before = snapshot(s) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') comp = Link(a, b, '/land', rise=1) s.place('link', comp, bindings=(a.binding(), b.binding())) old = s.cells('/link', True) s.regenerate('/a', dependents=('/b', '/link'), replacements={'/link': replace(comp, covered=True, rise=0)}) new = s.cells('/link', True) assert old != new assert all(s.inspect(p)['instance'] in s.nodes for p in new) assert all(not s.inspect(p)['instance'] or not s.inspect(p)['instance'].startswith('/link') for p in old - new) s.remove('/link') assert semantic_digest(s) == before[0] assert not any('/link' in a or '/link' in c for a, b, c in s.relations) assert not any(k.startswith('/link') for k in s.nodes) def test_boundary_missing_coping_support_and_whole_removal(work): s = Scene(0, domain=Box((-5, -4, -5), (45, 24, 25))) s.place('land', Terrain(s.domain, gradient(base=3))) curve = Polyline.bezier(((0, 0), (9, 20), (26, 0), (37, 17))) s.place('boundary', BoundaryChain(curve)) s.place('lamps', IlluminateBoundary('/boundary')) before = snapshot(s) with pytest.raises(ContractError): s.remove('/boundary') assert snapshot(s) == before changed = Polyline.bezier(((0, 1), (9, 19), (26, 1), (37, 18))) s.regenerate('/boundary', BoundaryChain(changed), dependents=('/lamps',)) s.finalize() p = s.view.offers('/boundary', 'mount')[0].frame.origin assert p in s.cells('/boundary', True) export_scene(s, work / 'curve.litematic') t = load_scene(work / 'curve.litematic') assert t.inspect(p) == s.inspect(p) base = (p[0], p[1] - 1, p[2]) damage(t, base) assert any(d.rule in ('support', 'enclosure') and d.position == base for d in validate(t, True)) def test_curve_boundary_rejects_incompatible_installation_frame(): from hearth_extensions import BoundaryLantern s = Scene(0, domain=Box((-3, -4, -3), (25, 25, 25))) s.place('land', Terrain(s.domain, gradient(base=3))) s.place('wall', Boundary(Polyline(((0, 0), (20, 8))))) port = s.view.offers('/wall', 'mount')[0] before = snapshot(s) with pytest.raises(ContractError, match='port-alignment'): s.place('bad-lamp', BoundaryLantern(), frame=Frame(port.frame.origin, port.frame.turn + 1), bindings=(Binding('/wall', port.key),)) assert snapshot(s) == before def test_failed_choice_does_not_perturb_sibling_randomness(): s = bridge_scene() s.remove('/link') a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') before = snapshot(s) bad = Link(a, b, '/land', fill_limit=0) with pytest.raises(ContractError): s.compose_choice(Choice('link', (Child('attempt', bad, bindings=(a.binding(), b.binding())),), lambda v, p: 0)) assert snapshot(s) == before good = Link(a, b, '/land', rise=1) s.place('link', good, bindings=(a.binding(), b.binding())) assert semantic_digest(s) == semantic_digest(bridge_scene())
test/test_extension_geometry.py · 128 行 · 原文件
# Extension-only probes for non-cardinal circulation and curve interfaces. from dataclasses import replace import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import validate, Child, Plan from hearth.components.primitives import Volume from hearth.environment import Terrain, gradient, wave from hearth.blocks import state_of from hearth.persistence import export_scene, load_scene, semantic_digest from hearth_extensions import Polyline, Endpoint, Link, Boundary, IlluminateBoundary, Platform def bridge_scene(seed=0, water=3, frame=Frame()): domain = Box((-8, -4, -8), (45, 42, 45)) s = Scene(seed, domain=frame.box(domain)) s.place('land', Terrain(domain, gradient(.02, .01, 1) + wave(.2, .1, .15, seed), water), frame=frame) s.place('a', Platform('/land'), frame=frame) s.place('b', Platform('/land'), frame=frame.compose(Frame((18, 0, 27)))) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'north') s.place('link', Link(a, b, '/land', rise=1), frame=frame, bindings=(a.binding(), b.binding())) return s.finalize() def test_diagonal_bridge_actual_route_support_railings_and_reload(work): s = bridge_scene() assert any(n.type == 'extension.trestles' for n in s.nodes.values()) assert len(set(x for x, z in s.nodes['/link'].contract.decisions['center'])) > 5 assert not validate(s, True) p = next(iter(s.cells('/link/deck'))) q = s.inspect(p) assert any('connect' in str(r) for r in s.inspect(p)['related']) or ('/link', 'connects', '/a') in s.relations export_scene(s, work / 'diagonal bridge.litematic') t = load_scene(work / 'diagonal bridge.litematic') assert t.inspect(p) == q and semantic_digest(t) == semantic_digest(s) def test_curve_boundary_interfaces_and_external_attachment(): s = Scene(3, domain=Box((-5, -4, -5), (45, 35, 35))) s.place('land', Terrain(s.domain, gradient(.015, .01, 3))) curve = Polyline.bezier(((0, 0), (7, 25), (28, -3), (37, 20))) s.place('boundary', Boundary(curve)) s.place('lamps', IlluminateBoundary('/boundary')) s.finalize() ports = s.view.offers('/boundary', 'mount') assert len(ports) > 3 p = ports[0].frame.origin q = s.inspect(p) assert q['chain'][1]['id'] == '/boundary' assert p in s.cells('/boundary', descendants=True) @pytest.mark.parametrize('width,depth,corner,lantern', [(13, 17, 0, False), (17, 21, 3, True), (25, 13, 4, False)]) def test_polygon_hall_multiple_usable_ports(width, depth, corner, lantern, work): from hearth_extensions import Pavilion, Polygon s = Scene(2, domain=Box((-15, -4, -15), (42, 60, 42))) s.place('land', Terrain(s.domain, gradient(.025, -.018, 4))) s.place('hall', Pavilion(Polygon.chamfered(width, depth, corner), '/land', entrances=('north', 'east', 'south', 'west'), lantern=lantern)) s.finalize() assert len(s.view.offers('/hall', 'access')) == 4 glass = next(p for p, c in s.blocks.items() if c.state == 'minecraft:glass' and '/facade/' in c.owner) assert [n['type'] for n in s.inspect(glass)['chain']][:3] == ['window.shuttered', 'extension.polygon-shell', 'extension.pavilion'] export_scene(s, work / 'hall.litematic') assert load_scene(work / 'hall.litematic').inspect(glass) == s.inspect(glass) @pytest.mark.parametrize('turn', [0, 1, 2, 3]) def test_extension_transforms_geometry_interfaces_claims_and_queries(turn, work): from hearth.blocks import blockstates_equivalent frame = Frame((7, 3, -5), turn) base = bridge_scene() moved = bridge_scene(frame=frame) assert len(base.blocks) == len(moved.blocks) for point, cell in base.blocks.items(): q = frame.point(point) assert blockstates_equivalent(frame.state(cell.state), moved.inspect(q)['state']) assert moved.inspect(q)['instance'] == cell.owner assert moved.view.port('/a', 'south').frame == frame.compose(base.view.port('/a', 'south').frame) assert moved.nodes['/link'].contract.rules[0].cells == tuple(frame.point(p) for p in base.nodes['/link'].contract.rules[0].cells) export_scene(moved, work / 'rotated bridge.litematic') restored = load_scene(work / 'rotated bridge.litematic') q = next(iter(moved.cells('/link/deck'))) assert restored.inspect(q) == moved.inspect(q) def test_untried_kinked_ribbon_and_asymmetric_polygon(): from hearth_extensions import Polygon, Pavilion # Endpoints share Z; a global endpoint clipping plane would sever this route. curve = Polyline(((4, 8), (4, 12), (13, 16), (22, 12), (22, 8))) s = Scene(19, domain=Box((-8, -4, -8), (50, 60, 50))) s.place('land', Terrain(s.domain, gradient(base=2), water_level=3)) s.place('a', Platform('/land')) s.place('b', Platform('/land'), frame=Frame((18, 0, 0))) a, b = Endpoint('/a', 'south'), Endpoint('/b', 'south') s.place('link', Link(a, b, '/land', curve=curve, covered=True), bindings=(a.binding(), b.binding())) s.finalize() # A six-sided asymmetric footprint absent from the shipped clients. polygon = Polygon(((2, 0), (18, 0), (22, 4), (22, 16), (0, 16), (0, 3))) other = Scene(19, domain=Box((-10, -4, -10), (40, 60, 40))) other.place('land', Terrain(other.domain, gradient(.01, .02, 3))) other.place('hall', Pavilion(polygon, '/land', entrances=('north', 'south'), height=7, roof_run=3)) other.finalize() def test_graph_parent_substitutes_public_access_components(): from hearth_extensions.graphs import Campus, Vertex, Edge from hearth_extensions import Pavilion, Polygon domain = Box((-12, -4, -12), (55, 65, 60)) variants = [] for component in (Platform('/land', 13, 13), Pavilion(Polygon.chamfered(13, 13, 2), '/land', entrances=('north', 'south'))): s = Scene(6, domain=domain) s.place('land', Terrain(domain, gradient(base=3), water_level=3)) campus = Campus((Vertex('a', component, Frame()), Vertex('b', Platform('/land'), Frame((25, 0, 29)))), (Edge('a', 'south', 'b', 'north'),), '/land', domain, landscape=False) s.place('group', campus) s.finalize() assert len(s.view.offers('/group', 'access')) == 1 assert ('/group/circulation/link-0', 'connects', '/group/a') in s.relations variants.append(semantic_digest(s)) assert variants[0] != variants[1] @pytest.mark.parametrize('environment_seed,structure_seed', [(0, 0), (1, 5), (2, 3), (3, 2), (4, 1), (5, 4), (6, 0), (7, 5)]) def test_independent_extension_environment_structure_pairs(environment_seed, structure_seed): from hearth_extensions.assessment import freeze_probe, connector_scene frozen = freeze_probe(environment_seed) digest = semantic_digest(frozen) scene = connector_scene(frozen, structure_seed) assert semantic_digest(frozen) == digest assert not validate(scene, True)
test/test_extension_interiors.py · 70 行 · 原文件
# Functional bays must preserve their own access, room circulation, support and inventories. import pytest from hearth import Scene, Box, ContractError from hearth.environment import Terrain, gradient from hearth.kernel import validate from hearth.blocks import state_of, name_of from hearth.components.primitives import Volume from hearth.persistence import export_scene, load_scene, semantic_digest, encode from hearth_extensions import Pavilion, Polygon from hearth_extensions.interiors import FUNCTION_GROUPS from test_extension_failures import damage, snapshot def furnished_scene(purpose='library', width=13): scene = Scene(23, domain=Box((-12, -4, -12), (40, 60, 40))) scene.place('land', Terrain(scene.domain, gradient(base=3))) scene.place('hall', Pavilion(Polygon.chamfered(width, 17, 4), '/land', purpose, ('north', 'south', 'east', 'west'))) return scene.finalize() @pytest.mark.parametrize('purpose', tuple(FUNCTION_GROUPS)) def test_functional_bays_are_reachable_and_preserve_inventory(purpose, work): scene = furnished_scene(purpose) bays = [n for n in scene.nodes.values() if n.type == 'extension.work-bay'] assert len(bays) >= 2 assert not validate(scene, True) for bay in bays: port = scene.view.port(bay.path, 'use') assert scene.view.clear(port.region) assert any(scene.blocks[p].nbt for p in scene.cells(bay.path)) path = work / (purpose + '.litematic') export_scene(scene, path) restored = load_scene(path) assert encode(restored.nodes) == encode(scene.nodes) assert semantic_digest(restored) == semantic_digest(scene) def test_larger_hall_allocates_more_bays_and_protects_central_aisle(): small = furnished_scene(width=13) large = furnished_scene(width=25) small_decisions = small.nodes['/hall/furnishings'].contract.decisions large_decisions = large.nodes['/hall/furnishings'].contract.decisions assert large_decisions['placed_bays'] > small_decisions['placed_bays'] assert large_decisions['omitted_optional'] == 0 point = large.nodes['/hall/furnishings'].contract.rules[0].cells[20] before = snapshot(large) with pytest.raises(ContractError, match='clearance'): large.place('crate', Volume(Box(point, point), state_of('stone'))) assert snapshot(large) == before def test_damaged_station_furnishing_and_support_are_detected(): scene = furnished_scene('library') bay = next(n for n in scene.nodes.values() if n.type == 'extension.work-bay') lectern = next(p for p in scene.cells(bay.path) if name_of(scene.blocks[p].state) == 'lectern') damage(scene, lectern) assert any(d.rule == 'furnishing' and d.component == bay.path for d in validate(scene, True)) bed = bay.contract.rules[0].cells[0] damage(scene, bed) assert any(d.rule == 'support' and d.position == bed for d in validate(scene, True)) def test_interaction_clearance_remains_protected_after_completion(): scene = furnished_scene('bedroom') bay = next(n for n in scene.nodes.values() if n.type == 'extension.work-bay') at = scene.view.port(bay.path, 'use').frame.origin before = snapshot(scene) with pytest.raises(ContractError, match='clearance'): scene.place('block-user', Volume(Box(at, at), state_of('stone'))) assert snapshot(scene) == before
test/test_extension_protocol.py · 93 行 · 原文件
# A read-only endpoint consumer must not need the host's mutation authority. import pytest from hearth import Scene, Box from hearth.kernel import Capability, Contract, Port, Grant, Plan from hearth.space import Frame from hearth.blocks import state_of from hearth_extensions import Endpoint, EndpointContact class Landing: def capability(self): return Capability('test.landing', ('landing',)) def negotiate(self, ctx, parameters): return Contract(Box((-1, 0, -1), (1, 0, 1)), ports=(Port('access', 'access', Frame((0, 1, 0)), Box((-1, 0, -1), (1, 2, 1)), 4, 'resurface'),), grants=(Grant('resurface', Box((-1, 0, -1), (1, 0, 1)), ('surface',), ('path',), 9),)) def realize(self, ctx, contract): p = Plan() p.fill(contract.envelope, state_of('stone_bricks')) return p def test_read_only_connection_to_mutable_port(): s = Scene() s.place('landing', Landing()) endpoint = Endpoint('/landing', 'access') before = dict(s.blocks) s.place('consumer', EndpointContact(endpoint), bindings=(endpoint.binding(),)) assert s.blocks == before assert ('/consumer', 'connected_to', '/landing') in s.relations s.finalize() def test_connection_does_not_acquire_write_authority(): from hearth.kernel import ContractError class Bad(EndpointContact): def realize(self, ctx, contract): p = Plan() p.block((0, 0, 0), state_of('gold_block')) return p s = Scene() s.place('landing', Landing()) endpoint = Endpoint('/landing', 'access') before = dict(s.blocks) with pytest.raises(ContractError, match='write-authority'): s.place('bad', Bad(endpoint), bindings=(endpoint.binding(),)) assert s.blocks == before and '/bad' not in s.nodes def test_atomic_multi_branch_replay_accepts_explicit_replacements(): from hearth.components.primitives import Volume s = Scene() s.place('a', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) s.place('b', Volume(Box((3, 0, 0), (3, 0, 0)), state_of('stone'))) s.regenerate('/a', dependents=('/b',), replacements={'/b': Volume(Box((3, 0, 0), (4, 0, 0)), state_of('oak_planks'))}) assert len(s.cells('/b')) == 2 assert s.inspect((0, 0, 0))['state'] == state_of('stone') def test_multi_branch_replay_rejects_undeclared_target_and_rolls_back(): from hearth.components.primitives import Volume from hearth.kernel import ContractError from hearth.persistence import semantic_digest s = Scene() s.place('a', Volume(Box((0, 0, 0), (0, 0, 0)), state_of('stone'))) before = semantic_digest(s) with pytest.raises(ContractError, match='replay-targets'): s.regenerate('/a', replacements={'/unknown': Landing()}) assert semantic_digest(s) == before and set(s.nodes) == {'/a'} def test_importable_generation_has_no_new_native_dependency(): import subprocess, sys from pathlib import Path code = ''' import sys,importlib.abc class NoNative(importlib.abc.MetaPathFinder): def find_spec(self, fullname, path=None, target=None): if fullname.split('.')[0] in ('numpy','mcio','scipy','shapely','ctypes'): raise RuntimeError('Unexpected native/transport dependency: '+fullname) sys.meta_path.insert(0,NoNative()) from hearth_extensions.assessment import hall_scene from hearth.persistence import semantic_digest scene=hall_scene(4,1) print(semantic_digest(scene)) ''' result = subprocess.run([sys.executable, '-c', code], cwd=Path(__file__).parents[1], capture_output=True, text=True) assert result.returncode == 0, result.stderr assert len(result.stdout.strip()) == 64
test/test_geometry_environment.py · 243 行 · 原文件
# Actual-geometry damage tests, independent environment sampling and regeneration. from dataclasses import replace, dataclass from pathlib import Path import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import validate, Capability, Contract, Plan, Port, Grant, Child, Rule from hearth.kernel.scene import Cell from hearth.blocks import state_of, name_of, blockstates_equivalent, validate_state from hearth.environment import Terrain, constant, gradient, wave, radial from hearth.components.building import Building, Blueprint, RoomSpec from hearth.components.primitives import Pool, Volume from hearth.programs import PROGRAMS, building_scene, settlement_scene from hearth.assessment import adaptation_expression, principal_signature from hearth.persistence import export_scene, load_scene, semantic_digest, companion_path, _mcio def damage(scene, p, material=None): scene = scene._fork() old = scene.blocks.get(p) if old: scene.reverse[old.owner].discard(p) scene.blocks.pop(p) if material: owner = old.owner if old else next(n.path for n in scene.nodes.values() if n.type.startswith('room.')) operation = old.operation if old else next(iter(scene.operations)) scene.blocks[p] = Cell(material, owner, operation) scene.reverse[owner].add(p) return scene @pytest.fixture def house(): return building_scene(Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom'))), 7, gradient(.04, 0, 4), 6) def test_removed_support_blocked_stair_exit_and_paired_door(house): foundation = next(n for n in house.nodes.values() if n.type == 'adapter.foundation') p = foundation.contract.rules[0].cells[0] assert 'support' in {d.rule for d in validate(damage(house, p), True)} stair = next(n for n in house.nodes.values() if n.type == 'circulation.stair') p = next(r for r in stair.contract.rules if r.kind == 'clear').cells[4] assert 'clearance' in {d.rule for d in validate(damage(house, p, state_of('stone')), True)} door = next(p for p, c in house.blocks.items() if 'spruce_door' in c.state and 'half=lower' in c.state) issues = validate(damage(house, door, state_of('stone')), True) assert {'door-pair', 'reachability'} <= {d.rule for d in issues} assert all(d.component.startswith('/') and d.conditions for d in issues) def test_lights_furniture_seal_and_inventory_are_actual(house): room = '/building/room-0-0-0' s = house for p in house.cells(room, True): if name_of(house.blocks[p].state) == 'lantern': s = damage(s, p) assert 'lighting' in {d.rule for d in validate(s, True)} glass = next(p for p in house.cells(room, True) if name_of(house.blocks[p].state) == 'glass') assert 'enclosure' in {d.rule for d in validate(damage(house, glass), True)} bed = next(p for p, c in house.blocks.items() if name_of(c.state) == 'red_bed') assert 'bed-pair' in {d.rule for d in validate(damage(house, bed), True)} barrel = next(p for p, c in house.blocks.items() if c.nbt) s = house._fork() nbt = dict(s.blocks[barrel].nbt) nbt['Items'] = [{'Slot': 0, 'id': 'minecraft:bread', 'count': 100}] s.blocks[barrel] = replace(s.blocks[barrel], nbt=nbt) assert 'inventory' in {d.rule for d in validate(s, True)} def test_pool_boundary_damage_and_unsupported_substrate(): s = Scene(domain=Box((-3, -3, -3), (14, 20, 14))) s.place('land', Terrain(s.domain, constant(0))) s.place('pool', Pool(), bindings=(Binding('/land', 'construction', 'excavate'),)) assert 'pool-containment' in {d.rule for d in validate(damage(s, (0, 0, 2)), True)} def test_nbt_roundtrip_and_real_schematic_mismatch(house, work): path = work / 'inventory and spaces.litematic' export_scene(house, path) restored = load_scene(path) assert semantic_digest(restored) == semantic_digest(house) assert {p: c.nbt for p, c in restored.blocks.items() if c.nbt} == {p: c.nbt for p, c in house.blocks.items() if c.nbt} _, _, tag, nbtfile = _mcio() nbt = nbtfile.load_regardless_of_gzipped(filename=path) region = next(iter(nbt['Regions'].values())) region['TileEntities'][0]['Items'][0]['count'] = tag.Int(7) nbtfile(nbt).save(path) with pytest.raises(ContractError, match='geometry-mismatch'): load_scene(path) companion_path(path).unlink() with pytest.raises(ContractError, match='untrusted-structure'): load_scene(path) @pytest.mark.parametrize('environment_seed', range(16)) @pytest.mark.parametrize('building_seed', range(4)) def test_64_frozen_independent_pairings(environment_seed, building_seed): field, water = adaptation_expression(environment_seed) domain = Box((-8, -4, -18), (34, 64, 34)) s = Scene(building_seed, domain=domain) s.place('ground', Terrain(domain, field, water)) before = {p: c.state for p, c in s.blocks.items()} # An existing protected environmental observation outside all building edits. protected = (32, s.view.elevation(32, 32), 32) from hearth.components.primitives import Assembly s.place('preserved', Assembly('protected-soil', Box(protected, protected), (), (Rule('expected', (protected,), data={'names': [name_of(s.blocks[protected].state)]}),))) design = PROGRAMS['dwelling'](building_seed) s.place('house', Building(design, '/ground')) s.finalize() assert s.nodes['/house'].contract.decisions['rooms'] == [(r.x, r.z, r.level, r.purpose) for r in design.normalized()] allowed = set() for path, old in s.displaced.items(): if path.startswith('/house/'): allowed.update(old) assert all(s.nodes[path].contract.envelope.contains(p) for p in old) assert all(p in allowed or (p in s.blocks and s.blocks[p].state == material) for p, material in before.items()) assert s.blocks[protected].state == before[protected] assert s.nodes['/house/approach'].contract.decisions['rows'] assert all(s.view.supports(p) for p in s.nodes['/house/foundation'].contract.rules[0].cells) def test_environment_implementation_substitution_and_public_forwarding(): @dataclass(frozen=True) class IndependentField: def __call__(self, x, z): return 4 + 0.01 * x - 0.01 * z def expression(self): return {'polynomial': [4, .01, -.01]} @dataclass(frozen=True) class WrappedEnvironment: domain: Box def capability(self): return Capability('extension.environment', ('environment', 'composite')) def negotiate(self, c, p): ports = tuple(Port(key, key, Frame(self.domain.lo), self.domain, 100000, delegate=('strata', key)) for key in ('construction', 'planting')) return Contract(self.domain, ports=ports) def realize(self, c, b): return Plan(children=[Child('strata', Terrain(self.domain, IndependentField()))]) domain = Box((-8, -4, -18), (30, 50, 30)) s = Scene(2, domain=domain) s.place('world', WrappedEnvironment(domain)) s.place('house', Building(Blueprint((RoomSpec(0, 0, 0, 'living'),)), '/world')) s.finalize() assert s.view.port('/house', 'street').delegate == ('approach', 'street') assert any(d['source'] == '/world' for d in s.dependencies) def test_environment_dependency_regeneration_is_explicit_and_atomic(): domain = Box((-8, -4, -18), (28, 55, 28)) s = Scene(3, domain=domain) s.place('land', Terrain(domain, constant(3))) design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom'))) s.place('house', Building(design, '/land')) before = semantic_digest(s) with pytest.raises(ContractError): s.regenerate('/land', Terrain(domain, constant(4))) assert semantic_digest(s) == before old_floor = s.nodes['/house'].contract.decisions['floor'] s.regenerate('/land', Terrain(domain, constant(4)), dependents=('/house',)) assert s.nodes['/house'].contract.decisions['floor'] == old_floor + 1 assert not any(n.stale for n in s.nodes.values()) assert all(p in s.blocks for cells in s.reverse.values() for p in cells) @pytest.mark.parametrize('program', tuple(PROGRAMS)) @pytest.mark.parametrize('seed', range(8)) def test_three_composition_programs(program, seed): s = building_scene(PROGRAMS[program](seed), seed) assert s.completed and any(n.type.startswith('room.') for n in s.nodes.values()) @pytest.mark.parametrize('seed,count', [(i, None) for i in range(8)] + [(0, 3), (0, 6)]) def test_settlement_corpus_and_boundaries(seed, count): s = settlement_scene(seed, count) assert s.completed buildings = [n for n in s.nodes.values() if n.type == 'building.rooms'] assert len(buildings) == count if count else 3 <= len(buildings) <= 6 route = next(n for n in s.nodes.values() if n.type == 'settlement.connections') assert len(route.contract.rules[0].cells) == len(buildings) + 2 def test_blockstate_explicit_semantics_and_rotation(): assert blockstates_equivalent('minecraft:oak_log[axis=x]', 'minecraft:oak_log[axis=x]') assert not blockstates_equivalent('minecraft:oak_log', 'minecraft:oak_log[axis=y]') assert not blockstates_equivalent('minecraft:oak_log[axis=x]', 'minecraft:oak_log[axis=z]') assert not blockstates_equivalent('minecraft:oak_log[axis=x]', 'minecraft:spruce_log[axis=x]') with pytest.raises(ValueError): validate_state('minecraft:stone[facing=north]') for turn in range(4): validate_state(Frame(turn=turn).state('minecraft:rail[shape=north_east,waterlogged=false]')) def test_complete_settlement_transforms_and_public_gateway(): from hearth.programs import Settlement, dwelling, atelier local = Box((-49, -4, -23), (49, 64, 66)) frame = Frame((150, 2, 80), 1) s = Scene(0, domain=frame.box(local)) s.place('land', Terrain(s.domain, constant(4))) s.place('district', Settlement((dwelling(1), atelier(1), dwelling(4)), local, '/land'), frame=frame) s.finalize() ports = s.view.offers('/district', 'public-access') assert len(ports) == 1 and ports[0].frame.turn == 1 assert ports[0].frame.origin == frame.point((0, 3, -12)) assert s.view.capability('/district/plot-0').inputs['design.bay'].accepts(9) assert any(d['reason'] == 'observed-spatial-input' for d in s.dependencies) def test_actual_subsurface_support_not_just_height(): domain = Box((-8, -4, -18), (28, 55, 28)) s = Scene(0, domain=domain) s.place('ground', Terrain(domain, constant(4))) s.place('local-cavity', Volume(Box((2, 3, 2), (2, 3, 2)), state_of('air'), 'siteworks'), bindings=(Binding('/ground', 'construction', 'excavate'),)) assert s.view.elevation(2, 2) == 4 and s.view.sample(2, 2).support_depth == 1 before = semantic_digest(s) with pytest.raises(ContractError, match='substrate-depth'): s.place('house', Building(Blueprint((RoomSpec(0, 0, 0, 'living'),)), '/ground')) assert semantic_digest(s) == before def test_path_endpoint_respects_host_authority(): from hearth.components.landscape import PathNetwork from hearth.components.primitives import Assembly domain = Box((-4, -3, -4), (12, 20, 12)) s = Scene(0, domain=domain) s.place('ground', Terrain(domain, constant(0))) # An unrelated solid host behind the offered endpoint must survive path widening. s.place('behind', Volume(Box((-1, 1, -1), (-1, 1, 1)), state_of('stone'))) s.place('route', PathNetwork(((0, 1, 0), (8, 1, 0)), ((0, 1),)), bindings=(Binding('/ground', 'construction', 'surface'),)) assert s.cells('/behind') == {(-1, 1, -1), (-1, 1, 0), (-1, 1, 1)} s.finalize() def test_upper_room_bay_boundary_with_vertical_circulation(): design = Blueprint((RoomSpec(0, 0, 0, 'living'), RoomSpec(0, 0, 1, 'bedroom')), bay=13) s = building_scene(design, 5, gradient(base=4), 6) assert s.completed and s.nodes['/building'].contract.decisions['bay'] == 13 assert s.nodes['/building/room-0-0-0/stairs'].contract.rules
test/test_kernel.py · 122 行 · 原文件
# Foundation tests run before extending architectural content. from dataclasses import dataclass import pytest from hearth import Scene, Box, Frame, Binding, ContractError from hearth.kernel import Capability, Contract, Plan, Child, Rule from hearth.components.primitives import Assembly, Volume, Wall, Window, Grass, Tree, Pool from hearth.environment import Terrain, constant from hearth.blocks import state_of, blockstates_equivalent from hearth.persistence import export_scene, load_scene, semantic_digest def land(): s = Scene(12, domain=Box((-10, -3, -10), (20, 25, 20))) s.place('terrain', Terrain(s.domain, constant(0))) return s def test_composite_attachment_automatic_chain(): s = Scene(4) children = (Child('base', Volume(Box((0, 0, 0), (8, 0, 0)), state_of('stone'))), Child('wall', Wall(), frame=Frame((0, 1, 0))), Child('window', Window(), frame=Frame((2, 2, 0)), bindings=(Binding('/house/wall', 'infill'),))) s.place('house', Assembly('house', Box((-1, 0, -2), (10, 8, 3)), children)) q = s.inspect((2, 2, 0)) assert [n['type'] for n in q['chain']] == ['window.shuttered', 'wall.framed', 'house'] assert len(s.cells('/house/window')) == 10 assert s.cells('/house/window') <= s.cells('/house', True) def test_substitution_same_parent(): def parent(window): return Assembly('room', Box((-1, -1, -2), (10, 8, 3)), (Child('base', Volume(Box((0, -1, 0), (8, -1, 0)), state_of('stone'))), Child('wall', Wall()), Child('window', window, frame=Frame((2, 1, 0)), bindings=(Binding('/room/wall', 'infill'),)))) a, b = Scene(), Scene() a.place('room', parent(Window())) b.place('room', parent(Window(shutters=False))) assert semantic_digest(a) != semantic_digest(b) assert a.nodes['/room/window'].contract.envelope == b.nodes['/room/window'].contract.envelope def test_tree_grass_and_pool_preserve_support(): s = land() s.place('grass', Grass(), frame=Frame((0, 1, 0)), bindings=(Binding('/terrain', 'planting', 'plant'),)) s.place('tree', Tree(), frame=Frame((0, 1, 0)), bindings=(Binding('/terrain', 'planting', 'plant'), Binding('/grass', 'replacement', 'plant'))) assert '/grass' not in s.nodes assert s.inspect((0, 1, 0))['instance'] == '/tree' before = semantic_digest(s) nodes = set(s.nodes) ops = set(s.operations) with pytest.raises(ContractError): s.place('pool', Pool(), frame=Frame((-2, 0, -2)), bindings=(Binding('/terrain', 'construction', 'excavate'),)) assert semantic_digest(s) == before and set(s.nodes) == nodes and set(s.operations) == ops with pytest.raises(ContractError): s.place('grass2', Grass(), frame=Frame((0, 1, 0))) s.place('pool-ok', Pool(), frame=Frame((6, 0, 6)), bindings=(Binding('/terrain', 'construction', 'excavate'),)) s.finalize() def test_tall_grass_whole_object_and_no_tree_excavation(): s = land() s.place('grass', Grass(True), frame=Frame((0, 1, 0))) with pytest.raises(ContractError): s.place('ordinary-tree', Tree(), frame=Frame((0, 0, 0)), bindings=(Binding('/terrain', 'construction', 'excavate'),)) s.place('tree', Tree(), frame=Frame((0, 1, 0)), bindings=(Binding('/grass', 'replacement', 'plant'),)) assert '/grass' not in s.nodes def test_transforms_and_persistence(work): frame = Frame((14, 3, -7), 1) s = Scene(-42) s.place('beam', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('oak_log', axis='x')), frame=frame) assert s.inspect((14, 3, -5))['state'] == state_of('oak_log', axis='z') path = work / 'space name.litematic' export_scene(s, path) restored = load_scene(path) assert restored.inspect((14, 3, -5)) == s.inspect((14, 3, -5)) assert blockstates_equivalent('minecraft:oak_stairs[facing=north,half=bottom]', 'minecraft:oak_stairs[half=bottom,facing=north]') assert not blockstates_equivalent('minecraft:oak_log', 'minecraft:oak_log[axis=y]') import json meta = path.with_suffix('.litematic.structure.json') data = json.loads(meta.read_text()) data['digest'] = 'bad' meta.write_text(json.dumps(data)) with pytest.raises(ContractError, match='geometry-mismatch'): load_scene(path) def test_clearance_rollback_and_bounds(): s = Scene() s.place('stairs', Assembly('circulation', Box((0, 0, 0), (3, 5, 3)), (), (Rule('clear', ((1, 2, 1), (1, 3, 1))),))) with pytest.raises(ContractError, match='clearance'): s.place('decoration', Volume(Box((1, 3, 1), (1, 3, 1)), state_of('stone'))) assert set(s.nodes) == {'/stairs'} and not s.blocks @dataclass class Escaper: def capability(self): return Capability('bad', ()) def negotiate(self, c, p): return Contract(Box((0, 0, 0), (0, 0, 0))) def realize(self, c, b): p = Plan() p.block((1, 0, 0), state_of('stone')) return p with pytest.raises(ContractError, match='envelope'): s.place('bad', Escaper()) def test_seed_stability_and_regeneration(): from hearth.randomness import Scope a = Scope(123).child('house') before = a.stream('layout').getrandbits(64) Scope(123).child('failed').stream().random() assert before == a.stream('layout').getrandbits(64) s = Scene() s.place('beam', Volume(Box((0, 0, 0), (2, 0, 0)), state_of('stone'))) s.regenerate('/beam', Volume(Box((0, 0, 0), (1, 0, 0)), state_of('oak_planks'))) assert s.inspect((2, 0, 0))['instance'] is None assert len(s.cells('/beam')) == 2
完整 ARCHITECTURE.md

Hearth architecture, version 1.2.0

The initial design was written before the kernel or extensive scene geometry. The executable foundation passed seven tests before the terrain/grass/tree/wall/window prototype, then furnished rooms and buildings were added, followed by settlements and the finite corpus. The stage sequence and generic fixes are recorded in reports/development-findings.md. This document describes the implemented design; GENERATOR.md contains usage and the R01-R30 evidence ledger.

The second development phase tests expressive breadth through a separate hearth_extensions package. Its pre-change public API and module hashes, failing probes and protocol delta, and retained development findings distinguish new evidence from the completed first delivery. This is a self-authored extension exercise, not an independent audit. The user's report of prior native/Pyodide agreement is preserved as external context; no claim is made that this revision was executed in a browser.

Module boundaries

Layer Modules Responsibility
Values and geometry space, blocks, randomness Inclusive integer boxes, frames, Java blockstates, stable random scopes
Composition kernel kernel/contracts, scene, view, validation, errors Negotiation, permissions, transactions, instances, graphs, queries and rule scheduling
Environments environment/fields, terrain Composable field expressions, frozen sampled strata and water
Architectural knowledge components/*, adapters/site Windows, walls, furnishings, rooms, roofs, buildings, contact and access strategies
Public composition composition, programs Selection, encapsulation, arrangement, repetition, scattering, room graphs and settlement intent
Transport and assessment persistence, assessment, examples/* Verified Litematica export/reload, inspection, explicit batches
Independent extension extension_demo A different light and a composite reading suite with a forwarded entrance
Further geometry and architecture hearth_extensions/{geometry,circulation,boundaries,sites,halls,interiors,graphs} Ribbons, curves, polygon halls, functional interior allocation and access graphs through the same protocol
New lightweight clients hearth_extensions/programs, examples/extension_* Locked graph intent on independently frozen fields, assessment, replay and inspection

The kernel imports no concrete architectural implementation and never imports the CLI. The CLI is an ordinary client. A browser adapter could retain the kernel, field expressions, plans and JSON records, replacing the Python host/transport. No browser runtime or UI is included.

One protocol for leaves and composites

A component implements:

capability() -> Capability negotiate(context: Context, parameters: dict) -> Contract realize(context: Context, contract: Contract) -> Plan

Capability separates feasible offers from a placed instance. It includes semantic tags, executable Domain checks for constructor inputs and execution parameters, assumptions, adaptation strategies, guarantees, implementation version and locked decisions. Nested constructor paths such as design.bay, and frame.turn, have executable domains. Constructors carry explicit principal intent; parameters contains only advertised runtime overrides. Unknown overrides fail. Recorded inputs include public constructor fields, execution arguments and negotiated decisions.

Contract contains a conservative local envelope, ports, grants, rules, decisions, input regions and whole-object status. It becomes a world-space contract through the instance frame. Occupied geometry is derived from effects and indexed exactly; an envelope is never substituted for actual membership. Rules express support, protected clearance, preservation, enclosure, lighting, furnishing and access. Effect coordinates must stay within the negotiated envelope, and child envelopes within their parent's envelope. Expansion requires another negotiation.

A Port has a kind, oriented frame, region, capacity, alignment, facts and an optional grant. Wall ports expose thickness, sill and excluded frame margins. A Binding names a host and port, a verb, and an optional further restriction in world coordinates. Installation requires compatible orientation, anchor alignment, available capacity and a compatible grant. Windows negotiate their reveal depth against the public port; parents can substitute shuttered and hooded implementations.

A connect binding now always consumes only connection capacity and records a dependency and typed association. It acquires no mutation grant, including when that port separately offers resurfacing authority. The unchanged-kernel probe failed because it previously demanded that unrelated mutation permission even for a read-only endpoint consumer. A negative test proves the new connection cannot write to the host. Installation, sharing and other mutation verbs retain their authority checks.

Composite ports may delegate to a named child port. The kernel resolves authority through the chain, while callers bind to the composite. It verifies the realized child's frame, region and kind against the negotiated public interface, including during later validation. Buildings forward their street connection; settlements forward a public gateway through their path composition. The independent reading suite forwards its room entrance. Parents do not name private approach children.

Plans, candidates and transactions

Plan contains writes, children, bounded Choice operations and typed relationships. Component code reads an environmental view and returns effects. It cannot receive the shared mutable store through its context. The view copies contract/port records and exposes styles through a read-only mapping. This is a trusted Python programming protocol, not an arbitrary-code security sandbox.

A placement forks the current state. The kernel:

  1. Allocates a stable instance path and random scope; checks feasible domains.
  2. Negotiates a contract and resolves binding authority.
  3. Applies final per-coordinate effects under the executing component/operation identity.
  4. Instantiates semantic children through the same protocol.
  5. Checks tentative geometry, existing consumers and completed local obligations.
  6. Commits the entire state or discards the entire candidate.

Multiple writes inside one candidate component are coalesced to their final operation. They do not create false collisions with earlier versions of that component's own local plan. Foreign writes still require authority. The kernel never uses a global priority or identical-state overwrite rule. Failed transactions preserve geometry, nodes, ownership, ports, relationships, dependencies, history and sibling random scopes.

Choice evaluates complete candidate child compositions in isolated forks. It first checks hard conditions, then scores actual sitework cost and exposed support proportions. It selects by a scoped seed among alternatives within an explicit quality tolerance. adapted(...) proposes stepped perimeters and piers under the same locked principal design. Water/high relief constrain the feasible strategy set. Candidate scores and all rejection diagnostics are recorded. A bounded search with unvisited alternatives reports SearchExhausted; identical hard failures of every declared contact alternative retain the specific failed constraint. This is not a proof about unimplemented techniques.

Authority, phases and logical objects

A grant identifies an owner, region, allowed verbs, consumer tags, per-binding change limit and whether whole-object replacement is allowed. Binding restrictions can narrow a grant. A high planting preference never grants excavation rights. Soil grants local construction edits, planting consumes substrate support, and grass explicitly grants whole-object replacement to trees. Existing support and clearance rules survive unrelated edits. Pools cannot undermine a supported tree. Paired plants and doors cannot be partially replaced through an ordinary binding.

Property adjustments retain the original semantic owner and require the same block type. Deletions remove current ownership; erasure history is separate from current cells. Displaced cells are retained compactly so branch removal/regeneration can restore surviving host content. Retired grass disappears from current nodes, relationships and ownership, while the operation history can still explain its replacement.

Explicit shared support records a participant, a capacity use, a support obligation and a typed association. It does not transfer the primary owner. Shared writes require consumer rebinding; identical states alone never authorize sharing.

Construction starts with a temporarily open scope. Invariants run throughout; completion rules run when the scope closes. complete=False permits an explicitly unfinished scope, and finish_scope closes it. Unfinished or stale content cannot be finalized or exported. Once a room is complete, subsequent placements must preserve its access, lighting and enclosure. A building provides internal circulation and an external landing. The settlement discharges its connection to public paths.

Environmental observations and adaptation

View uses world coordinates and explicit known bounds. Context.world/local convert positions; Context.elevation/water/state are local-frame convenience queries. Views expose actual 3D states, owners, solid support, bounded elevation search, water, slope, substrate depth, clearance, protected regions, obstacle distance, style roles, preferences and public interfaces. Unknown space raises an error. A roof is not assumed to be the ground surface: path observations are bounded by the offered access elevation.

Field expressions support constants, gradients, waves, radial masks, addition, multiplication, blending, transforms and clamping. They can be nested and supplied by an independent compatible implementation. Water intersects the sampled strata. Adaptation never inspects an environment class, recipe label or particular seed. The 64-case assessment freezes sixteen complete 3D terrain scenes before making four independently seeded building placements on copies of each.

Sitework measures support and water, preserves gravity alignment, and bounds relief, post height, fill, excavation grants and approach length. Foundations produce support columns/perimeters to the actual solid bed. The approach examines its full tread width and water surface. The principal room graph, functions, footprint bays, locked horizontal placement and chosen roof intent remain intact. No algorithm levels the whole site to guarantee success.

Three distinct graphs and exact indexes

An instance ID is its stable parent/key path. The kernel automatically records creation type, constructor inputs, resolved decisions, frame, implementation and random scope. Helper calls do not create semantic ancestors. Windows, walls, floors, furniture, lights and adapters are actual instances.

  • Structural containment and attachment form a graph. Attachment supplies the primary structural chain, while containment remains recorded. Bridges/path networks can relate to many structures.
  • Data/constraint dependencies have a source, consumer, region, input version and reason. An automatic read trace coalesces actual spatial observations and records interface reads, supplementing declared regions and bindings. These are not false structural ancestors.
  • Operations retain generating actor, operation key, write count, displaced identities and restorable old cells. These records do not make a displaced object a current owner.

The sparse coordinate map stores one current owner and operation per occupied cell. Reverse maps provide exact cells by owner and shared participant. A structural adjacency index supports descendant queries through attachment as well as containment: a window created by an external facade program is still included when highlighting its host wall or building. Queries traverse this graph, never scan the full voxel store or copy ancestor strings onto each cell.

Removing a branch updates all indexes. External attached/dependent consumers must be regenerated or removed together; otherwise validation rejects the transaction. regenerate(path, ..., dependents=...) restores displaced host output, removes obsolete nodes and replays affected branches from their original inputs/scopes. It never repeatedly cuts the already modified terrain. Explicit co-regeneration is intentional: there is no hidden oscillating terrain/building update loop.

Version 1.2 adds replacements={path: component, ...} to regenerate. Every replacement must be one of the explicit, distinct replay targets (path followed by dependents). Targets replay in that order under their original scopes, frames and bindings, within one transaction. This permits replaying unchanged endpoint hosts before a changed connector, which the previous single-replacement API could not express. It does not guess a dependency order, permit undeclared replacements, or clear stale flags to force success. Reloaded targets can provide implementations through the same mapping.

Extension data flow and architectural composition

The geometry layer adds finite polylines with arc projection, cubic sampling, cardinal rasterization and width ribbons, plus integer polygon masks and perimeters. It stays independent of block storage. The extension uses these operations because a curve needs coherent consecutive joins and a walkway needs a connected discrete route. A general mesh package or environment-family registry is unnecessary.

Link resolves two public access interfaces, verifies outward frames and mouth widths, and samples the frozen environment along a planned ribbon. Endpoint heights stay locked. Bounded upward profile propagation clears measured ground/water, or reports an incompatible grade. Trestles reach two real solid bed cells and obey depth, span and fill limits. Deck, guards and canopy are separate children; scoped terrain grants authorize their edits while read-only host contacts preserve landing ownership. Actual support, route, headroom and guard rules run on the tentative result. Span checks are an explicit bounded load-path model, not structural mechanics. Covered connections are open galleries.

Boundary follows an open contour on measured terrain, builds continuous masonry and exposes framed fixture sockets. BoundaryChain packages many bounded segments and forwards their sockets. An external lighting composition installs lamps through those interfaces, so the actual boundary remains their semantic host. Per-segment and cross-segment grade checks prevent disconnected joins.

Pavilion composes a polygon floor, foundation, shell, facade installations, independent approaches, ceiling, lights, interior and hipped roof. Its shell exposes window/door regions; existing Hearth implementations install through them. HallInterior allocates functional WorkBay components around protected aisles and validates access to their interaction ports. The fitted count has a mandatory minimum and an explicitly recorded optional shortfall. A cutaway exposed undersized inherited furniture groupings, motivating this reusable interior planner without changing locked principal architecture.

Campus takes Vertex components with locked frames and explicit Edge connections. It verifies a connected graph, then composes any compatible access provider; tests substitute a platform and polygon hall without changing the parent. It does not inspect concrete types or private approach children. One client forms a branching campus mixing new halls with the original stacked-room building. Another forms a triangular circuit with broad halls and curved routes. Their fields are frozen independently before placement. Principal geometry/topology signatures are separated from contact and furnishing counts. Explicit graph placement is delivered; autonomous city packing is not.

Persistence, coordinates and replay

Positions are (x,y,z), Y up, north -Z. A positive quarter-turn maps (x,y,z) to (-z,y,x). Frames transform coordinates, boxes, rule cells, ports and directional block properties, including cardinal connection keys, axes, rotation values and supported rail/orientation strings. Custom rule data is uninterpreted; a validator needing directions uses its node frame.

Export bounds are derived from every realized occupied cell. MCIO indexing is converted explicitly to (y,z,x). Export-local coordinates equal world coordinates minus the companion's offset. The original world frame is restored on reload, including negative coordinates.

persistence writes one Java 1.21.1 region (data version 3955) and a versioned structural JSON record. It retains capabilities/contracts, nodes, frames, random scopes, styles, field inputs, dependency and structure graphs, current ownership, operation/displacement records, and relevant inventory NBT. The geometry digest canonicalizes parsed names and explicit property mappings and includes world coordinates and block-entity data. It ignores property order only, not missing/defaulted properties. Reload reads actual schematic blocks and NBT, verifies dimensions/digest/ownership and reruns the validators. Missing/unknown metadata or mismatched geometry is rejected as untrusted.

The companion format remains version 1. Import hearth_extensions before loading its artifacts to register the extension guard/span validators; unknown handlers fail rather than silently skipping validation. The new manifest audit regenerates every selected recipe and compares all structural nodes, relations, dependencies, operations, port uses, displacement records, inventories and exact membership with the loaded artifact. It also queries a current cell from every nonempty component.

The companion is not a cryptographic signature, and arbitrary geometry cannot reconstruct a graph. Reload does not execute serialized Python. To regenerate a reloaded branch, explicitly supply its component implementation; inputs and source programs/manifests support replay. Arbitrary entity types and a general block-entity migration system are not implemented; these artifacts export no entities.

Validation model and limits

Validators register through @validator(name); component authors use existing rules or add a named handler without editing dispatch. Missing handlers are errors, including after reload. The physical model uses integer standing positions, two air/passable cells, cardinal moves and elevation changes of at most one block with extra clearance for ascending/descending. Wood doors are considered operable. Stairs are checked as usable flights and declared clearance volumes. This is not a full Minecraft collision/fluid/redstone simulator.

Lighting propagates actual source levels through passable/transparent cells with unit attenuation; closed opaque boundaries block propagation. It checks required room locations, not a claim that all possible mob-spawning cells are spawn-proof. Enclosure checks actual room floors/ceilings and wall surfaces. Roof abutments are bounded voxel joins above sealed ceilings; universal flashing or structural mechanics are not proved. Support checks declared load paths, substrate and support grids, not an engineering stress solver for arbitrary blocks or decorative cantilevers.

Default limits are 512 blocks per axis, 1,000,000 occupied blocks, depth 40, 10,000 instances and 24 search alternatives, with at most 16,000,000 cells in the dense export bounding box. Demo count limits live in the CLI, not the kernel. Costs, bounds and failure conditions are public. Existing tests and finite observations establish only the documented scope.

完整 GENERATOR.md

Hearth procedural composition

Hearth generates furnished timber-and-stone buildings and a connected settlement for Minecraft Java 1.21.1. The default seed is 0; it produces five buildings, public paths, a well terrace, lights, planters, trees and grass. Structural choices include room counts/functions/adjacencies, wings, storeys, stair allocation, roof runs/pitches, porches, foundation strategies and street topology. There is no whole-building family selector in the kernel or settlement generator.

Version 1.2.0 adds a separate extension package: diagonal bridges and covered galleries, curve-following boundaries with attachment sockets, polygon halls with hipped roofs, furnished activity areas, and explicit access graphs. New clients form branching campuses and perimeter circuits. The original generate.py default and its seed-zero semantic content are preserved.

Quickstart

python generate.py python generate.py --seed 0 --output example.litematic python generate.py --seed 1 --count 6 --output "samples/six building village.litematic" python -m pytest -q test

A successful command validates the composition, exports a nonempty single region, reloads it and verifies its semantic content. Each schematic has a .litematic.structure.json companion. Keep the pair together. Explicit paths may be relative, absolute or contain spaces.

No downloads, reference generator, previous output or credentials are used. Python 3.12 and numpy are required; transport uses the provided MCIO 0.2.0 public API. It is imported normally, then from /work/generator/MCIO in this environment. On another host, install MCIO from its source before using export/reload. The Java blockstate reference is bundled under hearth/data/. Exact versions observed here are recorded in reports/dependencies.json; no additional packages were installed. Rendering additionally needs the optional supplied MCRender toolset.

Importable generation itself uses the Python standard library and bundled block schema; numpy and MCIO are loaded for schematic transport. The extension's import test forbids native/transport imports during generation. This preserves the portability boundary, but is not a Pyodide execution test.

Short compositions

These are intent descriptions; clients do not write voxels, repair geometry or assign block owners.

from hearth.components.building import Blueprint, RoomSpec from hearth.programs import building_scene plan = Blueprint(( RoomSpec(0, 0, 0, "living"), RoomSpec(0, 0, 1, "bedroom"), RoomSpec(1, 0, 0, "workshop"), ), bay=11, porch=True, roof_axis="auto") scene = building_scene(plan, seed=17) # No file export required.

Place on a previously generated environment:

from hearth import Scene, Box, Frame from hearth.environment import Terrain, gradient, wave from hearth.components.building import adapted scene = Scene(seed=17, domain=Box((-15, -4, -20), (40, 60, 40))) field = gradient(x=0.025, base=4) + wave(amplitude=0.7) scene.place("land", Terrain(scene.domain, field)) scene.compose_choice(adapted("home", plan, "/land", Frame((3, 0, 4), 1))) scene.finalize()

Discover and substitute implementations:

from hearth.kernel import Registry from hearth.components.interior import Light from extension_demo import Pendant registry = Registry() registry.register(Light()) registry.register(Pendant()) candidates = registry.select("room-light") # Either implementation can be supplied as Blueprint(..., light_component=...). public_ports = scene.view.offers("/home", "access") capability = scene.view.capability("/home")

hearth.composition provides encapsulate, attach, arrange, repeat, scatter and constrain. A composition returns Plan(children=[Child(...), Choice(...)]) and uses the same component protocol as a light or tree. Building, reading-suite and settlement interfaces support recursive port forwarding. ARCHITECTURE.md documents frames, grants and the complete lifecycle.

Runnable examples and batches

python -m examples.prototype --seed 0 python -m examples.building dwelling --seed 3 --output samples/dwelling-demo.litematic python -m examples.building atelier --seed 5 --output samples/atelier-demo.litematic python -m examples.building commons --seed 6 --output samples/commons-demo.litematic python -m examples.courtyard --seed 0 python -m examples.gallery --seed 0 python -m examples.extension --seed 0 python -m examples.inspection --seed 0 python -m examples.assess --seed 0 --output reports/reassessment --artifacts python -m examples.verify_replay --seed 0

The three primary programs are short room-graph recipes in hearth/programs.py. The courtyard and gallery clients were written after the abstractions existed. The independent extension supplies an actual pendant light and a nested reading suite using public components/validators. The gallery uses that extension without geometry repairs. The courtyard exposed a generic concave-corner decoration conflict, corrected by moving facade climbers away from corner installation margins.

The assessment command is an explicit batch output: it writes all inputs, results, rejections, candidate scores, summaries and selected samples. Unit tests create only cleaned temporary files under test/; they do not silently produce corpus artifacts.

Optional rendering, in the supplied proc-tool environment:

python -m examples.preview --seed 0 --input output.litematic --output previews/settlement --size 1500 python -m examples.preview --seed 6 --input samples/commons-6.litematic --output previews/commons-6 --cutaways python -m examples.preview --seed 0 --input samples/adaptation-00.litematic --output previews/adaptation-00 --cutaways python -m examples.preview --seed 1 --input samples/atelier-1.litematic --output previews/atelier-1 python -m examples.preview --seed 0 --input samples/courtyard.litematic --output previews/courtyard-0 --cutaways

The preview command checks the source pair and seed, then uses the supplied MCRender and cutaway utilities. It writes labeled views, camera records and views.json. The stair section is chosen from an actual stair instance's current cells. Geometry-only slices are not exported as completed components and have no structural companion. See previews/README.md for inspected views and observations. Rendering is not needed for generation or tests and must not be invoked on another host without the optional tools/assets.

Seeds, domains and adaptation

Seeds are explicit signed Python integers. SHA-256 derives streams from seed, stable instance keys and purpose; Python hash() and ambient randomness are never used. Planning, adaptation, geometry, materials and decoration use separate purpose keys. Child(..., seed=...), Scene.place(..., seed=...) and regenerate(..., seed=...) override a subtree. Scene.fork(seed=...) preserves existing frozen content and changes only the seed for future placements. Stable independent branches commute; dependent grass/tree replacement intentionally does not.

The delivered building planner supports connected grid rooms with bay sizes 9, 11 or 13, six furnishing purposes, supported stacked levels, shared horizontal circulation and one vertical flight per upper connected group. Ordinary room contracts support the same bay sizes. Walls expose widths 5-64, heights 4-12 and thicknesses 1-3. Other implementations can advertise different feasible domains; the kernel has no room-grid or building-count dispatch.

Site policy defaults: measured relief at most 5, bed-to-floor support height at most 8, at least two contiguous solid bed cells, approach length at most 12, foundation fill at most 1,600 cells and excavation authority bounded by the terrain grant (default 2,500 changes per binding). SiteLimits and grants expose these values. Contact alternatives compare actual effects, permitting local piers, stepped perimeter work and access treads. The default buildings do not excavate; the pool component exercises authorized excavation separately. Small terraces fill bounded local differences. The major terrain surface is not flattened.

Hard constraints include write authority, existing consumers, declared support/headroom, protected regions, locked room functions and placement. Preference fields and style roles are public observations. Preferences do not override constraints. Unknown space is an error. The kernel rejects effects outside accepted envelopes and derives export bounds from realized content, including vegetation and adapters. Limits controls dimensions, block count, instances, recursion, candidate budget and dense export volume.

The new polygon vocabulary is independent of Blueprint's bay grid. Pavilion accepts normalized simple footprints 13..25 blocks across, multiple declared cardinal entrances, heights 5..7 and hipped roof runs 1..3. Link supports simple diagonal/bending routes, width 3 or 5, bounded rise, actual-bed trestles and narrow endpoint transitions. BoundaryChain composes continuous bounded contour segments. The extension domain table states exact constraints and interfaces. There is no unlimited route planner, arbitrary concave-room solver, or automatic graph embedding. Explicit vertex frames and port choices remain the client's intent.

A completed standalone building offers an exterior landing. Its enclosing composition is responsible for a public path beyond that landing; a wet site can offer a boardwalk landing. The settlement fulfills this obligation and exposes its own public gateway. It can be translated and rotated as a composite.

Inspection, identity and regeneration

from pathlib import Path from hearth.persistence import export_scene, load_scene point = next(p for p, cell in scene.blocks.items() if cell.state == "minecraft:glass") explanation = scene.inspect(point) print(explanation["chain"], explanation["related"], explanation["operation"]) cells = scene.cells(explanation["instance"], descendants=True) export_scene(scene, Path("sample.litematic")) restored = load_scene(Path("sample.litematic")) assert restored.inspect(point) == explanation

The runnable inspection example selects actual room glass and prints its window, host wall, room and building chain, typed relationships and exact cells before and after reload. See reports/inspection.txt. cells(..., descendants=True) follows semantic attachment/containment indexes, including windows installed by a higher-level facade program. shared=True includes explicitly shared supports. Removed/displaced objects are not current owners.

World coordinates are (x,y,z). Export coordinates subtract the JSON offset; reload restores the world coordinates. Quarter-turns transform states, ports, claims and ownership consistently. Explicit property mappings compare regardless of order; omitted properties are never inferred for equality. Inventory NBT is transported and verified. Missing, unknown or mismatched companions are rejected; a bare schematic is not claimed to contain its original semantic graph.

scene.regenerate("/land", new_terrain, dependents=("/house",)) explicitly replaces affected output and replays dependent branches. Old displaced terrain is restored before replay. Dependency records include automatic spatial/interface read traces and input versions. Invalidated branches cannot be exported as completed. After reload, regeneration requires an explicit component implementation; serialized metadata is never executed as Python.

When replay must first rebuild unchanged hosts and then replace a connector, use the additive mapping introduced by the extension probe:

scene.regenerate("/a", dependents=("/b", "/link"), replacements={"/link": revised_link})

Every mapping key must be an explicit replay target. Target order, frames and stable random scopes remain explicit. This is an atomic bounded replay, not an automatic dependency loop. connect bindings now consume capacity without acquiring a host's separate mutation grant. The two changes and their pre-change failures are recorded in api-delta.md.

For extension artifacts, import hearth_extensions before load_scene to register its validators. python -m examples.extension_inspection --seed 0 --input samples/extensions/campus-0.litematic prints actual deck, glass and mounted-light queries, exports the pair and verifies the same queries after reload. inspection.json retains a completed run.

Diagnostics and failure behavior

ContractError.diagnostic contains rule, component, position and conditions. ValidationError.diagnostics reports actual geometry violations. Examples include write-authority, whole-object, edit-limit, protected-region, support, clearance, reachability, lighting, door-pair, pool-containment, forwarded-interface and geometry-mismatch.

Failed candidates leave the entire scene unchanged. SearchExhausted distinguishes a search budget from an established parameter/contact incompatibility. A failed finite search does not prove that no other algorithm or composition can succeed. Tests include a budget-limited rejection where the next, unvisited candidate is valid.

First-phase evidence and continuing limits

The frozen sampling policy is reports/sampling-policy.json. The retained first-phase results are reports/final-corpus/results.json, summary.json and adaptation-inputs.json. Earlier result records remain under reports/baseline-corpus/ and reports/corpus/; their historical sample paths are labeled as superseded, not current matching artifacts.

reports/ASSESSMENT.md gives denominators, costs and timings: 134 tests passed, 64/64 adaptation inputs, 24/24 building runs and 10/10 settlement runs validated. The stress batch retained 9 valid / 32 inputs, plus 23 explicit limit incompatibilities. There were no budget-exhausted or unexplained-defect cases in the final corpus. Per-candidate acceptance is reported separately. Seed-0 content matches across two Python hash seeds in reports/replay.json. All 24 delivered current artifact pairs passed reload and identity checks in reports/artifact-audit.json.

The assessed finite budget consists of 64 independent environment/building pairings, 24 building runs (three clients, seeds 0-7), ten settlement runs (seeds 0-7 plus both count boundaries), and 32 unresampled stress inputs. Sixteen complete terrain scenes are frozen independently before placing buildings. Half the environment expressions use the held-out blend/transform composition. The same public measured-geometry adapters handle all cases.

The reported successful building corpus has 18 observed principal signatures: dwelling 5/8, atelier 8/8, commons 5/8. The ten settlement runs have 10 observed signatures. Signatures exclude names, surface materials and global placement; they include actual room extents, adjacencies, storeys/stairs, roof geometry and path organization. Foundation/contact signatures are reported separately and never counted as principal architectural variety. This is finite observation only.

Known limits remain explicit:

  • The movement model uses integer standing positions, operable wooden doors, two-cell headroom and bounded one-block elevation changes. It is not the full Minecraft collision or jump simulation.
  • Lighting uses actual source propagation/occlusion at required room locations; it is not a complete skylight, mob-spawning or Minecraft update simulation.
  • Declared support paths and bounded spans are checked. Arbitrary structural stress, every decorative cantilever, and universal watertight flashing for arbitrary roof intersections are not proved. The original roof system handles bounded gables, runs and wall abutments over sealed ceilings. The extension adds polygon hip courses and a bounded roof lantern, not arbitrary roof intersections.
  • General block/entity migration, arbitrary entity generation, a browser viewer, and a full city planner are not implemented. Exported entity lists are empty; barrel inventories are real NBT.
  • Regeneration is explicit and can be coarse. The kernel records affected dependencies and refuses stale completion; it does not invent an unbounded automatic replan or resolve every terrain shape.
  • The provided style is coherent timber/stone architecture, with visible modular bays. The small representative render set supports inspection, not an exhaustive aesthetic judgment or a claim to reproduce all sixteen reference images.
  • The courtyard example's central planted void is an unoccupied lightwell. Its room ring is connected; visitor access to the central garden is not part of that client's contract.

Extension-phase commands and evidence

The extension programs use the same public contracts; they do not alter the default CLI or invoke reference generators. A low-level example connects already placed buildings without knowing their private geometry, and a graph example substitutes different access providers, in hearth_extensions/README.md.

python -m examples.extension_generate campus --seed 3 --environment-seed 7 --output "samples/new campus.litematic" python -m examples.extension_generate perimeter --seed 3 --environment-seed 3 --output "samples/new perimeter.litematic" python -m examples.extension_assess --seed 0 --output reports/extension-reassessment --artifacts --samples samples/extension-reassessment python -m examples.extension_audit --seed 0 --manifest samples/extension-reassessment/replay-manifest.json --output reports/extension-reassessment/artifact-audit.json --cli python -m examples.extension_replay --seed 3 --environment-seed 7 --output reports/extension-reassessment/replay.json python -m examples.extension_views --seed 0 --input samples/extensions/campus-0.litematic --output previews/extension-reassessment --sections

Each environment is generated independently and frozen before placement. --seed controls structure; --environment-seed controls the field input. Assessment --seed selects the root environmental seed range; structure seed ranges remain the explicit sampling policy. --samples prevents a new assessment from overwriting earlier matching pairs. Unit tests continue to use cleaned temporary directories under test/.

reports/extension-corpus/ASSESSMENT.md reports the new test, sampling, identity and render results with denominators and limits. It supplements every first-phase result above. The frozen policy defines 48 connector pairings, 16 boundary pairings, 12 hall runs, 12 graph runs and 24 unresampled stress inputs. The interior refinement policy repeats those same inputs after a cutaway-driven furnishing improvement. Prior results and matching artifact pairs are retained. Principal signatures exclude contact geometry and cosmetic/furnishing counts.

Only two general kernel behaviors changed: read-only connection authority and explicitly mapped coupled replay replacements. There is no private-state access in the extension's components or ordinary clients. Metadata inspection and assessment intentionally read the public structural records. Clients still need documented public port kinds, frames, dimensions, grants and locked placement intent. A new architectural technique requires an implementation with a valid contract; this is not an unrestricted description-to-building solver. The supplied style remains relatively restrained, and a finite render set does not establish universal aesthetic quality.

The user's external report describes successful prior Pyodide executions. This phase preserves the pure-Python boundary, runs native hash-seed replay and restores complete structural records from its new pairs. It does not claim a new browser execution or independent audit.

Requirement ledger

ID Implemented API/module and evidence Qualification
R01 kernel/*, initial design, seven foundation tests before content; thin CLI Executable foundation, not placeholder interfaces
R02 Independent implementation; supplied snapshots unchanged; reference images used as aesthetic goals No reference generator invoked or imported
R03 Blueprint, room graph programs, Choice, roof planner, spine/loop paths; finite signatures Room grid and roof primitives are bounded, openly documented
R04 Module table in architecture; kernel has no component imports; transport separate Browser host adapter not implemented
R05 Capability, executable Domain, Contract, Port, Grant, rules and read-only View Free-form descriptive assumptions complement executable checks
R06 Plan/Child/Choice, registry, composition operations, forwarded ports; extension/nested tests New primitives can extend beyond the shipped grid vocabulary
R07 Scoped authority, whole-object replacement, shared support; tree/grass/pool/window/clearance tests No universal priority or same-state sharing shortcut
R08 Fork/validate/commit kernel, plans and automatic read traces; rollback snapshots Trusted Python components, not a hostile-code sandbox
R09 Open/complete scopes, ancestor-aware obligations, finalization; unfinished/light and late-edit tests Standalone landing-to-public-path is an enclosing obligation
R10 Automatic nodes/operation owners, real window/wall instances; inspection and cross-scope attachment tests No per-voxel client owner maps or post-hoc tagging
R11 Structural graph, dependency graph, operations/displacement records; update/share/removal tests Historic actors may remain in history, never as current owners
R12 inspect, owner/shared reverse indexes, semantic descendant index; regeneration and deletion tests Headless queries delivered; no clickable viewer
R13 Paired JSON/Litematica, version/digest/offset checks, actual reload validation; mismatch/NBT tests Pairing integrity is not cryptographic authenticity
R14 General field algebra, masks, transforms, strata, water and constrained scattering No environment-family dispatch; finite shipped operations are extensible
R15 Domain/version-aware 3D view, elevation cap, support/water/slope/clearance/style/preferences Unknown space errors; no simulation of every Minecraft behavior
R16 Foundation, approach, window-depth and roof-abutment components Universal roof-junction/flashing solver not implemented
R17 Frozen terrain, measured site survey, bounded complete candidates, joint tentative validation Fixed principal intent; failures beyond bounds are retained
R18 Hard checks then actual effect cost/exposure score, seeded near-best choice, rejection records Search-budget negative test; no claim of exhaustive feasibility
R19 Automatic/declared input dependencies, stale flags, explicit atomic co-regeneration Dependency updates are conservative; no implicit arbitrary auto-replan
R20 SHA-256 scope keys/purposes, overrides, copied environments; branch/order/retry and hash-seed replay tests Genuine spatial dependencies may change descendants
R21 Configurable Limits, SiteLimits, effect envelopes and realized export bounds Demonstration count bound is only in the CLI
R22 Initial design, kernel tests, prototype, buildings/extension, corpus/render stages Generic defects and fixes recorded in development findings
R23 test_kernel, test_contracts_provenance: substitution, independent extension, authority, rollback, sharing, transforms, seeds Custom validator registration also tested
R24 Glass chain, two identities, external attachment membership, updates/deletions/regeneration, shared cells, transport mismatch tests Actual structure restored from companion, not inferred from materials
R25 64 frozen pairings, compatible independent field/environment, protected outside cells, perturbation and stress records Finite supported domain; 32 stress inputs retained without resampling
R26 Three short clients x eight seeds; settlement x eight seeds plus counts 3 and 6; later courtyard/gallery Programs use public room/component APIs
R27 Actual blocks/NBT: schema, support, headroom/routes, pair consistency, enclosure, lights, furnishings, pools and path joins; deliberate damage tests Physical/lighting model limitations above apply
R28 Structural/contact signatures, exterior views, circulation/furnishing cutaways, inspection notes Modular aesthetic remains visible; no exhaustive beauty claim
R29 generate.py, importable scene builders, inspection example, verified one-region transport Offline runtime uses bundled schema and installed/provided MCIO
R30 Library, docs, CLI, tests, extension, output pair, manifest, reports and labeled previews Broader simulation, arbitrary entities, browser UI and city planner remain unfinished

The first-phase ledger above remains applicable. This supplemental ledger maps every requirement to the new work or its explicit regression evidence; qualifications from both phases apply.

ID Extension-phase API and evidence Remaining boundary
R01 Pre-change API/hash baseline; unchanged-kernel probe; separate extension modules and focused tests before client expansion Self-authored exercise
R02 New package, geometry and graph clients; original snapshots untouched No reference code reused
R03 Polygon, Pavilion, HipRoof, Link, Campus; actual massing/topology signatures Finite vocabularies and explicit graph placements
R04 hearth_extensions imports public kernel/services; generation, CLI, assessment and previews separate No new browser runtime claimed
R05 Endpoint kind/frame/width/capacity checks; fixture grants; domain/grade/fill/span contracts Point endpoint offers are not broad landing replacements
R06 BoundaryChain, Campus, HallInterior; forwarded mounts/access; platform/pavilion substitution test Arbitrary concave layouts remain outside assessed domain
R07 Read-only connection negative write test; scoped terrain edits; overflow, protected aisle and whole-removal tests New connectors do not acquire host resurfacing permission
R08 Full geometry/graph/index rollback snapshots in test_extension_failures Same trusted-component boundary
R09 Final graph routes and reachable interior stations; late blockers rejected Open galleries deliberately lack enclosed-room obligations
R10 Actual trestle/deck/window/shell/bay/lamp children; headless inspection output No hand-authored ancestry
R11 Two endpoint associations, attachment vs containment, separate input reads and operation records Existing semantic graph model retained
R12 Exact current cells across replacement/removal; transform and audit queries No viewer added
R13 New manifest audit compares regenerated nodes, graphs, inventories and queries with reloaded pairs Validator package import required; bare geometry remains untrusted
R14 General field expressions plus curves, polygon masks and explicit connection graphs Simple discrete geometry, not a general mesh engine
R15 Frozen 3D support/water/occupancy queries along routes and contour bases Unknown space still errors
R16 Trestles, bounded route profile, endpoint mouth transitions, terrain-following boundary Finite engineering strategies
R17 Frozen environments, locked endpoints/vertices, local grants, atomic link and campus placement No moving locked buildings to hide failures
R18 Feasible profile propagation and furnishing-domain construction; stress diagnostics retained One locked complete candidate per assessed input; no exhaustive search claim
R19 Explicit regenerate(..., replacements=...); coupled host/link and boundary/lamp replay tests Conservative coarse invalidation remains
R20 Scoped streams, hash-seed subprocess replay, failed-choice stability; baseline default digest retained Real constraints may affect dependent branches
R21 Existing limits plus route length, span, fill, per-segment contour and bounded furnishing domains Library count is not fixed to demo size
R22 Baseline -> failing probe -> protocol delta -> components -> new clients -> corpus -> inspected refinement Development failures retained
R23 New extension protocol/geometry/failure/interior tests plus all unchanged original tests Extension is not an external audit
R24 Shared endpoint ownership, deletion/replacement, transforms, every-node audit, mounted-light and window chains Companion format remains version 1
R25 64 new independent environment/structure connector and boundary pairings; novel kink/polygon test; 24 stress rows Not a proof over all parameter combinations
R26 Original 3 clients x seeds 0-7 and count boundaries retained; two new graph clients x seeds 0-5 and 12 polygon halls New graphs add to, not replace, original corpus
R27 Actual route/headroom/support/guard/frame/fixture/interior tests, damage cases, inventory reload Discrete movement, lighting and bounded-span model
R28 New principal/contact signatures, multi-angle views, floor/connection sections; shared interior refinement Open lawns and modular material language remain visible
R29 Original generate.py unchanged; no-argument, seed-1, spaced paths and hash-seed replay checked Transport dependencies unchanged
R30 Separate docs/reports/samples/previews, replay manifests and runnable batches Browser rerun, autonomous city planner and broader simulation remain unfinished

本页是第二轮独立报告;第一轮报告保留当时产物和判断。新增证据应与原始目标对应,不能因为测试数和代码规模变大,就把未解决的布局、美学及开放式组合问题当作已经完成。