Back to Powder Tool V600Billion
SOURCE / PINNED RELEASE

Made of little things.

Powder Tool V600Billion

Release
142767edcab8…
Author-recorded commit
6d92971effd0…
License
LICENSE
Author’s source reference
nostr://npub1fllw8kw0thjj55wds0uugcnp5kej2nfxd36eruq39d56wwz8r44q5q78wj/wss%3A%2F%2Fgit.napplet.soy%2F/powder-toy

Archive hash verified: ed7d6a8ea7083197…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

source/src/server/names.js
/**
 * The game thinks in integer save IDs and in usernames; Nostr has addresses
 * and public keys. These two maps are the translation.
 *
 * IDs are derived from the save's address, so the same save has the same ID
 * in every browser ("id 1234567" can be shared). Usernames carry a short
 * piece of the key, so two players who both call themselves "alice" never
 * look like the same person to the game (it uses the name to decide whose
 * save it is).
 */

/** 31-bit positive ID from a string (FNV-1a), never 0. */
export function stableId(text) {
  let hash = 0x811c9dc5;
  for (let i = 0; i < text.length; i++) hash = Math.imul(hash ^ text.charCodeAt(i), 0x01000193) >>> 0;
  return (hash & 0x7fffffff) || 1;
}

/** A username the game can show and search: letters, digits, _ and -, plus a key suffix. */
export function usernameFor(pubkey, profile) {
  const raw = [profile?.name, profile?.display_name, profile?.displayName]
    .find((value) => typeof value === 'string' && value.trim()) ?? '';
  const clean = raw.normalize('NFKD').replace(/[^A-Za-z0-9_-]+/g, '').slice(0, 16);
  return clean.length >= 2 ? `${clean}_${pubkey.slice(0, 4)}` : `nym_${pubkey.slice(0, 8)}`;
}