Something went wrong. Try again.
a tiny pet with a GPT-2 brain, living in your browser
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108import type { BrainState, Generated, Generation, PetState, View } from "../types.ts";
// `state` is a read-only snapshot of the pet (see engine.ts), replaced after// every change; Preact subscribes to revisions. Animation frames update `view`// without rendering the component tree at 60 Hz.export const store: { state: PetState; badEgg: { raw: string; why: string; newer: boolean } | null; tabOwned: boolean; resetting: boolean; executionRevision: number;} = { state: undefined as unknown as PetState, // set by boot() before rendering badEgg: null, tabOwned: false, resetting: false, executionRevision: 0,};export const brain: BrainState = { worker: null, state: "off", busy: false, tps: 0, prefillMs: 0, progress: null, threads: 0, id: null, error: "",};export const upgrade: { state: "idle" | "downloading" | "swapping" | "error"; loaded: number; error: string;} = { state: "idle", loaded: 0, error: "" };export const view: View = { x: 48, facing: 1, walking: false, target: 48, anim: null, queue: [], effects: [], want: null, wantUntil: 0, dream: null, dreamUntil: 0, game: null, thinking: false,};export const ui = { live: null as { text: string } | null, diaryWriting: false, diaryDraft: "dear diary,", upgradeOpen: false, storage: "", alertsNote: "", toasts: [] as { id: number; text: string; icon?: string }[], debugLog: [] as (Generated & { at: Date; mode: Generation["mode"] })[], hostingBusy: false, remoteError: "", remoteEndpoint: "", remoteLastSync: 0, remoteGameId: null as string | null, remoteWeather: "",};let revision = 0;const listeners = new Set<() => void>();export const snapshot = () => revision;export function subscribe(listener: () => void) { listeners.add(listener); return () => { listeners.delete(listener); };}export function emit() { revision++; for (const listener of listeners) listener();}let toastId = 0;export function toast(text: string, icon?: string) { const id = ++toastId; ui.toasts.push({ id, text, icon }); emit(); setTimeout(() => { ui.toasts = ui.toasts.filter((t) => t.id !== id); emit(); }, 4200);}export function liveBubble() { const bubble = { text: "" }; ui.live = bubble; emit(); return { update(text: string) { if (text && ui.live === bubble) { bubble.text = text; emit(); } }, remove() { if (ui.live === bubble) { ui.live = null; emit(); } }, };}