the troll gate stops flickering, the signpost lands, the chair holds

- a fix16 animation key is signed: Zul'Farrak's troll gate was drawing its burnt twin inside the intact one (a −1.0 key read as +1.0, so the cull never fired) — 24 two-state models stop showing both states, 65 fade curves lose an over-bright tail
- a GameObject is placed by its quaternion, not its facing: the Ravenwind arm of the Feralas signpost comes down from mid-air onto the post, and 1,411 visible spawns — 123 of them chairs — take their authored tilt; the inspector shows it
- sitting in a chair holds: a jumpless fall puts nothing on the wire until it lands and heartbeats on the ordinary 500 ms deadline, so the stalled frames inside the chair's collider no longer send the moving flag that stood you back up; and the use cursor greys past the chair's own 3.0 yd reach
- README's "Not built yet" catches up: guilds, the pet bar, fishing, the dressing room, macros, key bindings and addons are in

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-20 19:10:13 +07:00
co-authored by Claude Fable 5
parent d2b3492cd5
commit a047a31aea
14 changed files with 564 additions and 103 deletions
+16 -1
View File
@@ -283,8 +283,23 @@ pub(super) fn inspect_ui(
} else {
String::new()
};
// The **placement tilt** (decision 1459) — shown only when there is one. A GameObject
// is placed by its `GAMEOBJECT_ROTATION` quaternion, and 96.7% of live spawns encode a
// plain yaw in it; the rest carry a tilt that swings the model's off-origin geometry
// yards from the spawn point. So `tilt 70°` on a prop that looks misplaced says "this
// one's pose is quaternion-only" — the question B89 cost a DB round-trip to answer —
// and its absence says the placement is a bare facing and the fault is elsewhere.
let tilt = s
.0
.gameobject_rotation()
// The angle the quaternion leans the model's own up-axis off world up:
// `acos(m22)`, i.e. `2·asin(|x, y|)` — zero for every pure-yaw spawn.
.map(|q| (2.0 * q[0].hypot(q[1]).min(1.0).asin()).to_degrees())
.filter(|deg| *deg >= 0.5)
.map(|deg| format!(" · tilt {deg:.0}°"))
.unwrap_or_default();
format!(
"go type {} · state {state} {word} · {solidity} · flags {flags:#x}{flag_text} · {interact}{page_text}",
"go type {} · state {state} {word} · {solidity} · flags {flags:#x}{flag_text} · {interact}{page_text}{tilt}",
s.0.gameobject_type_id()
)
});