diff --git a/public/app.js b/public/app.js index 8b0d292..8738743 100644 --- a/public/app.js +++ b/public/app.js @@ -1524,17 +1524,27 @@ setInterval(() => { } }, 5000); -// Spawn me slightly off-center so two people don't land exactly on top of -// each other — small radius on purpose: at refDistance=4/rolloffFactor=1.4, -// the old radius-20 ring put name-hash-unlucky pairs up to 40 units apart -// (diametrically opposite), which is already down to ~7% audio gain before -// anyone's said a word. +// Spawn me slightly off-center so people don't land on top of each other. +// A single hashed angle on a *fixed* radius ring (the previous approach) +// puts anyone whose name hashes to a nearby angle almost exactly on top of +// each other too — on a small ring, "nearby angle" is only a few pixels of +// arc, and with just 360 angle buckets that's common (especially with the +// same recurring guest-xxxx test names). Hashing the radius independently +// from the angle means an angle collision no longer implies a full overlap. +// Both stay small enough that at refDistance=4/rolloffFactor=1.4 (see +// updatePanner) nobody starts out attenuated — this is purely about the +// dots being visually distinguishable, not audio range. (() => { - let h = 0; - for (const c of S.myId || S.name) h = (h * 33 + c.charCodeAt(0)) >>> 0; - const a = (h % 360) * (Math.PI / 180); - S.me.x = 50 + 6 * Math.cos(a); - S.me.y = 50 + 6 * Math.sin(a); + const key = S.myId || S.name; + let hAngle = 0, hRadius = 0; + for (const c of key) { + hAngle = (hAngle * 33 + c.charCodeAt(0)) >>> 0; + hRadius = (hRadius * 17 + c.charCodeAt(0) + 7) >>> 0; + } + const a = (hAngle % 360) * (Math.PI / 180); + const r = 8 + (hRadius % 12); // 8..19 room units + S.me.x = 50 + r * Math.cos(a); + S.me.y = 50 + r * Math.sin(a); })(); window.addEventListener('keydown', (ev) => {