Above: Timelapse of the game being played
While learning Python, I created a board game called the ‘Game of Ur’ that could be played inside of Maya. To my knowledge, there aren’t any other similar scripts that allow you to play a board game inside of Maya.
The game was played by the ancient Mesopotamians around 4,500 years ago. The rules were deciphered from stone tablets written in cuneiform. This video by Tom Scott explains it, and shows how the game is played.
The game consists of a board with tiles, some of which are marked by a rosetta, which give the player an extra turn if one of their pieces land on it, and also prevent their piece from being pushed off the board by their opponent. The aim of the game is to move all 7 of your pieces around the board to the end before your opponent does, however the column in the middle of the path is shared by both players, so if they are able to land one of their pieces on their opponent’s pieces, the other piece gets sent back to the start.
Players to take turns to roll 4 dice, which have a 50% chance of a 1 value, and 50% of being 0. The total of all 4 dice is added up and the player is allowed to move one piece by that distance. The strategy comes from choosing which piece to move
I recently revisited the project and applied techniques that I have learned to it.
While the game doesn’t have any practical purpose, besides fun, it did offer me a unique programming challenge, building a game into software that was not designed to be used this way.
The code consists of a manager object, that keeps track of the state of the game, including player scores, dice roll values, current turn stage, and whose turn it is. It also serves as a reference point for all of the pieces to communicate with each other.
The code contains a parent class for ‘Interactable’ objects which refer to Python objects that are linked to a Maya transform node via a scriptjob. When an object is selected in Maya, the scriptjob is triggered, and searches the list of interactable objects. If the selected object appears in the list, it triggers the “update” function in the linked Python object.
This update function is then inherited and modified by subclasses of Interactable such as the dice and player pieces to take the appropriate action (if the manager’s turn stage is appropriate for that action. i.e. only allowing dice rolls at the start of a turn or after landing on a rosetta.)
I added some randomness to the positions of all of the pieces and dice, to give a more realistic appearance.
When the user first launches the script, it automatically creates the board, dice and all of the pieces, shaders for each, and a UI to display useful information, it also turns on the textured display of the viewport.