1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
# Dungeon Crawl
Team members:
- Freya Murphy <freya@freyacat.org>
- Audrey Fuller <alf9310@rit.edu>
- Yusuf Elsharawy <yse2561@rit.edu>
- Ryan Symons <ras1178@rit.edu>
## Summary Description
Embark on a classic roguelike dungeon-crawling adventure. Players will explore
procedurally generated, tile-based dungeon floors crafted using a Wave Function
Collapse algorithm. Battle through waves of enemies with real-time combat,
collect powerful items, and push your limits to see how deep you can delve
into the ever-changing depths.
## Use Cases
### Player Input
- Directional Movement: The player can move up, down, left, or right across a tile-based dungeon map using WASD or arrow keys.
- Combat Actions: The player can use a mapped key to perform an attack in the direction of player movement.
- Item Interaction: The player can pick up items, manage inventory, and use consumables like potions.
### Gameplay Loop
- The player spawns on floor 1 of the dungeon.
- The map is procedurally generated using the Wave Function Collapse algorithm.
- Enemies and items are randomly spawned on valid tiles based on probabilities.
- The player explores and collects items until encountering an enemy.
- A real-time battle begins, where the player takes damage when colliding with an enemy, and the enemy takes damage when the player's weapon makes contact with them (in the same style as early zelda games)
- After winning, the player collects loot and continues exploring until finding the staircase to the next floor.
- Difficulty increases as the player descends deeper.
### Preliminary Dungeon Enemy Concepts
- **Zombie:** Slow Movement | Melee | Moderate HP
- **Skeleton:** Slow Movement | Ranged | Low HP
- **Spider:** Fast Movement | Melee | Moderate HP
- **Ghost:** Slow Movement | Melee | Moderate HP | Can move through walls/air tiles
- **Goblin:** Fast Movement | Melee | Low HP | When causing damage to the player, has a chance to make them drop an item
- **Troll:** Slow Movement | Melee | High HP
- **Slime:** Fast Movement | Ranged | Moderate HP
## Components
### **Game Binary Crate**
- **[main](game\src\main.rs)** - Initializes the game state and handles the Model-View-Controller loop.
- **input.rs** - Handles keyboard/mouse/controller events and translates them into gameplay actions.
- ```enum InputEvent { Move(Direction), Attack, UseItem(usize), NextFloor }```
- ```pub fn poll_input() -> Option<InputEvent>``` — Returns the next player input event, if available.
### **Dungeon Library Crate**
Core functionality for interacting with a `Dungeon` data structure and its components.
- `Dungeon` - The game state of the dungeon crawler.
```rust
pub struct Dungeon {
pub floor: Floor,
pub player: Entity,
pub enemies: Vec<Entity>,
pub items: Vec<Item>,
pub depth: u32,
pub rng: StdRng,
}
```
- ```pub fn new_seeded(seed: u64) -> Self``` Create a new dungeon with its components deterministically.
- ```pub fn update(&mut self, action: Action)``` Applies a player or AI action to the game state.
- ```pub fn next_floor(&mut self)``` Generates a new Floor when the player descends stairs.
- **[Map Module](dungeon\src\map.rs)** - Structures for the dungeon game map including the current `Floor`, map `Tile`, and `Entity`.
- `Floor` - Current playing grid of the dungeon. It contains the tiles of the grid, and the starting position of the player.
- ```pub fn generate_seeded(_seed: u64) -> Self``` Generates a dungeon `Floor` using wave function collapse provided with a seed. The provided seed is used for randomness in the wave function collapse algorithm.
- `Tile` - Enum that represents what is (or is not) at any given spot in the dungeon grid.
```rust
pub enum Tile {
Floor,
Air,
StairDown,
}
```
- `Entity` - The main player, or any other ai autonomous character that can move freely across the dungeon.
- ```pub const fn new(pos: Pos, dir: Direction, kind: EntityKind) -> Self``` Creates a new `Entity` at a given `Pos`, `Direction`, and `EntityKind`.
- ``` pub fn take_turn(&mut self, dungeon: &mut Dungeon)``` — Simple AI behavior for enemies.
- `Item` - An item that can be picked up by the player entity
- **Player Module** - Data specific to the player character, including inventory
```rust
pub struct Player {
pub entity: Entity,
pub hp: i32,
pub atk: i32,
pub def: i32,
pub xp: u32,
pub inventory: Vec<Item>,
}
```
- ```pub fn attack(&self, target: &mut Entity)``` — Executes a basic attack.
- ```pub fn use_item(&mut self, index: usize)``` — Uses an item from the inventory.
- ```pub fn gain_xp(&mut self, amount: u32)``` — Increases player XP and handles leveling up.
- **Item Module** - Manages collectible and usable items.
```rust
pub struct Item {
pub name: String,
pub kind: ItemKind,
pub pos: Pos,
}
```
- `Item Kind` - Enum describing item type
```rust
pub enum ItemKind {
Potion { heal: i32 },
Weapon { atk_bonus: i32 },
Armor { def_bonus: i32 },
}
```
- **Combat Module** - Handles combat resolution and damage calculations.
```rust
pub struct CombatResult {
pub damage_dealt: i32,
pub target_died: bool,
}
```
- ```pub fn calculate_damage(atk: i32, def: i32) -> i32``` — Core formula for combat outcomes.
- **[Position Module](dungeon\src\pos.rs)** - Structures for representation an entity or objects position and facing direction inside the dungeon grid.
- `Direction` - Enum that represents the direction an entity or any position object is facing inside the dungeon map. Since the dungeon lives on a grid, there are only four possible directions.
- `Pos` - 2D position inside the dungeon grid.
- ```pub const fn step(self, dir: Direction) -> Option<Self>``` Steps `Pos` one space in the `Direction` `dir`. Returns `None` if the position goes out of the map.
### **Graphics Library Crate**
Core functionality for rendering using the `raylib` library. Independent from game logic.
- `Window` - The game window containing rayLib Handle and Thread
- `pub fn renderer(&mut self) -> Renderer<'_>` - Returns the renderer for the game.
- **[Render Module](graphics\src\render.rs)** - The `render` module contains the structures for displaying the game, with each frame represented by a `Renderer` and frame specific information in `FrameInfo`.
- `FrameInfo` - Contains information about the current frame being rendered.
- `Renderer` - Renderer for a single frame of the game. It is created per frame.
- `pub fn draw_frame(&mut self, dungeon: &Dungeon)` Draws an entire frame
- `pub fn draw_entity(&mut self, entity: &Entity)` Draws a player or enemy sprite.
- `pub fn draw_tile(&mut self, tile: &Tile, pos: Pos)` Draws a tile at a position.
- `pub fn draw_ui(&mut self, player: &Player)` Renders player HP, inventory, and floor number.
## Testing
For our test libraries, we'll be sticking with the #[test] built-in functionality.
**Critical Tests**
- Map generation consistency (#[test] ensuring WFC produces valid connected maps).
- Combat damage calculation and turn order validation.
- Item effects and inventory behavior.
- Player movement and boundary checking.
## Development Plan
### Minimum Viable Product (MVP)
- Single floor procedural dungeon generation using WFC.
- Player movement and enemy spawning.
- Real-time combat with collision logic.
- Simple boxes and circles as sprites.
### Stretch Goals
- Multi-floor progression with increasing difficulty.
- Expanded item system (weapons, armor, consumables).
- Player stats and leveling.
- Usage of pixel art sprite sheets.
### Checkpoint Goals
- Procedural map generation functional and debuggable.
- Player movement implemented with basic collision detection.
- At least one working enemy and combat loop.
|