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

You can become a serverless blackbelt. Enrol to my 4-week online workshop Production-Ready Serverless and gain hands-on experience building something from scratch using serverless technologies. At the end of the workshop, you should have a broader view of the challenges you will face as your serverless architecture matures and expands. You should also have a firm grasp on when serverless is a good fit for your system as well as common pitfalls you need to avoid. Sign up now and get 15% discount with the code yanprs15!

In Here Be Monsters*, we have a story-driven, episodic MMORPG that has over 3500 items and 1500 quests, and with more text than the first three Harry Potter books combined – so it represented a fairly sizable challenge when we made the decision to localize the whole game!

 

The Challenge

From a technical point of view, the shear volume of words is of little consequence, although it is a significant cost concern. It’s the number of places that require localization that represents a maintainability headache.

With a conventional approach, the client application would consume a gettext file containing all the translations, and anywhere it needs to display some text it’ll substitute the original text with the localized text instead.

We found a number of issues with this approach:

  1. large number of files – Domain Objects/DTOs/game logic/view – need to change during implementation
  2. all future changes need to take localization into account
  3. need to replicate changes across client platforms (Flash, iOS, etc.)
  4. hard to get good test coverage given the scope, especially across all client platforms
  5. easy for regression to creep in during our frequent release cycles
  6. complicates and lengthens regression tests and puts more pressure on already stretched QA resources

 

Sounds like a dark cloud is about to take permanent residence above all our heads? It felt that way.

 

Our Solution

Instead, we decided to perform localization on the server as part of the pipeline that validates and publishes the data (quest,s achievements, items, etc.) captured in our custom CMS. The publishing process first generates domain objects that are consumable by our game servers, then converts them to DTOs for the clients.

This approach partially addresses points 3 and 4 above as it centralizes the bulk of the localization work. But it still leaves plenty of unanswered questions, the most important was the question of how to implement a solution that is:

  • simple
  • clean – it shouldn’t convolute our code base
  • maintainable – it should be easy to maintain and hard to make mistakes even as we continue to evolve our code base
  • scalable – it should continue to work well as we add more languages and localized DTO types

 

To answer this question, we derived a simple and yet effective solution:

  1. ingest the gettext translation file (the nuget package SecondLanguage comes in very handy here)
  2. use a PostSharp attribute to intercept string property setters on DTOs to replace input string with the localized version
  3. repeat for each language to generate a language specific version of the DTOs

 

For those of you who are not familiar with it, PostSharp is an Aspect-Oriented Programming (AOP) framework for .Net, very similar to AspectJ for Java.

Here is a simplified version of what our Localize attribute looks like:

 

To automatically apply localization to all present and future DTO types (assuming that all the DTO types are defined in one project), simply multicast the attribute and target all types that follows our naming convention:

[assembly: Localize(AttributeTargetTypes = “*DTO”)]

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

and here’s an example of how an almanac page in the game looks in both English and Brazilian Portuguese:

image

image

 

I hope you find this little story of how we localized our MMORPG interesting, and the morale of the story is really that there is much more to AOP than the same old examples you might have heard so many times before – logging, validation, etc.

With a powerful framework like PostSharp, you are able to do meta-programming on the .Net platform in a structured and disciplined way and tackle a whole range of problems that would otherwise be difficult to solve. To name a few that pops into mind:

the list goes on, and many of these are available as part of the PostSharp pattern library too so you even get them out of the box.

 

Links

Design Pattern Automation

PostSharp

 

*you can try the game out on Facebook, HereBeMonstersGame.com or iPad (Monsters HD)

Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter


Hi, I’m Yan. I’m an AWS Serverless Hero and I help companies go faster for less by adopting serverless technologies successfully.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.


Skill up your serverless game with this hands-on workshop.

My 4-week Production-Ready Serverless online workshop is back!

This course takes you through building a production-ready serverless web application from testing, deployment, security, all the way through to observability. The motivation for this course is to give you hands-on experience building something with serverless technologies while giving you a broader view of the challenges you will face as the architecture matures and expands.

We will start at the basics and give you a firm introduction to Lambda and all the relevant concepts and service features (including the latest announcements in 2020). And then gradually ramping up and cover a wide array of topics such as API security, testing strategies, CI/CD, secret management, and operational best practices for monitoring and troubleshooting.

If you enrol now you can also get 15% OFF with the promo code “yanprs15”.

Enrol now and SAVE 15%.


Check out my new podcast Real-World Serverless where I talk with engineers who are building amazing things with serverless technologies and discuss the real-world use cases and challenges they face. If you’re interested in what people are actually doing with serverless and what it’s really like to be working with serverless day-to-day, then this is the podcast for you.


Check out my new course, Learn you some Lambda best practice for great good! In this course, you will learn best practices for working with AWS Lambda in terms of performance, cost, security, scalability, resilience and observability. We will also cover latest features from re:Invent 2019 such as Provisioned Concurrency and Lambda Destinations. Enrol now and start learning!


Check out my video course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. There is something for everyone from beginners to more advanced users looking for design patterns and best practices. Enrol now and start learning!