Skip to content

yangdanny97/fire-emblem-chess

Repository files navigation

Fire Emblem Chess

A Fire Emblem themed, local, browser based chess game. Play it in your browser here

Intro

I've been playing a lot of chess during COVID, and Fire Emblem is one of my favorite video game series... so I thought it would be cool to whip up a version of chess where the visuals, sounds, and interface based on Fire Emblem. Gameplay-wise this is exactly the same as chess, and all the pieces work as you would expect chess pieces to work.

This game is designed to be played on a single computer, passed back and forth between players. The board orientation will flip depending on whose turn it is.

This project was originally implemented in JS, but I rewrote it in ReScript recently. Check out my blog post on rewriting a project in ReScript if you want to read about the rewriting process & my thoughts on ReScript as a language.

How to Play

Controls

  • WASD to move the cursor
  • X to select a unit or a square
  • Z to cancel your selection
  • Pawn Promotion: R(ook), Q(ueen), B(ishop), N(umm, knight)

Pressing X on one of your units will display which squares it can move to. Moving the cursor to a valid square and pressing X again will cause the unit to move to that square and capture any enemy unit on that square.

Pressing X on an enemy unit will show which squares it can move to, attack, or defend. You can toggle this off by pressing X again.

Features

Movement and Cover Highlighting

This is based on a similar mechanic in the Fire Emblem games, where legal movements and danger are displayed on the map. In chess, this feature makes it easy to visualize threats and identify hanging pieces.

When a unit is selected, undefended squares that it may move to/capture will be highlighted in blue. Squares that it may move to/capture that are in range of enemy units are highlighted in purple. While you are in check, your king will be highlighted in red.

Units which are threatened or defended by enemy units are highlighted in pink. You may also select an enemy unit to show all the squares that it threatens/defends (including empty squares).

In the following screenshot, the black pawn on B5 is hanging so its square is blue, while the black pawn on H5 is defended so its square is purple.

Here, the white bishop on C4 is threatened by the black pawn on B5, so its square is pink.

Pieces

I used modified sprites from the Fire Emblem GBA games to represent each chess piece. For reference, the mapping is shown below:

Chess Piece FE Sprite
Pawn Recruit Black pawnWhite pawn
Bishop Bishop Black bishopWhite bishop
Knight Great Knight/Paladin Black knightWhite knight
Rook Ballista Black rookWhite rook
King Pontifex Black kingWhite king
Queen Queen Black queenWhite queen

Sounds

I used sounds from the GBA games and Fire Emblem Heroes.

Dev Notes

Why didn't I use one of the many existing chess libraries?

I wasn't sure how to extract the necessary data to display which squares are covered by an enemy piece and keep it updated as the cursor moves, so I figured it wouldn't be too hard to just write a chess library myself. Back when I TA'ed a functional programming class in college, a few students submitted terminal-based chess games as their final projects, so I thought it could be fun to build one myself.

Why did I use D3 to render things instead of ___?

D3 is normally supposed to be used for dynamic & interactive data visualizations, so it definitely feels weird to use it for a game. One reason is it's the library I'm most familiar with, and I quite like using it. The other reason is that D3 is a really powerful library that is good for interactive graphics, and simple games like chess are just visualizations of the board state - when viewed that way, it's actually surprisingly suitable for the task.

Unimplemented Features

  • time controls
  • points system
  • repetition draws

TODO

  • general styling of the webpage outside of the chess board
  • notifications/banners for turn start, checkmate, stalemate, etc.
  • support dumping and reading board states from ASCII
  • vim key bindings for cursor movement