Skip to content

lijim/monks-and-mages

Repository files navigation

Monks and Mages

Monks and Mages is a trading card-style game inspired by Heroes of Might and Magic / Magic the Gathering. The gameplay is similar to Magic, but with vastly simplified rules. Players build decks, then pit these decks against 1-3 other players. Cards are inspired from a mix of medieval and Chinese settings

To play, visit: https://www.monksandmages.com/

This game is a work in progress. If you find bugs, feel free to let me know on the issues section of this project

Installation and Running

This game can be run locally if you have node v16.x and yarn installed globally

To get started:

yarn install
yarn dev

Go to http://localhost:3000/ to see the game (and open it in multiple browser windows to simulate multiple players)

To see sockets.io debug screen:

open https://admin.socket.io/#/sockets while running the app

This project also strives for extensive TDD and unit testing. To run tests in watch mode:

yarn test

To run tests for a particular file:

yarn test src/server/gameEngine/gameEngine.spec.ts

To run tests once through:

yarn ci

Note: with the new auth0 and DB service integrations, you may need to contact me as a project owner for additional setup help

Core technologies

This project runs on a few core technologies:

Linting on this project is done via a combination of typescript, prettier, and eslint

Unit testing is covered via Jest and React Testing Library

Gameplay

Game rules

  • Players come with a deck of at least 60 cards
  • 2-4 players can play against each other
  • 7 cards to start, 1 card drawn per turn (unless starting player)
  • Players start with 20 life
  • Players lose when they either reach 0 or less life or attempt to draw from an empty deck
  • Cards come in 3 flavors: Resources, Units, and Spells
    • Resources are the basis for paying for the other two types of cards. When a player deploys a resource card (one per turn can be deployed), they add that resource to their casting pool. This casting pool refills every turn.
      • Casting costs are represented similarly to MtG. For instance, a lancer costs (🛠️), meaning a single iron can pay for one to be deployed onto the field
    • Units have a cost, an attack, and a health pool. The health of a unit ticks down whenever it is attacked. The attack determines
      • On a given turn, you can deploy as many units as you have space (max 6 units per player) and resources
      • Units can attack once per turn (some have > 1 attack / turn), and cannot attack the turn they are deployed
      • Units have 3 overarching types:
        • Soldiers: Non-magical units must attack soldiers, if any are present on the board. Soldiers are the 'tanks' of the game
        • Ranged: ranged units (including most magic units) can attack without getting 'hit back'
        • Magical: magical units can attack any target, including the opponent directly, even if there are soldiers present
    • Spells have an effect that is deployed immediately upon casting, such as:
      • Ember Spear (🔥) deal 3 damage to any target
      • A gentle gust (🔥)(🌊) buffs the team's stats by 1

Game philosophy

  • the game has 5 resources with separate identities:

    • Bamboo 🎋: resource generation, minor healing effects, buffing hp, ranged units and ranged damage spells
    • Iron 🛠: soldiers, sturdy units, minor damage spells, buffing attack and hp
    • Fire 🔥: direct damage, conjuration, curses (e.g. cursing an opponents' hand), buffing attack
    • Water 🌊: drawing cards, conjuration, returning units to hands (bounce)
    • Crystal 🔮: drawing cards (minor), resurrection, augmenting other forms of magic
  • Within the resources, we have 2 color combos that form unique sub-identities:

    • Crystal + Water: Water (more water spells accessible)
    • Crystal + Fire: Fire (more fire spells accessible)
    • Crystal + Iron: Saharan - Drawing / discarding
    • Crystal + Bamboo: Earth magic / primal / witchcraft (e.g. polymorph into frog)
    • Water + Fire: Wind
    • Water + Iron: Seafaring / pirates
    • Water + Bamboo: Coral Magic
    • Fire + Iron: Might and machinery (e.g. cannons, buff cards, damage-based boardwipes)
    • Fire + Bamboo: Dragon raising / Phoenixes
    • Bamboo + Iron: Ninjas / assassins

Scripts

Normally, downloading images from pexels / unsplash, processing them to be 520px in width, converting them to avif is a very manual process that we do through tools like https://squoosh.app/

Luckily, we've written some scripts to help with this process.

For all the cards in cardDb, imgSrc is not used in the components, but rather in these scripts as part of the 'download -> compress' chain. The img src's for each card are actually calculated via @/transformers/getImgSrcForCard

To run these scripts:

yarn images

To get an image into assets/images:

  1. Make sure to brew install imagemagick
  2. add a new unit / spell / token card to src/cardDb
  3. set that imgSrc to be a jpg image off the internet (starting with http)
  4. run the scripts above ^
  5. prosper!

Note: on occassion, some imageMagick conversions will rotate the image b/c of orientation. The camera may have originally recorded the picture in a different rotation, and imageMagick is trying to re-orient it:

https://legacy.imagemagick.org/discourse-server/viewtopic.php?t=33900

To fix this, I recommend taking a screenshot of the image and pushing it through https://squoosh.app - it's hacky, but it gets the job done.

Also in terms of dev tooling on Macs, the easiest way to inspect the generated avif's is actually through Github Desktop client.