Hopper app update in progress.

Hopper is getting an update soon! Here’s a preview of one of the new characters that will be added:


Release should hit by next week, stay tuned! All added characters will be available to obtain for free.

This is the start of my first round of updates to my legacy apps in a few years. Hopper and Spin Ninja both fell behind in terms of support for new devices and performance, and Hopper is due for a dust off.

My Patreon | My Website

Let’s talk about REGEX.

Cloudflare, one of the biggest companies on the internet in terms of reach, expanse, control, and practicability out there. They specialize in internet security, safety, and general privacy. They’ve been named the leading DDoS Prevention source In fact, I use them for my own DDoS protection needs.

A couple weeks ago, for 30 minutes, a LARGE chunk of the internet was down. This is because CloudFlare serves as the “gateway” or access point for many such websites, including some cryptocurrency endevours. Needless to say, they have quite a bit of control over the internet.

Why did everything break? Because of a little something called REGEX. A CloudFlare engineer apparently screwed up with a “regex” rule.

What is REGEX?

It stands for “regular expression”, and is a sequence of characters that defines a search pattern. This search pattern can be used to compare against strings to find characters or sub-strings that match the said pattern. It was original created by a man named Stephen Cole Kleene. He was a mathematician in 1951, and he described what would eventually become early implementations of pattern matching.

REGEX is usually a bad idea, unless you’re attempting a pattern match, or you really know what you’re doing. Whenever working with regular expressions, be VERY careful that you double, and then triple check the logic of what you’re writing.


This is a pattern that matches strings of characters that start with a capital letter until it hits a space. Confusing, right?

\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b is a more complex pattern. It describes a series of letters, digits, dots, underscores, percentage signs and hyphens, followed by an at sign, followed by another series of letters, digits and hyphens, finally followed by a single dot and two or more letters. In other words: this pattern describes an email address.

Oh yeah. But not only are they confusing, they can be dangerous. Let me give you an example.

Suppose we have the following, very simple regex pattern:


What this does is match any string with two or more “X”s followed by a “Y”. This would match these strings:

“xxxxxy”, “xxxxxxxxxxxxxxxxxxxy”, “xxy”, “xxxy”, and any number of “X”s followed by a Y you can imagine. It will NOT match “xy”. Okay, fair enough. Simple enough, right?

Let’s take a look at what’s going on when compared to this string:


The first X+ will match all 10 X characters. The second X fails. The first x+ then “backtracks” algorithmically to 9 matches, and the second one picks up the remaining x. The group has now matched once. The group repeats, but fails at the first X. Since one repetition was sufficient, the group matches. The Y character then matches and an overall match is found. The coder sees the correct return value, the regex is declared functional, the code is pushed into the wild, and our computers get just a little closer to exploding.

Except… what happens if the Y character didn’t match? Like, what if there wasn’t a Y character in that string? Then what would happen?

The regex engine backtracks. Hard. The group has one iteration it can backtrack into. The second X matched only one X, so there’s nothing it can do there. “But wait,” The program thinks. “What if the X+ gives up a matching X character?”

So it matches the first X+ to 8 Xs instead of 9. The second x+ promptly matches xx. The group again has one iteration, fails the next one, and the Y fails. Stay with me here. Backtracking again, the interpreter now realizes that the second X+ contains a position it can backtrack into, by removing one of the Xs from the second match and combining it with the first X+. It’s all very confusing, but keep in mind it’s basically just the computer trying all possible combinations to attempt to match the string.

The group tries a second iteration. The first X+ matches but the second X+ doesn’t. Backtracking again, the first X+ in the group’s first iteration reduces itself to 7 characters. The second X+ matches XXX. Now maybe it matches? No, there’s still no Y character.

Failing, the interpreter tries again, since there are still many more combinations it can try. The second X+ is reduced to XX, it tries again, fails, and then reduces further back into the original X. Now, the group can match a second iteration, with one X for each X+. But this wacky combination fails too.

Are you starting to see the problem here? This is off ONE expression. If you go to


and put the same string in that I did without the Y, it will actually fail to match after adding a couple Xs because it will time out from taking so long.

With the Y, it completes within a millisecond.
Without the Y and a couple more Xs? Oh boy.

At least it tells us. If this exact situation happened inside a .NET application, it would crash, since a stack overflow would probably happen.

Now, the first thing you might think is: “Uh, just remove the parenthesis to fix  the nested quantifiers, genius”, but let’s replace each “X” with another, more complicated example. Something that might be coded in the workplace:


Not too much worse than what we had above. Now some context: The person writing this regex has a text file and they were attempting to figure out where the 20th item on a line started with an A.

Doesn’t seem like that hard of a task, and the regex works. What’s it doing, though? Same as the above example, it’s just harder to tell.

The regex looks like it work fine. The lazy dot and comma match a single comma-delimited field, and the {19} skips the first 19 fields. Finally, the A checks if the 20th field indeed starts with A. In fact, this is exactly what will happen when the 20th field indeed starts with a A. Straightforward logic.

When the 20th field does not start with a A, that’s when the problems start. Let’s say the string is “1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20” At that point, the regex engine will backtrack. It will backtrack to the point where ^(.*?,){19} had consumed “19“, giving up the last match of the comma. The next token is again the dot. The dot matches a comma, since a dot is a wildcard character. The comma does not match the 1 in the 20th field, so the dot continues until the 19th iteration of .*?, has consumed “19, 20” You can already see the root of the problem: the part of the regex (the dot) matching the contents of the field also matches the delimiter (the comma). Because of the double repetition (star inside {19}), this leads to a catastrophic amount of backtracking. At this rate, it would take multiple seconds just to check one line of text which should take less than a tenth of a millisecond. This can lead to HUGE lagspikes. In Cloudflare’s case, their server’s CPUs were maxed out to 100% load instantly, causing the internet as we know it to vanish for a solid 30 minutes as a software engineering positioning was busy being posted on Glassdoor.

How do you fix this?

Like this:


The trick is to be more specific. The complexity of the original regex expression was exponentially difficult, and contained a complexity of O(2n), which is terrible. The time it takes to complete said RegEx searches are exponentially higher the more characters in the string, and leads to terrible workarounds.

If you’d like to learn more about complex RegEx expressions, pattern matching, and how they could be vastly improved with the Ken Thompson algorithm, read this.

Now excuse me while I go back to something normal and non-confusing, like JavaScript.

My Patreon | My Website

A general report on the quality of Razer.

Been a while.

I’ve had many computer components over the years. Some might even say too many. I got my first computer when I was in 6th grade, and have been upgrading ever since. The point I’m making here is that I’ve had the privilege of owning many computer products, so I believe that I’m experienced enough to give my honest opinion on Razer’s quality control.

It sucks.

But it also doesn’t, and let me explain. Razer is a very very very hit and miss company. Their build quality FEELS excellent, and LOOKS excellent, but IS it excellent? Not usually, unfortunately.
I have owned these Razer products:
– Deathadder Elite (Original)
– Razer Kraken V2
– BlackWidow V2 Chroma
– Huntsman Elite
– Razer Blade 15

And I know many people that own Razer products as well. Now, this is entirely anecdotal, but out of every single Razer product I’ve had, all of them have had some sort of weird, critical malfunction or error.

– Deathadder Elite: Scroll wheel and middle click don’t work anymore. RGB colors don’t work anymore.
– Razer Kraken V2: Ear cup glue(?) wore out and so the padding started falling out of the ear piece.
– BlackWidow V2 Chroma: RGB lights on the T, G, and SPACEBAR keys don’t work, as well as the numpad lights. Additionally, the light profiles never actually stayed on. I actually had to write a program to load in my profiles at start without booting the terrible Razer Synapse program.
– Huntsman Elite: Volume scroll wheel glitchy and doesn’t work. Additionally, it gets stuck sometimes and adjusts the volume on its own.
– Razer Blade 15: Constant quality control issues. Luckily, my Blade is functioning as expected so far.

The laptop is not scott free, though. Just because I haven’t had a major issue with it doesn’t mean I haven’t had minor ones. For instance, recently someone screwed up on some end, and the Blade started crashing. Blue screened every 10 minutes or so. Figured out you had to downgrade to a random obscure driver buried in the NVidia support page in the archives. Really? Who else would bother rolling back their laptop drivers 15 versions in order to see if that’s a fix? Many YouTubers complained about this issue and Razer quoted them around $500 to replace the motherboard.

Razer support is a joke. Please never buy from Razer’s website. Buy from a retailer that will be able to actually communicate and help you if you have an issue. Here’s my story with Razer Support.

I was all set and ready to purchase a brand new laptop. I’d been wanting a Blade ever since the 14, but they were too expensive. Once I got older, I could actually afford a better computer, and Razer’s sleek design and look-alike feel to a Macbook drew me in. I’d been raised on Apple products, but switched over to Windows around 5 years ago.

I purchased it through Razer’s website for the standard price they were selling it at the time, I believe it was $2,499 or something. Either way, it was a bunch of money. I think with tax the total was around $2,700. I went to bed happy with my purchase.

The next day, I got an email from Microsoft saying they received Razer Blades and were having a student discount of $300 off. Crap. No big deal, I’ll just tell Razer to cancel my order. I emailed them that day.

The next day I received a reply from Razer Support. “Oh, no problem,” They said. “Just decline the package when it comes to you so it ships back to us and we’ll give you a full refund.”

Apparently they’d already sent out the laptop, so at least they work fast on that front. I did exactly as they said, and never even touched the package. In fact, I never opened the door. The front doors of my house have windows that you can open outwards, so the FedEx guy walked up to hand me the package and I declined it right there and then. He clicked a button on his device, scanned the package, thanked me, and left. And that was that.

Or so I thought.

A week later, I still had not received a refund from Razer. I emailed them over and over, hoping to get a reply. I went through numerous support chat sessions that said the package wasn’t refused or they hadn’t received it back, or the package had been delivered. What?

I check the tracking number that they’d given me from FedEx, and what do I see? They delivered it to someone else! The delivery says it was refused, sure, but then it says it went back to the FedEx facility and they delivered it to someone named A. Atkins. I hope he’s enjoying his free Razer blade.

So FedEx screwed up, right? Not my fault, right? Razer should take it up with FedEx and give me my money back, right?

Wrong. If you’re Razer Support, of course.

Not only is every single person on there that you talk to functionally illiterate, you also have to deal with the 5 minute response times between each message in the chat as they’re probably riding the clock for every minute they can milk out of it. I would too if I had to work in a support center for Razer.

If you’re set on buying a Razer product because of their looks, here’s what I recommend:

  • Buy from another retailer and get their extended damage/tech failure protection or whatever. Trust me, just work it into the price. You’ll be glad.
  • NEVER buy from Razer.com
  • Check your laptop for these common issues and return for another if any are experienced:
    • Coil whine
    • Backlight bleed
    • Trackpad clicking
    • Charger not working
    • Constant blue-screens (probably a software issue, message me first :P)
    • Graphics card not being utilized fully (run a benchmark or adobe premiere)
    • Loose keyboard keys
    • Dead pixels
    • Swollen battery

And yeah, that’s a scary list. However, these are just all the issues you could experience. I’m not saying you will, and you probably won’t. In fact, odds are you get a perfectly fine machine. Again though, Razer support is absolutely abysmal, so make sure you buy from another retailer and get extended warranty protection.

The problem is that there’s really no other alternatives for me. All the other Windows laptops just feel too clunky or they look too “gamer-like”. I don’t want RGB lights along every inch of my computer, nor do I want a giant stylistic red slash and a giant dragon across the front. And I wouldn’t be caught dead using an Alienware. I mean, look at those things.

So what did I hope to gain by writing all this? Honestly, nothing. I just want to share my experiences with a certain company with the world, in hopes that someone, somewhere, is helped just a little bit.

My Patreon | My Website

How to create a simple voice-activated assistant in C#.

While this sounds advanced (and it can be), it’s not that hard to set up a very basic setup where a custom application runs in the background in C# by using the built in speech recognition libraries in Windows 10.

Taking this idea further, I personally have a “Jarvis” that runs on my computer, automating basically all of my common actions, including launching games, music, sleeping my computer, adjusting the volume, minimizing windows, controlling the lights, and (best of all), sending emails and messages. I recommend using an external API for speech recognition if you’re serious about building something similar, as Microsoft’s sucks. You can build your own, or attempt to use something like Google’s API.

Anyway, here’s some simple C# code that should get some ideas flowing.

My Patreon | My Website


You may be wondering, “what the hell is up with your website? It doesn’t end in .com anymore.” You’d be right. The ending of a URL is called a “TLD”, which stands for a “top level domain”. Top level domains can be virtually anything, although for some reason craploads of regulations are put in place for what can go after the period in domain names. “.dev” is a newer such one, created by Google. I recommend you check these out if you’re interested.

Anyway, I decided to pick up “gmr.dev” and use it for a bit and see if I like it. Everything pointing to the old “gmrgames.com” domain still works perfectly and will redirect seamlessly to “gmr.dev” for now until I decide if I want to keep it or not.

Feel free to contact me at “hi@gmr.dev”. 😉

My Patreon | My Website