Developing FFXIVRotations.com

In Final Fantasy XIV every character class has up to 57 skills. The order of which to use the skills is often talked about - whether it’s new players wanting to know how to use their new skills, or high end raiders who want the optimal sequence.

All the skills in Final Fantasy XIV:

Previously people would manually type sequences out to share them, or use abbreviations. Here’s an example:

H -> [BL+BFB] -> ID -> [IR+BOTD] -> DI -> [DRAC-POT] -> CT -> [PS+ LEGS] -> 4TH -> [JUMP] -> P -> [SSD] -> TT -> [DFD] -> VP -> [LIFES + GK] -> FT -> 4TH -> Repeat

This is time-consuming to write out and can be confusing to read as a lot of players remember skills by their icon (or position on their keyboard).

I wanted to make a tool that would allow people to easily communicate skill sequences.

Initial concept:

Finished site: http://ffxivrotations.com/17f You can see the site live here.

Tools & Technologies

After doing a quick proof of concept with plain jQuery I researched all the new technologies, libraries and tools that had emerged in the last few years. Here is what I settled on using:

  • Typescript
  • Sass
  • Python
  • jQuery
  • Materialize
  • js-cookie
  • MySQL
  • SQLite
  • Grunt
  • ATOM
  • Google Analytics

There were a few technologies I found that I’d like to try but didn’t get around to:

  • PureScript (pretty much Haskell in the browser)
  • React
  • ReactiveX

Technologies Mini-Review

TypeScript

TypeScript is a language that compiles to JavaScript. The main difference is that it has type safety. It’s a superset of JavaScript so I could use existing libraries.

Sass

Sass is a language that compiles to CSS. I didn’t really need it for this project, but after using it I wouldn’t hestitate to use it on larger projects where variables or mixins would be more useful.

Python

I used Python as the server language (straight up cgi scripts) and to pre-process the skill database.

jQuery

jQuery is my goto JavaScript library for selecting and modifying the DOM. jQuery draggable and sortable were key components for the UI.

Materialize

Material design is totally vogue, and this framework made it easy for me to make a page that looked decent. I strongly recommend materialize. One thing did trip me up - with the Chrome developer console open, the Materialize selector didn’t register all clicks. I never figured out why…

js-cookie

A straight forward key-dictionary store for cookies.

MySQL

I needed a database to store skill sequences and hit counts. I was about to use PostgreSQL before realizing the version installed on my webserver didn’t have an UPSERT command (inserts a row if it doesn’t already exist, if it does exist then update it).

SQLite

I wanted a way to manipulate a skill database before compiling it into a JSON file. I used SQLite in conjuction with Python to do this. I’m not convinced it was the best choice - the SQLite editors are primitive, something like Excel might have been a better choice, especially with tracking changes.

Grunt

Grunt is a way to run various tasks. In practice I’d use it to do the following:

  • Watch for changes in my Python script or SQLite database and rebuild the JSON file
  • Watch for changes in my TypeScript file and compile it to JavaScript
  • Watch for changes in my Sass file and compile it to CSS
  • Minify JavaScript/CSS/HTML

The ecosystem around Grunt is active. There are lots of tasks available with good documentation. I had not used task runners like Grunt before so I found it pretty neat, but I wasn’t a big fan of the syntax. I’d love to see a friendly UI for Grunt (I did find Gulp Fiction for Gulp).

ATOM

ATOM is an editor. It supported all the languages I needed without much trouble. It occasionally freezes up, but even then it saves my work.

Google Analytics

I was pleased to see Google Analytics had improved. You can see realtime visitors. Some things are nested a little deep though - such as finding out specific referral URLs. You can also up the creepiness factor and find out your users age, sex and lifestyle (but I didn’t enable that feature).

Decisions

Use a server side framework or use CGI?

I decided to go with simple Python CGI scripts. I only needed two scripts that did basic database communication. If I needed something more complex I would have tried something like flask or bottle.

Store Data in the URL or in a database?

In my prototype I had the sequence of skills stored in the URL, like:

ffxivrotations.com?class=1&sequence=321581193813918232132312441251651351113513

This was nice because it meant I don’t need to store data server side and the url is updated as the sequence is edited (with replaceState). However I found users didn’t like to share long URLs, and since I wanted to store hits per page I already had a database available so I decided to store the sequences in the database. I’m also storing last visit date so the database can be pruned if needed. Now after fiddling around with Apache’s mod_rewrite the URLS are like:

ffxivrotations.com/fe5

Link to external data or show my own?

I found out there are no complete and accurate databases of skills for FFXIV. I decided to roll my own from a variety of sources, and then do manual fixes/additions to complete it. Some details on the skills still are not correct so it’s an ongoing process.

Discoveries

  • Web Development has advanced a lot recently. Cross browser compatibility wasn’t as much of a worry, better languages and tools were available (however coming from Haskell TypeScript still seems a bit weak). Applications that look native but are actually developed with web technologies are becoming more viable/frequent (such as http://www.gitkraken.com/ and https://discordapp.com/).
  • Flexbox is very cool…I want to put everything in Flexboxes! Things like making a browser height app are easy with Flexbox. It’s a little unintuitive to learn though.
  • Task runners save a lot of repetition.
  • I really like my webhost (webfaction) combined with pairNIC for registering the domain ($10 a year).
  • Choosing a color scheme is hard (it needs work).
  • ATOM is my friend.

Reception

Reception to the site has been good so far. Links spread across social media sites organically without me needing to do SEO or advertising.

This…This is great, I can share my rotation without typing or talking on ts3 with my fc mate ( ´ ∀ ` ).

Forum Goer