Lane E S18 gate 4: THE GLASSHOUSE TIER — the hail-net frame, and the apex made reachable
S16 shipped the glasshouse and priced it at $320. e.test said the rest in its own words: "nothing in the sim wrecks a glasshouse yet — the value is inert data". main.js bills collateral off a broken rig corner's baked key, and a glasshouse rightly offers no anchors, so the most expensive object in the game could not cost anybody a cent — RULE 2's mirror image, a price with no key that can reach it. DESIGN.md line 179 named the missing asset: hail nets rigged OVER glass. You tie to the frame that straddles it. hail_net_frame_01 / _wrecked: a powder-coat portal frame clear of the glasshouse on all four sides, head at 2.75 m to clear the 2.28 ridge, four welded eyes at 2.690 baking collateral 'glasshouse'. The tell is a POSITION, not a defect — the frame's numbers are good and the hazard is where it stands. Pinned as geometry off two GLBs (footprint strictly contains the glass; head clears the ridge) rather than as paint on one. The 20 m read is metalness: powder-coat at 0.05 renders bright where every trusted galvanised steel at 0.90 goes near-black with no environment map (S17's measured lesson, applied on purpose this time). Rung 0.80, proposal, A rules: it earns the highest rung below the honest post (engineered frame, four footings, the only structure built to be tied to) and is de-rated 20% for section, not condition. It usually holds — that is the tier: the corner failure that costs a shackle on a sail post costs $320 here. The root deliberately carries NO collateral_key. structFor() takes the first match, so a frame claiming the glass's key would bill the panes and wreck the frame, both papers agreeing and both wrong. That omission is gate 5 in one line. Wreck racks at one end (0.45 in at the head, 0.45 out at the feet) after the first cut still read as a clean level rectangle in the render. Carries no glass: the glasshouse swaps independently. Unpriced by ruling. ANCHOR_TYPE widened with 'hail_net_frame' (contracts.js is A's — revert and tell me; corroded_post precedent). Manifest unambiguous: 0.80, glasshouse, 4 sources. Determinism held: runs 2 and 3 are 56/56 byte-identical. NOTE the shipped GLBs were exported by Blender 5.1.2 and this box has 5.0.1 — the 45-binary churn that causes is semantically nil (60 nm accessor drift, PNGs losing sRGB/gAMA/cHRM with identical pixels) and was reverted, not shipped. Documented in the header. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e6d4c36daa
commit
00e6b288c8
@ -1,5 +1,5 @@
|
||||
{
|
||||
"blender": "5.1.2",
|
||||
"blender": "5.0.1",
|
||||
"assets": [
|
||||
{
|
||||
"name": "ref_capsule",
|
||||
@ -817,6 +817,73 @@
|
||||
"status": "PASS",
|
||||
"problems": []
|
||||
},
|
||||
{
|
||||
"name": "hail_net_frame_01",
|
||||
"dims": [
|
||||
3.42,
|
||||
3.02,
|
||||
2.766
|
||||
],
|
||||
"tris": 328,
|
||||
"nodes": [
|
||||
"footings",
|
||||
"hail_net_frame_01",
|
||||
"legs",
|
||||
"net_anchor_01",
|
||||
"net_anchor_02",
|
||||
"net_anchor_03",
|
||||
"net_anchor_04",
|
||||
"net_roll",
|
||||
"top_frame"
|
||||
],
|
||||
"anchors": [
|
||||
{
|
||||
"node": "net_anchor_01",
|
||||
"anchor_type": "hail_net_frame",
|
||||
"rating_hint": 0.8,
|
||||
"collateral": "glasshouse"
|
||||
},
|
||||
{
|
||||
"node": "net_anchor_02",
|
||||
"anchor_type": "hail_net_frame",
|
||||
"rating_hint": 0.8,
|
||||
"collateral": "glasshouse"
|
||||
},
|
||||
{
|
||||
"node": "net_anchor_03",
|
||||
"anchor_type": "hail_net_frame",
|
||||
"rating_hint": 0.8,
|
||||
"collateral": "glasshouse"
|
||||
},
|
||||
{
|
||||
"node": "net_anchor_04",
|
||||
"anchor_type": "hail_net_frame",
|
||||
"rating_hint": 0.8,
|
||||
"collateral": "glasshouse"
|
||||
}
|
||||
],
|
||||
"status": "PASS",
|
||||
"problems": []
|
||||
},
|
||||
{
|
||||
"name": "hail_net_frame_01_wrecked",
|
||||
"dims": [
|
||||
4.3007,
|
||||
3.02,
|
||||
2.7832
|
||||
],
|
||||
"tris": 480,
|
||||
"nodes": [
|
||||
"footings",
|
||||
"hail_net_frame_01_wrecked",
|
||||
"legs",
|
||||
"net_down",
|
||||
"top_frame"
|
||||
],
|
||||
"anchors": [],
|
||||
"status": "PASS",
|
||||
"problems": []
|
||||
},
|
||||
{
|
||||
"name": "pool_kit_01",
|
||||
"dims": [
|
||||
@ -955,5 +1022,42 @@
|
||||
"problems": []
|
||||
}
|
||||
],
|
||||
"debris": []
|
||||
"debris": [
|
||||
{
|
||||
"file": "BlueCrate_v2.glb",
|
||||
"dims": [
|
||||
0.36,
|
||||
0.36,
|
||||
0.29
|
||||
],
|
||||
"sane": true
|
||||
},
|
||||
{
|
||||
"file": "BlackTub_v2.glb",
|
||||
"dims": [
|
||||
0.36,
|
||||
0.54,
|
||||
0.2
|
||||
],
|
||||
"sane": true
|
||||
},
|
||||
{
|
||||
"file": "WhiteTub_v2.glb",
|
||||
"dims": [
|
||||
0.36,
|
||||
0.54,
|
||||
0.2
|
||||
],
|
||||
"sane": true
|
||||
},
|
||||
{
|
||||
"file": "WoodenBin_v2.glb",
|
||||
"dims": [
|
||||
0.35,
|
||||
0.36,
|
||||
0.31
|
||||
],
|
||||
"sane": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -20,6 +20,25 @@ Outputs (resolved from this file, so no absolute home paths):
|
||||
tools/blender/contact_sheet.png verification render vs the 1.7 m capsule
|
||||
tools/blender/asset_report.json measured dims / tris / node names
|
||||
|
||||
⚠️ BLENDER VERSION IS PART OF THE OUTPUT (SPRINT18, E — measured, not guessed).
|
||||
The shipped GLBs were exported by Blender **5.1.2** (glTF I/O v5.1.20), which
|
||||
`asset_report.json` records in its `blender` field — check it before you
|
||||
build. On Blender 5.0.1 (I/O v5.0.21) this script is still perfectly
|
||||
deterministic — three consecutive full runs gave 56/56 byte-identical
|
||||
artifacts — but its output DIFFERS from the shipped files in two ways, and
|
||||
both are cosmetic:
|
||||
· GLB accessor min/max drift in the 7th decimal (~6e-8 m, i.e. 60 nm).
|
||||
Node graph, mesh topology, materials and every custom prop are
|
||||
bit-identical; only float formatting of the bounds moves.
|
||||
· The generated PNGs lose their sRGB/gAMA/cHRM chunks — 73 bytes per file.
|
||||
IDAT pixel data decompresses bit-identically; the newer exporter simply
|
||||
writes colour-space chunks that 5.0.x omits.
|
||||
So a full run on the wrong Blender rewrites all 45 binaries with no change
|
||||
anybody asked for, and quietly DROPS the colour-space chunks. If your `git
|
||||
status` shows every GLB and texture modified after adding one asset, that is
|
||||
this and not your work: `git checkout --` the ones you did not author, and
|
||||
commit only the new files. Better: build on 5.1.2 and the churn is zero.
|
||||
|
||||
Idiom follows ~/Documents/Destroyulater/3D-STORE/racks_to_glb.py:
|
||||
reset_to_empty() per asset -> build under a root empty AT THE ORIGIN ->
|
||||
join by group -> stamp custom props -> export_scene.gltf(export_yup=True,
|
||||
@ -150,6 +169,23 @@ PAL = {
|
||||
# a pool is the one water in the game that is
|
||||
# supposed to look inviting
|
||||
"deck_board": "#A8845C", # decking oil, a shade lighter than fence timber
|
||||
"net_frame_white": "#E6E7E1", # SPRINT18 gate 4 — the hail-net frame's
|
||||
# powder-coat, and the BRIGHTEST entry in this
|
||||
# palette on purpose. The reason is metalness,
|
||||
# not lightness — S17's measured lesson applied
|
||||
# deliberately this time. Galvanised ships at
|
||||
# metallic 0.90, and with no environment map a
|
||||
# near-mirror has nothing to mirror, so every
|
||||
# steel you are ALLOWED to trust renders
|
||||
# near-black at yard distance (measured: rgb
|
||||
# 49,51,49 at 20 m). Powder-coat is paint —
|
||||
# metallic 0.05, diffuse — so this frame reads
|
||||
# as a white cage standing over the glass from
|
||||
# the far fence, and can never be misread as
|
||||
# the galvanised steel of an honest sail post.
|
||||
"net_mesh": "#3A4340", # knitted HDPE hail mesh: dark, matte, and the
|
||||
# only large dark mass any yard carries up at
|
||||
# 2.7 m. Rolled it is a bar; down it is a heap.
|
||||
}
|
||||
|
||||
# Rainwater caught in a sail is not swimming-pool blue. It's shallow, murky, it
|
||||
@ -1916,6 +1952,283 @@ def build_glasshouse_01_wrecked(name):
|
||||
return root
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# THE HAIL-NET FRAME (SPRINT18 gate 4 — the glasshouse tier's LIVE half)
|
||||
# ---------------------------------------------------------------------------
|
||||
# SPRINT16 shipped the glasshouse and priced it at 320. SPRINT18 read the gate
|
||||
# and found the thing the price was waiting on, written in e.test's own words:
|
||||
# "nothing in the sim wrecks a glasshouse yet — the value is inert data". The
|
||||
# apex could not be reached. main.js bills collateral off a BROKEN RIG CORNER
|
||||
# (`world.anchor(c.anchorId).collateral`), and a glasshouse deliberately offers
|
||||
# no anchors — correctly, it is the one rule pinned from every direction — so
|
||||
# the most expensive object in the game could not cost anybody a cent. That is
|
||||
# the free-failure bug inverted: not a hazard billing nothing by accident, but
|
||||
# a hazard that cannot bill at all by construction.
|
||||
#
|
||||
# DESIGN.md line 179 already named the missing asset: "Jobs: hail nets and mesh
|
||||
# sails rigged OVER glass, where your own failure is the worst debris of all."
|
||||
# You do not tie to the glasshouse. You tie to the frame that STRADDLES it —
|
||||
# and every corner of that frame is a corner whose failure drops steel, cloth
|
||||
# and hardware through fourteen panes.
|
||||
#
|
||||
# So this is the tier, and its teaching is new. Every other trap in this game
|
||||
# punishes you with a bad number: the carport beam at 0.22, the fascia at 0.35,
|
||||
# the corroded post at 0.55 whose real capacity you cannot read. This one is
|
||||
# GOOD hardware — purpose-built, plumb, on its own footings, factory eyes —
|
||||
# and it is the most dangerous anchor in the game because of WHERE IT STANDS.
|
||||
# The rating is not the hazard. The position is.
|
||||
NET_FRAME = dict(
|
||||
CLEAR_X=0.30, # portal stands this far clear of each gable end
|
||||
CLEAR_Y=0.45, # legs stand this far outside the long walls, on soil
|
||||
HEAD_H=2.75, # head-beam height. MUST clear the ridge (2.28) — a frame
|
||||
# that fouled the glass it protects is a joke, and
|
||||
# e.test measures the clearance off the two shipped GLBs.
|
||||
TUBE=0.032, # 32 mm net-frame section
|
||||
PAD=0.22, # footing pad
|
||||
)
|
||||
|
||||
# The rung. PROPOSAL — Lane A rules the number, same as every rung before it.
|
||||
#
|
||||
# Ladder as shipped: 0.22 carport beam < 0.30 carport post < 0.35 house fascia
|
||||
# < 0.45 swing frame < 0.55 corroded post < 0.65 pergola < 1.00 sail post.
|
||||
# This goes at 0.80, and the argument has two halves:
|
||||
#
|
||||
# · WHY IT OUT-RATES THE PERGOLA (0.65) BY A DISTANCE. The pergola is a deck
|
||||
# structure screwed to a house and it flexes; the corroded post's capacity
|
||||
# is unknowable; the swing frame stands on grass. This is an engineered
|
||||
# portal frame on four real footings with welded eyes, and it is the only
|
||||
# structure in the palette that was BUILT to be tied to. Rating it near the
|
||||
# bad steel would be the lie the corroded post exists to punish, inverted:
|
||||
# honest steel de-rated for looking dangerous.
|
||||
# · WHY IT IS NOT THE SAIL POST (1.00). The section is 32 mm sized for hail
|
||||
# mesh — a couple of hundred grams per square metre, and near-zero drag
|
||||
# because mesh SPILLS wind rather than catching it. A 25 m² impermeable
|
||||
# shade sail in a southerly is a load one order of magnitude larger. 0.80
|
||||
# is a 20% de-rate for "engineered for a load you are about to exceed".
|
||||
#
|
||||
# And 0.80 is chosen so that IT USUALLY HOLDS. That is the point of the tier,
|
||||
# not a softness in it: a corner that fails one night in five costs you nothing
|
||||
# on a sail post and 320 dollars here. The player who learns "0.80 is fine" on
|
||||
# every other yard is exactly the player this yard is for. The lesson is not
|
||||
# "don't trust this steel" — the steel is fine. It is "the same failure has a
|
||||
# different price depending on what is underneath it", which is the sentence
|
||||
# DESIGN.md line 179 has been waiting for an asset to say.
|
||||
NET_FRAME_RATING = 0.80
|
||||
|
||||
|
||||
def _net_frame(name, root, steel, conc, mesh_m, *, wrecked=False):
|
||||
"""The portal frame, shared by intact and wreck so the two cannot drift.
|
||||
|
||||
The wreck fails at the -x portal ONLY: its feet kick out of their pads and
|
||||
its head beam comes down onto the glasshouse ridge. +x stands, holding the
|
||||
eave rails up, which is why the wreck keeps the intact height — a hail-net
|
||||
frame does not fall over, it folds at one end, and the end it folds is the
|
||||
end that empties the glass."""
|
||||
G, N = GLASSHOUSE, NET_FRAME
|
||||
hx = G["W"] / 2 + N["CLEAR_X"] # 1.60 — clear of the gable ends
|
||||
hy = G["D"] / 2 + N["CLEAR_Y"] # 1.40 — clear of the long walls
|
||||
H, r, pad_h = N["HEAD_H"], N["TUBE"] / 2, 0.06
|
||||
|
||||
def foot(sx, sy):
|
||||
"""Where the leg meets the ground. Wrecked -x feet are OUT of the pad —
|
||||
a foot beside its own footing is the most legible steel failure there
|
||||
is, and it costs one offset to say."""
|
||||
if wrecked and sx < 0:
|
||||
return (sx * hx - 0.45, sy * hy, pad_h + (0.14 if sy > 0 else 0.0))
|
||||
return (sx * hx, sy * hy, pad_h)
|
||||
|
||||
def head(sx, sy):
|
||||
"""Where the leg meets the top frame. The wrecked -x portal has come
|
||||
down and is RESTING ON THE RIDGE (2.28) rather than passing through it:
|
||||
the glasshouse's own wreck keeps its aluminium frame standing at full
|
||||
height, so a beam that ended up below the ridge line would be inside
|
||||
it. Lying ACROSS the ridge is both true and non-interpenetrating.
|
||||
|
||||
The head comes IN (+x, dragged by the sail) while the feet kick OUT
|
||||
(-x) — the portal RACKS into a parallelogram, the carport's failure
|
||||
mode on a lighter section. The offsets are deliberately large (0.45
|
||||
each way, ~22° of lean over 2.3 m) because I looked at 0.30/0.16 in
|
||||
the render and the top frame still read as a clean level rectangle:
|
||||
a 0.43 m drop on a 2.77 m frame of 32 mm tube is invisible in
|
||||
perspective, and a wreck you cannot see is not a wreck."""
|
||||
if wrecked and sx < 0:
|
||||
return (sx * hx + 0.45, sy * hy * 0.90, G["RIDGE_H"] + 0.05)
|
||||
return (sx * hx, sy * hy, H)
|
||||
|
||||
def mid(sx):
|
||||
a, b = head(sx, -1), head(sx, 1)
|
||||
return ((a[0] + b[0]) / 2, 0.0, (a[2] + b[2]) / 2)
|
||||
|
||||
pads, legs = [], []
|
||||
for sx in (-1, 1):
|
||||
for sy in (-1, 1):
|
||||
pads.append(add_box(f"{name}_pad_{sx}_{sy}", (N["PAD"], N["PAD"], pad_h),
|
||||
(sx * hx, sy * hy, pad_h / 2), conc))
|
||||
legs.append(add_tube_between(f"{name}_leg_{sx}_{sy}",
|
||||
foot(sx, sy), head(sx, sy), r, steel, verts=8))
|
||||
join_group(pads, "footings", root)
|
||||
join_group(legs, "legs", root)
|
||||
|
||||
top = []
|
||||
for sx in (-1, 1): # portal head beams, spanning y
|
||||
top.append(add_tube_between(f"{name}_head_{sx}", head(sx, -1), head(sx, 1),
|
||||
r, steel, verts=8))
|
||||
for sy in (-1, 1): # eave rails, spanning x
|
||||
top.append(add_tube_between(f"{name}_eave_{sy}", head(-1, sy), head(1, sy),
|
||||
r, steel, verts=8))
|
||||
# The tensioning wire down the middle, deliberately thinner than the frame:
|
||||
# at 20 m the gauge difference is the "made for a net" read, and it is the
|
||||
# honest reason the whole thing rates 0.80 instead of 1.00.
|
||||
top.append(add_tube_between(f"{name}_ridge_line", mid(-1), mid(1),
|
||||
r * 0.35, steel, verts=6))
|
||||
join_group(top, "top_frame", root)
|
||||
|
||||
if not wrecked:
|
||||
# Rolled along the +y eave, because the JOB is to rig it. A deployed
|
||||
# net would be a finished yard, and this asset exists to be worked on.
|
||||
join_group([add_tube_between(f"{name}_roll", (-hx, hy, H - 0.11),
|
||||
(hx, hy, H - 0.11), 0.085, mesh_m, verts=10)],
|
||||
"net_roll", root)
|
||||
else:
|
||||
# YOUR debris, not the storm's. The net has come off its lashings at the
|
||||
# collapsed end and is draped down over the glass and heaped out past
|
||||
# the footing — deterministic scatter, so the same wreck twice.
|
||||
rng = rng_for(name)
|
||||
drape = []
|
||||
pts = [(hx * 0.85, hy, H - 0.10),
|
||||
(hx * 0.10, hy * 0.92, H - 0.78),
|
||||
(-hx * 0.55, hy * 0.80, G["RIDGE_H"] * 0.55),
|
||||
(-hx - 0.28, hy * 0.55, 0.24),
|
||||
(-hx - 0.80, hy * 0.20, 0.06)]
|
||||
for i in range(len(pts) - 1):
|
||||
drape.append(add_tube_between(f"{name}_net_sag_{i}", pts[i], pts[i + 1],
|
||||
0.055, mesh_m, verts=6))
|
||||
for i in range(9):
|
||||
a = rng.uniform(0, math.tau)
|
||||
rr = rng.uniform(0.05, 0.45)
|
||||
drape.append(add_box(
|
||||
f"{name}_net_heap_{i}",
|
||||
(rng.uniform(0.22, 0.50), rng.uniform(0.16, 0.40), rng.uniform(0.03, 0.09)),
|
||||
(-hx - 0.58 + math.cos(a) * rr, hy * 0.20 + math.sin(a) * rr * 0.8,
|
||||
rng.uniform(0.02, 0.07)),
|
||||
mesh_m, rot=(0, 0, rng.uniform(0, math.pi))))
|
||||
join_group(drape, "net_down", root)
|
||||
|
||||
return hx, hy
|
||||
|
||||
|
||||
def build_hail_net_frame_01(name):
|
||||
"""The hail-net frame — four good anchors in the worst place in the game.
|
||||
|
||||
The glasshouse tier's live half (SPRINT18 gate 4). This is what DESIGN.md
|
||||
line 179 means by "hail nets and mesh sails rigged OVER glass": a portal
|
||||
frame that straddles the glasshouse, clear of it on all four sides, with a
|
||||
head height that clears the ridge and a rolled mesh net waiting to go up.
|
||||
|
||||
THE TELL, and it is a position rather than a defect. Every reading of every
|
||||
other trap in this game is a bad number on the object. This object's numbers
|
||||
are GOOD — 0.80, plumb, four footings, welded eyes — and what the player has
|
||||
to read instead is the plan view: the frame BRACKETS the glass. e.test pins
|
||||
that geometrically off the two shipped GLBs (frame footprint strictly
|
||||
contains the glasshouse footprint; head height strictly clears the ridge),
|
||||
because "it stands over the glass" has to be a measurement, not a vibe.
|
||||
The 20 m read is the powder-coat: white, matte, metallic 0.05, against a
|
||||
palette where every trustworthy steel is metallic 0.90 and therefore renders
|
||||
near-black. A white cage over a glass box, visible from the far fence.
|
||||
|
||||
WHAT THE ANCHORS SAY. All four bake collateral="glasshouse". They are the
|
||||
only nodes in the palette whose collateral names a DIFFERENT structure than
|
||||
the one they sit on (the house's fascia→"gutter" is the precedent, and it is
|
||||
the same shape: the anchor names what its failure TAKES, not what it is).
|
||||
Break a corner here and the sail, the shackle and the turnbuckle go through
|
||||
fourteen panes: your own failure is the worst debris of all, wired as data.
|
||||
|
||||
AND WHAT THIS ROOT DELIBERATELY DOES NOT CARRY: collateral_key. See below —
|
||||
it is the whole of gate 5 in one omission.
|
||||
"""
|
||||
root = add_empty(name)
|
||||
# Powder-coat is PAINT, so metallic stays near zero. This is not a style
|
||||
# choice, it is the S17 measurement: high metalness with no environment map
|
||||
# renders near-black, and this asset's entire long-range tell is that it is
|
||||
# the brightest thing in the yard.
|
||||
steel = get_material("Mat_NetFrame", PAL["net_frame_white"], 0.50, metallic=0.05)
|
||||
mesh_m = get_material("Mat_HailNet", PAL["net_mesh"], 0.85, metallic=0.0)
|
||||
conc = get_material("Mat_Concrete", PAL["concrete"], 0.95)
|
||||
|
||||
hx, hy = _net_frame(name, root, steel, conc, mesh_m)
|
||||
|
||||
# The four eyes, at the four corners of the top frame — where a net corner
|
||||
# ties, and therefore where a sail corner will be tied instead.
|
||||
for i, (sx, sy) in enumerate(((-1, -1), (1, -1), (1, 1), (-1, 1))):
|
||||
e = add_empty(f"net_anchor_{i + 1:02d}",
|
||||
(sx * hx, sy * hy, NET_FRAME["HEAD_H"] - 0.06), root, size=0.18)
|
||||
e["anchor_type"] = "hail_net_frame"
|
||||
e["rating_hint"] = NET_FRAME_RATING
|
||||
e["collateral"] = "glasshouse"
|
||||
e["why"] = ("sound steel, and the most expensive corner on the board: it is "
|
||||
"rated for hail mesh, and everything it drops lands on glass")
|
||||
|
||||
stamp(root, name, "structure")
|
||||
root["site_hint"] = "glasshouse"
|
||||
root["is_anchor_trap"] = True
|
||||
root["rated_for"] = ("knitted hail mesh, ~0.2 kg/m2, near-zero drag — mesh spills "
|
||||
"wind. A 25 m2 impermeable sail is an order of magnitude more.")
|
||||
# ⚠️ NO collateral_key ON THIS ROOT, AND THAT IS THE POINT (gate 5).
|
||||
#
|
||||
# world.js resolves a collateral key to a structure with structFor(), which
|
||||
# returns the FIRST structure in site order whose key matches. If this frame
|
||||
# claimed collateral_key="glasshouse" — which looks like the helpful thing
|
||||
# to do, since its anchors bill that key — then in a yard where the frame is
|
||||
# authored before the glasshouse, every failure would bill "the glasshouse"
|
||||
# for 320 dollars and then WRECK THE FRAME: the player watches their own
|
||||
# frame fold while the invoice charges them for panes that are still in
|
||||
# their rebates. The bill and the wreck would agree with each other and
|
||||
# both be wrong, which is the only kind of wrong this repo cannot see.
|
||||
#
|
||||
# So exactly ONE structure owns a key, and it is the one that owns the
|
||||
# price. This frame POINTS at the key and never claims it. The pointer
|
||||
# lives in a field nothing resolves, so it can document intent without
|
||||
# arming anything.
|
||||
root["collateral_target"] = "glasshouse"
|
||||
root["rigs_over"] = "glasshouse_01"
|
||||
return root
|
||||
|
||||
|
||||
def build_hail_net_frame_01_wrecked(name):
|
||||
"""The frame after the corner you trusted let go.
|
||||
|
||||
The -x portal has folded: both its feet are out of their pads, and its head
|
||||
beam is lying across the glasshouse ridge with the net draped down over the
|
||||
glass and heaped out past the footing. The +x portal stands, holding the
|
||||
eave rails at full height — so this wreck is the same height as the intact
|
||||
frame, which is the honest read: a portal frame folds at one end, it does
|
||||
not lie down.
|
||||
|
||||
It carries NO GLASS. The glasshouse has its own wreck variant and swaps
|
||||
independently; a net-frame wreck that shipped shards would draw them twice
|
||||
the moment both swapped on the same night, and would also quietly claim
|
||||
the glass's failure as its own. e.test pins the absence.
|
||||
|
||||
UNPRICED, BY RULING — the bike/jacaranda pattern. A folded portal frame is
|
||||
obviously a repair bill, but the player is being taught about the glass, and
|
||||
one broken corner can only name one collateral key. Inventing a second bill
|
||||
with no mechanism to split it between them is exactly the guess the invoice
|
||||
exists to refuse. Price it when a break can bill two things."""
|
||||
root = add_empty(name)
|
||||
steel = get_material("Mat_NetFrame", PAL["net_frame_white"], 0.50, metallic=0.05)
|
||||
mesh_m = get_material("Mat_HailNet", PAL["net_mesh"], 0.85, metallic=0.0)
|
||||
conc = get_material("Mat_Concrete", PAL["concrete"], 0.95)
|
||||
|
||||
_net_frame(name, root, steel, conc, mesh_m, wrecked=True)
|
||||
|
||||
stamp(root, name, "structure")
|
||||
root["broken_variant_of"] = "hail_net_frame_01"
|
||||
# No anchor survives the wreck — the fascia rule, sixth application. An
|
||||
# anchor that outlives its structure is the free-failure bug in a costume.
|
||||
root["collateral_target"] = "glasshouse"
|
||||
return root
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# THE POOL KIT (SPRINT16 gate 5 — the compliant ring whose steel all says no)
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -3824,6 +4137,25 @@ ASSETS = [
|
||||
dict(name="glasshouse_01_wrecked", fn=build_glasshouse_01_wrecked,
|
||||
dims=((3.4, 5.4), (2.6, 3.8), (2.15, 2.40)),
|
||||
nodes=["frame", "door", "panes_left", "shards"]),
|
||||
# SPRINT18 gate 4 — the glasshouse tier's live half. Every band here is a
|
||||
# design claim about the glass underneath it, which is why they are tight:
|
||||
# x and y floors must both EXCEED the glasshouse's ceilings (2.8 / 2.1), or
|
||||
# the frame has stopped straddling the thing it bills; z must clear the
|
||||
# ridge (2.40 ceiling) or a frame built to protect glass is resting on it.
|
||||
dict(name="hail_net_frame_01", fn=build_hail_net_frame_01,
|
||||
dims=((3.30, 3.55), (2.90, 3.15), (2.70, 2.85)),
|
||||
nodes=["footings", "legs", "top_frame", "net_roll",
|
||||
"net_anchor_01", "net_anchor_02", "net_anchor_03", "net_anchor_04"]),
|
||||
# Folded at one end, not felled: the SAME z band as the intact frame,
|
||||
# because the +x portal stands and holds the eave rails up. If z ever
|
||||
# collapses, someone has laid a portal frame down flat and it never does
|
||||
# that. x runs WIDE on the -x side — the net heaped out past the footing,
|
||||
# and the wreck apron a yard author has to keep clear.
|
||||
# 4.10 floor, not 4.30: the measured span is 4.30 and it is set by the NET
|
||||
# HEAP, not by the racked feet, so it must not sit on the band boundary.
|
||||
dict(name="hail_net_frame_01_wrecked", fn=build_hail_net_frame_01_wrecked,
|
||||
dims=((4.10, 5.30), (2.90, 3.15), (2.70, 2.85)),
|
||||
nodes=["footings", "legs", "top_frame", "net_down"]),
|
||||
# The compliance ring. z is pinned tight around 1.2 m because the height
|
||||
# IS the flavour (AS 1926.1); y reaches past the ring for the ajar gate.
|
||||
dict(name="pool_kit_01", fn=build_pool_kit_01,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 MiB After Width: | Height: | Size: 5.0 MiB |
@ -80,6 +80,16 @@ export const FACTORY_ANCHOR_RATINGS = Object.freeze({
|
||||
"sail_post_corroded/top_anchor"
|
||||
]
|
||||
},
|
||||
"hail_net_frame": {
|
||||
"collateral": "glasshouse",
|
||||
"rating_hint": 0.8,
|
||||
"sources": [
|
||||
"hail_net_frame_01/net_anchor_01",
|
||||
"hail_net_frame_01/net_anchor_02",
|
||||
"hail_net_frame_01/net_anchor_03",
|
||||
"hail_net_frame_01/net_anchor_04"
|
||||
]
|
||||
},
|
||||
"house": {
|
||||
"collateral": "gutter",
|
||||
"rating_hint": 0.35,
|
||||
|
||||
@ -100,10 +100,26 @@ export const PHASES = ['forecast', 'prep', 'storm', 'aftermath'];
|
||||
* can't inspect the inside of). One rating for the whole type, per the
|
||||
* manifest rule. The GLB wears the tell (rust, a sagging pad eye); the type
|
||||
* string is the player's pre-rig read of the same fact.
|
||||
*
|
||||
* `hail_net_frame` (SPRINT18 gate 4, E): the frame that straddles a glasshouse
|
||||
* so a hail net can be rigged OVER the glass (DESIGN.md line 179). It is the
|
||||
* first anchor word in this enum whose danger is not in its own number.
|
||||
* rating_hint 0.80 — the highest rung below the honest post, and it EARNS it:
|
||||
* an engineered portal frame on four real footings with welded eyes, the only
|
||||
* structure in the palette that was built to be tied to. The 20% de-rate is
|
||||
* for section, not condition (32 mm sized for hail mesh, which spills wind;
|
||||
* a 25 m² impermeable sail is an order of magnitude more load).
|
||||
* What makes it the most dangerous anchor in the game is that its baked
|
||||
* `collateral` names the GLASSHOUSE, not itself — the `house`→"gutter"
|
||||
* precedent, and the same shape: an anchor names what its failure TAKES, not
|
||||
* what it is. Break a corner here and the sail, the shackle and the turnbuckle
|
||||
* go through fourteen panes at $320. The type string is the player's pre-rig
|
||||
* read of a hazard that is a POSITION, and the reason it must not be typed
|
||||
* `post`: "post" promises a corner whose failure costs a shackle.
|
||||
*/
|
||||
export const ANCHOR_TYPE = Object.freeze([
|
||||
'house', 'tree', 'post', 'carport', 'carport_post', 'swing_frame', 'pergola',
|
||||
'corroded_post',
|
||||
'corroded_post', 'hail_net_frame',
|
||||
]);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
BIN
web/world/models/hail_net_frame_01_v1.glb
Normal file
BIN
web/world/models/hail_net_frame_01_v1.glb
Normal file
Binary file not shown.
BIN
web/world/models/hail_net_frame_01_wrecked_v1.glb
Normal file
BIN
web/world/models/hail_net_frame_01_wrecked_v1.glb
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user