AOP – A story of how we localized a MMORPG with minimal effort

In Here Be Mon­sters*, we have a sto­ry-dri­ven, episod­ic MMORPG that has over 3500 items and 1500 quests, and with more text than the first three Har­ry Pot­ter books com­bined – so it rep­re­sent­ed a fair­ly siz­able chal­lenge when we made the deci­sion to local­ize the whole game!

 

The Challenge

From a tech­ni­cal point of view, the shear vol­ume of words is of lit­tle con­se­quence, although it is a sig­nif­i­cant cost con­cern. It’s the num­ber of places that require local­iza­tion that rep­re­sents a main­tain­abil­i­ty headache.

With a con­ven­tion­al approach, the client appli­ca­tion would con­sume a get­text file con­tain­ing all the trans­la­tions, and any­where it needs to dis­play some text it’ll sub­sti­tute the orig­i­nal text with the local­ized text instead.

We found a num­ber of issues with this approach:

  1. large num­ber of files – Domain Objects/DTOs/game log­ic/view – need to change dur­ing imple­men­ta­tion
  2. all future changes need to take local­iza­tion into account
  3. need to repli­cate changes across client plat­forms (Flash, iOS, etc.)
  4. hard to get good test cov­er­age giv­en the scope, espe­cial­ly across all client plat­forms
  5. easy for regres­sion to creep in dur­ing our fre­quent release cycles
  6. com­pli­cates and length­ens regres­sion tests and puts more pres­sure on already stretched QA resources

 

Sounds like a dark cloud is about to take per­ma­nent res­i­dence above all our heads? It felt that way.

 

Our Solution

Instead, we decid­ed to per­form local­iza­tion on the serv­er as part of the pipeline that val­i­dates and pub­lish­es the data (quest,s achieve­ments, items, etc.) cap­tured in our cus­tom CMS. The pub­lish­ing process first gen­er­ates domain objects that are con­sum­able by our game servers, then con­verts them to DTOs for the clients.

This approach par­tial­ly address­es points 3 and 4 above as it cen­tral­izes the bulk of the local­iza­tion work. But it still leaves plen­ty of unan­swered ques­tions, the most impor­tant was the ques­tion of how to imple­ment a solu­tion that is:

  • sim­ple
  • clean – it shouldn’t con­vo­lute our code base
  • main­tain­able – it should be easy to main­tain and hard to make mis­takes even as we con­tin­ue to evolve our code base
  • scal­able – it should con­tin­ue to work well as we add more lan­guages and local­ized DTO types

 

To answer this ques­tion, we derived a sim­ple and yet effec­tive solu­tion:

  1. ingest the get­text trans­la­tion file (the nuget pack­age Sec­ond­Lan­guage comes in very handy here)
  2. use a Post­Sharp attribute to inter­cept string prop­er­ty set­ters on DTOs to replace input string with the local­ized ver­sion
  3. repeat for each lan­guage to gen­er­ate a lan­guage spe­cif­ic ver­sion of the DTOs

 

For those of you who are not famil­iar with it, Post­Sharp is an Aspect-Ori­ent­ed Pro­gram­ming (AOP) frame­work for .Net, very sim­i­lar to Aspec­tJ for Java.

Here is a sim­pli­fied ver­sion of what our Local­ize attribute looks like:

 

To auto­mat­i­cal­ly apply local­iza­tion to all present and future DTO types (assum­ing that all the DTO types are defined in one project), sim­ply mul­ti­cast the attribute and tar­get all types that fol­lows our nam­ing con­ven­tion:

[assem­bly: Localize(AttributeTargetTypes = “*DTO”)]

and voila, we have local­ized over 95% of the game with one line of code!

and here’s an exam­ple of how an almanac page in the game looks in both Eng­lish and Brazil­ian Por­tuguese:

image

image

 

I hope you find this lit­tle sto­ry of how we local­ized our MMORPG inter­est­ing, and the morale of the sto­ry is real­ly that there is much more to AOP than the same old exam­ples you might have heard so many times before – log­ging, val­i­da­tion, etc.

With a pow­er­ful frame­work like Post­Sharp, you are able to do meta-pro­gram­ming on the .Net plat­form in a struc­tured and dis­ci­plined way and tack­le a whole range of prob­lems that would oth­er­wise be dif­fi­cult to solve. To name a few that pops into mind:

the list goes on, and many of these are avail­able as part of the Post­Sharp pat­tern library too so you even get them out of the box.

 

Links

Design Pat­tern Automa­tion

Post­Sharp

 

*you can try the game out on Face­book, HereBeMonstersGame.com or iPad (Mon­sters HD)