I'm a software engineer living in Louisville, Kentucky.
I make video games at Two Scoop Games,
volunteer at Louisville Makes Games,
and help organize the local tech scene at LouisvilleTech.org.
I work primarily with JavaScript, React, Elixir, Node.js, and Ruby.
I use IO.inspect/2 all the time
when I'm debugging something, and I often run into a problem where I'm looking
at a gigantic map with lots of fields that gets truncated. I usually want
everything to be printed, and I have to remember the options to enable it. So
for reference for my future self, here's a handy function that actually prints
everything:
Since most places are renaming the default git branch from master to main I
want to do the same to reduce friction. I want to rename all my default branches
in all my projects in one afternoon so I can retrain my muscle memory and not
have to remember which project uses which branch name.
Working as a programmer today you end up writing a lot of plumbing code, gluing
together systems under your control with external systems. Many times you have
to build processes to ingest data from other companies. Sometimes you pull
the data, either querying an HTTP API, downloading CSV files from an FTP server,
or even directly connecting to a partner's database. Other times, data is
pushed to you, either through your own API, webhooks, or a shared S3 bucket.
My game Kick Bot uses
Cinemachine
to control Unity's cameras. Cinemachine lets you create multiple virtual
cameras, and the real Unity camera will focus on the one with the highest
priority.
The priority is just an integer you can change with code whenever you want. When
a new virtual camera becomes the "live" camera, Cinemachine will perform a blend
from the old camera to the new one. Cinemachine will also let you create a blend
list specifying blends in between specific virtual cameras.
Idempotence is the property of a
software that when run 1 or more times, it only has the effect of being run
once. I'll describe a process I'm making at work, and describe the problems that
idempotence will help avoid.
I'm a big fan of RSS. I'm
up to 155 feeds in my favorite RSS reader. That means I
read lot of news, blog posts, etc. A lot of it is mildly interesting, but
there's a few links each week that stand out. These "interesting links" are
either really thought-provoking, give me a "light bulb moment", capture my
imagination, or are extraordinarily relevant to one of my interests/hobbies.
If you have a web site that shows dates and times, it can be confusing to people
reading the site if they are displayed in a different time zone than what the
person uses. With a little bit of JavaScript and the
Luxon date library you can format your dates
into the viewers local time zone.
I got a neat desk-mounted macro pad called the
Pikatea. I wanted one of the buttons to cycle my
computer's audio output between my headphones and speakers. I found that you can
use pactl to
inspect PulseAudio settings, and change them. Below is a bash script I wrote to
cycle output (i.e. "sinks" in PulseAudio terminology). You can run it multiple
times, and it'll pick the next output after the current one.
I decided to try out tmux's mouse mode by adding set -g mouse on to my
~/.tmux.conf file. It is really nice being able to select and resize panes
just by clicking on them. One thing I didn't expect was that when you have two
vertical split panes, that dragging your mouse to select text would wrap
correctly and only select text in a single pane! I had to add this command to my
~/.tmux.conf to make it automatically copy to the system clipboard:
I installed some old hard drives into my server to get some files off them. They
were a RAID 1 array, using LVM and encrypted with LUKS. It was confusing to
figure out which /dev entries belonged to what, and in what order
RAID/LVM/LUKS was setup. After some searching I found the lsblk command which
gives a nice visual layout of how the devices are laid out:
I believe privacy is a fundamental human right, and I set up technology to help
enforce my privacy on the internet. I use Firefox as my web browser because it's
open source and not run by an advertising company. A web browser is a user
agent, meaning it works for the user. Here are the settings I configure to help
me be private on the web.
I wrote Living in
Syndication to scrape
websites and generate missing RSS feeds. I was having trouble with a certain
site rate-limiting my scraping to something ridiculous like 5 requests per day!
It's not like I'm hammering the site or doing anything unethical.
I've recently rediscovered the joys of
RSS thanks to a RSS reader called
Miniflux. RSS lets you subscribe to websites and
automatically get notified when new content is available. RSS is a pull
technology, meaning you control how often you check for content, can unsubscribe
whenever you want, and don't have to give any information to the content
provider. RSS has the usability benefit of making it easy to consume lots of
information from many places very quickly.
I want to convince you to self-host as many internet services as possible.
Self-hosting a service means installing and running software on a computer you
control. You can self-host out of your home or a rented computer in the cloud.
I'm working on a project where I'm building an Elixir
Phoenix website to take over specific paths
on a larger website. The sites are hosted on AWS, so my plan is to use an ELB
with Listener
Rules
to send requests for specific path prefixes like /news* to my Phoenix server,
and send any remaining paths to the old server.
After showing a game at a trade show/gallery/festival, I've noticed a problem
where people walk away from a game mid-session. This makes it so the next person
to walk up will start the game half-way through and miss the beginning, which
often includes tutorials or learning moments. To make sure a demo restarts, I
wrote this Unity script that fires an event when no inputs have been received
for a set amount of time:
I'm going to be showing off an early build of Kick Bot, a game I've been working on for a long time, at Bit Bash Chicago this weekend. If you're in the area, stop by and say "Hi"!
At work we have an ASP.NET web site that uses the built-in ASP.NET
SqlMembershipProvider. My task was to enable one of our Elixir apps to
authenticate users using their credentials used in the ASP.NET app.
Many modern JavaScript development tools are distributed through
NPM and tell you to install them globally. For some
packages it is okay to install them globally, but other packages are creating a
future headache for you. I will explain the problem with global NPM packages,
how to tell when it is okay, and how to use locally installed packages instead.
CSS makes up the majority of code responsible for implementing a responsive web
site. Every once in a while I come across certain aspects of a responsive site
that can only be implemented with JavaScript. In order to avoid repeating the
screen widths (once in CSS, once in JavaScript), my coworker Martin
Hofmann and I came up with a way of detecting
the current CSS breakpoint from JavaScript.
I ran into a head-scratching problem with a pure React component where it was
re-rendering when it shouldn't. The component wrapped up a 3rd party script
which put a button on my site. The problem was that when the button was clicked,
some of my state changed so I could show a loading spinner. That state change
made my component re-render, which broke the 3rd party script by re-initializing
it.
Whether you're going to build a real life social network by organizing a new meetup, or begin attending one, this is a list of common technology meetup formats.
HTML5 gave life to new JavaScript APIs that make it possible to create amazing game experiences on a web page. Learn how to draw on a canvas, make sounds, respond to input, then how to package the game and ship it on the Apple App Store and Chrome Web Store.
In today's modern web development, much of a programmer's productivity comes from code that they did not write themselves. Much of that code is hosted on GitHub, and less and less of it has any amount of documentation. The most prominent form of documentation is now the README.md file in the project's root.
A few months back I was volunteering at Code Louisville and helping George log into a forum. He had signed up a few days ago, but never logged in. When he tried to log in, the forum gave an invalid username or password error. George had unknowingly created a Schrödinger-ed user account.
I'm interested in the quantified self and I wanted to log data about my car and how I drive. I'm also concerned about privacy, and wanted to keep my data private and not rely on a company or service. Since I already had a Android smartphone, I was able to put together a fully automated system for only about $35!
One of my favorite parts of Git is how it lets you fix your mistakes. One mistake I needed to fix a few times in the last year was having two separate repositories, when they ought to be a single respository. I will present commands to merge a child repository into a parent respository as a subdirectory. The new child repository subdirectory will preserve its history and look like it was always part of the parent repository.
Building a real social network is easier and more rewarding than building the next Facebook or Twitter. Even shy, introverted programmers (such as myself) can build a powerful network in just a few months.
The relationships you build will keep you excited, up-to-date, and alter the trajectory of your career. You can't afford to stay home.
While I was out to dinner last night I decided to pick up a movie on the way home. I opened up my RedBox Android app, and tried to make a reservation. The experience was more frustrating than it needed to be, so I wanted to document the problems with the app's UI in the hopes that they are fixed, and so others do not make the same mistakes.
I've spent a lot of time last year learning my tools better, and I've built up a list of plug-ins for Visual Studio that help me work smarter and faster. All of the plug-ins below work on both Visual Studio 2010 and 2012.
One of the coolest parts of Git is that once you learn it, you will never need to use another VCS. My company uses Perforce for version control, and it can be painful. So when I got to work on a new greenfield project, I stuck everything in Git. That worked great for a few weeks until I needed to begin collaborating with other developers who would only use Perforce. Fortunately, Git has a Python script that lets you interact with Perforce servers using a special "git p4" command set. The tricky part is getting it all set up on Windows where Git and Python are out of their normal Unix environment.
Back in November I was able to attend the Software Craftsmanship North America conference in Chicago. I signed up for the post-conference Code Retreat, which sounded like a fun day of writing code with my peers. During the conference I met many awesome people, including Mike Clement. Mike told me about the upcoming Global Day of Code Retreat on December 8th. Mike said he was going to run a session in Utah, and persuaded me to run one in Louisville.