Peter's Blog

Redefining the Impossible

Posts made during December 2007


Issue 200 special: Pooky Runs Deadmines!

What better to celebrate the 200th issue than my first ever completion of deadmines! Pook went to Westfall to farm linen/wool at a spot that Nibuca suggested. Linen dropped slowly from a couple of mobs and a lowbie turned up and as I don't think it's fair to steal lowbie kills I decided to just run Deadmines. None of my characters had ever got as far as VC due to groups wiping or high-levels running out of time. I thought VC would be a big tough guy, he's just a little human. Cookie looks just like a normal murloc. All the boss monsters dropped BoP blues that were worthless to pook, at 10s they weren't worth taking as vendor trash. Pookie finished the run with:

  • ten greens for Maexyn to disenchant
  • four stacks each linen/wool, bringing Maexyn's first aid up to 70, tailoring up four levels.
  • two green macaws for Maevyn's pet collection.

Warlocks are OP

When Maexyn got to level 18 she visited the Warlock Trainer in Stormwind and found one of the rarer demon trainer guys (I don't think there is one of these in ironforge, he's outside in the dwarf village, a tedious run ). It turned out that her voidwalker was overdue for training in Consume Shadows (useful out-of-combat heal) and Sacrifice (exchange voidwalker for a shield buff). The odd thing about Consume Shadows is that the voidwalker stands where it is and waves it's 'arms' about for ten seconds so Maexyn has to remember not to go into combat! Haven't tried Sacrifice yet.

For herself she got to make Soul Stones. These are nice, with a Soul Stone up, if she dies she doesn't have to do a corpse run, she can ressurect herself at the point she dies. She still gets the durability hit, she loses her pet, her buffs and there is also the possibility that the place she died is swarming with monsters such that she can't resurrect without promptly dying again. If she is doomed and going to use the soul stone, best to start running.

With the next ranks of Affliction Talents Maexyn gets 15% mana back if her enemy dies with Drain Soul running. This is quite easy to do and she can:

  • Pet Attack
  • Immolate
  • Curse of Agony
  • Corruption
  • Life Tap
  • Drain Life
  • Drain Soul

and end the fight on very nearly 100% health and mana. The Voidwalkers's health may be dented and it will need a Consume Shadows every few fights but still it is very efficient.

The Warlock can handle pairs of mobs ok. I tried using fear for a while but I'm not sure it's worth it, just DoTing both mobs up and burning them down is good enough and fear takes time to cast (during which time she is being beaten on) and starts the fear dice roll where you don't know where the feared mob will run (and they run a LONG way). The Fear tool tip says damge may break fear which is not the same as a Hunter's freezing trap where the slightest bit of doT damage WILL break it. It seems ok to DoT and Fear a mob (and vice versa). Handling three mobs is tough but I found Maexyn can handle camps much like Maezyn can: if there are four mobs in a camp, cast a DoT on a corner mob to pull and most often it and one other will come running and two can be dealt with. Just like a hunter, NEVER send the pet into a camp, PULL!

Maexyn has been grinding in Westfall and Redridge. I couldn't be bothered to tackle the Westfall murlocs again (the quest where you have to run all up and down the coast) but I found the murloc quest in Redridge much easier, using the underwater breathing spell to kill countless murlocs in the lake.

The lowbie areas seemed very busy, as if a lot of people have started new alt's. The Westfall linen grinding site was almost always occupied and it took time for Maexyn to get her quota of Defias. Maexyn got lots of group invites, one right in the middle of a big murloc fight. I don't know if people send group invites (unwhispered of course) while you are fighting just to wind you up (there was nobody nearby trying to help). One guy challenged her to a duel while she was levelling her first aid thirty levels so I just left him hanging by not pressing the button.

WTB /dnd to work with group/duel invites.

She's just one hour away from having a Succubus although that one hour is proving hard to spare.


Filed under: games warcraft wow

6 Comments

I'm going to blog this so I can remember it. How to get Rails/ActiveRecord to wrap an existing table in a database, i.e. one that you don't want created or manipulated via migrations:

ruby script/generate model my_table --skip-migration

where my_table is the name of the table you are wrapping. This assumes you are already connected to the database (easy: edit config/database.yml).

It may be possible to simply derive a new class from ActiveRecord but the above is probably ensuring that everything is done properly.

In my case the database is being stuffed from some complex python code that I don't have the time/inclination to port to ruby/rails and I would rather the creation of the tables was still done through python. ActiveRecord being the wonder that it is will pick up the schema of the table and create wrappers automatically so you still don't need to tediously reiterate the column names/functions as you would in lesser frameworks.

It should be entirely possible to create views in MySQL and wrap them for Rails in this fashion although I found that creating views on a 20,000 record table causes the mysqld to take 99% cpu time for ten minutes afterwards. I know what you're saying, 'check your indexes', well I have.


Filed under: mysql noob rails

Add a comment

Found another ruby gotcha when calling methods declared with default argument values:

irb(main):004:0> def a( b=1,c=2,d=3)
irb(main):005:1> print "#{b} #{c} #{d}\n"
irb(main):006:1> end
=> nil
irb(main):007:0> a(c=23)
23 2 3
=> nil

A python programmer would have expected this to print

2 23 3

as when calling the function we are saying we want c to be 23 and the other arguments to be left at their default values. Ruby appears to be ignoring the 'c=' bit when the function is being called so the first argument 'b' gets the value 23.

Pity, this python trick simplifies calling functions with lots of default parameters: you don't have to get the order of the parameters right or specify the correct default values of arguments before the one you are having to specify a value for. I should be calling this with:

irb(main):007:0> a(b=1, c=23)

i.e passing 'b=1' even though the declaration should tell ruby what the default for that should be. The 'b=' and 'c=' are only serving to help me selfdocument my code.

Ruby's behaviour is C/C++ish i.e. primitive.

UPDATE:

O'Reilly Ruby Cookbook:

   1  def fun_with_text(text, args={})
   2    text = text.upcase if args[:upcase]
   3    text = text.downcase if args[:downcase]
   4    if args[:find] and args[:replace]
   5      text = text.gsub(args[:find], args[:replace])
   6    end
   7    text = text.slice(0, args[:truncate_at]) if args[:truncate_at]
   8    return text
   9  end
  10  
  11  fun_with_text("Foobar", {:upcase => true, :truncate_at => 5})
  12  # => "FOOBA"
  13  fun_with_text("Foobar", :upcase => true, :truncate_at => 5)
  14  # => "FOOBA"
  15  fun_with_text("Foobar", :find => /(o+)/, :replace => '\1d', :downcase => true)
  16  # => "foodbar"

Filed under: gotcha noob ruby

2 Comments

I had my rsync scripts set up and running. I had backup and get scripts so I could backup my work to a server, go home, download the changes, do some work, upload the changes, download them again at work. Who needs a flash drive?

However there's this thing called 'finger trouble' that happens sometimes: you forget to backup the changes on one machine or another and suddenly, bam, your work vanishes. At least that is what I think happened, all I know is that twice now I have lost some work. Running backup and get scripts to synchronise two pc's against a server is too error prone for me.

So I set up unison which, once running, should be a less error prone solution. It will synchronise the files on my home and work pc's with the files on the server. Changes to the files may be propogated either way, depending on the time stamps. I can change the files on either pc and unison will help me resolve any conflicts I create. While it is synchronising it will prompt me with each file that has changed and ask me what to do with it so I can see if I am about to overwrite an evening's work.

I have the following unison profile file set up in my .unison directories on both pc's:

#
# Unison profile for project X
#
root = /cygdrive/c/projects/X
root = ssh://me@myserver.com//home/pcw/X

ignore = Name Downloads/*
ignore = Name Backup/*
ignore = Name Backups/*
ignore = Name Tmp/*
ignore = Name *.map
ignore = Name *~
ignore = Name *.obj
ignore = Name *.o
ignore = Name *.i

backup = Name *
backupdir = f:\users\pcw\BACKUP\X

If the profile file is called X.prf then I can synchronise this project by running

unison X

Because the profile is in my private .unison directory I don't even need to cd to the project directory.

The 'backup' and 'backupdir' lines at the end of the profile tell unison to maintain an extra local backup, in this case on our main file server such that the backups fall under our company tape backup procedure.

It has worked for a day now with fewer problems than rsync gave (and ironically unison uses rsync in it's underpinnings) and it is fast, taking less than a minute to work on 491 files.

To maintain straight backups unison would be overkill but where changes could be made to the files in more than one place it is looking good.

Of course, I could use unison with a flash drive rather than a file server but I don't have to remember to carry the server around with me.

And I know about synctoy but unison works easily through an ssh tunnel.


Filed under: backup rsync unison

Add a comment

Good News

Maexyn hit level 20 (warcraft sig site is broken again, click the sig for armory page if you don't believe me).

Bad News

She has to run all the way to the Barrens for the Succubus quest. Nearest flight point? Loch Modan! And I thought the paladin lvl 20 quest was a lot of running sad So this is why warlocks and paladins get free mounts, because their legs are really tired by level 40.

Other News

I didn't mention before but I followed spikeles's link regarding the vendoring bug and the workaround seems to be to right click the things you want to sell with the vendor dialog box open at the 'selling' page, not the 'buy back' page. In fact this is a more convenient way of selling things than the drag and drop I was doing so I'll probably do it this way from now on.


Filed under: games warcraft wow

2 Comments

Two c's in Succubus

I cannot resist this kind of project so Maexyn ran around for about three hours and got herself a Succubus. She picked up flight points for Menethil Harbour, Auberdine, Astranaar and Ratchet. Running through Darkshore and Ashenvale reminded me how vast and annoying these areas are, it was slow enough rep grinding with Maevyn on a normal mount, there is no way Maexyn is levelling there, I'd rather do Wetlands and Darkshire for the fourth time. The killing involved in the Succubus quest was quite straight forward, it is easily soloed. She did most of it except for the final Succubus taming at level 20, the quest before last in the chain dinged her to 21. Warlocks were virtually queueing for their Succubii at the end, two other's left the Slaughtered Lamb at the same time she did.

I haven't had time to try out the Succubus yet. I'd put up a screenshot of her but it's far too naughty and, being a warlock pet, it looks like every other Warlock Succubus. It's hard to warm to a warlock pet in the same way you do a hunter pet, even one that wears a thong.

Must work on Maexyn's 'armour'. I haven't done much in the line of upgrading it since level 14.

Fighting Style

I'm putting points in the talent that stops drain life being interrupted as I'm aiming at drain tanking and I'm not sure if it is viable yet with only rank two out of five. Soloing with the Voidwalker is still perfectly ok. I still haven't used the Sacrifice Voidwalker spell.

I've been mixing up my attack a bit. I have been opening with Curse of Agony and then sending the Voidwalker in. The enemy runs to Maexyn but as curse of Agony is low threat the voidwalker easily pulls agro, leaving Maexyn free to cast Corruption and Immolation. The difference this makes is that the enemy runs to Maexyn instead of the pet running to the enemy, Hunter Style. I don't feel that at the current levels keeping range is as important for the warlock as it is for the hunter (there is no minimum range) and having the enemy close means a shorter run to loot it's corpse. Maexyn does not seem to draw agro very often, even fighting close quarters. As I say, I'll probably have to review strategy at higher levels but I also have to remember that Maexyn is not a hunter.

Group Invites: Mystery Solved

I installed the AutoDecline mod because of all the annoying group invites Maexyn was getting. It works nicely, I just get an entry in the chat log to say that so-and-so's group invite was declined. I did some /who's on the names and they were level 1's in Elwyn Forest so it looks like a gold selling thing. Maexyn's warlock skills aren't in as much demand as I thought sad At least she won't get a group invite in the middle of a big fight that has gone tits up.

Plan

I'm going to try and be less fixated on running one character at a time and instead alternate between Maezyn and Maexyn and exploit rest bonus more. I am lucky, I have two viable characters that I enjoy playing and being 20 levels apart it means that there is a few week gap between doing an area on one character and repeating it with another.


Filed under: games warcraft wow

5 Comments

Voidwalker vs Succubus

At level 21 Maexyn was running around wetlands killing things. She tried using the Succubus but tackling mobs that were any higher level than her was a struggle as Maexyn would take a big beating and couldn't drain the monster's life quickly enough. However, with the voidwalker it was taking too long to kill things, more than twenty seconds per kill which is my boredom threshold.

Maexyn got to 22 by killing gnolls, carefully creeping around the outside of the camp and picking off stragglers, paladin style, except with a Succubus rather than a big sword. One interesting thing about the Succubus, probably a patch 2.3 change but when a monster is fighting Maexyn the Succubus lashes it from behind with her whip. Naughty monster...

At 22 Maexyn visited the Warlock trainer and, wonderful, got next rank drain life, 17 health/tick over 10, a 70% upgrade. She went back to wetlands and, again with the Succubus, still struggled against higher level mobs (up to 25). The mobs kept interrupting the Drain Life (I'm still working on the uninterruptability talents) and in recasting it all the time she would run into mana as well as health problems.

After a while, went back to the voidwalker and life improved a lot, could take out gnoll camps. Kill speed was improved by adding a bit of wanding to the fight.

Succubus may become more useful with better life draining and some more Succubus talents (I miss the Voidwalker's Consume Shadows and Sacrifice) but I will have to work on the Voidwalker vs Succubus strategy. I notice that you don't tend to see a lot of Succubii being used by other warlocks and it could be for a number of reasons:

  • they are useless
  • they are embarassing
  • people can't be bothered to run to the Barrens to get them

They could be the Warlock equivalent of a spider pet. Since a hunter can solo the whole game with just a boar, does the Warlock really need anything other than the Voidwalker and the big armoured thing the level 60's run around with?

Maexyn got to 23. Since she did all level 22 without rest bonus I switched to Maezyn who had full rest bonus and hence is now 40 minutes from level 45. The hunter is so much easier: the pet holds agro like glue on multiple monsters! And she's not even a Beastmistress! Freezing trap! Feign Death! Aspect of the Cheetah! Gotta love it.

One Stop Shop for all your Tailoring and Enchanting Needs

Had a big profession levelling session and got Maexyn to 160 tailoring and 150 enchanting, not bad for an (at the time) level 22. Still can't use either for anything useful though. The nice tailoring recipes all appear to need spiders silk of some form which is interesting as it explains why there are so many spiders in the game.

Loving AutoDecline

Still loving AutoDecline. Some random guy in Wetlands was giving Maexyn grief, trying unsuccessfully to kill steal and then throwing up duel challenges. One wonders what goes through the guy's tiny mind when his challenge is instantly declined. This simple WTF probably automatically prompts a second challenge.


Filed under: games warcraft wow

2 Comments

Sometimes software jargon gets in the way of understanding what practical use something is. For example, you have a problem and you want to know how to solve it so where do you look it up in the ruby book?

What I am going to describe is based on the concept of 'metaclasses' which are classes for creating classes. If that jargon fried your brain then lets have a problem and an example.

I want to create classes for implementing Commands. Each Command class has a command number and I want to define this Command Number in the class definition but I don't want to wear my fingers out typing them in. What nice syntactic sugar can ruby offer to help me with this?

   1  #
   2  # Class for building command classes
   3  #
   4  class Command
   5    class << self
   6      attr :nCommandNumber
   7  
   8      def CommandNumber( nNumber)
   9        @nCommandNumber = nNumber
  10      end
  11    end
  12  end

Ok, horrible syntax so what on earth is going on here? Well the effect of 'class << <object>' is to add new methods to an object so in this case we are adding a new attribute 'nCommandNumber' to hold our command number and a new method 'CommandNumber' so set its value to an object referred to by 'self'.

So what is 'self' equal to? Well it turns out that when you use this class (Command) to create another class (ACommand) then 'self' will hold the value of the 'ACommand' class object, i.e. the object that creates instances of ACommand objects.

#
# Declare a specific command
#
class ACommand < Command
  CommandNumber 123
end

Hum, that looks easy. When ACommand is being defined the line 'CommandNumber 123' will result in the CommandNumber method in Command being executed on the ACommand class object so 'ACommand' will have an attribute called nCommandNumber added to it. We can see whether this happened with:

print ACommand.nCommandNumber
=>123

and indeed it works sweetly (which is what you would expect from syntactic sugar). It is important to note that it is the ACommand class itself that has these attributes, NOT objects CREATED by ACommand:

oAC = ACommand.new
print oAC.nCommandNumber
NoMethodError: undefined method `nCommandNumber' for #<ACommand:0x345e180>
        from (irb):15

so how can an object created by ACommand find the value of this attribute?

oAC.class.nCommandNumber
=> 123

one of the attributes of the object is the class that created it.

How would this be done in a lesser object orientated language? Probably using techniques such as:

   1  class Command
   2    def GetCommandNumber
   3       raise RuntimeError, "Pure base function called"
   4    end
   5  end
   6  
   7  class ACommand < Command
   8    def GetCommandNumber
   9       return 123
  10    end
  11  end

or

   1  class Command
   2    def initialize( nCommandNumber)
   3      @nCommandNumber = nCommandNumber
   4    end
   5  end
   6  
   7  class ACommand < Command
   8    def initialize
   9      super( 123)
  10    end
  11  end

or something similar. Like all syntactic sugar, it doesn't make the impossible possible (anything is possible in hand-coded assembler) it just makes for less typing and clearer code.


Filed under: noob ruby

1 Comment

When researching VPS's to host websites a few months ago I came across SliceHost who were very highly regarded but had a long waiting list, with waiting times measured in weeks unless you were willing to commit to a top range deal for a year in advance.

Hence I went with vpslink and a 512Mb VPS. Vpslink are cheap but have the limitation that you get no 'burst' ram so if your 512M runs out then phut, apache crashes. This was happening to me until I changed from the preforking apache to the multithreaded one that uses less memory (fewer processes) after which it was rock solid. However, I no longer trusted it.

Last Saturday I was still mulling over hosting and checked Slicehost again to find that their waiting times were down to less than a week for all their packages. Their prices are slightly better than VPSlink so I applied for one and by tuesday I got an email with a link to sign up. Signing up was easy enough and within minutes I had 1024Mb slice for three months.

My first impression when I logged into it with ssh was that it was very fast. Typing into the console, the keypresses appeared immediately. In a way it's a detail but it shows there is low latency between me and the server (I'm not sure where the server is but I saw something about swbell in the iptables which makes me suspect it is in sw USA). Everything I did with it (installing packages etc) happened very quickly.

But the thing that impressed me most was... the documentation on their site. Very good indeed, great guides on setting up servers for Apache, Rails, Mongrel, iptables etc. Simple step-by-step instructions to go from a raw OS install (ubuntu gutsy for me) to a running site. Other hosting services I have used have had scrappy and out-of-date documents (oneandone) or I had to spend ages trawling forums for answers (site5: and with a shared hosting service like site5 setting anything up is intrinsically more difficult because of the shared hosting shackles). Slicehost appears to be a 'run-by-developers-for-developers' deal and feels very web 2 and geeky. Perfect.

Armed with the documentation my site is running under apache with a mongrel cluster serving up my rails app! And it is running very nicely, very snappy. The mongrel cluster is using 10% of my memory under zero load (I wouldn't dare do this on vpslink) and setting it up is not the most straightforward thing and I couldn't do it again without the slicehost docs. I would ditch apache and use pure mongrel but:

  • apache makes virtual sites very easy
  • if I ever wanted to move one of my drupal sites to this server I would need php and apache's url rewriting facilities (to get the clean urls working: the 'new wave' servers like lighttpd are great for serving static files but have too many shortcomings for anything beyond that).
  • I want multiple rails apps and I'm unsure whether mongrel can do that (I've been bitten by cherrypy and it's one-site-under-mod-python ethos so don't trust anything else yet).

So far Slicehost is looking very promising. And no, there are no referral links here. Vpslink are good but their slightly more expensive spry brand VPS's may be better for reliability. There aren't any other vps providers that I would consider. They are either the pile-high-sell-cheap types (oneandone) or poor/terse support (linode).

Petersblog is still on site5/drupal. Maybe, just maybe, I can make it my christmas holiday project to port it to rails. Maybe.


Filed under: rails slicehost

4 Comments

I had a complaint from a loyal reader about this site not rendering properly on IE. It got half way through my article on Ruby Metaclasses and stopped.

The problem was caused by my using the term <object> in my text and the wilki filter not changing the < and > into html entities. IE treated <object> as a keyword and tried to download a trojan or whatever it does in those circumstances. Presumably firefox saw that the semantics were totally wrong (for example, no attributes to direct it to a specific object) and ignored it.

Since I use firefox and I don't proof read ever article in every available browser this one slipped through.

Apologies for interruption of service.

And thanks again Dean for your concern.


Filed under: firefox ie

2 Comments