Sunday, April 10, 2011

Pyweek 12: Nine Times

So a bunch of us took part in pyweek 12. While we had a lot of fun, and the ended up with something that looked very good, we didn't quite manage to get the game completely playable inside the 1 week time limit.

Failures are generally more educational than successes, so some thoughts on what went wrong.

a) We were arguably over ambitious, although I'm not sure where we needed to scale down. This is probably the most important factor as it meant we took too long to get enough of the game playable that we could start getting stuff hooked up, and it also meant that we didn't have as much overlap on knowledge of the code base as we had on Suspended Sentence, which slowed us down at critical points, and made fixing various bugs quite hard.

b) We took too long to converge on what game we were writing. Various bits grew in different directions and got fixed in the wrong place, and there were a couple of dead ends we pursued. We also didn't have the time to refactor code to fix things as we've had previously, so the game is more than just somewhat buggy.

c) We didn't know mercurial nearly as well as we thought we did. Most of us had used it for the Genshi sprint, which was quite intense, as well as using it on other projects, so we thought we going for a safe option At the pace of pyweek development, however, we tripped over mercurial not behaving as we expected quite often, and the slow downs fixing the issues this caused all added up to quite a lot of lost time.

Still, the game has a number of promising bits, and, with some concerted work on the engine, and some work on the other bugs and the game balance, it can turn into something really quite cool. This should be a good candidate for pyggy, if we can summon the energy to tackle again.

Monday, April 4, 2011

Veiled Sight (April 2011 VTES Tournament)

So we recently held the first VTES tournament of 2011, with the first rounds on the 2nd of April and the delayed final (due to pyweek) only on the 13th.

We had a good turnout, with 12 players for the Saturday. A very important number, given the rules of the TWDA.

I decided (via die roll) to try the "Not a Lutz deck" again, which ended up being a good choice and did quite nicely for itself.

The first round saw me (starting) bleeding Hendrik (Assamite trophy deck) bleeding Dave (Kiasyd sleaze) bleeding Yancke (!Tremere DOM Mirror Walk stealth bleed). I had a fast start, with two early Zillah's Valley's which saw Lutz out on turn two, and Alicia on turn three, and an early secure haven on Lutz essentially shut down Hendrik's deck. I took a couple of turns to reach a Minion Tap, though, and, had Yancke drawn an early conditioning, I would have been the first ousted. I was able to oust Hendrik, but, due to a Covincraft from Dave, needed one more vote card to do so than I had hoped. At this point, I suffered a critical deck failure, and didn't draw the votes I needed to oust David, and, with not enough bounce, was rapidly whittled down by Yancke's DOM. Yancke critically ran out of bounce, and was ousted by David who then ousted me.

On the other tables, Brendan (Tzimisce wall with DOM) took 3 VPS, with Simon (Spiridonas bleed and vote) taking 1, and Marc (Torrance Circle BB) and Richard (Weenie Liabon Vote) getting none. James (Imbued) took 3 on his table with Kevin (Settites) getting 1VP, with Anthony (Kiasyd) and Evan (!Salubri with Q) getting 0 each.

The second round was one of the more stressful, and frankly odder, games I've ever been involved in.

The table was James (Imbued) bleeding Anthony (Kiasyd) bleeding Richard (Liabon vote) bleeding me. I didn't get as fast a start as the first game, but I did start by contesting James' first turn Dreams of the Sphinx immediately, as contesting with your prey is usually worth it. I got Lutz out on turn 3, only for James to Pentex him immediately. Richard was gradually building up, and not blocking any of Anthony's actions, and succeeded on jamming on stealth. I was extremely vulnerable for a turn while I got out Alicia, and got going again, and, had Richard had a extra bleed card, I may have been ousted before I got to act.

Once I had Alicia, I drew a Minion Tap, which gave me a buffer, and started to dent James' pool a bit. There was also a cross table rush on Richard by James that helped me, by slowing Richard up a bit. I made a misjudgement when I wasted a couple of actions trying to burn the Pentex before realising that I didn't need to. Due to another Minion Tap, I was able to bring out Aristotle, which was important, as, without his extra stealth, I was struggling to get past the intercept of the Imbued.

There was one critical vote by Richard, which would have led to my being ousted, but frantic negotiation with Anthony saw him cycle a Covincraft to save me. This however left Anthony without a wake, and he fell to the James' lunge immediately after this, and, at this point, the table looked to be falling for James. Richard, however, was worried about the threat of the Imbued and cut a deal to pass a couple of votes with me, which hurt James, and, combined by a bounced bleed (by the still Pentex'd Lutz) which forced James to tap his blockers, I was able to land a couple of votes and get him within range again. James then played Gambit accepted, and, thanks to a Minion Tap on Aristotle, I was able to buy myself enough breathing space to oust James, although, had he chosen to block rather than determine my Kine, I wouldn't have been able to make the lunge stick. In the end game against Richard, I was able to block a Founders, and, although Richard had managed to secure the vote lock, he couldn't call aggressive votes due to Lutz's special. Once I remembered that, with James ousted, Lutz was free to act again, I could bleed faster at stealth than he could, and so I was able to oust him for the sweep. I made several poor decisions, but was able to hang on enough to recover.

I didn't see what happened on the other two tables, but Yancke & Marc both swept, but my extra VP from the first round saw me enter the final as top seed. Brendan, James and Dave were all tied, and Brendan lost the roll off for a place in the final. Yacnke and Marc also rolled off to see who would choose seating first, with Marc rolling lowest (and so choosing first).

For the final, Marc (unsurprisingly) chose to sit upstream of the Kiasyd. Yancke then chose to sit between The BB and the Kiasyd, which surprised me, as I expected him to sit upstream of Marc. As I didn't want to sit downstream of the DOM decks, I chose to sit between James and Marc, hoping that the upstream pressure would keep James off my case and that I could oust Marc before he got the wall part of his deck setup. I rolled highest, so I started.

The final was one of those games where my deck, despite not quite coming as I wanted, generally ran nicely. I got a first turn Dreams, which allows me to get Lutz out on turn 3, despite starting, and despite taking an early bleed for 3 from James, an early Minion Tap saw me up to a decent pool again. I didn't draw any voter caps for much of the game, but, as I had enough stealth to go over Marc's Gestalts, and James was too occupied with the pressure from upstream, I didn't see any combat, and thus never has any real blood management issues.

YDave got up to 3 minions fairly quickly via some govern trickery, and Yancke got up to t2o, with Carna appearing in the mid-game. With Yancke bleeding heavily, and David drawing a truly astonishing number of bounce cards, James was left trying to block 5-6 bleeds a turn, which took all the pressure off me. A key early play saw James try to Pentex Dave's the Arcadian, only for Dave to Sudden it, which ensured that James never got to go forward at all. I had votes come up nicely, and was able to whittle down Marc in good order. Thanks to a Forgotten labyrinth, I was able to stealth over Marc and oust him despite his intercept, and, with the aid of a Zillah's Valley, able to get Aristotle out and into play as well. James eventually ran out of blockers (although there was one 4 bleed that was bounced to Yancke who then bounced it to me, which itched a bit), and was ousted. I had been able to Minion Tap Alicia, but at that point wasn't out of lunge range. I was able to call a couple of votes to whittle Yancke down, also including the first Voter Cap I'd drawn .

At this point, Yancke was looking quite vulnerable, and, as I had a Rumors of Gehenna in play I could vote away at will, I was fairly certain I had him next, but I was worried about the heads up against Dave, who had shown considerable bleed potential, no shortage of bounce and was looking pretty on 14 pool. Yancke bled forward, though, and it turned out that Dave was out of wake and bounce, and he was whittled down to only 4 pool. He was also short on bleed, so I started my next turn sitting quite pretty, espeically as I was then able to Minion Tap Arisotle to ensure I was safe. A Kine and a Conservative Agitation saw me oust Yancke, and the incidental damage reducde Dave to 1 pool, and then voting away the Rumors saw me oust Dave, so I ousted Dave and Yancke in a single turn for the game win.

The table did sit up very nicely for me. The shortage of other votes on the table meant that, although I only drew a couple of vote push cards and 1 Voter Cap, I never had a problem passing the votes. Choosing to be Marc's predator was the correct choice, as, once he was ousted, no-one else ever threatened to block me. The Masters came up very nicely - I had an early dreams, which got Lutz out one turn earlier, and drew Minion Taps when I needed them. The low combat environment meant I actually jammed a bit on S:CE cards, which is most unusual for Cape Town, but I always had a vote in hand when I needed one, so I never lost momentum.

So, a successful tournament win, and what should be an entry in the TWDA, which is a nice little milestone to tick off.

An Observation

It's regrettably common for car drivers to try and muscle out motorcycles, and, given that the motorcyclist is the squishier of the parties involved, it's usually better for the motorcyclist to choose discretion over arguing too hard about right of way.

As an enthusiastic motorcyclist, I've this happen to me numerous times. It is, however, hard not to feel particularly ticked off when the car in question sports a prominent "Think Bike" sticker.

Friday, April 1, 2011

Failing to learn from history again

Learning from history is often hard - without the perfect vision of hindsight, it's easy to overlook the similarities of your current situation with past experience. This isn't at all comforting when one recognised the similarities and dismissed them with "This time, it will be different".

I often write "throw away" code - usually to isolate some specific code path or test some specific case that's currently interesting from the larger system. As the code's initial life expentancy is quite short, I often don't bother with niceties like proper argument parsing or decent error handling. In theory, the technical debt from this never be a problem, just write a little wrapper program, learn what you need, and throw it away.

The scare quotes and "initial life expectancy" phrasing should immediately identify my problem, though. If I didn't but the code in the VCS, the theory might work, but, once the code is there, it's never going to be thrown away, and, since it exists, in a day or a week or a month or something, I'll need something similar, and it's easy enough to just quickly add an option and make the throw script do a little more, and, since it's still just a throw away script, there's still no need to do proper error handling or argument parsing. And, of course, the moment a couple of the command line options become enshrined in a test script or two, the effort required to actually fix things never seems worthwhile, despite the increasingly convoluted "simple quick code" handling things.

Given that I've trodden this path several times before, this week's effort of going from 100 lines of C requiring a single filename to two 250-line interlocked programs, each with complex combinations of options and error handling from the oblivious school (the actual important code of each program is still less than 100 lines each), via a steady stream of "I'll quickly add this", is one of my more impressive examples of failing to heed lessons from the past. Next week, I'll probably spend some time fixing things, although there's still that ever so seductive "it's just one last option and then you can throw it away" voice to deal with.