# limenqi/formula-2d architecture

> Architecture diagram of the GitHub repository limenqi/formula-2d, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/limenqi/formula-2d
- Repository: https://github.com/limenqi/formula-2d

## Overview

Formula 2D is a multiplayer 2D racing game with client-side driving, an authoritative UDP server, FPGA-backed physics and HDMI rendering, and AWS leaderboard support. Clients register, send timed player updates, and receive server snapshots; the server manages the race, updates hardware state, and submits results. The graph preserves the documented hardware, networking, leaderboard, and software-render comparison capabilities. Some source was not excerpted, so edges for those relationships rely on the README or indexed references; optional hardware links are marked unverified.

Main entry points: [`server_side/server/game_loop.py`](https://github.com/limenqi/formula-2d/blob/main/server_side/server/game_loop.py) (Race loop), [`client_side/client/game_loop.py`](https://github.com/limenqi/formula-2d/blob/main/client_side/client/game_loop.py) (Client game loop), [`client_side/client/main.py`](https://github.com/limenqi/formula-2d/blob/main/client_side/client/main.py) (Client entry), [`server_side/server/menu_loop.py`](https://github.com/limenqi/formula-2d/blob/main/server_side/server/menu_loop.py) (Lobby and setup)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client gameplay"]
  node_client_entry["Client entry<br/>[main.py]"]
  node_client_menu["Client registration<br/>[menu_loop.py]"]
  node_client_loop["Client game loop<br/>[game_loop.py]"]
  node_client_physics["Client physics<br/>[physics.py]"]
  node_client_state["Player state<br/>[models.py]"]
  node_client_config["Client config<br/>[config.py]"]
  node_client_protocol["Packet protocol<br/>[protocol.py]"]
  node_client_udp["Client UDP<br/>[udp.py]"]
end

subgraph group_server["Authoritative server"]
  node_server_entry["Server entry<br/>[main.py]"]
  node_server_menu["Lobby and setup<br/>[menu_loop.py]"]
  node_server_loop["Race loop<br/>[game_loop.py]"]
  node_server_engine["Authoritative state<br/>[engine.py]"]
  node_server_config["Server config<br/>[config.py]"]
  node_server_protocol["Packet protocol<br/>[protocol.py]"]
  node_server_udp["Server UDP<br/>[udp.py]"]
  node_race_results["Race results<br/>[game_ending.py]"]
end

subgraph group_hardware["FPGA hardware"]
  node_server_hw["Hardware interface<br/>[hw_interface.py]"]
  node_physics_ip["Physics AXI IP<br/>[physics_top.v]"]
  node_renderer_ip["HDMI renderer"]
end

subgraph group_services["Services and rendering"]
  node_aws(("AWS leaderboard"))
  node_aws_client["AWS calls<br/>[aws_functions.py]"]
  node_software_render["Software map renderer<br/>[map_renderer.py]"]
end

node_player(("Player"))
node_pynq(("PYNQ board"))

node_player -->|"starts"| node_client_entry
node_client_entry -->|"runs"| node_client_menu
node_client_entry -->|"runs"| node_client_loop
node_client_entry -->|"initializes"| node_client_physics
node_client_menu -->|"creates socket"| node_client_udp
node_client_menu -->|"encodes registration"| node_client_protocol
node_client_loop -->|"steps motion"| node_client_physics
node_client_loop -->|"encodes updates"| node_client_protocol
node_client_loop -->|"decodes snapshots"| node_client_protocol
node_client_loop -.->|"sends and receives"| node_client_udp
node_client_physics -->|"updates"| node_client_state
node_client_protocol -->|"serializes"| node_client_state
node_server_entry -->|"runs"| node_server_menu
node_server_entry -->|"runs"| node_server_loop
node_server_entry -->|"submits results"| node_race_results
node_server_menu -->|"opens socket"| node_server_udp
node_server_menu -->|"hands off game"| node_server_loop
node_server_menu -->|"uses services"| node_aws_client
node_server_loop -->|"decodes updates"| node_server_protocol
node_server_loop -->|"encodes snapshots"| node_server_protocol
node_server_loop -->|"applies updates"| node_server_engine
node_server_loop -->|"writes race state"| node_server_hw
node_server_loop -.->|"sends snapshots"| node_server_udp
node_race_results -->|"requests leaderboard"| node_aws_client
node_aws_client -->|"calls API"| node_aws
node_server_hw -.->|"controls"| node_physics_ip
node_server_hw -.->|"writes render state"| node_renderer_ip
node_pynq -->|"hosts"| node_server_hw
node_pynq -->|"outputs HDMI"| node_renderer_ip
node_software_render -->|"draws players"| node_client_state

click node_client_entry "https://github.com/limenqi/formula-2d/blob/main/client_side/client/main.py"
click node_client_menu "https://github.com/limenqi/formula-2d/blob/main/client_side/client/menu_loop.py"
click node_client_loop "https://github.com/limenqi/formula-2d/blob/main/client_side/client/game_loop.py"
click node_client_physics "https://github.com/limenqi/formula-2d/blob/main/client_side/game/physics.py"
click node_client_state "https://github.com/limenqi/formula-2d/blob/main/client_side/game/models.py"
click node_client_config "https://github.com/limenqi/formula-2d/blob/main/client_side/game/config.py"
click node_client_protocol "https://github.com/limenqi/formula-2d/blob/main/client_side/net/protocol.py"
click node_client_udp "https://github.com/limenqi/formula-2d/blob/main/client_side/net/udp.py"
click node_server_entry "https://github.com/limenqi/formula-2d/blob/main/server_side/server/main.py"
click node_server_menu "https://github.com/limenqi/formula-2d/blob/main/server_side/server/menu_loop.py"
click node_server_loop "https://github.com/limenqi/formula-2d/blob/main/server_side/server/game_loop.py"
click node_server_engine "https://github.com/limenqi/formula-2d/blob/main/server_side/game/engine.py"
click node_server_config "https://github.com/limenqi/formula-2d/blob/main/server_side/game/config.py"
click node_server_protocol "https://github.com/limenqi/formula-2d/blob/main/server_side/net/protocol.py"
click node_server_udp "https://github.com/limenqi/formula-2d/blob/main/server_side/net/udp.py"
click node_race_results "https://github.com/limenqi/formula-2d/blob/main/server_side/server/game_ending.py"
click node_server_hw "https://github.com/limenqi/formula-2d/blob/main/server_side/game/hw_interface.py"
click node_physics_ip "https://github.com/limenqi/formula-2d/blob/main/vivado/ip_repo/physics_axi_ip/physics_axi_ip_1.0/src/physics_top.v"
click node_renderer_ip "https://github.com/limenqi/formula-2d/blob/main/vivado/racing_axi/racing_axi.srcs/sources_1/imports/filles_axi/racing_renderer_axi.v"
click node_aws_client "https://github.com/limenqi/formula-2d/blob/main/server_side/server/aws_functions.py"
click node_software_render "https://github.com/limenqi/formula-2d/blob/main/server_side/software_render/map_renderer.py"

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_client_entry,node_client_menu,node_client_loop,node_client_physics,node_client_state,node_client_config,node_client_protocol,node_client_udp toneBlue
class node_server_entry,node_server_menu,node_server_loop,node_server_engine,node_server_config,node_server_protocol,node_server_udp,node_race_results toneAmber
class node_server_hw,node_physics_ip,node_renderer_ip toneMint
class node_aws,node_aws_client,node_software_render toneRose
class node_player,node_pynq toneIndigo
```

## Components

### Client gameplay

- [Client entry](https://github.com/limenqi/formula-2d/blob/main/client_side/client/main.py): `client_side/client/main.py`
- [Client registration](https://github.com/limenqi/formula-2d/blob/main/client_side/client/menu_loop.py): `client_side/client/menu_loop.py`
- [Client game loop](https://github.com/limenqi/formula-2d/blob/main/client_side/client/game_loop.py): `client_side/client/game_loop.py`
- [Client physics](https://github.com/limenqi/formula-2d/blob/main/client_side/game/physics.py): `client_side/game/physics.py`
- [Player state](https://github.com/limenqi/formula-2d/blob/main/client_side/game/models.py): `client_side/game/models.py`
- [Client config](https://github.com/limenqi/formula-2d/blob/main/client_side/game/config.py): `client_side/game/config.py`
- [Packet protocol](https://github.com/limenqi/formula-2d/blob/main/client_side/net/protocol.py): `client_side/net/protocol.py`
- [Client UDP](https://github.com/limenqi/formula-2d/blob/main/client_side/net/udp.py): `client_side/net/udp.py`

### Authoritative server

- [Server entry](https://github.com/limenqi/formula-2d/blob/main/server_side/server/main.py): `server_side/server/main.py`
- [Lobby and setup](https://github.com/limenqi/formula-2d/blob/main/server_side/server/menu_loop.py): `server_side/server/menu_loop.py`
- [Race loop](https://github.com/limenqi/formula-2d/blob/main/server_side/server/game_loop.py): `server_side/server/game_loop.py`
- [Authoritative state](https://github.com/limenqi/formula-2d/blob/main/server_side/game/engine.py): `server_side/game/engine.py`
- [Server config](https://github.com/limenqi/formula-2d/blob/main/server_side/game/config.py): `server_side/game/config.py`
- [Packet protocol](https://github.com/limenqi/formula-2d/blob/main/server_side/net/protocol.py): `server_side/net/protocol.py`
- [Server UDP](https://github.com/limenqi/formula-2d/blob/main/server_side/net/udp.py): `server_side/net/udp.py`
- [Race results](https://github.com/limenqi/formula-2d/blob/main/server_side/server/game_ending.py): `server_side/server/game_ending.py`

### FPGA hardware

- [Hardware interface](https://github.com/limenqi/formula-2d/blob/main/server_side/game/hw_interface.py): `server_side/game/hw_interface.py`
- [Physics AXI IP](https://github.com/limenqi/formula-2d/blob/main/vivado/ip_repo/physics_axi_ip/physics_axi_ip_1.0/src/physics_top.v): `vivado/ip_repo/physics_axi_ip/physics_axi_ip_1.0/src/physics_top.v`
- [HDMI renderer](https://github.com/limenqi/formula-2d/blob/main/vivado/racing_axi/racing_axi.srcs/sources_1/imports/filles_axi/racing_renderer_axi.v): `vivado/racing_axi/racing_axi.srcs/sources_1/imports/filles_axi/racing_renderer_axi.v`

### Services and rendering

- **AWS leaderboard**
- [AWS calls](https://github.com/limenqi/formula-2d/blob/main/server_side/server/aws_functions.py): `server_side/server/aws_functions.py`
- [Software map renderer](https://github.com/limenqi/formula-2d/blob/main/server_side/software_render/map_renderer.py): `server_side/software_render/map_renderer.py`

### Other components

- **Player**
- **PYNQ board**

## Connections

- Player → Client entry: starts (evidence: `README.md`)
- Client entry → Client registration: runs (evidence: `client_side/client/main.py`)
- Client entry → Client game loop: runs (evidence: `client_side/client/main.py`)
- Client entry → Client physics: initializes (evidence: `client_side/client/main.py`)
- Client registration → Client UDP: creates socket (evidence: `client_side/client/menu_loop.py`)
- Client registration → Packet protocol: encodes registration (evidence: `client_side/client/menu_loop.py`)
- Client game loop → Client physics: steps motion (evidence: `client_side/client/game_loop.py`)
- Client game loop → Packet protocol: encodes updates (evidence: `client_side/client/game_loop.py`)
- Client game loop → Packet protocol: decodes snapshots (evidence: `client_side/client/game_loop.py`)
- Client game loop → Client UDP: sends and receives
- Client physics → Player state: updates (evidence: `client_side/game/physics.py`)
- Packet protocol → Player state: serializes (evidence: `client_side/net/protocol.py`)
- Server entry → Lobby and setup: runs (evidence: `server_side/server/main.py`)
- Server entry → Race loop: runs (evidence: `server_side/server/main.py`)
- Server entry → Race results: submits results (evidence: `server_side/server/main.py`)
- Lobby and setup → Server UDP: opens socket (evidence: `server_side/server/menu_loop.py`)
- Lobby and setup → Race loop: hands off game (evidence: `server_side/server/menu_loop.py`)
- Lobby and setup → AWS calls: uses services (evidence: `server_side/server/menu_loop.py`)
- Race loop → Packet protocol: decodes updates (evidence: `server_side/server/game_loop.py`)
- Race loop → Packet protocol: encodes snapshots (evidence: `server_side/server/game_loop.py`)
- Race loop → Authoritative state: applies updates (evidence: `server_side/server/game_loop.py`)
- Race loop → Hardware interface: writes race state (evidence: `server_side/server/game_loop.py`)
- Race loop → Server UDP: sends snapshots
- Race results → AWS calls: requests leaderboard (evidence: `server_side/server/game_ending.py`)
- AWS calls → AWS leaderboard: calls API (evidence: `README.md`)
- Hardware interface → Physics AXI IP: controls
- Hardware interface → HDMI renderer: writes render state
- PYNQ board → Hardware interface: hosts (evidence: `README.md`)
- PYNQ board → HDMI renderer: outputs HDMI (evidence: `README.md`)
- Software map renderer → Player state: draws players (evidence: `server_side/software_render/map_renderer.py`)
