Game Designers Love XML
Product Managers Will Love SDUI
Imagine things with a bit of an inversion. Once the initial, bare-bones system is mapped out by the product team, development begins immediately. Once development has a working system, design or product then goes in and tunes the system iteratively. You have a decent boilerplate system, and the design may be 80-90% there. Development starts immediately, you end up with a well-tuned end product.
If you’ve ever poked around with game modding, you might notice that many games provide a fantastic amount of leverage to mod with without ever having to touch the code. How do they do this? Through the magic of XML tuning files.
What can Web learn from Games?
XML tuning files have a close analog in server-driven UI (SDUI). SDUI typically uses JSON to define how a component looks. For example:
{
"type": "Card",
"title": "Upgrade",
"cta": { "label": "Buy" }
}This, however, can go further. In addition to styling, you can also encode your data system to pick up queues for interactivity.
I’ve written quite a few game mods that encode a complex interaction chain: a particular effect is triggered, which on an auto-resolve curve; i.e., the effect is taken off after a given amount of time. On resolution, it presents a different effect, which in turn has its own auto-resolution. I didn’t have to touch the game scripts at all for these; these gameplay effects can be encoded entirely through XML.
To illustrate an example for the Web, imagine you knew you wanted to reward users “coins.” You’re not sure exactly how you want to grant or use those coins yet (economies are complex), and you want to experiment iteratively. If you have components specified through data, you can also define a field that specifies a number of coins to grant—on any component you want.
{
"type": "Button",
"title": "Upgrade",
"cta": { "label": "Buy" },
"coins": 100
}You could go even further and specify a level of randomness:
{
"type": "Button",
"title": "Upgrade",
"cta": { "label": "Buy" },
"coins": 100,
"randomness": 10 // granted +/- 10 the amount of coins listed above
}Or even specify a level of compounding:
{
"type": "Button",
"title": "Upgrade",
"cta": { "label": "Buy" },
"coins": 100,
"randomness": 10 // granted +/- 10 the amount of coins listed above
"gain": x * 1.01 // gain 1% of the initial value each subsequent time
}Decoupled, Event-Driven, Config-Driven Systems
When everything is specified in data files, your system becomes very easily auditable. Just as these data files are parsed into your code, they can be parsed into a configuration system where you can get an overview of each effect. For example, if you, as a product manager, wanted to get an overview of each interaction on your site that supports granting coins, that’s something that’s easily readable like a spreadsheet.
But how exactly do you parse and support these data files within your code as a developer? Through event-driven architecture. I once built a poker game with Solana blockchain rails that used websockets as the primary communication method between client and server. Contrasted to REST APIs, websockets are a push-pull model that require you to specify an event type for each event sent—such is event driven architecture. These types are easily leveraged in json files to enforce a data specification.
And using event-driven architecture has one massive advantage in particular—decoupling. When an event “producer” (e.g. a button is clicked) and an event “consumer” (e.g. a wallet counting how many coins you have) are decoupled, they do not know about each other. You can modify, redeploy, or even delete a consumer without touching the producer, and vice versa. This sharply reduces coordination cost and regression risk.
Consider an e-commerce product where the core checkout service emits an event called “OrderPlaced.”
The checkout team owns only one responsibility: validate payment, create the order, and publish that event. They do not know or care what happens next.
Design and product want to experiment with several things at once:
• a new post-purchase email flow
• a “people also bought” recommendation widget
• a loyalty points system
• a fraud-scoring model
In a tightly coupled system, each of those would require the checkout engineers to add logic, call new APIs, deploy new code, and take on risk. Product and design would have to file tickets, wait for sprint planning, and negotiate priorities just to run an experiment.
Decoupling vastly improves system extensibility. New behavior is added by subscribing to existing events rather than modifying existing code paths. So, as a designer or a product manager, you can attach a new analytics pipeline, billing rule, or notification system without having to have engineers change the service that emits an event “PlaceOrder.”
Conclusion
Data config-driven systems can fulfill a product team’s wildest dreams—and event-driven architecture is the engineering backbone that makes it happen. It’s embraced in many high-performance applications—embracing it can allow Web companies to scale their teams’ velocity to unprecedented levels, and provide extraordinary leverage for the business.

