Marquis: A networked card game engine


Aug. – Sep. 2016
HLAPI Unity Networking, define server/client boundaries.
Dec. 2016 – Present
Modular actions and conditions, gameplay logic.
Restructure option and asset activation procedure, client-side animation stack.

A 2-4 player networked card game engine. Built in Unity.



Hearthstone was my first digital card game and the first card game I really got into. The same friend who inspired me to work on Rog came up with the idea of moving beyond the limitations of a physical card game and pushing the boundaries of digital card games, similar to Hearthstone.


First time doing any networking using Unity. Took some time to intuit the chain of authority and how to handle calls over the network. Wanted absolutely no way for clients to gain an unfair advantage, so any information the player cannot see is not delivered to the client by the server.

Moving Cards Around

I’m a very game feel-oriented programmer, and if the game doesn’t feel good to play, I will get bored pretty quickly. So the first thing I did was make moving cards around feel good.

Transmitting card movements to other clients. Because all players see their own cards and the assets on the board from the same perspective, each card will move asymmetrically on each client’s screen. Created a quick and dirty way to get it to work. Following the compression-oriented programming approach, this is just a test iteration for when I develop a real manager.

Game Editor

Created a GameDefinition editor. Lets designer create classes, options, and assets. Encoded in XML then loaded by clients at runtime. When conflicts arise, server has authority. Clients cannot affect game logic.

Polymorphic Game Actions and Conditions

Game actions and conditions inherit from their respective base classes. Allows them to be processed in the same way and be transferred. This isn’t implemented yet.


Targeting proved to be very complex. Boiled down to three parameters “Target/All”, “Hostile/Friendly”, “Player/Son/Asset”. Required many iterations and a lot of careful thought to figure out which elements needed their own targeting criteria.

What eventually worked was this:
Each condition and action has its own targeting parameters. Options and assets that require a specific target would require any targeted Conditions and Actions to use the same targeting parameters. Anything that targeted All can use any parameter they want.

Took more iterations to realize that conditions used to initiate an activate should not evaluated the same way as conditions used to filter out target candidates.

Most problems understanding how to proceed were caused by over-designing instead of approaching the problem by its simplest parts. Reducing target acquisition to a simple “get all valid targets based on targeting parameters” formed the base that helped me restructure the code into a much cleaner solution.

Next Steps

Next need to clearly define an activation stack and a way to queue animations to play on the clients. Tools to add custom attributes to assets and options? Ways to track global conditions?

Also need to re-evaluate whether the current design is fun or not, but this comes after. Moving from a resource-generating game into a combat game.