I caught 2048 bug just like everyone else last week. The game is certainly a lot of fun, but I wanted to modify it in certain ways: increase the board from 4x4 to 5x5, increase the pace, etc.
I cloned the game and posted my version at https://glebbahmutov.com/2048/
This is a description of the few steps I took right after cloning the original github source. The steps are really basic techniques I use an ALL my projects. They are necessary to establish minimum quality base for a JavaScript / HTML project. The baseline is important because it allows automating all build steps.
Cloning
The basic step is to grab my own copy of the source, just like almost 2000 people have done. Press the "fork" button at the original github project and wait a few seconds to have a copy of the repo in your own space. For me, it is bahmutov/2048.
After bringing the code to local machine using
git clone [email protected]:bahmutov/2048.git
I got to work.
Each step is tagged using semver, and you
can inspect each milestone by looking at the
releases
0.0.0 - npm, grunt
I needed a systematic way to run certain command line tools: jshint, css preprocessor, maybe some others. I picked grunt because it is widely used, supports every other tool as a plugin, and I like it a lot.
In order to keep track of grunt plugins to install, I initialized
an NPM package
using npm init
command and answering a few questions.
I created Gruntfile.js to run jshint and nice-package. JShint will statically check JavaScript code for style and obvious syntax errors (like misspelled variables, etc). grunt-nice-package is my own Grunt plugin that checks the package.json structure to make sure everything is specified correctly. It is a good plugin to use whenever you need to open source your JavaScript code.
0.0.1 - fixing jshint warnings
Even a lenient .jshintrc file included with the project generated a few style warnings. I fixed the few found ones.
0.0.2 - sass to css
The game style is defined in style/main.css
and probably is generated from
the included style/main.scss
file. To compile SASS file into CSS file I added
grunt-contrib-sass plugin to package:
npm install grunt-contrib-sass --save-dev
I added sass
step to Gruntfile.
1 | sass: { |
I wanted a larger board size, 4x4 felt too small. So I increased the number of tiles from 4 to 5, and added corresponding HTML nodes to index.html. There was also field size passed around in JavaScript code. You can see the changes here.
0.0.3 - text changes
I changed the text on the game page to explain how 5x5 clone is different from the original 2048 and pointed back at my github project. The game at this point works, but the project has not been deployed to github pages yet.
0.0.4 - fast pace
I felt the original game started too slow. I could play for 5 minutes moving tiles one by one before real fun began. I increased the number of tiles appearing at each turn from 1 to 2. I also tweaked the probabilities for different new numbers: 2 is the most common, 4 is less common, and 8 very rare.
1 | // js/game_manager.js |
The JavaScript code is nicely separated into individual files, although I feel attaching everything to the window's global variable is bad. Ultimately I decided to not to restructure the code or even concatenate it at this point.
0.0.5 - github pages
2048 is a simple game, all code could be included in a single static HTML file if needed.
I decided to use free github pages to host it. For a github-hosted project it means
created a special branch gh-pages
, merging only the desired file (no Gruntfile, package.json, etc).
Doing this manually is a pain, so I installed grunt-gh-pages
and added gh-pages
step to Gruntfile
1 | 'gh-pages': { |
Only files necessary to play the game are included; no Gruntfile, no SASS input, no README.md. You can see the included files in the gh-pages and this is what gets served from https://glebbahmutov.com/2048/.
While testing the game from a mobile phone, I noticed wrong tile locations and incorrect number of tiles. So I found that number of tiles (4) is harcoded in two places in the SASS file. Desktop and mobile styles have separate number of tiles, see the SASS file. Because the file is long, I did not see the second variable. I would defnitely refactor this at first opportunity.
0.0.6 - offline mode
The game worked great on my phone, but whenever I had bad connection, I could not open the url. So I added offline mode by utilizing HTML5 app cache manifest.
I added cache attribute to the index.html
1 | <html manifest="cache.manifest"> |
and created a file cache.manifest
that lists files that should be cached by the browser
indefinitely. I also added a variable to this file that can be replaced with the
current timestamp using grunt-replace plugin.
Browser checks if the cache file has been updated to invalidate the cached files.
So by changing a commented out timestamp, I can clean the cached game version in the future.
The cache.manifest file lists all files used by the game that should be cached, it closesly mirrors what gh-pages brunch has
CACHE MANIFEST
# @@timestamp: Sun Mar 23 2014 23:03:21
CACHE:
index.html
js/animframe_polyfill.js
js/application.js
js/game_manager.js
js/grid.js
js/html_actuator.js
js/keyboard_input_manager.js
js/local_score_manager.js
js/tile.js
style/main.css
meta/apple-touch-icon.png
You can see the latest version of all code at github, and play the game from desktop or smart phone even without a connection. Happy hacking!