bstnfrmry / hanabi

Play Hanabi online with friends!
https://hanabi.cards
MIT License
95 stars 41 forks source link
game hanabi nextjs online typescript

Hanab.cards

Hanab is a cooperative card game inspired by, but unaffiliated with, a game made by French designer Antoine Bauza published in 2010 by Asmodée Éditions.

Like us, please buy the physical version to support its creator if you like this game!

If you enjoy our app, you can also buy us a coffee ☕️!

Buy Us A Coffee

Contribute

We are so happy to see people join the project and contribute to the repository. Do not hesitate to add an issue or open a pull request.

Thanks to all the people who contributed!

Issues

Open an issue everything you want to report

Do not hesitate to give us context on what you were trying to achieve, what page you were on, what user story, etc.

Code

Frameworks

The project uses the Next.JS React framework with Typescript and Firebase Realtime Database as a back-end.

You'll need to setup a free Firebase account to test the project locally.

Local setup and development
  1. Clone the project locally on your computer

  2. Execute yarn to install dependencies

# Install dependencies
$ yarn

# Configure Firebase
$ cp .env.sample .env && open .env

# Launch development environment
$ yarn dev

You'll probably see the following answer

ready - started server on http://localhost:3000 info - Loaded env from .env

  1. Open your browser on http://localhost:3000

Help us translate

The game is currently available in English, French, Dutch, Spanish and Russian thanks to a handful of contributors! Thanks a lot again!

We use react-i18n for translations. Documentation can be found here. Want to add a new language? Here is a short intro on how to proceed.

How to add a new language

First, setup the project locally and find the 2-letter language code of the new language you want to add. We use the standard ISO 639-1. en for English, es for Spanish, it for Italian...

Setup

Create the translation file and translate

ℹ️ How the translations are composed tagline: "Play Hanab online with friends!", The first element of every line is the translation name (keep it as is and do not translate it). The translation itself is located under the double-quotes.

For example, welcome: "Benvenuto", // Welcome in Italian

ℹ️ If you see html elements in your translation like <1>, you can refer to the next section for additional information.

Import the new languaage

(...)
import { en } from "~/locales/en";
import { es } from "~/locales/es";
import { fr } from "~/locales/fr";
import { it } from "~/locales/it"; // italian
import { nl } from "~/locales/nl";
import { ru } from "~/locales/ru";

i18n
  .use(initReactI18next)
  .use(LanguageDetector)
  .init({
    resources: {
      en: {
        translation: en,
      },
      fr: {
        translation: fr,
      },
      es: {
        translation: es,
      },
      it: { // italian
        translation: it,
      },

Add it to the configuration (next)

Open the next.config.js file and add the language to the list of options for the configuration.


  i18n: {
    locales: ["en", "fr", "es", "it", "nl", "ru", "pt"],
    defaultLocale: "en",
  },

Add it to the selector

const Languages = {
  en: "English",
  fr: "Français",
  es: "Español",
  nl: "Dutch",
  ru: "Russian",
  it: "Italian" // italian
};

Some advice If you started some work and did not have time to finish, do not hesitate to open a pull request labelling it as WIP (work in progress). It will help us know someone is currently working on the project so as to let them know if a new feature has been added (with new translations) or to help them continue translating directly on the open branch.

HTML elements in translations

discardPile: "discard ({{ discardLength }})",

ℹ️ The following discardPile translation will be displayed as discard (13) in English when 13 cards are in the discard pile.

Pluralization

The variable that will trigger the plural or singular is always named count.

For example

  turnsLeftDisclaimer: "· 1 turn left",
  turnsLeftDisclaimer_plural: "· {{count}} turns left", // 2 turns left

count does not have to be in the translation itself. It can be used only to trigger or not the plural. For example :

  // in the code file
  t("red", { count: hintableCards.length }),

  // in the translation file, for ex fr.ts rouge = red
  red: "rouge"
  red_plural: "rouges" // as you can see, count is not in the translation itself

Need to modify the code?

If your language requires adapting the code or splitting a translation and you do not know how to implement these modifications, do not hesitate to ask for help on Github or Discord.