Back to Wizard Duel
SOURCE / PINNED RELEASE

Made of little things.

Wizard Duel

Release
48b4ed933a32…
Author-recorded commit
3ed8fcbbf62c…
License
LICENSE
Author’s source reference
nostr://npub1ny7l44q0au5xkv3mjgt6zks5f0e2ydefslq4nhh2ve2xypgc2mqqat8qx2/wss%3A%2F%2Fgit.napplet.soy%2F/n-86005d75eb4

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

src/game/sprites.ts
// Hand-made pixel sprites. Letters pick colours from a palette:
// H hat, h hat shadow, B hat band, S skin, E eye, N nose, W beard,
// R robe, r robe shadow, K boots, s hand.

const WIZARD_TOP = [
  '....H.....',
  '....HH....',
  '...HHH....',
  '...HHHh...',
  '..HHHHh...',
  '..BBBBB...',
  '.HHHHHHHh.',
  '...SSSE...',
  '...SSSSN..',
  '..WWWWW...',
];

const WIZARD_BODY_IDLE = [
  '..RWWWRr..',
  '.RRRWRRrs.',
  '.RRRRRRr..',
  '.RRRRRRr..',
  'RRRRRRRrr.',
];

const WIZARD_BODY_CAST = [
  '..RWWWRrs.',
  '.RRRWRRr..',
  '.RRRRRRr..',
  '.RRRRRRr..',
  'RRRRRRRrr.',
];

const FEET = [
  ['.KK...KK..'],
  ['..KK.KK...'],
  ['.KK..KK...'],
];

export const WIZARD_W = 10;
export const WIZARD_H = 16;

export type WizardPose = 'idle' | 'walkA' | 'walkB' | 'cast';

/** Build the 10×16 wizard rows for a pose. Idle bobbing is applied by the caller. */
export function wizardRows(pose: WizardPose): string[] {
  const body = pose === 'cast' ? WIZARD_BODY_CAST : WIZARD_BODY_IDLE;
  const feet = pose === 'walkA' ? FEET[1] : pose === 'walkB' ? FEET[2] : FEET[0];
  return [...WIZARD_TOP, ...body, ...feet];
}

/** A hand reaching up with a wand, drawn beside the head while casting. */
export const WAND = ['..y', '.s.', 's..'];

export const HAT_ONLY = WIZARD_TOP.slice(0, 7);

export const CHICKEN = [
  '...cc.....',
  '..WWWW....',
  '..WWEWY...',
  '..WWWWYY..',
  '..WWWW....',
  'WWWWWWW...',
  'WWWWWWWW..',
  '.WWWWWW...',
  '..Y..Y....',
  '.YY.YY....',
];

/** A wizard stuck on their back in a turtle shell, boots in the air. */
export const TURTLE = [
  '...KK....KK...',
  '....R....R....',
  '..GGGGGGGGGG..',
  '.GGgGGgGGgGGG.',
  'GGgGGgGGgGGgGG',
  'GGGGGGGGGGGGGG',
  '.yyyyyyyyyyyy.',
];

export const TOAD = [
  '..ww..ww..',
  '.wEw..wEw.',
  '.GGGGGGGG.',
  'GGGGGGGGGG',
  'GgGGGGGGgG',
  'GGyyyyyyGG',
  '.GGGGGGGG.',
  'GG.G..G.GG',
];

export const TOAD_PALETTE: Record<string, string> = {
  w: '#ffffff',
  E: '#120a1f',
  G: '#4fbf4a',
  g: '#2d7a2a',
  y: '#c8e86b',
};

export const CHICKEN_PALETTE: Record<string, string> = {
  c: '#e8433a',
  W: '#fbf5e6',
  E: '#120a1f',
  Y: '#f7b733',
};

export interface WizardColors {
  hat: string;
  hatDark: string;
  band: string;
  robe: string;
  robeDark: string;
}

export function wizardPalette(colors: WizardColors, skin = '#f2c29b'): Record<string, string> {
  return {
    H: colors.hat,
    h: colors.hatDark,
    B: colors.band,
    S: skin,
    E: '#120a1f',
    N: '#e48a7a',
    W: '#eeeaf6',
    R: colors.robe,
    r: colors.robeDark,
    K: '#2b1c33',
    s: skin,
    y: '#fff36b',
  };
}

// 7×7 spell projectile icons. 'a' and 'b' are the spell's two colours, 'w' is white.
export const ICONS: Record<string, string[]> = {
  orb: ['..aaa..', '.abbba.', 'abbwbba', 'abwwwba', 'abbwbba', '.abbba.', '..aaa..'],
  snow: ['...a...', '.a.a.a.', '..aba..', 'aabwbaa', '..aba..', '.a.a.a.', '...a...'],
  banana: ['......b', '.....aa', '....aa.', '...aa..', '..aa...', 'aaa....', '.a.....'],
  pie: ['.......', '..www..', '.wwwww.', 'bbbbbbb', 'aaaaaaa', '.aaaaa.', '.......'],
  note: ['...aa..', '...a.a.', '...a..a', '...a...', '.aaa...', 'aaaa...', '.aa....'],
  bolt: ['...aa..', '..aa...', '.aa....', '.aaaaa.', '...aa..', '..aa...', '.a.....'],
  heart: ['.aa.aa.', 'awaaaaa', 'aaaaaaa', 'aaaaaaa', '.aaaaa.', '..aaa..', '...a...'],
  cloud: ['.......', '..aaa..', '.aaaaa.', 'aaaaaaa', '.......', '.b.b.b.', 'b.b.b..'],
  egg: ['..aaa..', '.aaaaa.', 'aaaaaaa', 'aawaaaa', 'aaaaaaa', '.aaaaa.', '..aaa..'],
  zzz: ['aaaaa..', '...a...', '..a....', '.a.....', 'aaaaa..', '.......', '.......'],
  drop: ['...a...', '...a...', '..aaa..', '.aabaa.', '.abaaa.', '.aaaaa.', '..aaa..'],
  swirl: ['.aaaaa.', 'a.....a', 'a.bbb.a', 'a.b.b.a', 'a.b...a', 'a.bbbba', '.......'],
  shell: ['..aaa..', '.abbba.', 'ab.a.ba', 'ab.aaba', 'abbbba.', '.aaaa..', '.......'],
  rubberchick: ['.....a.', '....aab', '.aaaaa.', 'aaaaaa.', '.aaaa..', '..b.b..', '.......'],
  spark: ['.......', '...a...', '..aba..', '.abwba.', '..aba..', '...a...', '.......'],
  balloon: ['..aaa..', '.aawaa.', '.aaaaa.', '.aaaaa.', '..aaa..', '...b...', '..b....'],
};