Sunday, October 25, 2015

Card Creator - Automating Card Creation in NodeJS

Card Creator is a little tool I've been working on for automating the creation of card graphics for a card game I'm working on (tentatively) called Sorcerer's Arena.  The purpose of the tool is to automate the combining of art and font assets from a set of JSON data into the image PNG assets needed to print the cards.

You can find the current version on GitHub and it works pretty well at the moment.  I need to find better images (not a phenomenal artist here) and I need to find some good fonts and backgrounds, but the program works.

Card Creator uses NodeJS and Node Canvas to render images in a canvas style way on the server.  I looked into a few alternatives like Graphics Magick  and Image Magick but neither were particularly suited to combining images easily in a layered format like the HTML5 Canvas is (and by extension Node Canvas, which uses Cairo).  By far, the installation and debugging of the setup of this project took the longest, so I'll go into the problems I came across and how I resolved them as well.

Setting It Up

First, this project was a pain in the arse to set up.  Cairo has many dependencies, all of which may or may not be working, and Node Canvas also has some issues as well with the latest versions.  First things first, you need Cairo.  My experience is with a Mac Book Pro, so it may differ if you have Windows or a Linux Distro.  

I ran into a few problems, namely I had issues with:
  • Multiple Installations of Cairo (Brew vs MacPorts, etc)
  • The Version of Cairo & Dependencies
  • The Version of Node Canvas
I created the project in NodeJS with the latest version of Node Canvas, Async and put a small sample together using a few image and some text.  I set up my Git repository and then began getting things set up with Cairo which Node Canvas relies on.

I had installed Cairo for Mac a long time before, but never got things working with it.  That was installed with Brew, and when I started this project, I tried a new installation method using MacPorts.  Using MacPorts only caused more issues, because some things were referencing the Brew installation and dependencies and some were referencing the MacPorts, and everything just broke.

So I uninstalled everything from MacPorts, and uninstalled everything Cairo related from Brew and tried the whole re-installation from Brew, because Brew tends to be pretty solid.  I made sure that I had all the dependencies I needed for Cairo and Brew would tell me which I did not have linked correctly.  After the MacPorts debacle, I had to manually link a few of the Brew libraries to get them all set up. 

It ended up working, and I could generate images with Node Canvas but I still had issues.  Namely, I could not get using Fonts to work correctly and could not get them to render correctly either.  As I dove into this issue, part of it turned out to be a known issue with the latest version of Cairo on Mac OSX Machines, so ultimately to get around it, I used Brew to install all of the dependencies that Cairo required, I then uninstalled Cairo from Brew since the only version available on Brew was 1.14.0 which did not work correctly.  I then reinstalled a 1.12.X version directly from a the Cairo Releases FTP which cleared up a few issues with the font sizing and not rendering correctly.

However, I STILL had issues.  I could not load TTF Fonts into Node Canvas, which is something it is supposed to support.  So I started looking into this and found that it was a recent issue in Node Canvas.  So after some searching and debugging, I blew away the node modules folder and instead of using Node Canvas version 1.2.11 (the latest version), I hard set the version to 1.1.0.  And FINALLY everything worked.  I was able to load in True Type Font files and display them on the cards.  Using old versions of both Cairo and Node Canvas.  

Just a side note:  All this debugging and set up took me longer than it took me to make the current version of the application (~7 commits in at the time of writing this).

So now I had everything working, I could position text and images, use fonts, and build cards to my specifications.  Now I could build my application.

The Application

The application is fairly simple, if you've ever worked with the HTML5 Canvas before, it should feel very similar.  First, the main entry point for the app is the creator.js file.

Creator.js uses the following workflow to generate card graphics:
  • First, load in the libraries, configs, and most importantly, the card sets in the /card_values directory.  This file is where all of the settings to generate each card are stored in JSON format.
  • Next, Iterate through each card from the combined JSON files and perform the following:
  • Create a canvas element with setting specified in a general config setting.
  • Load all of the True Type Fonts in with the font loader library.
  • Draw the Background of the card on the Canvas.
  • Draw the Icons for the element types and stats, (and if this is a Sorcerer card, the miniature icons).
  • Write the Description Text in the main box.
  • Write the Title of the Card at the top.
And that's the entire flow.  Unlike some of my other blog posts I won't go too into the code but that's essentially how it all works.  

What this allows me to do is make small changes in the main configuration file, changes images, add images, change text or descriptions and update cards and quickly generate the entire set and images in seconds.  This allows me to try different things, modify entire sets of cards and not worry about having to manually create the cards in Paint.NET (which is what I was doing before).

As it is now, the quality of the cards isn't up to par with creating them as pixel art in Paint.NET, but I'm working to improve that and make the quality better.  Primarily I need to find a good way to create bordered fonts that aren't see through on the inside which most tend to be that I've found.  This application also paves the way for getting an artist on the project later and being able to quickly create cards as new art assets come in.

The end result of this project is that I can take something like this:

And turn it into this (below) with just a single command (node creator.js).

So far the application has been very handy for prototyping, and all of the code is open source so if you like making card games, feel free to extend the project and build on it for your own game!

I'll be building more on the application as well.  A few features I would like to add in the future are:
  • Creating the JSON files directly from a CSV, Excel Document or Google Spreadsheets documents (since I normally work in Google Spreadsheets for building the cards).
  • Better Fonts and possibly auto loading & mapping all fonts in the fonts directory.
  • Images for the cards, currently none exist and none are attempted to be drawn in the creator code yet.
  • Legit background (other than some grey boxes and a yellowish background color).
So that's my Card Creator application, if you haven't used Node Canvas I encourage you to check it out, but definitely pay attention when you're setting it up and potentially just use older versions to get it working correctly.  Once it's all set up, Node Canvas is pretty fun and easy to use for building server side imaging applications.

See Post #2 on the Card Creator:

No comments:

Post a Comment