Planar Chaos Prerelease

Today I head-judged the prerelease of Planar Chaos, the latest Magic: The Gathering expansion. The prerelease at the FUNtainment Game Center here in Berlin was attended by 71 players, a fairly disappointing number after the strong Time Spiral prerelease. Some people blame The Burning Crusade, the latest World of Warcraft expansion, out this week. Personally I also think the traditionally weak month of January plays a fairly important role.

Speaking of World of Warcraft: One of the most funny cards of the new expansion is Ovinize, the color-shifted version of Humble. It allows you to “sheep” a creature, essentially remove all its abilities temporarily. One the one hand this resembles the old card Ovinomancer, which created Sheep tokens, on the other hand it plays with a similar concept in MMORPGs like World of Warcraft.

The color-shifted cards are an interesting concept: Reprinting old cards in another color, where they could have been printed if a few decisions had been different.

I had a few interesting calls:

  1. The interaction between Vesuvan Shapeshifter and Shaper Parasite. The Shapeshifter is turned face up and copies the Parasite. Question: Does the “Turned-face-up” ability of the Parasite trigger on the copy. I ruled in analogy to comes-into-play abilities and copy effects: The creature has all the copied characteristics before it is turned face up, so all triggered abilities that trigger on it being turned face up will trigger. Later the Time Spiral FAQ confirmed my ruling.
  2. I botched the interaction of Ovinize and Vanishing. The rules text for Vanishing reads in part (according to the Rules Primer):

    502.60. Vanishing

    502.60a Vanishing is a keyword that represents three abilities. “Vanishing N” means “This permanent comes into play with N time counters on it,” “At the beginning of your upkeep, if this permanent has a time counter on it, remove a time counter from it,” and “When the last time counter is removed from this permanent, sacrifice it.”

    For some reason I assumed that the third ability was included in the second one like this: “At the beginning of your upkeep, if this permanent has a time counter on it, remove a time counter from it. When the last time counter is removed from this permanent, sacrifice it.” Now the question was some like: “If I play Ovinize on a card with Vanishing and one time counter in response to Vanishing’s first triggered ability, what happens?” My ruling was that the last time counter is removed and the card with Vanishing is sacrificed, but any “leaves-play” abilities on the card don’t trigger. The correct ruling is that the last time counter is removed, but the permanent remains in play. At the time the counter is removed, the permanent has no abilities, in particular it doesn’t have Vanishing and so no “Last counter removed, then sac” ability.

  3. Player A had played Hunting Wilds. Some time later his opponent, player B, noticed that A’s graveyard was empty. A looked through his hand, and library and found a copy in the latter. Since he wasn’t sure whether he played one or two copies he wanted to see his decklist. After a short lecture that a player should under no circumstances look through his library without asking a judge first, I fetched the deck list and determined that the player only had one Hunting Wilds in total, so this one had to be the one played earlier. After a brief interview I was convinced that this was an honest mistake and the card had been shuffled into the library when the Forests had been searched for as part of resolving Hunting Wilds. The card was placed in the graveyard, the library was shuffled, and I issued a Warning for Procedural Error – Major.A case could be made for leaving the card in the library (leaving the game state as is is the default remedy if a decision point has been passed). But since the players had placed the card in the graveyard themselves in mutual agreement before a judge was called, I considered this to be the solution both would be more comfortable with, and let the card remain there. I think it was Scott Marshall who proposed to use a remedy both players of a match agree on instead of the normal remedy if this seems suitable. While I was initially opposed to it, this was a good example where this makes sense. I am still undecided on the issue, though.

New Python unittest module?

Collin Winter blogs about an updated unittest module he wrote. His update fixes the internal structure, and therefore the expandability, of the module, but also cleans up the external API. There are still a few minor improvements I would like to see, but nevertheless I hope that his updated version will be included in Python’s standard library eventually.

Java File API

I don’t like Java’s File API. It’s main problem is that is mixes several responsibilities into one class. One responsibility is handling of “abstract” file and path names, i.e. operating system independent file names. The other responsibilities are all file system related: Querying file meta information (access rights, access times, file type), creating files, and listing directory contents. In my opinion these should be clearly separated.

I am also missing a constructor or construction method that creates a File instance from a list of path components like this:

  File f = new File("/", "path", "to", "file");

Maybe I should start a Java warts page, similar to my Python warts page …

Disqualifications & Coverage

I am glad to see that there is an extensive article about the double disqualification of Amiel Tenenbaum and his opponent in Wizards’s coverage of Worlds 2006. I just had the discussion with another judge on #mtgjudge, whether this should be covered and how extensive.

I think covering DQs has several advantages:

  • It generates interest in the game. People like gossip. I know I do. Personally I couldn’t care less about play-by-play coverage, but I’m interested in stuff that happens at these events. I want stories. I want gossip. I want photos.
  • There is a professional interest for me as judge. It shows me how people cheat or try to cheat. It shows things than can happen that lead to disqualifications.
  • It shows that judges catch cheaters. If you read Magic-related message boards (and manage to keep your sanity) you will notice that many players, especially more casual ones, believe that cheating is rampant and cheaters are never caught. Making disqualifications public can help to dispell this myth. It shows that the tournament organizing staff will catch cheaters and that they will be penalized.
  • Word gets around if a player is disqualified. Whether it’s in the official coverage or not. It’s better to have an informed article with interviews with judges involved or the even the players. Otherwise people will speculate and lots of false rumors are started.

On the other hand the coverage still hasn’t got enough photos. And I would still prefer a blog from a coverage reporter to the “Pro Players Blog”, which is just another form of (boring) play-by-play coverage.

Gaia shut down by Google

Clint: Did you actually read the letter sent by Google? I actually consider this to be a perfect example of “don’t be evil.” There are no threats in that letter, Michael Jones, the writer, is just explaining why Gaia hurts Google and in what way he think the Gaia project is violating Google’s Terms of Service. He tells the Gaia project members that he understands their curiosity, even calls them “smart engineer[s] like ourselves”, but asks them to “refocus [their] work toward building an open earth viewer that uses open earth images.”

I don’t think that Google is free to do whatever they want with the images of the earth stored on their server. They most likely have a rather restrictive deal with the actual image providers. And even if they hadn’t, Google probably pays a rather large amount of money to these image providers. I can understand that they don’t want to offer these images for everybody to grab.

I consider this letter to be very kind and understanding, compared to what seems to be standard today: Let the lawyers do the talking, or don’t bothering with the talking at all and just sueing.

Java: Iterators are not Iterable

This is something I stumbled across multiple times now in Java: Iterators are not Iterable. Java 1.5 introduced the foreach statement, which allows easy iteration over collections like this:

for (MyClass item: myCollection) {
    doStuffWithItem(item);
}

For this to work class MyClass must implement the Iterable interface. This interface defines just one method that returns an Iterator:

    Iterator<T> iterator();

This works fine in many cases. But now suppose we have a class that can be iterated in multiple ways. For example a Tree class that can be iterated breadth first or depth first. I would define two methods and use them like this:

class Tree {
    Iterator<Node> depthFirstIterator();
    Iterator<Node> breadthFirstIterator();
}

// ...
    for (Node node: myTree.depthFirstIterator()) {
    }

This won’t work in Java. Iterators do not extend the Iterable interface, like they in other languages. For example in Python an iterator will return itself when its iterator() equivalent is called. Instead in Java I have to return an object that itself implements the Iterable interface like this:

class IterableIterator<T> implements Iterable<T> {
    private Iterator<T> iter;

    public IterableIterator(Iterator<T> iter) {
        this.iter = iter;
    }

    public Iterator<T> iterator() {
        return iter;
    }
}

class Tree {
    IterableIterator<Node> depthFirstIterator();
    IterableIterator<Node> breadthFirstIterator();
}

Not only is this boilerplate code for no gain, a generic class like the IterableIterator above is not included in Java’s standard library.

JavaScript Includes Revisited

I’ve given in in the JavaScript and Modules matter. I’m doing now what all the cool kids are doing: Using XMLHttpRequest synchronously to load external JavaScript files. This has the advantage that it works synchronously, a very important thing for includes. Therefore I don’t need callback and moduleLoadedhackery anymore. Also I have sensible error checking, i.e. I can notice when loading a JavaScript module failed. This enables me to have multiple search paths, for example, and sensible error handling.

But it comes at a cost, too. XMLHttpRequest is only supported by “modern browsers”. But since moderns browsers means any browser of the last five years I don’t care too much. When XMLHttpRequest is not supported, I suppose I can’t rely on other useful stuff neither. The synchronous requests also mean that there might be a slight performance hit. But the advantages of synchronous includes outweigh this by far. Finally, XMLHttpRequest doesn’t provide the means to recognize when a synchronous request is stalled. This is not of too much concern, since a stalled request usually means that an include files can’t be downloaded and so the JavaScript application is not usable anyways. It might be a concern for sensibly degrading, though.

Update: Here is the code to the updated module. Using it is now as simple as this:

<script src="include-http.js"></script>
<script>
    include.include("my.module");
    myfunc(...);
</script>

Porting JavaScript to Internet Explorer

While porting a small AJAX application I wrote to Internet Explorer, I encountered a few problems:

  1. IE doesn’t like <script> tags without a matching closing tag. This is especially a problem if you use the src attribute and try to use an XHTML-like closing tag like this:
    <script src="..."/>
    

    In this case IE doesn’t draw anything at all, since it keeps looking for the end of the script and doesn’t find it. This is especially a problem with templating toolskits like Kid. If Kid encounters a construct like <foo></foo> it will correctly shrink this to <foo/> in the XML output. The solution is rather easy: Insert a newline character between openening and closing tag in the template. Since Kid has now way to determine whether this whitespace is significant it will keep it in the output.

  2. It seems that IE doesn’t like trailing commas in JavaScript object literals:
    var o = {
        x: 'Foo',
        y: 1,
    };
    

    I like to insert trailing commas in cases like this. It’s easy to forget to add one if extending the property list. Firefox parses the trailing comma, while IE doesn’t. (IE follows the ECMAScript standard here, which doesn’t allow the trailing comma. Indeed in array literals a trailing comma has a special meaning, so it’s probably a good idea to disallow the trailing comma in object literals.)

  3. My AJAX application queries a web service for a list of items and displays that list in a table. The table is generated in HTML code like this:
    <table id="mytable">
        <tr>...</tr>
    </table>
    

    I then used JavaScript code like the following to populate that table:

    var table = document.getElementById("mytable");
    var trTag = createRow();
    table.appendChild(trTag);
    

    This worked fine in Firefox, but no matter what I did, IE refused to render the table rows. After much hair tearing I remembered that Firefox’s DOM Inspector showed a TBODY element just beneath the TABLE element and TR elements are attached to the former. The DOM Inspector basically showed the following structure:

    • TABLE id=mytable
      • TBODY
        • TR (my header row from the HTML)
      • TR (a dynamically generated row)

    So I changed my code to append the newly generated rows to the TBODY instead:

    var table = document.getElementById("mytable").
        getElementsByTagName("tbody")[0];
    var trTag = createRow();
    table.appendChild(trTag);
    

    This works in Firefox and IE.