Skip to content

nicetomytyuk/numerus

Repository files navigation

Stanghetta

presentation

Disclaimer: this project was mostly generated by AI (GPT-5.1-Codex-Max).

Stanghetta is a turn-based Roman numerals challenge. Players take turns entering one letter at a time (I, V, X, L, C, D, M) to assemble the correct numeral for an ever-increasing number. Miss a letter or run out of time and the round ends.

Gameplay

Why play

  • Sharpens attention: you must track the correct sequence while others play.
  • Trains working memory: in hard mode messages vanish quickly, forcing recall.
  • Reinforces number sense: you continuously translate numbers into Roman notation.
  • Builds focus under pressure: each turn has a short timer.
  • Encourages collaboration and friendly competition through chat and shared turns.

Modes

  • Online multiplayer: create or join a room with a 6-character code. Turns, scores, and chat sync via Supabase. A 10 s timer is enforced when at least two humans are present.
  • Offline (same device): play locally without any backend. Progress is saved per room code so you can resume later.
  • Offline with bots: add up to eight total players by inviting built-in bots. They auto-play optimal letters.

Turn rules

  1. Create or join a room and pick a nickname. If you create, choose a difficulty.
  2. On your turn, tap a Roman key to extend the shared numeral for the current number (starting from 1 and climbing).
  3. Finish the correct numeral to earn 1 point; the target number increments and the next player starts.
  4. Play passes in order; if the 10 s timer expires, your turn is skipped.
  5. If anyone plays an invalid sequence, the game ends and the correct numeral is shown. Start again to reset scores and pick a new starting player.

Difficulty levels

  • Facile (Easy): shows the correct Roman target as a hint.
  • Normale (Normal): no hints; messages stay in chat.
  • Difficile (Hard): no hints and chat messages fade after a few seconds, so you must remember what was played.

How to run

npm install
npm run dev

Then open the printed local URL. Use npm run build for production bundles or npm run preview to serve the build.

Online setup

  • Requires VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY in a .env file to enable multiplayer (the backend is Supabase).
  • Supabase Realtime must be enabled on the game tables below; the anon key is used client-side (sessions are not persisted).
  • Without these variables, offline and bot modes still work.
  • Share the room code with friends; they can join from any device.

Architecture

  • Frontend: React + TypeScript + Vite SPA. Client state manages turns, timers, and offline storage. Roman numeral logic lives in the browser.
  • Backend: Supabase Postgres + Realtime. The client subscribes to rooms, room_players, and room_messages tables for live updates. All writes go directly to Supabase via the anon key.
  • Networking: WebSocket channels (Supabase Realtime) push player, message, and room state changes. REST/RPC reads are used for room hydration and scoreboard updates.
  • Persistence: Offline mode stores snapshots in localStorage by room code; online mode stores a lightweight session (roomId, playerId, username) locally to reconnect.

Database schema (Supabase)

Run these SQL statements in Supabase (or adapt if tables already exist). Enable Realtime on all three tables. Enforce Row Level Security and policies as needed for your project.

-- Rooms
create table if not exists public.rooms (
  id uuid primary key default gen_random_uuid(),
  code varchar(6) not null unique,
  difficulty text not null check (difficulty in ('easy','normal','hard')),
  show_hints boolean not null default false,
  status text not null default 'active' check (status in ('active','finished')),
  current_number integer not null default 1,
  current_player_index integer not null default 0,
  created_at timestamptz not null default now()
);

-- Players
create table if not exists public.room_players (
  id uuid primary key default gen_random_uuid(),
  room_id uuid not null references public.rooms(id) on delete cascade,
  name text not null,
  is_bot boolean not null default false,
  points integer not null default 0,
  turn_order integer not null,
  is_owner boolean not null default false,
  created_at timestamptz not null default now()
);
create index if not exists room_players_room_order_idx on public.room_players (room_id, turn_order);

-- Messages (chat + plays)
create table if not exists public.room_messages (
  id bigserial primary key,
  room_id uuid not null references public.rooms(id) on delete cascade,
  player_id uuid references public.room_players(id) on delete set null,
  type text not null check (type in ('system','play','error')),
  text text not null,
  number integer,
  correct_roman text,
  created_at timestamptz not null default now()
);
create index if not exists room_messages_room_created_idx on public.room_messages (room_id, created_at);

About

Turn-based Roman numeral game. Play online, offline, or with bots to sharpen focus and memory.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages