Jacob Pariseau

Internet Marketing Solutions

New Project: Game of Sins

I’ve spent the last month working on a new project to get a feel for Angular.js and to come up with a fun game to play on weekends. I’ve never been terribly interested in bars or clubs — they’re just loud rooms where the worst people in town can get together. Instead, I invite friends over to watch movies and play drinking games. That’s where Sins comes in.

Arguably the most popular drinking card game is King’s Cup, also known as Kings, Ring of Fire or Sociables. It goes by many names, and has many variants, but the basis is the same: each turn is a little minigame decided at random by the draw of a card. With a standard deck of playing cards this gives us 13 minigames played four times each. Some common minigames include Categories, where the players go around in a circle naming the first object that fits the criteria, or Rhyme Time, where the players try to rhyme a word picked by the cardholder. The first person to fail or take too long loses, and must take a drink. Then on to the next player.

Other cards are simple drinking rules. Three to me, take a drink; Five to guys, all men take a drink; Eight pick a mate, pick someone and both drink — depending on the variant the numbers and details change slightly but they are always in the game somewhere. It’s quite common to have different rules for every combination of people you play with, as you get input and ideas from everyone who’s ever played a different version. And with all these variants, why not clean it up a bit?

With Sins, I started with the base set of Kings rules and split it into two categories: event cards that have winners and losers, and action cards that require the players to perform certain actions (eg, take a drink). Action cards can be split further into single action cards and persistent action cards, which I called Status cards. This gives me two decks. On each player’s turn, they draw from the white deck which contains a minigame, and based on the outcome of that, other players will draw an action or status card from the black deck.

The final change I made was to add Trap cards to the white deck, which simply go in the player’s hand and can be activated as soon as their condition is met. One might say “Activate when a player sits down” and allows you to force that person to draw from the black deck.

“Draw from the black deck” is verbose, so I came up with a paradigm to simplify it. The world is ruled by a strict deity who punishes the slightest misbehaviour. Failing the minigames, or performing the actions on the trap cards is a sin, so the god smites you, and you must reap your punishment. A card will say ‘Smite a player’ and that player must draw a black card.

If this game was played with tangible cards, the setup would be white and black decks side by side in the center of the table. The players would be surrounding it with their trap cards in hand and status cards on the table in front of them. For the app version, a bit of trickery happens trying to represent this on a screen. A phone is roughly the size of a deck of cards, so in mobile portrait view I can only show one deck at a time. I used a Material Design Floating Action Button to hide some options that allow the player to switch visible decks (swiping left/right works too), to show their hand (swiping up works too), and to switch to another player’s turn. On wider devices, both decks are visible side by side and the hand/table views are shown below.

game2

game1

The biggest impediment of this system is that players don’t always have constant access to their hand to see what trap cards they have. It didn’t pose a big threat while playing the game; each player could just remember which cards they had and discard the ones they’ve played when it gets back to their turn, but I’m not terribly happy with that solution.

One idea I had to get around it is to enable online play. People could create a private named room and other players could join. Each device could host as many players as it wanted, so a party of 8 people could use anywhere between 1 and 8 phones/tablets/laptops to play the game. As the turns go around the table, only the device linked to the correct player could make the turn happen. It shouldn’t take more than a day or two to code, but makes the overhead on the app significantly higher and doesn’t solve any problems that playing with real cards couldn’t solve. It might happen, depending on interest in the idea.

Another feature on the roadmap is inserting player wildcards into my card definitions. Instead of cards that say ‘Pick another player’ it would randomly select a player and say “You and Jon take a drink”. This would also open up status cards that increase the likelihood of being a Smite target — something that physical cards can’t do.

I already define the cards with themes as I create them. When the game is started, I’m going to add an advanced options menu that allows the players to choose what card themes they want to get. Some players might like speed rounds of naming nouns that start with F, while other groups of people would be more interested in historical figures or baseball players. This would also allow individual players to opt out of the drinking cards, opening the audience up to more casual players.

As a programmer, I’m very interested in Test Driven Development but I’ve always found it to have a high barrier to entry. With either this project or my next one, I’m going to delve into it and learn how to structure apps along that paradigm. But more importantly, my chief impediment with any of my projects is not programming ability, but marketing. The reason nobody uses my products is not because they aren’t good, but because nobody has ever heard of them, and I don’t know how to expand my reach. Once I establish an audience, I will have feedback which can be funneled back to the development side and accelerate my learning and programming speed.

Any comments or advice can be fielded to my Twitter account. If you play the game, definitely let me know how it goes and where I can improve.

You can play Sins here and view the source code on my GitHub page.

New Theme: Iris

I started on a new theme last night based on the old antiquated Pixel theme that was super popular after it came out eight years ago. This will be a free theme so I will be posting the link here in a few days when it is mostly complete.

iris1

iris2

iris3

Plugin: Reddit Featured

Reddit Featured is a WordPress plugin that allows you to feature any Reddit thread on your blog or website. Use it to embed a customizable widget that displays the original post and top comments of any Reddit post. Whether you want off-site commenting or just to share a post you’re discussing, it’s just one line of code away. In your `single` or `content-single` files, embed the widget with this line:

do_action('display_featured_post', $post->ID);

Then, in your post, add a Custom Field called “Reddit Link” with the path to the post you’d like to embed

r/{subreddit}/comments/{123ab4}

redditlink

The plugin does not come with any styling by default, but you can easily add it with your own CSS. An example of this is below:

unstyled


/** REDDIT FEATURED **/
@primary: #F44336; //Material design RED
@secondary: #D32F2F; //Material design DARK RED
@shadow: #000066;
#reddit {
margin: 0 -16px; // Wider to touch screen edges
.r-header {
background: @primary;
}
.r-op {
color: white;
.r-body {
background: @primary;
border-bottom: 1px solid fadeout(@shadow, 80%); //Transparent blue shadow
}
}
.r-comment {
background: @secondary;
color:white;
border-bottom: 1px solid fadeout(@shadow, 90%);
}
.r-meta {
color: fadeout(white, 10%); //Transparent white
}
}

If you don’t like or use LESS, you can convert it here

You can get the plugin at its Github Page.

Clone it into your wp-content/plugins/ folder and activate it in your admin page.

Devlog: Reddit Widget

I’m building a widget that allows me to link my blog posts to threads on Reddit. When it’s done, I should be able to view the top two or three comments and click through to the original post. At the moment I’m building this as an extension of my current theme, but I’ll cut it out and turn it into a plugin later. The first thing it does is make an API call to Reddit with the given URL. The docs give this nice little call to use:

GET [/r/subreddit]/comments/article

After a bit of frustration, I discovered it is patently incorrect.

GET [/r/subreddit]/comments/article/foo.json is the correct call, where foo can be any string.

The API provides easy access to the score of each post with three fields. `ups` and `score` provide the same value while `downs` returns 0 all the time. None of these respond to my test upvotes due to some anti-spam protections the Reddit team put in. While initially I planned on leaving it for live testing, I can set the URL to grab from one of Reddit’s front page posts with lots of activity. That will give me the user testing I need to verify it’s functional. The share on Reddit button already polls for existing links to prevent reposts. If I can tap into that system, I’ll be able to pop my plugin up the moment someone shares one of my posts.

For the plugin base, I’m using the plugin template provided by Devin Vinson. It has a lot of functionality I was going to have to recreate, and it has community support to back it up. Overall, it should be a good base to work from.

I don’t want my styling to be included with the plugin, so I’ll only include the base CSS required to format it. Colour is added in my theme file, like below


/** REDDIT **/
@primary: #F44336; //Material design RED
@secondary: #D32F2F; //Material design DARK RED
@shadow: #000066;
#reddit {
margin: 0 -16px; // Wider to touch screen edges
.r-header {
background: @primary;
}
.r-op {
color: white;
.r-body {
background: @primary;
border-bottom: 1px solid fadeout(@shadow, 80%); //Transparent blue shadow
}
}
.r-comment {
background: @secondary;
color:white;
border-bottom: 1px solid fadeout(@shadow, 90%);
}
.r-meta {
color: fadeout(white, 10%); //Transparent white
}
}

If you don’t like or use LESS, you can convert it here

Project Post Mortem – Masquerade

Masquerade wasn’t so much a project as it was a timesink. What it was, and what it was meant to be, changed constantly. I started with a vague idea and moved toward a vague result. From a dating site, to an anonymous social network, to an ephemeral reddit style message board; I truly understand this quote now.

“Startups don’t starve; they drown.” -Shawn Carolan

The Beginning

Since I was never close to what I felt the finished project should be at the time I didn’t spend much time showing the product to customers. Most of this piece will be about the technical side of development. I started with a LAMP stack on shared hosting. I wanted a slick, responsive UI, so I brought in AJAX to remove the need to refresh the page. This had the unfortunate consequence of forcing me to code everything twice: Once in PHP server side for the initial load, and once in Javascript for the changes returned by the AJAX call.

Feature: Location Batching

When people were on the site I wanted to group them into location batches. Each user was assigned a District which was the nearest city with more than 10,000 people, and a village which was the nearest city with more than 1,000 people. They would be labeled with their village (John McClane, SmallTown) but were only able to interact with people from their District. This meant that everyone was somewhat local, but even people in small rural areas would have a wide audience to meet.

For this to work I needed a database. Geonames.org had a nice one available in CSV format, so I looked up the schema and worked on importing it with PHPMyAdmin, but it wouldn’t work. Turns out my PHP upload settings were too low, so I fixed that and it worked. I did some MYSQL magic to drop the unnecessary columns and map every city in my >1 Kilopeople table to the nearest one in my >10 Kilopeople table, which let me drop the latter table. Now each user, on logging in, would scan their current location and and assign them to the nearest village, and therefore district, and everyone was batched properly. FamFamFam-Flags was a Github hosted database of silk flag icons named XY.png, which matched perfectly to the country codes that were already in my database, so one line of code and I had nice little country icons next to the cities.

At this point I shared the site to some friends of mine I’d met online around the world, and they all confirmed that the correct cities and flags were popping up for them. When a user entered a new district, it was added to their profile and they could then interact with people from both districts. A good incentive for people who traveled a lot, I figured.

Feature: Image Uploads + Cropping

I wanted the users to have profile pictures that were all the same size. I wrote a quick upload script that uploaded an image to a random ID and saved that to the user, but I was storing very large images and I wanted to crop them down. I liked Android’s image editor’s crop feature so I built one like that with HTML5. The user could select an image from their computer, which would be resized and letterboxed to fit on-screen. Step one was to click the crop button which rendered a draggable and resizeable box that they could place over the image. When they accepted, it took the region they selected and cropped the full size source image, then uploaded. The result was scaled and proportioned profile pictures in as high a resolution as possible.

However, when I tried it on my phone, half the images were sideways. Turns out there are several different standards for handling landscape images, one of which was portrait photos with an EXIF flag. I accounted for some of the cases, but after reading a blog post somewhere that showed many major image sites (Facebook, Google) didn’t solve every case, I put it off until later. Otherwise, the uploads worked properly on my phone too.

Feature: Tinder Style Matching

Each user would be represented by a card that other users could swipe left and right on. Mutual matches created a connection, and you would be able to communicate with your connections. For some reason I was avoiding jQuery, so I used Velocity.js to animate the swipe flyaway and wrote a quick mouse drag script to move the cards. Worked great on my laptop, not so great on my phone. Luckily someone online had written a script that mapped TouchEvents to MouseEvents and that made it work on mobile. Still it was laggy though, due to a 300ms delay on a click event while it waited to see if it was going to be a double click or not. FastClick.js solved this and it was working great on mobile and desktop.

Theme Change: Deck of Cards

I styled the whole app after a deck of standard playing cards. The Tinder-style page was called the Deck, and you would swipe left and right through every person’s Card. Clever, I know. In the profile settings, I could apply this theme to use card suits to describe a person’s interests on a per-gender basis. For Male and Female separately you got to specify if you were interested in dating (represented by Hearts), a long term relationship (that might result in marriage and Diamonds), just normal friendship (hanging out at ClubsSpades? Oh well, only suit left).

Feature: Anonymous Threaded Messaging

Rather than be a Tinder clone and just have users message one another, I wanted to do something different. As everyone knows, being different from the most popular app in the genre is a guaranteed formula for success. I would have an anonymous message board, where you only see threads made by people you’ve matched with. This required that connections be made silently, so you could swipe right on anyone you wanted and you’d never know if they swiped back. The idea here is to connect people with others that they find interesting enough to talk to, out of a total pool of people they’ve already thought were attractive. I pitched this to several friends and they were all confused, but I assured them it was a good idea.

The app Secret was being sunset, but I liked the way it handled anonymity. In Secret, each user was represented by a random coloured avatar. They would retain that avatar for the duration of the thread, but on any other thread they would be assigned a new one. I emailed the founder, David Byttow, and asked permission to use that mechanic, to which he replied something along the lines of “Thank you for asking, but everyone else already kinda copied it so go ahead.”

I found an icon font online with favourable licensing and a good selection of icons, mapped each one to an ID and wrote my algorithm for assigning avatars. When a new post was created it would first check to see if the user had posted. If not, it would randomly shuffle the avatars and go through one by one until it found one that had not been used, and then do the same for colours. If all the avatars were participating in the thread, it would look or unique avatar-colour combinations. If all of those were taken, the user would not be allowed to post. This would only happen if there were more than 1,000 people participating, so I considered it an edge case that didn’t need to be handled yet.

So now I had a message board where people could view threads posted by any of their connections and comment on them anonymously with randomly assigned avatars. While the user would know they swiped right on anyone who started a thread, they would have no validation for the commenters. Did this matter? I don’t know, but I made non-connections’ avatars 50% whitewashed. When a new connection was made, it would log the time it happened and only show posts from connections that happened afterward. This stopped users from being able to swipe on someone and check the message board for new posts, which would compromise the anonymity.

The Switch to Node

PHP is great and all (allegedly) but I was really getting frustrated with having to maintain my AJAX calls to keep the interface updated without refreshes while also rendering server-side in PHP. Could I have made the AJAX requests on page load and then only loaded with Javascript? Probably. But in a surprise twist of events, I did not do that.

Node.js has this crazy model where server stuff is handled on the server, client stuff is handled on the client, and the client just requests JSON data and renders everything on its own. This makes sense to me. Meteor.js is built on top of node and handles all the database client reactivity like magic. It uses a template system called Blaze that lets me just type {{> header}} to insert my header template in. Templates are declared like <template name=”header”> with HTML inside. Simple simple simple, I had to try it out.

The quickest way to get started in Meteor was with Nitrous.io so I hooked up my IDE and rewrote the whole site in a week. It was faster, better, and a thousand times more clean. My HTML5 image cropper was a bit hacky looking when I moved it over, but there was very little code to change. I exported my MySQL database and tried to import it into MongoDB, but that broke the whole site. The tiny bit of RAM I was allotted by Nitrous.io was used up. That fact combined with them sunsetting the free package tier I was using led me to drop it for a local Node and Meteor install.

Feature: Anonymous Chat

Now that the users could talk on message boards, how would they get to know anyone personally? Clearly I needed a user to user chat. Clicking a connected user’s avatar would pop up a menu that had a Chat option. Once this was clicked it registered a new chatroom with a random name from a list of adjectives and nouns. This gave neat names like “Sunny Parkbench” and “Shady Meadow”, but some adjectives fit nouns better than others and I also got names like “Shady Alley”. Oh well — not a big deal.

I used a chat bubble system with white avatars and coloured bubbles that matched the avatar colour you had in the thread you clicked. You could be talking to the same person in several rooms simply because you clicked them in different threads, but I didn’t see that as a problem.

At the moment I was just creating little JSON documents for each message that included the sender, the recipient, and the name of the chatroom and adding them to my Messages collection. Due to Meteor’s reactive nature, the UI for both clients updated immediately to match the database change. Secure? No. But it was fast and I knew I could change it later without much hassle.

Feature: Liking posts

Of course, I needed a way for people to rate posts without commenting on them, so a simple like/heart/upvote feature was needed. I stored a list of user IDs in each post for everyone who liked it. I could show the heart count as the length of that array and easily check on page load if it should show up as hearted or not yet. On the user’s profile I added a list of the posts they’ve liked, the threads they’ve started, and the comments they’ve made. This is also the stage of the project where I have screenshots to back up my story.

likes3likes2likes1laptop

Feature: Question Topics

Most people are bad at coming up with things to say, so I decided I would help them out by cycling question topics. Every 6 hours a new one would pop up and an old one would disappear.

Removed Feature: Tinder Style Matching

What if a user was really interested in chatting with someone they saw on the message board, but weren’t matched with them? Their only recourse would be to go back to the connections page and swipe right on everyone, and hope that person was nearby and matched their gender preferences. That would defeat the whole purpose of the swipe system, so I axed it. People could meet other people based on interests, not appearance, I decided.

So what to do with the message board? I would group everyone by district, and they could speak in a public board available to anyone from that district. If you were registered with more than one district (by using the app while travelling) you could select from a dropdown and choose which one you wanted to view and post it.

Theme Change: Masquerade

Without the Tinder Deck, an anonymous app doesn’t have much of a dating element so I scrapped the Deck of Cards motif. I decided to go with a colourful Masquerade theme, replacing the generic avatars with designed masks. I switched to a black background with bright neon colours for the other users’ masks, while your own posts were solid coloured with white masks. And now we’re at the stage of the project where I have some screenshots!~

masquerade1

I had been using a free copy of Illustrator CS2 that was released a few years prior, but I found it irritating so I switched to InkScape for the icons. The Masquerade logo mask and banner image I did in Photoshop, which I have always been more comfortable in for vector images. This is something I need to get over though, as Photoshop is not designed for vectors.

Feature: Unlockable, Functional Masks

I didn’t draw very many masks. I think I did 30 in total, but they were split across 6 colours so it accommodated a high users/thread. I wanted to incorporate a sort of achievements or reward system for the users, so I let new users be allotted a random 5 masks from a base group of 10 animal masks. Each of their posts would use one of these 5 masks at random. Through certain actions, like reaching a comment or heart threshold, chatting with X amount of people or any other achievement idea I could come up with, they would be given new masks.

Most masks were cosmetic, but some were functional and allowed users to break character limits, enter new VIP message boards, post images as comments, and various other features I thought would be nice rewards to give frequent users.

I removed the old location identifiers and added a new “Request Invitation” section. If the user was in a certain district they would get an invitation card to access that message board. Invitations were also the method used to assign masks to users and one was given to each user on registration.

profile

Deploying to Cloud

Deploying a Meteor.js app isn’t terribly difficult, but it was the first time I had done it. I opted for Meteor’s own Galaxy hosting service, which they had just that day released their Developer tier. I could no longer use the local copy of MongoDB I had installed so I registered with Compose.io and was up and running live on the web in two days.

Feature: Tagged Posts

After having a Tags vs Folders debate with myself, I decided that keeping users restricted to boards I create was limiting. I refactored the system such that the post input could also be a search bar that filtered to any tags that were present in the post. Nobody could tag a post as a district if they didn’t have it registered on their profile, so there were still some places you were guaranteed to be dealing with locals. So, if a user entered #UniversityOfAlberta Where is the nearest #party and clicked search it would filter the feed to posts from the University of Alberta that were tagged with party. Users could also delete their district tag and make posts that anyone could see, however each post needed to have at least one tag.

This was clever, I thought, because it meant any user could start a board talking about any topic, which had never been done before. I will note that at this point I had spent exactly one day several years prior on Reddit and at no point did I realise I was basically making Reddit.

Feature: Phone Login

I have always found email authenticated logins to be a huge hassle and I decided I didn’t want to do that. So I did what any self-respecting mobile developer would do. I turned to SMS. Twilio has a fantastic API and I was able to send SMS verification codes to log in within the evening. I built this on top of the email-password system for desktop users, but mobile users didn’t even need to enter a password. Their account was tied to a phone and if they were using that phone, it logged them in as soon as they received the text message.

Feature: Profile Names

I took a good look around at the market and tried to count all the successful anonymous sites. There was ChatRoulette, but it was full of the kind of people I didn’t want to interact with. There was 4chan, but it was full of the kind of people I didn’t want to interact with. There was Yik Yak, but it was CTRL+V and also adding profiles and de-anonymizing itself. I wondered, if there are no anonymous apps that don’t become internet hate machines, why should I be trying to make another one?

So I added profile names. But with names, there was no purpose to the random avatars. I refactored them to be defaults for users without pictures, and allowed users to upload profile pictures. All of a sudden there was no need for the random colours either, so I let the users pick their own post colour in their profile. I seem to not have taken screenshots that far.

The Change to Pulse, and the Project Sunset

So now I wasn’t anonymous and no longer had masks representing all the users. I realized what I had was almost identical to Reddit, except that posts could belong to multiple subs at a time. Should I have used that knowledge to revert back to anonymity, release the app, and see how it fared in the wild? Almost definitely. I could have ignored the sentiment and released it as it was too. However, there was a hidden third option where I stayed away from the scary ‘interacting with customers’ element that came with the correct path and spent more time programming.

I wanted to take the ephemeral expiring post mechanic popularized by Snapchat and apply it to my public message board. I called it Pulse, and every new post started at 300 seconds. For every second the post was visible in a user’s window, it would decrement by 1. But this was all managed server-side, so while a post viewed by 1 person would last 300 seconds, if 5 people were looking at it it would disappear in 60 seconds.

When a user likes a post, it no longer loses its ‘life’, so the system treats it as not being viewed. Comments are nested infinitely, and every comment adds 60 seconds of life recursively to each parent, all the way up the chain to the original post.

Once the system was balanced, it would create a unique scenario where every post has an equal chance of success, regardless of who posted it. Poor quality posts die quickly, without anyone liking or commenting. Good posts, on the other hand, are kept alive by user interactions.

Around the start of July 2016, it had been almost two years of weekends and evenings working on the project. I got the idea for PokéAlert and decided to take a break to work on that. When it was completed and released a week later, I decided that this project was far too large, too vague, and too much wasted effort to continue. Sunk costs fallacy be damned — I wasn’t going to sink any more. I learned so much about Node, Git, Mongo, Meteor, Javascript, Material Design, and many more lessons about project architecture and design theory. My only recourse, after this project, is to ensure that I put the lessons I’ve learned to good use and manifest it into something truly valuable.

Project Post Mortem – PokeAlert

When Pokemon Go was released, it took the world by storm. Where once there were thugs and ruffians roaming the streets, flocks of pokemon trainers would scamper about into the endless hours of the morning. Rather than let them be, I decided to write a helper app that would allow them to log the locations of their catches and share them for others.

The most basic element required here was a map. I would provide a simple interface for searching, and for logging, and the server backend would process the results and output a map detailing the regions each pokemon was likely to be found.

The method of reporting I settled on was a simple pin drop at the user’s current location, but I allowed the user to place pins at other locations too. It was unlikely they were going to update the map live while they were still at the catch site, so some tolerances were needed.

At this point I extended my roadmap to allow for an app that would scan the user’s screenshots directory for new images. When one appeared, I would use an image recognition library (which thanks to the wonderful open source pokemon fan world, already existed) to automatically log the sighting at the user’s current location. This would mean that users could play the game normally, and when they wanted to report a pokemon they just needed to take a screenshot.

The Technology

For this project I used a MEAN stack website. I had dabbled in Node and MongoDB before in other projects, and I wanted to take the chance to learn. This was my first foray into Express.io and Angular, so there was definitely a sharp learning curve. This was also the first time I set up SSL, but using Let’s Encrypt it was much easier than I thought it was going to be.

I used an EC2 Instance running Ubuntu with Node and Forever.js to keep the site running. I had a MEAN stack installed locally on my laptop for development, and I kept all my code in a private git repository. When I wanted to push to the server, I simply pulled from github to the VPS and was good to go.

What Went Right

The choice to build this on a MEAN stack was definitely correct. Development was smooth and organized thanks to Git and with EC2 I had a hard time knowing if my refreshes were working because the site loaded so quickly.

Given that it was a product I was interested in using, motivation remained at a high the whole time. I was excited to commit every feature and to show off my finished work. The site was also very small and focused, which allowed me to learn MEAN and complete the site in 6 days. After spending months or years on unfinished projects before, this was a game changer. I used the Angular-material library for my interface and it was super easy to get a clean Material Design UI going. I will be using it again.

Shortly after I had determined the project was dead and decided to sunset it, I got a nice phone call from a guy looking to buy the domain. I suggested $50 and we had the money and domain transferred within an hour.

What Went Wrong

The biggest problem with PokeAlert? Research. I spent zero time looking at the market, at what people were asking for, and what already existed. I may have been one of the first to start on this project, but I was definitely not the first to finish. I started seeing blog posts raving about one tracker or another that were almost identical to what I had independently created. Some had more features, some had fewer, but they all had more users.

I released PokeAlert as a Minimum Viable Product with a basic logging feature. The screenshot based image recognition system was on my roadmap, but only if people were going to start using the app. In hindsight, I could have considered the success of all the other clones as validation of my product idea. Launching with image recognition capability could have given me the value-add I needed to beat out some of the competition.

My other impediment was not looking to understand the Pokemon Go system well enough. PokeVision tracked the actual spawn times from the real server and gave users guaranteed results. I didn’t know there were scheduled times pokemon would appear, but if I had enough users I could have derived that on my own.

Technically speaking, I first wrote the site for HTTP and then switched to HTTPS when it was required by the Geolocation API. It was difficult figuring out how to rewrite the server setup with express to allow for SSL support, and if I were doing it again I would go SSL from the start no matter what the project.

I survived by using doc references to piece bits of Angular together, but I should have taken more time to learn it from the ground up. I will definitely come back to Angular in future projects.

Summary

Pokealert was a mapping tool that allowed Pokemon Go players to map pokemon as they found them. Unfortunately for me, by the time I released there were hundreds of other sites that did the exact same thing.

The MEAN stack is great, but Angular is tricky if you’ve never used it before and it’s a good idea to run though a few tutorials before using it in a project.

I know now that significant amount of research is required before starting a project. Rather than say “I wish I could do X. I’ll make a site that does it” I should take the time to research what solutions are already on the market. I don’t need to wait to validate assumptions if the market shows strongly something is in demand. That’s when I need to take the other path – to provide a better product than the competition and undercut their market.

Why most small businesses have useless websites

Everyone else is doing it. This is the age of the World Wide Web — where everyone has a website and first impressions are everything. And in this world of Haves, being a Have-Not can keep your precious customers at bay. But websites are expensive; they cost money and time, and so what if your competition is doing it. Why would you want to be like them anyway?

To be honest, I don’t know how to answer that question. Do I start with the fact that companies with websites make more money than companies without websites, or the fact that most small businesses don’t ever unlock the potential behind their site. It’s true — look out the window and type in the names of the stores you see. The odds are good you’re going to find a lot of internet brochures for basal businesses. “We got ourselves a website! Now we have a web presence!” Yes, we’re very proud of you.

The truth is most small businesses are run by your regular everyday normal guys. That’s a good thing, since too much corporate culture makes me yearn for human contact. But while the shop down the street might make a mean pot of coffee, and the employees at the fab shop downtown have a hundred years in welding experience put together, that doesn’t mean they know anything about internet marketing, and it doesn’t mean that hiring someone to make them “a website” is going to improve their business.

Just having a website isn’t going to improve your business any more than just owning a stairmaster is going to tone your thighs. If you want results, you have to use it. So how do you use it?

Sales

The most common entry point for getting your ROI out of your website is sales. Whether you’re offering digital goods, shipping physical products, dispatching crews of workers, or providing a service, there is so much more to internet sales than dropping a phone number on your homepage and calling it quits. Take this moment to Google your local competitors. Odds are, that’s all they do.

What is the current workflow for your sales funnel? Think of how you can shrink it down and create new entry points closer and closer to the sale point. If a prospect walks through your door, your first goal is going to be narrowing down what they want and assisting them in converting to a paid customer. Websites function similarly, but on a massive scale. When someone tries to visit your website, we can take the context they’re arriving in and curate their experience to optimize for the sale. Did they come from a blog post comparing couches? Drop them on a landing page designed to sell couches. Did they google “directional drilling” and find your website? Push the rest of your services to the side: give them the low-down on your drilling operations.

Using analytical tools you can track every click, scroll, and hover your users make. Bind all that data into actionable metrics and you’ve got a lean recipe for optimizing features that convert visitors into cash and dropping elements that distract or deter.

Marketing

How does anyone know who you are? Most of your customers might come from word of mouth and friends of friends, but people still need to be able to find you. 70% of people use the internet regularly, and with the excellent ad targeting options out there now, it has never been easier to expose your business to those who might want to use it. When someone foreign is travelling through your city, they aren’t going to be familiar with your offerings. But when they search for “cheap phone chargers” or “late night car wash” and you are number one in the results, you can be sure you’ll receive a visit.

Logistics

How much paper do you work with on a daily basis. If you find yourself running into problems because paperwork is missing, takes a while to find, or your employees can never be bothered to fill it out, you’re ripe for a systemic change in the way you operate. Vehicle and equipment inspection cards can be digitized and sent immediately to the office on completion. Your website can manage inventory and show both you and your customers exactly what you have available at that moment. You might have several crews heading out to different sites and they’re all trying to rig their trucks up with tools. Searching for shop tools that someone else might have grabbed, and later trying to account for everything that’s moved around can take a lot of time. Time is money. Get yourself a solid inventory management system and you can stop wasting both.

Customer Service

If you aren’t happy with something you paid for, how do you react? Do you try to get your money back? Do you look for help to understand it? Before the internet, people found information in very different ways. The predecessor to Wikipedia was not the Encyclopedia; no, we just talked about it with our friends and decided for ourselves what the truth was. Of course, there’s phone and fax, but their usage is dwindling and takes a lot more manpower to respond to.

Most people delay resolving issues with their bank, phone, or internet companies because they know what awaits them when they call the help line. An automated response maze of options, followed by several minutes or more on hold while you wonder if they’re actually busy or just like to wait for customers to calm down. This is where our standards are set. If you get a system in place to handle customer complaints immediately, your customers will become brand advocates and advertise for you for free. The bar is literally low enough to step over, and you can step over your competition while you’re at it.

I had a problem with this website the other day. If you tried to connect without the WWW, it would redirect you to a server configuration page for software I didn’t think I installed. So I did what any self-respecting adult should do: I asked for help. My webhost — DigitalOcean — responded so quickly with the solution that when email notification rang, I assumed it was just a confirmation that the support ticket went through successfully, and didn’t even bother to check it. That is customer service I’m willing to pay for.

Public Relations

Your website is the face of your company to everyone who has never met you. When was the last time you abstained from a product, or from shopping at a certain store, simply because you had once heard something bad about them? Of course, you wouldn’t repeat the rumour to anyone else, but you weren’t about to risk your own money. A good website will get you in front of the criticism, in front of your customers, and the next time someone hears something bad about you they can say “No. I disagree.”

If you have a new product or a new service, don’t wait until the media hears it through the grapevine. You can spoon feed them your story, your way, as it happens. Journalists are people, like you and me, and nothing makes their day better than a ton of research and writing effort wisped away in the midst of your completed story dropping on their desk.

Your website is your brand. It identifies you as unique and important and is the designated authority over your online persona. Who you are, how you started, what you offer, where you are, how to get ahold of you — these are the bare minimum elements that define a web presence. The true value of a website is its purpose as an extension of your company; as an interface for both customers and employees alike to interact, and as the single most important driving factor in helping you make money.

About

I grew up in the small area of Goodfare, Alberta. Juggling my welding apprenticeship, home life, and recreation, I spend my evenings creating and mastering internet marketing solutions.