Inspiration

It's time to bring a little fun to Teams! Whether you need to blow off some steam with work colleagues, or you’re a student who wants to interact with your home-schooled friends you haven't seen in forever (thanks COVID), playing a game together is just what the doctor ordered! Teams is the platform that already connects people, why not leverage it to play dice games! Who says “collaboration” can’t involve some fun!

What it does

The Dice app provides a flexible platform for a group of people to play dice games right inside of a Teams chat. It offers several tools depending on your needs:

  • Ad-hoc dice rolling based on dice notation. This option is great if you’d like dice rolls to be part of an active chat stream. Just instruct the bot to roll dice and it will return a card with the results of your roll.
  • “Open Play” dice rolling game board. This option is perfect if you’d like an interactive “game board” that allows multiple players to roll dice by clicking buttons and also see the roll history all in one place. Just ask the bot for an Open Play game board and it will return a card that all people in the chat can interact with.
  • “Pig” and “Midnight” game boards. The app also has built-in dice rolling games. In this case the app will control the game boards by enforcing the game rules, directing player turn and keeping track of scores!

More details on my website: https://gaiersoftware.com/teams

How I built it

The app is built in C# using ASP.NET Core 3.1, the Microsoft Bot Framework and Adaptive Cards. I have a full-time job and 4 school aged kids, so this was a nights and weekend project! Most of the work was completed during my Christmas vacation.

Challenges I ran into

Cards in Teams aren’t exactly designed to be stateful and for multiple people interacting with them at the same time. There are several challenges I had to overcome:

  1. I needed a way to maintain and propagate state as part of each Adaptive Card. Basically I devised a technique to embed “context” data inside hidden elements on the card. This context is round-tripped and updated with each interaction. Examples of context include player info, turn, score, game state, roll history, etc. This approach was then standardized and extensible so I could apply to all the Adaptive Cards and game logic in my app.
  2. I had to devise a scheme to control who has “permissions” to click certain buttons on the card. Since everyone in the chat sees the same card, the app needed a way to only allow the “current” player to interact with the card.
  3. I needed a system to handle the case where multiple people simultaneously click the “Join” button to join a game, and for the bot to collect all of that and update the card with everyone who joined. Each join message request is processed on different ASP.NET Core threads, so you can’t simply have the bot update the card in response to each join message as you’d have missing information about people who joined. Instead you must collect all the join requests and update the card in a coordinated out-of-band fashion (e.g. on background thread) on a sliding window basis. This approach ensures card updates contain complete and timely updates. However, updating existing cards on a background thread isn’t built into the framework, so that’s something I had to build.
  4. Lastly, Adaptive Cards are very limited. So to achieve the application-like UI in my cards required me to really push the limits of Adaptive Cards and come up with creative techniques to achieve the layouts I desired.

Accomplishments that I'm proud of

I'm proud of challenges I overcame above, and for the generic framework I designed that will enable me to add more dice games to the app with minimal effort.

What I learned

I learned a lot about Teams app development and the Microsoft Bot Framework. They're cool platforms and frameworks!

What's next for Dice App

I'd like to add more dice games to the app. Next up is likely some sort of Poker Dice game where players ante each round and roll for the best Poker "hand"!

Built With

Share this project:

Updates