Author Topic: Dev Log  (Read 2745 times)


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Dev Log
« on: January 10, 2018, 11:12:31 AM »
Dev Log: Creating the Card Management System

Greetings all! I was finding myself going down a bit of a feature creep/perfectionist lull with the production tools, so I decided to shift gears and work on our card management system. The card management system is the UI that allows the player to view all of the possible cards in the collection as well as create custom decks. If you’ve played CCG’s like Hearthstone, you’re probably familiar with what this system looks like, but just in case, here’s a quick breakdown of the elements:

  • Collection Management (Ability to view all of the cards)
  • Crafting (Ability to make new cards)
  • Deck Builder
    • View cards to place in deck
    • View cards in the deck (visualization)
    • Deck Stats
    • Ability to name deck
    • Number of each type of card in deck (Units, Spells, Equipment)
    • Average mana cost
    • Total mana cost
    • Card Quantity (X/20)
    • Sort By
    • Filter
    • Search
    • Back Out Button
    • Suggest Cards
    • “New” Indicator that appears over cards recently added to player’s collection
    • Deck Limit (Per card)
  • Party/Team Roster (A special case for Summoners Fate to also choose which characters are in your party).
Atm, I’m focused specifically on Deck Builder, as it is the most complex part of the system. The first challenge is layout, which is even more challenging for me because I support both portrait and landscape. The basic idea is to divide the screen into two parts (collection/cards available) and the deck visualization. The most intuitive approach is to drag cards from the collection and drop them into the deck.

My first step was to get a basic idea for the main layout of these elements. Portrait is the most limiting layout, so I started there. After some testing, I discovered I could fit about 3 cards across the narrowest dimension of the screen with the text still being readable. Additionally, I would support a “full size preview” for the user on tap to view the keywords and larger text. This would allow user to browse their collection 6 cards at a time. Additionally, I can fit the 20 cards needed to construct the deck as mini cards (showing only the icon and cost). As shown in images below, these numbers also work for landscape if I expand the number of columns.

Portrait layout for deck management. Cards in your collection are at the bottom, cards in your deck at the top.

Landscape layout for deck management. Cards in your collection are at the bottom, cards in your deck at the top.

Now that I knew the layout, the next step was determining how to effectively render and control display of all the cards. I decided to use Feathers, an open source library designed for AS3 and Starling, which has the exact components I need and (because it is open source) unlimited potential for me to customize for my game’s specific needs.

I use the “List” control component because it offers cell recycling. This is an absolute must for rendering 100+ items (particularly visual ones) because it vastly reduces the demands on the system to maintain/mask the hundreds of items the user will be scrolling. To reduce overhead as much as possible, I wrote a custom ListCellRenderer that takes the card data and renders it directly into a card visualization.

With this, I can get 60FPS scrolling performance. The only issue I’m still running into is that there is a slight “hiccup” the first time a user paginates to a new page of unit cards. This is because there is an overhead in the initial creation of the armatures to assemble the units. In several competitor games I’ve tested, this seems to be an acceptable “norm” though I would love a solution if any developers out there have an idea how to mitigate this.

Now for the hardest part: managing a texture atlas for 400+ cards. I also have to consider that with each game update, that number will grow as cards are added. In my previous dev logs, I’ve discussed how I can achieve optimal performance by scaling all assets to fit a single texture atlas (yielding only 1 draw call). However, this only works because each game instance contains a finite number of resources that I can manage without affecting quality. As the number of cards increases, it becomes impossible to fit all assets on a single atlas, so it’s necessary to paginate the atlas into multiple sheets.

This image shows the initial result of rasterizing the card images. At 400+ draw calls, application responsiveness is very sluggish.

I’m using Gil Amran’s open source DMT library to create my texture atlases dynamically from vector graphics. The library uses a rectangle packer algorithm to sort assets and place them on texture atlases, creating new atlases as needed. The algorithm is optimized to maximize use of area so that textures are packed as tightly as possible to reduce the total number of atlas sheets created. Generally, this works fine because most game levels can render on a single sheet. With hundreds of assets to manage however, this can result in an exponential increase in the number of draw calls when assets needed to render a layered display object (such as a character armature) are split across multiple texture atlases. For those familiar with the painter algorithm (see Daniel Sperl’s amazing depiction here) the best way to reduce draw calls and optimize performance is to plan your texture atlases according to how your game will display the assets.

This is why I use open source technology whenever possible: when modifications are needed to suit particular needs, I can examine the code and make the modifications as needed to adapt and evolve the software. And in turn, share these benefits with other developers once I’ve found and perfected a solution! In this case, the feature I needed was the ability to control how my texture atlases were being created based on how I would render the display objects.

To accomplish this, I created two properties “addedId” and “assetGroupId”. AddedId is a number indicating when something gets added to the raster list. AssetGroupId is a string identifier indicating that the asset to be rastered must have all assets within the same group added to the same texture atlas. Prior to rasterizing, I sort all of the assets by the addedId. Then, as items are packed into the texture atlas, I check to see if the next asset fits. If it doesn’t fit, I check to see if any of his “assetGroupId” buddies were added, and, if so, I pull all of those assets out of that atlas as well, then start a new atlas. Following this procedure, I was able to reduce draw calls down from 400+ to under 40 which, in turn, vastly improved the FPS and responsiveness of the application.

This image shows the draw call result of grouping the textures on each atlas according to how the game will render them. This is a 10X reduction from the initial test and results in substantially better application response.

Every choice has a trade off. In this case, my decision to break and start a new texture atlas rather than taking the next asset that fits can somethings result in an unnecessary number of texture atlases being generated. Where the original algorithm might have fit all of my assets into one atlas, the new algorithm might break it into two. At the same time, I find in practice that the tradeoff is worth it because I can guarantee more predictable performance by controlling which assets appear on each atlas.


  • Elite
  • Posts: 2
    • View Profile
Re: Dev Log
« Reply #1 on: January 11, 2018, 02:53:49 AM »
Thanks a lot for sharing the process with us, Ross! I really like the approach of using "addedId" and "assetGroupId" to find out how best to organize the atlas. Very smart!   8)


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Re: Dev Log
« Reply #2 on: February 07, 2018, 11:31:09 AM »
Dev Log 2: Solving the Tech Challenges of the Deck Builder

In my last update, I shared my solution for optimizing draw calls and performance of the deck builder by grouping assets that render together on the same page of the texture atlas. Well, what I hadn’t considered is just how much GPU memory 400+ cards consumes. It turns out that when rendering the cards at full screen resolution, I exhaust my 512MB of GPU ram and the game crashes. Asset grouping has its advantages when you know you have a finite amount of content, but with something like cards in a CCG, where the collection continues to grow, my previous solution was not going to work.

Back at the drawing board, I considered how an application like Google Photos works. To get the fast response time scrolling through the photos, it needs to render the images on the GPU (just like in the game). But how do you account for hundreds of photos without exhausting the GPU? I needed to conserve the available system resources (GPU memory) by unloading cards not being viewed and loading in the cards the player is scrolling to. Since I can’t anticipate the order in which player will view cards (depending on their unique collection and sorting filters they’ve applied) it’s no longer practical to group cards together on a shared atlas. Instead, I create a unique texture atlas for each individual card. This makes the system entirely module, allowing the loading/unloading of individual cards. It turns out loading and unloading from an image stored on the harddrive is very fast. But, my “all vector” based pipeline had a problem: I don’t have images stored on the harddisk, I’m creating them “on-the-fly” in memory. In order for this new approach to be practical, I needed to “raster” file versions of each card onto the harddrive into an asset cache (also similar to how Google Photos works when it stores thumbnails of your photo collection on your harddrive so you can quickly browse through them).

This brings us to another awesome feature of Gil Amran’s DMT solution: it supports asset caching out of the box. You simply set the “cache” flag to true and your vectors get converted to PNGs appropriately sized for crisp visual quality on any device. However, you still need to wait for the initial “raster” process (drawing all of the vectors into bitmaps) which, with 400+ cards, can be quite a delay. One thing I’m very keen on is providing the user with a fluid experience. Choppiness/delays in apps can be a big turn-off and send potential players looking elsewhere for entertainment. Rastering all the assets up front might take 10-20 seconds, dropping FPS in the application down to 0 during this process. This process would need to run:
  • Whenever the screen dimensions (screen area) changes. Not an issue on mobile, but needs to be considered for PC when changing the game window size.
  • Whenever the assets get updated
When this process happens, it’s important to communicate to the player what’s happening and show a progress bar. If the FPS drops to 0, they might believe the app has frozen. To solve this issue, I started looking at AS3 Workers, which is Adobe AIR’s solution to multi-threading or parallel processing. Normally, all CPU instructions operate in serial (one instruction at a time). FPS drops to zero because the CPU is bottlenecked with rasterizing the images. But, with multi-threading, I can tap into the second CPU core and have 2 sets of instructions running simultaneously without affecting the performance of the other.

To get the cards rasterizing seamlessly, I create a separate application, the BackWorker. When the main app boots up, it loads in the BackWorker app and sends it a job: “Hey, BackWorker, would please rasterize these vectors into PNGs while I entertain the player with a lovely progress bar?” BackWorker kindly obliges, allowing the user to maintain a 60FPS viewing experiencing of the progress. Even better, the BackWorker can do this job completely in the background. This means, I don’t actually have to have the player watch a loading bar if the assets necessary to perform the current task (ex: play the game) are available. Imagine this: The first time you boot up the game, you jump right into your first battle. While you’re playing, the BackWorker is building the asset cache of cards on your hard drive so when you go to open the deck manager the first time, all of the cards are available for you to browse. No waiting necessary!

All seemed well and good with this approach until I hit one final snag: While the spell cards use a single flat image to portray the card icon, characters in Summoners Fate consist of multiple body pieces that must be assembled to create the character. Some of these pieces (like wings and tails) require mesh transformations on the GPU in order to assemble correctly. That means, there’s no way to “pre-raster” a single flat image of the character. They are designed to be constructed as animated armatures. Well, the problem with that is that there is a substantial delay (several milliseconds) involved in creating an armature. While they may not seem like a lot, when a user is rapidly scrolling through a list of characters, those milliseconds add up into noticeable lag spikes, creating an undesirable, choppy experience.

I needed a way to capture the pose data of the character without having to go through the overhead of creating the armature each time the player scrolled. To accomplish this, I turned to my definitions editor to store the display data as a serialized string. Effectively, I wait for the animation to stop on a desirable pose, then “take a photo” that’s stored as text indicating the tree of necessary display objects and transformations necessary to render the character in that pose.

Smile for the camera, Dragon!

The hardest part here was determining how to capture the “mesh transformations” on things like the wings/tails/etc. Thanks to some helpful examples provided by Daniel Sperl, I was able to learn how to encode this into a series of number lists representing the indices and vertices structure.

Finally - one last stickler point with this approach: filesize. It was clear that storing all that mesh data would substantially bloat my definitions filesize. No one wants to download a 10MB definitions when a 1MB file will do. To solve this, I recycle the poses for units with common armature structures (ex: humanoid, dragon, quadruped). I leave the actual asset data abstract so that it can plugin the particular skins unique to each character without having to store display data for every single character.

At last, I have a working solution for browsing all the cards within your ever-expanding collection! See video below for the results.

There’s still more optimizations that can be made (additional flattening would help reduce the draw calls further and improve performance). But for now, I’m happy to have the functionality ready for the pre-release. We’ll get to these improvements later in the polish phase before WW release.


  • Elite
  • Posts: 2
    • View Profile
Re: Dev Log
« Reply #3 on: February 08, 2018, 12:10:24 AM »
Putting so much effort into details like these (providing a really smooth experience when browsing the cards) is what makes Summoners Fate so special. Thanks for sharing the process with us, Ross!  ;D


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Re: Dev Log
« Reply #4 on: February 16, 2018, 10:18:19 AM »
Putting so much effort into details like these (providing a really smooth experience when browsing the cards) is what makes Summoners Fate so special. Thanks for sharing the process with us, Ross!  ;D

Thank you so much! It means a lot to hear that. I agree that what makes indie games special is the care, love and attention to every aspect - ensuring a quality experience and a quality product through and through. The work isn't just a job, it's a part of you, and reflective of how you want the world to see you.


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Re: Dev Log
« Reply #5 on: February 16, 2018, 10:59:48 AM »
Dev Log 3: Campfire Menu and Campaign Design

Typically, I like to work towards “full completion” of each section before moving on, but, with playtesting and early access release a priority, I’ve shifted towards a “get everything functional” and then “go back and polish” style development.

With the general functionality of the Deck Builder working, I’ve moved on to the game’s main menu system. This is key in creating a cohesion to the experience and giving players the opportunity to use the game’s core features.

For the game’s main menu, I had three goals in mind:
  • Uniqueness: Immersion in the game world vs. ui/menu driven
  • Responsiveness: Support all aspect ratios, resolutions, and device orientations (portrait/landscape)
  • Accessibility: Fast load-in and ease of use
Very early on, I had envisioned this idea of a campfire with your heroes sitting around it. I wanted to instill a feeling reminiscent of the down-time in fantasy RPGs and create a sense of connection with the wilderness and exploration aspect of the world. Initially, I thought I would accomplish this with illustrated menus depicting a scene from a projected isometric angle. In practice though, this wasn’t going to work for achieving the second goal of responsiveness. I had already done a lot of work to support portrait/landscape on mobile, and I didn’t want a menu that was going to require landscape.

I’m not sure why it hadn't occurred to me earlier, but one day it hit me “Why not build the menu into the actual game engine (which already supports both orientations)?” So I created a quick mockup scene of a camp that you can see below.

The quick mockup I made of a campfire scene to inspire my development of an immersive main menu.

I started thinking about the types of objects you might interact with to access the game’s various features. Here you can see the plans for how the camp driven menu will ultimately look:

Here's where I'm planning to add interactive elements. The actual objects might be things like a caravan for the store, a tent for PvP, a table with battle plans for the campaign, etc. Each element will be labeled and rotate to match the orientation of the player's device.

The main menu is built entirely in the game's engine. To help achieve my goal of accessibility, I've optimized the loading process and taken advantage of the texture caching system I made for the deck builder so that everything you need to interact with the menu is readily available. For reference, many comparable games take 20-30 seconds or more after launching before you're in a "play-ready" state. I want the time it takes to boot up Summoners Fate and play to be less than 10 seconds. So far, it's about 7, leaving about 3 seconds to incorporate the multiplayer login.

In the center, you’ll have a campfire with your selected heroes sitting around it. Tapping the fire will allow you to switch out your characters and your new choices will be reflected back on the main menu screen. You’ll have a magical table depicting your cards. Here you’ll be able to do things like browse your card collection, edit your decks and eventually craft new cards.

This wireframe interface shows how the player will be able to edit and view their decks.

The campaign area will allow you to access the prophecy maps and single player missions. I’ve just started working on the functionality for these maps by creating gray box layouts and interactive nodes that can be programmed to specific or procedurally generated levels.

While this isn’t the most exciting screenshot, what’s notable is that the campaign map already supports all screen device dimensions and orientations (portrait and landscape). The map nodes all auto orient to face the viewing angle of the player.

Some players have asked “How long is the campaign?” I’m aiming to do something unique with it. Instead of a fixed story with a beginning and an end, my idea is to create episodic content, with each map being its own story. In some cases, the campaign is a scripted story, in others, its a strategic battleground where your choices will shape your adventure and outcome. My inspiration is pen and paper RPG campaigns. You don’t ever “finish” these kinds of games. When you complete a scenario or adventure, you play another and experience something new and exciting each time. Summoners Fate is being designed as a service that delivers continuous adventures and content.

Here’s an early concept that shows the vision for how these maps might look as art is added

While this particular example is linear, I’m building the engine to support non-linear paths. One of our ideas for a type of campaign you might experience in later game is a “rogue-like” adventure where you have limited lives to complete the mission in its entirety. Death of your Summoner or characters within any of the levels is permanent until the campaign is successfully finished or failed. At which point, you can select a new adventure. The spirit of this idea is to eliminate the “grind” that’s been heavily associated with mobile games and create something of an innovation. Instead of being continuously peppered with extrinsic reward drops, I want the motivation of our game to be intrinsically based, meaning that you play primarily for the satisfaction of overcoming the challenges rather than to gain rewards.

What do you think about these ideas and direction? I’d love to hear from you.
« Last Edit: February 16, 2018, 02:38:03 PM by KellyD20Studios »


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Re: Dev Log
« Reply #6 on: March 09, 2018, 12:42:42 PM »
Dev Log 4: Surprise and Trap Mechanics

Still recovering from surgery, I decided to use my first week back at programming to work on something light before diving into multiplayer code. Well, as the rule of software engineering goes, when a programmer believes a task will be easy, they are more often than not "surprised" to find the task is much more involved than expected. How appropriate that I should be so surprised working on the "Surprise and Trap" game mechanics.  ;D

What is a Surprise Mechanic?

In Summoners Fate, a Surprise is a card played with its target and effects hidden from the opponent until they are triggered by a game condition. This mechanic opens up a whole new catalogue of strategies for the more sneaky inclined players, such as placing hidden traps on the board that spring when the player's character walks over them. Traps were one of the most requested "abilities" from my players in Hero Mages, Summoners Fate's predecessor, so of course this time around, I aimed to deliver the feature.

In this video, an AI controlled Summoner casts a surprise Ice Trap, then, they use their knockback ability to push my gladiator into it, taking advantage of the trap's effect during their turn.

More than traps, Surprises are also a way to incorporate a common CCG mechanic known as an "interrupt" into an asynchronous turn-based game. Generally, interrupts are played by during an opponent's turn when they are attempting to do something (for example cast a spell) and you want to interrupt the action, say with a counterspell to stop that spell from happening. Since live interruption is impossible when you are playing a game asynchronously, one way to solve this is to premeditate the interrupt with a conditional effect. In Summoners Fate, counterspell is achieved by placing a hidden status effect on your caster. It has a condition "When enemy casts a spell, counter it". In this way, the game automatically interrupts your opponent on their turn, whether you are actively connected to their game or not.

Programming Surprises

The architecture of Summoners Fate supports surprise mechanics with the following structure:

  • Cards contain an action that performs any number of action effects. One type of action effect can affix a status effect to an object (unit or space on board)
  • Status effects can contain 1 or more attributes (modifiers to basic stats such as attack power or life) as well as any number of triggered abilities
  • Triggered abilities are actions that can respond to events and can have any number of conditions that must be true before executing the action's effect
  • Events are messages fired by the game when something happens, such as a unit entering a position or a spell being cast.
To program a surprise card, I write an action that affixed a status effect containing a trigger for a desired condition (such as when enemy casts spell) and executes desired effect. I do this using the definitions editor I wrote for the game. Pretty straight forward, right?

To make development easier, I created a tool for programming triggered abilities. It includes a "cheat sheet" that identifies what each event property maps to so I don't have to memorize all the permutations.

Well, that's what I thought until I started to unfold all the possible user-facing considerations about what a Surprise flow actually entailed.

Design Considerations

The first major design question I had was: When a surprise is played, what exactly happens? Is the opponent informed that a surprise has been played or do they not see anything until it the surprise triggers? How this question is answered has major implications on the player experience, including the perceived fun and fairness of the mechanic.

I spent a lot of time discussing this with players. Not showing the player anything at the time a surprise is played has the perception of a more "hardcore" experience, where players must rely on very subtle clues in the player's behavior (ex: not appearing to cast any spells on their turn, moving their units in odd patterns, etc.) to suspect there may be a surprise. On the other hand, showing a warning "Surprise has been cast!" creates immediate excitement and tension at the cost of losing a small element of the surprise. All agreed that only in practice can we really uncover what the experience will feel like, so it made sense to proceed programming the early warning system, with an option to turn this off during playtesting to try both options.

The next question, how are surprises tracked/stored? Well, it makes sense that traps placed on the board would naturally have markers indicating them. But, only the player who created the trap should see it, while the other player shouldn't see anything until revealed. For surprises attached to units, such as when a unit is attacked, do X, it made sense to store as effects on the unit's card, viewable when examining that card (but only visible to the creator of the surprise).

The complexity of how these items can be stored and tracked by the player suggested to me that there should be only 1 surprise allowed per target. It doesn't make sense to place multiple traps on the same tile if I can only effectively show 1 marker per tile. Interestingly, this also creates side mechanic for revealing/disarming traps where a player might try and place a trap on a tile already trapped by the opponent. Doing so would replace the existing surprise with a new one, ensuring to the placer of the new surprise that there isn't an additional surprise waiting on that tile and indicating to the placer of the old surprise that their opponent has played something on that spot.

Surprise User Flow

To help determine the list of tasks necessary to program the feature, I started by writing what the user flow looks like when a surprise is played.

  • Player casts a Surprise card. From their perspective, it casts like a regular spell. To the opponent, they see a “Surprise” card pop up, describing that the opponent has cast a surprise and that it’s effect will remain hidden until its conditions are triggered.
  • The player who casts the surprise will see a special status marker on the unit or space they cast it on. If it was a trap, they’ll also see the icon of the spell card appear on that tile as a marker.
    • The opponent will not see the marker nor the surprise status card when inspecting the board.
    • When casting surprise, do not change caster’s facing as this can reveal clues about the target.
    • When casting surprise, opponent should not see a feedback animation that reveals surprise target.
  • When the surprise is triggered, the card shower will reveal the card along with message and special SFX, “Surprise Triggered!” This will show for both players. The flow will mimic similar to if spell had just been cast, showing the card, then hiding card and playing spell animation, and then removing the status markers.
  • When a surprise is triggered, the undo action button should change to a replay action. It wouldn't be fair to use the undo action as a way to avoid triggering traps now, would it?
  • Each target can only have 1 surprise. If a new surprise status effect is added, remove the existing status.
As I began implementing, the work expanded, revealing other edge cases. For example, when a counterspell counters an enemy surprise, it should reveal the card that they were trying to cast (otherwise, the counterspell feels pretty lackluster).

I play a Counterspell surprise on my Summoner. When the Orc casts his Ice Trap (also a surprise), the Counterspell triggers, countering his effect as well as revealing what his surprise card was.

Other opportunities also revealed themselves. In the current implementation, counterspell triggers whenever an enemy casts a spell (regardless of where). But, with a tactical board, I can now add considerations, such as "Counter next enemy spell cast in line of sight of your Summoner." which creates a new dynamic on a widely used mechanic in other CCGs.

Naturally, surprises can be quite powerful and demand new strategies that can counter them. One such card, Revealing Light, reveals all of the surprises on board. Note that Summoners Fate does not distinguish between who a surprise has been revealed to. This means, your own traps are also revealed to the opponent when played.

Using Revealing Light, I can detect my opponent's Ice Trap and navigate around it to avoid being frozen.

Expect the Unexpected
My takeaway for fellow developers is "Always expect the unexpected" when developing a new feature, even if its one that seems straightforward at the onset. The nature of development is to expand like branches on a tree. It's not a bad thing, as opportunities for creativity present themselves with each new discovery, but, it is important to be mindful of timeframes, particularly when working towards a release date commitment. My initial time estimate for completing this mechanic was a couple days, and it took just over double that to complete the user flow. To avoid further impact to my release date, I'm making a conscious choice to stop further development here, get my multiplayer code working, and then see what new discoveries are made once the game is in the hands of players.
« Last Edit: March 09, 2018, 12:47:52 PM by RossD20Studios »


  • Elite
  • Posts: 52
    • View Profile
Re: Dev Log
« Reply #7 on: March 10, 2018, 02:51:53 AM »

I first saw the ice trap counterspell video on YouTube, without having read your explanatory text yet. I must say that I didn't understand at first that the ice trap was the countered spell. The fact that it is shown AFTER the counterspell is counter-intuitive in my opinion.

In this specific case of the trigerring spell being a surprise itself, I agree that the placeholder "surprise" card should be shown first, but I would then reveal its true nature by showing the ice trap card, and only then display the counterspell card.
I envision an animation like this:
1) Normal surprise animation showing the surprise placeholder card.
2) After a slight delay (to read or recognize the surprise placeholder card), show the actual trigerring spell card, and at the same time show the counterspell card, scrolling from the side of the screen where its caster's team is.
3) When the counterspell card reaches the trigerring spell card, then send it stops and the trigerring spell card gets pushed away to the other side (this is the low-intensive programming version), or it explodes/burns/spins out/etc. (for later development?).

Of course trigerring spells will not always be surprise cards. In the general case of normal spells, only steps 2) and 3) would apply.

Food for thought.


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Re: Dev Log
« Reply #8 on: March 10, 2018, 10:37:53 AM »
Thanks, Scribe! I like your solution, but there are some edge cases that I think might make this difficult to work in every situation. Let's suppose there are multiple surprise effects in queued that all respond to the cast event. In this case, they'll play in LIFO (last in, first out) order.

So, while it may be more direct to show the counter spell on top of the card that was countered, two problems are 1) The counter spell may not be the only surprise effect that triggers in response to the cast and 2) Difficult effectively show more than 1 card on screen on time and have both be clear/readable.

I do agree there is room for improvement, and that it could be communicated better that Ice Trap is the spell being countered. Since countering a surprise card is a special edge case, what if the animation of the card showing included a message such as "Spell Countered" while showing the Ice Trap?


  • Elite
  • Posts: 52
    • View Profile
Re: Dev Log
« Reply #9 on: March 10, 2018, 01:29:40 PM »
You have a point, I didn't think about multiple stacked surprises. Although you still would resolve them sequentially, right?
As for the difficulty of displaying two cards... you're far too modest, my friend!  :D

Anyway, in the end you're right. A simple mention can do the trick for now. It's non-essential stuff at this point. I should apply my own recommendations as far as keeping focus.  ;)
Let's table that for future enhancements.


  • Founder & Game Developer, D20Studios
  • Administrator
  • Posts: 96
    • View Profile
Re: Dev Log
« Reply #10 on: July 16, 2018, 01:34:00 PM »
Dev Log 5: Designing the Metagame of Summoners Fate

We’ve discussed and shared a lot about the characters, cards and tactical gameplay aspects of Summoners Fate. Now, I’d like to share more about our single player and metagame experience and how our approach sets us apart from other tactics card game and RPG experiences.

The original title I’d planned to call Summoners Fate was “Prophecies”, a name that speaks to how I envisioned our single player experience unfolding. Most RPGs focus on the journey of a single character and their impact within the world. With Summoners Fate, I wanted players to explore their own creative diversity by giving them the opportunity to command and experience the stories of hundreds of unique characters. Prophecies are about the player taking on the role of “Fate”, guiding the destiny of these characters, and discovering how to reach their maximum potential by choosing the right team members, cards and paths to explore.

With the "Prophecies" mechanic, you play the single player campaign as a series of episodic meta games (similar to a longer board game like Risk or an RPG experience such as a D&D campaign) where there is progression for the initial character choice and consequences to the decisions you make as you progress. Campaigns are replayable, and each "run" introduces a combination of hand-crafted and procedural elements. You'll build your team and deck as you progress and upon completion you will unlock additional characters and cards to play through in subsequent campaigns.

An early concept for a Prophecy map

Below are a list of the top 5 goals I have for the design of our single player. I’d love to get feedback from players - how do these goals align with your expectations for our game, do these feel like unique concepts in the context of tactics card games, do they sound exciting, is there anything you’d like to seeing here that we haven’t mentioned?

  • Create opportunities for meaningful player choices that encourage risk vs. reward thinking and have a permanent impact to the campaign run and lasting meta rewards. A meaningful reward is something that impacts the outcome of gameplay, such as unlocking a new character, while a meaningful risk permanently affects your progress (ex: permadeath, losing a character for the remainder of the run or even losing the campaign prior to its completion). Players might choose between an attempt to escape a dungeon with a rare relic or retreat with their lives. Attempting to escape with the treasure risks the player being defeated and losing all progress while potentially earning the chance to permanently unlock a new character or gain a benefit for the current run. Likewise, taking the safe route could allow the player to survive to the next stage, keeping what they have already earned. Another choice might be choosing to sacrifice a member of the team to rescue a new character, or choosing to rest and restore health or acquire a new upgrade. A tactical decision might be whether or not to play a card: Do I fireball the goblins in this room to avoid combating with my heroes and conserve health, or do I save my card for a future encounter?
  • Players need fair opportunities to assess their choices. While I want to the game to introduce a level of randomness to bring forward the excitement and the feeling of exploring/encountering the unknown, I don’t want randomness to make the gameplay unfair (ex: suddenly encountering an enemy that completely undermines the strategy you’ve been working to build without warning). I believe the best way to mitigate this is to give players some level of warning that they can use to adequately prepare for challenges. Examples: Player can choose from multiple paths in a branching saga map. Each node of the map should indicate things like the type of risk/reward the player might encounter. For example, indicating the environment as well as the potential types of monster spawns is important so the player can assess their deck strategy against the opponents. A player without a Cleric may not wish to risk encountering poisonous snakes and scorpions in the desert, while a Botanical Sage may prefer to travel through forests and other vegetated areas that she can exploit with her abilities.
  • The experience should seamlessly integrate and onboard users to deck building. Traditional CCG games throw deck building at the player after a handful of combat tutorials without allowing them to understand what/why they might choose certain cards to compliment their arsenal. I want our campaign to introduce the process of deck building and allow the player to experiment with the impact of their choices in small chunks at a time as they progress. This is accomplished by giving them limited choices in the beginning (ex: pick starting character) and then allow them to customize their deck (ex: pick 1 of 3 cards or pick 1 of 3 heroes) as they progress, slowly building their deck and strategy as they complete levels. As the player learns what works/doesn’t work about their choices, the game shall offer opportunities to hone and refine strategies (ex: replace a spell card for another or recruit a new hero to replace one that isn’t performing well in the team the player has designed).
  • The total completion time of a Prophecy campaign should be approximately 3-4 hours. Summoners Fate is a game about endlessly experimenting with creative diversity rather than perpetual grind to a final end state (ex: maximum level or completion of a narrative). We want every encounter, every choice, to have an immediate and obvious fun impact to the gameplay so that players can fully realize the potential of their strategic choices as quickly as possible. A 3-4 hour duration feels right to grant this potential with plenty of time and energy for players to explore new creative solutions in future playthroughs. A possible division of this would be 3 continuous maps, each containing an hour of content. That means each map might have 6 playable nodes, with each node taking approximately 10 minutes. Individual battles would last between 2-5 minutes so that they can be completed within a single session while playing on mobile. Combat/exploration nodes would be multi-staged (having a series of battles) while other nodes (rest/upgrade/merchant/special encounter) would be single staged.
  • Deliver episodic content with high-replayability. I want Summoners Fate to offer limitless adventures and keep our players engaged for years. With an episodic content structure, we can regularly release a variety of prophecy types, ranging from scripted narrative episodes to entirely procedurally generated challenges, and ensure gameplay is constantly evolving, new and exciting. I imagine campaigns and story elements tied together with new cards and characters, allowing us to expand upon our single player and multiplayer experiences together. I want our content to have a lot of value to our players. Being able to replay these campaigns with different characters and diverse chance encounters is important so players can experience how their outcome changes while experimenting with new strategies and playstyles.
« Last Edit: July 17, 2018, 02:21:24 PM by KellyD20Studios »


  • Elite
  • Posts: 3
    • View Profile
Re: Dev Log
« Reply #11 on: July 18, 2018, 04:43:14 AM »
I love the ‘Prophecy’ approach as it reminds me of old D&D modules. One storyline would usually contain 3-4 modules telling a grander story.

Length I think is good for mobile. Each node of 5-6 encounters / explores of about 5-10 minutes would fit a commute home.

Tying new prophecies to results of completed runs would be great. Here are some thoughts:

Prophecy 1: You rescue Jax the Paladin. Another prophecy could be his backstory and how he arrived at a point to need rescuing.

Prophecy 2: You make a decision to sacrifice Herman, leader of the dwarves to save the group from death. This could open 2 new prophecies. One of what would happen back in his realm after his people hear of his death, maybe form the point of view of his son and heir. That could also branch again to:

A: Does he then journey out and meet up with and join the group that his father sacrificed his life for

B: Does he plan vengence on them and recruit a team to hunt them down and kill them. This branch also leads to the question, do those characters get perms death :)

Seasonal prophecies would be nice too. I am a long time WOW player and remember when events like Brewfest and Hallowd Eve were fun.

These are just a few items that popped into my head after a quick read at breakfast :)