Files
lanspread/CLAUDE.md
T
2025-12-07 08:18:25 +01:00

6.2 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

LanSpread2 is a peer-to-peer (P2P) game distribution system with a Tauri desktop application frontend. It enables users to share games over local networks using mDNS discovery and QUIC protocol for peer communication.

Common Development Commands

Build

# Development (opens UI, needs user interaction)
cargo tauri dev

# Debug build for very quick testing (without bundle)
cargo tauri build --debug --no-bundle

# Release build for testing (without bundling)
cargo tauri build --no-bundle

# Production (with bundling)
cargo tauri build -- --profile release-lto

Build Profiles

  • release: Default release profile with debug info, assertions enabled, overflow checks on, for testing
  • release-lto: Optimized for distribution with LTO enabled, debug symbols stripped, smaller binary, only for production

Code Quality

# Lint all code
cargo clippy

# Format code (nightly Rust)
cargo +nightly fmt

Testing

# Run all tests
cargo test --workspace

# Run tests for a specific crate
cargo test -p lanspread-peer

# Run a specific test
cargo test -p lanspread-peer test_name

# Run tests with output
cargo test -- --nocapture

Dependencies

# Update frontend dependencies (Deno)
deno outdated --update --latest

Wayland Users

# Set this environment variable if running on Wayland
WEBKIT_DISABLE_DMABUF_RENDERER=1

Architecture

LanSpread follows a layered, modular architecture with clear separation of concerns:

Crate Structure

The project is organized as a Cargo workspace with 7 crates:

Foundation Layer:

  • lanspread-utils: Utility macros and helpers used across all crates
  • lanspread-db: Core data structures (Game, GameFileDescription, game metadata)

Protocol & Communication:

  • lanspread-proto: P2P communication protocol definitions
    • Message types: Request (Ping, ListGames, GetGame, etc.), Response, Message trait
    • Serialization: JSON with serde

Network Discovery & Compatibility:

  • lanspread-mdns: mDNS service discovery and advertisement

    • Advertises and discovers "_lanspread._udp.local." services on LAN
    • Uses mdns-sd crate
  • lanspread-compat: Compatibility layer for legacy ETI game database format

    • Reads legacy game.db SQLite databases
    • Converts EtiGame structs to modern Game struct

Core P2P Engine:

  • lanspread-peer: Central orchestration for all P2P functionality
    • Entry point: start_peer() in lib.rs
    • Communicates via unbounded channels (PeerEvent, PeerCommand)
    • Key modules:
      • services.rs: Background tasks (server, discovery, ping, local game monitor)
      • handlers.rs: Command handlers for UI requests
      • network.rs: QUIC connection management with length-delimited frames
      • download.rs: Chunked file transfer logic
      • peer_db.rs: Peer tracking and game availability
      • path_validation.rs: Security for file operations

Application Layer:

  • lanspread-tauri-deno-ts: Tauri desktop application
    • Binary + Library crate for the UI layer
    • IPC commands: request_games, install_game, etc.
    • Manages LanSpreadState for peer controller, game DB, and downloads
    • Uses Tauri plugins: logging, shell, dialogs, persistent storage
    • Allocates MiMalloc for memory efficiency

Data Flow

User (Tauri UI)
    ↓ IPC Commands (request_games, install_game)
    ↓
lanspread-tauri-deno-ts (app layer)
    ↓
lanspread-peer (P2P engine)
    ├─ lanspread-mdns (discovers peers via mDNS)
    ├─ lanspread-proto (constructs P2P messages)
    ├─ lanspread-compat (reads legacy game databases)
    └─ QUIC Network ↔ Other Peers
    ↓
lanspread-db (game data structures)
    ↓
Result → Back to UI

Key Architectural Details

  1. Async/Await: Tokio runtime throughout for non-blocking I/O
  2. Message Passing: Unbounded channels for inter-component communication (events and commands)
  3. Protocol: Length-delimited QUIC frames with JSON serialization
  4. Service Discovery: Automatic mDNS announcement and discovery of peers
  5. File Streaming: Chunked transfer with path validation for security
  6. Legacy Support: Backwards compatibility with ETI game database format
  7. Error Handling: Custom error types via eyre crate

Development Practices

From AGENTS.md

  • Always check code with cargo clippy and fix any issues
  • Always format with cargo +nightly fmt after completing changes
  • Use appropriate Rust log levels when debugging:
    • RUST_LOG=lanspread=debug for module-specific debugging
    • RUST_LOG=info,lanspread=debug for general info + module debug

Performance Considerations

  • Use release-lto profile for final builds to enable Link-Time Optimization
  • MiMalloc is used for the Tauri app to reduce memory overhead
  • QUIC protocol chosen for efficient P2P communication
  • Length-delimited framing reduces message parsing overhead

Important Implementation Notes

Logging

The codebase uses tracing and log crates. Note: There's documented uncertainty about their exact relationship (see LESSONS_LEARNED.md). The client app uses log crate; be consistent with whichever is used in the component you're modifying.

Legacy Database Support

Some users may have old ETI format game databases. The lanspread-compat crate handles reading these. When querying games, both modern and legacy formats are considered.

Path Validation

File transfers validate paths to prevent directory traversal attacks. All file operations use validated paths from lanspread-peer.

Retry Logic

lanspread-peer includes retry logic for requesting games from peers. This handles transient network failures in P2P discovery.

Known Design Decisions

Why not Tauri + Leptos? Leptos adds unnecessary complexity. Tauri is designed to transfer backend Rust to frontend JavaScript world, but with Leptos the frontend becomes Rust, creating a double translation. The current Tauri + Deno/TypeScript approach is cleaner.

Why Tauri? Simple setup, easy development with cargo tauri dev, easy testing and bundling with installers, small final binary (~13MB).