The Tri-Z Architecture: a Pattern for Layering ZIO Applications in Scala

From the article/tutorial:

After working on several different services and spending a lot of time improving the code to make it easier to use, I discovered a pattern for layering my applications that I found very useful.

...

My main job is writing game servers, and these typically have the following characteristics:

  • Heavy business logic: game rules are complex, and each player action requires validations (to prevent illegal actions) as well as calculations (to determine the outcome).

  • High concurrency: in multi-player games, different players may perform actions at the same time, and those actions may impact each other.

  • High performance: we need to support a large number of players and respond to player actions with the smallest latency possible. This also means that we try to keep the state loaded in memory rather than reading/writing it for each request.

To handle these with ease, I organized my code into these three layers:

  • The inner core only contains pure business logic (using the ZPure data type).

  • The middle layer consists of atomic state operations (using the ZSTM data type).

  • The outer layer is where we run side effects (using the ZIO data type).