text:
Summoners Fate => Game Updates & News => Topic started by: RossD20Studios on January 10, 2018, 11:12:31 AM
Title: Dev Log
Post by: RossD20Studios 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)
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)
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.
(https://summonersfate.com/images/forum/devlog/deckLayoutPortrait.png)
Portrait layout for deck management. Cards in your collection are at the bottom, cards in your deck at the top.
(https://summonersfate.com/images/forum/devlog/deckLayoutLandscape.png)
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 (https://feathersui.com/), 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.
(https://summonersfate.com/images/forum/devlog/deckLayoutnonOptimizedDrawCalls.png)
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 (https://manual.starling-framework.org/en/#_the_painter_s_algorithm)) 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.
(https://summonersfate.com/images/forum/devlog/deckLayoutOptimizedDrawCalls.png)
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.
Title: Re: Dev Log
Post by: PrimaryFeather 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)
Post by: RossD20Studios 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.
(https://summonersfate.com/images/forum/devLog/characterBuilderPose.jpg)
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.
Post by: PrimaryFeather 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
Quote from: PrimaryFeather on February 08, 2018, 12:10:24 AM
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.
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.
(https://summonersfate.com/images/forum/devLog/campfirePortrait.jpg)
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:
(https://summonersfate.com/images/forum/devLog/mainMenu.jpg)
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.
(https://summonersfate.com/images/forum/devLog/deckBuilder.jpg)
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.
(https://summonersfate.com/images/forum/devLog/campaignMap.jpg)
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.
(https://summonersfate.com/images/forum/devLog/summonersFate_prophecyMap.jpg)
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.
Post by: RossD20Studios 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?
(https://summonersfate.com/images/forum/devlog/d20StudiosTriggeredAbilityEditor.jpg)
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.
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.
Post by: Scribe on March 10, 2018, 02:51:53 AM
Ross,
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.
Post by: RossD20Studios 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?
Post by: Scribe 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.
Post by: RossD20Studios 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.
(https://summonersfate.com/images/screenshots/summonersFate_prophecyMap.png)
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.
Post by: Gundam0518 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 :)
Post by: RossD20Studios on August 24, 2018, 11:11:42 AM
Dev Log 6: How I'm Preparing to Showcase at PAX West 2018 with Indie MEGABOOTH
This week, I decided to put the deck builder interface on hold and begin preparations for our upcoming trip to PAX. Having run the booth at a few conventions in the past, I know that having the right materials and setup are essential to a successful show.
The Indie MINIBOOTH Setup
We'll be showcasing Summoners Fate with the Indie MINIBOOTH. One thing I really like about this setup is that it takes a lot of pressure off the logistics and planning of a larger booth. The Indie MEGABOOTH team houses 12 teams in the MINIBOOTH on any given day (we'll be showing on Sunday and Monday) and provides everyone with the same standard setup that includes:
(https://summonersfate.com/images/forum/miniBoothExample.jpg)
A red IKEA Kallax shelve in the background with the following dimensions:
Width: 30 3/8 ", Depth: 15 3/8 ", Height: 57 7/8 " or Width: 77 cm, Depth: 39 cm, Height: 147 cm
A white standing height table - the metal construction you can see in the front
27" monitor 2560x1440p resolution
AORUS Elite Dream Machine computer with mouse, keyboard, headset, mousepad and wired Xbox gamepad
Monitor topper with our game's logo
To ensure each developer in the space has adequate room, additional standing accessories not attached to the kiosk (ex: standing banners) are not allowed in the MINIBOOTH. Since I'll be running the booth solo, this setup is perfect: I don't have to worry about additional costs of renting or transporting equipment which can easily add up to anywhere in the ballpark of $2K-$10K.
All that being said, one might say my job is pretty easy: just show up! Actually, there's still a lot of room to be creative with marketing and help my game stand out to the thousands of show-goers that will be passing through the convention.
Preparing the Game for Convention Showcase
Let's start with the most important part: the game itself. The biggest eye-catcher I have is the action happening on that 27" monitor. If that monitor is stuck in a static menu screen while I'm chatting with players, it's not going to be as appealing for newcomers as action like fireballs exploding and dragons flying in. To that end, I modified the game to incorporate our game trailer (which has all that good stuff) so that during any periods where the gamer seat isn't hot, it's playing our best gameplay footage on a loop to draw interest. Also, if a player decides to get up and walk away, it'll monitor user activity and flip back to the trailer automatically so I don't have to.
Keeping the Player Engaged
Players are going to experience a game differently at a convention like PAX than they will when they're playing at home. There's so much excitement that goes on at conventions that I can't expect gamers to become as fully absorbed in Summoners Fate as I might like - especially since our game (being tactical and turn based) is relatively more complex than an action plat-former. To keep players engaged, I'm aiming for a 10-15 minute target experience. My goal is to tantalize players with the unique elements our game has to offer so they walk away feeling excited and wanting more.
My top concern is that the first impression players have will likely become their lasting impression. If I reduce the gameplay to a quick PvP battle, players might disregard the game as a tactical combat engine when there are so many more unique things it offers: creative deck building, branching levels with diverse paths, progression and story telling, etc. Plus, there's a good chance the more subtle combat elements may be missed or overlooked. To mitigate this risk, I'm doing my best to design the demo so it offers a broader scope: shorter combat sequences with more exciting finales, opportunities for players to choose cards to incorporate in their deck and power up their main character, a chance to choose a path in the campaign, and a final boss combat encounter. This is harder than it sounds because I need to create the right experience that delivers on these goals without being forcible or "hand-holdy" in the outcomes. I find players derive the most meaning when their actions come from their own planned decisions, not the ones I make for them as a game designer.
Creating a Memorable Booth
Now, let's talk about the booth itself. Having looked at some of the past designs, my eye was drawn to the booths that had a professionally printed banner depicting the game's key-art and logo, like this one:
(https://summonersfate.com/images/forum/bannerExample.jpg)
I stopped by my local FedEx Kinkos, Office Max, and a local print-shop to explore options and pricing. Ultimately, I discovered ordering online was both cheaper, easier, and had more options that better suited my needs. I settled on a 72"x24", grommeted and hemmed Vinyl banner from signs.com that I plan to wrap around the front and sides of the kiosk using non-residue adhesive wall hooks.
(https://summonersfate.com/images/forum/summonersFateBanner.png)
Edit: Check out what came early today!
(https://summonersfate.com/images/forum/sfBannerPhoto.png)
The other key item I wanted was a take-away card for guests that stopped by the booth: something with key art and information about our game they could place in their goodie bag to remind them of their experience with us. These are also perfect to attach promo codes to if I decide to do a game key give-away. I created this on signs.com as well as a 6"x4" glossy post card:
(https://summonersfate.com/images/forum/summonersFateGivewayCard.png)
In total (with free shipping and a 15% discount code I found online) I paid $88 for the banner and 500 cards. For means of comparison, a single color sheet (which I could have used to make 2 cards) would have cost anywhere between $0.88 - $1.29 at local print shops. That would have been over $200 just for the cards, let alone the banner - so ordering online is DEFINITELY the way to go!
Finally, I felt it imperative that I, myself, standout from the crowd so gamers know exactly who the dev team of this game is. Behold my Summoner's Fate T-shirt sporting our game logo on front and company logo on back. ($28 from customizedgirl.com)
(https://summonersfate.com/images/forum/sfTshirt.png)
Just needs a little ironing ;)
Total Cost Breakdown:
Indie MINIBOOTH Booth Cost: $1200
Marketing Materials (Banner, 500 giveaway cards, T-shirt): $116
Airfare (SLC to Seattle): $390
Hotel: $0 (My awesome game designer friend is letting me stay with her!)
Grand Total: $1706
Add in costs for uber, food, etc. and I think I'll probably balance out just under $2K for two-days of showcasing plus an extra day to walk-around Saturday and take-in the experience. I'll be showing at PAX Sunday September 2nd and Monday September 3rd. I hope to see you there and I'll be sure to let everyone know how it goes!
Post by: RossD20Studios on September 05, 2018, 12:26:12 PM
Dev Log 7: My experience at PAX West with Indie MEGABOOTH and why it was totally worth it.
(https://summonersfate.com/images/forum/myExperienceAtPax.png)
On my flight home from Seattle, I pondered over my time at PAX West where I had just finished showcasing my game, Summoners Fate, with Indie MEGABOOTH (https://indiemegabooth.com/event/pax-west-2018/). The experience was so surreal it felt like a dream: chance encounters and passionate discussions that seemed to flow naturally together in a series of meaningful, interconnected events.
I was tired and uneasy the morning I left because I had been up late the night before fixing bugs I discovered in the demo. I was frantic on the plane as I worked against the clock of arrival and the battery life of my laptop. Then I arrived in Seattle and there was a driver waiting with my name on a sign. I didn't have to worrying about where I was going, I flowed as if on a gentle current. Stress began to melt away.
This was thanks to my friend, Laura, who'd I met met several years back when we worked together at EA. She'd already anticipated the state I'd be in and had put an entire plan in motion to provide the support I would need to succeed at the show: a place to stay, time to polish the demo, introductions to her friends and rides throughout the area - including a stop for a signature Seattle hotdog. This is the delightful and heart-warming surprise of people I've met in the game industry: the lengths they go through to show their kindness and support. And this was just the first of many I would experience at PAX.
Making it to the MINIBOOTH
After spending the morning and early afternoon exploring the various PAX exhibits, I made my way to the Indie MEGABOOTH. Once there, I started talking with some of the other devs who were showing their games in the MINIBOOTH. I reached my hand out with excitement to Nicolás, another dev creating a game with CCG mechanics called Causa (https://indiemegabooth.com/project/causa-voices-dusk-1/). "I'm so excited to meet another dev also working on a CCG!" I said. "I can't wait to hear about your stories and how you've solved problems in your game design." His face lit up with joy. It's a wonderful feeling to meet someone like this. They've experienced and dealt with the same challenges so you can connect and understand each other in a way other people can't.
(https://summonersfate.com/images/forum/summonersFateBooth.png)
Our kiosk in the MINIBOOTH, ready to go!
Up and early the next morning, I was anxious to meet folks exploring the expo and have them play my game. I had quite a scare when my demo wouldn't install, but the volunteers were quick to respond. The MEGABOOTH team and Pax enforcers are among the most amazing and courteous folks I've ever encountered. What could have been a very uncertain and trying experience was made easy with their constant support and reassurance. "Are you doing ok? Can I get you anything? Here's some cough drops, let me refill your water…" This is a level of service and care all organizations should aspire to.
Mastering the Pitch
The showfloor was a great place to discover what gravitates people toward games. I found out it was a combination of familiarity and weirdness. "Summoners Fate is a top down fantasy adventure meets deck builder." "Ohhh, ok" (nodding inquisitively). "And you get to hurl squirrels at your enemies and then transform them into super squirrel mutants." Laughing. "Ok now I gotta try this…". Being with the Indie MEGABOOTH helped: people knew going in that everyone manning the booths were the actual game developers - and that's what makes the experience so special. It wasn't just a chance to show the game, but also my personality: that I'm sincere about my enthusiasm with the game and my commitment to players.
The Power of Connecting
Hanging out with fellow indies was good medicine. It was reassuring to hear similar stories about the sacrifices we're making. One of the dev teams, working on a game that rivals the art of Skyrim called Eastshade (https://indiemegabooth.com/project/eastshade/) told me how they were living together with their mom and grandma. Others were taking breaks while dealing with family emergencies or trying to juggle a full-time job or contract work on the side to keep things up. I could relate: My wife had to return to working full time to give us extra runway on our project. I had to take on more responsibility taking care of our two children. We had to pay for an expensive surgery out of pocket because we didn't have corporate insurance. We've missed out on vacations, we never travel to see family, and we're constantly dealing with disasters that come up. Uncertainty creates enormous pressure and there are many times it feels all-consuming and soul crushing.
Despite our common challenges, none of us deterred away from the hopeful sentiment we all believed in: You can always make more money, you can't get back the time in your life. Your moment must be seized while it can.
(https://summonersfate.com/images/forum/PAXSelfies.jpg)
Meeting new people was the best!
I met so many amazing people, including some of our longtime fans and followers who made a special trip just to see me. Shout outs to Tom, Patrick, Kyle and Jeremy! I got to tell John Baez, founder of The Behemoth (https://www.thebehemoth.com/) how Battle Block Theater's level editor inspired my son to become a game developer. Chainsaw Games Studio, creators of my favorite Xbox party game, Knight Squad, were just across from the MINIBOOTH showing their new game, Aftercharge (https://indiemegabooth.com/project/aftercharge/). An analyst from Magic the Gathering team told me he really enjoyed the onboarding in our demo. Wanderbot (https://www.youtube.com/channel/UC2wac-sRkNMPSFEnaOHCL3g), a YouTuber I admire and really wanted to share my game made a surprise visit. My new friend from Tencent, YiCong, also stopped by and I got a chance to show the development tools I wrote to make the game. As the sole engineer on my team, I don't get many opportunities to speak about the behind-the-scenes challenges of production and supporting a live service. It felt so incredibly validating to have a fellow developer take delight in the feats I'd accomplished.
(https://summonersfate.com/images/forum/YiCongPlaysSummonersFate.png)
YiCong plays Summoners Fate
Networking, Indie Style
On Sunday evening, Indie MEGABOOTH hosted a mixer event for the devs and their sponsors that included several publishers. The party itself was incredible: free food and drinks, arcade and pinball machines with bowls filled with complimentary quarters. There was no pressure of having to make a sales pitch, just casual conversation and engaging stories of our experience and getting to know each other. This was an opportunity to show your true self and realize how small and intimate the game industry is: Nearly everyone knows, has worked for, or has a friend who worked with someone and we're all just regular people with a desire to fulfill our potential doing creative work.
The Moment that Made the Show
The most intense moment of the show happened when I least suspected it. I had just sat down behind the booth for lunch, legs tired and back sore from three days of nonstop standing, when I overheard a group of people playing my game. It was their playful banter and obvious enjoyment of what they were experiencing that got to me. I only heard fragments, but I remember a woman saying "What are you doing to these poor animals?!" and a guy responding "You don't understand, this is WAR!". "Now watch this watch this... Mutant squirrel!! Squirrel army!!" And then just lots of laughter. I knew at that moment this was the highlight of the show. Something about just hearing their joyful commentary, not knowing I was there, made it all the more sincere and meaningful. I had made something that gave them a moment of happiness, and I was fighting hard not to cry and not to laugh at the same time.
The MEGABOOTH concluded with a group photo and hugs goodbye, then I headed for the airport. It was a successful show. I certainly had a lot of luck, and yet there was one specific choice I made that helped achieve this outcome: having a positive attitude. If I could offer one piece of advice I've validated time and time again from my experiences: When you engage with others in the community, give them your true, honest and open self. Pause and listen attentively, open yourself to feedback and the wisdom others have to share in their stories. Recognize and admire the work and talent of others.
Attitude and perception works like a mirror: when you seek out the best intent in others, it reflects back the best intent in yourself. From this, positive things unfold, like a gentle current that carries you along in a series of exciting adventures.
Post by: PrimaryFeather on September 06, 2018, 02:08:47 AM
What fantastic recap of your experiences at PAX West, Ross! Your enthusiasm can be felt in every word you're writing here. I'm super excited to hear it was such a success, and I can only imagine the boost it's given your motivation to carry on. You're living your dream, even if it means fighting through lots of unexpected hardships. A big KUDOS to the great work you're doing and the personal touch you're weaving into every fiber of the game. :D
P.S.: With these experiences, I guess you're already planning a rename of the game, right? "Squirrel Army's Fate [or how I learned to love that mutant rodent]". ;D
Quote from: PrimaryFeather on September 06, 2018, 02:08:47 AM
Wow, thank you so much, Daniel, that's so kind of you to say! Now, we've got to do something about that missing avatar of yours *WAVES MAGIC WAND* and *POOF!* there you are!
Squirrel Army's Fate: How I Learned to Love that Mutant Rodent <- Genius! Have you considered a role in marketing? That's one the press can't look away from. I'll have to find a way to work into a future press release ;)
Post by: Scribe on September 06, 2018, 10:20:12 PM
We can feel the excitement in every sentence you wrote, Ross. Thrilling!
It also makes me want to put my hands on that demo. Will you make it available to testers? I'm eager to try it, and to show it around!
Post by: RossD20Studios on September 07, 2018, 08:10:03 AM
Quote from: Scribe on September 06, 2018, 10:20:12 PM
You, bet, Scribe! I'll try and get a build update out as soon as possible with the new intro sequence we showed at PAX. So many of the improvements were the direct result of your feedback, so thanks again for taking time to do such a thorough assessment of our first tutorial and share your thoughts with us.
Post by: RossD20Studios on November 28, 2018, 11:43:18 AM
Dev Log 8: Highlights & Data of Summoners Fate at Dreamhack 2018
(https://summonersfate.com/images/articles/indieMarketingSummonersFateDreamhack.png)
For those following my indie game marketing, this is the third article in that series (see part 1 (https://www.gamasutra.com/blogs/RossPrzybylski/20180906/325942/My_experience_at_PAX_West_with_Indie_MEGABOOTH_and_why_it_was_totally_worth_it.php) and part 2 (https://www.gamasutra.com/blogs/RossPrzybylski/20181010/328270/Marketing_and_Session_Data_for_Summoners_Fate_at_PAX_West.php) for our experience and data on PAX West). It's my aim to capture both the subjective highlights and empirical data of our experiences so that myself and others can learn what to expect and how to improve our marketing. In this article, I share our marketing strategy, budget, event highlights and data of our Dreamhack Atlanta 2018 showcase of Summoners Fate.
What is Dreamhack and why did I showcase at their 2018 Atlanta Expo?
Dreamhack hosts several conventions internationally each year focused on eSports and multiplayer gaming. If you've ever experienced a LAN party where a group of friends all bring their gaming PC's to play multiplayer, Dreamhack is like that except with thousands of people.
Dreamhack presented several key opportunities for us:
Free 10x10 Ft. Booth as a featured game in their Indie Playground (https://dreamhack.com/atlanta/participate/indie-zone/indie-playground/#early-access)
15 Minutes to present on the Indie Stage streamed live on Twitch
Finalist for Best Game Pitch (https://dreamhack.com/atlanta/participate/business-zone/game-pitch-championship/) (Potential to win $2500 prize)
Additional 15 Minutes stage time for pitch finalists
Chance to create fan momentum by handing out our early access keys and getting gamers to play our multiplayer on their own personal PC's in the LAN gaming party
(https://summonersfate.com/images/articles/summonersFateBoothDreamhack.png)
Our awesome booth setup
My teammate Peter and I made the trip. To maximize our potential, we planned a 4 demo screens booth consisting of a 39" TV main monitor w/laptop, iPad Pro, iPad Air on tripod stand and a Surface Pro. For signage, we leveraged our existing horizontal banner from PAX and purchased a new vertical standing banner. Since the event allowed attendees to bring their own computers with internet access, we brought 300 keys for our early access multiplayer demo and hosted a contest to motivate players to actually play our game on the showfloor with their friends. Additionally, we held a social media contest, asking players to take pictures playing the game together to win one of Peter's hand-crafted armored squirrel plushies.
Budget Breakdown:
Airfare: $792.80
Hotel: $190.05
Car Rental: $136.01
Power: $120.00
Food: $193.05
Parking: $56.00
Vertical Banner: $129.80
This is how we get you pumped to play Summoners Fate
Stage Time - We rocked our indie stage performance with feverous passion and energy.
Fanatical Fans - We made a strong personal connection with players and even inspired a new streamer to choose Summoners Fate as the game for his first-ever live stream (https://www.twitch.tv/videos/337557226).
Game Pitch Competition - We made it to the Final 5! Check out the stream here (https://www.twitch.tv/videos/337284693?t=45m11s).
Comradery - We enjoyed beers and brats with fellow indie developers at Der Biergarten (thanks to Josh Delson for organizing).
Friendship - We traveled through underground cities, hordes of Falcon fans, and the biggest crowd I've ever seen at airport security (among other trials of travel I can't mention here). I wouldn't have made it without Peter, and it's my greatest gift of this experience knowing just how far a true friend will go to support me.
(https://summonersfate.com/images/articles/devDinnerAtDreamhack.jpg)
Indie dev comradery at Der Biergarten
Data and Take-Aways
Here's the summary of the data we collected with our demo analytics. For more information and a comparison to our PAX data, see here (https://www.gamasutra.com/blogs/RossPrzybylski/20181010/328270/Marketing_and_Session_Data_for_Summoners_Fate_at_PAX_West.php).
(https://summonersfate.com/images/articles/summonersFateDreamhackAtlanta2018Data.png)
Foot traffic was half what we expected, so we took a proactive approach of drawing players in by enthusiastically asking them "Would you like to throw a squirrel at your enemies?!" This was effective at turning heads "What?! Did you say throw a squirrel…?" Coupled with a friendly handshake and a personal introduction, we perfected the process of getting players in the demo seats and were among the most effective indie teams at maintaining an audience.
I'm continually seeking to learn how to effectively mobilize our fanbase to action. I think we had the right creative ideas with our multiplayer contest and squirrel giveaways, but we could have done a better job communicating the actionable steps and making it easier for players. This is a recurring lesson for us with all things marketing: continuous, clear and repetitive communication is key. I'll sometimes think our message is obvious, but the data says: "Hit folks over the head with it!" I think of that Simpsons episode where Bart joins a boy band sponsored by the Navy. You need to use the subliminal, liminal, and superliminal: "Hey, YOU! Join the Navy!"
(https://summonersfate.com/images/articles/rossAndPeterDreamhack.jpg)
Peter and Ross are pumped!
All together, Dreamhack was a great stepping stone and learning experience. We succeeded in attracting passionate new fans, gaining valuable experience pitching our game in front of a live audience, and made another milestone towards raising brand awareness amongst the gamer community.
Post by: RossD20Studios on April 04, 2019, 08:02:42 AM
Dev Log 9: "Go all in" to succeed as an Indie Dev at PAX East 2019
(https://summonersfate.com/images/articles/sfPaxEast2019Banner.jpg)
The camaraderie and brotherhood shared among fellow indie devs at events like PAX East never ceases to lift my spirit. Indie game development is the gem of the games industry where your market competitors passionately root for each others success. It's a badge of honor to share our experiences with each other, openly and honestly, to solve our paramount problem of discoverability: what works and what doesn't work to capture an audience? Who do we need to be speaking with to secure funding or publishing support? What crazy new ideas haven't we tried yet?
PAX East 2019 marks my third major event showcase of Summoners Fate (https://summonersfate.com/), and my second time showcasing as part of the Indie MEGABOOTH. I continue to learn from others with each experience and pay it forward by sharing here (https://gamasutra.com/blogs/RossPrzybylski/1014768/). So, here's three things we did different to stand out as an indie at PAX East this year and the data we have so far on how it compared to our previous showcases:
1. Demo Hydra
A key take-away I learned from showcasing last year at PAX West with the MINIBOOTH is that a single screen demo heavily bottlenecks potential plays. Space at the MINIBOOTH is limited to a single monitor kiosk, but exhibitors are allowed to embellish it with decor provided it respects the space of your fellow miniboothers. So, I expanded on the existing idea of lateral signage by substituting mounts that could support tablets and phones. Each of the devices connects to a 15 foot braided charge cord which allowed us to extend our reach into crowds that would gather to play and simultaneously keep everyone engaged and entertained.
(https://summonersfate.com/images/articles/sfPaxEast2019DemoHydra.jpg)
The Summoners Fate "Demo Hydra". Cut off one head, two grow in its place!
I lovingly named this concept the "Demo Hydra" for its likeness to the mythological beast of many serpent heads. In total, we had 8 screens with us including our personal phones which we handed out as needed to keep the hydra fed. It should be considered a scientific fact that "success breeds success" and likewise "a crowd brings a crowd". Whereas folks previously breezed past the MINIBOOTH, our perpetual crowd pulled them in, curious to discover what all the fuss was about. By virtue, this had the collective effect of drawing more audience for our fellow indie MINIBOOTH showcasers as well, allowing us all to share in the success.
(https://summonersfate.com/images/articles/sfPaxEast2019Data.jpg)
Our demo tracks telemetry so that we can learn and improve from our experiences.
All in total, we had 149 sessions and 42 total email registrations for a total budget under $2660 (including booth, hotel, travel, food and marketing materials). By comparison, our PAX West showcase (https://gamasutra.com/blogs/RossPrzybylski/20181010/328270/Marketing_and_Session_Data_for_Summoners_Fate_at_PAX_West.php) had 76 sessions, 37 email sign-ups, so the hydra had the effect of doubling our total sessions. Our conversions are more similar to our Dreamhack showcase (https://gamasutra.com/blogs/RossPrzybylski/20181129/331694/Indie_Marketing_Highlights__Data_of_Summoners_Fate_at_Dreamhack_2018.php). There we had 142 sessions and 49 sign-ups, but with a 10x10 foot booth over 3 days instead of 2. My theory is that a more crowded booth creates a less intimate experience where folks are less inclined to register their email. However, I prefer to let the game speak for itself. Time spent with us is an investment that raises brand awareness and breeds familiarity and likeness with our game. In aggregate of all three showcases, I believe our data may also suggest our demo is about 2 levels too long and that we could increase completion and conversion by shortening the experience and adjusting the difficulty on the earlier levels.
2. Branded Marketing Theme
Not unlike the vast ocean of games released daily on Steam, the waters of PAX are overloaded with games all competing to get prospective player attention. Showcasing with the Indie MEGABOOTH supports the first step of marketing by putting us in a school of fish strong enough to have a presence from afar and allowing folks to find us. The second step is creating a memorable impression that stands out and will last with players following the conference. Our previous showcases taught us that players respond well to a mix of familiarity and weird, and our signature hook became "Would you like to throw a squirrel at some orcs?"
We don't want to be typecast as a game just about squirrels, though, so we expanded our marketing with a broader theme of "WE LIKE WEIRD." and showing how our game connects emotionally to the characters and cool things you can do in the game. Varieties of these messages were looped constantly on a dedicated screen in the hydra. Here's some examples:
(https://summonersfate.com/images/articles/happyLikeAnImp.gif) (https://summonersfate.com/images/articles/archMageLikes.gif)
My teammate, Peter, took the concept a step further by devising a way to make an immediate personal connection to passerbys. Honestly, I was hesitant when he first shared his plan… "Hmm, that might be perceived as offensive, no?" but the real shocker was that it was actually extremely effective. Peter casually approached folks walking past the booth and said "Hey, you look weird." ...pause… "We like weird." … smile… Players considered it an honor to be recognized for their weirdness, and why not, right? What is PAX if not a celebration of the weirdness in all of us? Bonus tip: Bring a new teammate with you to showcase. Their perspective may lead to the discovery of the most effective way to connect with your audience.
3. Player Testimonial
A key benefit of showcasing with Indie MEGABOOTH is their Mixer event where you get to party and network with key industry folks including reps from Sony, Microsoft, Kongregate and more. One of the most interesting folks I had the pleasure of meeting that night was Alex Engel, a product manager with vast experience releasing AAA games in the industry. Word of advice: If you ever have the opportunity to strike up a conversation with a PM, listen carefully and absorb everything. They are among the most brilliant minds in the industry.
I asked Alex about how to make a wave connecting with our audience and a key piece of advice he shared was to use the convention as an opportunity to give our players a voice: let them communicate what excited them about the experience. That is what will excite new players, and that is what you should focus on. Real simple: Ask them what they enjoyed, then, create a compilation of their responses. So, the next day we did just that:
If you're using Google Photos, you can create a clip like this in about an hour using your phone. Select the all the clips, then use the auto-assist to make a movie. Then, adjust the clips so they reflect the most interesting parts of the interviews. To improve this in the future, I would bring personal mics to help filter out the background noise of the convention and have the voices be more clear. Even with just basic phone audio capture, though, I think this is a powerful takeaway of our experience.
What unites us all as indies?
Regardless of the tips, tricks and luck we all hope for, one sentiment was constant throughout all the fellow indies I spoke to: we "go all in" giving every ounce of strength and energy we have. Failure never deters us. We never consider the consequence of "What if this game doesn't succeed?" because we perceive every opportunity we have as a gift from which we can learn and grow. Perseverance is the standout character trait of those who ultimately succeed because every moment of life is lived passionately to its full potential.
(https://summonersfate.com/images/articles/sfPaxEast2019Peter.jpg)
DEMO HYDRA!!!
Post by: t_lark on April 08, 2019, 01:58:26 PM
I really appreciate the details as always. I've been trying to do more demos myself, so its great to compare results. At Berlin Talk and Play (https://berlingamescene.com/talkandplay/), a developer focused twice a month meetup, I get avg. 4 emails for 3 hours of time (and it costs 2 beers on average). I've demoed twice and I expect I will saturate that niche fairly soon but it seems good low hanging fruit due to its locality.
I love the demo hydra, I was concluding a similar thing myself that the bottle neck is the number of devices. I'me getting a chrome cast to send the main device to a HDMI, for the passives, and a few extra devices would help too.
Awesome stuff Ross, thanks for taking us on this journey.
Post by: RossD20Studios on June 14, 2019, 11:53:52 AM
Dev Log 10: Creating Original and Exciting Single Player Adventures
The path ahead unfolds...
Recently returned from Dreamhack Dallas, it's clear the most important next step we can make is to deliver on our promise of procedurally driven single player campaign adventures. We gained a lot of insight and ideas from our time at Dreamhack listening to player aspirations and learning from fellow indie devs showcasing games of like-minded spirit to Summoners Fate. Shout out to Fell Seal: Arbiter's Mask (https://www.fellseal.com/), Wildermyth (https://wildermyth.com/), RoundGuard (https://www.wonderbellygames.com/), Rogue Empire: Dungeon Crawler RPG (https://www.roguempire.com/) and Bound by Blades (https://boundbyblades.com/) for the opportunity to play your games and learn from you.
We've shared our big-picture vision of the single player campaign here in our Kickstarter page (https://www.kickstarter.com/projects/1181148431/summoners-fate-fast-and-fun-tactical-rpg-ccg-adven) and here in our development blog (https://summonersfate.com/forums/index.php?topic=56.msg580#msg580) . I'm pleased to say that vision remains consistent with where we envision the path forward. What's changing as a result of our learning are the particulars of how we intend to implement that vision. The games that excited us at Dreamhack were those that exhibited unique and original mechanics. The parts less exciting were those that felt derivative to other titles and implemented to satisfy perceptions of trends in the current market. This gave us pause to question our own design - Why were we implementing systems like our saga-style map (https://summonersfate.com/forums/index.php?topic=27.msg592#msg592), and would players perceive these mechanics as original and exciting or derivative and out of place?
Branching saga maps are trending in the market, but we learned we aren't doing ourselves a favor standing out by making derivatives.
Peter and I discussed the underlying motivations from a player perspective that make us feel compelled to move forward. Making a choice was the most prominent factor - but, not just any choice. It has to be a meaningful choice. It has to be a fair and informed choice. The choice must contribute to sense of progression and development of the ultimate character destiny we aimed to play out in our fantasy. Furthermore, at what starting point can we roll out our single player experience incrementally so that we can start getting player feedback as soon as possible to test our assumption?
Our first breakthrough was questioning why we were using certain mechanics in the first place. When I thought about our over-arching saga map, I reasoned it was there to provide break points and present choices to players - but were these choices meaningful or rudimentary? How informed is the choice I make on the path I take, and what can I do if I don't like the outcome (especially if the outcome is an unfair challenge I cannot overcome)? The saga map also directly conflicts with one of the unique and compelling aspects of Summoners Fate - our ability to tie tactical grid levels together as a seamless world.
What if we cut this feature and put our focus on what makes us unique?
(https://summonersfate.com/images/articles/SeamlessTransition.gif)
We built an engine that supports seamless transitions between levels. Why aren't we doubling down on this?
It's amazing how an experience followed by some heartfelt discussion can change your perspective. Once we realized our mistake and let go of it, other pieces of our design started falling into place and got us excited about how we can deliver on choice. Here's a quick synopsis:
The world is generated procedurally by placing tactical grid maps that connect together to form a continuous landscape. Key objectives such as treasures, new characters to recruit, and bosses to defeat are scattered throughout the world.
We assume players desire to explore the entire world - but if they do, their choice on which path to take becomes less meaningful (since they are not choosing to lose something, simply the order in which to see everything). To give weight to player decisions, we add a survival modifier: The longer you explore the world, the more difficult enemies become until they ultimately overwhelm you.
You get only one life and your resources (health, cards, number of rest points) are limited, so you have to make careful choices about where you want to explore. Make a wrong turn and stumble on a dragon? That's ok. Retreat and fall back, but remember that the longer you take to find the right path, the more imminent your defeat as the doomsday clock ticks down.
Players progress their Summoner by over-coming challenges one room/area at a time. Upon completion, you make a choice about how to develop your character by picking a new card to add to your deck, choosing a new companion to join you, or resting to recover health or used cards.
Incrementally, we believe we can quickly turn-around an initially linear/non-back tracking dungeon with player progression through deck building choices as a first iteration, giving players a chance to provide feedback. Then, we expand the experience by adding a mini-map overlay that allows you to see/choose paths to explore in a non-linear fashion (including backtracking).
We're eager to hear what you think about this design. Feel welcome to share your feedback, questions and concerns here and on our Discord (https://discord.gg/d20studios). We love hearing from you!

redpajama_set_name: RedPajamaCommonCrawl


EAFRD seeks to reflect the importance of the Agri-food sector in Cornwall and the Isles of Scilly.
Local partners have been working with DEFRA to help shape the new Rural Development Programme. It is important to recognise that the funding available is significantly less than Cornwall and the Isles of Scilly received in previous rounds.
LEADER funding is available to local businesses, communities, farmers, foresters and land owners. Eligible applicants can apply for funding through Local Action Groups (LAGs). Your LAG will prioritise funding for projects that create jobs, help your business to grow, and benefit the rural economy.
Further information around National Agricultural and Rural funding opportunities can be found here.
As the only Less Developed Region in England, with distinct challenges and opportunities, Cornwall and the Isles of Scilly will have its own Integrated Territorial Investment (ITI) Strategy to guide the investment of EU funds in the region.


Which of the following best describes Plan Stakeholder Engagement process?
Thank you replying my Query.
but as you know PMP always give all correct answers for a question asked and we need to choose the best suitable answer from the given question.
It may sound weird. How about option -d . Its the strategy that has all the plans in dealing Option A to C ?
Its the plan in handling all the other situations and executing it in further processes.


por le iron ore jaw crusher for hire south africa, por le iron ore cone crusher for hire south africa por le iron, Read more . por le gold ore crusher for hire in south africa. trubaindo coal mining email kaavyavaniin, mobile coal jaw crusher for hire in malaysia, coal grinding coal crushers por le south africa coal, for sale price gold .
por le crushing plant for quarry - esmab. Mobile quarry crushing plant for sale in new zealand. 2016-09-08 · mobile quarry crushing plant for sale in New Zealand for sale from Zealand Portable Crushing Plant,Quarry New Zealand based manufacturer.
mps in gyratory crusher · grinding mill mtm trapezium mill for sale china . grinder machine · por le combination type combine mobile recycling crushing cost in kenya . cone crusher for quarry for sale · quarry equipments for sale in houston us.
por le gold ore cone crusher for hire in india. dolimite jaw crusher provider in nigeria - Hotel… mobile gold ore cone crusher provider nigeria Mobile Lizenithne Impact Crusher For Results 1 25 of 233 portable dolomite impact crusher for hire malaysia B.M.D. College.
Portable Stone Crusher South Africa - … Crusher Jaw crusher Impact crusher Cone - Crusher, grinding machine used for crushing in stone quarry, coal, cement plant, mineral ore mining.
used por le stone crusher for sale in south africa. Flow Charts For Aggregate Crushing,Stone And Rock Crusher ...- used por le stone crusher for sale in south africa ,Hammer Crusher.
quarry crushing plant por le plant design - nvservices. Quarry Conveyor System Design In South Africa. coal mobile crushing plant and Screening Plant design,conveyor, Quarry, . africa STEINERT Global Australia Magnetic por le quarry crusher price in the us .
POR LE QUARRY MOBILE CRUSHER IN SOUTHAFRICA SALE. Por Le Stone Crusher For Sale Stone Quarry Plant India. used plant for aac bricks in nasik maharashtra india aug binq mining equipment mobile jaw crusher for sale in kenya,used jaw mobile how purchase por le quarry stone.
por le limestone crusher for sale south africa jkexports. por le limestone crushers. mobile stone crushers for sale south africa in india mobile impact crusher in south korea used stone crusher plant with low cost for Get Price › used por le crusher for sale south africa . used por le crusher for sale south africa .


text:
Ethan Edward Hayter (Londen, 18 september 1998) is een Engels wielrenner, die het baan- en het wegwielrennen combineert. Anno 2022 is hij op de weg actief voor INEOS Grenadiers.

Biografie
Al van bij de jeugdreeksen combineerde Hayter zowel het baan- als het wegwielrennen. Als junior won hij in 2015 Kuurne-Brussel-Kuurne en werd hij tweede in zowel de Guido Reybrouck Classic als Gent-Wevelgem. Bij de Beloftencategorie won hij in 2019 twee etappes in de Girobio en één rit in de Ronde van de Toekomst.

In 2018 werd hij, samen met Ed Clancy, Kian Emadi en Charlie Tanfield, wereldkampioen ploegenachtervolging. In 2021 werd hij wereldkampioen omnium.

Sinds 1 januari 2020 komt hij als profwielrenner uit voor het Britse UCI World Tour team: INEOS Grenadiers. Bij deze ploeg had hij tussen augustus en eind 2018 ook al stage gelopen.

Palmares

Wegwielrennen

Overwinningen

2019 - 2 zeges
2e etappe À travers les Hauts de France
Eindklassement À travers les Hauts de France
2020 - 1 zege
Ronde van de Apennijnen
2021 - 10 zeges
3e etappe Internationale Wielerweek
2e etappe Ronde van de Algarve
2e en 5e etappe Ruta del Sol
1e en 2e etappe Ronde van Noorwegen
Eindklassement Ronde van Noorwegen
3e (TTT) en 5e etappe Ronde van Groot-Brittannië
 Brits kampioen tijdrijden, Elite
2022 - 5 zeges
2e etappe Internationale Wielerweek
Proloog (ITT) en 2e etappe Ronde van Romandië
Puntenklassement Ronde van Romandië
2e etappe Ronde van Noorwegen
 Brits kampioen tijdrijden, Elite

Resultaten in voornaamste wedstrijden

|
|}

Baanwielrennen

Ploegen
2020 –  Team INEOS
2021 –  INEOS Grenadiers
2022 –  INEOS Grenadiers
 2023 –  INEOS Grenadiers

Brits wielrenner
Brits baanwielrenner

redpajama_set_name: RedPajamaWikipedia


Do you have a favorite magazine? Do you subscribe to it, look forward to getting it in the mail, and get a little sad when you've read the last page? Christy likes Coastal Living and Southern Living. For me, it is Newsweek (I like to read what the "other side" has to say!). Do the lives of people in your magazines seem perfect? Is every child smiling? Is every room decorated to the hilt? Are the waves the perfect blue with white caps that appear to be painted on with a brush? Do the pictures of every plate of food contain 5 colors from 4 food groups? And how about the articles??? Obviously if you write a magazine article you must be a leader in your field and you must know everything, right? Even the authors who share their short-comings do so for our benefit as they share with us how they cured their mortal temptations or traveled the globe on a dime. Never do we see citations in magazine articles, so these folks are obviously field-experts.
Living with Christy and watching her manage our home and tend to our children is sometimes like living in a magazine- the pictures are always perfect and the articles are inspiring. Each meal does have 5 colors from 4 food groups (last night was grilled rib eye steaks smothered in homemade crawfish etouffe, steamed mixed vegetables, Mediterranean salad with homemade dressing, French bread, peach tea, and chocolate dipped strawberries along side some to-die-for chocolate cheesecake desserts...and I must mention it was all set on the back porch with candles on the table and overhead which accented the beautiful table setting- with an occassional smell of burning oak coming from the firepit). Her children always leave for the school bus with a full "love tank" and nutritous lunches that the teachers take note of. Christy always answers the phone at the editor's desk with an energy that lifts the spirits of the lucky caller. To write an expose' highlighting her volunteer hours with Emma's Hugs and Blue Bird Circle Clinic after taking wonderful care of her church, husband and children would convince readers she wears a big "S" on her chest. She could write an editorial piece about the challenges of reviving a defunked HOA and the fun times that involves (sarcasm intended)...and explain her desire for her children to grow up in a better neighborhood. Yes, in "Dunnam Living" each picture is perfectly framed and the articles are always uplifting.
H-o-w-e-v-e-r, you should see the work she puts into each edition. The pressroom is hot and loud. Her arms and hands stay covered in ink. For each "perfect" picture or life-story that we see she has trashed 20 others. The 5 AM Edition is never finished before 3 AM. Her fingers bleed. She tries to work quietly so as to not bother anyone else. It is only the extreme demands of life that give her any rest from mourning her little angel in heaven. Tears wash away the salty sweat from her eyes. If there is anyone who doubts the glossy pages of her "Life Magazine" it is her. But, only her. For those of us who read her life-works on a daily basis, we are lifted by her energy; we fill loved; we can work harder; we are inspired to climb higher; we see more in life than we did before; she adds salt to our lives.
You are an awesome example to our children and especially me. You are admired from several continents (literally) and even by those you have never met, but most importantly within our home. Your children love to draw your picture. Your work is dirty, but the product is perfect. You are a Mom.
So sweet!!! I love how much you guys love each other and aren't afraid to tell everyone!!!
I LOVE my husband. He knows just the right things to say and do at just the right time. I'm so blessed and honored he still loves me even though he sees the chaos of the newsroom at the last minute before printing. I'm also blessed and honored to have so many friends who contribute to my "Life" magazine...and stores where I can buy the yummy chocolate dream desserts to which Kelvin referred.
This is VERY sweet. Y'all are cute! Hope you had a great weekend, Christy.
I love you both so. Kelvin, it is good to see you writing again.
Wow! Quite an ode there Christy! And thank you for sharing this moving moment with us Kelvin!


text:
/*!
 * Setings
 * -> Set Easing
 *   "easeOutQuart"
 *     cubic-bezier(0.165, 0.84, 0.44, 1);
 *   "easeInOutCubic"
 *     cubic-bezier(0.645, 0.045, 0.355, 1);
 *   "easeInOutBack"
 *     cubic-bezier(0.68, -0.55, 0.265, 1.55);
 * -> Set Duration
 * -> Set Delay
 */
/*!
 * Set Effects
 * -> effect__fadein-basic
 * -> effect__fadein-zoomin
 * -> effect__fadein-top
 * -> effect__fadein-bottom
 * -> effect__fadein-left
 * -> effect__fadein-right
 */
.scroll-effect-module .effect__fadein-basic {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transition: opacity 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: opacity 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-basic.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transition: opacity 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: opacity 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-zoomin {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transform: scale(0.99);
      -ms-transform: scale(0.99);
          transform: scale(0.99);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-zoomin.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transform: scale(1);
      -ms-transform: scale(1);
          transform: scale(1);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-top {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transform: translate(0, -30%);
      -ms-transform: translate(0, -30%);
          transform: translate(0, -30%);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-top.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transform: translate(0, 0);
      -ms-transform: translate(0, 0);
          transform: translate(0, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-bottom {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transform: translate(0, 30%);
      -ms-transform: translate(0, 30%);
          transform: translate(0, 30%);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-bottom.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transform: translate(0, 0);
      -ms-transform: translate(0, 0);
          transform: translate(0, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-left {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transform: translate(-80%, 0);
      -ms-transform: translate(-80%, 0);
          transform: translate(-80%, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-left.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transform: translate(0, 0);
      -ms-transform: translate(0, 0);
          transform: translate(0, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-right {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transform: translate(80%, 0);
      -ms-transform: translate(80%, 0);
          transform: translate(80%, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__fadein-right.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transform: translate(0, 0);
      -ms-transform: translate(0, 0);
          transform: translate(0, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__spinin {
  opacity: 0;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
  -webkit-transform: translate(0, 0) rotate3d(1, 0, 1, -720deg);
          transform: translate(0, 0) rotate3d(1, 0, 1, -720deg);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

.scroll-effect-module .effect__spinin.active {
  opacity: 1;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
  -webkit-transform: translate(0, 0) rotate3d(1, 0, 1, 0);
          transform: translate(0, 0) rotate3d(1, 0, 1, 0);
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  -webkit-transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
  transition: all 1s cubic-bezier(0.165, 0.84, 0.44, 1) 0s;
}

redpajama_set_name: RedPajamaGithub


text:
package org.pac4j.core.authorization;

import org.junit.Test;
import org.pac4j.core.context.J2EContext;
import org.pac4j.core.profile.CommonProfile;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Tests {@link RequireAllRolesAuthorizer}.
 *
 * @author Jerome Leleu
 * @since 1.8.0
 */
public class RequireAllRolesAuthorizerTests {

    private static final String ROLE1 = "role1";
    private static final String ROLE2 = "role2";
    private static final String ROLE3 = "role3";

    private final J2EContext context = new J2EContext(null, null);

    @Test
    public void testHasAllRolesOkDifferentOrder() {
        final RequireAllRolesAuthorizer authorizer = new RequireAllRolesAuthorizer(new String[]{ROLE3, ROLE1});
        final CommonProfile profile = new CommonProfile();
        profile.addRole(ROLE1);
        profile.addRole(ROLE3);
        assertTrue(authorizer.isAuthorized(context, profile));
    }

    @Test
    public void testHasAllRolesNull() {
        final RequireAllRolesAuthorizer authorizer = new RequireAllRolesAuthorizer(null);
        final CommonProfile profile = new CommonProfile();
        profile.addRole(ROLE1);
        profile.addRole(ROLE3);
        assertTrue(authorizer.isAuthorized(context, profile));
    }

    @Test
    public void testHasAllRolesEmpty() {
        final RequireAllRolesAuthorizer authorizer = new RequireAllRolesAuthorizer(new String[]{});
        final CommonProfile profile = new CommonProfile();
        profile.addRole(ROLE1);
        profile.addRole(ROLE3);
        assertTrue(authorizer.isAuthorized(context, profile));
    }

    @Test
    public void testHasAllRolesTwoRolesFail() {
        final RequireAllRolesAuthorizer authorizer = new RequireAllRolesAuthorizer(new String[]{ROLE3, ROLE1});
        final CommonProfile profile = new CommonProfile();
        profile.addRole(ROLE1);
        profile.addRole(ROLE2);
        assertFalse(authorizer.isAuthorized(context, profile));
    }
}