Files
dota_factory/docs/requirements.md

167 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Requirements
## Config Files
The following config files drive game parameters:
- **world.config** — world dimensions, region widths, expansion amounts, building refund percentage, wave timing, enemy ship level formula.
- **buildings.config** — building block cost per building type.
- **recipes.config** — crafting recipes: inputs, outputs, quantities, durations, and reprocessing plant probabilities.
- **ships.config** — ship stats (HP, speed, damage, attack range, attack rate) as formulas of ship level, required materials per blueprint, threat cost formula, and whether each blueprint is available from the start or unlocked via loot.
- **stations.config** — HP, damage, range, and fire rate for player and enemy defence stations.
## Game World
- REQ-GW-TILE-SIZE: Tiles are 20×20 pixels. Items on belts are 10×10 pixels (half a tile), so each belt tile holds at most 2 items.
- REQ-GW-HEIGHT: The world height (in tiles) is read from world.config.
- REQ-GW-REGIONS: The world is divided into horizontal regions whose widths (in tiles) are all read from world.config:
- **Asteroid** — the player's build area.
- **Player buffer zone** — space between the asteroid and the player's defence stations.
- **Contest zone** — space between the player's and enemy's defence stations. This is where combat happens.
- **Enemy buffer zone** — space between the enemy's defence stations and the enemy spawn boundary.
- REQ-GW-SCROLL-LIMIT: The player can scroll the view horizontally from the asteroid's left edge to the current set of enemy defence stations (the enemy buffer zone is not visible).
- REQ-GW-PUSH-EXPAND: When the player destroys a set of enemy defence stations, the scrollable area is extended by a configurable number of tiles (world.config). A new enemy buffer zone of the same configurable width is added beyond the new enemy defence stations.
- REQ-GW-ASTEROID-EXPAND: When the player unlocks an asteroid expansion, a configurable number of tile columns (world.config) is added to the left of the asteroid.
## HQ & Game Over
- REQ-HQ-PLACEMENT: The HQ is pre-placed at the asteroid's right edge at game start.
- REQ-HQ-BELT-INPUT: The HQ has a belt input port. Building blocks delivered to it are added to the global building blocks stock.
- REQ-HQ-STATS: HQ stats (HP) are read from stations.config.
- REQ-HQ-GAME-OVER: If the HQ is destroyed, the game ends and the final survival time is shown.
- REQ-HQ-INVULNERABLE: Factory buildings (other than the HQ) are never targeted or destroyed by enemies.
## Building Placement & Management
- REQ-BLD-COST: The player places buildings from a build menu. Placement costs building blocks from the global stock. The cost per building type is read from buildings.config.
- REQ-BLD-QUEUE: Placed buildings enter a construction queue and are built one at a time. Each building takes a duration defined in recipes.config to construct.
- REQ-BLD-ASTEROID-ONLY: Buildings can only be placed on asteroid tiles.
- REQ-BLD-SHIPYARD-EDGE: Shipyards must be placed at the asteroid's right edge.
- REQ-BLD-BUILDER-MODE: Clicking a build button activates builder mode for that building type. Builder mode is exited by pressing Escape, right-clicking in the game world, or clicking the same build button again.
- REQ-BLD-GHOST: While in builder mode, a ghost of the building is rendered at the tile under the cursor, showing where it would be placed.
- REQ-BLD-ROTATE: While in builder mode, pressing E rotates the ghost 90° clockwise and Q rotates it 90° counter-clockwise. Rotation affects the direction of the output port.
- REQ-BLD-PLACE: Clicking a valid tile in builder mode places a construction site and adds it to the build queue, consuming building blocks from the global stock.
- REQ-BLD-BELT-DRAG: For belts, the player can click and drag across multiple tiles to place a construction site on each tile in one gesture.
- REQ-BLD-DEMOLISH: The player can demolish a placed building. Demolition returns a configurable percentage of the original building block cost (default 75%) to the global stock. The refund percentage is read from world.config.
## Building Types
- REQ-BLD-MINER: **Miner** (2×2): The player selects which ore type it extracts. Produces ore at a rate defined in recipes.config. Ore never depletes.
- REQ-BLD-SMELTER: **Smelter** (2×2): Converts ore or scrap into basic materials. No recipe selection required. Inputs, outputs, and rates are defined in recipes.config.
- REQ-BLD-ASSEMBLER: **Assembler** (3×3): The player selects a recipe from the config-defined crafting tree. Produces the selected output item at the rate defined in recipes.config.
- REQ-BLD-REPROCESSING: **Reprocessing Plant** (3×3): Consumes scrap per cycle (quantity from recipes.config) and produces higher-level intermediate products. Each product type has a fixed drop probability per cycle, defined in recipes.config.
- REQ-BLD-SHIPYARD: **Shipyard** (4×2): The player selects a blueprint. Automatically produces one ship of that type at a fixed level (defined in ships.config, default: 5) whenever all required materials are present in its input buffer. Ship material requirements are defined in ships.config.
- REQ-BLD-SALVAGE-BAY: **Salvage Bay** (3×2): A dedicated drop-off point for salvage ships. Scrap delivered here is placed onto connected output belts.
- REQ-BLD-BELT: **Belt** (1×1): Transports items. Available in straight and curved variants.
- REQ-BLD-SPLITTER: **Splitter** (1×1): Distributes incoming items between two output directions. Each output can optionally have a filter (a list of item types), configurable via the selected building panel. Routing rules:
- An item matching only one output's filter is routed to that output.
- An item matching both outputs' filters is distributed by strict alternation between those outputs.
- An item matching neither output's filter is routed to the unfiltered output. If both outputs have a filter and the item matches neither, the splitter stalls and moves no items until the situation is resolved.
- If neither output has a filter, items are distributed by strict alternation.
- In all alternation cases, if one output is blocked the item goes to the other output until it unblocks.
## Material Transport & Buffers
- REQ-MAT-BELT-ONLY: Materials are transported exclusively via belts and splitters.
- REQ-MAT-INPUT-PORTS: A building accepts items from all adjacent belt tiles whose direction points toward the building, provided the item is an input required by the currently selected recipe.
- REQ-MAT-OUTPUT-PORT: Each building has one fixed output port (direction determined by rotation). Produced items are placed onto the belt at the output port.
- REQ-MAT-INPUT-BUFFER: Each building's input buffer holds up to twice the quantity of each required input material for one production cycle. When the player selects a new recipe or blueprint, all items in the input buffer are cleared.
- REQ-MAT-OUTPUT-BUFFER: Each building has an output buffer that holds up to twice the quantity produced by one production cycle. If the output buffer is full, production stops until space is available.
- REQ-MAT-GLOBAL-STOCK: The building blocks stock is the only global inventory. All other materials exist only in building buffers or on belt tiles.
## Resources
- REQ-RES-ORE: Ore is extracted by miners and smelted into basic materials by smelters.
- REQ-RES-SCRAP-DROP: Destroyed ships (both player and enemy) and destroyed defence stations (both player and enemy) drop scrap at their location. The scrap amount per unit is defined in ships.config and stations.config respectively. Scrap despawns after a configurable duration (world.config) if not collected.
- REQ-RES-SCRAP-COLLECT: Scrap is collected by salvage ships and delivered to a Salvage Bay on the asteroid. From there it can be fed via belt into a smelter (same output as ore) or a Reprocessing Plant.
- REQ-RES-BUILDING-BLOCKS: Building blocks are produced by an assembler recipe and are the only globally pooled resource. They are added to the global stock when delivered to the HQ via belt.
- REQ-RES-CONFIG: All recipes, production rates, and reprocessing probabilities are defined in recipes.config.
## Ships
- REQ-SHP-AUTONOMOUS: Ships are produced by shipyards and are fully autonomous once produced.
- REQ-SHP-STATS: All ship stats (HP, speed, damage, attack range, attack rate) are defined as formulas of ship level in ships.config. Required build materials and whether each blueprint is available from game start or must be unlocked are also defined there.
- REQ-SHP-NO-COLLISION: Ships move independently with no collision between them.
- REQ-SHP-COMBAT: **Combat ships** — move right through space and engage enemy ships. The player can configure the following per shipyard (applied to all ships produced by that shipyard):
- Stance: aggressive (advance toward enemies) / defensive (hold position near asteroid).
- Target priority: closest / highest HP / structures first.
- REQ-SHP-SALVAGE: **Salvage ships** — move to the location of destroyed enemy ships, collect scrap, and deliver it to a Salvage Bay on the asteroid. Vulnerable to enemy ships while operating.
- REQ-SHP-REPAIR: **Repair ships** — move to damaged player defence stations or player ships and repair them. The player can configure the target priority per shipyard:
- Defence stations first / ships first / nearest target.
- REQ-SHP-BLUEPRINTS: The player selects a blueprint per shipyard by clicking it. New blueprints are unlocked as loot from destroyed enemy defence stations.
## Defence Stations
- REQ-DEF-PLAYER-PLACEMENT: 2 player defence stations are pre-placed in space at the start. Their positions are determined by the world region widths in world.config.
- REQ-DEF-PLAYER-FIRE: Player defence stations automatically fire at approaching enemy ships. Stats are read from stations.config.
- REQ-DEF-PLAYER-DESTRUCTIBLE: Player defence stations can be destroyed by enemies and repaired by repair ships.
- REQ-DEF-ENEMY-PLACEMENT: 2 enemy defence stations are placed at the right boundary of the scrollable area at game start, and again each time a new set is spawned after a push. Stats scale with the station generation (REQ-PSH-STATION-STATS).
- REQ-DEF-ENEMY-FIRE: Enemy defence stations automatically fire at player ships within range.
- REQ-DEF-NO-CROSSFIRE: Enemy and player defence stations are never in each other's firing range.
- REQ-DEF-PUSH: When both enemy defence stations in a set are destroyed, the push scaling multiplier is applied (REQ-PSH-ACCUMULATION), the scrollable area is extended (REQ-GW-PUSH-EXPAND), and a new set of enemy defence stations is placed at the new boundary. The destroyed stations drop ship blueprint loot.
## Threat Level & Enemy Waves
- REQ-WAV-THREAT-RATE: A global **threat level** accumulates continuously over time. The rate of increase per second is determined by a formula read from world.config where the input is elapsed game time in seconds. Example: `1*t - 30` gives 0 threat/s at t=30s and increases linearly after that.
- REQ-WAV-GAP: At game start and immediately after each wave is triggered, a random inter-wave gap is drawn uniformly from a configurable [min, max] range (world.config, in seconds).
- REQ-WAV-TRIGGER: When the gap expires, a wave is triggered. Ships are spawned using the accumulated threat level. Any threat not spent on ships carries over to the next wave. A longer gap results in a larger wave.
- REQ-WAV-SHIP-LEVEL: Each wave's enemy ships are assigned a level determined by a formula of elapsed game time in seconds (t), read from world.config. This is the sole mechanism by which enemy waves grow stronger over time.
- REQ-WAV-THREAT-COST: Ships are spawned until the accumulated threat is exhausted. Each ship type has a threat cost defined as a formula of ship level in ships.config. Because enemy ship level increases with time, threat cost per ship rises naturally over the course of the game.
- REQ-WAV-SPAWN-DURATION: Ships in a wave are spawned one at a time over the spawn duration. Spawning duration is read from world.config.
- REQ-WAV-SHIP-STATS: Per-ship stats (damage, attack rate, range, speed) and threat cost are each defined as formulas of ship level in ships.config.
- REQ-WAV-GRACE-PERIOD: The grace period before the first wave is implicit: threat accumulates from t=0 but the first wave does not trigger until the initial gap (drawn at game start) has elapsed.
## Push Scaling
- REQ-PSH-ACCUMULATION: Each time the player destroys a set of enemy defence stations, a configurable push scaling factor (world.config) is multiplied permanently into the threat level accumulation rate. This causes all subsequent waves to be larger.
- REQ-PSH-STATION-STATS: Enemy defence station stats (HP, damage, range, fire rate) are each defined as formulas in stations.config where x is the station generation — an integer starting at 0 for the initial set and incrementing by 1 each time a new set is placed.
- REQ-PSH-STACKING: Push scaling factors stack multiplicatively with each other and with the time-based threat formula.
## Asteroid Expansion
- REQ-EXP-UNLOCK: The player can unlock additional asteroid tile columns to the left of the existing asteroid by spending building blocks from the global stock.
- REQ-EXP-COST: Each expansion adds a configurable number of columns (world.config) and costs a configurable amount of building blocks (world.config).
## UI
### Layout
The screen is divided into three vertical sections:
```
+--------------------------------------------------+
| Header Bar |
+--------------------------------------------------+
| |
| Game World (70%) |
| |
+-------------------------+------------------------+
| Selected Building Panel | Build Button Grid |
| (left) | (right) |
+-------------------------+------------------------+
```
- REQ-UI-HEADER: The header bar spans the full width above the game world and always shows the elapsed survival time and the current global building blocks stock on the left, and game speed controls on the right.
- REQ-UI-SPEED: The game speed controls in the header bar are buttons for 0×, 0.5×, 1×, 2×, and 4× speed. The currently active speed is shown as selected. All game simulation (production, movement, threat accumulation, wave timing) scales with the selected speed. 0× pauses the game.
- REQ-UI-WORLD-HEIGHT: The game world view occupies 70% of the remaining screen height below the header bar.
- REQ-UI-PANEL-HEIGHT: The UI panel occupies the remaining 30% of the screen height, split horizontally into a selected building panel (left) and a build button grid (right).
### Game World
- REQ-UI-SCROLL: The player scrolls the view horizontally across the scrollable area by pressing A (scroll left) and D (scroll right).
### Selected Building Panel
- REQ-UI-EMPTY-SELECTION: When no building is selected, the panel is empty.
- REQ-UI-SINGLE-SELECTION: When one building is selected, the panel shows: building name, current recipe or blueprint selection, input buffer contents, and output buffer contents.
- REQ-UI-MULTI-SELECT: The player selects multiple buildings by box-drag or by Ctrl+clicking individual buildings to add or remove them from the selection.
- REQ-UI-MULTI-SELECTION: When multiple buildings are selected, the panel shows how many of each building type are selected. No per-building detail is shown.
- REQ-UI-CONFIG-INLINE: Recipe, blueprint, ship stance, and target priority configuration for a selected building is shown and changed inline within this panel.
- REQ-UI-BELT-CLEAR: When one or more belt or splitter tiles are selected, the panel shows a "Clear" button that removes all items from the selected tiles. This can be used to resolve stalled belts and splitters.
### Build Button Grid
- REQ-UI-BUILD-GRID: All placeable building types are shown as a flat grid of buttons with no grouping.
- REQ-UI-BUILD-COST: Each button caption shows the building name and its building block cost, e.g. "Belt: 2 Blocks".
- REQ-UI-BUILD-DISABLED: Buttons for buildings the player cannot currently afford are shown as disabled.