C2C — Core to Cosmos

Space strategy game shipping with yakmesh — the first application built on the full protocol stack.

What is C2C?

Core to Cosmos (C2C) is a space strategy game with procedural planet generation, AI-driven factions, and NPU-accelerated gameplay. It ships alongside yakmesh as a showcase application demonstrating real-world use of the protocol stack.

Tech Stack

  • React + Vite frontend
  • Node.js / Express backend
  • SQLite database
  • 391 art assets
  • 85/85 tests passing

NPU Models

  • 8 AI models via DirectML
  • Planet generation & super-resolution
  • Faction AI decision-making
  • Combat prediction
  • Adaptive threat scaling

Yakmesh Integration

C2C uses several yakmesh subsystems for networking, encryption, time synchronization, and distributed compute:

Yakmesh System C2C Usage
ANNEX ML-KEM-768 encrypted WebSocket connections between game server and clients
SEVA 5 NPU model slots (planet-variation, planet-heightmap, planet-superres, faction-brain, combat-predict) shared across the mesh
TIVRA Hardware detection and ONNX model loading for local NPU inference
MANI Authoritative game clock — every tick, mutation, and NPU inference uses MANI time
KATHA In-game chat integrated via KOMM WebSocket
Studio Story mode for game chronicles and faction narratives

SEVA Model Slots

C2C registers 5 model slots with the SEVA compute sharing protocol. When a player's machine lacks an NPU, SEVA transparently routes inference to a peer node that has one:

planet-variation

Generates planet variations from metadata. Input: 8-float parameter vector. Runs on NPU for real-time planet customization.

planet-heightmap

Procedural terrain heightmaps for planet surfaces. Creates unique geography per planet seed.

planet-superres

Super-resolution upscaling of planet textures. Low-res textures upscaled on NPU for visual quality.

faction-brain

AI faction decision-making. Scores actions, picks strategies, generates faction narratives, handles diplomacy.

combat-predict

Combat outcome prediction for battle resolution. Predicts winner probability given force composition.

Fallback Chain

C2C's client-side NPU integration uses a transparent fallback chain. The player never knows which path was used — the experience is identical:

  1. HTTP API — Direct ONNX inference on game server's NPU/GPU
  2. WebSocket seva:work — If HTTP fails, route via WebSocket to server's NPU pool
  3. Mesh offload — If local server has no NPU, SEVA finds a mesh peer with one
  4. CPU fallback — Software computation, always available, always correct

Building Your Own Realm

C2C uses the Adapter pattern for realms. Each realm is a self-contained folder in c2c/server/realms/ with a manifest and an optional narrative module. The server discovers and loads all realms at boot.

Realm Folder Structure

c2c/server/realms/
  your-realm/
    manifest.json    # Required — realm definition
    narrative.js     # Optional — NPU narrative voice

Manifest Skeleton

The manifest.json defines everything the server needs to register your realm, create NPC factions, and drive the story arc system. Here is the minimum required structure:

{
  "id": "my-realm",
  "name": "My Realm",
  "slug": "my-realm",
  "mode": "sandbox",          // sandbox | coop-pve | pvp
  "description": "A custom realm for...",
  "max_players": 100,

  "config": {
    "aesthetic": {
      "palette": ["#0A0A1A", "#2D1B69", "#FF6600"],
      "theme": "nebula-dark",
      "accent": "#FF6600"
    },
    "gameplay": {
      // Your realm-specific game rules
    }
  },

  "factions": [ /* ... */ ],
  "npcs": [ /* ... */ ],
  "arcs": [ /* ... */ ]
}

Game Modes

Mode Description
sandbox Open-ended play, no NPC antagonist, player-driven economy
coop-pve Players unite against NPU-driven NPC factions (e.g. Obsidian Scion)
pvp Player-vs-player competitive with faction allegiances

Defining Factions

Each faction has a personality that drives the NPU decision-making, custom units, buildings, and mutable state that evolves as arcs progress:

{
  "name": "The Swarm",
  "tag": "SWRM",
  "faction_type": "npc",         // npc | player
  "alignment": "hostile",        // hostile | friendly | neutral
  "capabilities": {
    "units": [
      { "id": "drone", "name": "Hive Drone",
        "attack": 60, "hull": 150, "shield": 20, "speed": 12000,
        "desc": "Fast expendable swarm unit." }
    ],
    "buildings": [
      { "id": "hive_spire", "name": "Hive Spire",
        "desc": "Spawns drones. More spires = faster spawn rate." }
    ]
  },
  "personality": {
    "aggression": 0.9,
    "expansion_priority": 0.8,
    "diplomacy_willingness": 0.0,
    "target_preference": "nearest_first",
    "retreat_threshold": 0.05,
    "npu_voice": "hive_queen"    // Links to narrative.js voice
  },
  "state": {
    "phase": "dormant",
    "planets_controlled": 0,
    "threat_level": 0
  }
}

Story Arcs

Arcs are narrative phases that unlock progressively. Each arc has a trigger condition and rewards. The server evaluates triggers every realm tick (30 seconds):

{
  "name": "First Contact",
  "slug": "first_contact",
  "phase_number": 2,
  "trigger_type": "event",           // player_count | event |
                                     // faction_state | community_goal
  "trigger_config": {
    "event": "alien_base_discovered",
    "count": 1
  },
  "rewards_config": {
    "resources": { "metal": 15000, "crystal": 10000, "deuterium": 5000 },
    "npc_unlock": "aktai"
  },
  "description": "An alien scout probe is detected..."
}
Trigger Type Fires When
player_count Realm reaches min_players members
event A game event fires N times (discovery, combat, etc.)
faction_state NPC faction state matches a condition (e.g. planets_controlled >= 5)
community_goal Players collectively reach a threshold (alliance size, research, etc.)

NPCs

NPCs are quest givers, antagonists, or wild cards. They appear when their arc unlocks and speak through the narrative module:

{
  "id": "hive_queen",
  "name": "The Hive Queen",
  "role": "antagonist",         // quest_giver | antagonist |
                                // mini_boss | wild_card
  "title": "Mother of Drones",
  "bio": "A vast intelligence distributed across a million bodies...",
  "appears_in_arc": "first_contact",
  "dialogue_tags": ["alien", "collective", "hungry"]
}

Narrative Voice Module

The optional narrative.js gives your realm a unique writing voice. It exports vocabulary, dialogue templates, and event narration that the server uses for chat messages, notifications, and arc descriptions:

// c2c/server/realms/my-realm/narrative.js
import { createLogger } from '../../lib/logger.js';
const log = createLogger('narrative');

const _registry = {};

export function register(realmSlug) {
  _registry.slug = realmSlug;
  log.info({ realmSlug }, 'My realm voice registered');
}

// Vocabulary pools — used by the server for procedural narration
export const ADJECTIVES = [
  'chitinous', 'swarming', 'relentless', 'buzzing', 'vast',
];

export const VERBS = [
  'swarm over', 'consume', 'burrow into', 'engulf', 'devour',
];

// NPC dialogue templates ($LOCATION replaced at runtime)
export const NPC_DIALOGUE = {
  hive_queen: {
    greeting: [
      'We are many. You are few. The arithmetic is clear.',
      'Every world you lose feeds a thousand of our young.',
    ],
    mission_brief: [
      'The hive detects weakness at $LOCATION. We hunger.',
    ],
  },
};

Tech Tree Extensions

Realms can define custom technologies that unlock through arc progression. Each tech has resource costs, research time, and a description:

"tech_tree_extensions": {
  "hive_biotech": {
    "unlock_condition": "arc:first_contact",
    "techs": [
      {
        "id": "chitin_armour",
        "name": "Chitin Plating",
        "cost": { "metal": 30000, "crystal": 15000 },
        "time": 5400,
        "desc": "Armour harvested from drone carapaces. +10% hull."
      }
    ]
  }
}

How It Works

Drop your realm folder into c2c/server/realms/ and restart the server. The realm loader auto-discovers it, registers the realm in the database, inserts factions and arcs, and loads the narrative module. No code changes needed.

See the built-in obsidian-scion/ realm for a complete reference implementation with 6 story arcs, 6 NPCs, 2 factions, custom tech trees, and a full narrative voice.

AI Profiles

AI Profiles give players control over NPC faction behaviour. Instead of being locked to the personality baked into a realm manifest, players can select preset profiles, build custom personalities via sliders, or describe one in plain text and let the NPU generate a personality vector.

Three Tiers

Tier Source How
Preset Realm manifest Select from built-in profiles — Berserker, Turtle, Diplomat, Expansionist, Balanced
Custom Slider UI Set each personality axis (aggression, expansion, diplomacy, target pref, retreat threshold) manually
NPU-Generated Text description Describe the AI you want in plain language — the NPU faction-brain model maps it to a personality vector

Personality Shape

Every profile stores the same personality object used by NPC factions. The SEVA faction-brain model reads these numbers to drive NPC decision-making via NPU inference.

{
  "aggression":            0.85,   // 0 = pacifist, 1 = berserk
  "expansion_priority":    0.9,    // 0 = hunker down, 1 = claim everything
  "diplomacy_willingness": 0.0,    // 0 = no talks, 1 = always negotiate
  "target_preference":     "weakest_first",  // weakest_first | strongest_first | nearest | defensive
  "retreat_threshold":     0.15    // 0 = never retreat, 1 = flee at first scratch
}

Adding Presets to a Manifest

Realm creators add an ai_profiles array to their manifest.json. The realm loader seeds them into the database automatically at boot.

"ai_profiles": [
  {
    "name": "Berserker",
    "description": "All-out aggression. Attacks relentlessly, never retreats.",
    "personality": {
      "aggression": 1.0,
      "expansion_priority": 0.7,
      "diplomacy_willingness": 0.0,
      "target_preference": "strongest_first",
      "retreat_threshold": 0.0
    },
    "dialogue_tags": ["fierce", "reckless", "relentless"]
  }
]

API Endpoints

Method Endpoint Description
GET /realms/:id/ai-profiles List presets + your custom profiles
POST /realms/:id/ai-profiles Create a custom profile
PUT /realms/:id/ai-profiles/:profileId Update your custom profile
DELETE /realms/:id/ai-profiles/:profileId Delete your custom profile
POST /realms/:id/ai-profiles/:profileId/apply Apply a profile to a faction
POST /realms/:id/ai-profiles/generate NPU-generate a profile from text

NPU Generation Example

Describe what you want in natural language. The faction-brain SEVA slot converts it into a personality vector using keyword extraction (CPU fallback) or NPU inference (when SEVA is online).

// POST /realms/:realmId/ai-profiles/generate
const res = await fetch(`/api/game/realms/${realmId}/ai-profiles/generate`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    description: 'A ruthless conqueror who crushes the weak and expands relentlessly across every star system'
  })
});

const { profile } = await res.json();
// profile.personality → { aggression: 0.95, expansion_priority: 0.9, ... }
// profile.dialogue_tags → ["fierce"]
// profile.source → "npu_generated"

Applying a Profile

Once created or selected, apply a profile to any NPC faction in your realm. The personality vector merges into the faction's existing config — faction-specific fields like npu_voice and taunts are preserved, while the core personality axes get overwritten with your chosen profile.

Up to 20 custom profiles per realm per player. Presets are unlimited and shared across all players.

Version History

Version Changes
v3.0.0 C2C ships with yakmesh. Full SEVA integration, 8 AI models, MANI time protocol, ANNEX encryption, 391 art assets, 85/85 tests.