Enhancements to breadcrumb trail
This commit is contained in:
27
AGENTS.md
27
AGENTS.md
@@ -1,7 +1,7 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
Core gameplay lives in root-level C++ translation units: `ghostland.cpp` orchestrates the loop, `player.cpp`, `ghost.cpp`, `collisions.cpp`, `shader.cpp`, `text.cpp`, and `config.cpp` own their respective systems. Runtime assets stay alongside code: GLSL shaders (`*shader.glsl`), UI textures (PNG in the repo root), and bitmap fonts under `fonts/`. Level data is serialized in `maze.txt`, typically regenerated via `mazeparser.py` from `maze.png`. Adjustable settings belong in `ghostland.json`; document experimental JSON entries before relying on them in code to avoid null lookups.
|
||||
Core gameplay lives in root-level C++ translation units: `ghostland.cpp` orchestrates the loop, `player.cpp`, `ghost.cpp`, `collisions.cpp`, `shader.cpp`, `text.cpp`, and `config.cpp` own their respective systems. Runtime assets stay alongside code: GLSL shaders (`*shader.glsl`), UI textures (PNG in the repo root), and bitmap fonts under `fonts/`. Level data is serialized in `maze.txt`, typically regenerated via `mazeparser.py` from `maze.png`. Adjustable settings belong in `ghostland.json`; keep defaults mirrored in code so omitted keys never cause null or invalid lookups.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
- `make` – builds all objects with C++17 + O3 and links the `ghostland` binary with GLFW, GLAD, stb_image, and Freetype.
|
||||
@@ -12,6 +12,15 @@ Core gameplay lives in root-level C++ translation units: `ghostland.cpp` orchest
|
||||
## Coding Style & Naming Conventions
|
||||
Use 4-space indentation, braces on the same line as control statements, and guard new modules with include guards. Keep standard-library/GLM includes before project headers as in `ghostland.cpp`. Classes use PascalCase (`Player`), local variables use `snake_case`, compile-time constants stay uppercase. Prefer STL containers over manual arrays unless performance-critical, and keep shader uniform names centralized near the top of `ghostland.cpp`.
|
||||
|
||||
## Configuration Guidelines
|
||||
`ghostland.json` is intentionally a flat runtime tuning file. The parser in `config.cpp` is a minimal line-oriented JSON subset reader: it expects one `"key": value` pair per line, ignores braces and comment-like lines, strips one trailing comma, and stores raw strings in a process-wide map. Do not rely on nested objects, arrays, inline comments after values, duplicate-key semantics beyond "last loaded wins", or full JSON validation unless you first replace the parser deliberately.
|
||||
|
||||
Load config values once during startup after `Config::loadFromFile("ghostland.json")`, then copy them into typed globals or small config structs. Always use `Config::getFloat`, `Config::getInt`, or `Config::getString` with a meaningful in-code default; missing or malformed values should keep the game playable. Keep booleans as `0` / `1` integer keys for consistency with existing options.
|
||||
|
||||
When adding or renaming a setting, update all three surfaces together: the struct or default value in code, the sample value in `ghostland.json`, and the README configuration table/example. Prefer descriptive key names grouped by system prefix (`minimap_*`, `trail_*`, `ghost_*`). If compatibility matters, read the legacy key first and let the new key override it, as with `trail_y_offset` falling back to `trail_y_position`.
|
||||
|
||||
Validate numeric config values at the use site when bad ranges can break rendering or gameplay. Clamp or guard zero/negative values where appropriate (`std::max` for lifetimes, spacing, sizes, and shader divisors), and keep color channels documented as 0-1 floats. Avoid adding config knobs for internal implementation details unless they are useful for tuning gameplay, visuals, or reproduction.
|
||||
|
||||
## Testing Guidelines
|
||||
There is no automated framework yet, so rely on focused manual passes. Before opening a PR, build fresh (`make clean && make`), run `./ghostland`, and verify spawn position, collision bounds, ghost ordering, and text rendering. When touching geometry, regenerate `maze.txt` and inspect extremes logged at the bottom of the file. Mention any GPU or driver quirks encountered so others can reproduce.
|
||||
|
||||
@@ -20,6 +29,16 @@ Existing history favors short, descriptive subjects ("Player's position is reset
|
||||
|
||||
## Minimap Implementation Plan
|
||||
- Add minimap config keys in `ghostland.json` (enable flag, width/height, margin, colors). After loading `maze.txt`, cache 2D wall segments plus world bounds for quick reuse.
|
||||
- Create a lightweight 2D orthographic shader/VAO for overlay drawing; use GL_LINES for walls, triangle-fan circles for breadcrumbs/ghosts, and a small triangle for the player arrow. Disable depth test while rendering the overlay near the end of the frame.
|
||||
- Each frame convert wall endpoints and breadcrumb/ghost positions relative to the player’s X/Z so the minimap scrolls with the player centered. Clip or skip segments outside the visible minimap extents.
|
||||
- Draw order: white background quad, wall lines, breadcrumb dots, ghost dots (border then fill), red arrow rotated by player yaw. Re-enable depth test and continue with HUD text.
|
||||
- Create a lightweight 2D orthographic shader/VAO for overlay drawing; use GL_LINES for walls, triangle quads for the trail stroke, triangle-fan circles for ghosts, and a small triangle for the player arrow. Disable depth test while rendering the overlay near the end of the frame.
|
||||
- Each frame convert wall endpoints, trail points, and ghost positions relative to the player’s X/Z so the minimap scrolls with the player centered. Clip or skip segments outside the visible minimap extents.
|
||||
- Draw order: white background quad, wall lines, trail stroke, ghost dots (border then fill), red arrow rotated by player yaw. Re-enable depth test and continue with HUD text.
|
||||
|
||||
## Trail Implementation Overview
|
||||
The old breadcrumb arrows have been replaced by a continuous time-limited trail rendered as a flat ribbon mesh in world space. `ghostland.cpp` owns the trail data structures: `TrailPoint` stores sampled X/Z player positions, timestamps, and a `starts_segment` flag that prevents respawns from drawing teleport lines. `TrailVertex` stores generated ribbon vertices plus the source timestamp. `update_trail()` prunes samples older than `trail_lifetime_minutes`, adds a new sample only after the player moves at least `trail_sample_spacing`, and removes nearly straight intermediate samples using `trail_simplify_epsilon`.
|
||||
|
||||
`rebuild_trail_mesh()` turns adjacent trail samples into quad segments made from two triangles, avoiding driver-dependent OpenGL line width behavior. The VBO is updated only when samples are added, pruned, simplified, or a reset splits the trail. `trailshader.glsl` passes each vertex timestamp to `trailfragshader.glsl`, which blends from `trail_recent_*` color values toward `trail_old_*` based on age. Keep the shader GLSL version aligned with the requested OpenGL 3.3 context.
|
||||
|
||||
Trail tuning belongs in `ghostland.json`: `trail_enabled`, `trail_lifetime_minutes`, `trail_sample_spacing`, `trail_width`, `trail_y_position`, `trail_simplify_epsilon`, `trail_reset_marker_size`, and RGB triplets for recent/old colors. The legacy `trail_y_offset` key is still accepted as a fallback. The minimap consumes the same trail point deque and renders a screen-space stroke whose half-width is controlled by `minimap_breadcrumb_radius`, so changes to sampling behavior affect both the world ribbon and overlay path.
|
||||
|
||||
## Danger Tint Notes
|
||||
The red danger tint is driven by the nearest ghost in X/Z space rather than 3D distance, so ghost bobbing does not change the warning. Keep the tint calculation independent of ghost render ordering: the partial sort is only for drawing. The tint also keeps persistent intensity with a 30-unit enter / 35-unit exit hysteresis band and frame-rate-independent smoothing; this prevents threshold jitter from flashing the camera between normal and red.
|
||||
|
||||
Reference in New Issue
Block a user