Construction System PRD
This is a PRD example referenced in #001 AI Coding in Practice: An Indie Developer’s Document-First Approach. It’s a document we’ve actually used and continue to maintain in our project. I don’t think there’s a one-size-fits-all format for PRDs, but I hope this gives you a sense of what one can look like.
This document was exported from our internal Notion workspace. Names in italics are cross-references to other internal documents not publicly accessible.
Overview
Manage the fortress’s building planning and construction:
- In build mode, the player places building blueprints. After assigning crew priorities, crew members capable of construction automatically haul materials and complete the build.
- Supports rotation, deconstruction, and priority adjustment.
Concepts / Terminology
Spatial Structure
| Term | Chinese | Description |
|---|---|---|
| Deck | 甲板 | The outermost overall hierarchical area, composed of multiple Blocks. The game world’s Y coordinate corresponds to different Decks |
| Block | 区块 | The smallest spatial unit in the game; the target of build and deconstruct operations. A single Block can contain multiple Layers of buildings |
| Layer | 层 | A vertical sub-space within a Block, used to place different categories of buildings. Each Layer in the same Block can hold one building |
Layer Type Definitions
| Layer | Chinese | Description |
|---|---|---|
| Floor | 地板层 | The foundation for all construction; other layers must be built on top of a Floor |
| Facility | 设施层 | Workbenches, conveyors, engines, walls, beds, cannons, etc. |
| Pipe | 管道层 | Piping systems |
| Light | 顶灯层 | Lighting fixtures |
| Room | 房间层 | Room designations |
Building Entity
| Term | Chinese | Description |
|---|---|---|
| Building Entity | 建筑实体 | The entity that occupies spatial cells after the player places a building. Frames and completed buildings are different stages of a building entity |
| Building Preview | 建筑预览 | A ghost that follows the mouse — green (placement allowed) or red (placement denied). Becomes a frame upon click confirmation |
| Building Frame | 建筑框架 | The building entity after placement, displayed as a semi-transparent outline. Materials are gradually delivered, and crew accumulate work to complete construction |
| Building Completed | 建筑成品 | The building entity after construction is finished; can be used or deconstructed. See Building for details |
| Work Amount | 工作量 | The total work points required to complete construction of a building from frame to completed state |
States
State Definitions
| State | Chinese | Description |
|---|---|---|
| Idle | 空闲 | Initial state; no building entity exists |
| Frame | 框架 | A placed building, awaiting materials and construction |
| Completed | 完工 | Finished state; construction complete |
| Destroyed | 已摧毁 | Terminal state: destroyed |
| Removed | 已拆除 | Terminal state: deconstructed |
Event Definitions
| Event | Chinese | Description | Triggered By |
|---|---|---|---|
| E1: Designated | 已指定 | Building frame placed | Player |
| E3: MaterialDelivered | 材料送达 | Materials have been delivered | Crew |
| E4: WorkProgressed | 工作推进 | Work has progressed | Crew |
| E5: WorkCompleted | 工作完成 | Work has been completed | System |
| E6: Deconstructed | 已拆除 | Deconstruct (instant) | Player |
| E7: Destroyed | 已摧毁 | Destroyed | System |
E2 has been deleted (the original “Cancelled” state was merged into E6 Deconstruct)
Extended Variables
| Variable | Chinese | Type | Default | Description |
|---|---|---|---|---|
| material_progress | 材料进度 | float | 0% | 0%-100%, delivered materials / required materials |
| work_progress | 工作进度 | float | 0% | 0%-100%, completed work / total work amount |
State Transition Table
| Source State | Event | Guard Condition | Action | Task Operation | Target State |
|---|---|---|---|---|---|
| Idle | E1: Designated | — | — | Generate Build Task | Frame |
| Frame | E6: Deconstructed | — | Drop all delivered materials | Destroy associated Task | Removed |
| Frame | E3: MaterialDelivered | — | Update material_progress | — | Frame |
| Frame | E4: WorkProgressed | material_progress ≥ 100% | Update work_progress | — | Frame |
| Frame | E5: WorkCompleted | work_progress ≥ 100% | — | — | Completed |
| Frame | E7: Destroyed | — | — | Destroy associated Task | Destroyed |
| Completed | E6: Deconstructed | — | Drop all delivered materials | — | Removed |
| Completed | E7: Destroyed | — | — | — | Destroyed |
State Diagram
stateDiagram-v2
state "Idle" as Idle
state "Frame" as Frame
state "Completed" as Completed
state "Destroyed" as Destroyed
state "Removed" as Removed
[*] --> Idle
Idle --> Frame: E1 Designated / Generate Build Task
Frame --> Removed: E6 Deconstructed / Destroy associated Task, drop all materials
Frame --> Frame: E4 WorkProgressed [material_progress ≥ 100%] / Update work_progress
Frame --> Frame: E3 MaterialDelivered / Update material_progress
Frame --> Completed: E5 WorkCompleted [work_progress ≥ 100%]
Frame --> Destroyed: E7 Destroyed / Destroy associated Task
Completed --> Removed: E6 Deconstructed / Drop all materials
Completed --> Destroyed: E7 Destroyed
Destroyed --> [*]
Removed --> [*]
Interaction
Menu navigation (bottom bar tab switching, category expansion) is managed by the global UI Framework. This section only describes the interaction modes specific to the construction system.
Hotkeys:
- B key: Switch to the build tab, expand the building category menu
- C key: Switch to the deconstruct tab, enter deconstruct mode
Operation Mode State Machine
Describes the operation mode states of the construction system. This state machine does not concern itself with UI framework-level tab switching or menu browsing — it only concerns whether the construction system is in a special operation mode. Right-click context menus are managed uniformly by the UI Framework.
State Definitions
| State | Chinese | Description |
|---|---|---|
| Normal | 正常 | No special operation mode in the construction system. Player actions at the UI framework level (pressing B, browsing menus, switching tabs, etc.) do not affect this state |
| Previewing | 预览中 | Currently placing a building blueprint; position/orientation can be adjusted |
| Deconstructing | 拆除模式 | Batch deconstruction mode; clicking a frame or completed building triggers deconstruction |
Event Definitions
| Event | Chinese | Description | Triggered By |
|---|---|---|---|
| I1: EnterPreviewing | 进入预览 | Enter preview mode, carrying a building type parameter | UI Framework (called when the player clicks a specific building in the Building tab menu) |
| I2: EnterDeconstructing | 进入拆除 | Enter deconstruct mode | UI Framework (called when the player switches to the deconstruct tab) |
| I3: ExitMode | 退出模式 | Exit preview/deconstruct mode | Player input (Esc / right-click on empty space) |
| I4: MouseMove | 鼠标移动 | Update preview position | Player input (mouse movement in preview mode) |
| I5: Rotate | 旋转 | Rotate preview orientation | Player input (Q/E/scroll wheel) |
| I6: LeftClick | 左键点击 | Confirm placement / execute deconstruction | Player input (left-click in preview/deconstruct mode) |
| I7: LeftDrag | 左键拖动 | Continuously place buildings | Player input (left-click drag in preview mode) |
Guard Condition Dependencies
| Variable | Chinese | Type | Source |
|---|---|---|---|
| position_valid | 位置合法 | bool | Construction System |
| supports_drag | 支持连续放置 | bool | Construction System |
State Transition Table
| Source State | Event | Guard Condition | Target State | Action |
|---|---|---|---|---|
| Normal | I1: EnterPreviewing | — | Previewing | — |
| Normal | I2: EnterDeconstructing | — | Deconstructing | — |
| Previewing | I3: ExitMode | — | Normal | — |
| Previewing | I4: MouseMove | — | Previewing | Update preview position |
| Previewing | I5: Rotate | — | Previewing | Rotate 90° |
| Previewing | I6: LeftClick | position_valid | Previewing | Trigger E1 Designated |
| Previewing | I6: LeftClick | !position_valid | Previewing | Play error feedback |
| Previewing | I7: LeftDrag | supports_drag | Previewing | Trigger E1 Designated ×N |
| Deconstructing | I3: ExitMode | — | Normal | — |
| Deconstructing | I6: LeftClick | Clicked on frame or completed building | Deconstructing | Trigger E6 Deconstructed |
State Diagram
stateDiagram-v2
state "Normal" as Normal
state "Preview Mode" as Preview
state "Deconstruct Mode" as Decon
[*] --> Normal
Normal --> Preview: I1 EnterPreviewing / UI Framework call
Normal --> Decon: I2 EnterDeconstructing / UI Framework call
Preview --> Normal: I3 ExitMode (Esc / right-click empty space)
Preview --> Preview: I4 MouseMove
Preview --> Preview: I5 Rotate
Preview --> Preview: I6 LeftClick [position_valid] / Trigger E1
Preview --> Preview: I6 LeftClick [!position_valid] / Play error feedback
Preview --> Preview: I7 LeftDrag [supports_drag] / Trigger E1 ×N
Decon --> Normal: I3 ExitMode (Esc / right-click empty space)
Decon --> Decon: I6 LeftClick on frame or completed building / Trigger E6
Right-Click Menu
Right-click menu content defined by the construction system. Show/hide behavior is managed uniformly by the UI Framework.
Frame Menu (right-click on a building frame)
| Button | Action | Triggered Event |
|---|---|---|
| Priority | Modify construction priority | — |
| Deconstruct | Deconstruct this frame | E6 Deconstructed |
Completed Building Menu (right-click on a completed building)
| Button | Action | Triggered Event |
|---|---|---|
| Deconstruct | Deconstruct this building | E6 Deconstructed |
Feedback
Organized by trigger source:
- Operation mode feedback (player interaction)
- Entity state feedback (persistent display)
- System event feedback (instantaneous trigger)
Operation Mode Feedback: Preview Mode
Persistent Feedback (real-time checks on mouse movement)
| Check Condition | Sound | Toast | Visual Feedback | System Behavior |
|---|---|---|---|---|
| Violates Layer dependency rule (R1) | — | — | Preview shown in red | — |
| Violates Layer exclusivity rule (R2) | — | — | Preview shown in red; conflicting building also shown in red | — |
Instantaneous Feedback (triggered on left-click)
| Check Condition | Sound | Toast | Visual Feedback | System Behavior |
|---|---|---|---|---|
| Violates Layer dependency rule (R1) | Error sound | “Cannot build here: Floor foundation required” | — | Prevent placement |
| Violates Layer exclusivity rule (R2) | Error sound | “Cannot build here: space already occupied” | — | Prevent placement |
| Position valid | Placement sound | — | Preview becomes frame; frame entity spawned | Trigger E1 Designated |
Entity State Feedback: Frame State
Persistent Feedback (displayed continuously while the frame exists)
UI feedback is determined by the frame’s own condition checks, not dependent on Task state.
| Check Condition | Sound | Toast | Visual Feedback | System Behavior |
|---|---|---|---|---|
| material_progress < 100% | — | — | Frame displays missing material icon | — |
| No available materials on the map | — | — | Frame displays yellow warning icon + “Materials lacking” | — |
| Frame position unreachable | — | — | Frame displays red warning icon + “Unreachable” | — |
| Task unassigned, no available Crew | — | — | Frame displays pending assignment icon | — |
System Event Feedback (Not Player-Triggered)
E5: WorkCompleted (instantaneous trigger)
| Check Condition | Sound | Toast | Visual Feedback | System Behavior |
|---|---|---|---|---|
| — | Completion sound | “[Building Name] construction complete” | Building spawn animation | Frame transitions to completed building |
Rules
R1: Layer Dependency Rule
- Required: All non-Floor layer buildings must be built on a Block that already has a Floor placed
- Non-Floor layers have no dependency relationships between each other during construction and can be placed in any order
R2: Layer Exclusivity Rule
- Forbidden: Placing multiple buildings on the same Layer of the same Block
- The Room layer is only mutually exclusive with Room-type buildings; it does not affect other Layers
R3: Deconstruction Cascade Rule
- Required: When deconstructing a Floor, cascade-remove all buildings on other Layers within that Block (order: Light → Pipe → Facility → Floor)
- When deconstructing a non-Floor building, only that Layer’s building is removed; other Layers are unaffected
Crew Construction Workflow
This section uses the Task/Action framework defined in Task System. General content such as Task lifecycle, Action definitions, and interrupt response tables can be found in the Task System documentation. This section only describes content specific to the construction system.
Task: Build
Work Type: Construction
Execution Flow
flowchart TD
start(("Start")) --> check1{"material_progress < 100%?"}
check1 -->|Yes| A1["GoTo(Material)"]
A1 --> A2["PickUp"]
A2 --> A3["CarryTo(Frame)"]
A3 --> A4["Drop"]
A4 --> E3["E3: MaterialDelivered"]
E3 --> check1
check1 -->|No| check2{"work_progress < 100%?"}
check2 -->|Yes| B1["GoTo(Frame)"]
B1 --> B2["Build"]
B2 --> E4["E4: WorkProgressed"]
E4 --> check2
check2 -->|No| E5["E5: WorkCompleted"]
Action Descriptions
| Action | Description |
|---|---|
| GoTo(Material) | Move to the nearest available material location |
| PickUp | Pick up material |
| CarryTo(Frame) | Carry material to the frame location |
| Drop | Put down material |
| GoTo(Frame) | Move to a position adjacent to the frame |
| Build | Advance construction progress |
Design Principles:
- The same Crew member is not required to complete the entire construction workflow
- Progress is tracked by the frame entity (
material_progress,work_progress), not by the Task
Task Generation and Assignment
The association mechanism between frames and Tasks is detailed in Task System under “Entity-Task Association.”
Build Task Regeneration Condition:
work_progress < 100% (frame not yet completed, or materials not yet fully delivered).
Task-Side Assignment Conditions:
| Condition | Description |
|---|---|
| Materials available | Required materials exist on the map and are reachable |
| Frame reachable | A traversable path to the frame position exists |
Crew-Side Assignment Conditions: See Task System for details.
Calculation Logic
Calculation: Construction Speed
\[\text{Actual work contribution per tick} = \text{Base work contribution per tick} \times \text{Construction level} \times 0.3\]See Crew under “Skills and Proficiency” for the construction skill level value range.
Base work contribution per tick = 1
Data Configuration
Construction Configuration
[Notion embedded database — Construction Configuration Table]
Material Costs
| Building | Material Cost | Work Amount |
|---|---|---|
| All buildings | Wood × 100 | 1000 |
Acceptance Checklist
Interaction
- B key opens the build menu
- C key enters deconstruct mode
- Q/E/scroll wheel rotates preview
- Esc/right-click on empty space exits mode
- Left-click places a frame
- Left-click drag continuously places buildings
- Right-click on frame shows menu (Priority, Deconstruct)
- Right-click on completed building shows menu (Deconstruct)
Feedback
- Preview turns red when violating R1/R2
- Conflicting building also turns red when violating R2
- Placement failure plays error sound + Toast
- Placement success plays placement sound
- Frame shows missing material icon when materials are lacking
- Yellow warning displayed when no materials are available on the map
- Red warning displayed when frame is unreachable
- Completion plays sound, Toast, and animation
Rules
- R1: Non-Floor buildings must be placed on a Floor
- R2: Same Block, same Layer cannot have multiple buildings
- R3: Deconstructing Floor cascades deconstruction to other Layers
Construction Workflow
- Placing generates a frame and a Build Task
- Crew correctly hauls materials to the frame
- Construction speed matches the formula (base × construction skill level × 0.3)
- Frame transitions to completed building when work amount is met
- Frame regenerates a Task after interruption
States and Materials
- Deconstructing a frame: drops delivered materials, destroys Task
- Deconstructing a completed building: drops all materials
- Frame/completed building destroyed: destroys associated Task
To Be Refined
- Priority-related content during the construction process