Home · Architecture · Combat · Extensions · Known gaps · Source index
Rendering and UI
Macroquad application shell
Live. The program is a single Macroquad async loop with a fixed, non-resizable 900 × 900 window titled “Tower Defense.” The frame sequence is:
step simulation
draw simulation
draw/handle crate overlay if open
apply returned UI action
Q check
next_frame
Simulation dt is clamped to 0.05 seconds. get_time() is passed to the crate function but ignored. Pressing Q exits the process with status 1.
Risk. The screen state does not gate step_world. Gameplay continues while the crate overlay is open.
Sources: src/main.rs, src/systems.rs.
Simulation drawing
Live. draw_simulation clears the frame to a dark background and draws in this order:
| Order | Element | Implementation |
|---|---|---|
| 1 | Arena | Gray rectangle outline at (50,50), size 800×800 |
| 2 | Four spawn markers | Radius-8 outlines at side midpoints |
| 3 | Tower | Blue radius-16 circle and sky-blue direction barrel |
| 4 | Enemies | Calls each enemy's stored draw function |
| 5 | Projectiles | Yellow radius-5 circles |
| 6 | Animations | Calls animation draw function |
| 7 | Metrics | FPS, Hit DPS, DoT DPS, Total DPS |
Blob rendering is function-pointer based. It draws a radius-10 circle whose color darkens with remaining HP. Projectile drawing uses the global PROJ_RADIUS constant rather than each projectile's stored radius, although current projectiles also use 5.
Partial. There are no sprites, textures, camera, scaling, health bars, wave/level/XP display, pool rendering, status rendering, hit flashes, or tower/loadout display.
Sources: src/systems.rs, src/enemies/blob.rs, src/world.rs.
Death animation
Live. EnemyKilled handling queues an EnemeyDeathAnimation at the corpse position with duration 2.5 seconds. The animation system increments elapsed time, marks entries whose remaining duration is non-positive, calls animate, and then removes marked IDs. The normal draw pass calls animate again for retained entries.
The animation is a radius-10 circle whose red channel fades according to:
normalized = (duration - elapsed) / duration
color = (normalized, 0.47, 0.95, 1.0)
Risk. animation_system performs drawing during the update phase, but draw_simulation clears the background afterward. That first draw is normally erased; retained animations are drawn a second time in the correct draw phase.
Risk. Duplicate EnemyKilled events create overlapping duplicate animations. The misspelled enum variant EnemeyDeathAnimation is the sole animation kind.
Sources: src/animations.rs, src/systems.rs, src/world.rs.
Weapon crate overlay
Live. The crate uses three centered 200 × 260 cards with 24-pixel gaps. The selected card has a blue background and yellow border; unselected cards use a near-black background and gray border. Each card displays only its registry display name.
200 px 200 px 200 px
+-----------+ +-----------+ +-----------+
| weapon | | weapon | | weapon |
| name | | name | | name |
| | | | | |
+-----------+ +-----------+ +-----------+
24 px gap 24 px gap
| Key | Action |
|---|---|
| Left | Move selection left, bounded at 0 |
| Right | Move selection right, bounded at 2 |
| Enter | Return PickWeaponCrate(selected WeaponID) |
| Space | Return ClosePanel |
No mouse or touch input is implemented. There is no heading, tier/current-level comparison, description, stat preview, reroll control, or pending-picks count. Duplicate offers can appear because sampling is with replacement.
The overlay is drawn after simulation and before the UI action is applied. Picking upgrades/adds the weapon and dismisses one level credit. Closing preserves the credit and marks the player as manually closed; Space during normal play can reopen it.
Sources: src/systems.rs, src/world.rs, src/main.rs.
DPS HUD
Live. Three gray, 18-pixel lines appear at the top-left:
FPS: N
Hit DPS: x.x
DoT DPS: x.x
Total DPS: x.x
DPS values are tower-attributed resolved damage divided by a fixed three-second span. Samples age out only when a new sample is recorded, so the HUD can retain stale nonzero values after combat stops. See TowersWeaponsProgression.
UI and state behavior
| State/path | Status | Actual behavior |
|---|---|---|
Screen::Playing |
Live | Simulation and base drawing |
Screen::WeaponCrate |
Live | Same simulation plus crate overlay |
| Pause while panel open | Unwired | Comments mention it; main loop does not implement it |
| Manual reopen | Live | Space calls open_weapon_crate, which requires a pending pick |
| Exit | Live | Q exits with code 1 |
| Mouse controls | Unwired | Keyboard only |
| Other screens | Unwired | No title, pause, game-over, settings, or results state |
Coordinate mismatch visible in rendering
Risk. The drawn arena is offset by (50,50), while wall collision and the grid use 0..800. The tower and movement target are at drawn center (450,450), but the wave spawn is (0,400) rather than the visible left marker (50,450). See SpatialGeometryRng.
Dormant rendering code
Unwired. draw_weapon_crate in animations.rs draws a small green rectangle near the center but is never called; the live crate renderer is in systems.rs. animations.rs also imports unused RED and draw_text.
The crate UI arguments _t and _dt are intentionally unused. PlayerStatus is imported but unused in main.rs.
Sources: src/animations.rs, src/main.rs, src/systems.rs.
Home · Architecture · Combat · Extensions · Known gaps · Source index