Last week I did a useful prototype, but this week was mostly silly things and experiments with minimalist HTML.
I remade a countdown timer prototype I tried to do ages ago in Elm. Keeping in mind my observations about useful vs interesting in prototypes, I realised I just wanted to make one that worked. So I built it in plain old Javascript. Not even in a separate file, just embedded in the HTML. It was super old school, but it felt surprisingly good to throw out all that complexity. The final version did exactly what I wanted it to, and it's on my demoserver if you need a countdown for some reason.
I wanted to make a silly gift for a friend who was into Hamilton, the musical, so I followed in the noble footsteps of "instant x" buttons across the internet and made an Instant Hamilton. This was, again, an all-in-one HTML page and felt similarly good. I had to do some clever double-buffering trickiness so you don't get caught by the audio or video loading, which worked a treat in the end. The prototype was just with 3 images and sound clips, but I scaled it up to 16 for the version on my demoserver. Instant Hamilton, away!
I've been thinking for a little while about how to make git more usable. Part of the problem is that I think most approaches to git suffer from xkcd syndrome: "Just wait through a few minutes of 'It's really pretty simple, just think of branches as...' and eventually you'll learn the commands that will fix everything."
Git has a simple model, but it's not an intuitive model. Unfortunately, git tries to help you by hiding the details of that model behind user-friendly "porcelain" commands that ultimately stop working in weird ways you don't expect. The reason why your local neckbeard can jump in and fix things is because they're not thinking in terms of the Fisher Price My First Version Control metaphors you've been given, they're thinking in terms of the actual model, which is harder to understand at first but is how the system actually works.
So I think it would be worth, effectively, reskinning git. Instead of starting with commands that seem like the kinds of things people might understand, start with the fundamental concepts of the system and build commands from those. If this system takes a little longer to get up to speed with, fine. Everyone needs a tutorial for git anyway, and they still don't understand it when they're finished. This can't be worse.
Here are the concepts I would use to build my new git frontend, which I have named Dave after a git expert I know:
Objects are the core building block: an object is something that has been added to git and stored in its internal database. An object can be a file, or a directory of files, or even a commit. Objects are stored based on their contents, so if you add the same file a hundred times with different names, it will still only be stored once. For that reason, they have funny names like d3486ae9136e7856bc42212385ea797094475802
Adding a file as an object is not very useful on its own, you usually want it to be part of a commit.
Commands for operating on objects include dave object add file/directory
(adds a new object to the database), dave object list
(shows all objects), and dave object show
(shows you the contents of an object).
Commits are objects that represent some files at a certain point in time. Normally we measure time with numbers, but this gets tricky when multiple people are doing things at the same time. Imagine you start with version 1, and two people separately make new versions, call them 2a and 2b. Which is the real version 2? And how do you get to version 3? To resolve this, we get rid of version numbers, and instead each commit just says which other commits it comes after. Commit WASH_HAIR and SCRUB_ARMPITS can both come after commit TURN_ON_SHOWER, no problem. Then we can add a new commit TURN_OFF_SHOWER which comes after WASH_HAIR and SCRUB_ARMPITS. It turns out that this comes after idea is enough to give us a workable history even without numbers.
Commands for operating on commits include dave commit add
(saves your current checkout into a commit), dave commit list
(shows the history going back in time from the given commit), and dave commit show
(shows information about a commit).
Refs are how we deal with the fact that d3486ae9136e7856bc42212385ea797094475802
is not a very nice name to look at. It's too long and doesn't mean anything unless you're a robot. We want nice short names we can use to look particular commits up, or describe things like "whichever commit is the latest one in production" or "whichever commit Dave worked on last". For these, we use refs, which are just labels for a particular commit that change in predictable ways. There are also special refs like HEAD, which points to whatever commit you currently have checked out.
Commands for operating on refs include dave ref add name [commit]
(makes a ref that points to the given commit), dave ref update name [commit]
(updates the ref so it points to the given commit, but only if that commit comes after the current one), dave ref set name [commit]
(sets the ref to point to the given commit), dave ref list
(shows all current refs)
A Checkout is the connection between the files in your working directory and the files in a commit. When you want to work on a commit, you check it out, which updates your directory so it has the files from that commit. After you make changes, you add them to the checkout so git knows about them. Then you commit that checkout to add it to the history. After that, you will probably want to update some refs so they point to your new changes.
Commands for operating on checkouts include dave checkout update commit
(make your directory look like the given commit, unless that would lose changes), dave checkout set commit
, (make your directory look like the given commit, even if it would lose changes) dave checkout add file/directory
(adds changes from your directory to the current checkout), and dave checkout remove file/directory
(removes changes from the checkout)
All the commands take the form dave concept [verb]
, where the verb is inferred if not provided. So you can say dave object commit
or dave object file
instead of using object add
and object show
. Similarly, you can use dave commit
instead of dave commit add
, dave ref
instead of dave ref add
or dave ref update
, and dave checkout
instead of dave checkout update
.
This may seem fairly similar to vanilla git, and in a sense it is, but consider something like the awful git reset
. If you want to undo staging a file, you git reset file
. If you want to undo a commit, you git reset --soft HEAD^
or git reset --mixed HEAD^
. If you want to update your current branch to point to a different commit, you git reset --hard commit
. The metaphors are hopelessly mixed: "reset" says something about user intention, but "soft/mixed/hard" are about git's internal model, whether you update the index, work tree, or both.
By contrast, you unstage a file (remove it from your checkout) with dave checkout remove file
. You go back to the previous commit with dave checkout update HEAD^
. You update the current branch (ref) with dave ref set branch commit
. The metaphor is consistently about the internal data model of git, with very little affordance for the user's mental model. That may be quite confronting at first, but over time I think it would be far easier and lead to less memorising of arbitrary commands.
Many people would like to get into the super cool sport of FPV drone racing, but camera drones are expensive. Separately, many people have dogs who need regular walking. Can we bring these two problems together and solve them simultaneously? I believe we can, by turning dogs into drones!
Here's the plan: you rig up a microcontroller, a wireless receiver and a servo onto a dog harness with a short boom pole, and some food or a dog toy on the end. Your remote control inputs move the boom pole, controlling the direction the dog wants to run. You can then rig up a standard wireless transmitting camera as well and have full a FPV dog experience. You get to enjoy the thrill of high-octane virtual racing, and your dog gets some much needed exercise.
While this is a pretty tongue-in-cheek idea, I am genuinely curious to find out if it would work.
This is a pretty fun one. I really enjoy Squad's Kerbal Space Program, a space exploration/ridiculous vehicle simulator. While you fly the vehicles yourself, a lot of the heavy lifting in terms of flight control is done by the stock game, and even more by the amazingly sophisticated MechJeb automation mod. But I think it'd be pretty fun to turn that idea on its head.
What if, instead of having to build and fly a spaceship, you had to write a control system for a spaceship that was already built, and would be flown by a simulated pilot? You'd get all the control inputs in, sensor readings, etc, and have to write code to turn that into stable flying. The early levels would be simpler things like pilotless control of a single gimballed engine, but you'd eventually build up to pilot-assisted autopilot of complex multiple-control-surface vehicles. Maybe you'd even have to deal with incorrect sensors or hardware faults.
If it was done right, it could be basically the Kerbal Space Program of control theory, and who wouldn't want that?
I've been thinking a bit about mood boards, a visual inspiration tool mostly used by designers. The idea is that you put up a collage of related images and concepts surrounding something you want to think about. If you do it right, it lets you sort of soak in all these various associations and hopefully make it easier to come up with new related ideas.
That's roughly the idea behind my (currently neglected) idea globe, but I think a more visual form might be interesting to pursue. You could make a big virtual wall with various clippings, images, animations, videos, etc, and have the whole thing iterate and evolve over time. There was an old piece of software called Debris Visual Art that had a kind of similar evolving idea, but this would need to be a bit more, uh, structured.
There are some advantages of this virtual kind of mood board over the physical one. Obviously, the possibility of using video and other dynamic stuff within the panels is one, but I think the real benefit is that the whole thing is dynamic. If your goal is to form new connections and come up with ideas, randomness seems like an important attribute. As each panel changes over time, you would end up with combinations of the mood elements you hadn't considered before.