SlidePlay is a lightweight real‑time slideshow and quiz app built with Express and Socket.IO. It lets guests join from their phones, answer fun questions, and watch results live on a host screen while an admin drives the show.
This project was created as a birthday surprise for my dad. All images, videos, and texts in the demo are just placeholders — you can replace them by editing public/slides.json and assets under public/assets.
- Real‑time multiplayer quiz and slideshow
- Three roles out of the box:
- Player: joins on mobile and answers questions (
public/index.html) - Host: TV/projector stage view with a join QR code (
public/host.html) - Admin: token‑protected panel that controls slides, reveal, reload, goto, and remote video playback (
public/admin.html)
- Player: joins on mobile and answers questions (
- Slide types:
content,video,question,scoreboard,final - Scoring with correctness + configurable speed bonus
- Auto‑reveal correct answer when everyone has answered; optional auto‑advance with delay
- Reveal is terminal — answers arriving after a reveal are ignored
- Players see the correct answer after reveal and a live "waiting" progress while others answer
- Live reload of
slides.jsonand avatar files — no server restart needed - Avatar picker for players (drop images into
public/assets/avatars/) - Simple, dependency‑light architecture (no DB; in‑memory state)
- Mobile‑friendly player UI; host screen tuned for TV/large displays
- Basic smoke tests (
npm test)
Requirements: Node.js 18+
- Install dependencies
npm install
- Start the server
npm run start
- Open the three views (from the same LAN so phones can join):
- Player:
http://<server-ip>:3000/ - Host stage:
http://<server-ip>:3000/host.html - Admin panel:
http://<server-ip>:3000/admin.html
The admin panel is protected by a token. Set ADMIN_TOKEN as an environment variable to
use a fixed token, or read the randomly generated one printed to the server console at boot.
Tip: Use your machine’s local IP (e.g., http://192.168.1.20:3000) so other devices on Wi‑Fi can connect.
All content is defined in public/slides.json.
Top‑level settings control game behavior:
pointsPerCorrect(number): points for a correct answer.maxSpeedBonus(number): max extra points for the fastest answers.speedBonusWindowSec(number): time window for speed bonus to decay linearly to 0.revealDelayMs(number): wait time after reveal before auto‑advance.autoAdvanceAfterReveal(boolean): auto‑advance to next slide after reveal.
Slides are an array of objects. Supported types:
- content:
{ id, type: "content", title, text?, img? } - video:
{ id, type: "video", title, video, autoplay? }- Host screen is controlled from Admin (play/pause/mute/seek/restart). Player page shows a local video element.
- question:
{ id, type: "question", title, choices: string[], answerIndex }- After reveal, Host shows the correct choice and a detailed answer list with timing.
- scoreboard:
{ id, type: "scoreboard", title? } - final:
{ id, type: "final", title?, text? }
Assets referenced in slides should live under public/assets/... (e.g., images, videos).
Player avatars are read from public/assets/avatars/. Just drop PNG/JPG/etc. files there. The server watches this directory and updates the selection list for new/removed files automatically.
- Correct answers earn
pointsPerCorrect. - A linear speed bonus up to
maxSpeedBonusis added based on how quickly the player answered withinspeedBonusWindowSec. - Each player can submit only once per question.
- Scores accumulate across questions; the
scoreboardslide shows a ranking.
-
Player (
/):- Enter name, pick an avatar, answer questions.
- After answering, choices lock in and a "waiting for others" counter appears.
- Once revealed, the player sees the correct answer and their own pick.
-
Host (
/host.html):- Displays slides for the audience, with a QR code and join URL for players.
- On questions, highlights the correct choice after reveal and shows an answer list with timing and correctness.
-
Admin (
/admin.html):- Requires the admin token (from
ADMIN_TOKENor the server console). - Controls: Previous/Next, Goto slide, Force Reveal, Reload JSON.
- Video remote: Play, Pause, Restart, Mute/Unmute, Seek.
- Shows the current slide list, live scoreboard, and per‑question answer progress.
- Requires the admin token (from
- When a new question starts, the server snapshots the set of currently connected players. Reveal occurs automatically when everyone in that set has answered (disconnects adjust the requirement).
- Reveal is terminal: once the answer is revealed (automatically or via the admin), later answers are ignored and the result cannot change.
- After reveal, if
autoAdvanceAfterRevealis true, the server waitsrevealDelayMsthen advances and starts the next question. Manual navigation cancels any pending auto‑advance. - Editing
public/slides.jsonlive reloads slides; editingpublic/assets/avatarsupdates the avatar picker.
- Express serves static files from
public/. - Socket.IO handles real‑time events (player join, answer, slide changes, reveal, admin controls, host video control).
server.jskeeps in‑memory state for slides, players, and the active question.chokidarwatchesslides.jsonand avatar files for live reload.qrcodegenerates the host join QR code.node:testpowers a basic socket smoke test intest/(run withnpm test).
Key files:
server.js: Express + Socket.IO server and game logicpublic/index.html: Player clientpublic/host.html: Host/stage clientpublic/admin.html: Admin panelpublic/slides.json: Content and settingstest/smoke.test.js: End‑to‑end smoke tests
- This repo is intended for GitHub (not npm).
package.jsonis markedprivateto avoid accidental publish. - Run with
node server.jsor a process manager likepm2. - Put it behind a reverse proxy (Nginx/Caddy) if deploying on the internet.
- Ensure large video files are encoded for web playback and accessible under
public/assets. - The app is designed for trusted LAN use. If it is reachable beyond a trusted network, set a strong
ADMIN_TOKENenvironment variable; player names are sanitized, but a join PIN and HTTPS are recommended for public deployments.
- Join PIN for players
- Per‑question countdown timers visible on clients
- Persistence for scores and sessions
- Transitions/animations between slides
- i18n to switch between languages easily
Licensed under the MIT License. See LICENSE for full text.
- Built as a birthday surprise for my dad — happy birthday, Dad! 🎉
- Replace the demo text/images/videos with your own by editing
public/slides.jsonand placing media inpublic/assets.