Mischiefblog
I WATN 2 MAEK GAEM!

The Halls of Reflection (Heroic) tax

Posted by Chris Jones
On December 27th, 2009 at 21:54

Permalink | Trackback | Links In |

Comments (1) |
Posted in General

After my, what, 30th wipe in Halls of Reflection Heroic, this time to a tank that wouldn’t pull waves back to the group but kept trying to fight on the altar, finally keeping Falric out of my healing range after I was feared in the opposite direction, I’m convinced Halls of Reflection is actually a gold tax on people using the random group tool.

I’ve run it successfully despite a lot of bad pugs but I much prefer doing it with a guild group. Becky saw how bad it was on normal mode today when she ran it with one of her Hunters. By comparison, Forge of Souls and Pit of Saron are cakewalks.

Maybe it’s because Halls of Reflection is a healing test, or maybe it’s because most pugs can’t seem to assist. When I ran it earlier today on Normal mode, I made sure everyone knew to assist off the main tank (a mediocre Death Knight, but it’s tough to be a good DK tank). At the least, a successful HoR group can pull 3k DPS per character, minus the healer and maybe the tank — any less and I’m out of mana or dead before I can keep the group’s health up. I feel like HoR was really built around the Holy Priest, even more so than the Tribunal encounter in Halls of Stone.

Oculus with four dragons, dismounted healer

Posted by Chris Jones
On December 27th, 2009 at 13:00

Permalink | Trackback | Links In |

No Comments |
Posted in Games

So we ran heroic Oculus with a dismounted healer (me) today. It was unintentional: I got knocked down early and landed on Treasure Island safely, where I healed myself up and started healing the other drakes. It was much easier to keep the rest of the group up as a T9 Tree than it was on a green drake. We won with only one other player getting dismounted.

Edit: My second Oculus of the day disbanded before I could pick up a drake. I replaced a healer who quit after a wipe on Eregos: people are still convinced this is hard, which just goes to show they never tried it before 3.3 nerfed him. Amber Void, Emerald Void, and Ruby Void are much more attainable now than they were a month ago.

The inevitable decline in HPS

Posted by Chris Jones
On December 26th, 2009 at 16:05

Permalink | Trackback | Links In |

No Comments |
Posted in Games

I’ve been running a lot of random heroics (10-15 a day on weekends — I’m putting together two sets of T9+) and have noticed that as the other players gear up, my HPS has done down faster than my Healing Spellpower has gone up.

In my last run, for instance, I got 1744.7 HPS for a total of 1,485,319 points of healing on a Halls of Lightning run. Two weeks ago, my HPS would have been closer to 2200 and I would have had to heal nearly 2 million points. At the same time, my overhealing has slightly declined (I’m better about only renewing HOTs when needed), and accounted for more potential healing than healing performed. Blame the Warlock or blame the HOts, the fact is that other players require less healing as they gear into Tier 9.

Role DPS Healing Taken Gear Score
Tank (Warrior) 1485.4 923,697 4473
DPS (Ret Pally) 2712.2 320,807 4850
DPS (Destro Warlock) 2479.7 265,365 4803
DPS (Enh Shaman) 3031.3 157,341 4850
Healer (Resto Druid) 125,574 4629

At this time, I only start finding my maximum HPS on raids where the entire group takes damage as once.

Examining the heal values themselves helps to show how overhealing occurs (ignoring crits):

  • Rejuvenation: 2001 per tick
  • Regrowth: 4600 hit, 1095 per tick
  • Lifebloom: 843 tick average, 1487 max tick; 2529 hit average, 8830 hit maximum
  • Nourish: 6409 average
  • Living Seed: 2598 average
  • Wild Growth: 770 average per tick
  • Glyph of Rejuvenation: 1175 average per tick

So as my healing spellpower has gone up from 2000 to 2500, my HPS has gone down from 2200 to 1700 because other players are better geared.

G13 WoW UI layout

Posted by Chris Jones
On December 25th, 2009 at 22:42

Permalink | Trackback | Links In |

No Comments |
Posted in General

Here’s my updated UI for World of Warcraft.

Buttons are laid out to match the Logitech G13 — the exact choice for each button is still being tweaked, but it’s pretty close to done. Main chat and Grid are next to each other to watch player health, discussion, and DBM warnings in the chat log.

Tanking is done using the same UI with different buttons (replacing the set by virtue of the extra bar groups with multiple talent specs).

(more…)

WoW patch 3.3’s impact

Posted by Chris Jones
On December 8th, 2009 at 08:09

Permalink | Trackback | Links In |

No Comments |
Posted in Games

In World of Warcraft, I’m playing one of two roles lately: tank and healer. Patch 3.3 has been released and here are the big impacts on those roles:

Classes: General

  • Area-of-Effect Damage Caps: We’ve redesigned the way area damage is capped when hitting many targets. Instead of a hard cap on total damage done, the game now caps the total damage done at a value equal to the damage the spell would do if it hit 10 targets. In other words, if a spell does 1000 damage to each target, it would hit up to 10 targets for 1000 each, but with more than 10 targets, each target would take 1000 damage divided by the number of targets. 20 targets would be hit for 500 damage each in that example.

(more…)

Signature of a Java service

Posted by Chris Jones
On October 28th, 2009 at 08:37

Permalink | Trackback | Links In |

No Comments |
Posted in Java

I’ve dealt with Java services at Amazon too long when I can spot one by the CPU/memory signature.

The classic signature of a long-running Java service

The classic signature of a long-running Java service


This is pretty typical of a long-running service garbage collecting with old generation objects. Note the CPU utilization as the VM removes old generation objects and subsequent drop in memory utilization.

Radar Revisited

Posted by Chris Jones
On October 14th, 2009 at 00:08

Permalink | Trackback | Links In |

No Comments |
Posted in Python

I’ve been snatching 30 and 60 minute blocks of time in the evenings and on the weekends to get back to work on my Radar test in Python with PyGame from nearly four years ago. PyGame 1.9.1 installed easily on my Windows box and OS X laptop and integrated well with Python 3.1 (on Windows) and Stackless Python 2.6 (on OS X). The only significant changes to be made in the code between Python 2 and Python 3 had to do with exception handling.
(more…)

Notes on Spring development

Posted by Chris Jones
On August 15th, 2009 at 21:28

Permalink | Trackback | Links In |

Comments (3) |
Posted in General

3.0.0.M3 library problems
I haven’t tried 3.0.0.M4 with my new development environment yet, but I had missing class and Antlr problems with 3.0.0.M3. I ended up using 3.0.0.CI-319 at the time to get a working Spring framework.

Creating a logging bean
Create an annotation package with a Log interface:

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
  
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
  
/**
* Injects a logger of an appropriate type into beans.
*/
@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Log {
  
}

Create a logger injector:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
  
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;
  
/**
* Auto injects the commons Log implementation into the bean when a field is annotated
* with Logger.
*/
public class LoggerInjector implements BeanPostProcessor {
  private static Map>String , Logger< loggers = new HashMap>String , Logger<();
  
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }
  
  public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        // make the field accessible if defined private
        ReflectionUtils.makeAccessible(field);
        if (field.getAnnotation(Log.class) != null) {
          String cls = bean.getClass().getName();
          field.setAccessible(true);
          Logger logger = null;
          if (loggers.containsKey(cls)) {
            logger = loggers.get(cls);
          } else {
            logger = Logger.getLogger(cls);
            loggers.put(cls, logger);
          }
          field.set(bean, logger);
        }
      }
    });
  
    return bean;
  }
}

Declare your logger bean in your application context:

<bean class="mypackage.annotation.LoggerInjector"/>

Attach the Logger to your class:

import org.apache.log4j.Logger;
 
import mypackage.annotation.Log;
 
// in your class fields
 
/**
* Logger
*/
@Log
private Logger logger;
 
// use it
logger.error("Invalid request type: " + requestType);

Interface-oriented design
Define your data objects and factories as interfaces (methods), then provide factory implementations to create or retrieve instances of your data objects:

<bean id="myDaoFactory" class="mypackage.factory.myDaoFactoryImpl"
  factory-method="getFactory" scope="singleton"/>

Autowiring
Use the Autowired annotation to automatically add beans to your consuming classes.

/**
* Storage engine.
*/
@Autowired
private Storage storage;

Non-SQL databases
Non-SQL databases should be handled through high level “use case” calls against a storage engine rather than direct puts and gets.

It’s elementary

Posted by Chris Jones
On August 7th, 2009 at 16:37

Permalink | Trackback | Links In |

Comments (1) |
Posted in Design Journal, Games

I’ve been considering what would make a good, unique quest. Putting aside Becky’s concerns about griefing, competition for mobs or clues, etc., and that this is intended for a text game (although it would work in a graphical game), I’ve got the skeleton of a design for generating mysteries that I’d like to try to implement sometime.

We’ll call it, for lack of a better term, Mystery Quest.

One outstanding question remains: do you believe players need feedback when collecting correctly clues, interviewing witnesses, and assembling evidence?
(more…)

Goodbye Daily

Posted by Chris Jones
On August 5th, 2009 at 16:35

Permalink | Trackback | Links In |

No Comments |
Posted in Work

While Amazon Daily isn’t shutting down yet, we’re losing our gateway (homepage) placement to another new service offering. This will cut our traffic down dramatically.

The last Amazon daily lozenge
Bet you never even noticed this widget, did you?

For me this represents the beginning of the end of an era. I was hired to work as a server software developer at Amazon for the Plogs project, which later turned into Amazon Daily. As the project has languished and priorities have shifted from enhancement to maintenance to life-support, I’ve been working on other things (like Musician, Author, and TV entity pages) but I’ll always have a soft spot for Plogs and a deep interest in scalable blogging aggregation and authoring platforms.