The best kittens, technology, and video games blog in the world.

Sunday, July 28, 2013

SwiftKey for Android review

Solea's Time... by ERIO from flickr (CC-NC-SA)

One of the reasons I've been reluctant to get a smartphone in the past is that it's pretty difficult to type on touchscreens. Input method was always my priority when it came to phone choice - I never got anywhere near keypad typing, and by previous phones all had either stylus-based virtual keyboard (which is actually fine since stylus tip is tiny compared with a finger), or an actual physical keyboard.

So even after I gave in and got myself a Galaxy S4 the first thing I looked for was better input methods.

Good things about SwiftKey

SwiftKey is a paid app, but it comes with a month trial period - reasonably long to learn if it works for you or not.

Unlike with all the predictive text methods (and for that matter all spellchecking) I saw, it can support multiple languages (English and Polish) without switching between them in menu all the time. It just tries to figure out the language from context and is pretty happy to switch it in the middle of text if you need it.

This was always hugely annoying and it's a proof that Americans with their massive single language bias should stay the hell away from designing any software having to do with languages. The world differs from Murica not in people using a single non-English language - it differs in people using multiple languages. I know, shocking, right? (SwiftKey is London based - in UK people are more aware that non-English languages exist).

At least for English it's pretty reasonable most of the time, and it's very easy to fall back to manually fixing the word if it doesn't get it right.

SwiftKey also doesn't try to censor every ducking thing you write, unlike some other predictive text systems I won't mention.

Bad things about SwitfKey

One very bad but easily fixable thing is long touch delay for punctuation. If you need some punctuation like "://" you long press the letter key on virtual keyboard corresponding to particular symbol - but defaults are just insanely slow. Yes, it's easy to fix it, but then if that excuse worked we'd all be using Emacs, right?

A more annoying problem is that it's not very context aware. For example if you try to type URL it will likely contain whole words. So you type one word, then second word, then ".com" and done, right? Well, not so much because SwiftKey "helpfully" inserted spaces between the words for you and now you need to go back and fix them. It really needs some concept of contexts where spaces should not be included.

And second big problem is quality of Polish language support. Unlike with English where it has decent success rate, Polish support barely even gets half the words right - and when it doesn't it's very difficult to correct it yourself with proper Polish diacritical characters.

Overall, it's a 4/5 for English, 3/5 for Polish. Much better than I expected from touchscreen devices (I expected regretting ever buying a touchscreen phone), but it's still nowhere near good enough level.

Saturday, July 27, 2013

Distributed dotfile management with Dropbox

Lucas by End of Level Boss from flickr (CC-NC)

Managing configuration files across multiple computers is hard - especially if you can't rely on any one of them being constantly online (the Linux home server setup from the 90s).

As far as I know nobody ever published a fully satisfactory solution to this problem. In this post I'll explain my setup - it's not perfect, but it's flexible, solves most of the problem, and is very easy to setup.

The system I'll describe will work with any combination of Linux and OSX computers, and also has enough reasonable enough support for Windows machines and smartphones.

~/everything

First, you need to designate one Linux or OSX box as master. It doesn't have to be always online, or even always on, or even your most frequently used machine - any box sitting safely at home you use (directly or via ssh) at least once a week will do perfectly fine.

On this machine, create a git repository for all the things - I call mine ~/everything.

Within this repository create ~/everything/bin for all your scripts. I'd strongly recommend making a public repository for some of them like this one, but usually at least some of the scripts will be too specific to your setup or too private to Open Source.

Now create ~/everything/dotfiles and ~/everything/dotfiles/boxname for each one of your Unix boxes.

You could also create a lot of small git repositories, but I find single repository setup more convenient here. And for that matter I find that people create far too many git repositories for things which belong together in a single one as a general rule, but that's a different story.

Install Dropbox and first round of symlinkery

The next step is installing Dropbox on all machines - making it sync ~/Dropbox directory. For now we do not want any of the dotfiles or scripts or other stuff to live there directly.

Now create symlinks on your master box from ~/Dropbox/bin to ~/everything/bin and from ~/Dropbox/dotfiles to ~/everything/dotfiles.

This is the key, since on all other machines they'll look like regular directories containing regular files, but on your master box the files will reside within your git repository, but will still be managed by Dropbox.

You do not want to put the whole git repository with .git stuff on dropbox, or symlink directly to a repository (which would make Dropbox manage your .git). That's not supported scenario for git, and it might bite you hard at some point.

Symlink all the ~/bin

Now on each machine create ~/bin directory and add it ot your $PATH. Do not put any actual files there, just create symlinks from ~/bin/somescript to ~/Dropbox/bin/somescript for each script you want to include.

Or simply add ~/Dropbox/bin to your $PATH if you don't need per-script setup.

The most common reason for wanting different scripts on different boxes is Linux vs OSX issues, and this can also be solved with ~/Dropbox/bin/linux and ~/Dropbox/bin/osx directories, selectively added to $PATH

Dotfiles

Now the fun part. On each machine for each dotfile move it to ~/Dropbox/dotfiles/boxname/.whatever and put a symlink in place of the original.

Notice how you can edit any machine's file on any other machine - and it will not only automatically update, it will also automatically update in the git repository.

Now every week or so you should login to your master server, wait for Dropbox to finish syncing, and then add proper commits to keep history of your changes.

Windows support

There's good news and bad news.

The good news is that most Windows applications let you select path for their stuff anywhere - so you can point it to c:\Dropbox\someapp or wherever you want. In the Unix world it's much more common to simply enforce some path, and if you don't like it - use symlinks.

The bad news is that while Windows has some kind of symlinks (and I'm talking real symlinks, not .lnk files it uses for "shortcuts"), but they only work one way with Dropbox.

Here are instructions how to setup Windows symlinks. Dropbox will push data to such symlink, but it won't track data changes on the other side of Windows symlink - so if you want to push data from Unix machines to Windows, such symlinks are good enough, if you want to modify them two-ways unfortunately not so much.

Fortunately you can still get two-way updates if you leave the files in c:\Dropbox\windows\stuff directory, and then symlink from c:\someplace\else to c:\Dropbox\windows\stuff.

You could even have a very fancy system of symlinks to get it all. On master: ~/Dropbox/windows/stuff symlinking to ~/everything/windows/stuff, then on Windows c:\some\place symlinking to c:\Dropbox\windows\stuff.

And everything else

Phones don't use dotfiles directly, but you can use Dropbox to store any .apk files you want to install, photos, and other such stuff.

With this kind of symlinkery you have a lot of flexibility - you can designate different masters for different parts of your dropbox, use different path names, any number of repositories and so on.

It helps with backups a bit too - since all your dotfiles are synchronized in a single git repository, you just need to snapshot your repository on one box for monthly backup (or however often you do it) instead of gathering files from a lot of boxes.

Dropbox is also sufficiently aware of file permissions that you can use it for somewhat sensitive information like low value private keys and so on. Highly sensitive information needs much better protection than that of course.

I mentioned some other uses of Dropbox in my previous post about it, so I'm not going to repeat it now.

Master Rakefile

One small technique that's somewhat related to all that is having master ~/Rakefile with all the common tasks you need. It would of course be a symlink to ~/Dropbox/dotfiles/boxname/Rakefile, which would be properly source controlled and so on.

rake searches for Rakefile up, so you'll have full access to all rake commands even when you're in ~/Downloads/my_little_pony (unless of course you have ponies-specific Rakefile).

Now the task I recommend setting up is searching your entire home directory for everything that's not supposed to be there. For every file, unless it's one of:
  • symlink - OK (into Dropbox or elsewhere managed)
  • empty directory - OK
  • git repository - make sure to git fetch -p, then OK if clean and on master branch
  • on whitelist as known garbage (Unix programs make a lot of them)
  • on whitelist as Dropbox directory, or something else non-garbage that you want to be there
  • for some nonempty directories you want to apply this rules recursively to their content, not to the directory directly. For example ~/Downloads, ~/Desktop, and ~/Documents with probably have some empty subdirectories, ~/bin will have symlinks etc.
Then it's a problem that needs to be dealt with.

This kind of zero tolerance for crap policy is natural extension of GTD inbox zero concept. It's really difficult to get started, but once you get used to it, you'll probably thank me. If there's enough interest, I'll write a post on how to make such Rakefiles and what to put there in the future.

Saturday, July 20, 2013

Introduction to Data Archeology

A lot of data is in open or otherwise maintained formats - which you can access directly or use one of existing converters to work with. But sooner or later you're going to run into some completely undocumented format created just for a single no longer maintained software for which you have no source code, documentation, or tools of any kind.

Especially when you want to mod video games - which are pretty much all one-off no longer maintained programs with no source code, documentation, or tools of any kind.

If that ever happens - it's time to put your Indiana Jones hat and start some good old Data Archeology!

The most important fact about Data Archeology

The task might seem insurmountable at first - you're given a huge stash of undocumented binary (usually, I'll deal with text files or executable code later) files and task to make sense out of them, and at least extract data - or even better write tools to modify them.

Fortunately there's one thing helping you:
Data formats weren't designed to make your job harder - they were designed to make original developers' jobs easier.
Hypothetically the data could be completely crazy - it's not that much more difficult to use 22-bit middle-endian integers, strings encoded in backwards UTF-7, and interleaving members of the same struct one byte at a type. In practice you'll be seeing the simplest possible encodings 99% of the time because they get things done just as well.

How to get started

The best way to start is just getting some hex editor - 0xED for OSX is pretty good, but then so is plenty of others (feel free to recommend them in comments). Then open some data files and look inside.

There are two ways to look at files - bottom up and top down. Usually it's easier to start with a bottom up approach first. At this point you don't want to decode anything, just identify some patterns how data is encoded, and get an idea what the file is for in case that's not yet obvious.

Going bottom up

Here are some of the things you could look for:
  • Are there obvious strings in the file? Usually they're either ASCII (or derived encoding), or UTF-16. Usually they are either terminated by a 0 byte like in C, prefixed by number of characters or bytes (with length encoded in 8 or 16 bits), or padded with 0 bytes or spaces to some predefined size, but they could be something else.
  • Do you see any small integers? Are they 8, 16, or 32 bits? Little or big endian?
  • Can you see any floating point numbers? For PC games they're usually 32 bit (float), less commonly 64 bit (double). You'll probably need help from your hex editor to see them. Are there any obvious pairs or triples which could be 2D or 3D coordinates?
  • Does the file has obvious header at the beginning? Some kind of section headers within the file?
  • Do you see embedded text files, XMLs, or other formats?
  • Do you see anything which could be a file offset, or data size? These will take a little practice to recognize - and it helps to have file offsets and data decoding in your hex editor set to the same setting (either both hex or both decimal). File offsets are usually 32 bits, data sizes can be 16 or 32 bits, but it could be something else.
  • Are there any repetitive patterns like common data structures? Strings or file offsets in the file make it relatively easy to notice patterns, otherwise it's usually a lot trickier.
  • Does the file contain a lot of data that's not obviously decodable as something already mentioned?
You're not trying to decode the entire file at this point - just get a sense of what kind of data is inside, and how it's encoded.

For bottom up analysis it's best to pick a variety of highly complex samples of the format - the more complex and bigger the data, the more likely you'll be to find something useful there.

Bottom up - example

Let's take a look at groupformations.bin file from Empire: Total War.


We open the file - and from abundance of 00s everywhere it's clear they didn't bother encrypting (or more like obfuscating, usually), compressing, or optimizing it too much. We can get straight to the good stuff.

The first thing that should be immediately apparent are UTF-16 strings - "Multiple Selection Drag Out Line" and "Single Line Standard" (highlighted red). Just before each of them there seems to be a small little-endian int16 number (highlighted green) - it doesn't take much guessing that it's probably number of characters in the string. We already have something.

There are a few things that look very much like small little endian int32 numbers (highlighted blue) - FF FF FF FF block is pretty clearly -1 (unless it's two int16 -1s, but that's much less likely). The one at the beginning of file just before the string looks like int32 too. Could that be number of records in the file, size of something, section id? We'll figure that out later.

It seems everything is aligned to 2 bytes. There's no guarantee we won't find something that breaks the alignment, but that can save us some guesswork. It also seems that things are aligned to 4 bytes, but presence of dynamically-sized UTF-16 strings suggests any string with odd number of characters will violate 4-bytes alignment. You can scroll down the file to check if alignment is consistent everywhere - if it is, it will save you some time.

There are a few stranger things. What's that "00 00 80 3F" (highlighted yellow)? If you move your cursor there with your hex editor it will tell you it's a 32-bit floating point number for 1.0. Once we establish there are floats there we can guess that "00 00 00 40" a bit further down is probably floating point for 2.0, not alignment-violating integer 64 (hex 0x40).

We can also take advantage of negative spaces - the "01 00 00 00" between "FF FF FF FF" (-1) and "00 00 80 3F" (1.0) we already decoded could be a few things - but since it's exactly 4 bytes and everything else seems to be 4 bytes long int32 number 1 seems like the most obvious interpretation.

This is a really good start. The file seems to consist of only:
  • UTF-16 strings (with 16-bit character count prefix)
  • 32-bit little endian integers
  • 32-bit floats
We don't quite know how they're structured yet, and what they mean, but we're up for a good start.

Top down

The second approach is going top down. Instead of trying to figure out bits and pieces of data we'll try to figure out how the data is organized.

For top down analysis it's best to start with a few very simple files - the simpler the better. Hopefully you'll see all the structural elements like headers, timestamps, checksums, and whatnot without actual data getting in the way.

Once you're comfortable decoding the simplest files try your understanding on the next slightly more complex one - it probably will need a few tweaks to work. Then keep adding more files to your test set.

You can either test your understanding manually with pen and paper - or by writing a converter program. I'll cover writing converters (it's much easier than it sounds) in some future post, for now let's do good old pen and paper conversion.

Top down - example


Let's try decoding much more complex target - Empire: Total War db files. It's actually not a single format, but a group of somewhat related formats.

Looking for the simplest case we found a db file with just 5 bytes. Let's look inside.
5 is a strange number and there are two reasonable way to interpret this data - it's either "01" (byte 1 - highlighted green) followed by "00 00 00 00" (int32 0 - highlighted red), or "01 00 00 00" (int32 1) followed by "00" (byte 0).

The answer is not obvious yet, so let's look at some slightly more complex file. We found one with just 27 bytes.
First, the mystery from the previous file is solved - "1 (green), 2 (red)" is much more likely combination that "513, 0". The rest of the file is two length-prefixed UTF-16 strings - first in yellow, second in blue.

That gives us a pretty decent theory of how db files are organized:

  • mysterious byte 01
  • number of records as int32
  • record 1
  • record 2
  • ...
We still have a lot to discover:
  • What's the mysterious byte 01? (it turns out it's a schema version number - but with funny encoding)
  • How can we know what kind of data is in records (it turns out every db table has different record types)
  • What these records actually mean? (that's a lot of detective work, but it's much easier after you decode the data into spreadsheet or text file)

Writing converters

The final step is writing a converter. If you managed to completely figure the format out with pen and paper this is really straightforward.

Unfortunately most formats are too complex to decode them by hand, so learning about the format and writing the converter will have to be done simultaneously.

And again, there are two ways to go about writing converters - bottom up or top down.

In top down approach, you write a converter that tries to decode the file completely, and throw increasingly complex files at it, modifying it as you go. This is relatively easy, since you have a working converter (for simplest of the files) very early, and you can be sure you're not breaking things by rerunning it on the same simple example even once it gets support for more complex formats. The downside is that it's an all-or-nothing approach - if the format is too complicated to decode fully you won't get even partial information out of it.

In bottom up approach you teach converter how to detect partial data structures (like strings, floats, etc.) and then to skip parts of the file which it doesn't understand. This can be very powerful technique - especially for very complex formats where full decoding is not yet possible. Unfortunately it's usually much more difficult to write such converters, so it's an advanced technique to try only after you get some practice with data archeology.

Coming next

In future blog posts, I'll show you how to easily write such converters to decode a few file formats.

Or if you can't wait, you can check etwng repository, with a lot of converters for various formats from Empire: Total War and other games from Total War series.

Thursday, July 11, 2013

How not to design game mechanics: Lessons from CK2 combat system

The overcaffeinated Fail Bear by quinn.anya from flickr (CC-NC-SA)

I'm in the tiny minority of gamers who enjoys Paradox games. I often enjoy quite a lot of complexity in games I play - some of them like Magic: The Gathering are among the most complex games ever created (Magic's Comprehensive Rules are about 200 pages, and then add to it over 13,000 cards), and I just love discovering unusual interactions between disconnected parts of the ruleset.

Complexity in games can be not only fine, but amazing. On the other hand quite often it backfires horribly, and one really good example of such misuse of complexity is Crusader Kings 2's combat system.

How does it work

Here's a quick summary of just major CK2 combat elements by coanda. It doesn't really cover half of it like sieges, morale, army recruitment and upkeep, traits you can get in battle, chance of death during battle and so on.

Even that limited part of combat system looks really interesting at first - different unit types, multiple combat phases, interactions of different tactics, commander influence with separate commanders on each flank. Well, sure, there's the usual complaint that none of that is explained anywhere, but that's just the way Paradox games are. That's not the real problem.

The real problem is that nothing about the combat system translates to meaningful player actions.

Wait, what?

Different unit types are good against different opponents? Too bad, your demesne army is just a random mix of all unit types. Your vassals' levies? You have even less control over these mixes. Mercenaries? Almost the same story. You have a lot more control over your retinue, but then retinues are just overpowered without needing any special tactics and if a mod nerfs them down to reasonable size (like just about all of them do) they'll no longer affect your army composition significantly.

Different commanders having modifiers for unit types? Too bad again, all armies are just a random mix of everything, so it doesn't matter who you assign to lead whom.

Using terrain to give your mix of army advantage over opponent? (different unit types have different bonuses depending on terrain) The bonuses are pretty low and armies on both sides will be fairly similar mixes so it just turns into general terrain bonus equal to about their average.

And even if by some change you have perfect commander for your mix of troops - it still won't matter all that much, since he's only 1 of 3 commanders.

Basically everything a player can do other than:
  • having bigger army
  • appointing commanders with higher stats
  • defending on difficult terrain
is nearly completely worthless because hundreds of positive and negative bonuses that different parts of player's and opponent's armies get for these fancy things end averaged up to approximately zero.

The result of this highly complex system is that it leaves all players feeling that "bigger army wins" and that's they need to know.

Simple grokable systems are the answer

Meanwhile EU3 had far simpler combat system - one commander, three unit types (infantry, cavalry, and artillery - all with tech-dependent fire, shock, and morale stats), everything expressed as straightforwardly additive numbers. 

And even though EU3's system was so much simpler - it led to many interesting interactions and it wasn't outside realm of possibility to defeat armies many times larger than your own by taking advantage of the system. (with navies even more spectacular victories were achievable, but AI stupidity also had a lot to do with it)

CK2's complexity doesn't lead to wonderful scenarios like "I'm going to bait French knights harrassing them with my light cavalry, then my spearmen will ambush them in hard terrain and finish them off easily" (the kind of stuff that's so common in all Total War games) - it leads to everything getting so mixed up that it's provides far fewer actionable options than EU3.

For contrast take a look at arumba's Clear Combat mod - it basically rips out the entire tactics system out of CK2 and replaces it with a very simple system based on just commander's martial ability. Does that reduce player's ability to do interesting things? Hardly! Unless you're playing with Mongol event troops (85%-cavalry army, and most of that horse archers) or some other event troops, you can basically do all the things you did before and they'll have pretty much the same effect, except now it's all much simpler and better presented.

Complexity is not a value in itself

Complexity in games is valuable if there are ways to interact with it - if it's just an excuse to roll a thousand dice behind player's back and average the results then its existence is completely pointless.

There are so many ways to turn CK2 combat system into something that players can interact with, and much simpler at the same time. Here are just the first few ideas that come to mind:
  • Group troops in armies by type, not by levy origin. Then you could rearrange them on flanks the way you want and assign appropriate commanders to each unit type. (possible impossible to mod)
  • At least have mercenaries of just one or two unit types, with big culture specific bonuses (like retinues) so you can use them this way. (that should be very easy to mod)
  • Have very large terrain modifiers to different terrain types, so with even slightly more cavalry-heavy army you'd really want to stick to plains, while your slightly more infantry-heavy opponent would really want to stick to heavy terrain. (not too hard to mod, but AI will probably have no clue)
  • Give different unit types very different uses, for example cavalry can't siege (like in EU3), only light units can loot. (probably very hard to mod)
  • Have primary commander much larger impact over the entire battle, instead of just 1/3 of it. (I'm not sure how that works exactly)
  • Have commanders or terrain or something else controllable strongly determine length or importance of battle phases. For example in forest you have no skirmish, just instant melee, on plains skirmish is twice as long, or something like that. And I don't mean insignificant 10% bonus, but something that would make a big difference. (not sure how moddable that would be) 
  • Have an option to just harass enemy then flee. If your army is mostly light cavalry and horse archers, and their is mostly melee infantry that should let you bleed them a little at little cost then flee without actually losing the battle (and war score). Of course there should be a chance of this failing miserably if your commander is bad. (this looks doable with some heavy modding within existing tactics system)
  • Just throw the complexity away like ClearCombat and put it in some other part of the game where it can be interacted with.

Sunday, July 07, 2013

Shellwords.split technique for Ruby scripting

Stella Doo by moriza from flickr (CC-BY)

I write 100% of my shell scripts in Ruby (by the way, here are some of the scripts I wrote). If you prefer Perl, or Python or something else relatively sane, all power to you - but people who write complicated scripts in bash are certifiably insane.

One of many problems of using bash for scripting is how difficult it is to keep data properly quoted - even writing SQL by string concatenation is far easier to do safely, and we all know how that usually ends.

Unfortunately while everybody knows that building SQL by string concatenation is crazy, doing that in bash is somehow still practiced widely, and what's worse - even people who know better than that and use a sane language often revert to many awful and insecure bashisms.

How not to code

Let's start with a simple task. User has some EDITOR variable set. We have some files. We want to edit them with user's favourite editor.

Plenty of people who suffered from being exposed to bash in their youth will write code like this:


    system "#{ENV['EDITOR']} #{files.join(" ")}"

And such code is going to fail miserably if files have any spaces in them, let alone any unusual but perfectly legitimate characters like "lol.txt\nrm -rf /".

One step towards sanity

People who know better are aware that system command takes multiple argument, so you can pass files separately:

    system ENV['EDITOR'], *files

This is not only far safer it's also much more concise. There's only one little problem - unlike in the unsafe version EDITOR is now restricted to a single command - user can no longer select mate -w to be their editor, since that's the name of the executable.

If you intuition is to do something like *ENV['EDITOR'].split(" "), please don't since that's just opens another set of problems.

Shellwords to the rescue

Fortunately a solution to all these problems is easy:

    require shellwords
    system *Shellwords.split(ENV['EDITOR']), *files

(In case you didn't know it yet, Ruby 1.9 and 2.0 lets you use multiple * in the same method invocation.)

And that's all in today's lesson.

Amazon delivery options miss the most important information

Just look at this and tell me what's missing:

It has all the fancy options on how fast to get your order, how to group them, and even lets you sign up for free trial of Amazon Prime.

What's missing? Any indication of how the packages will be delivered - by mail or by courier. This matter quite a lot since packages sent by mail I can pick up from the post office any time I wish, while courier packages are a huge pain in the ass to get if courier misses me.

Meanwhile all the delivery time estimates are just estimates, and as often as not package will come earlier or later than the estimate anyway.

Seriously Amazon, you can do better than that!

How to make magiccards.info even better

Chipmunk Checking Email by Stewf from flickr (CC-NC-SA)

If you play any Magic: the Gathering even semi-seriously, you'll need a card search engine. There's an official one by WotC - Gatherer - but it's overall miserable.

Fortunately some good people created a far superior alternative of magiccards.info. It's not only a good search engine, it should be a mandatory study example for anyone who makes search engines for advanced users.

All advanced functions are converted into simple text options key:value, and there's a lot of leeway in how the values are parsed - so these keys are easy to discover (by using advanced search), and after a few times using advanced search you'll be using even fairly fancy queries comfortably.

Anyway, however great magiccards.info is, it is not without problems, so let's talk about them.

No syntax for searching blocks

If you want to search all cards in Return to Ravnica block you need to type (e:rtr or e:gtc or e:dgm). That's not horrible for new blocks, but for many older blocks you might not remember codenames of individual sets or they might get fuzzily matched. It's a pretty obvious and simple functionality to add.

Reminder text is treated as part of Oracle text - sometimes

This is basically a bug, and a really annoying one.

How do you search for all green flying creatures? c!g o:flying t:creature right? You wish! Instead it will also include cards with word "flying" in reminder text - as in "Reach (This creature can block creatures with flying.)" usually.

So how about adding -o:reach to exclude that? Nope, some flying creatures have reminder text of "Flying (This creature can't be blocked except by creatures with flying or reach.)".

Of course only some creatures with reach and flying have this reminder, and often there are multiple printings of the same card - some with reminder text, and some without.

Basically the only right thing is to not include reminder text in o: search ever.

It shouldn't be too hard to fix with some straightforward regexpery, since reminder text is typically parenthesised.

That was the only thing that ever made me seriously consider using Gatherer, but suffers from the same problem.

Name search includes non-English cards by default too

Here's a search for "penumbra" cards. That's a very specific mechanic (green creature which leave identical except black token when it dies) and all the cards have "penumbra" in name. Except in addition to 4 correct hits we have 5 completely spurious hits for foreign names.

There are pretty much zero cases where anybody would ever want that, especially since other functionality like o: doesn't work for non-English cards anyway. Sure, leave these foreign cards somewhere, but they shouldn't be a default.

Edition order as implemented makes no sense

90% of the time what you want is ordering cards by their edition - that's how they logically belong together, by sets, blocks, or design philosophies which change with time - and most people play Limited or Standard so they care for new cards far more than for old cards. It's bad enough that sort by name is the default.

What's even worse is how supplemental products are included in the search order. Let's ignore Modern Masters since that's a very special case, but for reprints in just about everything else like Duel Decks, Planechase, Commander, and other supplemental products nobody cares what they reprinted there.

The only sane thing here is to treat all supplemental products as older than all regular products.

Conclusions

I guess I should actually report these suggestions to whoever runs magiccards.info, but blogging first is more fun ;-p

Saturday, July 06, 2013

I'm moving back from Google+ to Blogger

Morse - Walrus by Gattou - Lucie Provencher from flickr (CC-SA)

As you might have noticed, this blog hasn't been very active recently. I never went offline, I was just using Google+ as microblogging platform.

Unfortunately the truth is - Google+ sucks as microblogging platform. Old posts are unsearchable and get pretty much lost as soon as they drop off the front page, there's no way to put any formatting there, and there are a lot fewer people on Google+ than people on the wide Internet who can stumble upon this blog.

And then the Pinterest+ redesign was the last straw.

I'm not quitting Google+ - it's still OKish for random link sharing and a few other thing - not great, but I don't know what would be better (the once great delicious got pretty much killed by Yahoo). My current plan is to use this blog more (and mostly write shorter posts than in the past) and use Google+ less.

In case you're interested, here are my Google+ posts. There's a lot of good stuff there, even if it's hard to search.

Online Education and Udacity HTML5 Game Development course

cuteness by davedehetre from flickr (CC-BY)

Online education has pretty huge potential to revolutionize the world the same way Wikipedia did a few years back, so I've been trying to keep up with what's going on there. So far I'm not exactly impressed, but that's how the future starts.

We haven't figured out the best format for it yet, and there are different approaches. The most basic one is just throwing videos and exercices at people like MRUniversity, and a huge number of youtube channels do. That's pretty limited, since the thing that's most useful to learn are skills not raw information.

Then there's Khan Academy, which mixes really nice short lecture videos with interactive exercices. This might be pretty useful for beginners, but they currently seriously lack any kind of advanced material which would be more interesting to me.

Then there are all the sites for learning foreign languages like DuoLingo, which are worth checking. By the way, if you want to learn Japanese writing, check my awesome game for it.

Anyway, Udacity offers free courses fairly similar to how Khan Academy works, except they're a bit more structured and also cover more advanced subjects, so I thought I'd give it a try as well.

HTML5 Game Development course on Udacity

I've been taking this HTML5 Game Development mini-course on Udacity, more to check how udacity approaches online education than due to subject matter.

I feel this Khan Academy/Udacity learning format - a mix of short videos and short exercises you need to pass to progress - has huge amount of potential. Videos themselves are pretty decently done, they're fairly informative and concise, even if they have a bit less personality than Khan's videos.

The huge problem is the quizzes. They're filled with far too many ambiguities and even outright errors, and most exercices are about "WTF did they mean" than any actual coding, let alone gamedev. You don't really get much useful feedback other than pass/fail, and console.log is only marginally helpful.

I don't know yet if that's just one course I was unlucky to choose first, or if they're all like that. I'm somewhat interested in checking Functional Hardware Verification and Introduction to Parallel Programming at some point as well - hopefully they'll be better executed.

It would be nice if Udacity had some kind of star rating for courses so you can avoid bad ones.

HTML5 Game Development

And while I'm on the subject - please do not develop anything the way they recommend.

Javascript without jQuery (and with fake class-based OO instead) is just a sad sad language. Just use jQuery always and without exception for all your Javascript needs, and don't pretend it is Java.

Even then, HTML5 canvas API really sucks compared with good old PyGame from ten years ago. Perhaps some heavy wrappers could make it less painful, but I haven't really found any yet.

And in vague relation to that - APIs for all game programming libraries I've checked for Android also really suck compared with good old PyGame. Even Python-based kivy feels somewhat off, but that might simply be not being used to it yet. jrpg for phones will probably have to wait a bit.

Dropbox as solution to minor inconveniences

Just Too Cute! by Bill Gracey from flickr (CC-NC-ND)
I'm sure most people reading this blog have multiple computers and computer-like devices (like phones, Raspberry Pis and whatnot). This comes with a huge deal of minor inconveniences - files are often on one of devices but you want to access them somewhere else.

Traditional solution was imperative file transfer - there's always some way to order a computer to transfer a file somewhere else. There's a ton of issues with this since computers are not always turned on, they're not always on networks, file transfer fail, in many cases you want to edit the same resource from different computers at different times and still want just one canonical representation of it.

Here comes Dropbox (and similar Cloud-based solutions) - its biggest innovation is replacing the imperative paradigm with declarative file transfer. You link a directory like ~/Dropbox with your account, you add, edit, and delete files and directories within it any way you like, and without your effort to babysit all that Dropbox takes care of it to make sure your ~/Dropbox directory everywhere else also reaches such state.

This solves a lot of issues like:
  • You want to keep .dotfiles across multiple machines in some single versioned repository - you can solve that with Dropbox and some symlinkery (or a private github account and some symlinkery).
  • You want photos you make on your camera available on your computer - at the phone should do the uploading whenever you're on some wifi, without your intervention. Dropbox completely solves that problem.
  • You play a game like Cockatrice on multiple machines and you edit your decklists on multiple machines. Manually sorting out which decklist is the most recent one is pretty annoying - but Dropbox does that for you.
  • A simple todo.txt file is pretty awesome if you're moving between computers a lot, even if it's obviously not a full GTD solution. In the past I did silly things like making gmail drafts for that, which I then accessed from multiple places.
  • You want to write a quick note for action later, but you're somewhere outside with no paper? Simply open Dropbox directory on your phone, create somefile.txt, write whatever you wish there, and you'll get it on your computer for later access automatically. There's no way to forget about it.
  • For that matter simply transferring files between computers not on shared network can be a big pain in the ass. For small files people just send emails to themselves with such files as attachment - and it's another problem Dropbox solves completely.
Ironically the only one problem that Dropbox is really horrible at solving is backups.

By the way, Dropbox gives away a lot more space than it seems at first - my free account was 2 GB initially, but they just increased that to 51.25 GB for simply connecting a few boxes and a phone to it.

Basically, the only two reasons you could have for not using Dropbox is:
  • you only ever use 1 computer and 0 smartphones (pretty unlikely if you're reading this blog) 
  • you use another Cloud storage service like Google Drive (with drivers installed on all your boxes)

Friday, July 05, 2013

Digg Reader as Google Reader replacement is disappointing

Cute slow loris by snowflakegirl from flickr (CC-BY)

Since Feedly disappointed me I gave Digg Reader a try. In case everybody forgot already, Digg used to be something like Reddit, except with much more frequent corporate-driven redesigns - and one too many of them killed the site. Meanwhile Reddit is getting more popular than ever proving that simply not breaking what's working in corporate redesign spree gives you a lot of competitive advantage.

Anyway, Digg Reader is currently completely unusable:
  • There's no "Show only unread items" mode. Seriously.
  • Items are ordered by their timestamp, not time of arrival on the list - so they routinely arrive on page 2 or 3.
  • To make matters worse, Digg Reader doesn't update as often as Google Reader, so arriving way down is a pretty common problem. And even if that wasn't a problem low update frequency is just very annoying.
  • There aren't even any counts of unread items per feed.
I expect they'll fix these issues someday, but for now it's literally unusable, and I'll be testing another RSS reader next. Probably expect a few more posts like that in the future.