Start writing out user stories for game creation
Some checks failed
Monorepo build / build-flake (push) Has been cancelled

This commit is contained in:
2025-12-02 23:34:11 -05:00
parent 726816cfbd
commit 0e3fac90a7
19 changed files with 215 additions and 18 deletions

View File

@@ -22,7 +22,7 @@ tasks:
report:
cmds:
- cargo run --bin planning-report planning/
- cargo watch -x 'run --bin planning-report planning/'
test-all:
cmds:

View File

@@ -17,7 +17,7 @@ As a player, I want to see my character sheet while I am in a game so that I can
- [[T000-task-example]] <!-- use Obsidian wikilinks -->
## Planning
- [[planning/US000-planning]] <!-- link to planning doc (see planning template) -->
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]

View File

@@ -16,9 +16,6 @@ As a player, I want to adjust scores on my character sheet so that I can always
## Linked Tasks
- [[T0004 Add Cypher system Spin Box for the pools]]
- [[T0005 Add a Candela mechanism to set and clear Marks]]
- [[T0006 Add a Candela mechanism to mark a Scar]]
- [[T0007 Add a Candela mechanism to set and clear Drives]]
- [[T0008 Add a Candela mechanism to set and clear Resistances]]
- [[T0014 Add pool meters to the GM view of a Cypher system character]]
- [[T0015 Add health meters to the GM view of a Candela system character]]
- [[T0016 Persist character sheets to disk]]
@@ -26,7 +23,7 @@ As a player, I want to adjust scores on my character sheet so that I can always
- [[T0018 Create APIs for Character CRUD]]
## Planning
- [[planning/US000-planning]] <!-- link to planning doc (see planning template) -->
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]

View File

@@ -16,7 +16,7 @@ As a user, I want my session to be preserved through server restarts so that my
- [[T0012 Create a database and persist sessions]]
## Planning
- [[planning/US000-planning]] <!-- link to planning doc (see planning template) -->
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]

View File

@@ -16,7 +16,7 @@ As a Storyteller, I want to be able to create characters for my game without pla
- [[T000-task-example]] <!-- use Obsidian wikilinks -->
## Planning
- [[planning/US000-planning]] <!-- link to planning doc (see planning template) -->
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]

View File

@@ -0,0 +1,27 @@
---
id: US0008
type: userstory
status: Not Started
---
## Story
As a player, I want to be able to edit my full Candela character sheet so that I can track the status of my character and reflect my character's growth over time.
## Acceptance Criteria
- The user can add abilities to their character sheet
- The user can add scars to the character sheet
- The user can set and clear drives and resistances
- The user can move an action score from one action to another
## Linked Tasks
- [[T0006 Add a Candela mechanism to mark a Scar]]
- [[T0007 Add a Candela mechanism to set and clear Drives]]
- [[T0008 Add a Candela mechanism to set and clear Resistances]]
## Planning
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]
## Status
- Status: Not Started / In Progress / Blocked / Done
- Remaining tasks: 0 / N <!-- keep updated or automate -->

View File

@@ -0,0 +1,26 @@
---
id: US0009
type: userstory
status: Not Started
---
## Story
## Acceptance Criteria
- AC1
- AC2
- AC3
## Linked Tasks
- [[T000-task-example]] <!-- use Obsidian wikilinks -->
## Planning
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]
## Status
- Status: Not Started / In Progress / Blocked / Done
- Remaining tasks: 0 / N <!-- keep updated or automate -->

View File

@@ -0,0 +1,26 @@
---
id: US0010
type: userstory
status: Not Started
---
## Story
As a user, I want to create a new game and configure my existing games so that I can host a game for players.
## Acceptance Criteria
- The user can create a new game.
- The user is automatically assigned as the GM for a game they create.
- The GM for a game can add and remove users.
- The GM for a game can view and edit all characters in the game.
## Linked Tasks
- [[T000-task-example]] <!-- use Obsidian wikilinks -->
## Planning
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]
## Status
- Status: Not Started / In Progress / Blocked / Done
- Remaining tasks: 0 / N <!-- keep updated or automate -->

View File

@@ -0,0 +1,28 @@
---
id: US0011
type: userstory
status: Not Started
---
## Story
**As a** [role]
**I want** [goal]
**So that** [benefit]
## Acceptance Criteria
- AC1
- AC2
- AC3
## Linked Tasks
- [[T000-task-example]] <!-- use Obsidian wikilinks -->
## Planning
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]
## Status
- Status: Not Started / In Progress / Blocked / Done
- Remaining tasks: 0 / N <!-- keep updated or automate -->

View File

@@ -2,7 +2,7 @@
id: T0005
type: task
story: US0005
status: In Progress
status: Done
assignee:
---

View File

@@ -1,7 +1,7 @@
---
id: T0006
type: task
story: US0005
story: US0008
status: Not Started
assignee:
---

View File

@@ -1,7 +1,7 @@
---
id: T0007
type: task
story: US0005
story: US0008
status: Not Started
assignee:
---

View File

@@ -1,7 +1,7 @@
---
id: T0008
type: task
story: US0005
story: US0008
status: Not Started
assignee:
---

View File

@@ -2,7 +2,7 @@
id: T0014
type: task
story: US0005
status: In Progress
status: Done
assignee:
---

View File

@@ -2,7 +2,7 @@
id: T0015
type: task
story: US0005
status: In Progress
status: Done
assignee:
---

View File

@@ -0,0 +1,17 @@
---
id: D0005
type: defect
story:
status: Not Started
assignee:
---
## Description
Any time the user updates the health or bleed marks for their character, the character sheet should be broadcast to the GM. At this time, GMs must refresh the page to see any updates.
## Definition of Done
- DoD 1
- DoD 2
## Notes
- code paths, files to touch, tests to add

View File

@@ -0,0 +1,42 @@
# Planning / US0010 — Detailed plan
## Overview
The goal here is to build basic game setup and editing.
Creating a new game is easy. Simply click the "New Game" button on the game management screen.
The game editing screen must contain a variety of details:
- The name of the game
- The system
- A list of scenes
- A list of images
- A list of all the cards
- A list of all the characters
The user will need to be able to
- create a new scene
- edit a scene -- this implies a scene editing dialog
- add image resources
- associate images with the scene background and with tabletop images
- create a card
- edit a card
## Architecture / Design notes
- components, models, API sketches
## Implementation plan (steps)
1. Step 1
2. Step 2
3. Step 3
## Risks & Dependencies
- external systems, third-party libs, design decisions
## Estimation
- Rough estimate (hours / story points)
## Acceptance / QA notes
- Anything QA must verify beyond ACs.
## Open questions
- Q1, Q2

View File

@@ -18,7 +18,7 @@ status: Not Started
- [[T000-task-example]] <!-- use Obsidian wikilinks -->
## Planning
- [[planning/US000-planning]] <!-- link to planning doc (see planning template) -->
- [[US0010-planning]] <!-- link to planning doc (see planning template) -->
## Manual Tests (links)
- [[M000-login-success]]

View File

@@ -18,6 +18,8 @@ struct FrontMatter {
fn main() -> std::io::Result<()> {
let planning_dir = std::env::args().skip(1).next().unwrap();
let mut user_stories: HashMap<String, Vec<String>> = HashMap::new();
let mut story_titles: HashMap<String, String> = HashMap::new();
let mut task_titles: HashMap<String, String> = HashMap::new();
// Traverse the planning directory
for entry in walkdir::WalkDir::new(planning_dir) {
@@ -27,13 +29,31 @@ fn main() -> std::io::Result<()> {
if let Some(frontmatter) = extract_frontmatter(&content) {
if frontmatter.item_type == "userstory" && frontmatter.status != "Done" {
user_stories.entry(frontmatter.id.clone()).or_insert(vec![]);
story_titles.insert(
frontmatter.id.clone(),
entry
.path()
.file_name()
.and_then(|p| p.to_str())
.map(|s| story_title(s.to_owned()))
.unwrap(),
);
} else if frontmatter.item_type == "task" && frontmatter.status != "Done" {
if let Some(story_id) = frontmatter.story {
user_stories
.entry(story_id)
.or_insert(vec![])
.push(frontmatter.id);
.push(frontmatter.id.clone());
}
task_titles.insert(
frontmatter.id.clone(),
entry
.path()
.file_name()
.and_then(|p| p.to_str())
.map(|s| task_title(s.to_owned()))
.unwrap(),
);
}
}
}
@@ -42,13 +62,17 @@ fn main() -> std::io::Result<()> {
// Generate the report
println!("Open User Stories Report:");
for (story, tasks) in &user_stories {
println!("\nUser Story: {}", story);
println!(
"\nUser Story: {} {}",
story,
story_titles.get(story).unwrap()
);
if tasks.is_empty() {
println!(" No open tasks.");
} else {
println!(" Open Tasks:");
for task in tasks {
println!(" - {}", task);
println!(" - {} {}", task, task_titles.get(task).unwrap());
}
}
}
@@ -72,3 +96,13 @@ fn extract_frontmatter(content: &str) -> Option<FrontMatter> {
let yaml = &content[start + 3..end];
serde_yaml::from_str(yaml).ok()
}
fn story_title(content: String) -> String {
let file_stem: String = content.chars().rev().skip(3).collect();
file_stem.chars().rev().skip(7).collect()
}
fn task_title(content: String) -> String {
let file_stem: String = content.chars().rev().skip(3).collect();
file_stem.chars().rev().skip(6).collect()
}