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
166
167
168
169
170
171
172
173
174
|
# Dungeon Crawl
Team members:
- Freya Murphy <freya@freyacat.org>
- Audrey Fuller <alf9310@rit.edu>
- Yusif 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: On encountering an enemy, the player can choose to attack or use an item.
- 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.
## 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 it's components determanistically.
- ```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``` Genreates 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 representa 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
- Thoughts on testing. These might include critical functions or data structures
that will be given `#[test]` functions. Also consider using the
[`insta`](https://crates.io/crates/insta) crate,
[`mockall`](https://crates.io/crates/mockall) crate,
[`proptest`](https://crates.io/crates/proptest) crate,
[`quickcheck`](https://crates.io/crates/quickcheck) crate,
[`test_case`](https://crates.io/crates/test-case) crate, or [`cargo
fuzz`](https://rust-fuzz.github.io/book/cargo-fuzz.html) tool.
- Thoughts on a “minimal viable product” and “stretch goals”. Be sure to review
the final project grading rubric and consider organizing the project around a
core deliverable that will almost certainly be achieved and then a number of
extensions and features that could be added to ensure that project is of
suitable size/scope/effort.
- Expected functionality to be completed at the Checkpoint.
***
***
The following should be deleted from the proposal document, but is included in the initial `Proposal.md` file for reference.
## Final Project Rubric
- Correctness (15%)
- Free of compilation errors and warnings.
- Correctly accomplishes the goals of the project.
- Correctness is supported by suitable testing.
- Style/Design (15%)
- Project applies one or more elements of Rust design:
- Uses traits. Minimally, makes use of traits from the Rust Standard Library (e.g., `PartialEq` and `Iterator`). Better, implements appropriate traits for the types defined for the project. Best, defines and uses novel traits for the project.
- Uses `struct` and `enum` definitions appropriately.
- Uses types to capture invariants.
- Uses modules appropriately (e.g., place distinct data structures in distinct modules).
- Effort/Accomplishment (30%)
- How “big” is the project?
- A “small” project will have at least 500 Lines of Rust Code per team member. (Significantly less than that corresponds to a “tiny” project and would not be acceptable for this activity.) A “medium” or “large” project may have significantly more and would likely also correspond to a more “difficult” project (see below).
- How “difficult” was the project?
- An “easy” project that required trivial data structures and algorithms. Feedback about how to extend the project was ignored. (Projects falling into this category are likely to lose points in Style/Design as well.)
- A “moderate” project that applied basic course concepts, but did not require the group members to significantly challenge themselves or to learn something new.
- A “challenging” project that demonstrates significant thought in design and implementation. Clear that the group members challenged themselves and learned something new by undertaking the project.
- What work was done for the project? (This includes both the work embodied by the final submission and work not obvious from the final submission (e.g., approaches attempted but then abandoned, suitably described).)
- Did the project require learning advanced features?
- Did all team members contribute to the project?
- Presentation (10\%)
|