Decisions

This document records the key architectural and design decisions made for the CROSS project.


📌 ADR-001: Centralized Master Server for MVP

Status

Approved

Context

We need a way for viewers to retain their character level, items, and resources across multiple streams. We discussed two hosting options: a centralized model (single root server hosting the database and server) or a self-hosted federated model (where streamers host their own servers and sync databases/assets).

Decision

For the Minimum Viable Product (MVP), we will focus exclusively on a centralized master server hosted on a root server.

Consequences

  • Pros:
    • Simplified database design (single source of truth).
    • Eliminates the security risk of streamers editing local databases to cheat items/levels.
    • Faster development and deployment cycle.
  • Cons:
    • Higher initial server hosting cost for the project owners as user counts grow.
    • Scalability must be addressed later (potential migration to GCP).

📌 ADR-002: Keycloak for Identity and Access Management

Status

Approved

Context

We need secure authentication and authorization for streamers (to access dashboards, room configurations, and stream keys) and viewers (to link their Twitch accounts for inventory and extension usage).

Decision

Use Keycloak as the authentication provider, integrated with Twitch OAuth.

Consequences

  • Pros:
    • Keycloak is already deployed and ready to use.
    • High security standards (OAuth2, OIDC).
    • Twitch Developer OAuth can be configured directly as an Identity Provider in Keycloak.
  • Cons:
    • Adds another service dependency to manage and keep updated.

📌 ADR-003: Client Delivery via Steam Desktop Executable (Godot & OBS Game Capture)

Status

Approved

Context

How do streamers render the RPG overlay onto their Twitch stream? We need a delivery mechanism that supports monetization (selling on Steam), runs performantly, and allows streamers to easily customize their stream assets (avatars, items, cosmetics) without overloading our central servers.

Decision

Target a Godot Desktop Executable distributed via Steam as the primary delivery mechanism, using OBS Game Capture with transparency enabled to render the overlay on stream.

Consequences

  • Pros:
    • Monetization: Straightforward integration with Steam for commercial distribution and sales.
    • Custom Assets: Streamers can load custom art/mods locally or via Steam Workshop, bypassing the need to upload files to a central CDN.
    • Performance: Natively compiled Godot desktop build is highly performant compared to WebGL running inside OBS’s Chromium-based browser source.
    • Lower Infrastructure Costs: Minimizes web hosting and asset distribution bandwidth.
  • Cons:
    • Friction: Streamers must download, install, and run a desktop executable rather than just pasting a URL.
    • Updates: Client updates must be pushed via Steam or managed via an in-game patcher.

📌 ADR-004: Server-Authoritative Game Loop

Status

Approved

Context

To maintain game integrity and prevent viewers from hacking their stats or gold, we must choose where game actions are simulated.

Decision

Implement a Server-Authoritative Game Loop. The server processes all ticks, calculations, combat, movements, and rewards. The Godot client simply listens to state packets via WebSockets and plays animations.

Consequences

  • Pros:
    • Highly secure: clients cannot hack their speed, damage, or gold values.
    • Engine-agnostic: makes it easy to expose WebSockets to other engines (Unity, HTML5 canvas) in the future.
  • Cons:
    • Higher server CPU load to run the ticks for multiple active stream sessions.
    • Latency compensation must be handled so viewer commands feel responsive.

📌 ADR-005: State-Based Chat Command Toggle Interface

Status

Approved

Context

Frequent typing of chat commands (e.g., spamming !attack for every hit) causes chat clutter, disrupts normal streamer-viewer conversation, and increases Twitch IRC and backend parse loads.

Decision

Implement a State-Based Command Interface where a single chat command toggles a state (e.g., !attack, !defend, !support). The server maintains the character in that state, processing ticks and actions automatically, until the state is explicitly changed or target conditions vanish.

Consequences

  • Pros:
    • Eliminates chat spam completely.
    • Reduces Twitch message rate limit bottlenecks.
    • Better fits a simulation/passive-RPG visual layout.
  • Cons:
    • Requires robust server-side state machines to handle auto-targeting and pathfinding states when conditions change.

📌 ADR-006: Proximity-Based Path Interception for Enemy Aggro

Status

Approved

Context

We need a simple, visually intuitive aggro mechanic suitable for a 2D side-scrolling overlay without requiring complex UI targeting commands for chat users.

Decision

Use Proximity-Based Path Interception for drawing aggro. When an enemy’s path collides or comes within a close range of a player’s avatar shape, the enemy changes its target to that player, halting its march toward the streamer’s buildings.

Consequences

  • Pros:
    • Intuitive visual play: players simply position their avatars in front of incoming monsters.
    • Extremely easy to implement using Godot’s collision system or lightweight server-side line/circle intersection checks.
  • Cons:
    • Can lead to “body block stacking” where a single tank draws all aggro easily; requires balance.

📌 ADR-007: Spritesheet Bundling for Streamer Assets

Status

Approved

Context

Streamers will supply custom art assets (textures for rooms, customized decorations, emotes). Downloading dozens of individual small images for each stream is network-inefficient.

Decision

Implement a Dynamic Spritesheet Bundler on the master server. When streamers upload assets, the backend compiles them into a single spritesheet texture and a corresponding atlas coordinates JSON file.

Consequences

  • Pros:
    • Drastically reduces HTTP requests during game loading.
    • Improves Godot batch rendering efficiency.
  • Cons:
    • Requires maintaining a server-side image manipulation library (e.g., Sharp in Node.js or go-image).

📌 ADR-008: Prioritizing Twitch Extension & Standalone Over Bot Whispers

Status

Approved

Context

Traditional text-based chat commands for complex RPG systems (like managing inventories, upgrading multi-tier skill trees, or browsing shops) are extremely cumbersome and user-unfriendly. Furthermore, the Twitch API heavily rate-limits and restricts bots sending direct messages (Whispers) to combat spam.

Decision

Prioritize the Twitch Extension Panel and the Standalone Godot Game Client as the first-class, primary user interfaces. Drop Twitch Bot Whispers entirely and keep chat command interactions restricted to basic combat state toggles (!attack, !defend, !support, !goto).

Consequences

  • Pros:
    • Premium, mouse-driven user experience for viewers.
    • Avoids Twitch rate-limiting and whisper restrictions on the bot.
    • Keeps Twitch chat clean from bot status output.
  • Cons:
    • Demands earlier development of the Twitch Extension front-end, making it MVP-critical instead of a post-launch extra.

📌 ADR-009: Hybrid Simulation with Server-Authoritative Combat Math

Status

Approved

Context

Running a fully server-authoritative physics engine (tracking coordinates and running pathfinding on the backend) for hundreds of active streams is extremely CPU-intensive and expensive. However, letting the client calculate and report its own damage and healing outcomes opens the door to clients hacking their combat reports (e.g. spoofing instant mob kills).

Decision

Implement a Hybrid Simulation Model with a request-response math loop.

  1. The streamer’s Godot client handles spatial physics, collisions, and AI movement/targeting.
  2. The Master Server handles all combat math, health tracking, cooldowns, and formulas. When the client detects a collision/range trigger (e.g. Viewer A attacks Mob B), it requests an calculation from the server. The server calculates the damage against the database’s record of Viewer A’s gear/stats, updates Mob B’s current HP in the server’s session state, and returns the result (e.g., Damage Dealt: 20 or Mob B Died) to the client.

Consequences

  • Pros:
    • Negligible root server CPU load (no coordinate calculations or tick loops).
    • High security: absolute protection against client-side stat/damage spoofing, as the client can never “tell” the server how much damage was dealt.
    • Zero-latency local rendering of movement on the streamer’s side.
  • Cons:
    • Higher network message volume during combat (each attack/heal requires a WebSocket round-trip).

📌 ADR-010: AI-Driven Combat with Queued Viewer Overrides

Status

Approved

Context

We want characters on the Twitch overlay to fight intelligently without forcing the viewer to actively click commands for every action, while still offering manual override control for active viewers.

Decision

Implement a Client-Side Combat AI (running in the streamer’s Godot app) that handles basic movements and spellcasting on cooldown automatically. However, allow viewers (via standalone app or Twitch extension) to send manual command events. These manual events bypass the AI, are queued, and take execution priority over auto-cast skills once the character’s Global Cooldown (GCD) finishes.

Consequences

  • Pros:
    • Characters behave intelligently even if the viewer goes AFK (avoids idle characters standing still during waves).
    • Keeps the overlay visually dynamic and clean.
    • Satisfies active players by letting them manually trigger high-impact skills at key moments.
  • Cons:
    • Requires coordinating the client-side state machine in Godot to cleanly toggle between AI-driven behaviors and queued manual commands.


📌 ADR-011: Co-dependent Loop Split (Gathering vs. Processing Environments)

Status

Approved

Context

We need to give players a reason to buy the standalone game client, while ensuring that free Twitch-only viewers do not get frustrated by missing out on the core crafting loops of the world.

Decision

Both Twitch viewers and Standalone owners can gather, refine, and craft, but the environment determines the scale, speed, and quality:

  1. Twitch Extension (Free): Access to basic processing and crafting using the streamer’s rooms. Limited to standard quality items (Common/Uncommon), short queues, and slow processing times.
  2. Standalone Client (Premium): Access to private estates, active minigames (producing high-tier Rare/Epic/Legendary/Unique gear), solo dungeons with exclusive boss-drop materials, and a player auction house.

Consequences

  • Pros:
    • Free viewers get the “whole world” experience without feeling locked out.
    • Clear, powerful incentives (efficiency, minigames, artifacts, dungeons) to purchase the standalone client.
  • Cons:
    • Requires maintaining dual crafting endpoints (extension UI vs standalone UI) on the backend.

📌 012: Rigid Quality Tiering (Instead of Dynamic Custom Stats)

Status

Approved

Context

If active crafting minigames generate completely customized random stats (like dynamic RPG rolls for Strength, Agility, or custom suffixes), we cannot stack these items in database rows. With thousands of players crafting daily, storing unique stat blocks for every item will cause massive database bloat and slow query performances.

Decision

Implement a Rigid Quality Tiering System. Items are defined in the database solely by their Base ID and a Quality Level (e.g. {"item_id": 101, "quality": "Epic"}). The quality multiplier (+15% damage/armor, etc.) is a flat value calculated by the game client at runtime. Minigame performance only affects the probability roll of obtaining a higher Quality Tier.

Consequences

  • Pros:
    • Massively optimized database: items remain stackable in user inventory tables.
    • Highly secure: prevents client-side custom stat injection hacks.
  • Cons:
    • Limits item variety slightly compared to traditional “looters” with completely randomized stat affixes.

📌 ADR-013: Serialized Legendary Artifacts for Prestige Tracking

Status

Approved

Context

Players want truly unique, collectible items that feel like massive community achievements. However, we cannot allow unlimited custom items without overloading the database.

Decision

Introduce a curated pool of Legendary Artifacts that are assigned a Unique Serial Number upon successful crafting/drop (e.g., *Shadow Reaper 003). These items are tracked in a dedicated lightweight database table and displayed on a public web registry/leaderboard to show ownership.

Consequences

  • Pros:
    • Creates high-prestige goals and community tracking.
    • Minimal database impact because the number of artifacts generated globally is strictly throttled by rarity.
  • Cons:
    • Requires writing logic for unique serial number generation and verification on the server.

📌 ADR-014: Silent Anti-Cheat Flagging & Brittle Item Break Sinks

Status

Approved

Context

Autoclickers and timing macros are difficult to fully prevent on standalone clients. Directly blocking players who cheat triggers them to build better macros. Furthermore, the game needs a sink to remove surplus weapons and items from circulation to prevent inflation.

Decision

  1. Ghost Nerfing: When the server detects automated click behavior, it silently flags the crafted item in the database (is_hacked = true). The item looks normal to the player, but hiddenly suffers from severe debuffs (misses 50% more, deals minimum damage, shatters extremely fast).
  2. Brittle Break Sinks: Instead of writing item durability ticks (e.g. 98/100) to the database on every hit (which spikes database write traffic), we implement probability-based shattering. Every combat action carries a tiny chance to shatter the item (0.05% for normal gear, 10% for hacked gear), deleting the item and driving continuous resource consumption.

Consequences

  • Pros:
    • Discourages botting subtly: botters waste resources producing brittle, useless weapons.
    • Massively reduces database write operations by removing durability counters.
    • Provides a healthy, continuous resource sink for the economy.
  • Cons:
    • Shattering gear might frustrate some casual players; break rates must be carefully balanced.

📌 ADR-015: Standalone Premium Client Content Scope

Status

Pending Refinement / Future Idea

Context

To make the Standalone Client a viable commercial product, it needs unique content that keeps solo players engaged. We need to define this scope, though the exact implementation details remain open for adjustment.

Decision

Log the following proposed standalone content features for post-MVP iteration:

  1. Personal Estates: Offline player-owned bases/housing that can be customized using the game’s visual prop pools.
  2. Solo Dungeons (2D Side-Scrolling Adventure): Active combat levels where players fight monsters, complete quests, and harvest exclusive materials needed for high-level artifact crafting.
  3. Player Auction House: A centralized market where players can buy and sell refined resources or high-quality gear.

Consequences

  • Pros:
    • Establishes a concrete target for premium content.
    • Keeps the core scope focused on the Twitch overlay MVP first.
  • Cons:
    • Content details are not fully finalized; features may pivot during early alpha testing.

📌 ADR-016: 30-Day Rolling Viewership Bracket for Base Costs

Status

Approved

Context

Streamer room upgrades must scale in cost according to channel size to keep progression balanced for both small and large streamers. However, scaling dynamically by current live stream viewer counts can be exploited by starting streams at 0 viewers or streaming privately. Furthermore, Twitch’s public Helix API does not provide a direct endpoint to query historical average viewership statistics without high-privilege broadcaster analytics tokens.

Decision

Calculate the 30-day rolling average viewership internally on the Master Server:

  1. While a streamer is actively running the Godot overlay, the Master Server polls the Twitch Helix API GET /streams?user_id=... endpoint once every 10 minutes.
  2. The server only stores the viewer_count snapshot in the database if the stream is actively live on Twitch (the API returns an active stream object). Offline sessions (e.g. layout testing, room setup off-stream) are completely ignored.
  3. Every week, the Master Server aggregates these live-only snapshots to calculate the rolling 30-day average and updates the streamer’s cost tier (1.0x to 10.0x cost multiplier).
  4. Data Pruning: During the weekly average calculation, the Master Server automatically deletes all snapshot logs older than 30 days. Only the active 30-day window is saved in the database to prevent “data trash” accumulation.
  5. First-Week Cold Start: For new accounts, the server performs a Follower-Based Estimate by querying the channel’s total followers via GET /channels/followers. Followers map to starting cost brackets (e.g. followers = 1.0x, followers = 10.0x). After 7 days of live log data (or 10 hours of active stream time), the server transitions the streamer to their actual viewership-based average.

Consequences

  • Pros:
    • Extremely stable; completely immune to short-term viewer manipulation or start/stop exploits.
    • Offline setup/testing sessions run by the streamer do not drag down their calculated average viewership.
    • Follower estimate prevents large streamers’ chats from building out max-tier bases instantly in their first week.
    • Keeps database clean and lean by automatically purging expired snapshot records.
    • Requires only public/app Twitch access tokens, keeping integration low friction.
    • Keeps base costs balanced and fair for different channel sizes.
  • Cons:
    • Requires maintaining a stream session logging table and running weekly aggregation jobs on the server.
    • Follower count isn’t always perfectly correlated to live viewership (e.g., dead accounts or botted followers), but it is a reliable enough initial filter for a 7-day cold start.

📌 ADR-017: Active & Passive Item Sinks (Upkeep, Feasts, Traps)

Status

Approved

Context

If active crafting and gathering have short cooldowns, the economy will flood with surplus items and raw materials, leading to severe resource inflation. We need continuous sinks that drain resources from circulation.

Decision

Implement four distinct item sinks:

  1. Room Upkeep: Rooms consume a weekly maintenance package (e.g. planks, food) to keep their passive buffs active.
  2. Tavern Feasts: Viewers can pool thousands of food/beer items to trigger a channel-wide feast event, buffing all participants.
  3. Combat Traps: Viewers can build consumable defenses (barricades, traps) in real-time by spending raw resources during combat waves.
  4. Blacksmith Salvaging: Viewers can melt down excess equipment back into 30% of its base refined metal cost.

Consequences

  • Pros:
    • Natural depletion of raw and finished resources.
    • Encourages continuous participation and teamwork.
    • No need for long, boring crafting cooldown timers.
  • Cons:
    • Forcing weekly upkeep can feel like a chore if maintenance rates are tuned too high.

📌 ADR-018: C# (ASP.NET Core) for Server Backend to Enable Code Sharing

Status

Approved

Context

Developing the game’s client overlay and standalone spectator client in Godot requires implementing logic for character statistics, damage calculations, equipment weights, and data structure models. If the server is written in Node.js/Go and the client in C#, we must maintain duplicate codebases for shared math formulas and network structures, which increases maintenance and double-coding risks.

Decision

Implement the Master Server using C# and ASP.NET Core (with SignalR for real-time WebSockets communication).

Consequences

  • Pros:
    • Shared Libraries: We can write a single C# library containing data models, network packets, math formulas (e.g. weight intervals, mitigation percentages), and class definitions. This library is imported by both the ASP.NET Core backend and the Godot C# client.
    • Type-safe communication and 100% logic alignment between client and server.
    • SignalR offers robust, built-in WebSocket channel pooling and fallback mechanisms.
  • Cons:
    • ASP.NET Core can have a slightly larger memory footprint than lightweight Go binaries (negligible on a modern root server).

📌 ADR-019: Resource Depletion vs. Combat XP Scaling (Small vs. Big Stream Synergy)

Status

Approved

Context

If all players cluster in the channels of a few massive streamers, small streamers will get no overlay activity, and the global cross-stream economy will inflate rapidly. We need a mechanic that organically spreads viewers across the Twitch directory.

Decision

Implement opposing economic forces for gathering vs. combat:

  1. Resource Depletion (Small Stream Focus): The individual gathering yield on a stream decreases as the number of active, non-sleeping gatherers on that screen increases.
  2. Combat XP Scaling (Large Stream Focus): Large streams trigger larger wave compositions (Elites, Champions) and grant a “Group Morale” XP bonus based on the number of active defenders.

Consequences

  • Pros:
    • Organic Directory Flow: Viewers will seek out small, quiet streams to farm raw materials quickly, while returning to large streams to level up and engage in epic battles.
    • Helps boost smaller creators by driving viewer traffic to their channels.
  • Cons:
    • Requires monitoring active gatherer counts per stream session in memory on the server to apply the yield modifier.