Skip to content

Architecture Overview

Joshua Ferguson edited this page Nov 7, 2025 · 2 revisions

Architecture Overview

Technical overview of Terminal Velocity's architecture and design patterns.

System Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         SSH Clients                              │
│          (Players connecting from anywhere)                      │
└────────────────────┬────────────────────────────────────────────┘
                     │ SSH Protocol (Port 2222)
                     │
┌────────────────────▼────────────────────────────────────────────┐
│                      SSH Server Layer                            │
│  - Multi-method auth (password + public key)                    │
│  - Session management                                            │
│  - BubbleTea program lifecycle                                   │
└────────────────────┬────────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────────┐
│                    Application Layer                             │
│                                                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │     TUI      │  │  Game Logic  │  │  Background  │         │
│  │  (BubbleTea) │  │   (29+ Sys)  │  │   Workers    │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
│                                                                  │
└────────────────────┬────────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────────┐
│                   Repository Layer                               │
│  - 20+ repositories (Player, Ship, Market, Quest, etc.)         │
│  - Thread-safe (sync.RWMutex)                                   │
│  - Connection pooling (pgx)                                     │
└────────────────────┬────────────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────────────┐
│                   PostgreSQL Database                            │
│  - 20+ tables                                                    │
│  - UUID primary keys                                             │
│  - JSONB for flexible data                                       │
└──────────────────────────────────────────────────────────────────┘

Core Design Patterns

1. Repository Pattern

All database access goes through repositories:

type PlayerRepository interface {
    Create(ctx context.Context, player *Player) error
    GetByID(ctx context.Context, id uuid.UUID) (*Player, error)
    Update(ctx context.Context, player *Player) error
    Delete(ctx context.Context, id uuid.UUID) error
}

Benefits:

  • Encapsulates SQL queries
  • Type-safe data access
  • Easy testing (mock repositories)
  • Separation of concerns

2. BubbleTea MVC

UI follows Model-View-Update pattern:

type Model struct {
    screen Screen
    player *models.Player
    repos  *Repositories
}

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    // Handle messages (keyboard, async results)
}

func (m Model) View() string {
    // Render current state
}

Benefits:

  • Declarative UI
  • Clear separation of state and rendering
  • Composable components
  • Event-driven

3. Server-Authoritative Architecture

All game logic runs on the server:

Player Action → SSH → Server Validates → Database Update → UI Refresh

Benefits:

  • No cheating possible
  • Consistent multiplayer state
  • Centralized game logic
  • Fair gameplay

4. Background Workers

Long-running tasks use goroutines:

func (m *Manager) eventScheduler() {
    ticker := time.NewTicker(1 * time.Minute)
    for {
        select {
        case <-m.ctx.Done():
            return
        case <-ticker.C:
            m.updateEvents()
        }
    }
}

Workers:

  • Event scheduler (1 minute tick)
  • Auto-save (30 second tick)
  • Market updates (1 hour tick)
  • Session cleanup (5 minute tick)

Package Structure

internal/
├── server/          # SSH server & session management
├── tui/             # 30+ BubbleTea UI screens
├── database/        # 20+ repositories (pgx)
├── models/          # Data structures
├── combat/          # Turn-based combat system
├── missions/        # Mission lifecycle
├── quests/          # Quest & storyline system
├── events/          # Dynamic events manager
├── achievements/    # Achievement tracking
├── news/            # News generation
├── leaderboards/    # Player rankings
├── chat/            # Multiplayer chat
├── factions/        # Player faction system
├── territory/       # Territory control
├── trade/           # Player trading
├── pvp/             # PvP combat
├── presence/        # Player presence
├── encounters/      # Random encounters
├── outfitting/      # Equipment & loadouts
├── settings/        # Player settings
├── tutorial/        # Tutorial system
├── admin/           # Server administration
├── session/         # Auto-save & persistence
└── universe/        # Procedural generation

Key Systems

1. Universe Generation

Algorithm: Prim's MST + Random Connections

1. Generate 100 star systems (spiral galaxy distribution)
2. Create MST for guaranteed connectivity
3. Add 20-30% extra connections for redundancy
4. Assign tech levels (radial distribution from Sol)
5. Distribute factions by distance
6. Generate planets per system (1-4)
7. Assign services based on tech level

2. Dynamic Economy

Price Calculation:

FinalPrice = BasePrice
           × TechLevelModifier
           × SupplyDemandModifier

Market Updates:

  • Player trades immediately affect prices
  • Stock regenerates at 5%/hour
  • Demand normalizes at 5%/hour
  • Random events: 5% chance/hour

3. Turn-Based Combat

Combat Flow:

1. Initialize combat state
2. Player turn:
   - Select weapon
   - Calculate hit chance
   - Resolve damage
3. Enemy turn:
   - AI selects target/weapon
   - Calculate hit chance
   - Resolve damage
4. Check win/loss conditions
5. Repeat until resolved

AI Decision Tree:

- Assess threat level
- Check hull/shield status
- Evaluate weapon options
- Consider range/accuracy
- Apply difficulty modifiers
- Execute action

4. Quest System

Quest Structure:

type Quest struct {
    ID          string
    Type        QuestType  // Main, Side, Faction, etc.
    Objectives  []Objective
    Choices     []Choice   // Branching narrative
    Rewards     Reward
    Status      Status
}

Branching Logic:

  • Player choices affect outcomes
  • Multiple paths through quests
  • Reputation impacts availability
  • Dynamic quest generation

5. Event System

Event Lifecycle:

Scheduled → Active → Ending → Ended
    ↓         ↓         ↓        ↓
  Notify   Track    Warn    Rewards

Event Types:

  • Trading competitions
  • Combat tournaments
  • Expeditions (community goals)
  • Boss encounters
  • Festivals (multipliers)

Concurrency & Thread Safety

Locking Strategy

All shared state uses sync.RWMutex:

type Manager struct {
    mu      sync.RWMutex
    data    map[string]*Data
}

func (m *Manager) Get(id string) *Data {
    m.mu.RLock()
    defer m.mu.RUnlock()
    return m.data[id]
}

func (m *Manager) Set(id string, data *Data) {
    m.mu.Lock()
    defer m.mu.Unlock()
    m.data[id] = data
}

Database Connections

Connection Pooling (pgx):

  • Min connections: 2
  • Max connections: 10
  • Max idle time: 5 minutes
  • Acquire timeout: 10 seconds

Message Passing

BubbleTea uses channels for async operations:

func loadDataCmd() tea.Msg {
    data, err := fetchData()
    return dataLoadedMsg{data, err}
}

// In Update():
case dataLoadedMsg:
    m.data = msg.data
    return m, nil

Database Schema Highlights

Key Tables

players:

  • UUID primary key
  • Nullable password_hash (SSH-only accounts supported)
  • Credits, experience, level
  • Current location (system_id, planet_id nullable)

ships:

  • UUID primary key
  • Player foreign key
  • Ship type, name
  • Hull, shields, fuel, cargo
  • Equipment slots (JSONB)

star_systems:

  • UUID primary key
  • Name, position (x, y, z)
  • Tech level, government
  • Description

quests:

  • UUID primary key
  • Quest type, status
  • Objectives (JSONB array)
  • Choices (JSONB array)
  • Rewards (JSONB)

See Database Schema for full details.

Performance Considerations

Optimizations

  1. Database Indexes:

    • All foreign keys indexed
    • Player lookups by username/email
    • System lookups by name
    • Quest lookups by player + status
  2. Caching Strategy:

    • In-memory caching for static data (systems, ships, commodities)
    • 15-minute TTL for market prices
    • Session state cached in memory
  3. Connection Pooling:

    • pgx pool for database connections
    • SSH connection reuse
  4. Efficient Queries:

    • Batch operations where possible
    • Prepared statements for repeated queries
    • JOINs minimized (denormalization where beneficial)

Scalability

Current Capacity:

  • 100+ concurrent players
  • Sub-10ms database queries
  • 30-second auto-save cycle
  • Real-time multiplayer features

Bottlenecks:

  • Database writes (auto-save at scale)
  • Event leaderboard updates
  • Market price calculations

Future Improvements:

  • Redis caching layer
  • Database read replicas
  • Horizontal scaling (multiple servers)

Security Architecture

Authentication

Multi-Method:

  1. Password: Bcrypt hashing
  2. SSH Keys: SHA256 fingerprints

Flow:

SSH Connect → Auth Handler → Validate → Create Session

Authorization

RBAC (Role-Based Access Control):

  • 4 roles: Player, Moderator, Admin, SuperAdmin
  • 20+ permissions
  • Permission checks on all admin actions
  • Audit logging (10,000 entry buffer)

Data Protection

  • SQL Injection: Parameterized queries (pgx)
  • Session Hijacking: Secure token generation
  • Input Validation: All user input sanitized
  • Rate Limiting: Connection throttling

Development Workflow

Adding a New Feature

  1. Models: Define data structures in internal/models/
  2. Repository: Create repository in internal/database/
  3. Game Logic: Implement in appropriate package
  4. UI: Add TUI screens in internal/tui/
  5. Tests: Write unit tests
  6. Documentation: Update wiki pages

Testing Strategy

Unit Tests:

  • Game logic (combat, economy, quests)
  • Data models
  • Utility functions

Integration Tests:

  • Database operations
  • Multi-system interactions
  • Player workflows

Manual Testing:

  • UI/UX testing via SSH
  • Multiplayer testing
  • Performance testing

Code Quality

Tools:

  • golangci-lint: Linting
  • go fmt: Formatting
  • go vet: Static analysis
  • go test -race: Race detection

Standards:

  • Idiomatic Go code
  • Comprehensive error handling
  • Public function documentation
  • Consistent naming conventions

Deployment Architecture

Docker Setup

docker compose.yml:
  - PostgreSQL container
  - Terminal Velocity server container
  - Shared network
  - Volume mounts for persistence

Production Recommendations

Infrastructure:

  • 2 CPU cores minimum
  • 2GB RAM minimum
  • PostgreSQL on separate instance (production)
  • SSL/TLS for SSH (via reverse proxy)

Monitoring:

  • Server metrics (CPU, memory, connections)
  • Database performance
  • Player activity
  • Error logging

Backup Strategy:

  • Daily PostgreSQL dumps
  • Continuous WAL archiving
  • Off-site backups

Future Architecture Plans

Phase 8+ Enhancements

  1. Redis Caching:

    • Market price caching
    • Session state caching
    • Leaderboard caching
  2. Microservices (if needed):

    • Event service
    • Combat service
    • Market service
  3. Horizontal Scaling:

    • Multiple game servers
    • Load balancing
    • Shared database
  4. Web Dashboard:

    • REST API
    • Player statistics
    • Admin interface
  5. Modding Support:

    • Plugin architecture
    • Content loading system
    • Scripting support (Lua?)

For detailed API reference, see API Reference

For database details, see Database Schema

For development setup, see Development Setup

Clone this wiki locally