final fixes and readme
This commit is contained in:
@@ -1,212 +0,0 @@
|
|||||||
# Untitled Maze Game - ID30011 Midterm Project Proposal (Revised)
|
|
||||||
|
|
||||||
- **Name:** Bumgyu Suh
|
|
||||||
- **Student ID:** 20240905
|
|
||||||
- **Repository URL:** https://git.prototyping.id/20240905/homework5
|
|
||||||
- **Engine:** Babylon.js
|
|
||||||
|
|
||||||
## 1. Project Summary
|
|
||||||
|
|
||||||
Untitled Maze Game is a 3D first-person dungeon maze game. Each level generates a new maze, and the player must find the key hidden in one chest, then reach the exit area to progress.
|
|
||||||
|
|
||||||
Main twist:
|
|
||||||
- Opening a chest that has already been opened in the current level causes immediate game over.
|
|
||||||
- This memory pressure creates the core challenge.
|
|
||||||
|
|
||||||
Scoring tracked for now:
|
|
||||||
- Total time spent
|
|
||||||
- Progress (level reached)
|
|
||||||
|
|
||||||
## 2. Finalized Design Decisions
|
|
||||||
|
|
||||||
These are locked decisions for implementation:
|
|
||||||
|
|
||||||
1. Chest reset scope:
|
|
||||||
- Opened chest state resets every level.
|
|
||||||
|
|
||||||
2. Chest interaction:
|
|
||||||
- Player must left click while targeting a chest.
|
|
||||||
- Interaction prompt shown: "Click to open chest" when chest is targetable.
|
|
||||||
|
|
||||||
3. Maze topology:
|
|
||||||
- Maze is allowed to contain loops (not necessarily a perfect maze).
|
|
||||||
- Each level must guarantee a minimum number of dead-end cells with chests.
|
|
||||||
- Additional dead-ends without chests are allowed.
|
|
||||||
|
|
||||||
4. Difficulty scaling:
|
|
||||||
- Increase maze width and height by level.
|
|
||||||
- Lighting settings stay fixed (no light-based difficulty scaling).
|
|
||||||
|
|
||||||
5. Win condition:
|
|
||||||
- Exit is a highlighted zone/area.
|
|
||||||
- Entering exit zone with key automatically transitions to next level.
|
|
||||||
|
|
||||||
6. Visual implementation order:
|
|
||||||
- Start with primitive meshes for all gameplay-critical elements.
|
|
||||||
|
|
||||||
## 3. Gameplay Rules
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
- Search chests to find the key.
|
|
||||||
- Avoid reopening previously opened chests in that level.
|
|
||||||
- Reach exit area after obtaining key.
|
|
||||||
- Clear levels as fast as possible.
|
|
||||||
|
|
||||||
## Win / Lose Conditions
|
|
||||||
- Win level: player enters exit zone while holding key.
|
|
||||||
- Soft block: entering exit without key shows message and does not transition.
|
|
||||||
- Lose run: player opens a chest already opened in current level.
|
|
||||||
|
|
||||||
## Player Controls
|
|
||||||
- `W/A/S/D`: movement
|
|
||||||
- Mouse: look direction
|
|
||||||
- Left click: open chest when targeted
|
|
||||||
|
|
||||||
## 4. Technical Architecture Plan
|
|
||||||
|
|
||||||
To keep implementation clean, split into four layers:
|
|
||||||
|
|
||||||
1. Maze Logic Layer (pure functions)
|
|
||||||
- Generate grid layout
|
|
||||||
- Detect dead-ends
|
|
||||||
- Place chests, key chest, exit, and spawn
|
|
||||||
- Return plain data only
|
|
||||||
|
|
||||||
2. Game State Layer
|
|
||||||
- Track current level
|
|
||||||
- Track timer / elapsed time
|
|
||||||
- Track hasKey
|
|
||||||
- Track chest open state (per level)
|
|
||||||
- Resolve win/lose transitions
|
|
||||||
|
|
||||||
3. Babylon Scene Layer
|
|
||||||
- Build meshes from grid
|
|
||||||
- Configure first-person camera and collisions
|
|
||||||
- Handle raycast/pick chest targeting and click interaction
|
|
||||||
- Render highlighted exit zone
|
|
||||||
|
|
||||||
4. UI Layer
|
|
||||||
- HUD: level, time, key possession, prompt/status text
|
|
||||||
- Messages: wrong chest, key found, find key first, game over, level clear
|
|
||||||
|
|
||||||
## 5. Data Model (Revised)
|
|
||||||
|
|
||||||
Use separate static and dynamic state instead of overloading one numeric ID.
|
|
||||||
|
|
||||||
## Static cell data
|
|
||||||
- `cellType`: wall | path | chest | exit | spawn
|
|
||||||
|
|
||||||
## Dynamic state
|
|
||||||
- `openedChests`: set/map keyed by cell coordinate
|
|
||||||
- `keyChestCoord`: coordinate of the one correct chest
|
|
||||||
- `hasKey`: boolean
|
|
||||||
|
|
||||||
Benefits:
|
|
||||||
- Cleaner logic
|
|
||||||
- Easier debugging
|
|
||||||
- Lower chance of state bugs from mixed meanings
|
|
||||||
|
|
||||||
## 6. Level Generation Specification
|
|
||||||
|
|
||||||
Per level:
|
|
||||||
|
|
||||||
1. Compute maze dimensions from level number.
|
|
||||||
2. Generate a solvable maze grid (loops allowed).
|
|
||||||
3. Find dead-end candidates.
|
|
||||||
4. Place at least `minChestDeadEnds` chests on dead-ends.
|
|
||||||
5. Choose one chest as key chest.
|
|
||||||
6. Choose one exit location (highlighted zone).
|
|
||||||
7. Choose valid spawn point.
|
|
||||||
8. Validate reachability:
|
|
||||||
- Spawn can reach key chest
|
|
||||||
- Spawn (after key) can reach exit
|
|
||||||
|
|
||||||
If validation fails, regenerate.
|
|
||||||
|
|
||||||
## 7. Babylon.js Implementation Notes
|
|
||||||
|
|
||||||
- Camera: use first-person style camera (for example `UniversalCamera`) with pointer lock.
|
|
||||||
- Collision: enable gravity/collision with wall meshes.
|
|
||||||
- Interaction: center-screen ray pick + left click.
|
|
||||||
- Chest meshes: primitive boxes in MVP.
|
|
||||||
- Exit zone: highlighted plane or emissive ground area.
|
|
||||||
- Keep one scene; rebuild level meshes on level transition.
|
|
||||||
|
|
||||||
## 8. MVP Checklist (Implementation Order)
|
|
||||||
|
|
||||||
## Phase A - Core scaffold
|
|
||||||
- [ ] Refactor current Babylon template into modular files/functions.
|
|
||||||
- [ ] Add first-person camera controls and pointer lock.
|
|
||||||
- [ ] Add movement collision against wall meshes.
|
|
||||||
|
|
||||||
## Phase B - Maze system
|
|
||||||
- [ ] Implement maze generation with loops allowed.
|
|
||||||
- [ ] Implement dead-end detection.
|
|
||||||
- [ ] Implement chest placement with minimum dead-end chest count.
|
|
||||||
- [ ] Implement key chest assignment and exit placement.
|
|
||||||
- [ ] Implement reachability validation and regenerate on failure.
|
|
||||||
|
|
||||||
## Phase C - Gameplay rules
|
|
||||||
- [ ] Implement per-level chest open tracking.
|
|
||||||
- [ ] Implement chest click interaction and "Click to open chest" prompt.
|
|
||||||
- [ ] Implement outcomes: wrong chest / key found / reopened chest game over.
|
|
||||||
- [ ] Implement exit-zone behavior: block without key, auto-next-level with key.
|
|
||||||
|
|
||||||
## Phase D - UI and scoring
|
|
||||||
- [ ] Display level number.
|
|
||||||
- [ ] Display elapsed total time.
|
|
||||||
- [ ] Display key possession status.
|
|
||||||
- [ ] Display gameplay feedback messages.
|
|
||||||
|
|
||||||
## Phase E - Level progression
|
|
||||||
- [ ] Increase maze width/height per level.
|
|
||||||
- [ ] Reset per-level state correctly on transition.
|
|
||||||
- [ ] Preserve run-level state (time, current level progression).
|
|
||||||
|
|
||||||
## 9. Testing Checklist
|
|
||||||
|
|
||||||
- [ ] Reopening an opened chest always ends run.
|
|
||||||
- [ ] Chest-open state resets at new level.
|
|
||||||
- [ ] Entering exit without key never transitions.
|
|
||||||
- [ ] Entering exit with key always transitions.
|
|
||||||
- [ ] Every generated level is solvable.
|
|
||||||
- [ ] Minimum chest dead-end count is always satisfied.
|
|
||||||
- [ ] Performance remains stable across first several levels.
|
|
||||||
|
|
||||||
## 10. Assets Plan
|
|
||||||
|
|
||||||
Immediate plan (MVP):
|
|
||||||
- Use primitives for wall, floor, chest, and exit zone.
|
|
||||||
- Use simple material colors to distinguish gameplay objects.
|
|
||||||
|
|
||||||
Prepare soon (after core loop works):
|
|
||||||
- Tileable wall texture
|
|
||||||
- Tileable floor texture
|
|
||||||
- Chest texture/material
|
|
||||||
- Basic SFX set:
|
|
||||||
- chest open
|
|
||||||
- wrong chest
|
|
||||||
- key found
|
|
||||||
- level clear
|
|
||||||
- game over
|
|
||||||
|
|
||||||
Optional polish later:
|
|
||||||
- Better chest model
|
|
||||||
- Exit marker model
|
|
||||||
- Ambient loop audio
|
|
||||||
|
|
||||||
## 11. Class Concept Coverage
|
|
||||||
|
|
||||||
This project uses:
|
|
||||||
- JavaScript arrays and object state
|
|
||||||
- Functional decomposition in generation pipeline
|
|
||||||
- Event handling (keyboard/mouse)
|
|
||||||
- External library usage (Babylon.js)
|
|
||||||
- Real-time tracking (elapsed time HUD)
|
|
||||||
|
|
||||||
## 12. Scope Guardrails
|
|
||||||
|
|
||||||
To keep delivery reliable:
|
|
||||||
- Prioritize clean gameplay loop over art polish.
|
|
||||||
- Keep lighting simple and fixed.
|
|
||||||
- Do not add non-essential mechanics before MVP checklist is complete.
|
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
- **Student ID:** 20240905
|
- **Student ID:** 20240905
|
||||||
- **Student Email:** bumgyu@kaist.ac.kr
|
- **Student Email:** bumgyu@kaist.ac.kr
|
||||||
- **Repository URL:** https://git.prototyping.id/20240905/Untitled-Maze-Game
|
- **Repository URL:** https://git.prototyping.id/20240905/Untitled-Maze-Game
|
||||||
- **Video Demonstration:** [YouTube Link]
|
- **Video Demonstration:** https://youtu.be/8LDcLpsNJck (turn on youtube subtitles)
|
||||||
|
- **Play Link:** https://pobadoba.com/games/maze
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ Jumpscare)
|
|||||||
|
|
||||||
### How to Play
|
### How to Play
|
||||||
|
|
||||||
|
0. **Project Setup:** Run the commands: `npm install`, then `npm run dev` in the project repository top folder; alternatively, access the game in [this website](https://pobadoba.com/games/maze)
|
||||||
1. **Start the Game:** Press **R** on the start screen to begin
|
1. **Start the Game:** Press **R** on the start screen to begin
|
||||||
2. **Navigate:** Use **WASD** to move, mouse to look around
|
2. **Navigate:** Use **WASD** to move, mouse to look around
|
||||||
3. **Find the Key:** **Left-Click** chests until you find the key, do not click on a chest you have opened before (leads to game over)
|
3. **Find the Key:** **Left-Click** chests until you find the key, do not click on a chest you have opened before (leads to game over)
|
||||||
@@ -512,4 +514,4 @@ babylon_panel.js (orchestrator) ← high-level control
|
|||||||
|
|
||||||
## Conclusion
|
## Conclusion
|
||||||
|
|
||||||
**Untitled Maze Game** was an interesting project as it made me realize that a lot is possible simply through javascript libraries and today's LLMs. AI really saved a lot of time that would have normally taken me hours to debug, and having dialogue with the AI over the code structure and such was quite helpful and interesting.
|
**Untitled Maze Game** was an interesting project as it made me realize that a lot is possible simply through javascript libraries and today's LLMs. AI really saved a lot of time that would have normally taken me hours to debug, and having dialogue with the AI over the code structure and such was quite helpful and interesting. I think the advantage of AI is I can spend a lot more time on thinking about the big-picture structure of the code rather than the little details and line-by-line code, which is more fun.
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
<div class="status-line"><strong>Time left:</strong> <span id="status-time">60.0</span></div>
|
<div class="status-line"><strong>Time left:</strong> <span id="status-time">60.0</span></div>
|
||||||
<div class="status-line"><strong>Key:</strong> <span id="status-key">no</span></div>
|
<div class="status-line"><strong>Key:</strong> <span id="status-key">no</span></div>
|
||||||
<div class="status-line"><strong>Rounds:</strong> <span id="status-rounds">0</span></div>
|
<div class="status-line"><strong>Rounds:</strong> <span id="status-rounds">0</span></div>
|
||||||
|
<div id="status-message" class="status-line-message"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
const initialSeed = Math.floor(Math.random() * 100000);
|
||||||
|
|
||||||
export const sharedState = (window.mazeGameState ??= {
|
export const sharedState = (window.mazeGameState ??= {
|
||||||
config: {
|
config: {
|
||||||
seed: Math.floor(Math.random() * 100000),
|
seed: initialSeed,
|
||||||
level: 1,
|
level: 1,
|
||||||
mazeWidth: 11,
|
mazeWidth: 11,
|
||||||
mazeHeight: 11,
|
mazeHeight: 11,
|
||||||
@@ -14,3 +16,6 @@ export const sharedState = (window.mazeGameState ??= {
|
|||||||
message: "Press Start to play.",
|
message: "Press Start to play.",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Debug logging
|
||||||
|
console.log("State initialized with seed:", sharedState.config.seed, "Initial seed value:", initialSeed);
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ function updateDisplay() {
|
|||||||
const statusMessage = document.getElementById("status-message");
|
const statusMessage = document.getElementById("status-message");
|
||||||
|
|
||||||
if (!statusSeed || !statusLevel || !statusMazeSize || !statusChests || !statusTime || !statusKey || !statusRounds || !statusMessage) {
|
if (!statusSeed || !statusLevel || !statusMazeSize || !statusChests || !statusTime || !statusKey || !statusRounds || !statusMessage) {
|
||||||
console.warn("Some status display elements are missing from DOM");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user