ShortFormRules is a full-stack webapp for quickly creating and sharing rulesets for tabletop gaming. Made in AngularJS v2, it supports creating, editing and viewing rulesets, with a block editor that features markdown text, tables, blockquotes and dice-roll tables, with custom editors for each to enhance the user experience.
This project was developed over 1 1/2 months, integrating fine-grain UX improvements throughout the development process. The aim of the project was to facilitate a quick, smooth creation process for writing up and sharing tabletop rulesets that was lightweight enough to accommodate the looser, more interconnected nature of tabletop game rules when compared to other games.
Thus, the editor was designed from the ground up to enable writing at the speed of thought while taking into account personal experience with the pain points of writing tabletop rulesets in more traditional word editors like Google Docs.
While well-featured, Homebrewery's innate flavor would clash with the differing aesthetics of games like Lancer, Masks: A New Generation and Starfinder.
The app's initial concept was intended as a lightweight, flavor-agnostic alternative to existing rules-editing options like The Homebrewery (which maintains a strong D&D flavor), while encouraging brevity and clarity in rules-writing based on personal experience with having to reference verbose rules as a Game Master.
This focus is reflected in the app being built around limiting the user's polishing options (most notably, not allowing images), encouraging them to focus on the raw rules themselves and ensure their writing is concise.
The short-form nature of rulesets enforced by this system was originally intended to be utilized by a batch-export feature for combining multiple rulesets into a single PDF file, however this was later scrapped due to difficulties in conforming to modern PDF specifications.
Markdown table syntax:
| Column Header 1 | Column Header 2 |
| --- | --- |
| Col 1 Item 1 | Col 2 Item 1 |
| Col 1 Item 2 | Col 2 Item 2 |
Markdown blockquote syntax:
> Separated Block text
>
> With two paragraphs (blank line read as a paragraph break)
> > And a nested block inside that
In keeping with the no-frills intention of the app, rulesets were originally represented using a single markdown file that users could paste content into for the sake of speeding up the creation of tables and blockquotes.
This proved to be insufficient for providing a truly streamlined editing experience, as the raw markdown syntax for tables and blockquotes specifically is tedious to edit manually.
To resolve this, the editor was pivoted from a single-file markdown editor to a block-based approach with dedicated editors for each block type, namely including text, tables and dice roll tables as their own blocks.
The initial mockup for the reading view with headers, keywords and tables, in addition to an early version of the radial menu
With the design's shift in focus came a new design, which was distilled into a series of mockups targeting both mobile and desktop screen layouts.
A primary design trend that emerged was the use of an overlay modal setup for mobile that could be ported easily to a two-column format on desktop given its extra screen real estate.
In addition to traditional panel-based controls, a quick-access radial menu inspired by Krita's pop-up palette was considered to allow for quickly adding blocks of a specific type using only two clicks.
A mockup of the ruleset card view, along with the cancelled multi-ruleset PDF export feature.
An early mockup of the table and dice table editors, which was later scrapped due to the lack of control over where new rows/columns were placed
A mockup of the text editor view, with buttons to paste markdown syntax for headers and bolded keywords
A later mockup of the table and dice table editors, now using buttons to manipulate rows/columns, and using the table preview to select cells for editing
During development, user experience goals were kept at the forefront, and improvements were actively baked into the system design during its initial implementation.
Most notably, dice roll tables are given a different editor that automatically rebalances their rows and labels based on what dice type is being used, in addition to keeping a temporary cache of the table's largest size in order to prevent catastrophic loss of data in the event a user accidentally changed a d100 table to a d4 table.
This addresses two major pain points of table editing in traditional word processors: manually adjusting row count and ensuring the alternating background color for rows is maintained after resizing.
For good accessibility, non-traditional selection elements like these color swatches use styled labels with included text to enable effective use by screen-reader users.
Selections for a game system and ruleset type allow viewers to quickly glean a ruleset's intent and purpose.
After implementing the mockups to test the app's base functionality, a secondary testing pass was made to identify pain points in the editing experience and shore up the editor's overall functionality.
Of the tweaks that resulted from this, many concerned the flow of focus across input elements, such as auto-focusing the text input when a table element is selected to facilitate Excel-style "click-and-type" editing, or automatically refocusing the editor's text area when pressing one of the buttons to paste a header into the text content.
System state was also made more visible during this update via the addition of toasts to all pages that communicate with the backend and dedicated styling rules for whether form inputs were valid.
The initial design system for the app
Example notification and error toasts, with notification toasts disappearing after a set time and error toasts needing to be closed manually
Detailed visual feedback given to the user when registering, only unlocking the submit button when all entries are valid
A sample screenshot of the finished editor, incorporating improvements from the second round of testing
Additionally, the back buttons implemented in the app follow the path a user would typically take to access them, backtracking from the editor to the read-only view to the card view in order to align with the user's mental model of how the application is structured.
With these and other improvements, the app felt far more intuitive to use and aligned far better with its intended user journey.
Life Is Pain is a comedic deck-builder video game about telling jokes to make the world less depressing, made in Godot 3.5. Build a deck of comedic strategies and tailor your jokes to a varied cast of strange, colorful characters.
This project was developed over 8 months, refining and prototyping during the first four and expanding to a full implementation during the last four. The aim of the project was to create an innovative dialogue system that makes conversation as rich and engaging as other traditional game systems like combat or construction.
Thus, the dialogue system was designed from the ground up to facilitate clever use of information and thinking critically about NPCs and their personalities while allowing for multiple success vectors rather than mandating a series of multiple-choice questions.
The initial storyboard for the game and its core mechanics.
Due to natural conversations being highly complex, the game's design focused primarily on the specific act of joke-telling, granting both structure and a concrete objective to the player's interactions. Comedy was also chosen due to promoting a win-win attitude in contrast to conversations based around persuasion, haggling or other zero-sum outcomes.
The game was also initially focused on incorporating a teaching aspect, using joke-telling interactions to give players hands-on experience with deciding where and when to use specific types of jokes. This was later dropped due to time constraints and due to the innate subjectivity of comedy as a subject.
Initial inspirations for this project included Potionomics for its abstraction of conversation into a deckbuilder format, The Secret of Monkey Island's Insult Swordfighting mechanics and Oh... Sir!! The Insult Simulator's keyword targeting.
The paper prototype used for initial testing, featuring base mechanics like gaining mood, unlocking topics and combining modifier cards with strategy cards.
The primary challenge for the game's design at this stage was ensuring that jokes could be effectively evaluated. Playtesting of the paper prototype was initially based on a spreadsheet of +1 or -1 bonuses for a joke combo and for a specific character, which was later formalized into a numerical-scoring algorithm for the second round of paper playtesting. This system met its needs well, however testers noted that the system provided no useful feedback and often gave unhelpful net-zero results.
The initial Godot prototype, featuring NPC response dialogue, card-playing and mood / stress tracking.
An initial prototype of the core conversation mechanics was then created based on feedback from the paper prototype, focusing on providing feedback to players on a five-point scale and through the use of evaluation-related NPC reaction dialogue.
In contrast to conventional branching-path dialogue systems, Life Is Pain uses a reaction-based system where an NPC's dialogue is largely done in reaction to topics the player mentions and the quality of their joke choices. This grants conversations a more natural quality while allowing NPCs to react more dynamically to abnormal inputs.
Following the prototype's completion, the project was then pitched to a committee of ATLAS Institute faculty to determine the project's value and whether development would be allowed to continue.
The committee's verdict was ultimately positive, with key critiques of its design being the lack of a narrative reason for why the player would want to continue and doubting the effectiveness of its teaching aspect.
Following the project's approval, the prototype was fleshed out with deck customization, integrating the deck with card-drawing and a basis for the overworld.
Modifier cards were also added, as their effects were based partially on turn order and thus required a separate system from the blue strategy cards.
Feedback from the approval process was also considered, and the project shifted its focus away from teaching and towards providing an entertaining, silly experience that retains the original vision of mechanical depth.
The game's story was fleshed out to provide player motivation, placing them in the role of a downtrodden former comedian who resolves to use their jokes to help both themself and others by lifting their spirits in a dark and dismal world. The environment would see slight improvement upon helping each NPC, not completely eliminating the oppressive atmosphere but making noticeable changes in the lives of the characters.
Subsequent user tests showed both the need for a tutorial and a desire to learn more about the game's characters, thus a tutorial area was created for the protagonist to talk to themself in the mirror before talking to anyone else, with the player only being allowed to leave once their own spirits were recovered.
For character building, the response system was modified to queue additional, non-joke-related dialogue lines as another means of learning more about characters and giving NPCs more agency in conversations.
As with the original playtests, testers needed additional feedback to learn from their mistakes, responses occasionally contradicted numerical outcomes (a positive response being met with more stress and less mood, for instance) and net-zero responses continued to confuse the learning process.
To remedy this, the evaluation algorithm was tweaked to prevent net-zero responses, mid-range responses were eliminated entirely and the response selection system was overhauled to ensure responses corresponded to stat outcomes. Additional response output was also added to the non-dialogue console window regarding what within a joke the NPC liked or disliked most.
An in-progress version of the final overworld mesh, with a portion of the ground texturing complete.
With the core systems in place, more characters were added to provide differing comedic tastes and personalities. The game's character design maintains a wacky atmosphere by using exclusively nonhuman characters with abnormal features that provide clues to their comedic preferences.
Additionally, the game's output resolution was doubled to reduce the crunchiness of the overworld view while allowing the main conversation UI more room to breathe.
Another round of playtesting revealed that the deck customization UI was in need of a more intuitive design, and thus A/B testing was carried out using figma prototypes (despite figma's limitations)
Based on the A/B test and studying other deck customization systems, most notably for Magic: The Gathering, the UI was revised to more clearly differentiate the deck from the library and suggest a library-first approach based on left-to-right placement of UI elements.
The finished environment mesh, textured and ported into Godot with an auto-generated collision mesh.
Nearing the end of design and development, work on final polishing and usability tweaks began, adding cutscenes and cutscene skipping, hand-drawn mugshots to replace the older placeholder mugshots, and relocating console information into a custom-built message log that highlights different types of information via color.
Music and track-switching were added to set the mood and give a sense of stress when the player's stress reaches critical levels.
Upon the project's completion, it was showcased at CU Boulder ATLAS Expo 2024, with a monitor set up to allow attendees to play the game and experience its story.
Panopticon is a cylindrical, arcade-style side-scroller game built using P5.js and P5Play. Run and roll to make it as far as you can up the tower, avoiding the gaze of the eye and going for a high score.
This project was developed in 2 weeks using P5.js and P5play around the limitations of an arcade-style experience and only using inputs for left, right and one action. Thus, its cylinder format was chosen to provide a novel experience while keeping objectives fully visible and providing a challenging risk-versus-reward experience.
The game is designed around cylindrical movement, which required unique visual effects to properly capture the continuous nature of its levels. Underneath this, however, the game uses a more standard 2D collision system before projecting objects onto a cylindrical play field based on their horizontal position relative to the player.
In this example, a representation of the actual collision mapping is shown in the top left, whereas the game’s interpretation is shown in the center.
Rather than using P5.js' standard 3D rendering tools, the project opted to use manual distortion of generic quadrilaterals to represent the blockers, using the position of a blocker on the cylinder to shear the quad into the correct shape. Later on, the use of manual distortion allowed for additional freedom to add effects, such as randomized sizing and lighting effects for blockers in the background being lit up by light from the center of the tower.
An initial prototype was developed to test the basic engine, after which another was created to add visual effects. exits, rolling and the eye. In this new prototype, the eye is cycle-based rather than exposure-based, exposing uncovered areas to danger on a set interval before allowing safe passage. This timing-based approach proved to be both challenging and uninteresting, thus it was changed to an exposure-based system in the final version. This version also added a darker tint to the background when behind a blocker to visually signal that the player was in cover.
The pixel filter used was promising, however the score text became difficult to read and thus the idea was scrapped in the final version.
The final version added floor transitions, redeeming extra rolls for points at the exit, floor spikes, additional background colors and the ability to roll at the last second to cancel the eye's attack and gain a large number of points.
In addition to sharpening the UI and adding a visual count of the player’s available rolls, this version increased the contrast of the background tint change from the previous version to better signal the player's safety or vulnerability.
The eye's animation was also changed to snap to a downwards position when the player moves out of cover and shake when the player is exposed, which gives a sense of intensity and danger as the background color increases in vibrance until the eye attacks.
You Are Alone is a short shoot-em-up game about remotely controlling four planes in tandem with their four AI units. Swap formations, dodge missiles and avoid lasers while listening to the AI units’ bickering dialogue.
This project was built in 3 weeks using Godot to fit the theme “You are alone”. The game’s design focuses on limiting the player’s vision and mimicking the feeling of non-GUI computer terminals while delivering a short, fully-packaged narrative experience.
In line with its limited-vision wireframe aesthetic, the game is built around a stationary play area that conveys motion via raising and lowering pieces of the ground to mimic terrain moving along the ground.
The game was originally prototyped in P5.js to test the feasibility of the game’s terrain system, which after some development proved successful in a form nearly identical to the final implementation.
The game’s terrain was implemented using a grid of quad objects that are moved up and down according to a heightmap texture read in by the game. This was initially intended to provide an extra challenge for the player akin to the “trench run” sequence from Star Wars: A New Hope. However, the constrained nature of the terrain grid and difficulty gauging the canyon walls’ location caused this idea to be largely scrapped in the final version.
Original canyon heightmap
Original full-height canyon run
Revised canyon heightmap
Canyon in the final version, largely cosmetic
The game initially featured a greater focus on combat, however its static, repetitive nature required a drip-feed of novel content that could not be delivered within the time constraints. As such, dialogue between the four AI units was added to fill time and maintain player engagement while building character for the player’s avatars.
To add character relations and history, the AI units were written like bickering siblings under the assumption they were trained simultaneously on the same data with the goal of collaborating in the future. This allowed the four to have an established group dynamic that could be leveraged for comedy, while adding the user as an outsider figure about whom the AIs are curious.
Dialogue progresses linearly with breaks between conversations, and the system for reading text was built from scratch due to its integration with game UI and its simplistic manner of operation when compared to complex, branching-path dialogue favored by systems like Ink.
Selected code from the dialogue file reader, specifically for loading conversations and checking if any remain
A selection of four conversations from the game's internal dialogue file
Raiding Castle Ashera is a pseudo-side-scroller game, with comedic dialogue and incompetent enemies. Advance through the rain and fight your way into a castle filled with colorful characters.
This project was developed in one week using Bitsy, with the objective of breaking from Bitsy’s traditional focus on interactive fiction and dialogue-driven narrative experiences. To this end, the game was designed around combat as a core theme and styles itself after pop culture conceptions of both knights and samurai.
The initial concept for this game was more combat-focused, designed around a rock-paper-scissors stance system for puzzle-based combat. Despite seeing some moderate success in testing stages, the idea was abandoned due to the technical restraints of Bitsy.
In this system, enemies would need to be removed from the path and interact with the player such that the player could game over upon using the wrong stance, however Bitsy only offers two interactable object types (sprites and items). Of these, sprites cannot be removed from the world, and items are removed automatically regardless of any logic applied, neither of which met the needs of this system.
Due to the combat system being scrapped, the game’s focus shifted to embracing the inevitability of the player’s victory and using it as a source of comedy, with the player character’s quips both reaffirming their superiority while seeding the eventual narrative twist through playful advice based on specific enemies’ dialogue.
Likewise, enemies were written as distracted, unprepared, scared or clumsy in order to add more humor and make the player's effortless victory more plausible. Enemy sprites were made unique by taking the scrapped combat stances and iterating on them in both posing and attire to create a widely varied NPC cast while repurposing existing assets.
Despite attempts to work within Bitsy’s limitations, workarounds were required for the game’s two-stage dialogue and finale, both of which required duplication of assets to achieve their desired effects.
The finale specifically required assets to be flipped vertically in order to create a mirror-reflection effect on the water beneath the bridge, and cleverly placed scene transitions turned an otherwise choppy final segment into a split-second finish befitting the game's Kurosawa-esque affectations.