<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Gary Stanton]]></title><description><![CDATA[So, I seem to be doing *this* now.]]></description><link>https://garystanton.co.uk/</link><generator>Ghost 0.11</generator><lastBuildDate>Sun, 19 Apr 2026 01:02:21 GMT</lastBuildDate><atom:link href="https://garystanton.co.uk/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[My ZX Spectrum gaming journey]]></title><description><![CDATA[<p>Recently, I got into an argument with a random Twitter troll who, for reasons best known to himself, refused to believe that I’d ever owned a ZX Spectrum. This, despite my actually providing this rather nostalgic photo of my young self, receiving said Speccy one utterly glorious Christmas morning.</p>]]></description><link>https://garystanton.co.uk/zx-spectrum-gaming-journey/</link><guid isPermaLink="false">19e3260a-8148-479f-9f2b-d7c52a2a8115</guid><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Mon, 28 Aug 2023 14:16:03 GMT</pubDate><media:content url="https://garystanton.co.uk/content/images/2023/08/Banner.png" medium="image"/><content:encoded><![CDATA[<img src="https://garystanton.co.uk/content/images/2023/08/Banner.png" alt="My ZX Spectrum gaming journey"><p>Recently, I got into an argument with a random Twitter troll who, for reasons best known to himself, refused to believe that I’d ever owned a ZX Spectrum. This, despite my actually providing this rather nostalgic photo of my young self, receiving said Speccy one utterly glorious Christmas morning.  </p>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Gary---Speccy.png" alt="My ZX Spectrum gaming journey" title="">  </p>

<p>According to said troll, being a fan of Dizzy is a dead giveaway that my memories are fake. <br>
It’s a weird, weird hill to die on… but we live in strange times.</p>

<p>Anyway, it got me thinking about the first Spectrum games that I owned. I’m prone to reminisce over the games that defined the machine for me, (such as the aforementioned Dizzy, Chaos, Bak 2 Skool, et al), but I hadn’t really spent much time thinking about all the other random games that filled my cassette box… As I begun to think back and try to work out a chronology, more and more titles came into focus in my memory – rather like staring into the night sky as more and more stars become visible…</p>

<p>So let’s take a look at my half remembered chronology of Speccy games.  </p>

<hr>  

<p>First off… it’s Christmas morning and after years of yearning, and convincing myself that we’d never be able to afford one, I’ve finally received my first ever computer. My beloved ZX Spectrum. <br>
My mother helps me hook it up to the living room TV (a mistake she rectifies a week or so later with a dodgy black and white portable that could live in my bedroom, thus allowing her to actually watch something again), and I eagerly load up the first game that I received with the system.</p>

<h2 id="firststepswiththemrmen">First Steps with the Mr. Men</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/MrMen.gif" alt="My ZX Spectrum gaming journey">
Not a glorious start, it has to be said. I have little memory of this game, as I probably only played it that one time. As I remember it, there were little ice creams that popped up on the screen and I had to run around collecting them. I think I was playing as Mr. Bump at one point. This is clearly aimed at young children and at 8 years old, it’s way too slow for me… moving on.</p>

<h2 id="saracen">Saracen</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Saracen.png" alt="My ZX Spectrum gaming journey">
This second game is a much better outing and my first ever puzzle game. You’re this little archer dude and you have to run around collecting arrows that you can shoot to open doors or kill enemies, find keys to open locks, walk through one-way gates and such. Some of the levels are well thought out and this thing is days of fun… and it’s really difficult too. The enemies are just these little crosses that fly around the level at breakneck speed. They hug the walls, but kill you just by being next to you. Open the wrong door and fifty of these things will just start flying out like a swarm of bees from a hive. As you see them coming from just off screen, your death isn’t immediate, but it is definite… the whole thing is mildly terrifying.</p>

<h2 id="atvsimulator">A.T.V. Simulator</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/ATV.png" alt="My ZX Spectrum gaming journey">
Man, I loved this game… it’s essentially a 2D physics game where you control a vehicle and try to get to the end of several obstacle courses within a qualifying time. It’s an early example of the ubiquitous ‘motocross bike’ games where the aim is to get up some speed whilst actually keeping the wheels on the ground, lest the physics throw you upside down or get you stuck on an obstacle. It’s surprising how similar the gameplay feels to the modern versions, given that it came out in ’87. <br>
Again, it’s brutally difficult but crucially the learning curve is achievable. Pretty sure I managed to get through all of the courses eventually.</p>

<h2 id="masterofmagic">Master of Magic</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Master-of-Magic.png" alt="My ZX Spectrum gaming journey">
I gotta be honest, this game confused the hell out of me as a kid. It’s a dungeon crawler from Richard Darling. I played it a fair bit, but I think I was too young to realise I needed to start mapping out the rooms and working out how to dispatch certain enemies. I revisited the game quite recently and it makes a lot more sense as an adult… it’s pretty solid. Unfortunately, I also discovered it’s one of those games that are better on the C64. Sorry. <br>
Anyway, this game was published by Mastertronic’s ‘M.A.D.’ label and had this dude in a fedora on the label saying, ‘You bought the game, now play it!’. That stuck in my head for… well, the rest of my life. No idea why.</p>

<hr>  

<p>These were my only games for the first week or two, but it’s not long before I’ve saved some pocket money. There was a toy shop not too far from me, ‘Toycraft 70’ (I couldn't find a photo of this place anywhere), and every few weeks I’d have saved up enough money for a budget title. I’d make my way up to the shop, and ask the incredibly patient shopkeeper to pull down the trays of Spectrum games he kept on the top shelf behind the counter, and I’d spend hours going through them, reading the blurb, looking at screenshots, and narrowing down my choices. The fact that I’m alive today is a testament to the shopkeeper’s willpower, in not murdering me where I stood. <br>
I’m too young at this point to be interested in Spectrum magazines, so I’m not reading reviews – all I have to go on is the cassette tape covers, and word of mouth.</p>

<p>So next up we have: </p>

<h2 id="staykool">Stay Kool</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Stay-Kool.png" alt="My ZX Spectrum gaming journey">
My first platformer!! This is basically just a Manic Miner clone, but I’ve not played Manic Miner at this point (actually, sorry, I never owned Manic Miner as a kid), and I love it to bits. It’s incredibly difficult and I can’t remember how far through it I’ve got, but I remember still playing it the following Christmas. Looking back, it seems it got a pretty mediocre reception, but I have fond memories of it.</p>

<h2 id="dawnssley">Dawnssley</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Dawnssley.png" alt="My ZX Spectrum gaming journey">
A knock off of Gauntlet, (which I’ve yet to discover, and couldn’t have afforded anyway). Again, this game got absolutely trashed in the reviews, but I’ve not read them and I’m drawn to the weird alien creature on the front cover, which has absolutely nothing to do with the game whatsoever. <br>
Despite being universally hated, I loved this game! I mean, it’s Gauntlet. It’s 2 player, so I rope my mum into playing with me, and we plough through 27 levels of dungeon fun. I remember realising certain tactics, like destroying the enemy spawn points as a priority, and weirdly, that Hobbo the Elf should always be the one to open doors, as Thor the warrior is so big he can accidentally waste multiple keys by hitting both doors at once.</p>

<h2 id="cookie">Cookie</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Cookie.png" alt="My ZX Spectrum gaming journey">
A fast paced arcade shooter from Ultimate. It’s crazy difficult, and at such a young age I’m not sure I understood how to progress… but it’s fast, and fun, and looks great. Crazy to think this came out so much earlier than the other games in my list… Ultimate really knew what they were doing.</p>

<h2 id="punchy">Punchy</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Punchy.png" alt="My ZX Spectrum gaming journey">
I think this was given to me by the headmistress' secretary at my primary school... I can't remember why! <br>
It’s basically a Hunchback clone. Wild how many clones were out there and how that was just fine and no-one got sued. It’s not a bad clone, but the gameplay’s not great to start with… the levels get very repetitive after a while, but I played it to death anyway.</p>

<h2 id="dizzy">Dizzy</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Dizzy.png" alt="My ZX Spectrum gaming journey">
Finally, I get my hands on Dizzy. I’ve already played this countless times on a friend’s Amstrad, so I’m already well in love with the game and the character. It’s literally a dream come true to finally have Dizzy on a machine in my own bedroom, where no-one can kick me off or tell me to ‘go outside and play’… I can just work my way through the game. Tbh, I’m not sure I ever completed it as a kid, though definitely did through emulation later on. </p>

<h2 id="dynatronmission">Dynatron Mission</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Dynatron-missino.png" alt="My ZX Spectrum gaming journey">
This was a genuinely brilliant game with crazy colourful graphics and pretty decent physics. I played it a lot, but it always sticks in my memory as a game that I used when trying to make my first game. Before I understood anything about coding, I attempted to create a new game by copying the first half of my Dynatron mission tape, followed by the second half of my Saracen tape - thinking it would result in some kind of hybrid mash-up game with elements from both. <br>
It did not.</p>

<h2 id="daleythompsonsdecathlon">Daley Thompson’s Decathlon</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Daley-Thompson.png" alt="My ZX Spectrum gaming journey">
I must have picked this up at a bootsale, or had it donated by an adult… as this was in a big box and therefore well and truly out of my budget. Of course, it’s a classic, and I spent hours either hammering on the ‘O’ and ‘P’ keys, or turning my joystick upside-down and shaking it for all it was worth.</p>

<h2 id="enduroracer">Enduro Racer</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Enduro-race.png" alt="My ZX Spectrum gaming journey">
Actually, I think this belonged to the kid next door, but I played it a lot… a great bike racing game… really fast and fluid, and you can send the bike flying through the air. Hours of fun.</p>

<h2 id="trapdoor">Trap Door</h2>

<p><img src="https://garystanton.co.uk/content/images/2023/08/Trap-Door.png" alt="My ZX Spectrum gaming journey">
Oh man, just look at those beautiful big sprites! I loved the show as a kid and clearly remember it first being introduced by Niel Buchanan on the Saturday kid's show '73'. So I was excited to play the video game and it didn't disappoint. It was hard though... I don't remember ever getting beyond one or two tasks for 'im upstairs. I should try playing this again as an adult and see if the puzzles are any easier to grasp...</p>

<hr>  

<p>That's about all I can remember from the first few weeks and months of my Spectrum love affair. Subsequent birthdays and Christmases would yeild a glut of new games to play; basic and largely futile attempts at software piracy would occurr whenever I borrowed a game from a friend... and over the years my collection grew, up until I upgraded from my trusty ZX Spectrum to an Amstrad CPC464 plus.</p>

<p>Perhaps I'll make another post with the first games I played on that machine too... but as it's been three years since my last post, I wouldn't hold your breath!</p>]]></content:encoded></item><item><title><![CDATA[Black Lives Matter]]></title><description><![CDATA[I’d just like to state, unequivocally, for the record and for the avoidance of any doubt: 
Black Lives Matter.
I shouldn’t have to say that. But I do.]]></description><link>https://garystanton.co.uk/black-lives-matter/</link><guid isPermaLink="false">a68d2336-2ca0-47ea-ab0a-62303119de0e</guid><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Sun, 07 Jun 2020 16:20:22 GMT</pubDate><media:content url="https://garystanton.co.uk/content/images/2020/06/Black.gif" medium="image"/><content:encoded><![CDATA[<img src="https://garystanton.co.uk/content/images/2020/06/Black.gif" alt="Black Lives Matter"><p>We live in incredible times...</p>

<p>Those who don’t follow my Twitter feed (where I usually package my vitriol), those who don’t speak to me regularly and thus hear my incessant ranting, and those that aren’t privy to the constant level of conversation and news dissection that occurs in my home on a daily basis, may not be aware of my views.</p>

<p>So, I’d just like to state, unequivocally, for the record and for the avoidance of any doubt: <br>
<strong>Black Lives Matter.</strong> <br>
I shouldn’t have to say that. But I do.</p>

<p>There are those that might respond ‘all lives matter’ and I understand why you’d say that, but you’re wrong to respond that way.</p>

<p>There are those who would respond ‘white lives matter’ and I have absolutely no fucking time for you people.</p>

<p>I don’t mean to preach, I’m not best placed to do so – but I must say this: <br>
I stand with the protestors. I stand with black people. </p>

<p>I live in a system based almost entirely on white supremacy. I was educated in a whitewashed curriculum that sought to hide this fact... How little we learned in school about colonialism!! <br>
I grew up almost believing that racism was a thing of the past – a problem that had been solved long ago with protests and legislation and increasingly aware and progressive generations. <br>
When I encountered racism (never directed at me, obviously) it was like a relic from an older time, and shocking as much for its rarity as its abhorrence. </p>

<p>I’ve long since learned this is not the case, and that while being ‘openly racist’ is deemed unacceptable, systemic racism and racial disparity is so ingrained in our society that in truth I have unfairly benefitted from it every day of my life.</p>

<p>I am not in danger because of the colour of my skin. I am not discriminated against. No-one makes assumptions about me or feels threatened by me as I walk past them in the street. I have nothing to fear from police. </p>

<p>I’ve had the luxury of <em>deciding</em> when and if I will engage with issues of racial prejudice. I am ashamed of each and every occasion on which I’ve taken the easy way out by not challenging prejudice when I saw it. I’m not proud of the occasions on which I’ve taken a stand, because that should be the norm, not something worthy of pride.</p>

<p>I’ve come to learn there is a vast gulf between ‘not-racist’ and ‘anti-racist’. The former is easy, it’s passive. The latter is more difficult, it’s action, every day.</p>

<p>I wasn't at the protests in London yesterday, as travelling on public transport right now seems pretty dangerous. It’s difficult, because while there is a huge public health issue in thousands amassing to protest, the reason for the protest is too important to ignore. In truth, we should be protesting every single day. In truth, we shouldn’t have to.</p>

<p>It feels like this moment, for so many reasons, could be a tipping point – and I’m angry. I’m angry that it’s taken this long and that this is still an issue in 2020. I’m angry at myself for not being at every damned protest that has ever occurred in my lifetime. I’m utterly bereft in the knowledge that we have a racist prime minister. That America has a racist president. That the ‘arc of history’, does not it seems, bend toward justice. I despair at the rise of populism, the legitimacy of racism as a fucking ‘point of view’. I’m angry at every single person who votes for more inequality and policies that while devastating for all, will be particularly so for people of colour.</p>

<p>I want change. <br>
So, once again, I’d like to add my voice to those shouting: <strong>BLACK LIVES MATTER</strong>.</p>]]></content:encoded></item><item><title><![CDATA[Ludum Dare 46 in the bag...]]></title><description><![CDATA[Making 'For Ducks' Sake' in Phaser 3 for Ludum Dare 46. A post mortem of a 72 hour game development adventure.]]></description><link>https://garystanton.co.uk/ludum-dare-46-in-the-bag/</link><guid isPermaLink="false">c2936dcb-6d98-4d73-bbb3-d63ef1b6b398</guid><category><![CDATA[Ludum Dare]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[Phaser]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Mon, 11 May 2020 15:57:43 GMT</pubDate><media:content url="https://garystanton.co.uk/content/images/2020/05/Banner01.gif" medium="image"/><content:encoded><![CDATA[<img src="https://garystanton.co.uk/content/images/2020/05/Banner01.gif" alt="Ludum Dare 46 in the bag..."><p>Over a largely caffeine fuelled weekend in April, I embarked on my first non-solo game dev adventure, taking part in the Ludum Dare 46 with my long-time friend and collaborator, Lawrence Wong.  </p>

<p>The theme for this jam was the somewhat vague phrase, ‘<em>Keep it alive</em>’. I mean… that’s kinda the theme of every videogame, right?  </p>

<p>Game link: <a href="https://simiane.itch.io/for-ducks-sake">https://simiane.itch.io/for-ducks-sake</a> <br>
Jam link: <a href="https://ldjam.com/events/ludum-dare/46/for-ducks-sake">https://ldjam.com/events/ludum-dare/46/for-ducks-sake</a></p>

<h2 id="ideas">Ideas…</h2>

<p>We had two main ideas at the outset, the first being a lemmings style puzzler whereby the main character would be walking around obliviously triggering death-causing traps at every turn, and it would be down to you as the player to run around disarming said traps.   </p>

<p>The second idea was one involving a main character being followed around by slew of NPCs that were in constant peril from enemies and obstacles.</p>

<p>Once we’d decided to add a weapon to the mix, the second idea was the obvious choice since we wouldn’t have to worry about level mechanics, doors and the like. Our penchant for pixel art and animals dictated the theme of the game, and the delightfully titled <a href="https://ldjam.com/events/ludum-dare/46/for-ducks-sake">For Ducks’ Sake</a> was born.</p>

<h2 id="gettingthingsworking">Getting things working</h2>

<p>I heart <a href="https://phaser.io/">Phaser</a>. <br>
I’ve been messing around with game development for years and looked at countless frameworks, but they all seem very opinionated. I find the IDEs and workflow to be restrictive and confusing, and I’m generally happier with a black screen and some text. Phaser allows me to basically get my hands dirty. <br>
It’s a mixed blessing – I have full control over every little thing, but at the same time, every little thing has to be created and tweaked. What this tends to mean is that rather than solve an immediate problem, I try to solve the type of problem with some encapsulated code that I can reuse again and again… with mixed results.</p>

<h3 id="theplayer">The player</h3>

<p>With Phaser it’s very easy to get a sprite on the screen, animate it and move it around, but of course our player needs to do other things like fire a weapon, accept input, play sounds, etc. Sure, we could put this logic in the game scene itself, but if we create a dedicated player class that extends a Phaser ‘GameObject’, we can keep this functionality coupled to the player and that makes it much easier to drop the player class into this or any other game. In fact, the player class I used here is adapted from another game I’ve been working on, and thus when I dropped it into the game the movement logic was already working.</p>

<p>Rather than extend a sprite, I chose to extend a container. Why? Well, a container can contain multiple sprites, and also has a physics body to play with. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/18-2330.gif" alt="Ludum Dare 46 in the bag..."></p>

<h3 id="aiming">Aiming</h3>

<p>And so we embarked upon the creation of some basic shoot-em-up mechanics and quickly decided that we’d want to allow directional shooting in a twin-stick arcade style.</p>

<p>Previously I’ve written a <a href="https://www.npmjs.com/package/phaser3-merged-input">Phaser 3 plugin to merge keyboard and gameput input</a> into a single object to be interrogated. The plugin only handled a single ‘direction’ input however, i.e. the left stick / d-pad / keyboard. Adding the right stick was simple enough, but what about mouse input? It was simple enough to add a function to track where the mouse was in relation to the player, but in order to convert that angle information into a direction for the player to face, requires engagement with my old adversary – circle maths.</p>

<p>Honestly, I remember learning about circles in maths at school and thinking I’d never need to use this as long as I lived. I was correct about that for over 2 decades – right up until I started making games. <br>
The upshot is that I had to really delve into the merged input plugin and as a result a lot of great changes and additions have been made. It’s really solid now and I’d recommend checking it out if you’re making games with Phaser. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/19-0220-circle-math.jpg" alt="Ludum Dare 46 in the bag..."></p>

<h3 id="shooting">Shooting</h3>

<p>Phaser has an unofficial <a href="https://www.npmjs.com/package/phaser3-weapon-plugin">Weapons plugin</a> that handles grouping and reusing (i.e. ‘pooling’) of bullet sprites. It also has a number of methods that make it easy to indicate direction of shot, rate of fire, etc. Originally we had different sprites for each direction in which the bullet would travel, but I could find no easy way of changing the frame of a bullet on the fly like that. There’s almost certainly a way to do it, as the weapon plugin is designed to allow multiple weapon types, but we were already way behind schedule. Luckily the plugin does handle sprite rotation, so after creating a simple method to position the bullet at the edge of the gun depending on the direction of the player, we were good to go.  </p>

<p>Explosions were added directly to each bullet object by looping through each bullet in the pool and extending the kill method. Before calling its parent method a new ‘explosion’ sprite is created, so for every bullet collision we get a lovely explosion animation too. In other games (with more time) I’ve used this technique to provide gunsmoke when a bullet is spawned too. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/19-1730.gif" alt="Ludum Dare 46 in the bag..." title="">  </p>

<h3 id="followers">Followers</h3>

<p>Next came the creation of our follower objects - the ducklings. These are classes that extend a ‘follower’ class, that in turn extend the sprite GameObject. The reason for three separate levels of extension (duckling > follower > sprite) is that we’d hoped to have other characters in the game and this level of abstraction allows for base functionality (following the player) to be extended with individual characteristics (speed, health, etc.)  </p>

<p>Initially the ducklings were set to simply follow the player around, using the ‘moveToObject’ function, however this constant movement toward the player looked little unnatural, and so I implemented a short random delay, so that the ducklings would only note the player’s position every so often and move to where they last remember the player being. This seemed to give the ducklings a bit more autonomy – they seem a little bit more like individual entities than sprites that are set to follow the player. It’s really fun when such a simple (one line of code) change can really change the feel of an object. I love game dev. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/19-2100.gif" alt="Ludum Dare 46 in the bag..."></p>

<h3 id="enemies">Enemies</h3>

<p>Enemies came next, and again for our Gnome enemies I chose to create a gnome class that extends a generic enemy class, which in turn extends a Phaser sprite GameObject. We of course, planned to have multiple enemy types, but alas, time was very much against us and it never came to pass. So the enemy (gnome) is set to randomly choose a single follower (duckling) when it spawns, and move toward it at a ranged random speed. If there are no followers in the scene, no gnome enemies will be spawned. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/20-0100.gif" alt="Ludum Dare 46 in the bag..."></p>

<h3 id="collisions">Collisions</h3>

<p>Adding collisions makes the game feel real for the first time. <br>
To begin with, a collision event between bullet objects and enemy objects so we can kill our gnomes. This event plays a death animation.</p>

<p>Next, our gnomes need to be able to capture our ducklings. <br>
Initially I’d planned to have the collision event change the properties of the duckling so that it could no longer move and attach it to the gnome object so that as the gnome tried to get away, the duckling sprite followed it at a fixed point, making it appear to be in the hands of the gnome, then if the gnome is killed, the duckling sprite is dropped, decouples from the gnome and regains the ability to move… However, one of the things I’ve learned about game dev is that ‘cheating’ is often the best way to go – it’s a difficult coding style for me to get my head around coming from a web dev background where code elegance is important – so I quickly realised that it would be much easier to simply ‘kill’ the duckling object and change the animation of the gnome sprite to make it <em>look like</em> it was carrying a duckling. Then if the gnome is killed, we can simply spawn a new duckling object at that position. Probably saved about a hundred lines of code there and made life much easier!</p>

<p>Finally we need to allow collision between the player and both ducklings and gnomes so that you can push them away from each other to give you room to breathe/shoot… just to add another dimension to the gameplay. This also has the added effect that if a gnome isn't actively chasing a duckling (i.e. when the gnome has <em>caught</em> a duckling) and you push him away, he'll run off screen at an increased speed. </p>

<p>You may notice that the gnome running animation goes faster if the gnome is <em>moving</em> faster. This is due to a little bit of code that dynamically adjusts the framerate of an animation based on the velocity of the object. It's a nice little effect I tend to use <em>everywhere</em>. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/20-0400.gif" alt="Ludum Dare 46 in the bag..."></p>

<h3 id="gameplaypolish">Gameplay &amp; polish</h3>

<p>At this point, the project really started to feel like a game. All we needed to do was add some scoring and a bit of a difficulty curve.  </p>

<p>We had of course originally planned to flesh this out into a much bigger game, incorporating waves of enemies, power-ups including new weapons &amp; extra lives - which in this case were to be little eggs that you’d need to sit on for a few seconds to hatch into ducklings… oh, it would have been so cute!</p>

<p>But fleshing out a game isn’t really what a game jam is about… stripping everything down into something playable and polishing it up in the last few hours on zero sleep and enough redbull to floor an elephant… is what a game jam is about.</p>

<p>So the last few hours were spent adding music and sounds, menu and gameover screens, storing scores &amp; timers in local storage and generally getting the game ready to publish.</p>

<p>I particularly love the little giggle the gnomes make when they steal a duckling. </p>

<p><img src="https://garystanton.co.uk/content/images/2020/05/21-0530.gif" alt="Ludum Dare 46 in the bag..."></p>

<hr>

<h2 id="bugsbugsmoredamnedbugs">Bugs, bugs, more damned bugs</h2>

<p>It was of course at this last second, that we noticed some bugs in movement and collision. <br>
It seems that the gamepad support would simply fail to work maybe 20% of the time. <br>
Occasionally collision between bullets and gnomes failed to work too. </p>

<p>We had to publish the game before fixing, and in fact it took a long time to get to the bottom of the bugs. What I found is that gamepad support on browsers can be pretty flaky, and for various reasons there were knock on effects that caused problems elsewhere.</p>

<p>At the heart of the problem is our reliance on the ‘<em>connected</em>’ event of the gamepad. If the browser has registered the gamepad’s existence before Phaser loads up (i.e. if you’re pressing a button when the game loads) then the ‘connected’ event will never fire and this the game logic won’t connect the player and the pad. I ended up interrogating the browser’s gamepad API directly to manually fire the connected event in the case that a gamepad was already registered. <br>
I updated my input plugin to handle this and pushed it up to Github and NPM.</p>

<p>This worked great for me, but a couple of days later when I came to use the input plugin on another game I was working on, I found that the gamepad would no longer work at all on Firefox. It still worked on Chrome. We were still getting occasional reports of gamepad problems on the game, so I figured this must be the same issue. On further investigation I found that sometimes, for reasons unknown, the browser’s gamepad API will register null gamepad objects in addition to the actual gamepads! So in this case I would have two gamepads, a null at index 0 and the real gamepad at index 1. <br>
Fixing this is easy enough, but it’s just another little inconsistency we have to deal with. </p>

<h2 id="stillheartphaser">Still heart Phaser?</h2>

<p>The whole experience has made me question my use of Phaser as a framework for more serious releases. The ‘blank slate’ nature of Phaser development makes things like UI long winded to create and I’m sure other frameworks will do a bit more of the heavy lifting there. <br>
What really worried me though, is the bugs in the game and how difficult it was to get to the bottom of them… however I had some great support from the community and although it took a long time to work through what appeared to be bizarre and inexplicable issues, there was always an underlying cause and the issue has always been fixable. </p>

<p>Importantly and somewhat expectedly, the bugs are rarely anything to do with Phaser, but with my implementation and expectations. It’s reasonable to assume I’ll have a similar amount of issues and difficulties with any other framework. </p>

<p>In all likelihood, Phaser isn’t the <em>best</em> tool for the job when considering a larger game for a Steam release, but it’s still the framework I feel most comfortable with and least constrained by. </p>

<p>The mantra for game development remains ‘Do whatever works for you’. <br>
So, yes. I still heart Phaser. <br>
Heart heart heart. <br>
<img src="https://garystanton.co.uk/content/images/2020/05/hearts.png" alt="Ludum Dare 46 in the bag..."></p>

<h2 id="feedback">Feedback</h2>

<p>At the time of writing, the Ludum Dare 46 rankings period is almost at an end. So far we’ve had almost 300 ratings submitted, which puts us in the top ten most ranked games of the entire competition. </p>

<p>The feedback has been great – in opposition to my own sense of disappointment that the game couldn’t achieve all the lofty goals we set out to, it seems people have largely enjoyed playing it. For the first time, I’ve seen people playing the game on a live stream and chatted to them as they’ve done so. It’s been awesome.</p>

<p>I think <em>polish</em> accounts for a lot more in a game than you’d imagine… the gameplay is very basic, but while getting things like the physics and feel of a game right is probably the most important thing, you can cover a lot of issues with good graphics and little extra touches. For this I really have to hand it to Lawrence – the pixel art and animation style is nothing short of beautiful, and little touches like the duck crying animation and the gleeful smile of the gnomes are unexpected delights that make the player laugh and provide a subtle affinity with the game. </p>

<p>Without wishing to gush too much, Lawrence is a fantastic designer who can not only produce wonderful artwork, but also has a great understanding of what makes an experience fun. It’s always an enormous pleasure to work with him and anyone reading this should hire him <em>immediately</em>.</p>

<p>In a little over 24 hours, we’ll have the results of the ranking period. It’s always been my ambition to rank in the top 100 for a game on Ludum Dare. <br>
This competition has seen around double the number of entries at around 5,000 games, so top 100 is very unlikely – but I’ll be back to report on the results in a few days.</p>

<h2 id="finally">Finally</h2>

<p>Making games is more fun than playing them. <br>
It’s more fun than pretty much any other kind of development I’ve done throughout my career.</p>

<p>With frameworks like Phaser, it’s easy to get started and with communities like the one surrounding Ludum Dare, game dev is accessible and fun.</p>

<p>If you’ve ever felt even the <em>slightest</em> inkling that you’d like to make a game, stop thinking about it and get started. </p>

<p>GLHF.</p>]]></content:encoded></item><item><title><![CDATA[It's been a while...]]></title><description><![CDATA[<p>Every now and again I check back on this blog and think to myself, “Oh, I must write about…” Whatever it is I’m thinking about at the time. Three years since my last post would indicate that I’ve not followed through with those inclinations… Still, here it sits,</p>]]></description><link>https://garystanton.co.uk/its-been-a-while/</link><guid isPermaLink="false">069f0313-b362-42a5-8332-886a7e070078</guid><category><![CDATA[General]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[Ludum Dare]]></category><category><![CDATA[ColdThumbs]]></category><category><![CDATA[CFML]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Thu, 16 Apr 2020 23:28:33 GMT</pubDate><content:encoded><![CDATA[<p>Every now and again I check back on this blog and think to myself, “Oh, I must write about…” Whatever it is I’m thinking about at the time. Three years since my last post would indicate that I’ve not followed through with those inclinations… Still, here it sits, an ever present reminder that I exist and have a little space on the web. What better time than during a worldwide lockdown, where we have little to do but sit indoors staring at screens, to pick up the virtual quill?</p>

<p>Over the last few years I’ve been hacking away on a bunch of different projects, some of which I still quite like – and I woke up this morning realising that I haven’t posted about any of them! So, first things first, let’s catch up a little:</p>

<h2 id="coldthumbs">ColdThumbs</h2>

<p>I launched my first real open source project, on ForgeBox. <br>
ColdThumbs v2, is a rewrite of a CFML image manipulation module I’ve been using in personal projects for a number of years. When given a source image, the ColdThumbs module will resize in a background thread and store the result as a cached image. Subsequent requests for the same size will return the cached image, unless the source has since changed. It sounds simple, but it’s a requirement for virtually every web application I’ve ever built, and ColdThumbs represents the best and most efficient solution I’ve found, Now, the fact it’s modularised and on ForgeBox means I can now use it in any application with a simple install in CommandBox. You can too, as it happens… <br>
Check out the demo, documentation and source code at <a href="https://simianenterprises.co.uk/coldthumbs/">https://simianenterprises.co.uk/coldthumbs/</a></p>

<hr>

<h2 id="wintersprinteragame">Winter Sprinter – a game</h2>

<p><img src="https://garystanton.co.uk/content/images/2020/04/winter-sprinter.jpg" alt="">
I’ve been playing with the <a href="https://phaser.io/">Phaser</a> JavaScript game framework for a number of years now and back in 2017 I built a Christmas themed game for a client. It’s a fun little endless dodging game, and you can play it over at <a href="https://amplicon.itch.io/winter-sprinter">https://amplicon.itch.io/winter-sprinter</a></p>

<p>Winter Sprinter was the last game I made in Phaser v2 and since then I began familiarising myself with Phaser v3, which led to another open source project and the first thing I’ve put out on NPM.</p>

<hr>

<h2 id="phaser3mergedinput">Phaser 3 Merged Input</h2>

<p><img src="https://garystanton.co.uk/content/images/2020/04/merged-input-demo.gif" alt="">
This Phaser plugin merges various input methods in a Phaser game into a single object, and solves a number of problems.</p>

<ul>
<li>Single place to handle all your input.</li>
<li>Keyboard and Gamepad input is amalgamated.</li>
<li>Handle input for multiple player objects to easily create multiplayer games.</li>
<li>Assign and reassign keys to actions for each player, allowing for ‘redefine keys’ function.</li>
<li>Assign multiple keys to a single action.</li>
<li>Interrogate current state of all buttons.</li>
<li>Global events emitted on button down/up.</li>
<li>Check for gamepad button presses (i.e. ‘justDown()’ functionality for gamepads)</li>
<li>Check the last device type used for interaction.
This is something you can just drop straight into your Phaser game and use straight away. Check it out at <a href="https://github.com/GaryStanton/phaser3-merged-input">https://github.com/GaryStanton/phaser3-merged-input</a></li>
</ul>

<hr>

<h2 id="liquifyboagame">Liquify Bo - a game</h2>

<p><img src="https://garystanton.co.uk/content/images/2020/04/Cover-Art-16x9.png" alt="">
All this messing about with Phaser 3 led me to take part in my second Ludum Dare game jam, where in a frenetic 72 hours I created my most recent game, Liquify Bo. The theme here was ‘your life is currency’, which I took to mean that you would need to spend your lives to continue. What resulted was a cute little platformer with some really nice physics. It’s fun to play, but there’s lots of room for improvement. No baddies ended up in the game, so it’s just about puzzling your way out of each level. This is the first game I’ve made with a level structure, so it was interesting getting that kind of functionality working. <br>
Have a play over at <a href="https://simiane.itch.io/liquify-bo">https://simiane.itch.io/liquify-bo</a></p>

<hr>

<p>I'd love to say I'll post more frquently from now on, but let's not kid ourselves... it may not happen... however as I type, the next Ludum Dare game jam is upon us. The theme will be decided in a little over 24 hours, and I’m intending to spend every waking moment of the subsequent 72 hours making a new game. For the first time, I’ll be entering the jam with my longtime friend and collaborator, Lawrence Wong. So whatever we end up building, I know it’s going to look awesome. I'd love to tell you about it.</p>]]></content:encoded></item><item><title><![CDATA[Gulp SASS: file to import not found or unreadable]]></title><description><![CDATA[<p>I recently ran into a problem with gulp-sass, whereby some of the partials that were being included in my main .scss file were intermittently not being found. Gulp would throw up the error: <br>
<code>file to import not found or unreadable: somefilename</code> <br>
What's odd about this is that not only did</p>]]></description><link>https://garystanton.co.uk/gulp-sass-file-to-import-not-found-or-unreadable/</link><guid isPermaLink="false">869e76d8-c8ba-45df-9b41-0bbc0b72a331</guid><category><![CDATA[gulp]]></category><category><![CDATA[Javascript]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Tue, 07 Feb 2017 21:57:03 GMT</pubDate><content:encoded><![CDATA[<p>I recently ran into a problem with gulp-sass, whereby some of the partials that were being included in my main .scss file were intermittently not being found. Gulp would throw up the error: <br>
<code>file to import not found or unreadable: somefilename</code> <br>
What's odd about this is that not only did the files in question exist, but if I simply went in and saved any file at all that was being 'watched' by Gulp - triggering a refresh of the gulp-sass task - the files would miracuously be found and everything would work fine!</p>

<p>Doing a bit of Googling I found that lots of people were having <a href="https://github.com/dlmanning/gulp-sass/issues/235">similar issues</a> and the general consensus seems to be that the cause is something to do with race conditions when saving files - specifically that libsass is just too damned fast.</p>

<p>I've seen it asserted that anyone who has this error must be using Windows with Sublime Text, and thus the workaround is to enable an option available in Sublime Text called <em>atomic_save</em>. This option saves to a temporary file and then overwrites the old with the new - and indeed it does seem to solve the issue for a lot of people.</p>

<p>I'm using an older version of Sublime Text however, which doesn't have the <em>atomic_save</em> option available - so I had to look elsewhere.</p>

<p>What I found is that simply getting gulp to pause for a few milliseconds before attempting to compile the SCSS, solved the issue perfectly.</p>

<p>Here's how we do this: <br>
Navigate to the project folder and from the command prompt install <em>gulp-wait</em> <br>
<code>npm install gulp-wait --save-dev</code></p>

<p>I'm using the <a href="https://github.com/yeoman/generator-webapp">html5 webapp yeoman generator</a> (that's a mouthful), which makes use of the <a href="https://www.npmjs.com/package/gulp-load-plugins">gulp-load-plugins</a> package and uses <a href="https://github.com/taptapship/wiredep">wiredep</a> to hook up bower dependencies, so in my case I needed to add <code>.pipe($.wait(200))</code> to the <em>wiredep</em> task, thus:</p>

<pre><code class="language-javascript">// inject bower components
gulp.task('wiredep', () =&gt; {  
    gulp.src('app/styles/*.scss')
        .pipe($.wait(200))
        .pipe($.filter(file =&gt; file.stat &amp;&amp; file.stat.size))
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)+/
        }))
        .pipe(gulp.dest('app/styles'));

    gulp.src('app/*.html')
        .pipe(wiredep({
            exclude: ['bootstrap-sass'],
            ignorePath: /^(\.\.\/)*\.\./
        }))
        .pipe(gulp.dest('app'));
});
</code></pre>

<p>Now, all is well!</p>]]></content:encoded></item><item><title><![CDATA[Scaffolding CRUD functionality in CFML - SELECT all the things!]]></title><description><![CDATA[<p>Following on from my recent post where I detailed <a href="https://garystanton.co.uk/my-cfc-methodology/">my approach to CFC organisation</a>, I wanted to share some more details of my current CFML coding methodology. <br>
Today I’m going to talk a little about database interaction.  </p>

<p>Unless you’re taking advantage of ORM in your CF application, you</p>]]></description><link>https://garystanton.co.uk/scaffolding-crud-cfml-select/</link><guid isPermaLink="false">2441c23c-3846-4155-b771-25ddabbb483b</guid><category><![CDATA[CFML]]></category><category><![CDATA[Coding]]></category><category><![CDATA[SQL]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Sat, 28 Jan 2017 14:25:00 GMT</pubDate><content:encoded><![CDATA[<p>Following on from my recent post where I detailed <a href="https://garystanton.co.uk/my-cfc-methodology/">my approach to CFC organisation</a>, I wanted to share some more details of my current CFML coding methodology. <br>
Today I’m going to talk a little about database interaction.  </p>

<p>Unless you’re taking advantage of ORM in your CF application, you will most likely have to spend a bit of time scaffolding your components with some standard CRUD functionality. Some developers like to use a single component to manage all database interactivity, but I tend towards creating functions for each individual component. The goal is to have a standardised set of code for CRUD functionality that serve as core private functions on which others can be layered for the needs of the app.</p>

<p>Below, I’m going to show you how I handle READ functionality and we’ll look at how to efficiently use a single function to select data, dealing with:</p>

<ul>
<li><a href="https://garystanton.co.uk/scaffolding-crud-cfml-select/#filtering">Filtering</a></li>
<li><a href="https://garystanton.co.uk/scaffolding-crud-cfml-select/#pagination">Pagination</a></li>
<li><a href="https://garystanton.co.uk/scaffolding-crud-cfml-select/#sorting">Sorting</a></li>
</ul>

<hr>

<h2 id="somedata">Some data</h2>

<p>First off, we need some data to play with. For this exercise, I've created a very simple table with some test data in it. <br>
<img src="https://garystanton.co.uk/content/images/2017/01/CRUD-01.PNG" alt="Database content">
Feel free to <a href="https://garystanton.co.uk/code/data/gamesdb.sql">download the SQL</a> if you'd like to play along. <br>
n.b. I’m using Microsoft SQL Server Express 2014 and Lucee 4.5 for my examples. Everything should work in SQL Server 2008, CF9 and above.</p>

<p>I’m going to start by building up a very simple function that we can use to <code>SELECT</code> data from the table in our database.</p>

<pre><code class="language-cfml">&lt;cffunction name="getRecords" access="public" returnType="query" output="false" hint="Queries the database for Games records"&gt;

    &lt;!--- Get records ---&gt;
    &lt;cfquery name="Local.qGetRecords" datasource="CFExamples"&gt;
        SELECT
            [Games].[ID]
        ,   [Games].[DateCreated]
        ,   [Games].[LastUpdated]
        ,   [Games].[Title]
        ,   [Games].[Machine]
        ,   [Games].[ReleaseDate]
        ,   [Games].[Publisher]

        FROM    [Games]
    &lt;/cfquery&gt;

    &lt;cfreturn Local.qGetRecords /&gt;

&lt;/cffunction&gt;
</code></pre>

<p>As you’d expect, this will simply return all the data in our Games table. <br>
<img src="https://garystanton.co.uk/content/images/2017/01/CRUD-01---Data.PNG" alt="Database content"></p>

<hr>

<p><a name="filtering"></a>  </p>

<h2 id="filtering">Filtering</h2>

<p>Let’s take a look at how to build record filtering into our functions. We’ll start by filtering by the most obvious criteria, the unique ID for the record. <br>
First, we’ll add an argument to the function to accept an ID:  </p>

<pre><code class="language-cfml">&lt;cfargument name="ID" required="false" type="string" /&gt;  
</code></pre>

<p>You may notice that I’ve chosen <code>string</code> as the argument data type, even though the ID will always be a numeric value. This is so that we can pass a list of IDs as an argument, and have our query return multiple matching rows.</p>

<p>Next we need to add the filters to our SELECT query.  </p>

<pre><code class="language-cfml">WHERE    1 = 1

&lt;cfif StructKeyExists(Arguments, "ID") AND ListLen(Arguments.ID) GT 1&gt;  
    AND [ID] IN (&lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#" list="true"&gt;)
&lt;cfelseif StructKeyExists(Arguments, "ID") AND isNumeric(Arguments.ID) AND Arguments.ID GT 0&gt;  
    AND [ID] = &lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#"&gt;
&lt;/cfif&gt;  
</code></pre>

<p>As you can see, I’m using <code>WHERE 1 = 1</code> as a dummy clause for my query. This will allow each conditional filter to begin with the word ‘AND’ without causing an error.</p>

<p>Using conditional statements in this way, we can dynamically construct our SQL query, whilst still maintaining security – <em>don’t ever forget to use <code>&lt;cfqueryparam&gt;</code>!</em></p>

<p>We can use similar methodology to add other filters as applicable. Here's a more fleshed out version with a couple of examples:  </p>

<pre><code class="language-cfml">&lt;cffunction name="getRecords" access="public" returnType="query" output="false" hint="Queries the database for Games records"&gt;  
    &lt;cfargument name="ID"           required="false" type="string" hint="Filter by ID" /&gt;
    &lt;cfargument name="Title"        required="false" type="string" hint="Filter by Title" /&gt;
    &lt;cfargument name="Machine"      required="false" type="string" hint="Filter by Machine" /&gt;
    &lt;cfargument name="ReleaseDate"  required="false" type="string" hint="Filter by release data - range separated by comma" /&gt;
    &lt;cfargument name="Publisher"    required="false" type="string" hint="Filter by Publisher" /&gt;

    &lt;!--- Get records ---&gt;
    &lt;cfquery name="Local.qGetRecords" datasource="CFExamples"&gt;
        SELECT
            [Games].[ID]
        ,   [Games].[DateCreated]
        ,   [Games].[LastUpdated]
        ,   [Games].[Title]
        ,   [Games].[Machine]
        ,   [Games].[ReleaseDate]
        ,   [Games].[Publisher]

        FROM    [Games]

        &lt;!--- Dummy clause ---&gt;
        WHERE   1 = 1

        &lt;!--- ID ---&gt;
        &lt;cfif StructKeyExists(Arguments, "ID") AND ListLen(Arguments.ID) GT 1&gt;
            AND [ID] IN (&lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#" list="true"&gt;)
        &lt;cfelseif StructKeyExists(Arguments, "ID") AND isNumeric(Arguments.ID) AND Arguments.ID GT 0&gt;
            AND [ID] = &lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#"&gt;
        &lt;/cfif&gt;

        &lt;!--- Title ---&gt;
        &lt;cfif StructKeyExists(Arguments, "Title") AND ListLen(Arguments.Title) GT 1&gt;
            AND [Title] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Title#" list="true"&gt;)
        &lt;cfelseif StructKeyExists(Arguments, "Title") AND Len(Arguments.Title)&gt;
            AND [Title] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Title#"&gt;
        &lt;/cfif&gt;

        &lt;!--- Machine ---&gt;
        &lt;cfif StructKeyExists(Arguments, "Machine") AND ListLen(Arguments.Machine) GT 1&gt;
            AND [Machine] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Machine#" list="true"&gt;)
        &lt;cfelseif StructKeyExists(Arguments, "Machine") AND Len(Arguments.Machine)&gt;
            AND [Machine] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Machine#"&gt;
        &lt;/cfif&gt;

        &lt;!--- Release date range ---&gt;
        &lt;cfif structKeyExists(Arguments, 'ReleaseDate') AND ListLen(Arguments.ReleaseDate) EQ 2&gt;
            AND [ReleaseDate] BETWEEN &lt;cfqueryparam cfsqltype="cf_sql_timestamp" value="#GetToken(Arguments.ReleaseDate, 1, ',')#" /&gt; AND &lt;cfqueryparam cfsqltype="cf_sql_timestamp" value="#GetToken(Arguments.ReleaseDate, 2, ',')#" /&gt;
        &lt;/cfif&gt;

        &lt;!--- Publisher ---&gt;
        &lt;cfif StructKeyExists(Arguments, "Publisher") AND ListLen(Arguments.Publisher) GT 1&gt;
            AND [Publisher] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Publisher#" list="true"&gt;)
        &lt;cfelseif StructKeyExists(Arguments, "Publisher") AND Len(Arguments.Publisher)&gt;
            AND [Publisher] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Publisher#"&gt;
        &lt;/cfif&gt;

    &lt;/cfquery&gt;


    &lt;cfreturn Local.qGetRecords /&gt;

&lt;/cffunction&gt;


&lt;cfset Local.British_Home_Computing = getRecords(  
        Machine         = 'ZX Spectrum,Amstrad CPC,Amstrad GX4000'
) /&gt;


&lt;cfset Local.Nintendo_90s = getRecords(  
        ReleaseDate     = '1990-01-01,1999-12-31'
    ,   Publisher       = 'Nintendo'
) /&gt;

&lt;cfdump var="#Local#"&gt;  
</code></pre>

<p>So now we can see our filtered datasets: <br>
<img src="https://garystanton.co.uk/content/images/2017/01/CRUD-02.PNG" alt=""></p>

<hr>

<p><a name="pagination"></a>  </p>

<h2 id="pagination">Pagination</h2>

<p>There are plenty of different methods out there for paginating results of a query, but most of them require that we <code>SELECT</code> an entire recordset before filtering using CFML or sometimes JavaScript. I prefer to handle pagination directly in the database as it's much more efficient.</p>

<p>We can do this using a 'common table expression', which might be easier to think of as an RDBMS equivalent to 'query of queries'. <br>
We can add a <em>rownumber</em> to the query and then query the <em>results</em> to select rows that are between our pagination parameters. Here's a basic example:</p>

<pre><code class="language-sql">DECLARE  
        @PageSize    INT  = 5
    ,   @CurrentPage INT  = 1
;

WITH queryTable AS  
    (
        SELECT TOP 100 PERCENT
            [RowNumber]       = ROW_NUMBER() OVER (ORDER BY [Games].[ID] ASC)
        ,   [Games].[ID]
        ,   [Games].[DateCreated]
        ,   [Games].[LastUpdated]
        ,   [Games].[Title]
        ,   [Games].[Machine]
        ,   [Games].[ReleaseDate]
        ,   [Games].[Publisher]

            FROM    
                [Games]

        ORDER BY 
            [Games].[ID] ASC
    )

SELECT  
        (SELECT COUNT(*) FROM queryTable) AS TotalRecords
    ,   ID
    ,   DateCreated
    ,   LastUpdated
    ,   Title
    ,   Machine
    ,   ReleaseDate
    ,   Publisher

FROM queryTable

WHERE  
    [RowNumber] BETWEEN ((@CurrentPage - 1) * @PageSize + 1)
AND (((@CurrentPage - 1) * @PageSize) + @PageSize)

ORDER BY  
    [RowNumber]
</code></pre>

<p>This will give us a subset of our data as shown: <br>
<img src="https://garystanton.co.uk/content/images/2017/01/CRUD-03.PNG" alt=""></p>

<p>By adding this to our existing filterable function, we can filter the data and paginate our results, all before we ever get the CF query object. It's important to note that filtering should occurr <em>before</em> pagination, otherwise you'll only be filtering on the subset of data. <br>
Here's how our function looks now:  </p>

<pre><code class="language-cfml">&lt;cffunction name="getRecords" access="public" returnType="query" output="false" hint="Queries the database for Games records"&gt;  
    &lt;cfargument name="ID"               required="false"    type="string"   hint="Filter by ID" /&gt;
    &lt;cfargument name="Title"            required="false"    type="string"   hint="Filter by Title" /&gt;
    &lt;cfargument name="Machine"          required="false"    type="string"   hint="Filter by Machine" /&gt;
    &lt;cfargument name="ReleaseDate"      required="false"    type="string"   hint="Filter by release data - range separated by comma" /&gt;
    &lt;cfargument name="Publisher"        required="false"    type="string"   hint="Filter by Publisher" /&gt;

    &lt;cfargument name="ResultsPerPage"   default="25"        type="numeric"  hint="Number of results per page" /&gt;
    &lt;cfargument name="DisplayPage"      default="1"         type="numeric"  hint="Which page to display" /&gt;

    &lt;!--- Get records ---&gt;
    &lt;cfquery name="Local.qGetRecords" datasource="CFExamples"&gt;
        DECLARE 
                @PageSize       INT  = &lt;cfqueryparam value="#Arguments.ResultsPerPage#" cfsqltype="cf_sql_integer" /&gt;
            ,   @CurrentPage    INT  = &lt;cfqueryparam value="#Arguments.DisplayPage#" cfsqltype="cf_sql_integer" /&gt;
        ;

        WITH queryTable AS
            (
                SELECT TOP 100 PERCENT
                    [RowNumber]       = ROW_NUMBER() OVER (ORDER BY [Games].[ID] ASC)
                ,   [Games].[ID]
                ,   [Games].[DateCreated]
                ,   [Games].[LastUpdated]
                ,   [Games].[Title]
                ,   [Games].[Machine]
                ,   [Games].[ReleaseDate]
                ,   [Games].[Publisher]

                FROM    
                    [Games]

                &lt;!--- Dummy clause ---&gt;
                WHERE   1 = 1

                &lt;!--- ID ---&gt;
                &lt;cfif StructKeyExists(Arguments, "ID") AND ListLen(Arguments.ID) GT 1&gt;
                    AND [ID] IN (&lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "ID") AND isNumeric(Arguments.ID) AND Arguments.ID GT 0&gt;
                    AND [ID] = &lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#"&gt;
                &lt;/cfif&gt;

                &lt;!--- Title ---&gt;
                &lt;cfif StructKeyExists(Arguments, "Title") AND ListLen(Arguments.Title) GT 1&gt;
                    AND [Title] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Title#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "Title") AND Len(Arguments.Title)&gt;
                    AND [Title] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Title#"&gt;
                &lt;/cfif&gt;

                &lt;!--- Machine ---&gt;
                &lt;cfif StructKeyExists(Arguments, "Machine") AND ListLen(Arguments.Machine) GT 1&gt;
                    AND [Machine] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Machine#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "Machine") AND Len(Arguments.Machine)&gt;
                    AND [Machine] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Machine#"&gt;
                &lt;/cfif&gt;

                &lt;!--- Release date range ---&gt;
                &lt;cfif structKeyExists(Arguments, 'ReleaseDate') AND ListLen(Arguments.ReleaseDate) EQ 2&gt;
                    AND [ReleaseDate] BETWEEN &lt;cfqueryparam cfsqltype="cf_sql_timestamp" value="#GetToken(Arguments.ReleaseDate, 1, ',')#" /&gt; AND &lt;cfqueryparam cfsqltype="cf_sql_timestamp" value="#GetToken(Arguments.ReleaseDate, 2, ',')#" /&gt;
                &lt;/cfif&gt;

                &lt;!--- Publisher ---&gt;
                &lt;cfif StructKeyExists(Arguments, "Publisher") AND ListLen(Arguments.Publisher) GT 1&gt;
                    AND [Publisher] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Publisher#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "Publisher") AND Len(Arguments.Publisher)&gt;
                    AND [Publisher] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Publisher#"&gt;
                &lt;/cfif&gt;

                ORDER BY 
                    [Games].[ID] ASC
            )

        SELECT 
                (SELECT COUNT(*) FROM queryTable) AS TotalRecords
            ,   ID
            ,   DateCreated
            ,   LastUpdated
            ,   Title
            ,   Machine
            ,   ReleaseDate
            ,   Publisher

        FROM queryTable

        WHERE
            [RowNumber] BETWEEN ((@CurrentPage - 1) * @PageSize + 1)
        AND (((@CurrentPage - 1) * @PageSize) + @PageSize)

        ORDER BY
            [RowNumber]
    &lt;/cfquery&gt;
&lt;/cffunction&gt;  
</code></pre>

<p>This is a great way to get a paginated dataset, but it's worth noting that we'll still have to do some work with the results to <em>display</em> pagination controls in our views. In another post I'll show you how I generate pagination data with a separate function.</p>

<hr>

<p><a name="sorting"></a>  </p>

<h2 id="sorting">Sorting</h2>

<p>As with filtering, it's important that we sort our dataset <em>before</em> we paginate. <br>
It's easy enough to simply change the order directly in the SQL, but to expose different sorting options to our function we need to accept a fieldname as an argument and dynamically build our query. This is of course a dangerous thing to do, so we'll explicitly specify which fields can be used for sorting and validate against the list before building our query.</p>

<pre><code class="language-cfml">    &lt;cfargument name="SortField"            default="ID"        type="string" /&gt;
    &lt;cfargument name="SortDir"              default="DESC"      type="string" /&gt;

    &lt;!--- Set up allowed ordering fields ---&gt;
    &lt;cfset Local.AllowedSortFields = [
            'ID'
        ,   'DateCreated'
        ,   'Title'
        ,   'Machine'
        ,   'ReleaseDate'
        ,   'Publisher'

    ] /&gt;
</code></pre>

<p>Now we can use some tenery operator magic to build our 'rownumber' statement:</p>

<pre><code class="language-sql">[RowNumber]       = ROW_NUMBER() OVER (ORDER BY [Games].[#ArrayFind(Local.AllowedSortFields, Arguments.SortField) ? Arguments.SortField : "ID"#] #ArrayFind(["DESC","ASC"], Arguments.SortDir) ? Arguments.SortDir : "DESC"#, [Games].[ID] DESC)
</code></pre>

<p>Let's put this into our function:  </p>

<pre><code class="language-cfml">&lt;cffunction name="getRecords" access="public" returnType="query" output="false" hint="Queries the database for Games records"&gt;  
    &lt;cfargument name="ID"               required="false"    type="string"   hint="Filter by ID" /&gt;
    &lt;cfargument name="Title"            required="false"    type="string"   hint="Filter by Title" /&gt;
    &lt;cfargument name="Machine"          required="false"    type="string"   hint="Filter by Machine" /&gt;
    &lt;cfargument name="ReleaseDate"      required="false"    type="string"   hint="Filter by release data - range separated by comma" /&gt;
    &lt;cfargument name="Publisher"        required="false"    type="string"   hint="Filter by Publisher" /&gt;

    &lt;cfargument name="ResultsPerPage"   default="25"        type="numeric"  hint="Number of results per page" /&gt;
    &lt;cfargument name="DisplayPage"      default="1"         type="numeric"  hint="Which page to display" /&gt;

    &lt;cfargument name="SortField"        default="ID"        type="string" /&gt;
    &lt;cfargument name="SortDir"          default="DESC"      type="string" /&gt;

    &lt;!--- Set up allowed ordering fields ---&gt;
    &lt;cfset Local.AllowedSortFields = [
            'ID'
        ,   'DateCreated'
        ,   'Title'
        ,   'Machine'
        ,   'ReleaseDate'
        ,   'Publisher'

    ] /&gt;

    &lt;!--- Get records ---&gt;
    &lt;cfquery name="Local.qGetRecords" datasource="CFExamples"&gt;
        DECLARE 
                @PageSize       INT  = &lt;cfqueryparam value="#Arguments.ResultsPerPage#" cfsqltype="cf_sql_integer" /&gt;
            ,   @CurrentPage    INT  = &lt;cfqueryparam value="#Arguments.DisplayPage#" cfsqltype="cf_sql_integer" /&gt;
        ;

        WITH queryTable AS
            (
                SELECT TOP 100 PERCENT
                    [RowNumber]       = ROW_NUMBER() OVER (ORDER BY [Games].[#ArrayFind(Local.AllowedSortFields, Arguments.SortField) ? Arguments.SortField : "ID"#] #ArrayFind(["DESC","ASC"], Arguments.SortDir) ? Arguments.SortDir : "DESC"#, [Games].[ID] DESC)
                ,   [Games].[ID]
                ,   [Games].[DateCreated]
                ,   [Games].[LastUpdated]
                ,   [Games].[Title]
                ,   [Games].[Machine]
                ,   [Games].[ReleaseDate]
                ,   [Games].[Publisher]

                FROM    
                    [Games]

                &lt;!--- Dummy clause ---&gt;
                WHERE   1 = 1

                &lt;!--- ID ---&gt;
                &lt;cfif StructKeyExists(Arguments, "ID") AND ListLen(Arguments.ID) GT 1&gt;
                    AND [ID] IN (&lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "ID") AND isNumeric(Arguments.ID) AND Arguments.ID GT 0&gt;
                    AND [ID] = &lt;cfqueryparam cfsqltype="CF_SQL_BIGINT" value="#Arguments.ID#"&gt;
                &lt;/cfif&gt;

                &lt;!--- Title ---&gt;
                &lt;cfif StructKeyExists(Arguments, "Title") AND ListLen(Arguments.Title) GT 1&gt;
                    AND [Title] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Title#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "Title") AND Len(Arguments.Title)&gt;
                    AND [Title] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Title#"&gt;
                &lt;/cfif&gt;

                &lt;!--- Machine ---&gt;
                &lt;cfif StructKeyExists(Arguments, "Machine") AND ListLen(Arguments.Machine) GT 1&gt;
                    AND [Machine] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Machine#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "Machine") AND Len(Arguments.Machine)&gt;
                    AND [Machine] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Machine#"&gt;
                &lt;/cfif&gt;

                &lt;!--- Release date range ---&gt;
                &lt;cfif structKeyExists(Arguments, 'ReleaseDate') AND ListLen(Arguments.ReleaseDate) EQ 2&gt;
                    AND [ReleaseDate] BETWEEN &lt;cfqueryparam cfsqltype="cf_sql_timestamp" value="#GetToken(Arguments.ReleaseDate, 1, ',')#" /&gt; AND &lt;cfqueryparam cfsqltype="cf_sql_timestamp" value="#GetToken(Arguments.ReleaseDate, 2, ',')#" /&gt;
                &lt;/cfif&gt;

                &lt;!--- Publisher ---&gt;
                &lt;cfif StructKeyExists(Arguments, "Publisher") AND ListLen(Arguments.Publisher) GT 1&gt;
                    AND [Publisher] IN (&lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Publisher#" list="true"&gt;)
                &lt;cfelseif StructKeyExists(Arguments, "Publisher") AND Len(Arguments.Publisher)&gt;
                    AND [Publisher] = &lt;cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Arguments.Publisher#"&gt;
                &lt;/cfif&gt;

                ORDER BY 
                    [Games].[ID] ASC
            )

        SELECT 
                (SELECT COUNT(*) FROM queryTable) AS TotalRecords
            ,   ID
            ,   DateCreated
            ,   LastUpdated
            ,   Title
            ,   Machine
            ,   ReleaseDate
            ,   Publisher

        FROM queryTable

        WHERE
            [RowNumber] BETWEEN ((@CurrentPage - 1) * @PageSize + 1)
        AND (((@CurrentPage - 1) * @PageSize) + @PageSize)

        ORDER BY
            [RowNumber]
    &lt;/cfquery&gt;


    &lt;cfreturn Local.qGetRecords /&gt;

&lt;/cffunction&gt;  
</code></pre>

<p>And some examples:  </p>

<pre><code class="language-cfml">&lt;cfset Local.80s_By_Title = getRecords(  
        SortField           = 'Title'
    ,   SortDir             = 'ASC'
    ,   ResultsPerPage      = 5
    ,   ReleaseDate         = '1980-01-01,1989-12-31'
) /&gt;
</code></pre>

<p><img src="https://garystanton.co.uk/content/images/2017/01/80s-by-title.PNG" alt="80's by title"></p>

<pre><code class="language-cfml">&lt;cfset Local.80s_By_Date = getRecords(  
        SortField           = 'ReleaseDate'
    ,   SortDir             = 'ASC'
    ,   ResultsPerPage      = 5
    ,   ReleaseDate         = '1980-01-01,1989-12-31'
) /&gt;
</code></pre>

<p><img src="https://garystanton.co.uk/content/images/2017/01/80s-by-date.PNG" alt="80's by date"></p>

<pre><code class="language-cfml">&lt;cfset Local.90s_By_Publisher = getRecords(  
        SortField           = 'Publisher'
    ,   SortDir             = 'ASC'
    ,   ResultsPerPage      = 5
    ,   ReleaseDate         = '1990-01-01,1999-12-31'
) /&gt;
</code></pre>

<p><img src="https://garystanton.co.uk/content/images/2017/01/90s-by-publisher.PNG" alt="90's by publisher"></p>

<hr>

<p>This forms the basis of our read functionality. With this function in place, I tend to use a wrapper that passes parameters <em>to</em> this function and manipulates the results to handle pagination controls, logging, or anything else that might need to be done on each call. <br>
I also add freetext searching using a separate function - hopefully I'll go into more detail on this in another post.</p>

<p>In the meantime, I hope what I've gone over here will be of help to someone out there!</p>]]></content:encoded></item><item><title><![CDATA[My CFC methodology]]></title><description><![CDATA[<p>I’ve been thinking recently about my coding style. I’m always interested in doing things in the most elegant and efficient way possible and the methodology I use these days is a result of many years of experimentation and refinement.</p>

<p>I think a coding style, from formatting and file</p>]]></description><link>https://garystanton.co.uk/my-cfc-methodology/</link><guid isPermaLink="false">aeebcb39-d3c8-4881-bd93-961a8e3f0e94</guid><category><![CDATA[CFML]]></category><category><![CDATA[Coding]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Wed, 11 Jan 2017 23:58:00 GMT</pubDate><content:encoded><![CDATA[<p>I’ve been thinking recently about my coding style. I’m always interested in doing things in the most elegant and efficient way possible and the methodology I use these days is a result of many years of experimentation and refinement.</p>

<p>I think a coding style, from formatting and file structure to app conceptualisation; is a delicate balance between personal preference and the conventional wisdom of our peers. Well structured and thought out code is easy to maintain and a joy to return to, but inconsistent code can easily become unwieldy. </p>

<p>I wanted to share some examples of the way I’ve come to structure things – Perhaps someone will find it useful, or perhaps others might share their own methodology and I may learn something!</p>

<h3 id="todayimlookingatmycoldfusioncomponents">Today I’m looking at my ColdFusion components</h3>

<p>I like to create CFCs that can be reused across projects, and so I’ve found that I often add more and more functions and over time these components can become difficult to manage. <br>
My methodology now is to split each function into separate files, including them in the CFC code itself. It’s a simple concept, but the result is that it's easy to see from a glance in the filesystem which functions are in a given component, and all are easily editable.</p>

<p>The problem with splitting your functions out into separate files is finding an efficient way to include them in the CFC. To this end, I now use CFML file operations to automatically include .cfm pages from all sub directories. <br>
This means we can also split functions up in to separate sub-folders to group them together. For a large CFC, it's really rather zen like. ;)</p>

<p>Here’s a look at a typical CFC using this trick:  </p>

<pre><code class="language-cfml">&lt;cfcomponent  
    name        = "CFCDemo"
    output      = "false"
    hint        = "A demo of my CFC Methodology"
    displayname = "CFCDemo"
&gt;

    &lt;cfscript&gt;
        // Set CFC name
        Variables.CFCName       = 'CFCDemo';
        // Set folders
        Variables.CFCFolder     = GetDirectoryFromPath(GetCurrentTemplatePath());
        // Get CFC files
        Variables.CFCFiles      = DirectoryList(Variables.CFCFolder, true, 'query');        
    &lt;/cfscript&gt;

&lt;!---  
    Init function 
---&gt;
    &lt;cffunction name="init" access="public" returnType="any" output="false" hint="Constructor"&gt;
        &lt;cfargument name="DSN"  type="string"   required="true" hint="Datasource" /&gt;

        &lt;cfset Variables.DSN    = Arguments.DSN /&gt;
    &lt;/cffunction&gt;

&lt;!---  
    Include CFC files 
---&gt;
    &lt;cfoutput query="Variables.CFCFiles"&gt;
        &lt;cfif Variables.CFCFiles.type EQ 'file' AND ListLast(Variables.CFCFiles.name, '.') EQ 'cfm'&gt;
            &lt;cfinclude template="#(Variables.CFCFiles.Directory &amp; '\' NEQ Variables.CFCFolder ? ReplaceNoCase(Variables.CFCFiles.Directory, GetDirectoryFromPath(GetCurrentTemplatePath()), '') &amp; '/' : '') &amp; Variables.CFCFiles.Name#" /&gt;
        &lt;/cfif&gt;
    &lt;/cfoutput&gt;

&lt;!---  
    Memento
---&gt;
    &lt;cffunction name="getMemento" access="public" returntype="struct" output="false"&gt;
        &lt;cfreturn Variables /&gt;
    &lt;/cffunction&gt;

&lt;/cfcomponent&gt;  
</code></pre>

<p>What we're doing here is using DirectoryList to return a query object containing all the files in the current folder and sub-folders. If these files have .cfm extensions, they're included in the CFC itself. It's important to specify <code>.cfm</code> files only, as if you're using version control or comparison tools, backup files can easily sneak into the folder and be included in the CFC automatically.</p>

<p>I'm using a mixture of tags and CFScript here as I'm still more comfortable with tag based CFCs even though most of my logic is written in CFScript these days. Each to their own, ay?</p>

<p>So, how does this compare with your own methodology? I'd love to hear some opinions.</p>]]></content:encoded></item><item><title><![CDATA[Still writing CFML in 2017]]></title><description><![CDATA[<p>I came across a post by Adam Cameron today regarding <a href="http://blog.adamcameron.me/2017/01/survey-cfml-usage-and-migration.html">migrating away from CFML</a>, and the possibility of helping others to do so with some kind of project similar to the excellent <a href="https://github.com/cfjedimaster/ColdFusion-UI-the-Right-Way">ColdFusion UI the Right Way</a> - showing how common CF functionality could be replicated in other languages.</p>

<p>I</p>]]></description><link>https://garystanton.co.uk/still-writing-cfml-in-2017/</link><guid isPermaLink="false">5dd4b3ef-14e8-460c-bfe7-c6b0811aa01c</guid><category><![CDATA[CFML]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Tue, 10 Jan 2017 23:30:35 GMT</pubDate><content:encoded><![CDATA[<p>I came across a post by Adam Cameron today regarding <a href="http://blog.adamcameron.me/2017/01/survey-cfml-usage-and-migration.html">migrating away from CFML</a>, and the possibility of helping others to do so with some kind of project similar to the excellent <a href="https://github.com/cfjedimaster/ColdFusion-UI-the-Right-Way">ColdFusion UI the Right Way</a> - showing how common CF functionality could be replicated in other languages.</p>

<p>I still love CFML, but I can't deny that the community has gotten smaller over recent years and some of the work I've had of late has involved helping to maintain legacy CF based systems while new ones are being built in some other language.</p>

<p>I'm certainly not against moving to other languages, but I have to say I'm still in the process of building complex and if I do say so myself, <em>awesome</em> systems in CFML. There's life in the old girl yet if you ask me. <br>
Still, it's a worthwhile discussion and I would certainly be interested in a project that showed the <em>right</em> way to do things in languages I'm unfamiliar with.</p>

<p>I'd suggest anyone with some time to spare go over and fill out Adam's survey. In the meantime, I thought I'd share my answers below for posterity.</p>

<h3 id="provideabriefcommentaboutyourself">Provide a brief comment about yourself</h3>

<p>I'm Gary Stanton, a freelance webdev based in Brighton. Primarily contracting for a few clients and have been building bespoke systems for well over a decade.</p>

<h3 id="howdidyoucometobeadeveloper">How did you come to be a developer?</h3>

<p>I have no formal training beyond some very limited exposure to Turbo Pascal and Cobol in college. <br>
Back in the late 90's I was primarily designing, and coding websites for anyone who'd pay me to do so. Static HTML, tables for layout, all that lovely stuff. My focus was mainly on the design at that stage. <br>
In the early 2000's I was working for a small startup e-commerce company using an off-the-shelf offline package. As we grew, we began to need something more bespoke and dynamic. We were approached by a CF developer who ended up building our new system and so I was forced to familiarise myself with CF... It was so easy to get involved in the server side, and the possibilities excited me far more than design... I never looked back really. <br>
Dev is my core function, but with most of my clients I have to act as sysop as well. I do a bit of design and UX too if I can’t avoid it.</p>

<h3 id="summariseyourcfmlusagetimeline">Summarise your CFML usage timeline</h3>

<p>I’ve been using CF from about 2003 I think. I started on MX so have only ever experienced JVM versions. <br>
I've worked with every version up until CF11 <br>
Around 2012 I think, I began to use Railo for some clients and now split about 60/40 between ACF and Lucee. <br>
I’m not moving on yet, but front end dev has become a bigger part of my workload in the last 3 years or so.</p>

<h3 id="duringthattimewasityourprimaryorsoledevlanguageorwasitalwaysanadjuncttosomeotherlanguage">During that time was it your primary or sole dev language? Or was it always an adjunct to some other language?</h3>

<p>CFML has always been my primary server side language, but work has often required significant client-side stuff and I've sometimes found months have gone by where I've not used CFML much at all. <br>
I've had to work with Wordpress a fair bit, which I consider to be different to building in PHP as the API is so extensive. It's amazing how much you can do in Wordpress whilst still remaining utterly ignorant of the intricacies of PHP... alas. <br>
These days my primary focus is still CFML, but I'm doing more with JS... I've had some work with HTML5 game development and dabbled in Node a little. </p>

<p>Client side stuff has become more and more involved over the last few years, with responsive dev, package managers, build automation, etc. - I'm finding this is taking up higher percentages of dev time in any given project... ‘s fun though.</p>

<h3 id="didyouworkonjustinhousecodebasesforyouremployerordidyoualsoworkonthirdpartycodebasestoo">Did you work on just in-house code bases for your employer, or did you also work on third party code bases too.</h3>

<p>I've inherited a few in-house systems, and built a few of my own. <br>
I've not really had much experience with third party CF stuff - be it a framework, CMS or application. Everything is usually built from scratch. I’ll sometimes make use of a library or some Java class though.</p>

<p>I've been itching to open source some of my better stuff but have never quite got anything to a stage I'd be happy to release.</p>

<h3 id="ifyourestillprimarilyacfmldeveloperwhy">If you're still primarily a CFML developer... why?</h3>

<p>There's a whole bunch of reasons really... I've got a lot of CFML experience and I still find it a pleasure to build with. <br>
There are fewer CF devs out there, so I find myself on the radar of companies that need it.</p>

<p>There's also the fact that if I'm busy being hired to write CFML, I have less time to look at other languages. I'm confident in my ability to build robust and secure apps in CFML, but without the years of experience I've had, I'd feel less confident building complex systems in another language.</p>

<p>As a contractor, no-one is going to pay for my time to learn anything new, so my entire workday is filled with CFML or front end dev.</p>

<h3 id="ifyouvemovedonfromcfmlwhy">If you've moved on from CFML: why?</h3>

<p>I'm aware of the way the winds are blowing - while I've not moved away from CFML, I know I need to expand my skillset. Which way to turn is a bigger question and I've struggled to think of another serverside language that I could feel as empowered with, as CFML.</p>

<h3 id="doyouuseprimarilyorsolelycoldfusionorluceeorrailoorsomevariationofbluedragon">Do you use primarily or solely ColdFusion; or Lucee or Railo; or some variation of BlueDragon?</h3>

<p>I moved from ACF to Railo for my own systems primarily because of cost - my clients have limited budgets. <br>
I found however that Railo was faster, and that the team were far better at offering help and fixing issues. Most of my systems have migrated to Lucee now of course, though one or two are still on a legacy Railo version.</p>

<p>Some of my clients are still running ACF and that's great.... but if there's a bug, I have to find a workaround really, because it'll take Adobe well over a year to look at it and then decide they can't be arsed to fix it.</p>

<p>Having said that, the more corporate environments sometimes have requirements that ACF can handle and I'm not sure Lucee could. Bizarre legacy DLLs and the like... probably why they went for ACF in the first place.</p>

<h3 id="doyouparticipateinanycfmlbasedopensourceprojects">Do you participate in any CFML-based open source projects?</h3>

<p>Not really... I'll engage with a community if I'm using a project, but that rarely goes beyond submitting bugs or discussing features.</p>

<h3 id="andwhataboutinotherlanguages">And what about in other languages?</h3>

<p>I’ve made a few commits to the Magento API documentation... that count?</p>

<h3 id="whatisorwasforyouthebestfeatureofcfmlwhichhasyougoingyeahthatsprettycoolactually">What is or was - for you - the best feature of CFML which has you going "yeah, that's pretty cool actually".</h3>

<p>Flash forms? ;)</p>

<p>I dunno that there’s any one killer feature... and certainly none of the RIA bollocks... but there’s a few things I prefer in CF to php. <br>
I like that I can switch between CFScript and CFML and that I can embed a tag directly in HTML. I find php cumbersome in this regard. <br>
I like the struct and query objects, both of which seem more useful than what’s available to me in php. I also find the formatting of CFDump to be a real timesaver compared to the php options. I actually found a php UDF to mimic CFDump not so long ago.</p>

<h3 id="arethereanycfmlfeaturesthatwouldhavefallenintothatcategoryforyouwhenyouweredoingcfmlbutendedupnotbeingascoolasyouthoughtwhenyoulookedatotherlanguages">Are there any CFML features that would have fallen into that category for you when you were doing CFML, but ended up not being as cool as you thought when you looked at other languages?</h3>

<p>At a push maybe... query of queries? They can be useful, but more and more now I’m tending to write similar functionality directly in the DB, which feels a lot cleaner.</p>

<h3 id="whatisitaboutcfmlortheunderlyingcoldfusionluceeetcplatformyouliketheleast">What is it about CFML (or the underlying ColdFusion / Lucee / etc platform) you like the least?</h3>

<p>The JVM is still something of a mystery to me. I’ve had problems with the JVM over the years that I simply lack the understanding to diagnose... CFML is so easy to build great functionality and with a bit of experience I’m even confident I’m building things the <em>right</em> way; but still I’m at the mercy of the goddamned JVM, and I’m not sure as a CFML developer I should <em>have</em> to delve into the underlying JVM as much I have done. </p>

<p>I also find Adobe’s attitude to CF frustrating. Bugs take ages to get fixed, and way too much emphasis has been placed on poorly implemented RIA functionality to the detriment of the core language.</p>

<h3 id="iftherewasaprojectsimilartocoldfusionuitherightwaybutaimedatanypartofcfmllikehowtomakeadbqueryinphpinsteadofcfmlforexamplewouldyoubekeentohelponitwoulditbeofinteresttoyoutobeauserofit">If there was a project similar to "ColdFusion UI the Right Way", but aimed at any part of CFML (like how to make a DB query in PHP instead of CFML for example), would you be keen to help on it? Would it be of interest to you to be a "user" of it?</h3>

<p>I’d be interested in something like this if there was an emphasis on the ‘Right Way’ aspect. It took me a couple of months to learn to code in CF and probably about another five years to learn how to code <em>well</em>. Perhaps that would have been different if I had a computer science background, but I think it’s way too easy to learn bad coding habits. When I’ve dabbled in other languages, I have a niggling worry that I’m writing terrible code that I’ll come to <em>loathe</em> in a short while. <br>
I’m not sure how much help I could be, but I’ll keep an eye on the project.</p>]]></content:encoded></item><item><title><![CDATA[Mining ZCash on Windows]]></title><description><![CDATA[Add some stability to your ZCash Windows mining rigs, with some automated powershell magic.]]></description><link>https://garystanton.co.uk/mining-zcash-on-windows/</link><guid isPermaLink="false">c1050e39-d407-418c-b379-404e556a2346</guid><category><![CDATA[Tutorials]]></category><category><![CDATA[crypto]]></category><category><![CDATA[zcash]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Tue, 01 Nov 2016 00:16:38 GMT</pubDate><content:encoded><![CDATA[<p><strong><a href="https://z.cash/">ZCash</a> launched on October 28th among some of the craziest price volatility imaginable. <br>
Here’s how I got on, mining to a ZCash pool on a Windows GPU mining rig.</strong></p>

<p>I’ve been playing around with Bitcoin and alt currency mining since 2013, initially building a couple of GPU rigs to mine Litecoin and then diversifying across all manner of coins and algorithms. I’ve been mining Ethereum for some time and until recently no new coin launch has caught my attention enough to move my hashing power.</p>

<p>Recently however, I couldn’t help but notice the hype surrounding ZCash. <br>
ZCash is supposed to be truly anonymous in a way that Bitcoin never was. Anonymity is something that was <em>assumed</em> by early users of Bitcoin, but it was soon discovered that analysis of the blockchain could link transactions to people, fairly reliably. </p>

<p>Several coins have stepped in and tried to fill the anonymity gap, including the likes of <a href="https://www.dash.org/">DASH</a>, <a href="https://www.stealth-coin.com/">StealthCoin</a> and more recently, <a href="https://getmonero.org/home">Monero</a>. <br>
I won’t go into a technical comparison of competing coins, but suffice to say that no other anonymous coin has enjoyed quite the marketing push that ZCash has... I get a lot of my crypto news from <a href="http://www.coindesk.com/">CoinDesk</a> who are invested in ZCash, so that might have something to do with it – but either way I was interested enough to give mining a go at launch.</p>

<h2 id="zcashminingsoftware">ZCash mining software</h2>

<p>The ZCash wallet is only available on Linux at the time of writing. My woes with Ubuntu and AMD drivers are a <em>whole other topic;</em> so I decided to try mining to a pool on Windows.</p>

<p>At the time of writing there are three main Windows miners for AMD cards that I’ve been able to play around with. My rigs are a little old, housing mostly 7950 and R9 280X cards. Most of the testing for the Open CL miners seems to be around the RX 480 cards, so I’ve found the miners to be a little slower less stable on my older cards.</p>

<p>Here’s how the mining software stacks up currently:  </p>

<h3 id="silentarmy">SilentArmy:</h3>

<p><strong><a href="https://github.com/mbevand/silentarmy">https://github.com/mbevand/silentarmy</a></strong> <br>
The SilentArmy solver by <a href="http://www.zorinaq.com/">Marc Bevand</a> is widely considered to be the fastest. There are no Windows binaries for this, however other mining software authors have been implementing the solvers too.</p>

<h3 id="nicehash">NiceHash:</h3>

<p><strong><a href="https://github.com/nicehash/nheqminer/releases">https://github.com/nicehash/nheqminer/releases</a></strong> <br>
The team at <a href="https://www.nicehash.com/">NiceHash</a> had a Windows miner out quickly. Primarily the software is aimed at allowing rig owners to rent out their hashing power on the NiceHash platform, however NiceHash also have a pool at <a href="https://zcash.nicehash.com">https://zcash.nicehash.com</a> and their software can be used to connect directly to this, or any Stratum enabled pool. <br>
The NiceHash software will mine using CPU as well as AMD and NVIDIA GPUs... all at the same time. <br>
With an AMD 7950 using the latest drivers, I managed to get around <strong>10 Sols/s</strong> per card with this software.</p>

<h3 id="extremal">eXtremal:</h3>

<p><strong><a href="https://bitcointalk.org/index.php?topic=1660023.0">https://bitcointalk.org/index.php?topic=1660023.0</a></strong> <br>
eXtremal’s miner has a version using the SilentArmy solver and another forked from NiceHash. (eXtremal is listed as helping with the NiceHash Open CL implementation). <br>
The standard version was the first that I was able to get working on launch day – the others at the time were all crashing too much to use. However the software is tied into <a href="http://coinsforall.io/#!/coin/ZCASH">eXtremal's own mining pool</a>, which has a high fee of 4% and had payout issues on launch day. <br>
Speeds varied across rigs, but I was able to get around <strong>12 – 14 Sols/s</strong> with a mixture of 7950 and R9 280x cards. <br>
I was unable to get the SilentArmy version working with my cards, but I understand this might be a lot quicker.</p>

<h3 id="genoil">Genoil:</h3>

<p><strong><a href="https://github.com/Genoil/ZECMiner">https://github.com/Genoil/ZECMiner</a></strong> <br>
Genoil is well known in the Ethereum mining community. He had a few ZCash releases available on launch day, but it was very unstable and I couldn’t get it to run at all with my cards. <br>
The latest version at the time of writing is 0.4.2. It implements the SilentArmy solver and this is the first Genoil release that I’ve managed to get working. It’s running much quicker at around <em>20-25 Sols/s</em> per card – however it’s not the most stable, it can take several attempts to run and crashes every now and again. It still seems to be the best of the bunch for now, so we’ll address the instability with a bit of scripting further down.</p>

<h2 id="howtogetupandrunningminingzcashonwindows">How to get up and running mining ZCash on Windows</h2>

<p>AMD’s drivers can be pretty fickle and I’ve not updated in a while, so I decided to run with a fresh install of Windows 7. Here’s the steps to getting a rig up and running mining ZCash:</p>

<ul>
<li><p><strong>Windows update</strong> <br>
No, really. The latest AMD Crimson drivers require an up to date version of Dot NET (4.6 I think) and service pack 1 if you don’t have it. Installing the drivers without a fully updated version of Windows is a fool’s errand.</p></li>
<li><p><strong>TightVNC</strong> <br>
Much as it might look like Remote Desktop is working, in truth it plays havoc with a multi GPU mining system. The AMD card sensors don’t seem to function, drivers may not install correctly and I’ve been unable to adjust clock settings. Thus, I use Tight VNC to access my Windows miners over the network. <br>
Download the server here: <a href="http://www.tightvnc.com/download.php">http://www.tightvnc.com/download.php</a></p></li>
<li><p><strong>AMD Crimson drivers</strong> <br>
At the time of writing, the latest drivers are 16.40.2311 and available here: <a href="http://support.amd.com/en-us/download/desktop?os=Windows+7+-+64">http://support.amd.com/en-us/download/desktop?os=Windows+7+-+64</a> <br>
Install the display driver locally or over Tight VNC for best results.</p></li>
<li><p><strong>AMD APP SDK 3.0</strong> <br>
Available here: <br>
<a href="http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/">http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/</a> <br>
Download, install, etc.</p></li>
</ul>

<h2 id="scripting">Scripting</h2>

<p>The ability to leave your miner unattended is the key to a happy and stress free mining career. With the instability of the current mining software, there are a few steps we can take to keep our rigs running.</p>

<h4 id="firstwellwriteapowershellscripttocheckthatoursoftwareisrunningandstartitupifnot">First, we’ll write a Powershell script to check that our software is running and start it up if not</h4>

<pre><code class="language-javascript">$b = 1
do  
    {
        $a = get-process genoil -ErrorAction SilentlyContinue
        echo($a);
        if($a -eq $null) {
            Start-Process "cmd.exe"  "/c D:\ZEC\genoil-zec-miner-0.4.5\Genoil.exe -c stratum.zcash.nicehash.com:3357 -u YOUR-ZCASH-ADDRESS -p x -P 0 20 -g 0 1 2 3" -WorkingDirectory "D:\ZEC\genoil-zec-miner-0.5"
        }
        Start-Sleep -s 5
    }
while ($b -eq 1)  
</code></pre>

<p>This script loops every five seconds and checks that the mining software (in this case, the Genoil miner) is running. If not, it fires up a new instance.</p>

<h4 id="secondweneedtoallowthesoftwaretoexitwhenitcrashes">Second, we need to allow the software to exit when it crashes.</h4>

<p>Out of the box, Windows will attempt to ‘Find a solution’ to the problem of software crashing (has anyone, <em>ever</em> seen that work?) and when it fails, will require user input to close the window. We need to stop that from happening so that the process dies completely when the ZCash mining software crashes – and our script can fire off a new instance. <br>
There are two steps to this: </p>

<ul>
<li><p>Disable problem reports via the ‘Action Center’ in the Control Panel
<img src="https://garystanton.co.uk/content/images/2016/10/Mining-ZCash-01-1.jpg" alt=""></p></li>
<li><p>Disable the UI dialog box when crashing out by creating a DWORD value in the registry at: <br>
<code>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI</code>
<img src="https://garystanton.co.uk/content/images/2016/10/Mining-ZCash-02.jpg" alt=""></p></li>
</ul>

<h4 id="thirdweneedtogetthescripttorunonboot">Third, we need to get the script to run on boot.</h4>

<p>There are ways of running Powershell scripts through the group policy on boot, but I’ve not had any luck getting that to work – instead, we’ll create a batch file to run the PowerShell script. </p>

<p>Create a batch file in the same folder and with the same filename as your PowerShell script. <br>
Add the following:  </p>

<pre><code class="language-javascript">@ECHO OFF
PowerShell.exe -ExecutionPolicy Bypass -Command "&amp; '%~dpn0.ps1'"  
</code></pre>

<p>What we’re doing here is telling PowerShell to allow unsigned scripts for this session, and running the script we created to boot up the miner.</p>

<p>Create a shortcut to the batch file and place it in the <em>‘Startup’</em> folder in your start menu, so that it’ll run on boot.</p>

<h4 id="finallyweneedtomakesurethatourbatchfilerunsunattendedwhenwebootwindows">Finally, we need to make sure that our batch file runs unattended when we boot Windows</h4>

<p>Usually the system will wait for us to login before running items in the startup folder, so we need to automatically login.</p>

<p>Click on start and run: <strong>netplwiz</strong>. <br>
Choose the account you want to log in automatically and uncheck the box marked: <strong>‘Users Must Enter A User Name And Password To Use This Computer’</strong> <br>
<img src="https://garystanton.co.uk/content/images/2016/10/Mining-ZCash-03.jpg" alt=""></p>

<h2 id="andthatsityouredone">And that’s it, you’re done!</h2>

<p>The mining rig should now automatically run our PowerShell script causing it to check for the existence of the ZCash mining software, running it again whenever it has crashed.</p>

<p>Don’t forget to keep an eye on the various ZCash miners out there – these are very early days and new releases are coming out all the time... these new releases can often result in huge hash rate increases, so don’t get left behind!</p>

<p>Good luck!</p>]]></content:encoded></item><item><title><![CDATA[Ludum Dare 35 & my first game: Shiftah]]></title><description><![CDATA[<p>I’ve been dabbling in HTML5 game development with <a href="http://phaser.io/">Phaser.io</a> for the last few months and along the way I got wind of the <a href="http://ludumdare.com">Ludum Dare game jam</a>. </p>

<p><img src="https://garystanton.co.uk/content/images/2016/04/Ludum_Dare_Logo_small-3.png" alt=""></p>

<p>For those who’ve not heard of LD, this is a 72 hour (or 48 if you’re brave) game jam</p>]]></description><link>https://garystanton.co.uk/ludum-dare-35/</link><guid isPermaLink="false">e83a7114-a52d-4dc6-a8a9-154be749aa37</guid><category><![CDATA[Phaser]]></category><category><![CDATA[Game Development]]></category><category><![CDATA[Ludum Dare]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Sat, 23 Apr 2016 00:51:00 GMT</pubDate><content:encoded><![CDATA[<p>I’ve been dabbling in HTML5 game development with <a href="http://phaser.io/">Phaser.io</a> for the last few months and along the way I got wind of the <a href="http://ludumdare.com">Ludum Dare game jam</a>. </p>

<p><img src="https://garystanton.co.uk/content/images/2016/04/Ludum_Dare_Logo_small-3.png" alt=""></p>

<p>For those who’ve not heard of LD, this is a 72 hour (or 48 if you’re brave) game jam held three times a year. The community decide on a theme, announced at the beginning of the jam, and developers of all ages and experience levels spend a weekend creating a game to fit. <br>
Along the way, people post updates of how their game development is going, and offer inspiration and encouragement. </p>

<h2 id="theldcommunityspirit">The LD community spirit</h2>

<p>The LD jam has been going on for some years now and a significant community has built up around it. <br>
Reading through the rules and documentation on the website it really comes across that while there is a competitive element, the main point of the event is simply to encourage people to <em>create</em> something. There’s no prize as such, just the satisfaction of having taken part and having something to show for it. </p>

<p>As a complete newbie to game development, I was surprised at just how welcoming everyone was. I spent most of the weekend alone in my office in front of my computer, but very much felt that I was in a group and that we were all in it together. <br>
When I mustered up the courage to post what I considered to be a very mediocre game submission, I was absolutely floored at the positive response it received. Not to say that it was anything special, but it seems people only have positive words to say to <em>anyone</em> who took the time to get involved.</p>

<p>I will definitely be returning!</p>

<h2 id="thetheme">The theme</h2>

<p>The theme for Ludum Dare 35 was ‘<strong>Shapeshift</strong>’. <br>
Of course, the obvious way to go with a theme like that is a game whereby the main character can change into another form or creature, such as the main character in the game Altered Beast. </p>

<p>My abilities as an artist are very limited, so I couldn’t see myself creating anything along those lines, and instead took the theme literally, using ‘shapes’ and the ‘shifting’ mechanic. <br>
It seems I wasn’t alone in this, with over 2,000 entries, some of the submissions found really novel ways of interpreting the theme. Indeed, the rules state that even adhering to the theme <em>at all</em> is optional – the point is to spend the time creating something. <em>Anything</em>... Just get it out there!!</p>

<p>I set out to do just that, eventually deciding on a simple shape restricted movement game. <br>
Initially I was thinking of a kind of racing game where the player can take different paths around a track, but can only move through shape related obstacles when the correct shape is selected.</p>

<p>As I’ve only been playing with Phaser a short while, there’s plenty that I’ve not learned or experimented with; and after a while of thinking through how my racing game would work it became apparent that too many of the elements involved would be new to me. I would need to spend much of the little time I had, learning how to do new things such as create a level with Tiled and work on camera movement mechanics.</p>

<p>As I’ve been learning Phaser I’ve been applying new techniques to a basic SHUMP game and using it as a testing ground – so I had a rethink about how I could make a game that is closer to the mechanics and functions that I’m familiar with.</p>

<p>Eventually I settled on an endless runner style game, where the character would have to move through obstacles without getting stuck. There would be a path through the obstacles, but only the currently active shape would allow passage. The player would need to switch the active shape in order to proceed.</p>

<h1 id="developingmygame">Developing my game</h1>

<p>Sticking to relatively safe mechanics and functionality, I was fairly confident of being able to code up something playable in the time. I already had a prefab I’d been working on that handled sprite movement, one that dealt with keeping timers and hi scores, and some experimentation I’d done with animating text and such. As long as I kept the gameplay simple, I should be fine.</p>

<p>What I was less confident about is how the game might <em>look</em>. I spent the best part of a day messing about with graphics and mocking up a visualisation of my game. Initially I thought I’d embrace my complete lack of artistic abilities by hand drawing elements and scanning them in – but I wasn’t happy with the results and ended up just using very basic vector shapes. <br>
The minimalist style appealed to me once I’d added some very basic effects. I quickly stumbled onto an understated colour scheme I liked and the style of the game started to take shape.</p>

<p><img src="https://garystanton.co.uk/content/images/2016/04/Day-1.png" alt=""></p>

<p>Initial versions of the game began with very slow moving obstacles, and standard 8 way movement. It worked well enough, but just wasn’t very challenging until the game sped up significantly. To make play a bit more interesting I changed the movement to be rotation based, with left and right spinning the player and up and down moving them forward and backward in whichever direction they were facing. I also found that starting at a much higher speed just felt more exciting. Previously it would have taken about 90 seconds ramp up to the speed that the game ended up beginning at.</p>

<p>By the second day I had a working game with graphics I liked well enough, but I spent quite a long time trying to fix problems with the collision detection. <br>
Eventually I decided perhaps Arcade Physics as it’s known, (AABB collision) wasn’t right for the game and I made an ill-fated attempt at using Phaser's ‘Ninja Physics’ – which allows for different shaped bodies. Unfortunately, after spending a couple of hours trying to convert the game over to Ninja Physics I found that it wasn’t really complete and didn’t have function parity with the more basic Arcade Physics. I didn’t have time to work around all the problems that came up, so reluctantly switched back.</p>

<p>By the last day, I had to abandon fixing the collision issues in favour of finishing off the game. I still needed to add instructions, a game over screen, a logo, music and sound, scoring and a few other bits and bobs – not to mention getting the game live.</p>

<p>Despite my reservations, this all went fairly smoothly. I’d been playing around with Mod tracker software recently, following some tutorials. I had a few patterns I quite liked so it didn’t take too long to flesh one of them out a bit into a looping track for the game. </p>

<p>My game data prefab already handled keeping scores and local storage, so all I needed to do was hook it up and create some events to fire at it. </p>

<p>I knocked up some quick graphics for the logo and when I found myself with an hour or so left, I took a risk and started playing with tweening my font into a nice transition for the intro screen. It ended up working really well and I’m glad I took the time to add that little touch, I think something so subtle adds a great deal to the very first impression of the game.</p>

<h1 id="thefinishedarticle">The finished article</h1>

<p>After about 30 hours of work spread across the weekend, I ended up with <a href="https://garystanton.co.uk/games/ld35/">Shiftah</a> - a hastily named endless runner style shape based game.</p>

<p><a href="https://garystanton.co.uk/games/ld35/"><img src="https://garystanton.co.uk/content/images/2016/04/Shiftah.gif" alt="Shiftah - An HTML5 game made for Ludum Dare 35" title=""></a></p>

<p>My first ever game submission was quite nerve wracking. It's one thing to play with different ideas, but quite another to submit a full game, made in a rush, for judgement. I wasn't <em>happy</em> with my game, but felt I could be proud of what I'd managed to produce in such a short time, and with my level of experience. <br>
<a href="http://ludumdare.com/compo/ludum-dare-35/?action=preview&amp;uid=86710">You can view my LD submission page here.</a></p>

<h3 id="whatiliked">What I liked</h3>

<p>Mostly I was pleased with the clean look and feel of the game. I took the time to add some little bits of polish and I think it elevates the very basic gameplay to something that looks like it's had some effort put into it. <br>
I was very pleased with the feedback I got on the music too. I've spent such a short time learning to use a tracker - literally a matter of hours - so I feel that I can do so much better once I've learned some new tricks.</p>

<h3 id="whatidchange">What I'd change</h3>

<p>In truth, if I could go back and try again I'd change the entire game mechanic. I settled on it because something is better than nothing, but playing some of the other submissions has been really inspiring and I'd love to have another crack at it! <br>
Also, there are some glaring problems with the gameplay, specifically with regard to collisions and such.</p>

<h1 id="andfinally">And finally...</h1>

<p>Developing games is awesome. Frameworks these days do so much of the heavy lifting that it's really easy to get some instant gratification. Getting a sprite to move around the screen is so trivial, and having it shoot bullets and kill enemies, equally so. <br>
My advice to anyone who's ever wanted to make a game is to check out some tutorials online, and find out how quickly that itch can be scratched. <br>
Then, enter the next Ludum Dare and I'll see you there.</p>]]></content:encoded></item><item><title><![CDATA[Wordpress on IIS - Cannot create directory, and other issues surrounding Windows file permissions.]]></title><description><![CDATA[<p>Anyone brave/stupid/stubborn (delete as applicable) enough to <em>dare</em> to run Wordpress on Windows and IIS, is likely to have run headlong into the brick wall that is NTFS file permissions.</p>

<p>The language I'm using here is deliberately ironic. Even in 2016 the level of help you can expect</p>]]></description><link>https://garystanton.co.uk/wordpress-iis-file-permissions/</link><guid isPermaLink="false">0ea7426b-67b3-4243-bbe3-7e44a6e2b2f4</guid><category><![CDATA[iis]]></category><category><![CDATA[wordpress]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Fri, 05 Feb 2016 00:25:00 GMT</pubDate><content:encoded><![CDATA[<p>Anyone brave/stupid/stubborn (delete as applicable) enough to <em>dare</em> to run Wordpress on Windows and IIS, is likely to have run headlong into the brick wall that is NTFS file permissions.</p>

<p>The language I'm using here is deliberately ironic. Even in 2016 the level of help you can expect when searching online for Wordpress / IIS configurations is abysmal. The attitude of a great many contributors amounts to the following:</p>

<blockquote>
  <p>"Why are you using Windows (you idiot)? Don't use that, use LAMP (DUH!) and don't come around here no more, asking your Windozy questions like a n00b... it's called CHMOD, now get back in your damned cage."</p>
</blockquote>

<p>The Wordpress docs aren't a great deal better.</p>

<p>So perioically I find myself running into this issue on a Wordpres IIS installation, whereby I'm unable to update plugins or do other things that involve the system putting files into the <strong>wp-content</strong> folder. Thus ensues the usual frustration of spending hours Googling, clicking on results that look like they might be helpful, only to find that they're for a LAMP stack.</p>

<p><strong>No. More. Damnit!</strong></p>

<p>So I thought I'd document the various things I've found myself trying. Some of these have worked on their own in certain environments, others required a combination of factors. </p>

<h2 id="checkyourfilepermissions">Check your file permissions.</h2>

<p>It's the first place you look when you see a filesystem related error. Check who owns the <strong>wp-content</strong> folder in Windows. Check who has access to write to this and sub folders. </p>

<p>Many times, this is the only advice you'll be able to find that is Windows centric, and indeed it is very important. <br>
Messages are conflicting, however.</p>

<p>There are various users that could require access to this folder, depending on your setup. <br>
It used to be the case that people would grant access to the <code>NETWORK_SERVICE</code> user. This is outdated advice and while it may help, it's not the best security wise. <br>
Generally these days I would advocate using the App pool user for the site in question. <br>
If your Application pool for the site is set to the default <code>ApplicationIdentity</code>, then you would want to grant write access to the <strong>wp-content</strong> folder to the user: <br>
<code>IIS APPPOOL/YourAppPoolName</code> - where <strong>YourAppPoolName</strong> is the name of the website in IIS.</p>

<p>Other advice states that granting write access to the <code>IIS_USRS</code> group will help you - indeed, it might. This group is supposed to house the application pools, but it's overkill to grant access to all your IIS users if you have multiple sites.</p>

<p>Another account to try is the <code>IUSR</code> account, which is the anonymous IIS user. Indeed, in many cases you'll find that PHP is running as this user and thus it would make sense that it should have access to folders it wants to write. <br>
In my case, only the Application pool user is necessary, but your mileage may vary.</p>

<p>While this is always the first place to look, it's not always the solution for Wordpress plugin update issues. A good test is to <em>temporarily</em> enable full control over the <strong>wp-content</strong> folder for 'Everyone'. <br>
<strong>Please note that I am not in any way advising you do this permanently!</strong> <br>
The idea is that if you enable full control for everyone and still have a problem, it's likely not permissions causing your issue. </p>

<h2 id="procmonisyourfriend">Procmon is your friend...</h2>

<p>As a Wordpress user on Windows, friends are few and far between! (It's ok, I'll be your friend too). <br>
<strong>Procmon</strong> is a lovely piece of software that gives an incredible amount of realtime information and will allow you to get an idea of what's happening and to which files, when Wordpress is attempting an auto update or plugin update. <br>
<a href="https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx">Procmon can be downloaded directly from Microsoft.</a></p>

<p>It can be a little overwhelming, but using filters you can drill down to see which files are being accessed, and by whom. <br>
A good starting point is to add a filter for the <strong>.maintenence</strong> file in the root of your Wordpress installation. This file is added temporarily by Wordpress when it's attempting an auto update, and catching it in Procmon will help you to see what user Wordpress is using to write the file.</p>

<h2 id="thetemporaryuploadfolder">The temporary upload folder</h2>

<p>When PHP is uploading files from forms and such, and indeed when Wordpress is downloading update packages, it tends to store them temporarily in a folder while they're being transferred. By default in many Windows PHP installations, this folder is <strong>C:\Windows\Temp</strong>. <br>
Obviously this is a standard temporary folder and is shared with countless other processes.</p>

<p>In the first case, this folder might not be fully writable by PHP - but it makes sense to change the folder completely, just to segregate these operations from the rest of your OS.</p>

<p>In the <strong>php.ini</strong> file (If you've used the Windows Platform installer you can access this via the PHP Manager in IIS, otherwise you'll usually find it in <strong>C:\Program Files (x86)\php</strong> or similar.) there's a setting that you can change to whatever folder you like: <br>
<code>upload_tmp_dir = "C:\YourNewPHPTMPFolder"</code> <br>
Be sure to give writable permissions to PHP on this folder. Again, check what user PHP is running as!</p>

<h2 id="disabledfunctions">Disabled functions</h2>

<p>Another thing that can really trip you up, is spending all your time looking at file permissions without realising that PHP may not even have the <em>ability</em> to copy files from one place to another!</p>

<p>Once again in the <strong>php.ini</strong> file you may find a setting for <code>disable_functions</code>. Newer versions of the Web Platform Installer are able to lock down PHP pretty tightly and disable a whole bunch of functions out of the box, including some file operations that are used by Wordpress when updating plugins. <br>
Remove the following functions from your configuration to re-enable this functionality: <br>
<code>move_uploaded_file</code>
<code>chdir</code>
<code>mkdir</code>
<code>rmdir</code>
<code>rename</code></p>

<h2 id="wincache">WinCache</h2>

<p>WinCache is a popular caching module for PHP. Some versions of the module have been known to cause problems with Wordpress automatic plugin updates on IIS. There's an article about this here: <a href="http://ruslany.net/2011/04/wincache-and-wordpress-plugin-upgrade-problem/">http://ruslany.net/2011/04/wincache-and-wordpress-plugin-upgrade-problem/</a> <br>
Essentially the advice is to update the version of WinCache, but you could simply try disabling it to see if it is indeed the cause of your issue.</p>

<h2 id="ymmv">YMMV!</h2>

<p>These are the main issues <em>I've</em> found when attempting to solve the file permissions problems that plague many Windows IIS Wordpress installations. There may well be more, and I'd be very interested to hear them!</p>]]></content:encoded></item><item><title><![CDATA[Better explosions with Phaser’s particle emitter]]></title><description><![CDATA[<p>So I've been dabbling for a while in HTML5 game development, specifically using the <a href="http://phaser.io/">Phaser framework</a>. I've been documenting my progress offline for a few weeks and I'd like to post this online at some point...</p>

<p>For now though, I wanted to write a post about using Phaser’s particle</p>]]></description><link>https://garystanton.co.uk/better-explosions-with-phasers-particle-emitter/</link><guid isPermaLink="false">3512e8bd-1cb6-471f-817b-2111e3b8df6a</guid><category><![CDATA[Game Development]]></category><category><![CDATA[Javascript]]></category><category><![CDATA[Phaser]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Sun, 31 Jan 2016 17:12:00 GMT</pubDate><content:encoded><![CDATA[<p>So I've been dabbling for a while in HTML5 game development, specifically using the <a href="http://phaser.io/">Phaser framework</a>. I've been documenting my progress offline for a few weeks and I'd like to post this online at some point...</p>

<p>For now though, I wanted to write a post about using Phaser’s particle emitter to create an explosion effect that I think’s worked out really well. </p>

<p>The effect combines a single explosion animation, with a particle emitter to make multiple semi-random explosions which really beefs up the effect.</p>

<p>The graphics I’ve been using for B-Type came from GameDevMarket and along with the space shooter pack I purchased came a simple explosion animation that looks like this.</p>

<p><img src="https://garystanton.co.uk/content/images/2016/01/phaser-basic-explosion-1.gif" alt="Phaser standard explosion animation"></p>

<p>It’s nice enough, but doesn’t really have the impact I was hoping for.</p>

<p>My idea was to fire off several of these explosions, one after the other. I could probably do this by creating a group, adding the explosion animation and using the timer to spawn new instances of the explosion sprite in quick succession with a bit of randomising logic to place them around the collision area... </p>

<h3 id="butwaitisntthatbasicallywhatparticlesare">but wait, isn’t that basically what particles are?</h3>

<p>There’s a comprehensive particle system shipping with Phaser, and an even more complex one available as a plugin, so I thought this should be an easy challenge. <br>
Unfortunately, I found it difficult to get any information about using animations as the individual particles.  I’d have thought that I could simply add an animation to the particle emitter and have it play as particles are spawned – however, Phaser wasn’t having any of that! <br>
Looking around the forums I found that I could loop through the particles, adding an animation to each, but that didn’t seem to work very well either, <br>
What I landed on was creating a custom particle class, adding and playing the animation on the onEmit function. </p>

<pre><code class="language-javascript">explosionParticle = function(game, x, y, key, frame) {  
    Phaser.Particle.call(this, game, x, y, key, frame);
}

explosionParticle.prototype = Object.create(Phaser.Particle.prototype);  
explosionParticle.prototype.constructor = explosionParticle;  
explosionParticle.prototype.onEmit = function() {  
    this.animations.add('explosion', Phaser.Animation.generateFrameNames("explosion_",  1, 11, ".png", 2));
    this.animations.play('explosion', 20, false, true);
}

//  Player explosion
playExplosionAdvanced = function(x, y) {  
    emitter     = game.add.emitter(x, y, 6);
    emitter.particleClass = explosionParticle;
    emitter.makeParticles('explosion');
    emitter.width = 20;
    emitter.height = 20;
    emitter.minParticleScale = 0.5;
    emitter.maxParticleScale = 3;
    emitter.minParticleSpeed.set(0, 0);
    emitter.maxParticleSpeed.set(0, 0);
    emitter.gravity = 0;
    emitter.start(false, 2000, 50, 6);        
}
</code></pre>

<p>The emitter creates six explosion animations using a random scale and position, within very tight parameters. The emitter.start function is set to output the explosions every 50ms. <br>
I’m sure you’ll agree, the result looks much better!</p>

<p><img src="https://garystanton.co.uk/content/images/2016/01/phaser-particle-explosion-1.gif" alt="Phaser particle explosion animation"></p>

<p>You can see this technique in action on the <a href="https://garystanton.co.uk/code/demos/particleExplosions">demo page</a>.</p>]]></content:encoded></item><item><title><![CDATA[Running Ghost on Windows and IIS.]]></title><description><![CDATA[<h2 id="ijustcouldntleaveitalone">I just couldn’t leave it alone...</h2>

<p>So only one day after setting up my blog on a cloud hosted Ghost instance, I’ve found myself trawling through blogs and documentation on a voyage of discovery – with the intent of hosting Ghost on my own NodeJS server.</p>

<h2 id="why">Why?!</h2>

<p>You may</p>]]></description><link>https://garystanton.co.uk/running-ghost-on-windows-and-iis/</link><guid isPermaLink="false">f0b82b0b-03ea-458f-8d13-380cd7d88cb7</guid><category><![CDATA[Ghost]]></category><category><![CDATA[NodeJS]]></category><category><![CDATA[iis]]></category><category><![CDATA[Tutorials]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Wed, 27 Jan 2016 01:25:18 GMT</pubDate><content:encoded><![CDATA[<h2 id="ijustcouldntleaveitalone">I just couldn’t leave it alone...</h2>

<p>So only one day after setting up my blog on a cloud hosted Ghost instance, I’ve found myself trawling through blogs and documentation on a voyage of discovery – with the intent of hosting Ghost on my own NodeJS server.</p>

<h2 id="why">Why?!</h2>

<p>You may want to just <a href="https://garystanton.co.uk/running-ghost-on-windows-and-iis/#tutorial">skip to the instructions</a>.</p>

<p>When I made the decision to go with Ghost, the thinking was that I didn’t want to get bogged down in the creation of a website or management of blog software... instead reasoning that the content I wanted to post should take the highest priority.</p>

<p>That thinking still stands, however I really wasn’t comfortable with the lack of overall control I had without hosting the system myself. <br>
In no particular order, here’s what was concerning me:</p>

<h3 id="urlmanagement">URL management</h3>

<p>Ghost Pro allowed me to use my own domain... that’s great, but I also want to host other things. </p>

<p>As I’m getting into game development, I’d need a place for the games I make. Many of my posts will contain code. Ghost handles this well, but I also need to post demos of said code. Those demos may be HTML5 and Javascript, they may be CFML, PHP, any number of other technologies as I progress... <br>
The only solution seemed to be to separate these concerns across various sub-domains. I’m not happy with this solution as conceptually, this is all one site. </p>

<p>Hosting Ghost myself, allows me to place the blog content under a subfolder, and allows other content to exist wherever I like.</p>

<h3 id="nossl">No SSL</h3>

<p>Wait, what? <em>Seriously?</em> <br>
Apparently I can use SSL if I host through CloudFlare, which I have no intention of doing. Otherwise I’m stuck with standard non-secure hosting. </p>

<h3 id="themedevelopment">Theme development</h3>

<p>I found I had no way of previewing changes I made to my theme as I have no local version of the Ghost software. <br>
Additionally, the workflow seems to be:</p>

<ul>
<li>Make a change</li>
<li>Save the file</li>
<li>Create a zip file of the entire theme</li>
<li>Upload it to Ghost</li>
<li>Refresh the browser</li>
<li>Repeat</li>
</ul>

<p>That’s <em>insane!</em> My usual workflow of <code>Alt-Tab, F5</code> is infuriating enough already... I really need to get some live reload functionality working, but I’ve run into problems with that on Windows. Apparently Grunt is the way forward there, but I've  yet to delve into that beyond build minification... I’ll get there eventually.</p>

<p>So if I host the software myself, I can at least save and refresh. </p>

<h3 id="nodejsbaby">Node JS, baby!</h3>

<p>Over the last few years I’ve found myself using Javascript more and more, out of sheer necessity. I’ve been planning to embrace this a little more and start dabbling with Node.js for server side development for some time. <br>
I’ve run Node locally for some basic Grunt build tasks, but I’ve not really advanced beyond that. Hosting Ghost necessitates running a Node.js instance on a live server, and getting my hands dirty a little. </p>

<p>My hope is that as I want to add bits and pieces to the site outside of Ghost, I will attempt to do that with Node first. </p>

<h3 id="butistilllovecfml">But I still love CFML...</h3>

<p>I do. It’s true. <br>
CFML made me a developer. <br>
Years of experience made me a pretty <em>good</em> one. <br>
Contracting and inheriting code made me confident enough to <em>make</em> that last statement... There’s nothing quite like inheriting god-awful code, to combat impostor syndrome!</p>

<p>So while I want to get out of my comfort zone and start developing for Node, I’d like to know that if I just need to get something done I can switch back to old faithful, by hosting Node alongside a Lucee instance.</p>

<h3 id="icantseethedatabase">I can’t see the database!</h3>

<p>Yeah. That just doesn’t sit well with me. Ghost apparently has a nice API in beta that will allow me to pull content out and do whatever I want with it, sure... but there’s nothing quite like delving into the database and bending the data to my will. </p>

<p>No. If there’s an option that allows me to access the DB, I’m taking it.</p>

<h2 id="anametutorialaandsotowork"><a name="tutorial"></a>And so, to work!</h2>

<p>With the decision made, it’s time to get down to it. <br>
Installing Node is straight forward. The homepage of <a href="https://nodejs.org">https://nodejs.org</a> points directly to the download. We want the LTS version, since that’s what Ghost is supporting.</p>

<h3 id="iisnode">IISNode</h3>

<p>I want to run Node through IIS. Partially because I want to be able to use other technologies on the same site and partially because it’s what I’m comfortable with. I also don’t fancy opening up more ports on my server.</p>

<p><strong>IISNode</strong> seems to be what I’m looking for here: <a href="https://github.com/tjanczuk/iisnode">https://github.com/tjanczuk/iisnode</a> <br>
Setup is a straight forward installer and running a batch file adds a bunch of samples on the default website. <br>
Initially, these samples don’t work and I receive the following error:  </p>

<blockquote>
  <p>The iisnode module is unable to start the node.exe process. Make sure the node.exe executable is available at the location specified in the system.webServer/iisnode/@nodeProcessCommandLine element of web.config. By default node.exe is expected in one of the directories listed in the PATH environment variable.</p>
</blockquote>

<p>A quick Google shows I need to restart the WAS service, thus: <br>
<code>net stop was /y &amp; net start w3svc</code></p>

<p>I’m now able to see the hello world sample. That was fairly painless... hurrah!</p>

<h3 id="installingghost">Installing Ghost</h3>

<p>Again, this is fairly straight forward. Download the latest version of Ghost, <a href="https://ghost.org/download/">https://ghost.org/download/</a> &amp; unzip the contents to a folder under the webroot. <br>
Open a command prompt, navigate to the folder containing the Ghost installation and run the following command: <br>
<code>npm install –-production</code></p>

<h3 id="updatingtheconfig">Updating the config.</h3>

<p>I now have a version of Ghost installed, but before I start it I need to mess with some config settings. <br>
In the root of the Ghost setup is a file, config.example.js. If I run Ghost now, it’ll copy that over to a new file, config.js. I may as well do this myself.</p>

<p>In the <code>config.js</code> file there are a few settings we need to change.</p>

<p><strong>url:</strong> Set the URL of your blog. <br>
<strong>email:</strong> In order to send password reset emails, we need to tell Ghost about our email setup. <br>
Detailed instructions are here: <a href="http://support.ghost.org/mail">http://support.ghost.org/mail</a> <br>
<strong>server:</strong> Since we’re using IIS, we need to tell Ghost to let IIS decide the port. <br>
<code>port: process.env.PORT</code></p>

<h3 id="updatewebconfig">Update web.config</h3>

<p>We need to tell IIS to forward requests to node. In the root of the Ghost installation, add this to the web.config under: <br>
<code>&lt;configuration&gt;&lt;system.webServer&gt;</code></p>

<pre><code class="language-markup">&lt;handlers&gt;  
    &lt;add name="iisnode" path="index.js" verb="*" modules="iisnode" /&gt;
&lt;/handlers&gt;  
</code></pre>

<p>We now want to route all traffic through the Ghost node app, whilst allowing other javascript to be executed client side, so we can use the rewrite module:  </p>

<pre><code class="language-markup">&lt;rewrite&gt;  
    &lt;rules&gt;
        &lt;rule name="Ghost"&gt;
            &lt;match url="/*" /&gt;
            &lt;conditions&gt;
                &lt;add input="{PATH_INFO}" pattern=".+\.js\/debug\/?" negate="true" /&gt;
            &lt;/conditions&gt;
            &lt;action type="Rewrite" url="index.js" /&gt;
        &lt;/rule&gt;
    &lt;/rules&gt;
&lt;/rewrite&gt;  
</code></pre>

<p>Finally, we want Ghost to handle any 404 responses for missing URLs - by default IIS will be handling them.  </p>

<pre><code class="language-markup">&lt;httpErrors existingResponse="PassThrough" /&gt;  
</code></pre>

<p>Thanks to Lubomir Kamensky for the tip.</p>

<h3 id="settingupthedatabase">Setting up the database</h3>

<p>I notice the installation has created an SQLite instance for my data. I’m much happier with MySQL or MSSQL, and after a bit of Googling it seems I’m not alone.</p>

<p>I create a new database my MySQL instance, grant access to a new user and add the following details to the config.js file:  </p>

<pre><code class="language-javascript">    client: 'mysql',
    connection: {
        host: 'localhost',
        user: 'YourUsername',
        password: 'YourPassword',
        database: 'YourDBName',
        charset: 'utf8'
    },
</code></pre>

<h3 id="runningghost">Running Ghost</h3>

<p>I read a lot of articles during the course of setting this up. Most of the ‘Ghost on Windows’ tutorials include a manual starting of the app, using <code>Npm start –production</code>.</p>

<p>What’s not been made clear, but actually makes sense now that I think about it, is that this isn’t required when using IISNode. The module will automatically start the Node app if a request is made to the URL. <br>
Thus, you can now visit your blog URL and you should see the default Ghost blog homepage!</p>

<p>Hurrah! You now have a working Ghost installation on IIS. <br>
Hopefully.</p>

<h3 id="anoteonenvironments">A note on environments</h3>

<p>Node has an understanding of different environments out of the box, using the <code>NODE_ENV</code> setting. You may have noticed in your config.js, there were settings for both development and production environments. </p>

<p>Ghost runs in development by default, but obviously on a production server you’ll want to change this. <br>
Since IISNode is starting the app for us, we can’t simply set the environment in the command line, but we can change the default in the <strong>/core/index.js</strong> file, thus: <br>
<code>process.env.NODE_ENV = process.env.NODE_ENV || 'production';</code>  </p>

<p>I’m not overly happy with this, for two reasons. Firstly I don’t feel right editing anything in the core. Presumably updates will overwrite this setting, so it’s something to remember whenever you update Ghost. <br>
Secondly, this messes with my version control. I don’t want to have to have a different setting on dev than in production and usually create some form of conditional sever interrogation to avoid this.</p>

<p>For now however, I can’t seem to find another way of doing this – short of having the .js file auto updated by something else server-side.</p>

<h3 id="updateusinghttps">Update: Using HTTPS</h3>

<p>When deploying on my production server, I found that the site was returning an infinite redirect. <br>
It turns out that if you try to use an https url, you need to add a header to the request. I found a github fork of Ghost specifically for Azure, and this had the answer:</p>

<p>Create a file in your Ghost root called <strong>iisnode.yml</strong>, and add the following:  </p>

<pre><code class="language-javascript">node_env: production  
loggingEnabled: true  
logDirectory: iisnode  
enableXFF: true  
nodeProcessCommandLine: "%programfiles%\nodejs\node.exe"  
</code></pre>

<p>You may need to update the last line with your location of the Node executable. <br>
Not only does this work, but it also overrides this line in <strong>web.config</strong>:  </p>

<pre><code class="language-markup">&lt;iisnode node_env="%node_env%" loggingEnabled="true" nodeProcessCommandLine="&amp;quot;%programfiles%\nodejs\node.exe&amp;quot;" /&gt;  
</code></pre>

<p>And that’s about it! It was quite a hassle to get everything working the first time around, but to deploy on production I simply followed my own instructions and by and large it was all pretty smooth.</p>

<p>Now as I want to add other areas to the site, I’ll have the choice of Ghost static pages, or integrating CFML, or whatever I like really. <br>
Sky’s the limit!</p>]]></content:encoded></item><item><title><![CDATA[Another well intentioned January starting point...]]></title><description><![CDATA[<h2 id="ahhjanuary">Ahh January...</h2>

<p>It's that wonderful time of year that's just pregnant with promise. The time of new beginnings, new undertakings. Change for the better. It's no wonder that <a href="http://http://www.which.co.uk/news/2011/01/brits-waste-37m-on-unused-gym-memberships--242448/">new gym membership subscriptions soar at this time of year</a>.</p>

<p>The sad truth is of course, that all our good intentions and</p>]]></description><link>https://garystanton.co.uk/and-so-it-begins/</link><guid isPermaLink="false">6da0eef2-626e-4698-b1c0-a9d9ddd6aee6</guid><category><![CDATA[General]]></category><dc:creator><![CDATA[Gary Stanton]]></dc:creator><pubDate>Sat, 23 Jan 2016 01:17:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="ahhjanuary">Ahh January...</h2>

<p>It's that wonderful time of year that's just pregnant with promise. The time of new beginnings, new undertakings. Change for the better. It's no wonder that <a href="http://http://www.which.co.uk/news/2011/01/brits-waste-37m-on-unused-gym-memberships--242448/">new gym membership subscriptions soar at this time of year</a>.</p>

<p>The sad truth is of course, that all our good intentions and indeed our enthusiasm for them, generally peters out by about mid-February.</p>

<p><strong>Not this time though!</strong> 
Let us live in this delusion a little while longer, as I explain that in 2016 I've decided to create my own little space on the web, in the guise of the delightful blog you currently find yourself reading. <br>
(Really, how did you get here exactly?!)</p>

<h2 id="allchangeplease">All change please.</h2>

<p>For years I've had a blog over at <a href="http://www.simianenterprises.co.uk">Simian Enterprises</a> that housed my various code shenanigans, and occasional rants. <br>
As with many blogs, the frequency of updates became less and less, as I became busier and busier. It was always my intention to post little updates detailing what I'd been working on with samples of any code I thought worth sharing... but who has the time?</p>

<p>Over the last couple of months, I've been dabbling a bit in HTML5 game development. I've been documenting my progress offline, with the intention of posting online at some point. Given that this has little to do with my application development work, it seemed that the Simian Enterprises blog wasn't the right place for this - and so I decided I would retire the old blog and transfer the content over to my own personal site at <a href="http://blog.garystanton.co.uk">garystanton.co.uk</a>.</p>

<p>Posting on a specifically personal site rather than on my company website, should allow me to write more diverse content. <br>
<strong>I code, lots.</strong> But I do other things too, and I also have strong opinions no-one really wants to hear. What better place for them than this little corner of the interwebz?
Plus I can swear here too. <br>
<em>Fiddlesticks!</em> <br>
See?</p>

<h2 id="standclearoftheplatform">Stand clear of the platform.</h2>

<p>I've had ideas about this blog floating around in my head for a couple of years now. As with a lot of developers, I spend so much time and effort working on projects for clients that I very rarely find the time to work on my <em>own</em> site, and so nothing ever really happened. <br>
I realised that I was never going to sit down and spend the time to hand craft the perfect website and so decided to just <em>get it done</em> - and to that end I'm using a cloud hosted blogging solution, <a href="https://ghost.org/">Ghost</a>.</p>

<p>This feels odd to me. I like to build things from scratch. It's what I do. I like to build them in CFML primarily. I like to have full control over the minutiae of every byte... I'm actually writing some basic blogging software for a client at the moment! <br>
Handing over the reigns to another system feels... weird.</p>

<p>I also realised that I probably wasn't going to find the time to push pixels around in Photoshop and come up with a lovely, expressive design that wowed viewers whilst alluding to the nuances of my character... etc. <br>
So for now I've simply downloaded a theme <del>that appealed to me</del> - <del>no longer appeals to me</del> - Do you like the new theme? ;) <br>
I'm not sure how I feel about Ghost yet. Again, I wasted lots of time wading through the various blogging platform options and there's too many to really know if I've made the right choice. I'm fully prepared for the possibility that I will migrate to another platform, or eventually roll my own - and you, dear reader, should be prepared for this eventuality also. If you're reading this in 2016, the blog may well look completely different the next time you visit.</p>

<p>I'm also not sure whether Ghost can handle importing my old posts from the Wordpress powered Simian Enterprises blog. I don't feel a blog is right for that site any longer, but I'd still like the content to be available here.</p>

<p>We shall see what happens.</p>]]></content:encoded></item></channel></rss>