A web-based implementation of the Hanabi board game.

Overview

Senko

Project "Senko" is a web-based implementation of the Hanabi board game.

Online Demo

The frontend uses TypeScript, Stylus, Mithril, Rxjs, and Material Design.

The backend features a serverless design using Firestore as the database, with game rules validated entirely with Firebase Security Rules.

Features

  • Basic gaming with 2-6 players + observers.
  • Creating and joining rooms.
  • Visual gameplay and layout.
  • Extensive in-game hints and "insights", e.g.
    • Possible color / ranks of unknown cards
    • Copies left of a certain card
  • Configurable rulesets
    • 5/6 colors
    • Wildcard (rainbow) cards (EXPERIMENTAL, in-game description has errors)
    • Unicorn Unique color (which has only one copy of each rank)

Wishlist

  • Ending the game one round after deck runs out
    • Right now, players can keep playing until they have only one card in hand.
    • Ideally, the end-game condition should be configurable.
    • Perfecting the game and too-many-errors are correctly implemented though.
  • Animations
  • Alerts / notifications when it is your turn
  • AI players (e.g. adapters for existing Hanabi algorithms / models)
  • Better mobile support

Development / Contributing

This project is a monorepo managed using Lerna.

To start, install Lerna and bootstrap:

npm i -g lerna
lerna bootstrap

Dev server

The dev server can be started with npm run dev at repo root.

This starts a Webpack server for the web part (./packages/web) and also Firebase emulators for Firestore, Functions, and Auth.

Open http://localhost:8081/ in the browser to access the Webpack dev server. The port is configurable in ./packages/web/webpack.config.js under devServer.port. (Should you run into port conflicts for the Firebase emulators, those can be changed via ./packages/server/firebase.json. Just keep in mind to always visit the Webpack server, NOT the Firebase hosting emulator, in your browser.)

You should now be able to create a new room using the + button on the bottom right corner. To join the room as another player (to play test yourself), you may want to use use a different browser or an incognito / private window.

All front-end changes (TypeScript, Stylus, etc.) should trigger Webpack hot-reload. Changes to the Security Rules should be automatically picked up by the Firestore emulator.

Testing

npm test in ./packages/server should run the tests. These tests are mostly for the security rules (see below).

Security Rules

One unconventional design choice of this project is to implement the full game rules with Firebase Security Rules. Rules enforces that one cannot see their own cards and all moves (hints, plays, and discards) must be valid.

A Cloud Function is still needed for the initial random shuffling of the deck to ensure no player (read: client code) can see the full arrangement of cards. It also handles creation of the initial game state for convenience of implementation. After that, the entire Hanabi game is deterministic and can be expressed in terms of Rules conditions and document lookups.

With that being said, since Rules do not support loops or queries, one need to get creative on expressing the in-game invariants. The Firestore data schema is designed with these constraints in mind and features quirks and de-normalizations as a result.

  • /waitingAreas/{roomId}: pre-game player recruiting and game settings.
  • /rooms/{roomId}: public metadata and rules about each game.
    • Room schema: interface Room in ./packages/types/index.d.ts.
    • /cards/{cardId}: cards in the game with suit/rank and who can see them.
      • The IDs are indexes assigned based on their order in the deck.
      • Moves only references cardIds, ensuring the suit/rank of the cards is kept secret. This enables playing a card without seeing it.
      • shownToUids tracks which users can read the card.
      • Full schema: interface Card in ./packages/types/index.d.ts.
    • /moves/{moveId}: actions taken by players (publicly visible).
      • Immutable once created. IDs are indexes acsending from 0 (init).
      • Contains the type of the action and payload (e.g. play, cardId: 1)
      • Contains stateAfter, a snapshot of the board state after the move.
      • Both the action and stateAfter are validated by extensive rules.
      • Full schema: type Move in ./packages/types/index.d.ts.

The full Rules can be found at ./packages/server/firestore.rules.

When making a move, the client code must create /moves/{moveId} AND update visibility of any /cards/{cardId} (if changed) at the same time using a Firestore batch write. For example, when playing / discarding a card, the revealedByMoveId must be set to the proposed moveId and the shownToUids list must be set to all players. Also, a new card (if available) is drawn for replacement, which must be shown to all players EXCEPT the turn player.

A move must also calculate the stateAfter by delicately making an updated copy of the previous move's stateAfter with changes according to game rules. Hint moves must also indicate which cards match the hint. Since this quickly become complicated, helper functions are created for all types of moves, see ./packages/client/src/actions.ts.

The reading paths are comparably easier, but one must keep in mind that Rules are NOT filters. In other words, the client of a player must read / listen on queries that only returns cards visible to that player instead of the full cards collection. Since information is scattered across multiple collections, a client may see them temporarily out of sync due to timing of listener pushes. In other words, the client need to solve a stream-to-stream JOIN problem. ./packages/client/view.ts handles that gracefully and produces Rxjs Observables with the most up-to-date information.

Licensing

Apache License 2.0.

This project does not contain any material (e.g. graphics or rules text) from the physical version of the Hanabi board game. The project contributors are not in any way affiliated with the artists, designers, or publishers of that game.

This is a personal project maintained using my own spare time and own resources. It is not an officially supported Google product.

You might also like...

A Leaderboard app that pulls from a LeaderboardGameAPI and allows users to view recent scores and add more scores to the score board. Built with HTML5, CSS, JavaScript, and Webpack.

A Leaderboard app that pulls from a LeaderboardGameAPI and allows users to view recent scores and add more scores to the score board. Built with HTML5, CSS, JavaScript, and Webpack.

Leaderboard A Leaderboard app that pulls from a LeaderboardGameAPI and allows users to view recent scores and add more scores to the score board. Buil

Dec 21, 2022

Easily create key board shortcuts for your JS functions. Built using JS only with no other dependency. Inspired from MacOS spotlight

floodlightjs Inspired from macOS spotlight, floodlight is simple JS library that will show a search area. How the search is handled is completely on y

Aug 12, 2022

A public board for all the Computer Society and Students to display their profile. An online year-book for you to display your profile in the most creative manner

A public board for all the Computer Society and Students to display their profile. An online year-book for you to display your profile in the most creative manner

Student's Yearbook by IEEE Computer Society Student's yearbook is an open-source project which intends to dispaly the students who will be graduating

Dec 18, 2022

A task board is considered to be one of the most successful tools for teamwork. Whether it's for work, a side project or even the next family vacation, we helps your team stay organized.We've got the flexibility and featuresto fit any team's style.

TaskBoard !Important! The project is in its initial stage. In the near future I'll be adding new features and upgrading the old ones to be more optima

Oct 11, 2022

Bulletin board system (BBS) for our laboratory with enthusiasm

Bulletin board system (BBS) for our laboratory with enthusiasm

Cubilose Cubilose 是基于 Create-T3-App 开发的论坛框架,旨在为开发者提供简单易用、高效稳定的论坛搭建体验 文档 · 快速开始 · 参与贡献 ⚠ 开发中 项目处于开发设计阶段,目前还不可用 如何开发 安装 pnpm npm i -g pnpm 克隆仓库 git clon

Oct 25, 2022

An implementation of the Dungeons & Dragons 5th Edition game system for Foundry Virtual Tabletop

An implementation of the Dungeons & Dragons 5th Edition game system for Foundry Virtual Tabletop.

Jan 2, 2023

NFT Game Starter Project: https://github.com/buildspace/buildspace-nft-game-starter

Running React on Repl.it React is a popular JavaScript library for building user interfaces. Vite is a blazing fast frontend build tool that includes

Feb 11, 2022

Conways-game-of-life - A Conway's Game Of Life project using Python

conways-game-of-life A Conway's Game Of Life project using Python JavaScript Devlog January 1st 2022: also need to remember Python's syntax a bit will

Sep 23, 2022

Slime jumper game is a simple game that requires you to escape from the enemies that come your way.

Slime Jumper What is this game? The slime jumper game is a game with a simple logic (but it was not so easy to do) where you have to escape from the e

Mar 1, 2022
Owner
Yuchen Shi
Yuchen Shi
Leader Board is a simple project based on JavaScript programing language. The purpose of this project is to work with APIs and ASYNC & AWAIT methods. I have used vanilla JavaScript with web pack to implement this project

Leader Board - JavaScript Project Table of contents Overview The challenge Screenshot Links Project Setup commands My process Built with What I learne

Mahdi Rezaei 7 Oct 21, 2022
SimpleProject is a web app that allows users to create projects and manage them in a Kanban board.

What is SimpleProject SimpleProject is a web app that allows users to create projects and manage them in a kanban board. SimpleProject was built with

Mahmoud Fettal 25 Nov 23, 2022
PDF data extraction for Physiotherapy Board NZ APC's

physioboard-apc-reader Parses and extracts info from NZ Physio board issued certificates Install npm install physioboard-apc-reader Use import { physi

null 2 Jan 13, 2022
JavaScript project for the Leader-board list app, using webpack and ES6 features, notably modules

Leaderboard JavaScript project for the Leader-board list app, using webpack and ES6 features, Built With HTML CSS Javascript webpack Getting started t

Banlon Jones 3 Feb 17, 2022
Leader board application made with JavaScript that fetches an API to keep a record of users' scores.

Leaderboard This is a leaderboard that allows the user to created boards and input scores to them usin Rest API. Also, it saves new boards into local

Leonardo Albornoz 8 Mar 23, 2022
An interpreter for College Board's specified pseudocode for the AP Computer Science Principles Exam.

College Board Pseudocode Interpreter A playground for this interpreter is up on my website. This project is a mostly-functioning interpreter for Colle

Daniel 7 Nov 16, 2022
Use Kanban board with filled-in tasks that have categories and time estimations to assign work in group.

javascript-capstone 456movies 456movies is the home of amazing original programs that you can’t find anywhere else. Movies, TV shows, specials and mor

Oybek Kayumov 12 Dec 27, 2022
The only job board you will ever need.

Jobilist A stunning job search engine that helps job seekers find the perfect employment opportunity by connecting them with the best employers around

Jobilist 14 Dec 23, 2022
Anti - Web3 Developer Project Board

Anti is a social media platform designed to aggregate social media accounts for developers in the Web3 space with NFT profile pictures. Developers can

Josh Francisco 4 Jun 10, 2022