sparkengine-architecture-contract

Enforces SparkEngine's subsystem ownership, service locator, and ECS phase-ordering design invariants.

31|3|Updated Jul 26, 2025
One-click install
npx skills add https://github.com/Krilliac/SparkEngine --skill sparkengine-architecture-contract-krilliac
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: sparkengine-architecture-contract
Source: https://github.com/Krilliac/SparkEngine/tree/main/.claude/skills/sparkengine-architecture-contract
Command: npx skills add https://github.com/Krilliac/SparkEngine --skill sparkengine-architecture-contract-krilliac

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? When modifying the SparkEngine C++23 game engine, it is easy to break load-bearing design rules—adding a global subsystem pointer that is null inside game-module DLLs, registering an ECS system in the wrong phase, or hard-coding a GPU backend that breaks headless CI. This Skill states the engine's six architectural invariants, the reasoning behind each, and the exact failure mode caused by violating them. ## Core Features & Use Cases - Subsystem ownership rules: Defines that EngineRuntime owns all subsystems and EngineContext acts as the single service locator, including the non-const type-id trick that prevents Release-only ICF folding bugs. - DLL boundary guidance: Explains how the host injects EngineContext into game-module DLLs and why per-module singletons cause duplicate subsystems. - ECS phase topology: Documents the canonical PhaseSystemManager registration point and the fixed Physics-to-Render ordering, plus wiring verification via tools/check-wiring.sh. - Use Case: Before adding a new audio subsystem, consult this Skill to learn it must be owned by EngineRuntime, registered with RegisterSubsystem and dependency ordering, fetched via EngineContext::Get(), and wired into the real startup and frame loop in the same change. ## Quick Start Ask the AI to review your planned SparkEngine subsystem change against the architecture contract invariants before writing any code.

Frequently Asked Questions about sparkengine-architecture-contract

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I add a new subsystem to SparkEngine correctly?

Add an owning std::unique_ptr field to EngineRuntime, create it on the startup path, and register it with RegisterSubsystem<T> using DependsOn for topological init ordering. Fetch it at call sites via EngineContext::Get()->GetSystem<T>() and wire its Update into the real loop in the same change.

Why is my subsystem pointer null inside a game-module DLL?

Each game-module DLL statically links its own copy of the engine, so file-scope globals and the default context are per-image and null inside the module. The host injects its live EngineContext via SparkModuleInjectEngineContext, so module code must call EngineContext::Get() rather than any local singleton.

Where do I register a new ECS system in SparkEngine?

Register new ECS systems in Spark::EngineSetup::CreatePhaseSystemManager with the correct Phase bucket such as Physics, AI, or PreRender. Do not use the legacy flat SystemManager, which has no phase ordering guarantee.

Why must GetTypeId's static char id stay non-const?

A static const char compiles to an identical read-only COMDAT for every type, which MSVC's /OPT:ICF folds to one address in Release builds, collapsing all type ids to a single key. Keeping it writable prevents ICF folding and avoids a Release-only bug where the locator returns the wrong subsystem.

Can I hard-code D3D11 device creation in SparkEngine?

No. All GPU work must go through the RHI abstraction with backend selection centralized in RHIFactory.cpp, which supports SPARK_RHI_BACKEND overrides and falls back to NullRHIDevice. Hard-coding a backend breaks Linux and macOS builds, headless CI, and dedicated servers.

When should I not use this architecture contract skill?

Skip it for phase-execution mechanics, threading, and allocators, which belong to the ECS lifecycle skill, and for module ABI, SDK exports, or hot-reload mechanics, which belong to the modules SDK skill. Self-contained bug fixes crossing no subsystem boundary need no skill at all.