For more, check out my GitHub page.

Habits March 2018

After spending so much time thinking about measuring and monitoring productivity, I realized that a separate but somewhat related problem in my own life was establishing and maintaining habits. In particular, I seem to have a tendency to start to do something (such as write my thoughts or reflections down regularly) but then after a few months, I would lapse.

I think the main reasons for lapsing on these habits would be that I would miss doing it a handful of times, and then forget. In the off chance that a habit ended up being useless, this would be a totally natural and good process, but I kept thinking that there were other classes of habits that are pretty much universally good - such as flossing - that are equally hard to establish and maintain.

Having just gotten a new Android phone (Pixel 2), I decided to take a stab at making an Android app again (having not done so in at least 4 years). The learning curve was a bit rough, but it ended up not being too hard to get something working locally with all of the bells and whistles that I wanted - editing, push notification reminders, etc.

MeDB December 2017

In between building Life and Starter, there was actually another project "Lens" (orginally Life3) that was built ontop of Meteor. I usually prefer to talk about the "why" of my projects than the "what" as it pertains to the particular technical stack that I use, but in this case my choice turned out to be a disaster. Lens was meant to be a website building and organization application that leveraged paths instead of hashtags to link content together. I still actually like a lot about the original publicity settings of that project, but building it in Meteor was a huge mistake. I trapped myself into a walled-garden that eventually became impossible to build in anymore.

Eventually, I abandoned Lens and imported what was there into Starter as a "Notes" tab. This process was painful and so I spent some time thinking about a common data format that I could use across applications and I arrived at the flat file. MeDB is a project that adds a short plaintext header to text files, saves them into a git repo, and manages syncing them to that repro via a UI built with Pagedraw. It was fun to build, but after using it for a bit I got upset about the amount of time I was spending on the UI. I also eventually discovered Perkeep which seems spiritually similar and deserves further investigation.

Bots June 2017

In the summer of 2017, I decided to revist one of my favorite books on game physics engine design but this time with the intent of implementing a "Battlebots"-esque web application that let users submit specifications for bots to batter.

I got pretty far into implementing the physics part of the project but didn't really get into the whole collaborative website part. In particular, I ran into a wall where the engine never really "felt right" and kept digging further into the math rather than building out any of the rest of the experience. I think this was fine, I definitely enjoyed the exploration back into this area of physics, but it's a shame that I never got all the kinks out. I might have to take another stab at 2d physics simulation someday after I get a bit more background on complex numbers, which seem to be the secret to making all the math work out nicely.

Starter October 2016

Starter is my personal take on a task tracking and management website similar to Trello or Maniphest. I started building this project after realizing at a Dropbox hackathon how much nicer it was to build websites in Python rather than Node.js. I was starting a new "starter" project (one that I intended to fork multiple times but without much other than boilerplate itself) but then ended up keeping the name and iterating on it over the past couple of years.

In the first phase of the project, Starter was a task tracking board with a calendar-like "event" tracking interface. What this let you do was finely monitor how you were spending your time in 15 minute chunks. When you started working on a new task, or finished one, the corresponding event would be created or finished respectively. This ended up being sort of fun but not all that useful - I never found myself actually reflecting on the higher-level view of what I was doing or if I was happy with my productivity.

After becomming a bit uninterested in the project, my coworker pointed me towards the "Getting things done" (or GTD) methodology and the associated book. After reading some of the book, I realized that I could adapt Starter to be a tool to help me implement this in my own life, or at least the parts that I found most useful. In particular, I scrubbed the side calendar-like interface and replaced it with "captures" which have an associated webview that I have bookmarked on my phone to be able to write down things at any time. Regularly, I then move captures into tasks or delete them (if they're short and I can do them in < 2 minutes).

After about one and a half years, I'm still working on Starter as I find things - and definitely still using it both for captures and for "contexts" - having separate (but also unified) views of my personal tasks and work tasks has been quite useful as I've advanced through my career so far. In the future, I'll explore more deep integrations into my real company's task tracker - to keep tasks in sync, and potentially Google calendar to help keep my scheduling overhead in check.

Space Shooter May 2015

At the end of my senior year of undergraduate at UT, Josh Slocum, Dillon Walker, and I were bored and couldn't decide what game to play. We had recently been playing a game at agar.io and were having a bit of fun, but decided we wanted to write our own game instead. We initially spent approximately 3 hours working on the game and after these initial 3 hours we had a working multiplayer game which is demonstrated in the video linked above.

The game uses Socket.IO to broadcast game state from the server to the connected clients. Simple position interpolation is used on the client side to keep the game updates smooth even in the place of server latency. All move and shoot commands are sent to the server which performs the update of all entities at each time step. The game consists of two teams: players (actual users) and enemies that employ a simple AI to move and shoot at the players. We added the simple AI to the game after the initial video and it simply moves enemies around until they can "see" a player, at which point they follow and try to shoot accurately. When players kill enemies, they grow larger and more powerful, but also move more slowly.

Some later optimizations we added involved reducing small object creation and eliminating JSON serialization in the state transfer. We wrote our own simple serialization code to convert the game state to a JavaScript ArrayBuffer which resulted in at least a 2x performance improvement over using simple JSON serialization. In addition we spent some time making sure that we reused objects whenever possible to avoid large GC overheads.

Rise March 2015

Upset by my recent habit of hitting snooze many times every morning, I decided to try to make an app that forced me to get out of bed and face the day. I mainly wanted to make the app to familiarize myself with the new Android Studio and some of the Android features I had never used before like accessing the camera. The overall idea of the app was to make an alarm clock that required me to go to a separate room and scan a smiley face before it would turn off in the morning.

Rise is firstly an alarm clock, I found a great guide on how to make an alarm clock Android application so I followed that pretty closely for this part. I then built a scanner that used Android's interface with the camera to look for a specific smiley face in order to turn off the alarm. The picture of the smiley face that the app recognizes is above.

Instead of using some computer vision library to detect the face, I made a very simple algorithm to detect it quickly (albeit less robustly). Essentially, the algorithm takes an image as input and shoots out four rays from the center in the four cardinal directions. It then checks that the two arrows going east and west do not intersect any lines. After this, it makes sure that the north ray intersects one line and the south ray intersects two lines, all of approximately the same width. The line detection is done by a simple threshold on the color intensity (hence the black and white face).

Life December 2014

After my first semester of school senior year, I was looking for a side project to work on over the winter break. I remembered back to one point in my life when I had wanted to try to keep a journal of my life so that I could read it in the future and remember everything that I had done as a kid. Starting a journal was something that I tried to do multiple times but each time I only managed to make it a few days before forgetting about it or getting frustrated with it. I decided I wanted to try to start a journal again, but this time I thought of ways that I could leverage the myriad of APIs that already track the events of my life to help me.

One key thing I realized when I was thinking of this project was that there was a lot of stuff in my life that I wanted to say or express in some way, but there wasn't really anyone I wanted to say it to. This is of course the point of a diary but the corollary to today's world would be a Facebook type product that you can post things to without those things ever being shared. What I realized I wanted to make and use was a social network type project that was completely antisocial.

Life is a project that I'm just getting started on. I launched the first version of the website on December 30th, 2014 but it's certainly not feature complete. I wanted to get this website out there mainly so I could start using it myself to record my thoughts throughout the day in it. Some of the upcoming features for the website will be the ability to label your events, automatic Dropbox photo integration (your newly updated photos automatically are added to your life timeline), and a mobile app to add events on the go.

Beta November 2014

Recently I was using the Snapchat messaging functionality that allows messages to be read only once and although I liked the idea, their interface for it was awful. Because of this, I set out to build a similar messaging service that would also work on the web through shareable links. In the end, the service converged to a system like email, with a subject and a body, with the body only being able to be viewed once. I implemented this by having two records in a SQL table for each message, a metadata record that stores the header and information about who sent it, and a message record that stores the actual content of the message. The only request that can retrieve the content of the message deletes the record from the database so that it can only be read once.

One interesting feature I added that Snapchat's messenger doesn't have is the possibility for anonymity. You can use the website and generate a message without it being to tied to an account of any kind. The downside is that the first person who gets the shareable link is the only one who can view it. To enable more control over the message, you can create an account and specify a recipient who will then be the only person who can ever retrieve the message body from the server (not even the sender can see it again).

I'll probably add more functionality to this project in the future because I'm very much interested in how the world communicates. I think there's something very fundamental to how we interact that a messaging service like this or Snapchat provides; spoken word is often not recorded forever like most services around today. I believe that because of this, there will always be a desire for record-less communication.

Alpha October 2014

I was preparing for an interview with Imgur in my senior year of college and one thing I decided to do was familiarize myself with the technologies they said they used on their public blog. I went about this by trying to implement as much as Imgur as I could and I got pretty far (except I ended up using node.js instead of PHP). The application I made was a node app written in Coffeescript that uses MySQL (with an ORM), Redis for image ranking, and nginx.

At one point, my friends at school wanted to try using it so I started hosting it on my tiny DigitalOcean instance and let them use it and help me refine it. The live website itself can be found at the link above and of course all of the code can be found on Github.

Countdera October 2014 - December 2014

At HackTX 2014, my college friends and I decided to make a web application that could potentially replace display advertising on the internet. The inspiration for this project was a project called Tidbit, which mined bitcoins in a browser when someone visited a website. We like to think of this approach as a way to pay for the websites you use everyday with your CPU cycles (after opting in) instead of your personal information (which is what targetted advertising today relies on).

Countdera specifically was a Javascript Framework that allowed people to upload map and reduce functions (written in Javascript), provide links to input files, and run MapReduce style jobs on their input data. We demonstrated this functionality at the hackathon with a simple word counting program running on the text of the US constitution and you can see how this works in this video. We used Firebase as a way to keep track of all the worker nodes (visitors to websites with an embedded iframe instead of a display ad) and as a way for worker nodes to communicate to each other. We also didn't exactly implement MapReduce, the day before the hackathon, I designed a protocol for us to implement which is described in great detail at the link above. This worked reasonably well but there are a few optimizations and improvements that we would need to make to deploy something like this that we outline on the GitHub readme. The reception of Countdera at the hackathon was quite positive and we even had the opportunity to present it in the finals to all of the contestants.

I personally believe that the world is moving in a direction that will value personal privacy more than in the past and I think that eliminating targeted advertising is a good start. I even wrote a very long paper about targeted advertising once for a class in college. I built Countdera with John Agnew, Dan Rutledge, Jim Given, and Josh Slocum.

Grouped August 2014

After my internship at Dropbox I became interested in ways that people collaborated in documents. I set out to emulate the Google docs product or at least the real-time collaborative editing part. I read through some of the research on the subject and settled on this paper that was able to provide collaborative editing without the use of operational transforms. An implementation of this paper in a textarea element using Firebase as the backend is what is available at the demo link above.

The issue with this paper that I quickly found is that there is never a way to checkpoint the document since someone could always come back online (and change the order of many events), and this makes the calculation that computes the state of the document more and more expensive over time (even if you delete everything). I thought of an interesting alternative approach that involved using a data structure backed by a skip list that is sorted by base 64 encoded strings. The way my idea worked was based off the fact that there is always a rational number between any two rational numbers. Because of this simple fact, if you have two items and insert one between them (corresponding inserting a character in a string) you can always generate a unique and totally orderable id for that new character.

I made a good amount of progress on implementing my new technique, but eventually ran into a weird case that happens if two clients (at least one being offline) edit between the same two characters. My solution would work meaning it would be eventually consistent, but it would not being intention preserving and characters would be interleaved in a strange way. If I ever think of a way to fix it, I might revive this project.

Touch July 2014

A fellow Dropbox intern and I in the summer of 2014 got together with a full-time designer who was new at Dropbox and a mutual friend to build something for Y Combinator Hacks 2014. We met several times before the hackathon to discuss ideas and how we would build them and eventually settled on building a lightweight event planning tool to facilitate planning short-lived or spontaneous events like grabbing dinner with some friends for instance.

When we got to the hackathon, we realized that one of the APIs that we had planned to use (Facebook's chat API) was not going to be accessible to us so we switched gears 6 hours into the contest to build Touch. The motivation behind Touch is that your phone is pretty useless when you're sitting at a computer at work or at home. We thought it would be cool to provide contextually relevant buttons for your phone to interact with your computer as an extension of your keyboard. Touch also ended up doubling as a fantastic presenter's tool, enabling someone in keynote to switch to a YouTube video for instance in the middle of the presentation and back without touching their computer.

We relied on Firebase to be a secure communication channel between the computer and your phone. Touch only works on Macs currently because it uses something called AppleScript to scrape what tabs you have open in chrome or what native applications you are running. More technical details about Touch can be found on the GitHub readme. I built Touch with Damon Doucet, Predrag Gruevski, and Ryhan Hassan and although we didn't win anything at YC Hacks, we really enjoyed the experience.

TuringPoke February 2014

In the middle of February of 2014, a phenomenon called Twitch Plays Pokemon (TPP) swept the media and my friend group. The idea was to stream the playing of a video game in such a way that the people watching could submit moves to the game and either make progress or cause mayhem. More information on the original game can be found in a nice writeup on Wikipedia about it.

During this time, I decided it would be fun if some of my college friends and I played our own version of it so I threw together this project. The project worked by running a laptop in my house at all times with an emulator on it running a GameBoy game. I then used the utility ffmpeg to stream a portion of the screen that included both the emulator and a console through a webserver powered by jsmpeg. I then created a small node application that served a canvas that showed the stream from my laptop and submitted commands or chat messages from users to the emulator itself using the xdotool utility.

I shared my version of TPP with my CS honors program at UT (the Turing Scholars program) and we actually managed to play through an entire game of Pokemon and win before the real TPP stream did. A more detailed writeup on how all the components of this project worked together can be found in the readme on GitHub.

3D JS physics engine December 2013 - January 2014

I have always enjoyed physics and the math behind it so when I learned to program, some of the first things I made were physics simulations. This is probably the fourth or fifth one I made but it was the first to include many complex collisions in 3 dimensions.

My parents gave me a fantastic book on how to implement a commercial physics engine one Christmas and after reading through it, I decided to implement a physics engine like the one the author described in Javascript leveraging WebGL libraries for rendering. While implementing this engine, I actually found some errata in the book and corrected them in the author's open source C++ implementation. Some small demos of the engine working can be seen at the link above and all of the code is available on GitHub.

Dwopbox November 2013

My college roommates and I built what we eventually called "Dwopbox" during HackTX 2013. We were surprisingly successful during the hackathon and actually won the "Hacker Lounge" prize for this project. Dwopbox is a peer-to-peer file sharing system written entirely in Javascript that uses WebRTC channels to transmit files.

We built Dwopbox in the midst of many of Edward Snowden's NSA revelations which inspired us to think of a new way to share files across the Internet without the contents of the files themselves getting into the hands of a government. Dwopbox consisted of two parts, a simple Postgres database that stored file metadata, and a distributed protocol we created (essentially a simplified version of BitTorrent). The protocol allows users who joined a "room" to receive information about the files that the original user was sending. Using Chrome's local storage support, we first loaded the chosen files into the broadcaster's web browser, then started sending pieces of the file to other web browsers through WebRTC data channels. Once a viewer has all parts of the file, some client-side Javascript reconstructs the file by pulling it out of local storage and immediately "downloading" it to the device.

The friends I worked on this project with were Calvin MacKenzie, Josh Slocum, Dan Rutledge, and Adam Faulkner.

Expense Tracker February 2013 - April 2014

In the later half of my second year of college, my friend Adam Faulkner and I thought of a startup idea. The idea was to make a website that simplifies paying your friends back when one friend pays for something like a meal or a monthly bill. Our insight was that if different friends in the same group pay for things, the debts could cancel out and result in smaller payments to equalize. This project was one that Adam and I took very seriously at times, even going as far as to have secret weekly meetings to discuss our goals.

Over the course of the project, Adam and I were able to experiment with a myriad of new hot technologies. These included databases such as Apache's CouchDB, Couchbase, RethinkDB, Cassandra, and finally PostgreSQL with the Bookshelf.js ORM. We always wrote the server code in Node.js but experimented with AngularJS for the frontend. Working with all of these technologies was probably one of the most intelligent things I could have done in college because it taught me how to ramp up quickly and become more comfortable with reading documentation and even contributing back to open source projects.

During my junior year of college, my roommates and I used our website to manage our bills and make sure everyone was being paid back. In the end we never could really devote enough time or effort to the project and eventually found a website that had the very same as idea and did it with a much better interface called Splitwise so we finally gave up on the project for good.

Simple Tanks November 2012

In my operating systems class first semester sophomore year, my project partner, Adam Faulkner, and I set out on an ambitious final project. The class required us to build an operating system called JOS using some skeleton code. We got to start by implementing the bootloader in x86 assembly and slowly moving up through memory management, file I/O, process communication, and eventually a functioning shell. Our professor had us choose whatever final project we wanted so Adam and I chose to enable graphics mode and write some cool programs to run on our operating system.

We wrote this game to run on an emulator running our OS mainly because memory was an issue and the game state was fully encoded in the framebuffer (the pixels for the ground). In order to compute the arcs that the bullets traveled in, we had to also enable the floating point unit and allow our operating system to make trigonometry calls such as sine and cosine. The game is written in C using SDL and takes in basic keyboard input. The other fun part of this project however was getting text to render. Since we weren't in text mode in our OS, we had to use a bitmap font and render characters ourselves. In the end, our professor and TA really loved our project and gave it the best project award. We had also ported my C Rasterizater to render some 3D triangles, cubes, and axis lines all within a tiny emulator running an OS that we wrote ourselves.

2D JS physics engine November 2012

I implemented a 2-dimensional bouncing ball simulation to experiment with Javascript's access to device accelerometer data and the math behind momentum based glancing collisions. It was a lot of fun to derive the math behind elastic collisions that aren't head on. One interesting result of this was a almost labyrinth-style simulation on mobile devices (and some MacBook Pros). You can see the working simulation at the link above and the source code is hosted on GitHub.

Old Website September 2012

After my first internship, I my friend Adam showed me his intern hosts website which had this cool effect where it turned a random image into colored ASCII text and rendered it. I wanted to emulate the same effect so I made my first student website at UT Austin (originally at cs.utexas.edu/~david) be a page that converted three chosen images into black and white text, colored text, or showed the original photo. Over the years I tweaked this page as I added more projects and did more work before eventually purchasing my first domain (davidw.com) and making a new website for it.

The effect works by examining the pixels that each character is representing, determining the average color (for the text color) and the overall density. This density is then used to determine which character should be displayed. For example, a very dark area would be rendered with a '@' while a very light area might be rendered with '`'. I scored each character in a separate java program that literally rendered each character in a white area and calculated the number of pixels that were black using a monospace font.

Tetris Battle Bot September 2012

In my sophomore year of college I was telling my roommate about when I used to write bots for RuneScape when we thought of a challenge for each other. We were both addicted to playing the Tetris Battle game on Facebook and wanted to see who could write the better program to play it automatically. I was able to get a working program out by the end of the week and definitely won the contest, plus I learned a lot along the way.

This program was written entirely in Java which was a pretty bad choice I learned. It used Java's Robot class to take pictures of the screen, find the game board, identify the pieces, calculate the best move, and move that piece to the best position. I quickly found out that the hardest part in the whole project was to get Java's library to reliably move the pieces around the board. It was so difficult and finicky in fact that I eventually just gave up and lived with the mediocre result. Check out the video to see it in action, it was optimized to clear as many lines as fast as possible, not necessarily trying for combos of any kind.

C Rasterization Engine April 2012

Towards the end of high school, I became really interested in how to render 3D scenes. I started out by trying to write some Java applets that used a lot of vector math that I derived myself to render points. This approach didn't workout however because I could never render anything more than wireframes. My freshman year of college however, I took a linear algebra class and got to learn all about matrices. To help myself learn, I wrote a matrix library in C for fun and then to show it off, I started reading papers on how graphics rendering works on GPUs today.

I taught myself what matrix operations I needed to perform to render scenes in 3D and wrote the graphics part of this project in the second semester of my freshman year. The result could render triangles with colors along with points and wireframes. Later when I was taking operating systems, my project partner and I enabled graphics mode in our OS and ported this library to work on the operating system we wrote. This library (and a game that we wrote for the project as well) really wowed the professor and we won the best project prize for that year.

RuneScape Botting September 2010

RuneScape was actually the thing that caused me to love programming. RuneScape was a game written as a Java applet that could be "botted" (or automated) by modifying the jar (to add some accessors) and writing complicated scripts to interact with this hacked client. I found out about these scripts right around the same time I was taking a computer science class in high school, and I quickly realized that I could write them. It was a tremendous amount of fun. Whenever something in game got too boring, I would just write a new script to do it for me automatically and share it with the world for free. I made a website that had links to all of my scripts and instructions on how to use them as well as analytics that I loved watching as more than fifty thousand people from all over the world enjoyed what I had made.

My most popular script was called Conderoga's Chopper (or CChop for short). The original forum thread for it had over four thousand replies and over a hundred thousand views. It automated the process of collecting wood resources in the game, storing them in the bank, and included what I deemed to be some revolutionary "anti-banning" practices such as realistic waiting, occasional mess ups from "not paying attention", and a neat GUI. I've included a picture of it above and if you search for it on YouTube you can find videos of people using it.

Botting RuneScape had a tremendous impact on my life, it showed me that with programming I could use what I learned in school to make literally thousands of people happy. I thoroughly loved being a part of a community where I was the hero for writing code and making their lives easier and I love that it pushed me down the path of a career in computer science.