Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

arena: cool per-handle specColor + 'specs' HUD label

Spectator/guest visuals now use a deterministic cool-palette per handle
instead of flat gray — hue range is constrained to 170°–319° (cyan,
blue, violet, pink) at moderate saturation and high lightness, so anon
watchers read as ghostly/icy and are still individually distinguishable.

Refactor: extracted handleHash() + hslToRgb() so handleColor (full hue
spectrum, vivid) and specColor (cool half, ghostly) can share the same
math.

HUD: rename the 'watchers' line to 'specs' (short for spectators).
Minimap dots for specs are now 2×2 in their own cool color instead of
1×1 flat gray.

+28 -10
+28 -10
system/public/aesthetic.computer/disks/arena.mjs
··· 501 501 return f; 502 502 } 503 503 504 - // Deterministic per-handle color so remotes are distinguishable at a glance. 505 - function handleColor(handle) { 504 + function handleHash(handle) { 506 505 let h = 0; for (let i = 0; i < handle.length; i++) h = (h * 31 + handle.charCodeAt(i)) | 0; 507 - const hue = (h >>> 0) % 360; 508 - // HSL→RGB (s=0.7, l=0.6) 509 - const c = 0.7 * 0.6 * 2, x = c * (1 - Math.abs(((hue / 60) % 2) - 1)); 510 - const m = 0.6 - c / 2; 506 + return h >>> 0; 507 + } 508 + 509 + function hslToRgb(hue, sat, light) { 510 + const c = sat * (1 - Math.abs(2 * light - 1)); 511 + const x = c * (1 - Math.abs(((hue / 60) % 2) - 1)); 512 + const m = light - c / 2; 511 513 let r = 0, g = 0, b = 0; 512 514 if (hue < 60) [r, g, b] = [c, x, 0]; 513 515 else if (hue < 120) [r, g, b] = [x, c, 0]; ··· 518 520 return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]; 519 521 } 520 522 523 + // Deterministic per-handle color for named players: full hue range, vivid. 524 + function handleColor(handle) { 525 + const hue = handleHash(handle) % 360; 526 + return hslToRgb(hue, 0.7, 0.6); 527 + } 528 + 529 + // Spectators (specs) — anon guest_/swarm_ tabs. Constrained to the cool half 530 + // of the spectrum (cyan→blue→violet→pink) with bright lightness so they read 531 + // as ghostly/icy rather than just "dim gray". 532 + function specColor(handle) { 533 + const hue = 170 + (handleHash(handle) % 150); // 170..319 534 + return hslToRgb(hue, 0.55, 0.72); 535 + } 536 + 521 537 // Called from paint() once per frame. 522 538 function paintRemotes(ink, form, Form) { 523 539 const t = renderTimeNow(); ··· 526 542 if (!sample) continue; 527 543 if (!o.body) { 528 544 const watcher = isGuestHandle(handle); 529 - const color = watcher ? [170, 175, 195] : handleColor(handle); 545 + const color = watcher ? specColor(handle) : handleColor(handle); 530 546 o.body = buildRemoteBody(Form, color, watcher); 531 547 } 532 548 // Mirror local body positioning: Form.position uses (-x, y, -z). ··· 1901 1917 if (!s) continue; 1902 1918 const { px, py } = project(s.x, s.z); 1903 1919 if (isGuestHandle(handle)) { 1904 - ink(150, 155, 175, 160).box(px, py, 1, 1); 1920 + const [r, g, b] = specColor(handle); 1921 + ink(r, g, b, 200).box(px, py, 2, 2); 1905 1922 } else { 1906 1923 const [r, g, b] = handleColor(handle); 1907 1924 ink(r, g, b).box(px - 1, py - 1, 3, 3); ··· 1916 1933 const { px, py } = project(myX, myZ); 1917 1934 const meWatching = isGuestHandle(myHandle); 1918 1935 if (meWatching) { 1919 - ink(180, 185, 205).box(px - 1, py - 1, 3, 3); 1936 + const [r, g, b] = specColor(myHandle); 1937 + ink(r, g, b).box(px - 1, py - 1, 3, 3); 1920 1938 } else { 1921 1939 ink(255, 255, 255).box(px - 2, py - 2, 5, 5); 1922 1940 } ··· 1947 1965 ); 1948 1966 advance(); 1949 1967 if (watcherTotal > 0) { 1950 - rightLabelMulti([[dim, "watchers "], [[170, 175, 200], `${watcherTotal}`]], lineY); 1968 + rightLabelMulti([[dim, "specs "], [[170, 200, 235], `${watcherTotal}`]], lineY); 1951 1969 advance(); 1952 1970 } 1953 1971