Transforming a monolith browser-based game into a serverless AWS app (Part 1)
Tags: javascript, react, php, aws
Published: 2021-11-05 04:56:28

Like many software engineers, I have a hobby project.  It is the website [ninjawars.net](http://www.ninjawars.net), launched around 2003 and I have been hacking on it and releasing new features for decades.

## Refactoring a Browser-Based Game

Since I engineer web apps professionally full-time since 2007, and mainly work in React and serverless AWS these days, I am working on converting the existing app & browser-based-game over into React, using serverless Amplify.  Here is a glimpse of the legacy version 1:
![Ninjawars version 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8or9wpzvg10zjpl1h0wk.png)

On a subdomain of the site, I am developing a React + Amplify (+ DynamoDB + Cognito + Lambda) replacement for the PHP + jQuery + Postgresql legacy app.  Here is a snapshot of the React based site's homepage (allowing for a more mobile-friendly layout, and using Material-ui as a base for component based development).

![Tile and Themed Ninjawars 2 Homepage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u03rsmcxx2evet2ujlnr.png)

## Preservation of Behavior

There are a lot of features, functionality, and behavior to replace, and the paradigms of the current (EC2 hosted) site and a serverless lambda approach couldn't be further apart.  Here, for instance, is a snapshot of a bit of the content that has to be replaced:
![Page for attacking other ninja and NPCs near you](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vfidf1layx4iz1gmsv9.png)
...which involves a lot of heavy-duty back-end behavior.  Attacking other ninja, for example, triggers a combat round game loop that pulls in a wide variety of contributing factors.  You can use items, combat skills, and in the traditional jrpg sense clash hitpoints against hitpoints.  
![Considering whether to fight an opponent at all](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51e20rnf9r5dhh8emva5.png)

Combat could be a single round, or it could be tens of rounds with different items/skills taken into account for each.
![Combat After](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akepm2ng9lehq1htmijz.png)

## Comparing apples and oranges

In a traditional monolith, this all is par for the course.  You may write your UI as a view, but you put a lot of logic into controllers, in part because the ui, the routing, and the core logic are intertwined.  This has it's pros and cons:

 - One benefit of even going serverless is that it's easier to ensure and enact a separation between UI and backend logic.  In a monolith, especially with php, even with a templating system the two tend to blend together. 
 - There's also performance and cost.  An app that hits cloudfront first and has limited operational cost in an unused minute is exceedingly cheaper to pay for over the decades than a continually running pile of EC2 instances.
 - No really, cost: I suspect the cost of even a single load balancer to route to those EC2 instances may cause more of a budgetary hit than the serverless ecosystem, in the end, based on how the cost differences during development have gone.
 - Ok, here is the downside, though, which is not insubstantial:  Monoliths are easier to conceive, and easier to grow.  There's a reason so many developers start out on their own server and not on serverless.  Separation and abstraction increase the complexity. Having everything in one place makes integration constant, for better or worse.

## Nowhere to Go But Forward

If the two approaches fight, in the end serverless wins, if nothing else then because the paradigm of the web has shifted.  What was standard in 2003 (a monolith), begs for a different approach in 2021 (say a static front-end and thin-sliced microservices). In future articles I will go through this process more, comparing monolith to micro, and get into how to stay motivated for the process as a developer and how to help users survive the process when there may be two split codebases.  One part of that process is using the strangler-fig pattern (strangler fig pictured):

![strangler fig roots taking over a legacy trunk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/us9j83c3l06si1p2r4vg.jpg)

The strangler fig pattern allows slowly strangling out the legacy monolith in favor of the refactor, but without a sharp switch-over.  I'll get into how I am going about that with ninjawars 2 in later parts of this article.  See you there.