Final Fantasy VIII & TypeScript
Tags: gamedev, javascript, typescript, webdev
Published: 2022-04-23 12:44:04

For a better reading experience, you can read this article on my blog at [philscode.com](https://philscode.com/blog/ff8-typescript/).

## Overview 🗒️

Growing up I was an avid fan of the Final Fantasy game series. Particularly Final Fantasy 7 through 10. Each game in the series contains an in-depth story, hours of gameplay, and some mini-games. One mini-game introduced during Final Fantasy 8 was a card game known as Triple Triad.

Released in 1999, Final Fantasy 8 was a single-player game and so too was Triple Triad, the included card game. Being a single-player game meant that you couldn’t challenge friends to a quick card game. This led to continuous debates throughout my childhood about who really was the better player!

To settle the debate once and for all I wanted to re-create Triple Triad in such a way that allows you to grab a friend and challenge them to a quick game!

Below I will briefly run through the process of re-creating the base game, followed by a fully playable version (click [here](https://philscode.com/blog/ff8-typescript/#playable-game-) to skip to the playable version if you like 😀).


## Setup ⚙️

This game is going to use web technology so the Phaser framework is going to be used. It will also be piled with static assets so a Progressive Web App (PWA) is going to be created, not only to allow offline support but also greatly speed up reload times and provide installers for various mobile and desktop operating systems. To make this setup quick I'm going to utilise [this](https://github.com/yandeu/phaser-project-template) amazing Phaser boilerplate by [Yannick](https://github.com/yandeu).

## The board and cards 🎴

To start we're going to get a couple of assets for the board and mock some card assets to begin placement. Check out the gif below for the initial result.

![Gray identical placeholder cards being slotted on a board.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gziamkidj6yfdqkab81m.gif)

Coming together already! Let’s add some simple animations for placing the cards on the board and also to slide the remaining cards closer to the base of the screen.

![Gray identical placeholder cards being slotted on a board with animations.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74g6wn644xdhyruijht4.gif)

That makes it look a little less… dead. Always carefully manage your architecture correctly when considering animations. Some you may want to play asynchronously and others you want to wait until they are complete before starting another task or animation, rather than just utilising the `onComplete` callback to fire your next method, a more modular approach can be emitting events upon tween completion.

Let’s add some real cards! The cards are currently made up of 3 different assets. The card image itself is a transparent background and the blue or red back will change depending on its owner (Player 1 or Player 2).

![Cards with images and red and blue backgrounds being placed on a board.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zu6shs65wv07kwwyel7d.gif)

The above gif also demonstrates a randomisation of the cards upon reload.

Finally, let’s add the card ranks. Each card has 4 ranks (top, right, bottom, left) that each represents a score respective to the side they are placed on. The scores range from 1 through 10, with 10 being denoted as A. Each of these numbers is also a static asset so let’s add them in!

![Cards, with alphanumeric values in their upper left corner, being placed on a board.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/88x21b08n0qhedyjii5a.gif)

All in all our card is now made up of 7 assets in total. Each of these assets needs to animate together when moving the cards in order to maintain the look and feel that a card is just a single entity. Luckily Phaser's animation `Tweens` accepts an array of values so the heavy lifting is done for us. Onto the gameplay!

## The gameplay 🎲

The next step is being able to detect surrounding cards. Since the board is essentially a 2-dimensional array, this task proves to be quite simple.

![Cards being placed near each other with a pop up displaying surrounding card names.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il9nhcx9vq23ir09lsi8.gif)

The above demonstrates how once a card is placed horizontally or vertically next to another card it will detect which card or cards are surrounded by it. This is the most important mechanic of the game.

From here, it’s just a matter of comparing the values of the cards and changing the colour of the card or cards based on the opposing card.

![Cards being placed next to each other and changing background colour.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz20rhew5cmcaz29dnx1.gif)

Now when we place cards around the board, if their ranks are higher in value than the card they are placed next to we will update the colour of those cards to match the opposing card.

That alone gives us the basic game mechanic. Now for a little clean-up.

## Clean up 🧹

Lastly, a little bit of clean-up is in order. Firstly we are going to randomise the starting player. Then, we'll also add an indicator as to who won. Tossing in a few more animations around card flipping (tricky with 2D - but check out [Ourcade's](https://ourcade.co/) tutorial [here](https://www.youtube.com/watch?v=u1wNToPU8UY) - this helped a lot) and tweaking some of the asset depth and we have something playable. We'll also throw in some audio to bring it to life!

Check out the preview for the final result!

## Playable Game 🎮

Grab a friend and click below to play by `clicking or tapping` to select and place cards.

Please keep in touch and reach out to me to [connect with me on Twitter 😀.](https://twitter.com/intent/user?screen_name=philscode) 

[Click here to play the final result. Enjoy! 🎢.](https://philscode.com/blog/ff8-typescript/#playable-game-)

## PWA 💾

[To check out the PWA click here.](https://philscode.com/blog/ff8-typescript/#pwa-)