Shared Configuration

Problem

Game configuration (body hierarchy, spin axes, ship classes) is duplicated between the Python backend (galaxy_config/__init__.py) and the JavaScript frontend (bodyConfig.js, shipSpecsData.js). Manual synchronization is error-prone — adding a new ship class or body on one side but not the other causes silent UI failures.

Solution: Single JSON Source of Truth

A single shared_data.json file defines the three shared data structures. Both Python and JavaScript consume it directly, eliminating duplication.

Data File

Location: services/shared/galaxy_config/shared_data.json

Contains three top-level keys:

Key Type Description
BODY_PARENTS object<string, string> Moon name → parent planet name (20 entries)
BODY_SPIN_AXES object<string, [number, number, number]> Body name → ecliptic spin axis unit vector (10 entries)
SHIP_CLASSES object<string, object> Ship class key → physics properties

All values are JSON-safe primitives (strings, numbers, arrays, objects). No Python-specific syntax (underscored numeric literals, tuples, etc.).

Python Consumption

galaxy_config/__init__.py loads the JSON at import time:

import json, os
_data_path = os.path.join(os.path.dirname(__file__), 'shared_data.json')
with open(_data_path) as _f:
    _shared = json.load(_f)

BODY_PARENTS = _shared['BODY_PARENTS']
BODY_SPIN_AXES = _shared['BODY_SPIN_AXES']
SHIP_CLASSES = _shared['SHIP_CLASSES']

Helper functions (get_body_spin_axis, get_ship_class) remain as Python code. The module’s public API is unchanged — existing imports work identically.

JavaScript Consumption

The JSON file is copied into services/web-client/src/generated/sharedConfig.json at build time (not checked into git).

  • bodyConfig.js imports BODY_PARENTS (moon→parent mappings) from the JSON and adds the planet→Sun and Sun→null entries that the frontend needs for tree building. BODY_SPIN_AXES is imported directly.
  • shipSpecsData.js imports SHIP_CLASSES from the JSON and merges frontend-only properties (display_name, dimensions) that the backend does not need.

Frontend-only data (colors, spawn altitudes, body subtypes, formatting functions) stays in the JS files.

Build Pipeline

The JSON must be copied to the web-client build context before building:

  • scripts/build-images.sh: Uses a temp-dir build pattern for web-client (consistent with Python services). Copies the JSON to src/generated/sharedConfig.json inside the temp dir.
  • .github/workflows/build-push.yml: A “Prepare build context (shared config for frontend)” step copies the JSON before building.
  • .github/workflows/ci.yml: A copy step before web-client tests ensures the generated file is available for vitest.

Gitignore

services/web-client/.gitignore excludes src/generated/ since the JSON is copied at build time, not committed.

Shared Validation: Password

Password validation was previously duplicated in the api-gateway and players services, each hardcoding min_password_length = 8. The shared module now provides:

MIN_PASSWORD_LENGTH = 8

def validate_password(password: str) -> bool:
    """Check password meets minimum length requirement."""
    return isinstance(password, str) and len(password) >= MIN_PASSWORD_LENGTH
  • api-gateway (routes/helpers.py): _validate_password delegates to galaxy_config.validate_password and raises HTTPException(400, E012) on failure.
  • players (auth.py): validate_password delegates to galaxy_config.validate_password and returns error code "E012" on failure (preserving the existing return-type contract).

Both services import from galaxy_config, eliminating the duplicated constant.

Invariants

  1. shared_data.json is the single source of truth for body parents, spin axes, and ship classes.
  2. Python and JavaScript must produce identical values for all shared keys.
  3. Adding a new body or ship class requires editing only shared_data.json.
  4. Frontend-only data (display names, dimensions, colors, spawn altitudes) lives in JS files, not in the JSON.
  5. Password length requirements are defined once in galaxy_config (MIN_PASSWORD_LENGTH). Services must not hardcode their own minimum.

Back to top

Galaxy — Kubernetes-based multiplayer space game

This site uses Just the Docs, a documentation theme for Jekyll.