[{"document_url": "http://www.andymikulski.co/dev/peg-solitaire/", "unformatted_src": "http://i.imgur.com/gL5lM7Jh.jpg", "src": "http://i.imgur.com/gL5lM7Jh.jpg", "formatted_filename": "gL lM Jh"}, null, {"document_url": "http://www.andymikulski.co/dev/peg-solitaire/", "unformatted_src": "https://i.imgur.com/cSewvc3.jpg", "src": "https://i.imgur.com/cSewvc3.jpg", "formatted_filename": "cSewvc"}, null, {"document_url": "http://www.andymikulski.co/dev/peg-solitaire/", "unformatted_src": "http://i.imgur.com/lcupcb5h.jpg", "src": "http://i.imgur.com/lcupcb5h.jpg", "formatted_filename": "lcupcb h"}]
Peg Solitaire

Development time ~30-35 hours over three days

Engine Written from scratch in TypeScript

Concept Peg Solitaire-style game which players must jump over pegs to clear the game board.


As part of a programming challenge, I was tasked with recreating a peg solitaire game. Peg solitaire is a game youâve probably played before: Given the time constraint of three days, and self-assigning the task of building the game from scratch, Iâm very happy with the result! I tackled a lot of technical challenges that probably werenât really meant to be touched on, but ultimately it was a very fulfilling learning experience. The game itself is enjoyable, too, and I feel I made the right choice in secondary mechanics.


Outside of the standard peg solitaire rules outlined above and the âpeg jumpâ mechanic, I added a handful of secondary mechanics to the game. These mechanics work with helping/hindering board clearing and affording the user more points, which in turn leads the user to play differently than they might play normal peg solitaire.


The âengineâ for the game was written from scratch in TypeScript, which was a fun challenge to tackle. I wanted to build the entire experience within canvas, simply more as a challenge to myself than anything. Prior to this game, I had done a bit of canvas work (see: demos from other blog posts), so I felt prepared for the most part. At the end of the project, the only third-party package used in the code was for a psuedo-random number generator, which was pretty cool.

VCRâs and the Rendering Pipeline

The VCR (or Virtual Canvas Renderer) is a primary component in the game engine. Essentially, VCRâs are responsible for creating off-screen canvas instances and holding them in memory. Game objects (such as the score or time displays) each have their own personal VCR, dedicated to drawing whatever is needed for that instance. The game timer, for instance, has a VCR with which it prints text to on each tick of the game clock.

Another component in the system, the RenderingPipeline, handles printing each game object to the main output canvas. Each game object simply passes the image of their VCR to the pipelineâs rendering context with appropriate positioning, reducing draw calls while keeping the stage as up to date as possible.

An interesting feature of using VCRâs in this manner is that itâs quite trivial to set up a cached render (or a flyweight-esque pattern). For instance, the Peg game objects all pretty much look the same, so thereâs no need to redraw each one individually on each frame. By using a shared/static VCR, the visual display for each peg is rendered once and then simply re-printed during the draw call. This optimization was actually a huge boon to performance early on in development.

VCRâs also offer support for double buffering, though that feature isnât used in this game.


Having only a few days to put this game together, I decided to simply pass the asset loading off to the browser. The game only has a few assets to load: a couple webfonts, and a few sounds. Most of these files are not mission critical to the player, either, which is great; I didnât need to hold the game up to load assets.

Ideally, the Asset Manager would handle listening for onload events and all that, showing progress until the game is sufficiently loaded. For the purposes of getting the game out the door on time, I simply cut the âpreloadingâ corner, but in the future I wonât be so lucky.


Open in new page