# ujjwalvivek/baremetal architecture

> Architecture diagram of the GitHub repository ujjwalvivek/baremetal, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ujjwalvivek/baremetal
- Repository: https://github.com/ujjwalvivek/baremetal

## Overview

1. **Overall shape**
   - This repo is a single static Linux/x86-64 executable written entirely in Intel-syntax assembly.
   - There is no libc, no dynamic allocation, and no graphics API. The whole application is organized into four runtime subsystems: core game control, terminal/platform I/O, math helpers, and text-mode rendering.

2. **Process entry and top-level control**
   - Execution begins at `_start` in `src/core/entry.asm`.
   - That module owns bootstrapping, the fixed 60 FPS frame loop, frame timing, and shutdown.
   - It coordinates the other subsystems in a strict order: terminal setup → input/render/game initialization → start screen → main loop → restore terminal on exit.

3. **Platform boundary: terminal control**
   - `src/platform/terminal.asm` is responsible for all terminal state transitions.
   - It switches the TTY into raw mode, enters the alternate screen, hides the cursor, clears the display once, and restores everything on exit.
   - It also handles terminal resize discovery via `TIOCGWINSZ` and signal-driven cleanup/resize behavior.

4. **Platform boundary: input**
   - `src/platform/input.asm` drains keyboard input every frame using nonblocking polling and byte reads.
   - It converts raw key bytes into gameplay flags for movement, turn, shoot, use-door, and quit.
   - This layer is intentionally small and stateless: the game loop resets and re-derives input state each frame rather than maintaining an input history.

5. **Platform boundary: timing**
   - `src/platform/timing.asm` abstracts monotonic frame timing and sleep.
   - The main loop uses it to enforce the fixed timestep and to keep rendering and simulation synchronized at 60 FPS.
   - Any early wakeup from sleep is tolerated; the loop simply continues on the next frame.

6. **Game state and simulation core**
   - `src/core/game.asm` contains the actual world model and gameplay rules.
   - It stores the 32×32 map, player position/angle/health, door state, enemies, and light sources.
   - This module is the main simulation boundary: input is translated into movement, combat, door toggles, enemy AI, and per-frame world updates here.

7. **World representation and movement**
   - The map is a fixed grid with encoded cell types for open space, several wall materials, and doors.
   - Movement uses collision checks against the grid, with separate X and Y resolution so the player can slide along walls.
   - Doors are not just visual; they are active world cells with mutable state that affects both collision and raycasting.

8. **Raycasting and visibility**
   - The rendering view is driven by a DDA raycaster implemented in `game.asm`.
   - For each screen column, it finds the first wall hit, computes perpendicular distance, returns wall type, and provides side information for shading.
   - This output feeds the renderer as the primary visibility pipeline and also seeds the Z-buffer used by sprites and hitscan combat.

9. **Combat, AI, and lights**
   - Enemies are simulated in the game core as a small state machine with chase, hurt, and dead states.
   - Shooting is hitscan-based: the game uses view-direction math and the render Z-buffer to decide whether an enemy is in front of a wall and within the hit cone.
   - Lighting is also game-state driven: static, pulsing, and muzzle-flash point lights influence wall shading during rendering.

10. **Math support layer**
    - `src/math/math.asm` supplies fixed-point and lookup-table math used throughout the game.
    - It replaces floating-point trig with precomputed sin/cos tables and handles integer-to-ASCII conversion for HUD text.
    - This module is a shared utility boundary, not a simulation layer; it exists to keep core and render code free of libc-style helpers.

11. **Rendering pipeline**
    - `src/render/render.asm` owns the frame buffer and all terminal text generation.
    - Rendering is multi-pass: raycast columns first, then row-major wall/ceiling/floor output, then sprites, then the gun HUD, minimap, and status line.
    - The final output is emitted as one large `write(1, ...)` per frame, which is the only high-volume I/O path in the program.

12. **Rendering data and helpers**
    - `src/render/render_data.asm` holds all visual constants: colors, fonts, sprites, HUD strings, and other static art data.
    - `src/render/render_utils.asm` contains low-level buffer and cursor helpers plus drawing primitives for sprites and terminal positioning.
    - `src/render/render_start.asm` is a separate startup-screen renderer, which keeps the intro/title flow isolated from in-game rendering.

13. **Data flow across subsystems**
    - The central runtime flow is: terminal/input state → game update → render state → terminal write.
    - The game core produces positions, distances, sprites, enemy states, and lighting; the renderer consumes those values to build the terminal frame.
    - The renderer never directly mutates world logic, and the platform layer never interprets game state beyond resize/input/terminal management.

14. **Build and deployment shape**
    - The project is built with `nasm` and linked statically with `ld`, producing a Linux-only binary.
    - The architecture is designed around predictable memory layout: static `.data` and `.bss` storage, no heap, and fixed-size buffers.
    - A GitHub Actions release workflow exists, but the runtime architecture itself is entirely local-process and terminal-bound.

Main entry points: [`src/core/entry.asm`](https://github.com/ujjwalvivek/baremetal/blob/main/src/core/entry.asm) (Entry), [`src/render/render.asm`](https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render.asm) (Renderer), [`src/core/game.asm`](https://github.com/ujjwalvivek/baremetal/blob/main/src/core/game.asm) (Game), [`src/platform/terminal.asm`](https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/terminal.asm) (Terminal)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_core["Core"]
  node_entry["Entry<br/>bootstrap/loop<br/>[entry.asm]"]
  node_game["Game<br/>simulation/state<br/>[game.asm]"]
end

subgraph group_platform["Platform"]
  node_terminal["Terminal<br/>tty lifecycle<br/>[terminal.asm]"]
  node_input["Input<br/>key polling<br/>[input.asm]"]
  node_timing["Timing<br/>frame clock<br/>[timing.asm]"]
end

subgraph group_render["Render"]
  node_render["Renderer<br/>frame builder<br/>[render.asm]"]
  node_render_data["Art Data<br/>static assets<br/>[render_data.asm]"]
  node_render_utils["Draw Utils<br/>buffer helpers<br/>[render_utils.asm]"]
  node_render_start["Start Screen<br/>intro renderer<br/>[render_start.asm]"]
end

subgraph group_math["Math"]
  node_math["Math<br/>fixed-point utils<br/>[math.asm]"]
end

node_entry -->|"setup/restore"| node_terminal
node_entry -->|"init/poll"| node_input
node_entry -->|"pace frames"| node_timing
node_entry -->|"run sim"| node_game
node_entry -->|"show intro"| node_render_start
node_entry -->|"frame output"| node_render
node_input -->|"controls"| node_game
node_game -->|"state feed"| node_render
node_game -->|"trig/format"| node_math
node_render -->|"primitives"| node_render_utils
node_render -->|"assets"| node_render_data
node_render -->|"formatting"| node_math
node_render -->|"write tty"| node_terminal
node_terminal -.->|"resize/cleanup"| node_entry

click node_entry "https://github.com/ujjwalvivek/baremetal/blob/main/src/core/entry.asm"
click node_game "https://github.com/ujjwalvivek/baremetal/blob/main/src/core/game.asm"
click node_terminal "https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/terminal.asm"
click node_input "https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/input.asm"
click node_timing "https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/timing.asm"
click node_math "https://github.com/ujjwalvivek/baremetal/blob/main/src/math/math.asm"
click node_render "https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render.asm"
click node_render_data "https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render_data.asm"
click node_render_utils "https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render_utils.asm"
click node_render_start "https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render_start.asm"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_game toneBlue
class node_terminal,node_input,node_timing toneAmber
class node_render,node_render_data,node_render_utils,node_render_start toneMint
class node_math toneRose
```

## Components

### Core

Process entry, loop control, and game state

- [Entry](https://github.com/ujjwalvivek/baremetal/blob/main/src/core/entry.asm): bootstrap/loop · Process start, setup, frame pacing, and shutdown · `src/core/entry.asm`
- [Game](https://github.com/ujjwalvivek/baremetal/blob/main/src/core/game.asm): simulation/state · World model, movement, combat, AI, doors, and lights · `src/core/game.asm`

### Platform

Terminal, input, and timing boundaries

- [Terminal](https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/terminal.asm): tty lifecycle · Raw mode, alternate screen, cursor, resize, restore · `src/platform/terminal.asm`
- [Input](https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/input.asm): key polling · Nonblocking keyboard reads mapped to gameplay flags · `src/platform/input.asm`
- [Timing](https://github.com/ujjwalvivek/baremetal/blob/main/src/platform/timing.asm): frame clock · Monotonic timing and sleep for fixed-step frames · `src/platform/timing.asm`

### Render

Frame assembly and terminal text output

- [Renderer](https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render.asm): frame builder · Builds wall, sprite, HUD, and status output · `src/render/render.asm`
- [Art Data](https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render_data.asm): static assets · Colors, sprites, fonts, HUD text, and constants · `src/render/render_data.asm`
- [Draw Utils](https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render_utils.asm): buffer helpers · Buffer, cursor, and primitive drawing helpers · `src/render/render_utils.asm`
- [Start Screen](https://github.com/ujjwalvivek/baremetal/blob/main/src/render/render_start.asm): intro renderer · Title and startup-screen drawing flow · `src/render/render_start.asm`

### Math

Shared fixed-point and lookup-table helpers

- [Math](https://github.com/ujjwalvivek/baremetal/blob/main/src/math/math.asm): fixed-point utils · Trig tables and integer formatting helpers · `src/math/math.asm`

## Connections

- Entry → Terminal: setup/restore · Owns terminal lifecycle around execution
- Entry → Input: init/poll · Initializes and refreshes input state each frame
- Entry → Timing: pace frames · Uses monotonic timing and sleep to hold 60 FPS
- Entry → Game: run sim · Coordinates initialization and per-frame game updates
- Entry → Start Screen: show intro · Runs the startup screen before the main loop
- Entry → Renderer: frame output · Drives per-frame rendering and terminal writes
- Input → Game: controls · Converts key bytes into movement and action flags
- Game → Renderer: state feed · Provides positions, visibility, enemies, and lights
- Game → Math: trig/format · Uses lookup tables and numeric formatting helpers
- Renderer → Draw Utils: primitives · Uses low-level buffer and drawing helpers
- Renderer → Art Data: assets · Consumes static art, HUD, and color data
- Renderer → Math: formatting · Uses shared helpers for numeric and HUD text output
- Renderer → Terminal: write tty · Emits the completed frame to the terminal
- Terminal → Entry: resize/cleanup · Feeds terminal state changes back to startup and exit flow
