✨feature: Implementation notes
This commit is contained in:
12
Notes/Clarification Q&A.txt
Normal file
12
Notes/Clarification Q&A.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Implementation Clarification Q&A:
|
||||||
|
---------------------------------
|
||||||
|
1. Should the app keep full room geometry internally and show a cleaner simplified map visually, or do you want the visible map to be as literal as the paper layout?
|
||||||
|
2. Do you want to support player-entered/manual dice at all, or should MVP stay fully automated with only a roll log?
|
||||||
|
3. For in-app presentation, should we favor short flavor snippets plus structured effects, rather than reproducing long room text from the books?
|
||||||
|
4. Do you want lightweight debug/recovery tools planned from the start for blocked generation states, or should we keep the production flow completely clean and handle edge-case recovery only in code/tests?
|
||||||
|
|
||||||
|
1. Let's opt for configurable, but default to clean map visually with the geometry tracked internally. This allows us to have a more user-friendly interface while still maintaining the necessary data for game mechanics.
|
||||||
|
2. For MVP, let's keep it fully automated with only a roll log. This will simplify the initial development and allow us to focus on core features. We can consider adding manual dice input in future updates based on user feedback.
|
||||||
|
3. Let's favor short flavor snippets plus structured effects for in-app presentation. This will make the content more digestible and engaging for players, while still conveying the necessary information effectively.
|
||||||
|
4. Let's plan for lightweight debug/recovery tools from the start. This will help us quickly identify and resolve any issues that arise during development and testing, ensuring a smoother user experience and faster iteration cycles.
|
||||||
|
|
||||||
415
Planning/IMPLEMENTATION_NOTES.md
Normal file
415
Planning/IMPLEMENTATION_NOTES.md
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
# 2D6 Dungeon Implementation Notes
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
This document records the digital-only rulings needed to implement **2D6 Dungeon** as a web app.
|
||||||
|
|
||||||
|
It exists because the books describe a paper play experience, and some parts rely on:
|
||||||
|
|
||||||
|
- player judgment
|
||||||
|
- manual map drawing
|
||||||
|
- flexible interpretation of room text
|
||||||
|
- ad hoc bookkeeping
|
||||||
|
|
||||||
|
The goal here is to make those areas deterministic enough for software without losing the feel of the original game.
|
||||||
|
|
||||||
|
This document should be treated as:
|
||||||
|
|
||||||
|
- the source of truth for adaptation choices
|
||||||
|
- a companion to `GAME_SPEC.md`
|
||||||
|
- a guide for coding heuristics and tests
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
These notes cover:
|
||||||
|
|
||||||
|
- what the app automates
|
||||||
|
- what the player still chooses manually
|
||||||
|
- how ambiguous rules should be resolved in code
|
||||||
|
- where MVP intentionally simplifies the physical game flow
|
||||||
|
|
||||||
|
These notes do **not** replace the rulebooks. They explain how the app should behave when the books leave room for interpretation.
|
||||||
|
|
||||||
|
## Adaptation Principles
|
||||||
|
|
||||||
|
### 1. Preserve rules outcomes, not paper rituals
|
||||||
|
The app should preserve the gameplay consequences of the books even when the physical procedure changes.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- automatically logging calculations instead of requiring note-taking
|
||||||
|
- rendering a generated map instead of requiring player drawing
|
||||||
|
- resolving table lookups in-app instead of asking players to cross-reference PDFs
|
||||||
|
|
||||||
|
### 2. Prefer explicit player confirmation over hidden automation
|
||||||
|
If a rule has a meaningful tactical or strategic choice, the app should ask.
|
||||||
|
|
||||||
|
If a rule is pure bookkeeping, the app should automate it.
|
||||||
|
|
||||||
|
### 3. Keep ambiguity visible
|
||||||
|
When the app applies a heuristic, it should log:
|
||||||
|
|
||||||
|
- what rule area triggered
|
||||||
|
- what choice the engine made
|
||||||
|
- why it made that choice
|
||||||
|
|
||||||
|
### 4. Separate flavor from mechanics
|
||||||
|
Where possible, descriptive room text should be stored separately from mechanical effects so the engine can act deterministically.
|
||||||
|
|
||||||
|
## MVP Defaults
|
||||||
|
These are the default implementation decisions unless superseded later.
|
||||||
|
|
||||||
|
- MVP supports one adventurer and one active campaign.
|
||||||
|
- MVP supports Level 1 only.
|
||||||
|
- MVP uses encoded structured content instead of freeform text parsing.
|
||||||
|
- MVP automates all table rolls and does not support player-entered dice.
|
||||||
|
- MVP keeps a visible roll log, including primary and secondary die for `D66`.
|
||||||
|
- MVP uses deterministic heuristics for map generation and edge-case resolution.
|
||||||
|
- MVP keeps optional tables out of the default ruleset.
|
||||||
|
- MVP should include lightweight debug and recovery tooling in development builds.
|
||||||
|
|
||||||
|
## Automation Boundaries
|
||||||
|
|
||||||
|
### The app should automate
|
||||||
|
|
||||||
|
- dice rolling
|
||||||
|
- modifier application
|
||||||
|
- modified-range clamping
|
||||||
|
- room generation
|
||||||
|
- room connectivity validation
|
||||||
|
- encounter lookup
|
||||||
|
- combat arithmetic
|
||||||
|
- armour reduction and deflection handling
|
||||||
|
- XP updates
|
||||||
|
- inventory quantity changes
|
||||||
|
- save/load and autosave
|
||||||
|
|
||||||
|
### The player should choose
|
||||||
|
|
||||||
|
- starting weapon
|
||||||
|
- starting armour
|
||||||
|
- starting scroll
|
||||||
|
- movement direction when multiple exits are available
|
||||||
|
- when to use potions or scrolls
|
||||||
|
- combat manoeuvre selection
|
||||||
|
- whether to continue exploring or leave the dungeon
|
||||||
|
- town purchase and service choices
|
||||||
|
|
||||||
|
### The app should confirm before applying
|
||||||
|
|
||||||
|
- leaving the current level
|
||||||
|
- consuming one-time items
|
||||||
|
- selling valuable or quest-like items
|
||||||
|
- any action that would end a run or lock out a choice
|
||||||
|
|
||||||
|
## Dice And Roll Presentation
|
||||||
|
|
||||||
|
### Default behavior
|
||||||
|
|
||||||
|
- All rolls are performed by the engine.
|
||||||
|
- Every roll is logged with raw dice, modifiers, and final result.
|
||||||
|
- `D66` logs must preserve:
|
||||||
|
- first die
|
||||||
|
- second die
|
||||||
|
- combined number
|
||||||
|
- whether a modifier/clamp changed the lookup result
|
||||||
|
|
||||||
|
### UI note
|
||||||
|
The interface should visually distinguish:
|
||||||
|
|
||||||
|
- raw roll
|
||||||
|
- modifier
|
||||||
|
- final lookup result
|
||||||
|
|
||||||
|
This matters because many outcomes will otherwise feel opaque in a digital version.
|
||||||
|
|
||||||
|
Manual dice entry is intentionally out of scope for MVP.
|
||||||
|
|
||||||
|
## Map Generation Heuristics
|
||||||
|
|
||||||
|
### Internal representation
|
||||||
|
Use a true room-and-exit graph with spatial coordinates.
|
||||||
|
|
||||||
|
Each room should have:
|
||||||
|
|
||||||
|
- grid origin
|
||||||
|
- width and height
|
||||||
|
- connected exits
|
||||||
|
- room class
|
||||||
|
- generation source tables
|
||||||
|
|
||||||
|
The visual map can be simplified, but the internal representation should preserve geometry well enough to support:
|
||||||
|
|
||||||
|
- overlap checks
|
||||||
|
- boundary checks
|
||||||
|
- last-room logic
|
||||||
|
- secret door fallback logic
|
||||||
|
|
||||||
|
### Visual map modes
|
||||||
|
Map display should be configurable.
|
||||||
|
|
||||||
|
Default behavior:
|
||||||
|
|
||||||
|
- show a cleaner player-friendly rendered map
|
||||||
|
- keep full underlying room geometry for rules and validation
|
||||||
|
|
||||||
|
Future-friendly behavior:
|
||||||
|
|
||||||
|
- allow a more literal geometry-heavy rendering mode later without changing saved data
|
||||||
|
|
||||||
|
### Coordinate system
|
||||||
|
|
||||||
|
- Use integer grid coordinates.
|
||||||
|
- Treat each room as a rectangle on the level plane.
|
||||||
|
- Exits connect through wall midpoints rather than abstract node links only.
|
||||||
|
|
||||||
|
### Collision handling
|
||||||
|
When generated room geometry would overlap an existing room:
|
||||||
|
|
||||||
|
1. Attempt legal placement using the generated exit direction and dimensions.
|
||||||
|
2. If placement is invalid, mark the attempted exit as blocked for this generation pass.
|
||||||
|
3. If all generated exits are invalid, trigger the fallback flow for stalled progression.
|
||||||
|
|
||||||
|
### Boundary handling
|
||||||
|
If a generated room extends outside the legal dungeon boundary:
|
||||||
|
|
||||||
|
1. Do not resize the room silently.
|
||||||
|
2. Reject the placement.
|
||||||
|
3. Continue trying other legal generated exits if available.
|
||||||
|
4. If no legal exits remain, use the same stalled-progression fallback.
|
||||||
|
|
||||||
|
### Room permanence
|
||||||
|
Once a room is generated and placed, it should not be regenerated differently on reload or after backtracking.
|
||||||
|
|
||||||
|
### Last-room logic
|
||||||
|
For MVP, define the "last room" operationally:
|
||||||
|
|
||||||
|
- it is the most recently generated reachable uncleared room on the active level when no other forward generation options remain
|
||||||
|
- if the rulebook requires a special feature to appear in the last room, the engine should assign it only after reachability has been evaluated against the current known graph
|
||||||
|
|
||||||
|
This avoids trying to infer narrative intent from room flavor.
|
||||||
|
|
||||||
|
## Stalled Progression And Secret Door Fallback
|
||||||
|
|
||||||
|
### Trigger condition
|
||||||
|
Treat progression as stalled when:
|
||||||
|
|
||||||
|
- the player has no unresolved reachable exits that can generate a new room
|
||||||
|
- the required reveal threshold or level-completion condition has not been met
|
||||||
|
|
||||||
|
### MVP fallback rule
|
||||||
|
When stalled progression is detected:
|
||||||
|
|
||||||
|
1. Search eligible existing rooms in reverse discovery order.
|
||||||
|
2. Select the most recently discovered room that can legally host a secret exit.
|
||||||
|
3. Create one secret door/exit there.
|
||||||
|
4. Log that the fallback rule was used.
|
||||||
|
5. Mark the level so the fallback cannot be applied repeatedly unless the rules explicitly allow it.
|
||||||
|
|
||||||
|
### Eligibility rules
|
||||||
|
A room is eligible for fallback if:
|
||||||
|
|
||||||
|
- it is reachable
|
||||||
|
- it is already generated
|
||||||
|
- it has wall space for another exit
|
||||||
|
- adding the exit can produce a legal new room placement
|
||||||
|
|
||||||
|
### Reasoning
|
||||||
|
This keeps the game moving while avoiding hidden retries that would make map generation feel arbitrary.
|
||||||
|
|
||||||
|
## Room Content And Text Handling
|
||||||
|
|
||||||
|
### Content storage rule
|
||||||
|
Room results should be encoded as:
|
||||||
|
|
||||||
|
1. structured mechanical fields
|
||||||
|
2. optional flavor text
|
||||||
|
3. explicit references to follow-up tables or entities
|
||||||
|
|
||||||
|
Do not rely on runtime parsing of prose to determine rules.
|
||||||
|
|
||||||
|
### Verbatim text policy
|
||||||
|
Use book text sparingly in the app and store it as display content, not executable logic.
|
||||||
|
|
||||||
|
Implementation note:
|
||||||
|
|
||||||
|
- if a room paragraph mixes flavor and mechanics, split it during content entry
|
||||||
|
- keep a source reference so the original wording is traceable during validation
|
||||||
|
- favor short flavor snippets in the main gameplay UI, with structured mechanical effects driving resolution
|
||||||
|
|
||||||
|
### Unique and narrative rooms
|
||||||
|
When a room or result is effectively unique:
|
||||||
|
|
||||||
|
- add a uniqueness flag in content
|
||||||
|
- track whether it has already appeared in campaign or run state
|
||||||
|
- prevent duplicate generation unless the books explicitly allow repeats
|
||||||
|
|
||||||
|
## Encounter Generation
|
||||||
|
|
||||||
|
### Encounter lookup
|
||||||
|
Encounter resolution should be a two-step process:
|
||||||
|
|
||||||
|
1. determine encounter type from the room/level table
|
||||||
|
2. resolve creature or event content from the referenced table/card
|
||||||
|
|
||||||
|
This preserves traceability and makes it easier to validate incomplete data.
|
||||||
|
|
||||||
|
### Multi-enemy groups
|
||||||
|
When a result generates multiple creatures:
|
||||||
|
|
||||||
|
- store them as separate combatants linked to one encounter
|
||||||
|
- keep a shared encounter source
|
||||||
|
- allow combat logs to refer to both the encounter and the individual creature instances
|
||||||
|
|
||||||
|
## Combat Resolution Notes
|
||||||
|
|
||||||
|
### Combat visibility
|
||||||
|
Combat must always show:
|
||||||
|
|
||||||
|
- selected manoeuvre
|
||||||
|
- roll used
|
||||||
|
- exact strike or other bonuses
|
||||||
|
- shift spent
|
||||||
|
- damage dealt
|
||||||
|
- armour prevented
|
||||||
|
- interrupt effects
|
||||||
|
- fatigue effects
|
||||||
|
|
||||||
|
### Interrupt handling
|
||||||
|
For MVP:
|
||||||
|
|
||||||
|
- interrupts should pause normal combat resolution and create an explicit pending interrupt state
|
||||||
|
- the engine resolves the interrupt fully before continuing the original action
|
||||||
|
|
||||||
|
### Fatigue handling
|
||||||
|
Fatigue should be represented as explicit round-based state, not inferred on the fly from the combat log.
|
||||||
|
|
||||||
|
This makes saves and tests much more reliable.
|
||||||
|
|
||||||
|
### Simultaneous effects
|
||||||
|
When two effects could reasonably happen at the same time, use this priority:
|
||||||
|
|
||||||
|
1. trigger interrupts
|
||||||
|
2. apply hit/miss determination
|
||||||
|
3. apply armour/deflection
|
||||||
|
4. apply damage
|
||||||
|
5. apply defeat checks
|
||||||
|
6. apply post-hit or post-kill rewards/effects
|
||||||
|
|
||||||
|
If the books later define a stricter order for a specific edge case, that specific rule overrides this general priority.
|
||||||
|
|
||||||
|
## Inventory And Economy Rules
|
||||||
|
|
||||||
|
### Inventory tracking
|
||||||
|
The app should track quantities explicitly for:
|
||||||
|
|
||||||
|
- rations
|
||||||
|
- potions
|
||||||
|
- scrolls
|
||||||
|
- treasure
|
||||||
|
- light sources
|
||||||
|
- stackable loot
|
||||||
|
|
||||||
|
### Identification
|
||||||
|
For MVP, use a simple boolean identified state where content requires it.
|
||||||
|
|
||||||
|
Do not build a more elaborate unidentified-item subsystem unless the source material clearly needs it.
|
||||||
|
|
||||||
|
### Sell protection
|
||||||
|
Items tagged as `quest` or `unique` should trigger a confirmation before sale or disposal.
|
||||||
|
|
||||||
|
## Save System Rules
|
||||||
|
|
||||||
|
### Autosave policy
|
||||||
|
Autosave should occur after:
|
||||||
|
|
||||||
|
- room generation
|
||||||
|
- room resolution
|
||||||
|
- combat round resolution
|
||||||
|
- inventory changes
|
||||||
|
- town actions
|
||||||
|
- level transitions
|
||||||
|
|
||||||
|
### Save integrity
|
||||||
|
A save must include:
|
||||||
|
|
||||||
|
- campaign state
|
||||||
|
- active run state, if any
|
||||||
|
- content version
|
||||||
|
- rules version
|
||||||
|
- enough roll/log history to explain the latest state transitions
|
||||||
|
|
||||||
|
### Determinism policy
|
||||||
|
Once a roll or room generation result has occurred, it should be stored, not re-rolled on load.
|
||||||
|
|
||||||
|
## Error Handling And Manual Recovery
|
||||||
|
|
||||||
|
### Missing content reference
|
||||||
|
If a rule points to missing encoded data:
|
||||||
|
|
||||||
|
1. block only the affected action
|
||||||
|
2. show a developer-readable error message
|
||||||
|
3. preserve the save
|
||||||
|
4. log the missing table or content ID
|
||||||
|
|
||||||
|
### Impossible generation state
|
||||||
|
If the engine reaches a state where no legal room can be placed and fallback has already been used:
|
||||||
|
|
||||||
|
1. mark the run as blocked, not corrupted
|
||||||
|
2. expose a debug/admin recovery action in development builds
|
||||||
|
3. log the full generation context for diagnosis
|
||||||
|
|
||||||
|
### Debug tooling expectation
|
||||||
|
Plan lightweight developer-facing recovery tools from the start.
|
||||||
|
|
||||||
|
Initial scope:
|
||||||
|
|
||||||
|
- inspect current room graph and unresolved exits
|
||||||
|
- inspect the latest generation and roll logs
|
||||||
|
- force-save diagnostic snapshots
|
||||||
|
- manually unblock a run in development mode only
|
||||||
|
|
||||||
|
## Content Entry Conventions
|
||||||
|
|
||||||
|
### Table encoding
|
||||||
|
Each encoded table should include:
|
||||||
|
|
||||||
|
- source book
|
||||||
|
- source page
|
||||||
|
- table code
|
||||||
|
- dice type
|
||||||
|
- result keys
|
||||||
|
- structured effects where possible
|
||||||
|
- freeform notes only when mechanics cannot be fully structured yet
|
||||||
|
|
||||||
|
### Traceability
|
||||||
|
Every creature, room, and item should preserve a link back to:
|
||||||
|
|
||||||
|
- source page
|
||||||
|
- originating table, when applicable
|
||||||
|
|
||||||
|
### MVP content status
|
||||||
|
For MVP, content can be entered in three passes:
|
||||||
|
|
||||||
|
1. minimally playable structured data
|
||||||
|
2. improved rules annotations
|
||||||
|
3. richer flavor and display text
|
||||||
|
|
||||||
|
## Testing Notes
|
||||||
|
|
||||||
|
The most important adaptation-specific tests are:
|
||||||
|
|
||||||
|
1. `D66` primary/secondary order is preserved in logs and lookups.
|
||||||
|
2. Modified ranges clamp to the nearest legal result.
|
||||||
|
3. Room generation never creates overlapping rooms.
|
||||||
|
4. Secret door fallback triggers exactly once under the chosen MVP rule.
|
||||||
|
5. Reloading a save does not change previously generated rooms or rolls.
|
||||||
|
6. Interrupts pause and resume combat in the correct order.
|
||||||
|
7. Unique room or event results do not duplicate after save/load or backtracking.
|
||||||
|
|
||||||
|
## Confirmed Product Decisions
|
||||||
|
|
||||||
|
These decisions are approved for planning and implementation:
|
||||||
|
|
||||||
|
1. Map display should be configurable, with a clean visual map as the default and full internal geometry preserved for rules.
|
||||||
|
2. MVP should remain fully automated for dice, with transparency provided through the roll log rather than player-entered rolls.
|
||||||
|
3. In-app presentation should favor short flavor snippets plus structured mechanical effects.
|
||||||
|
4. Lightweight debug and recovery tools should be planned from the start for development use.
|
||||||
BIN
Source/2D6 Dungeon - Play Sheet.pdf
Normal file
BIN
Source/2D6 Dungeon - Play Sheet.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user