May 25th 2011

The Goat Inventory Tracker

The year is 1516. The Royal Mail has just been founded.

You’re an enterprising goat farmer. You want to service requests for goats by mail. You have multiple paddocks. Paddocks contain multiple goats.


one of the only two cute goat photos on the entire internet, (c) 2011 abbsworth, used without permission

An order comes in for some goats. You spring into action!

Firstly, you need to select some goats to send out.


For this, you’ve designed a tool called the Goat Inventory Tracker. It deals with all the management aspects, so you can do what you love most; breeding goats.

You decree, Goat Inventory Tracker, Allow Me To Pick From My Goats!

The Goat Inventory Tracker shows you each of your goats across all of your paddocks, and asks you if you would like to include it. If you do, it takes the goat and places it in a pending crate.

When you’re done selecting goats, you can look into the pending crate and check everything is what you want. If it helps, you can preview your shipping log as if you had no outstanding goats.

This is important, as you’re required to maintain various arbitary constraints by the local land baron.


the other only cute goat photo on the entire internet, (c) 2011 Loredana Preston, used without permission

Now that you’re happy, you can decree Goat Inventory Tracker, Seal This Box!

This will, obviously, seal the box of goats, and place it near the post box with a shipping note of your choice.


You repeat this procedure for a couple of days. During this time, loads of boxes pile up near the mail point.

You don’t like mess.

You decree, Goat Inventory Tracker, Allow Me To Rearrange My Boxes!

You are then able to reorder, change the shipping note of, merge, and completely change or split your boxes.


Postman Pat, Postman Pat, Postman Pat and his black and white cat.  EARLY IN THE MORNING, JUST AS DAY IS DAWNING...

Once you’re happy with your outstanding orders, you can decree Goat Inventory Tracker, Summon The Postman!

The postman will arrive, and will then check he can load your boxes into his wagon. Due to safety concerns, the postman isn’t allowed to pile your boxes on top of other people’s boxes, or allowed to re-order other people’s boxes. This means that if he has any boxes in his van already, you’ll need to do some work first.


No worry; you just decree Goat Inventory Tracker, Pile My Boxes Atop These Lowly Boxes! It will.

Sometimes your boxes won’t fit nicely on top of the other people’s, at which point the Goat Inventory Tracker will panic, and you’ll need to reshape your boxes. Remember that the Goat Inventory Tracker has many tools for dealing with boxes, as explained above.

Once you’re done piling your boxes, the postman will be happy and will leave with your boxes, and you have entered them into your account book.


You’ve made some money, you’ve made your customers happy, and you’ve done basically no work. Excellent. Back to breeding goats.
Continue Reading »

2 Comments »

April 22nd 2011

Tiny Windows utilities

I have a set of tiny utilities that I use on a daily basis but have never bothered to release.

All are in the tinies v001 archive, in both x64 and legacy format. Symbols, source and signatures are available. No installer is available; just drop them into your All Programs -> Startup folder.


shiftfocus.exe adds an extra set of hotkeys for focusing windows. Ctrl+win+arrow focuses the window to that side of the current window.

This makes the most sense with Aero’s Snap turned on. If you have two windows “half-maximised” on a screen (i.e. one has been win+left‘d, and the other win+right‘d), then you can switch between them using ctrl+win+left and ctrl+win+right.


topkey.exe adds win+w to toggle a windows’ always-on-top flag, and win+return to create a new command prompt “in the current directory”. (This works for Explorer windows, and things that have the directory at the start of the title, i.e. Notepad++.)


mousex.exe allows you to use an xbox360 controller as a mouse. Different analogue sticks are different sensitivity. A/B for left/right click. Shoulder analogue controls for the scrollwheel.


And, for more niche users:


powerstatustray.exe shows which drives are spun-up, and notifies you when a drive spins up or down. (Yes, actually, this one was released before.)


keydump.exe shows what you can keylog by binding globally to DirectInput. Most keylogging preventers/detectors completely ignore this, and/or only work through blacklisting, which is laughably pointless. It doesn’t bother translating numbers into keycaps, but it’s obvious whether it’s working and whether it’s been detected.


Others, to date:

  • aukiller: Legacy XP application.
  • foobar2000-loader.exe: Demo of pre-loading a dll into an application via the debug api.
  • keytoputty.exe: Take input and send it to a running instance of putty, i.e. to allow input during full-screen applications.
  • loaddlls.exe just calls LoadLibrary on all it’s arguments.
  • noelev.exe: Legacy implementation of setting __COMPAT_LAYER=RunAsInvoker.
  • quickkey.exe: Legacy XP application.
  • unrequireadmin.exe: An even less healthy implementation of noelev.exe.

No Comments yet »

April 11th 2011

Sometimes people really do just want to help…

Late last year we were playing TrickyTrucks.

TrickyTrucks is okay fun single-player, but what really makes it fun is the competition. For this, it has built in scoreboards, per track. Attempting to beat certain people’s times on tracks is the fun.

What it lacks is a cross-track scoreboard, i.e. some kind of championship, and/or notifications of people beating your scores. Even Audiosurf, one of the… most entertainingly engineered indie games recently, got this right.

I implemented one.

After some initial beta testing (and ensuring I was near the top of the championship), I messaged the TrickyTrucks author with the source of the scraper and of the web interface, asking for permission to link to the website on the official forum, so others could join us in competing for the championship title.

An aside, on licensing: Both of these components were released under the BSD. That allows anyone, including the TrickyTrucks author, to use the code for any purpose, including incorporating it into his official website. The component split was done such that there was a neat interface for him to implement on a non-scraper backend. The best result for me would be for there to be an official API and an officially hosted version of the site, such that I never had to do anything ever again to continue appreciating it.

An aside, on development costs: Reverse engineering binary protocols is a nightmare. Especially so with only access to a read client (with no source). Especially so when there’s no way to get the server to return things consistently or with user-specified plaintext. Especially when the protocol has (what you believe to be) NIH compression. Don’t ever, ever try and pay someone to do this unless they really, really want to.

He replied that this would be fine, but only if I removed the link from the website to the source. I, grudgingly (given it was already in the wild), did so and posted on the forum.

His response? Delete the post, and change the server to have some additional, weak protection against 3rd-party clients.

What. The. Hell.

(Eventually he sent me details of an API to use, but I’d lost interest by then.)


This post brought to you by libspotify being incompatible with most 3rd party DLLs, probably due to the copy protection on their DLL. Copy protection. On something that requires a paid account, verified against their server. Please tell them what you think about this on my GetSatisfaction thread (apparently this is what passes as a bug tracker these days).

This prompted me to waste ALL WEEKEND porting foo_input_spotify to libdespotify. foo_input_spotify will increase the value of their product. Why are they making my life miserable? Perhaps it’s unintentional. Time will tell.

No Comments yet »

April 7th 2011

History cleanliness in git

This post is for documentation only. It was going to be a rebuttal to jwh’s Mercurial fanboyism but I realised while writing it and re-reading his post that I have absolutely no idea what he’s talking about, nor can I work out how to get hg to tell me.

Given a repo of:

My proposals for alternatives to this simple workflow are as follows. These all result in the same order of code going into the master branch, but have different histories. (Actually, I think there’s still mistakes in there but I’m tired of staring at the horrible procedural script that generates it, so it’ll do).

1. A flat history, made by rebasing everything on top of master instead of merging:

2. Only merges on master, giving you the illusion of a neat history…

…but, underneath, loads of ugly information available:

3. A hybrid, supercommits, whereby you keep a flat history but you maintain where branches were:

…or, with the history information visible:


Thoughts:

Serious concurrent projects like git itself use the ‘only merges on master’ approach. I strongly agree that they shouldn’t be flattening the history; it’s nice to be able to see groups of patches as they go into master, and to navigate the history of “feature commits”, instead of the history of “developer changes”.

The flat model seems to work much more like how I think about software development:

  • You start working on something.
  • You do your normal develop, commit, developer-test, commit cycle.
  • Master moves on a bit while you’re messing around. The fact that you happened to start developing before a specific commit on master, instead of just after it (so it would be the root of your branch) is reasonably irrelevant; you may as well move the branch-root (or branch point) up to the top of master.
  • Additionally, if you do a real merge, you need to test your changes. This leads to more developer testing, and possibly more commits.
  • What do you do with these commits? Assuming your merge with master is still local you can fix it (this is git, you can fix anything), but it’s inconvenient.
  • When you’ve rebased, you can continue committing on your rebased branch like normal, with confidence that when you merge it’ll all be fine (as it’ll be a fast-forward merge).

‘Supercommits’ is a hybrid of these two; you can use the rebase-onto-master workflow from ‘flat’, but you can logically group your set of commits into a… family? I like this idea, but haven’t really implemented it in practice so can’t really comment.

(Apologies for screenshots of text; I’m lazy, ansifilter was NOT WORKING and it’s prettier than gitk.)

1 Comment »

February 10th 2011

Release anouncement: PatchPiler!

Many people find modern version control systems confusing. PatchPiler offers a new, simpler way to think about version control, offering you far more flexibility than certain other version control systems.

All software development is the creation of patches; small changes to the state of the software. PatchPiler’s command-line tool, papi, lets you manage these patches efficiently.


Like in other version control systems, papi commit adds a patch (yellow) to the existing stack of patches (green). As with any modern version control system, you can have multiple outstanding patches on a pile.


Sometimes you want to be working on multiple things at the same time, say yellow and blue things. For this, there’s papi new-pile.

It lets you name your new pile, let’s call it blue. This means you can pile patches on “blue” while continuing to pile patches on “yellow”. This is amazingly cool. In fact, given that “blue” is completely unrelated to “yellow”, somebody else can be piling patches on “blue” while you continue working on “yellow”.


Frequently you’ll want to copy patches between piles.

papi copy lets you copy a patch from one pile to another.

Something cool has happened in “yellow” and you want in? Just copy it across! The patch is now in both piles, but this is okay, as they’re currently unrelated.


papi re-pile allows you to catch-up with another pile’s entire history.

It just “re-piles” your patches on top of the patches from the other pile. This doesn’t affect the other pile; it’s still a separate stream of development.

Note how it intelligently works out that the yellow patch in “blue”‘s pile was already included earlier on, so it’s no-longer necessary to copy it in.


You’ll notice that the pile named “blue” now has all of the outstanding patches; this brings us on to the last command: papi bless marks changes as complete and removes any unnecessary piles.

This results in a nice, clean pile of patches, leaving you ready to continue developing. The possibilities are endless!


Continue Reading »

No Comments yet »

January 29th 2011

UWCS Progcomp Chain 6, Results

As a continuation of bucko’s progcomp chain, I set Progcomp 6.

The objective was to walk your way through a “maze” with huge constraints to make the problem simpler.

I believed the simplest solution to the problem was graph search with backtracking. My inefficient implementation (with debugging) of this is unbelievably fast; it can solve a 300×5000 map (>100 times the size of the original problem) in around 2 seconds. The map generator ensures there are no problems set with trivial solutions (i.e. going in a straight line all the way down the map). I thought that the effort of solving it by hand within the (6-second) time constraint would require far too much UI work, so keeping the problem size small enough to fit on the screen was fine.

I was wrong. So wrong.

bucko’s Perl solution was first, after 15 minutes, with a tree search implementation. While easier to implement, this is much slower.

I’d carefully designed the page, submission process and timeout so that people who found curl / wget too much effort could submit the solution by copy-pasting; I could copy the result from the page (without the IE-only JS’ assistance) into my solver, solve it, and copy the result back in ~5 seconds; hence the 6-second timeout. bucko’s solution sometimes doesn’t finish in time, even on these tiny maps. It’ll never finish on the huge map.

fice was second, after 21 minutes. Algorithm / code unknown, although I’m guessing there was auto-submission as no User-Agent was set.

Queex (outsider!) was third, after about 50 minutes, with his Java solution. He decided the problem wasn’t complicated enough to write a “proper” solution for, and went for just trying to jiggle away from the edges. Obviously it works fine, and I have no idea how to harden the map generator against it, except perhaps forcing you to go from the left edge to the right edge at least once. It can only solve some of the maps, but this isn’t important as it was a “solve once” problem.

Next up was Afal’s js solution. He (correctly) guessed that the map generator only generates large walls every 10 spaces, worked out which side it was, and jiggled away from it a bit. Apparently works most of the time. Again he uses an in-browser implementation to avoid having to do any page parsing or post rubbish.

Afal then decided to submit 62,000 other solutions, which has made my log huge and writing this a pain. Such a penis. Such a penis.


At this point an hour had passed and I turned the debugger on; when you die it tells you where and shows you what you submitted, etc.

james was next, with some more jiggling Java, and a shell-script wrapper.

MrWilson then submitted a travesty. It generates random solutions and assumes loads of things about the map. It works in nearly no cases. I don’t know how he can show his face in public after this.

Connorhd duplicated bucko’s solution in php.

sadiq, tom, Softly, Trencha and Steve Brandwood also had a correct answer.


Meta: I wrote my own solutions website instead of using bucko’s. I got the logging all wrong. I got the map size all wrong (not realising how lazy everyone is).

It took me about 90 minutes to do the map generator and my solution with debugger, and verifier. Another 90 minutes was spent on the website. That is, a ~3 hour time investment for causing hours of suffering and an entire night of entertainment. Totally worth it.

Next up is bucko’s progcomp chain, link 7, but tom still owes us a progcomp.

3 Comments »

« Prev - Next »