Write Warz

Try it right now on Steam!

Writing, voting, and adding a new sentence to the story.

Players write together to build out a story in Write Warz. Each player submits a single sentence then votes on their favorite one to get added to the story before a new round starts. Mini games, writing challenges and player abilities break up the flow of the game and shape the final product. At the end, points are counted and a winner is crowned.

Write Warz is a multiplayer party game developed by Boltz Entertainment that has won two Dreamhack Audience Choice Awards. I joined the team in July 2024 as a senior programmer and my duties quickly ballooned to touching, understanding, and ultimately refining every system in the game.

A large amount of the legacy code needed refactoring as the final product evolved and the design requirements changed. I spearheaded much of this change, drilling the team with programming fundamentals like “Single Source of Truth,” “Don’t Repeat Yourself,” and the dangers of circular references and tight coupling. I additionally introduced the team to many object oriented design patterns like Observer, Abstract Factory, and Template Methods. I became a champion for clean, readable, and reusable code.

Genre: Party/Writing
Timeline: Joined the project July 2024, released into early access March 6, 2025. Development ongoing.
Engine: Unity
Platform: Windows, Mac
Team size: 10 core and 20+ freelancers and interns
Role: Senior Programmer
Website: https://boltzentertainment.com/
Steam Page: https://store.steampowered.com/app/2477650/Write_Warz/ (free to play!)

Responsibilities

  • I designed a bespoke AI system utilizing Large Language Models to efficiently generate sentences for bots.
  • I redesigned the backend system for character abilities with highly reusable and extendable code, streamlining the creation of new abilities. This created a robust system that removed a large amount of duplicated code.
  • I spearheaded transitioning the team to track their tasks using Trello. Task allocation before I arrived was through individual text files and Microsoft Teams messages. Tasks in Trello are organized first by 2-4 week sprint, with specific goals for the project and each team member. We mark tasks for type with an automation I wrote that automatically organizes new and completed tasks by priority.
  • As the team grew, I took on a managerial role for the group of 5 interns. I became the go-to for training and asking questions and developed a working environment that encouraged giving something an attempt while also not being afraid to ask a question.
  • I learned and touched nearly every corner of the code base, learning all of its intricacies and quirks. This knowledge allows me to fix any bug I came across, as small as a misaligned UI element to as big as a fundamental flaw in the voting system. In addition, my knowledge became a valuable asset for everyone on the team that needed direction to a specific reference or subsystem.

Spotlight: AI

Other than the greyed out sentence, all sentences here were generated by my AI. This is in the custom Game Mode with the Bots Use AI setting switched on.

I led the effort to integrate modern AI technology into the game to enhance the single player experience. The AI would be running locally on the players computer to avoid overhead and privacy issues from sending prompts to a 3rd party. My first step was exploring various solutions and technologies in a testing environment before presenting my findings to the team. Then I built the backend from the ground up to integrate pre-trained AI into our game files and then allow it to work with our systems. This includes allowing it to both write intelligible and interesting sentences as well as vote on the best sentences.

AI in this day and age has many limitations. The biggest are space and performance. Models are large and must be kept in memory for best performance so the AI system fights with the flashy visual effects for that memory and access to the GPU. I implemented a number of standard optimizations such as automatic prompt caching and context reduction to reduce the inference time by over 50%.

The other most notable limitation is that I need AI to play along; I need the AI to write sentences that followed the story and not reference the internal prompts. At the required number of parameters, instruct models were not enough to prevent the classic “Here’s your sentence:” that occasionally shows up. I heavily utilize Logit Bias in the system to prevent certain terms, such as “sentence”, to reduce the chance of the AI from becoming meta. I also implemented a bespoke filtering system that removes most instances of prompt references as well as censoring and possibly forcing a retry if prohibited patterns or terms are detected.


Spotlight: Character Abilities

One of my first duties was to create abilities for the ten characters in the game. The backend system had been originally designed by another programmer. As I learned the code base and implemented the characters, I noticed several possible improvements that could be made. For example, both Valthrax and Sigrun interacted with the Good Judgement system so I was able to extract that functionality and remove dozens of lines of nearly identical code.

The original system was designed for a rigid situation in which every character ability triggered at the same time near the end of the round. As more abilities got designed and reworked, those conventions were broken. More abilities triggered in the middle of the writing or voting rounds. I then reworked the system to allow a wider variety of trigger conditions and timings.

Evelyn’s ability reduces everyone’s max character limit when she wins a round.


Spotlight: Game Speed

This bat animation used to last nearly 3 seconds by itself, and would play once or twice every round.

A major issue I saw in the game when I joined the project was how slow it felt. It was difficult to identify just one issue, but each section and animation felt a little too slow which compounded into an unpleasant game experience.

I took on the project and implemented a large number of changes to increase the pace of the game, reducing overall game time by over 30% without reducing the time players were actually playing the game: writing sentences or voting on them.

The first most obvious change was that the visual effect after voting lasted much longer than necessary. It looked nice, but overstayed it’s welcome. Other small changes included, letting the player write a bit earlier before the round has officially been announced, and giving the player more time to read the story by not transitioning to a blank screen each round.

The largest change that I designed was removing the breakdown that occurred every round. After voting on a sentence, a long animation and info screen would appear. It showed how many points each player earned and the winner was revealed with a dramatic pedestal animation that took nearly 15 seconds. I first reduced this pedestal animation, and then eventually removed this entire state. I replaced it with a simple reveal for the winner with a bit of fanfare and ribbons for the top 3 before transitioning immediately back to the writing phase. The full point breakdown was then moved to an intermission that occurred halfway through the game.

The new winner reveal that occurred in the writing area.


Spotlight: Pirate Theme

Each match of the game has a theme. A theme defines certain rules for the gameplay as well as giving guidance for the story itself. The game was launching with two themes: Horror, a very basic theme with few unique twists, and Pirate, a much more complex and interesting theme with many theme specific resources and a shop.

I was chosen to lead development of the pirate theme. We had a specific design document but I had a large hand in shaping the trajectory of the theme. For example, the original design required the players use cannonballs during the shop state, but I thought it would be more interesting and exciting if the players could shoot each other while writing their sentence.

Getting ready to shoot someone with a cannonball while another player is also getting hit. Cannonballs damage the player costing them gold to repair as well as adding random letters to their sentence, disrupting their writing.

A look at the Pirate shop. The word contract bounty shows which word you’ll have to use if you purchase.

The shop went through multiple iterations as well. The original shop had bounties you could purchase that would give you additional gold if you had good judgement or won a round. These bounties were difficult to balance around because they were either too bad to buy or always worth purchasing. This was replaced with the more interesting system that allowed players to buy one of their choice of bonus words to include in their sentence. Now, even if a player buys a bounty every round they still have a choice to make as to which bounty to purchase.

Many of the plot points, minigames that disrupt the flow of the game, were implemented by the team of interns. I oversaw this progress personally and was the main point of contact throughout the process for the interns.


Spotlight: Reconnecting

When I joined the project no consideration had been given to reconnecting. Though the game is almost entirely server authoritative, there were many client objects that were set up when the game began and many multi round effects that were only initialized when they triggered.

I engineered a simple system using an interface IReconnectable that allowed any MonoBehavior to define its own reconnection behaviors. This retained locality and allowed the main reconnection code to be state and implementation agnostic. The reconnect system initializes the major controller objects then runs reconnecting code for any reconnectable objects on both the server and the client. I had to implement a priority system to determine the order of reconnection calls. Some objects depended on the state of other objects; for example the UI relied on the initialization of backend managers that synced points and player names.

This system allows reconnecting to be independent from an object’s behavior. Often reconnecting just needed to sync a few variables, for example each player’s points, then run the usual initialization code.


Official trailer for Write Warz.