Skip to content

Repository files navigation

DAILY ARCADE

A browser-based collection of 30 daily puzzle games.
A new challenge every day, streaks, friends rankings and live duels.

JavaScript · Supabase · PWA · Vercel

status no framework PWA

Play Daily Arcade →

Features

Daily Challenges A new puzzle in every game each day at midnight (Madrid time), the same for every player
Streaks & Stats Games played, wins, streaks, best and average time, and a 28-day activity map
Friends & Rankings Add friends by username and compare daily and streak rankings, with public or private profiles
Live Duels Challenge a friend to a best-of-5 match across randomly chosen games
Star Scoring Every game is scored from 0 to 5 stars, with a time penalty for hints and checks
Spoiler-free Sharing Share the result of a single game or of the whole day without revealing solutions
Installable & Offline Works as a PWA and keeps running without a connection once the day's page has been opened
Accessibility Light, dark or system theme, plus a colour-blind friendly palette
Guest Mode Play without an account; progress is uploaded when you sign in with email, username or Google
Admin Panel Edit the challenge calendar from a built-in dashboard

The Games

Game Goal
Palabra Guess the 5-letter word in 5 attempts.
Cifrado Decode the quote: every letter hides another one.
Coronas One crown per row, column and colour, with none touching.
Sudoku mini Fill the 6×6 board without repeating numbers.
Escalera Change one letter at a time to get from one word to another.
Operaciones Reach the target number using sums, differences, products and divisions.
Camino Draw a line through every cell, passing the numbers in order.
Luces Turn off all the lights with as few presses as possible.
Tuberías Connect the matching pairs of dots and fill the whole board.
Sopa de letras Find the 6 hidden words in the grid.
Sospechosos Work out who was where, with what, from 5–6 clues (one unique solution).
Balanza Place the weights so the beam balances: weight × distance on both sides.
Intruso Spot the one pattern that breaks the rule (shape, colour, rotation) in 5 rounds.
Mezcla Match a target colour by mixing drops of 4 base paints, using as few drops as possible.
Siluetas Build a cube figure that fits both its front and side shadows with the minimum number of cubes.
Rayo Place a limited number of mirrors so the laser lights every gem and reaches the exit.
Carátula Guess the movie from its poster, divided in 3×3 zones (needs a TMDB_KEY env var in Vercel, see below).
Cronología Put 4 historical events in order, oldest first, over 5 rounds (events in content/eventos.js, no API).
País Guess the country from its silhouette; each miss gives a new clue (shapes in content/paises.js, generated by tools/gen-paises.js, no API).
Pokémon Guess the Pokémon from its black silhouette (generations 1–5; names in content/pokemon.js from PokeAPI; artwork loaded live from PokeAPI's sprites repo via jsDelivr, nothing stored here). Not part of the duels. Pokémon is a trademark of Nintendo, Game Freak and Creatures: this is an unofficial fan project.
Más o menos Higher or lower: two items face off and you pick which has more (country population from REST Countries, daily Wikipedia page views from the Wikimedia API, mountain heights, river lengths). 10 rounds, the same for everyone each day, ends at the first mistake. Live data is fetched when you play, nothing is stored here. Not part of the duels.
Dominó de ríos Lay water tiles from the spring to the sea, passing through every marked town, without crossing yourself or stepping on rocks. The generator brute-forces the puzzle so every daily river has exactly one solution (5×5 on Mon/Tue, 6×6 otherwise). Not part of the duels.
Eco Two boards, two characters: you on the left, your mirrored echo on the right. Every move you make is repeated by the echo mirrored left/right; if one bumps into a rock it stays put. Get both onto their exits at once. Each daily puzzle is solved by breadth-first search over (you, echo) positions, so it is always solvable and needs coordination (6×6, 5×5 on Mon/Tue). Arrow keys supported. Not part of the duels.
Parcelas Split the 6×6 board into rectangles: each holds exactly one number, which is its number of cells; together they cover the whole board (one unique solution, checked by brute force).
Faros Place lamps so every free cell is lit. A lamp shines in a straight line up to a wall; lamps cannot see each other, and a numbered wall says how many lamps touch it. The generator removes numbers while brute force still finds exactly one solution (5×5 on Mon/Tue, 6×6 otherwise).
Dado rodante Roll a die across the board, one cell at a time. A numbered cell can only be stepped on with that number on top; step on all of them, then reach the flag. Each daily board is solved by breadth-first search over (cell, die orientation, numbered cells visited), so it is always solvable and the die forces detours.
Horizonte 4×4 skyscrapers: heights 1–4 with no repeats in any row or column, and each number on the edge tells how many buildings are visible from there. The generator checks against all 576 Latin squares that the clues leave exactly one solution.
Atasco Rush Hour on a 6×6 board: slide cars and trucks in straight lines to let the red car out. Each daily board is explored completely with breadth-first search (moving is reversible), and the puzzle is a position far from the exit, so it is always solvable and the minimum number of moves is exact.
Hielo The floor is ice: you slide until you hit a rock or the edge. Pass through every star and stop on the flag (which also stops you). Solved by breadth-first search over (cell, stars collected); only long puzzles where the stars force detours are accepted.
Jarras Two or three unmarked jugs and a tap: fill, empty or pour to get exactly the requested litres in one jug. Breadth-first search over every jug state gives the minimum; targets that equal a jug's capacity are rejected.

Tech Stack

Frontend
Backend & Database
PWA
Deployment

Screenshots

image

Installation

Local mode

Leave js/config.js empty and open index.html. Challenges are read from the local/ folder. To see what each day brings, open admin-local/calendario.html.

Google sign-in, offline mode and installation need https:// or http://localhost:

npx serve

With Supabase

  1. Create a project at supabase.com.

  2. In the SQL Editor, run these files in order:

    • supabase/schema.sql
    • supabase/seed.sql
    • supabase/duelos.sql
    • supabase/endurecimiento.sql

    Already have a database? Run supabase/juegos_sospechosos_balanza.sql and supabase/juegos_intruso_mezcla_siluetas.sql and supabase/juego_rayo.sql and supabase/juego_caratula.sql and supabase/juego_cronologia.sql and supabase/juego_pais.sql and supabase/juego_pokemon.sql and supabase/juego_masmenos.sql, then duelos.sql and endurecimiento.sql again (all are idempotent).

  3. Copy your Project URL and publishable/anon key into js/config.js. Never use the service_role key.

  4. Sign up in the app, then make yourself an admin:

    update profiles set rol = 'admin'
    where id = (select id from auth.users where email = 'you@example.com');

Optional: to sign in with a username, deploy supabase/functions/login/index.ts as an Edge Function named login with Verify JWT turned off. To enable Google sign-in, configure the provider under Authentication → Providers → Google.

How to Play

  1. Pick a game from the home screen.
  2. Every game shares the same toolbar: Undo · Restart · Check · Hint · Give up, showing only what makes sense for that game.
  3. Hints and checks add seconds to your time, shown on the button (e.g. Hint ⏱15 s).
  4. Finish faster for more stars. Giving up scores 0.

Keyboard

The whole app can be used without a mouse.

Key Action
Tab / Shift+Tab Move through buttons and links. Each board (Sudoku, Coronas, Luces) and on-screen keyboard is a single tab stop.
Arrow keys Move the focus to the nearest control in that direction (home, boards, settings, rankings…). In Sudoku this also selects the cell.
Enter / Space Activate the focused control.
Esc Go back.
Letters, Enter, Backspace Type in Palabra, Cifrado and Escalera; digits 1–6 in Sudoku.
Arrow keys or WASD Draw the path in Camino.
Sopa de letras Tab to the board, arrows move the cursor, Enter on the first and on the last letter, Esc cancels.
Tuberías Tab to the board, arrows move the cursor, Enter on a dot starts a pipe, arrows extend (or go back along) it, Enter/Esc release.
Parcelas Tab to the board, arrows move the cursor, Enter on one corner and again on the opposite one places the plot, Del removes the plot under the cursor, Esc cancels.
Faros Tab to the board, arrows move the cursor, Enter/Space cycle lamp → mark → empty, X toggles the «no lamp here» mark.
Dado rodante Arrow keys roll the die.
Horizonte Tab to the board, arrows select the cell, digits 1–4 set the height, Backspace/Del clears it.
Atasco Tab to the board, Enter marks the next vehicle (Shift+Enter, the previous one), arrows slide the marked vehicle one cell (several in a row in the same direction count as one move).
Hielo Arrow keys slide.
Jarras Tab through the Fill, Empty and Pour buttons of each jug.

Games that need the arrow keys for themselves register with flechas: true. Board containers opt in to the single tab stop with data-rv="name".

Scoring

Time vs. reference Stars
Up to 1× ⭐⭐⭐⭐⭐
Up to 1.5× ⭐⭐⭐⭐
Up to 2× ⭐⭐⭐
Up to 3× ⭐⭐
More ⭐

Palabra is scored by attempts instead: 1 attempt gives 5 stars, down to 1 star for the fifth. Duels do not use stars and do not count towards streaks or rankings.

Adding a Game

  1. Copy js/games/_plantilla.js to js/games/your-game.js and fill it in.
  2. Add its <script> tag to index.html.
  3. Add it to SHELL in sw.js and bump V.
  4. Register it in Supabase with a migration (see supabase/juegos_nuevos.sql).
  5. To include it in duels, add its id to duelo_juegos() in duelos.sql.

Project Structure

index.html          App entry point
admin.html          Admin panel
sw.js               Service Worker
js/games/           One file per game (+ _plantilla.js)
js/core.js          Shared utilities, scoring and reference times
js/sfx.js           Optional sound effects (Web Audio, no audio files)
js/musica.js        Optional generative background music (Web Audio; key and melody change every day)
js/teclado.js       Keyboard navigation (focus, arrows, Esc)
js/duelo.js         Duel client
supabase/           SQL schema, seed, duels, hardening + login function

Warning

supabase/seed.sql and local/ contain the solutions for the coming months.

Carátula (TMDB)

Carátula loads each day's poster live from TMDB; no image is stored in this repository (the list in content/peliculas.js only holds titles and years). The browser never talks to TMDB with a key: it calls /api/tmdb (api/tmdb.js, a Vercel serverless function) which adds the key on the server. To enable it, create a free API key (the v3 "API Key", not the Read Access Token) at https://www.themoviedb.org/settings/api and add it in Vercel → Settings → Environment Variables as TMDB_KEY, then redeploy. Without it the game shows "not available" and nothing leaks.

Releases

Packages

Contributors

Languages