Building The Projector in Dextrous - Design Diary

The vision
When Tate Albert & I started talking about the game we’ve always wanted to play, we imagined a game that would be:
- Fully-cooperative
- An RPG with focus on discovery, exploration, and creativity
- A campaign that remembers player choices and tells an interesting story
- Filled with lots of things for players to unlock and discover as they progress in the campaign
- Driven by an interesting story
- Easy to learn
- Quick to set up and tear down
Over the past 2+ years we’ve been building a game we’re calling The Projector: a fully cooperative RPG roguelike deckbuilder about exploring strange worlds, unraveling mysteries, and finding someone you love. Most of the game’s action takes place in a psychic dreamscape, where reality and fantasy and memory all converge and player choices affect future discoveries.
We realized very early on that the only way we could make this game was by making it almost entirely card-based. Cards have numerous advantages for us over other traditional components, not least of which is that cards can build an evolving game board and allow the game itself to remember player choices and campaign game state in ways that other systems don’t.
But it turns out, this isn’t so easy. Making the game we want to play means building out thousands of cards, many of which are unlocked by other cards (which might in turn be unlocked by other cards…). For a game this complex and large, that means keeping all of the game data in spreadsheets, spreadsheets, and more spreadsheets.
It also means a lot of playtesting to find where the game sucks isn’t as much fun as it could be. This involves many iterations through small and not-so-small changes, all of which have to be maintained in the spreadsheets to generate cards. While virtual tabletops (VTT’s) make this sort of rapid iteration theoretically possible, we tried several card-building tools only to find that it would take a day to set up a new build of the game, even with custom scripting - not to mention the campaign issues.
Dextrous to the rescue!
Problem #1: Cards as gameboard
We want to transport players to many varied worlds, each of which has a different objective, a different feel, and different constraints, but all connected by the same basic ruleset augmented by the players’ evolving abilities. In the adventure phase of the main gameplay loop, players choose which world to explore, discovering the objective and advancing the campaign storylines. Exploration is done by moving figures on a map made of cards, meaning that most of the cards not only have unique fronts, but unique backs as well. The relationship between fronts and backs is different for each world.
For example, here is the opening world, which happens in real (non-psychic) space. This world has a fixed layout - a house is a house, at least this one is:

On the other hand, this world has a hallway and rooms and vents in specified rows, but the cards within the rows are randomized:

This world uses a classic TTRPG map approach, with players revealing the map as they go through a dungeon (the stacks of cards are those that the players have yet to reveal):

Being able to create all of these worlds with a two-person team requires a robust tool with strong data-driven features. Dextrous solves all of our problems very elegantly, and the team has a number of videos on the site to show you how all of this can be done.
However, our game has over twenty-five of these worlds to explore, each of which is between 15 and 96 cards in size. In addition, there are more than twenty other decks, containing hundreds of cards that are unlocked by player choices. So, yeah - anything close to rapid prototyping is hard, and requires thoughtful planning.
Much of that planning involves our card data organization, but we found pretty early on that one of the biggest limitations was going to be our card making tool. There are a lot of really good ones out there, for sure. But for us, getting changes into a VTT as quickly as possible was a make-or-break feature, and we found that most tools don’t do this with the speed we need.
For our use, Tabletop Simulator was by far the best VTT for our game. It is robust and has an entire ecosystem that other platforms are just starting to build out. However, when we started (B.D. - Before Dextrous), getting an updated copy of the game on the virtual table meant a day’s worth of work: updating the spreadsheets, using the spreadsheets to create new image files in the card maker, importing the image files into TTS to build deck objects (each of which had a max size of 7 by default), combining the decks where necessary, setting all the decks up, saving them as objects, saving them to the cloud, and finally saving the game. Anything - even a typo in a single card - meant redoing some of this and tracking what needed to be redone. All of this requirs lots of typing, which for me means lots of mistakes.
To speed up the process, we built custom scripts in Lua (Tabletop Simulator’s scripting language), but that had problems as well. For example, any time the number of cards in the deck changed, we had to change the scripts. However, scripting got the iteration process down to about 3-4 hours for a clean starting build.
The secret sauce of Dextrous, however, is that it is cloud-based. This means that the images can be stored in some server that lives in I-don’t-care-where-it-is, and the export function just spits out a JSON that I can copy over to my TTS save directory and I am good to go. (There are videos in the tutorial section that show how to eliminate this copy step, but quite frankly, that started to feel too easy.)
With Dextrous, full rebuilds dropped from hours to about 30 minutes, most of which is positioning all the decks on the table and saving the starting game in TTS. One of the most important insights we discovered was that spending less time setting up is better than spending more time setting up. Who knew?
Problem #2: Campaign state
The Projector is a story-driven campaign game. Players work together not only to unlock new abilities, but also to unlock new worlds and even changes within worlds. For instance, in some areas such as The Tomb (Figure 3, above), players can take actions that not only affect future runs of The Tomb, but also future runs in other worlds. Player decisions will show up later - sometimes many sessions later. Asking the players to manage that sort of “game memory” is too much to ask normal non-DM humans, especially if a group is only able to play a couple of hours a week. Other games have found systems of handling this with various levels of efficiency, but with cards you can simply have players replace or add cards from locked decks into the active decks to have the game “remember” player choices.
This is an amazing ability of cards: complex game states can be stored in the decks themselves. For instance, there is a deck in the game - the scenario deck - that acts in part as the timer deck seen in many cooperative games. However, in The Projector, the scenario deck evolves over time to reflect your choices and your advancement through the game; things you experience one session might show up many sessions later in this deck. As another example, there are two “hub” worlds - worlds through which other worlds may be accessed and unlocked. Since players visit these hub worlds more than other areas, they too evolve regularly in response to player choices to give players new experiences as they revisit them. Some of the worlds - like the Victorian murder mystery - swap cards in and out each run to create new possibilities each playthrough.
But that leads to another - much harder - technical difficulty in rapid prototyping. Let’s say a group is playtesting the full campaign, and they’ve played about 10 hours across five sessions. Chances are that they’ve eliminated, unlocked, and moved somewhere around 20-50 cards. Fixing a typo in a card or handling a major design change means rebuilding from scratch and then manually resetting the game state by “replaying” the campaign to that point (which means having kept card-by-card play logs on all 10 hours). Once you get 30 hours in, all bets are off.
Furthermore, for the more typical playtester who is interested in checking out the game for a single session, we set up various “checkpoints” - saved games on TTS that represent typical game states at various points in the campaign. This lets us take folks into later campaign stages without having to play through 20-40 hours of gametime to get there. However, if we have a change, guess what? All those saved games have to be rebuilt. We’re back to days of work, depending on the number of checkpoints we’re trying to recreate.
If only there were a cloud-based card making tool that persisted card images in the cloud so that changes would automatically show up in TTS! Could there really be such a tool? (Spoiler: Yes. It’s Dextrous.)
If “Mod Caching” is off in TTS, anytime you reload a saved game, TTS will reload the images using the image file specified in the deck’s JSON. This will work whether you have decks or partial decks or single cards, and it doesn’t matter where they are on the table or how they are ordered. Since the images are in the cloud, whenever we tell Dextrous to re-export, the cloud images are updated automatically. We don’t have to rebuild anything, we don’t have to reload the objects, and we don’t even have to copy the JSON files over to the TTS saved object directory. All that’s required to see the changes is to force TTS to reload the new images by reloading the saved game. And the amazing thing?
It just works.
It’s hard to describe how cool this feels! Iterations were costing us so much time that I had become concerned about the game’s feasibility. We were having to batch changes in such large chunks to avoid rebuilds that we were testing a version of the game that was a month old.
Most games won’t be as complicated as ours, but this benefit isn’t only for campaign or legacy games. Any card game that involves any level of deckbuilding (which is pretty much all of them) will benefit from this feature. For instance, if you’re making a more traditional TCG/LCG, one of the most time-consuming aspects of getting people in the game is setting up starter decks. In existing tools, you’re either going to have to build starter decks separately in the card-making tool (which means structuring your entire project around the composition of starter decks), build and maintain VTT scripts, or manually build starter decks every time you rebuild your project. With Dextrous, you build your project, set up your starter decks, and save the game. Then as you edit cards, just reload the saved game in TTS and the cards will all be updated and your starter decks will be there waiting for you. You can organize your data by the structure of the game and you can let Dextrous take care of the rapid prototyping issues. This is a…wait for it…game-changer.
As for our game, The Projector, we’re still in the development process, with about 1100 of the anticipated 1700+ cards built out so far.
We’re opening alpha playtesting soon to folks who are interested enough to sneak peek bits of an unfinished game, which would help us understand how we can make the game more fun for more people. If you’re interested in learning more about the game or in joining us for a playtest, give me a shoutout on Discord: @texan_in_vt or go ahead and join our (brand new) Discord channel.
In the meantime, keep building the game you want to play! We all win when more of us are making games we love.