PTQs for Valencia

It was a hard weekend. I was head-judging two Pro Tour Qualifiers for Valencia. The first on Saturday in the Der Andere Spieleladen here in Berlin, the second on Sunday in the Heldenwelt in Magdeburg.

Saturday we had 66 players. I had two floor judges (Robert Zemke and Christopher Eucken, both level 1) as well as two staff employees helping out. This turned out to be just the right number of staff for this event. The event went rather smooth, without any major headaches. The most problematic situation arised during top 8 when one player started with extensive trash talking and disregarding judge’s instructions to stop. Only after I made it very clear to him that I would issue the appropriate Unsporting Conduct penalty if he continued (a Match Loss at Competitive REL), did he stop.

Like at most PTQs here in Berlin we had a few Polish players. In general this is not a problem, since they speak English very well and I do all announcements in German and English. But it is always a problem if they with each other in Polish while another player is still playing. When players or spectators speak in English or German I am able to automatically filter out “harmless” chatter, e.g. a spectator telling a player that they will fetch food for themselves now or two spectators speaking about their last match. This is not possible when people speak a language I don’t understand. Therefore I ask them to stop communication more often than I ask players I can understand. This is not an ideal situation, but one that is hard to resolve, unfortunately.

In one semi-final match two of the Polish players were paired against each other. Both had card-identical decks, so the match was played in a rather light mood. The finals again were rather quiet. The event ended at about 23:30.

Unfortunately I did not get much sleep that night, so I was rather tired when I met my co-judge Kersten Rückert (L1) at Berlin Central Station at seven in the morning. Magdeburg’s judge situation is even worse than Berlin’s (it seems they don’t have any active judges), so they had to import judges from outside. This meant Kersten and me. One other judge unfortunately had cancelled his participation. At Magdeburg main station we were greeted by Peter from the Heldenwelt, who supported us as scorekeeper. With a total of 57 players (a good turnout, considering the location, and time during holidays) we were unstaffed by about one judge.

The tournament took place in a basement that consisted of two long halls with fairly high, vaulted ceilings. This gave the event a nice, medieval touch. One hall contained the playing tables, while the other had the scorekeeper and judge’s tables and the feature match area. The halls were connected at the end by two small doorways. Actually the layout was rather good, because the separate scorekeeper and judge tables meant quiet, relatively disturbance-free working. And you could use this hall to get quickly from one end of the playing area to the other one.

Teardrop was doing coverage of the event (in German). I like coverage for these smaller events. I think many people who can’t make it to the tournament can still follow it and see how their friends are doing. It helps the community in a local context the same way coverage of Pro Tours and Grand Prixs help the community at large.

Unfortunately the coverage was ill-fated. During round 5 one player of the match that was originally going to be covered was disqualified. (The other player of that match followed a bit later.) The next (and last) round of the tournament, the feature match was between two players who would make top 8 if they won the match. A spectator noticed marked sleeves though. When I checked the sleeves, I pulled out two cards that had especially bad, but different, marks, without looking at them. It turned out I had singled out two of the three Psionic Blasts in the deck. After a short glance at the sleeve of the third Blast I was able to consistently identify all three Blasts. After a short investigation I came to the conclusion that the player did not know about the marks and they occured because of wear during play. Nevertheless I had to issue a Game Loss for Marked Cards — Pattern. This is always a hard penalty to give in a situation like this (it effectively decided who got to top 8), but there was no way around it.

In the top 8 (which were played back in the store) Kersten had to give another Game Loss for Drawing Extra Cards, but apart from that the matches rent quiet and well. I was especially grateful that the final match between Jim Herold and Frieder Michel Drenger went rather quickly, since I and Kersten had to fetch the last train back to Berlin. We ended the day like we had started it: Sitting in the train, eating tasty and healthy food from McDonalds. Congratulations to Jim, who had already made top 8 the day before in Berlin and now has Pro Player level 3 status if he attends Pro Tour Valencia.

Blog Statistics

Yesterday I had a look at the webalizer statistics for this web page. Still, by far the most hits got my review of GTA: San Andreas, followed by several pages that are automatically fetched. It is also by far the entry page #1, with nearly five times as many hits as the root page. The referers to the GTA review are also interesting: Lots of people get there from Google’s image search, and some warez forums also seem to link there. (I wonder why, unfortunately these forums are all non-public.)

Also notable is page #2: /blog/submitcomment.cgi got more than 2000 hits this month alone. This is the script used to submit comments to blog entries. It shows how much comment SPAM I get per month, although only about one or two SPAM comments are not filtered out automatically. It seems that my list of filtered words is rather comprehensive.

setuptools breaks PYTHONPATH

setuptools and egg files are a great way to distribute Python packages and programs. But today I stumbled over a really braindead design decision: setuptools overrides Python’s standard module search path algorithm in a very inconvenient way. Normally, when Python looks for a module or package, it first looks in the current directory, then in any path specified in the PYTHONPATH environment variable, and finally in the default search path. setuptools changes the lookup order to the following:

  1. the current directory
  2. egg files specified in PYTHONPATH
  3. egg files in the default search path
  4. regular modules in PYTHONPATH
  5. regular modules in the default search path

This means that an egg file in the default search path overrides a non-egg module in PYTHONPATH. I wonder what the rationale for that decision is (and it seems to be a deliberate decision). PYTHONPATH is a means to override the default search path and is perfectly suited for testing, developing, and forcing to use a particular (e.g. a bundled) version of a package. Not anymore! Now, the only way to override an egg is to create your own egg. And this is non-trivial and often means an extra step during development.

Here is where it bites me: I have created a library of custom classes, that I use in several projects. I break API frequently, since it is developed in a just-in-time fashion: whenever I need some functionality, I implement it. Therefore I bundle the library (or parts of it) with most projects. This works well for projects that go into a separate directory, like web projects. Nevertheless I use the library for some other projects that are installed system-globally. Otherwise I would need some way to namespace it for the different projects. Not my idea of fun. Normally, this is not a problem, since I can just set PYTHONPATH for all projects that have a local copy, at least when developing. Due to the strange path handling of setuptools, this method breaks and I have to work around it. Great …

gnome-keyring with Python

The documentation on gnome-keyring I discovered helped me to access it successfully with Python. I’ve written a small module that fetches and stores a username and a password for some server.

Some notes:

  • The attributes are freeform, but there a some common attributes for network hosts. These are: “user”, “domain”, “server”, “object”, “protocol”, “authtype”, and “port”. Actually there is a convenience API for network hosts.
  • libgnome-keyring requires that the application is correctly set using g_set_application_name. Unfortunately the Python module gnomekeyring does not do that for us and pygtk does not provide a function to set the application name. Therefore you need to include the module gtk to make it work. (Filed as bug 460515.)Update: g_set_application_name was added to pygtk in the 2.13 development version.
  • Python’s find_network_password_sync function does not allow None to be passed as arguments. The C API allows NULL to be passed here. This means that this function is basically unusable in Python, since you never want to provide all values. (Filed as bug 460518.)

Documentation for libgnome-keyring

I was trying to find documentation for libgnome-keyring for little project I am writing, which accesses a password-protected web service. Unfortunately there is no real documentation for it. No API documentation (well, there are a total of two functions documented), no tutorial. Finally I found this document in GNOME’s Subversion repository. Better then nothing, but why isn’t this part of the API documentation?

Filed as bug 460475.

Update: It seems that libgnome-keyring has gained documentation a few weeks ago, so far only found in Subversion. Kudos to the maintainers!

Selection in GtkTextBuffer

I’ve recently played around with GtkTextBuffer. It’s a rather nice text editing widget (or rather widget part). Unfortunately it misses one functionality, which is also missing from GtkEditable derived widgets: A signal for selection changes. There are two workarounds:

  1. You can setup a notification on the “has-selection” property like this:
    buffer.connect("notify", on_buffer_notify)
    
    def on_buffer_notify(buffer, prop):
        if prop.name == "has-selection":
            if buffer.get_has_selection():
                ...
            else:
                ...
    

    This method only works if you are interested in whether there is a selection or not, not if you are interested in any selection changes. Also, this method works only for GtkTextBuffers, not for GtkEditables.

  2. Tomboy uses a timeout to check the selection status:
    namespace Tomboy
    {
    	public class NoteWindow : ForcedPresentWindow 
    	{
                    ...
    		public NoteWindow (Note note) : 
    			base (note.Title) 
    		{
                            ...
    			// Sensitize the Link toolbar button on text selection
    			mark_set_timeout = new InterruptableTimeout();
    			mark_set_timeout.Timeout  = UpdateLinkButtonSensitivity;
                            ...
                    }
    
                    ...
    
    		void UpdateLinkButtonSensitivity (object sender, EventArgs args)
    		{
    			link_button.Sensitive = (note.Buffer.Selection != null);
    		}
    
                    ...
            }
    }
    

    This method works, but seems a bit complicated, when a simple signal should do the trick.

Filed as bug #448261.

German Card Translations

German card translations are a sad affair. They are riddled with clumsy translations, especially in the card names. It’s not such a great idea to translate english card names 1:1. The rules texts are translated sanely, i.e. using special German templates, although some of the template choices are a bit strange and more verbose than needed. For example, “target” is translates as “deiner Wahl” (“of your choice”), while “of your choice” is translated with “die du bestimmst” (“that you choose”).

In Planar Chaos Ovinize was translated as “Verhammelung”. First of all this sounds strange. The noun “Hammel” was turned in the verb “verhammeln”, which was turned back into the noun “Verhammelung”. But it’s also not good templating. Ovinize is an Instant, and Instants and Sorceries usually get a verb as name. Ovinize is a verb. The German translation “Verhammelung” on the other hand is a noun. This shows a lack of understanding of magic card naming on the part of the translator. “Verhammeln” or “Schafen” had been a much better name.

But what’s worse are wrong translations. For example the German version of Necrotic Sliver has the following ability: “All Slivers have ‘3, Sacrifice this creature: Sacrifice target permanent.'” (You can only sacrifice your own permanents.) Since Wizards decided not to publish Oracle texts until Monday after the prerelease, I could not confirm that the card was actually a mistranslation and had to rule it by its German text. Unfortunately the mistranslations (in the rules text) average around one per expansion.

Finally, cards that have obvious templating problems in the original are not corrected in the German version. For example the flip side of Saviours of Kamigawa’s Erayo, Soratami Ascendant reads “Counter the first spell played by each opponent each turn”, a rather obvious templating error. This was unfortunately not corrected in the German translation. In my opinion a good translator should catch errors like this.

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.