diff options
| author | Alex Pickering <alex@cogarr.net> | 2026-02-01 13:14:32 -0600 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2026-02-01 13:14:32 -0600 |
| commit | 3a975db66a3711f34e8b64bb27a8eaca79fdeca9 (patch) | |
| tree | fcc12f8f9d638ff575c1963796de76b7628854b4 /context.md | |
| download | ggj26-3a975db66a3711f34e8b64bb27a8eaca79fdeca9.tar.gz ggj26-3a975db66a3711f34e8b64bb27a8eaca79fdeca9.tar.bz2 ggj26-3a975db66a3711f34e8b64bb27a8eaca79fdeca9.zip | |
Diffstat (limited to 'context.md')
| -rw-r--r-- | context.md | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/context.md b/context.md new file mode 100644 index 0000000..cb0ee87 --- /dev/null +++ b/context.md @@ -0,0 +1,100 @@ +# Project Context + +## Project Type +Game project (likely a game jam entry - ggj26). Features top-down twin-stick shooter gameplay. + +## Asset Generation +Uses ImageMagick scripts (`.imagemagick` files) in `assets_src/` to procedurally generate game assets. + +### ImageMagick Script Conventions +- Start with `#!/usr/bin/env magick-script` +- Standard canvas: `512x512` +- Consistent styling: 8px border with `rgb(58,58,58)`, slight blur (`0x0.3-0.5`) +- Output to PNG via `-write png:-` +- Color palette: grayscale tones (40-80 RGB range) + +### Existing Assets +- `floor.imagemagick`: Checkerboard pattern floor tile +- `wall.imagemagick`: Gray wall tile with horizontal stripe +- `player.imagemagick`: Top-down player sprite (circle body, shoulder pads, gun pointing east) +- Pre-made button sprites: 18 PNG files for UI buttons (up/down states, 3x3 grid variations) + +## Drawing Approach +ImageMagick uses `-draw` commands for shapes. Player sprite demonstrates layering: +- Base circle for body +- Rounded rectangles for shoulder pads +- Rectangles for gun barrel extending horizontally + +## Shaders (`src/shaders/`) +The game uses custom GLSL shaders with MoonScript/Lua setup code, built on the Amulet game engine. + +### Rendering Architecture +- **Pseudo-3D perspective**: Uses Z-coordinate scaling to create depth without true 3D projection +- **Buffered rendering**: Pre-allocated vertex buffers for performance (world.moon sets MAX_PLAYERS=8, MAX_LEVEL_TRIS=1024) +- **World-space rendering**: All shaders receive `world_x` and `world_y` uniforms for camera positioning +- **Multi-lamp lighting**: Up to 8 dynamic lamps per shader with distance-based illumination + +### Color Palette System +All lit shaders use a consistent 7-color palette for quantized lighting: +- `black` (darkest) +- `outline` +- `shadow` +- `background` +- `midground` +- `foreground` +- `highlight` (brightest) + +Colors are selected based on calculated light intensity thresholds (>1.0, >0.8, >0.6, >0.4, >0.2, else black). + +### Individual Shaders + +#### Lake Shader (`lake.frag`, `lake.vert`, `lake.moon`) +- Water surface rendering with dynamic lighting +- Distance-based lamp illumination (up to 8 lamps: `lamp1` through `lamp8`) +- Noise/random functions for visual texture +- `streamer` uniform: toggles noise off for cleaner rendering +- Normal map support via `atlas` texture and `norm` varying +- Simple vertex shader (no rotation or Z-effects) + +#### Land Shader (`land.frag`, `land.vert`) +- Ground/terrain rendering, nearly identical to lake shader +- Additional `water` uniform: enables simplex noise animation when > 1 +- Vertex shader includes rotation matrix (`rot` uniform) +- Z-scaling for pseudo-3D perspective (clamped ±0.5) +- Normal mapping support + +#### Player Shader (`player.frag`, `player.vert`) +- Character rendering (currently shows UV debug visualization) +- Supports texture mapping with `textures`, `emissives`, `normals` samplers +- Directional rotation via `dir` uniform +- Fixed Z-depth at -2 to position above world +- Lamp support declared but not used in fragment shader + +#### Stars Shader (`stars.frag`, `stars.vert`, `stars.lua`) +- Starfield background using point sprites +- Procedurally generates ~500 stars in Lua setup +- Stars arranged in 3×3 tiling pattern for infinite scrolling +- Animated blinking: `gl_PointSize = pow(intensity, 2.) * stars.z * 0.3` where intensity = `sin(stars.z + time) * cos(time) + 1` +- Stars avoid circular region in center (radius 0.5) for game area +- Wrapping via `world_x_period` and `world_y_period` +- Z-position: -0.1 (behind everything) + +#### World Shader (`world.frag`, `world.vert`, `world.moon`) +- Main 3D geometry renderer for levels +- Texture-mapped rendering (currently uses floor texture) +- Pseudo-3D via Z-based offset: `xoff = clamp(world.z * vxy.x * z_scale, -32., 32.)` +- Geometry generation in MoonScript: + - `up_down_hall`: Creates hallway segments with floor and walls + - `barrel`: Generates cylindrical objects with triangulated sides + - `room`: Room generation (partially implemented) +- Buffered architecture allows dynamic level geometry +- Uses depth testing (`less`) and front-face culling +- Support for round objects via radius attribute (unused currently) + +### Technical Details +- **Noise functions**: Simplex noise from Shadertoy (https://www.shadertoy.com/view/Msf3WH) +- **Random function**: Hash-based PRNG by @patriciogv (2015) +- **Lamp format**: `vec4(x, y, z, strength)` in normalized coordinates, scaled by 256 in shaders +- **Coordinate system**: World space, with fragment coord offset by `worldxy * 256` +- **View matrices**: Custom MV/P matrices in MoonScript, not standard OpenGL projection +- **Engine**: Amulet (`am.*` functions), uses scene graph with `append`, `bind`, `draw` nodes |
