For each upload attempt, XMLHttpRequest.prototype.abort and AbortController.prototype.abort are
wrapped (reference-counted across overlapping attempts, restored in finally) and every call is
recorded with a six-frame file:line:col stack; "abort calls: none" says the page called neither.
The upload hook also counts renders after attach (and those within 300ms) and any unmount.
The in-memory copy and the once-only retry are unchanged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Replaces the exp(-(k d)^1.6) haze with the camera volume of Hillaire, EGSR 2020 section 5.4 (and sebh/UnrealEngineSkyAtmosphere
RenderCameraVolumePS): slices on the squared distribution, in-scatter integrated with each step's extinction analytic, alpha the
grey opacity 1 - mean(T). Baked into baked.scatter.aerial_perspective by src/sky/scatter.js (RGBA16F 7 x 96 x 12, 86 KB), looked up
in the terrain fragment shader (two fetches). Night: the moon lights the haze through the same volume, plus a deep blue starlight floor.
Shortcuts, with units and constants, in src/sky/README.md: sun-relative indexing, 12 x 8 x 7 texels, path = scene metres x 8,
ground ignored, single scattering, no multi-scattering LUT.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- albedo wobble, grain and strata are triplanar (weights |n|^4 over yz, xz, xy), so a cliff is not the floor pattern smeared down it
- normals from bilinear height at a continuous position, stencil 1.5 texels each side
- the grid is packed toward the camera at the patch centre (warpUv), 192 low / 256 full, vertex heights bilinear: near ridge silhouettes no longer step in 23 m blocks
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An AbortError within 3s of starting, with no progress event and no user cancel, is retried once;
the failed attempt discards its connection, so the retry cannot reuse it. The final failure text
says "retried" with attempt 1's timing. Never retried after progress, a user cancel, a
different error, or a slow abort. The cause (a reused dead keep-alive socket) is unproven.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- the name pill is at most bubble width minus portrait minus 30px, so it cannot reach the face
- a bubble with a portrait is at least portrait + 170px wide, so text beside a right portrait
no longer wraps into a ~100px column
- <=480px: the pose status block shows only the newest mood plus "+N more" on one line, tap to
expand; the read-receipt line is hidden and its slot is an 8px margin under the composer
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Why it read hazy and flat at 390x844: the camera started with the noon sun straight behind it (no shading), the low tier
sampled a 512 height map (6 m texels), plain exp(-k d) haze greyed the near ground, albedo had no grain, and the night
ground sat at ambient 0.018 (near black).
- camera starts with the noon sun 100 degrees off axis (START_TURNS; ?az= still moves the sun)
- haze T = exp(-(k d)^1.6), k 0.0007: near ground clear, far ridges melt
- low tier bakes 1024 texels
- albedo grain (three-wave octaves, fine one fades with distance) and rock strata; shader-only cavity shading
- night: moon from the sun's mirrored position, ambient lifted by nightness
- tier label (full / low / still / sky-only) in preview builds or ?tierlabel=1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Adds connectivity (onLine, effectiveType, rtt, downlink, saveData), tab visibility, ms since
last user activity, time to first progress and bytes loaded, and ms to failure. Nothing patches
XMLHttpRequest; the progress handler and window input events are the only sources.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- portrait on phones is min(38vw,160px), was min(50vw,210px): at 390px the text column beside
it was ~85px
- outside list markers ignored the portrait silhouette and landed under the art; inside markers
wrap with the text
- Jump to Latest sits 8px (was 16px) above the timeline's lower edge
- preview banner is in flow above the app, not fixed over the room header and connection strip
- on the pretend server the training line and the registration checkbox say nothing is trained
(trainingNoticeText); the real sentence and its wording are unchanged and still await Meta's
legal read
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The catch in uploadContent set errcode from e.message and dropped an empty
message, so the SDK's status-0 AbortError (DOMException with empty message)
surfaced as "MatrixError: Unknown message". uploadFailure now uses e.name for
errcode, keeps the original as cause, and puts size, type and whether the
file can still be read into the message the upload card shows.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
createTerrainScene returned null without WebGL2, leaving plain dark ground. The door now mounts
terrain/TerrainSky2D.ts on the same canvas: skyColour (the CPU twin of SKY_FRAG) painted once, the star
layer on top when dark, same ?sky= ?sun= ?az= choice. chooseSky moves from Terrain.ts to terrainSky.ts
so both scenes share one owner.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Albums as threads, marks as custom reference events (or local), export, mobile
layout, existing media code, and a four-slice first plan. Design only.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The host's CSP map grants allow-forms to /void/rat-* (live nginx, minds.gamecult.org), so native form submission fires its submit event and deliverSubmitEvents has nothing left to do. The manifest link was host-root (/manifest.json, a 404 under /void/rat-*); ./manifest.json resolves under the build's base.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Drops the vendored terrain/skyData.ts and the computed azimuth. terrainSky.ts reads src/sky/baked.ts:
sun {elevation_deg, azimuth_deg, color_linear}, ambient_linear, horizon_hex. terrainScatter.ts decodes
baked.scatter and uploads sky_view as an RGB16F 3D texture; SKY_FRAG and GRID_FRAG sample it (README
sampler), the sky for the view ray, the haze for the horizon in the fragment's azimuth.
- Sky: 1 - exp(-exposure * radiance) + night glow (midnight horizon colour, off as the sun nears the
horizon) + sun disc; +-0.5/255 dither on the 8-bit output.
- Stars fade by sun elevation (starGain: 1 below -12, 0 above -6) instead of a dark-sky gate; the
field is placed against the midnight gradient.
- ?sun=<deg>&az=<deg> (or the sun option) lights between the two bakes for dusk (skyAtSun).
- Changed numbers, noted in scene/README.md: haze colour is the scattered sky (was the gradient's
horizon stop), ambient is ambient_linear as baked (was gradient zenith x 0.25 x night lift up to 4),
HAZE_K unchanged at 0.0004.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
shape-outside: url() sizes the image at its natural size and anchors it at the margin box, which the
phone layout's -82px top margin moves down by the overhang, so the exclusion was the wrong size and
in the wrong place and long-post words ran under the art. PoseAvatar now traces the displayed art's
alpha (0.35, as before) into a polygon in border-box pixels, retraced on load and resize.
The pose status lines sat in a shrinkable flex box (12px high, three 18px lines) and overflowed into
the composer; the box is shrink="No".
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Terrain overlay draws the ridge field at 2.4x alpha (capped at 1) and 1.3x
radius; the dark-sky gate is unchanged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
scatter.js ray-marches a single-scattering Rayleigh+Mie atmosphere whose vertical optical depth is
sun.js's TAU, and bakes two tables into baked.scatter: transmittance to space by view elevation
(32x1) and sky radiance by azimuth from the sun x view elevation x sun elevation (7x32x12), RGB
half floats, little-endian base64, value x 64. Layout, exact decode and a GLSL sampler are in
src/sky/README.md. Tests pin layout, encoding, checksums and physical anchors (zenith transmittance
equals exp(-TAU); blue noon, red low sun toward the sun, black below the planet-shadow limit).
The per-sky sun {elevation_deg, azimuth_deg, color_linear}, ambient_linear and horizon_hex were
already baked in 7216456a; sun.js now exports TAU.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reuses ridge/stars.ts (placement, tint, rolling 32-star twinkle) projected with the terrain camera
onto an overlay cut to the sky; stops with the terrain loop.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Bands moved so snow caps only the peaks and soil/scree/rock read; haze
0.0007 -> 0.0004 so the albedo is not washed out; ambient x4 at night so a
moonlit face is readable on a phone.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Rock on steep faces, soil to scree to snow by height, snow only on gentle
faces; no texture reads. Pure albedoAt()/albedoPalette() mirror the grid
fragment shader; the palette is read from the baked sky (snow line and tint
by sun elevation: cool haze at night, warm sun by day).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The noise is evaluated at vec3(xz * f, c), so .z is the slope along the held
constant axis. Confirmed numerically (harness/scene/gradAxis.cjs): analytic
.xy matches central differences for fbm and phacelle, .z does not. Only the
ray-march scene's normals were affected; the grid tier already used .xy.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Previews are static dirs with no SPA fallback; a reload or shared link on
/login/matrix.org was an nginx 404. preview-config now enables the hash
router, and index.html's manifest link follows the base path.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed in, the shell is clear over the ridge scene (html[data-scene]): Background and Surface
container tokens are redefined on #root only, so menus, dialogs and tooltips in #portalContainer
keep their fills. Bubbles and the composer are the filled surfaces: their colour at 50% over a
12px blur. Avatar initials read the surface colour through a variable captured above the override.
On phones the message content (a flex column) formed its own block formatting context and sat
beside the floated portrait for the bubble's whole height, so text stayed as narrow as the gap
beside the portrait. It is a plain block there now: lines wrap around the silhouette and then
run the bubble's full width.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The demo pose thumbnails were 160px wide palette PNGs, about 4 KB, shown at up to 210 CSS px
on phones: 195 CSS px x DPR 3 = 585 device px from 160, a 3.6x upscale. They are now 480px
wide (about 2.5x the phone portrait at DPR 3, still 25-70 KB each), generated from
/opt/commons/cast-art/poses by scripts/make-pose-thumbs.mjs, and cover every pose the
catalogue lists for the three demo Minds.
The Ratatoskr demo room gains three long Mind posts with paragraphs, lists and code,
sent with formatted_body like the real Minds' Markdown.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found driving Chrome: the pose setting was seeded after settings.ts had already read defaults;
the Connecting bar stayed until the first 15 s long poll returned.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The host CSP sandbox lacks allow-forms; Chrome drops native submission before the submit
event fires, so the login button did nothing in a real browser (found driving Chrome).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
src/preview-demo answers a demo.invalid homeserver from fixtures through a guarded fetch;
own-origin requests pass, every other origin is refused (fetch, WebSocket, XHR, beacon).
Built in only with VITE_PREVIEW_DEMO=1 and switched on by previewDemo in config.json
(scripts/preview-config.js --demo, run by the dev workflow). Login prefills 'demo'.
Pose art: 24 downscaled thumbnails in preview-demo/poses, copied into dist by the workflow.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Preview on Starfire showed one flat normal per height-map texel (blocky ground)
and a hard step in the sky gradient at the geometric horizon. Normals now blend
the four surrounding texels; the sky's elevation mapping eases through the
horizon; haze k 0.0012 -> 0.0007 so relief reads.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
style 'terrain' (WebGL2, tier-gated, dynamic import): height map baked once on the
GPU into RGBA8 (promoted from the terrain-tier-spike), a displaced grid, the baked
gradient as sky, baked sun/ambient/haze. Sky from option, ?sky=, or the stars'
night notion. Cadence guard, pauses, context loss and compile failure follow the
ridge scene. preview-config.js takes an optional style argument.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Vendors the small set the terrain needs from Void's baked sky (PR #22, 7b4aa2f):
sun elevation, the 7-stop gradient, sun.js light().direct, plus a sun azimuth
computed from the same series (not in the bake). Lambert from the sun, ambient
from the gradient zenith, exp(-k d) haze toward the gradient's horizon stop;
a sun below the horizon lights nothing. Pure functions, no GL.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Run 170: CreateArtifact got an nginx 404 page; /twirp 404s at the host root and answers
(401 without a token) at /forge/twirp. Try the results URL with the subpath.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Every star is seeded, placed toward the zenith, faded by the local sky
luma, and baked once into the sky canvas. A night sky is one whose
zenith luma is below 110; the ridge scene has no theme flag, so the
dusk default qualifies faintly and a day sky gets no stars and no
overlay.
32 slots twinkle at a time on a small overlay canvas under the ridges:
each slot runs back-to-back one-cycle twinkles (own 2-7 s period and
offset) of one star from its own partition, shuffled per epoch, never
repeating across the seam. Gain is a pure function of (slot, t), 0.35x
to 1.15x, exactly 1 at start and end. Dimming paints the sky's own
colour over the baked star; brightening adds a star. The pass is
clear + at most 32 arcs at 20 fps, stopped under reduced motion (live),
while hidden, in tier 'still', and after the slow-frame fallback.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>