phase 9: biome expansion — 3 biomes, 40 elements, 119 reactions, 9 species

Expand beyond vertical slice with two new biomes and massive chemistry expansion:

Chemistry: +20 real elements (Li→U), +39 compounds (acids/salts/oxides/organics),
+85 reactions (Haber process, thermite variants, smelting, fermentation, etc.)

Biomes: Kinetic Mountains (physics/mechanics themed) and Verdant Forests
(biology/ecology themed), each with 8 tile types and unique generation rules.

Creatures: 6 new species — Pendulums/Mechanoids/Resonators (mountains),
Symbiotes/Mimics/Spore-bearers (forests). Species filtered by biome.

Infrastructure: CradleScene biome selector UI, generic world generator
(tile lookup by property instead of hardcoded names), actinide element category.

487 tests passing (32 new).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Денис Шкабатур
2026-02-12 17:27:15 +03:00
parent 3c24205e72
commit 6ba0746bb9
16 changed files with 2176 additions and 39 deletions

View File

@@ -238,7 +238,7 @@
| Фаза | Содержание | | Фаза | Содержание |
|-------|-----------| |-------|-----------|
| Phase 9 | +2 биома (Кинетические Горы, Вердантовые Леса), +20 элементов, +100 реакций | | Phase 9 | +2 биома (Кинетические Горы, Вердантовые Леса), +20 элементов, +100 реакций |
| Phase 10 | +3 школы (Механик, Натуралист, Навигатор), принципы физики и биологии | | Phase 10 | +3 школы (Механик, Натуралист, Навигатор), принципы физики и биологии |
| Phase 11 | Великий цикл (7 ранов): следы между ранами, Великое Обновление | | Phase 11 | Великий цикл (7 ранов): следы между ранами, Великое Обновление |
| Phase 12 | +3 Архонта (Спора Прайма, Энтропа, Когнитон) | | Phase 12 | +3 Архонта (Спора Прайма, Энтропа, Когнитон) |

View File

@@ -1,7 +1,7 @@
# Synthesis — Development Progress # Synthesis — Development Progress
> **Last updated:** 2026-02-12 > **Last updated:** 2026-02-12
> **Current phase:** Phase 8 ✅ → Vertical Slice Complete > **Current phase:** Phase 9 ✅ → Biome Expansion Complete
--- ---
@@ -111,15 +111,29 @@
- [x] Scene flow extended: GameScene → BossArenaScene → DeathScene (on death or victory) - [x] Scene flow extended: GameScene → BossArenaScene → DeathScene (on death or victory)
- [x] Unit tests — 70 passing (`tests/boss.test.ts`) (455 total) - [x] Unit tests — 70 passing (`tests/boss.test.ts`) (455 total)
### Phase 9: Biome Expansion ✅
- [x] 9.1 New elements — 20 additional real elements (Li, B, F, Ne, Ar, Ti, Cr, Mn, Co, Ni, As, Br, Ag, I, Ba, W, Pt, Pb, Bi, U) → 40 total
- [x] 9.2 New compounds — 39 new compounds (acids, salts, oxides, organics) → 64 total
- [x] 9.3 New reactions — 85 new reactions (synthesis, combustion, acid-base, redox, decomposition, replacement) → 119 total
- [x] 9.4 Kinetic Mountains biome — physics/mechanics themed: chasms, gear floors, magnetic fields, steam vents, ore deposits
- [x] 9.5 Verdant Forests biome — biology/ecology themed: bogs, toxic blooms, ancient trees, mycelium carpet, herb patches
- [x] 9.6 Biome selection — CradleScene biome picker UI, biomeId passed to GameScene, generic world generator
- [x] 9.7 New creatures — 6 species: Pendulums/Mechanoids/Resonators (mountains), Symbiotes/Mimics/Spore-bearers (forests)
- [x] 9.8 World generator genericized — tile lookup by property (interactive/resource) instead of hardcoded names
- [x] Chemistry types extended — `actinide` element category for Uranium
- [x] Species types extended — `biome` field, `SpeciesId` enum expanded (08)
- [x] GameScene filters creatures by selected biome
- [x] Unit tests — 32 new tests (487 total)
--- ---
## In Progress ## In Progress
_None — Vertical Slice (Phase 08) complete_ _None — Phase 9 complete_
--- ---
## Up Next: Post-MVP (Phase 9+) ## Up Next: Phase 10+
_(See IMPLEMENTATION-PLAN.md for Beyond Vertical Slice)_ _(See IMPLEMENTATION-PLAN.md for Beyond Vertical Slice)_
@@ -144,3 +158,4 @@ None
| 7 | 2026-02-12 | Phase 6 | Run Cycle: full roguelike loop (Cradle→Game→Death→Fractal→Cradle), school selection (Alchemist), meta-progression (Codex/spores/IndexedDB), run phases with auto-advance, escalation effects (creature aggression/env damage), Chemical Plague crisis with neutralization, death animation (real body composition), WebGL fractal shader, 56 new tests (349 total) | | 7 | 2026-02-12 | Phase 6 | Run Cycle: full roguelike loop (Cradle→Game→Death→Fractal→Cradle), school selection (Alchemist), meta-progression (Codex/spores/IndexedDB), run phases with auto-advance, escalation effects (creature aggression/env damage), Chemical Plague crisis with neutralization, death animation (real body composition), WebGL fractal shader, 56 new tests (349 total) |
| 8 | 2026-02-12 | Phase 7 | Mycelium: persistent knowledge graph (nodes/edges/strength), fungal node ECS entities with glow animation, knowledge deposit (auto on death + manual at nodes), memory flash extraction (weighted by strength, Russian templates), mycosis visual effect (tint overlay + reveal threshold), spore shop in Cradle (5 bonuses: health/elements/knowledge), MetaState+IndexedDB persistence updated, GameScene+CradleScene integration, 36 new tests (385 total) | | 8 | 2026-02-12 | Phase 7 | Mycelium: persistent knowledge graph (nodes/edges/strength), fungal node ECS entities with glow animation, knowledge deposit (auto on death + manual at nodes), memory flash extraction (weighted by strength, Russian templates), mycosis visual effect (tint overlay + reveal threshold), spore shop in Cradle (5 bonuses: health/elements/knowledge), MetaState+IndexedDB persistence updated, GameScene+CradleScene integration, 36 new tests (385 total) |
| 9 | 2026-02-12 | Phase 8 | Ouroboros boss fight: 4-phase cyclical AI (Coil/Spray/Lash/Digest) with escalating difficulty, 3 chemistry-based victory paths (NaOH neutralization, direct damage, Hg catalyst poison), circular arena generator, BossArenaScene with attacks+collision+UI, Archont's Memory lore reward, CodexEntry extended, GameScene Resolution→arena trigger, 70 new tests (455 total) | | 9 | 2026-02-12 | Phase 8 | Ouroboros boss fight: 4-phase cyclical AI (Coil/Spray/Lash/Digest) with escalating difficulty, 3 chemistry-based victory paths (NaOH neutralization, direct damage, Hg catalyst poison), circular arena generator, BossArenaScene with attacks+collision+UI, Archont's Memory lore reward, CodexEntry extended, GameScene Resolution→arena trigger, 70 new tests (455 total) |
| 10 | 2026-02-12 | Phase 9 | Biome expansion: +20 elements (40 total), +39 compounds (64 total), +85 reactions (119 total), 2 new biomes (Kinetic Mountains + Verdant Forests), biome selection in CradleScene, 6 new creature species (3 per new biome), generic world generator, 32 new tests (487 total) |

View File

@@ -8,7 +8,8 @@ export type ElementCategory =
| 'metalloid' | 'metalloid'
| 'nonmetal' | 'nonmetal'
| 'halogen' | 'halogen'
| 'noble-gas'; | 'noble-gas'
| 'actinide';
export type MatterState = 'solid' | 'liquid' | 'gas'; export type MatterState = 'solid' | 'liquid' | 'gas';

View File

@@ -1,10 +1,9 @@
/** /**
* Creature Types — data definitions for the creature/ecology system * Creature Types — data definitions for the creature/ecology system
* *
* Three species in Catalytic Wastes: * Catalytic Wastes: Crystallids, Acidophiles, Reagents
* - Crystallids: slow, sturdy, eat minerals, excrete silicon * Kinetic Mountains: Pendulums, Mechanoids, Resonators
* - Acidophiles: medium speed, eat minerals, excrete acid * Verdant Forests: Symbiotes, Mimics, Spore-bearers
* - Reagents: fast, paired, predatory, explosive
*/ */
/** Species identifier (stored as numeric ID in ECS components) */ /** Species identifier (stored as numeric ID in ECS components) */
@@ -12,6 +11,12 @@ export enum SpeciesId {
Crystallid = 0, Crystallid = 0,
Acidophile = 1, Acidophile = 1,
Reagent = 2, Reagent = 2,
Pendulum = 3,
Mechanoid = 4,
Resonator = 5,
Symbiote = 6,
Mimic = 7,
SporeBearer = 8,
} }
/** AI behavior state (FSM) */ /** AI behavior state (FSM) */
@@ -40,6 +45,7 @@ export interface SpeciesData {
name: string; name: string;
nameRu: string; nameRu: string;
speciesId: SpeciesId; speciesId: SpeciesId;
biome: string; // biome id this species belongs to
description: string; description: string;
descriptionRu: string; descriptionRu: string;

View File

@@ -34,5 +34,77 @@
"geyserOnTile": 4, "geyserOnTile": 4,
"mineralOnTiles": [0, 1, 2] "mineralOnTiles": [0, 1, 2]
} }
},
{
"id": "kinetic-mountains",
"name": "Kinetic Mountains",
"nameRu": "Кинетические Горы",
"description": "Towering cliffs embedded with ancient gears and pendulums. Anomalous gravity zones, avalanche-prone slopes, and whirring mechanical ruins.",
"descriptionRu": "Высокие скалы с вросшими древними шестернями и маятниками. Зоны аномальной гравитации, лавиноопасные склоны и гудящие механические руины.",
"tileSize": 32,
"mapWidth": 80,
"mapHeight": 80,
"tiles": [
{ "id": 0, "name": "bare-rock", "nameRu": "Голый камень", "color": "#5a5a5a", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 1, "name": "gravel-slope", "nameRu": "Гравийный склон", "color": "#7a7a6e", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 2, "name": "iron-ridge", "nameRu": "Железный хребет", "color": "#4a3a2a", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 3, "name": "chasm", "nameRu": "Пропасть", "color": "#0a0a1a", "walkable": false, "damage": 15, "interactive": false, "resource": false },
{ "id": 4, "name": "gear-floor", "nameRu": "Шестерёночный пол", "color": "#8b7355", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 5, "name": "magnetic-field", "nameRu": "Магнитное поле", "color": "#3344aa", "walkable": true, "damage": 2, "interactive": false, "resource": false },
{ "id": 6, "name": "steam-vent", "nameRu": "Паровой клапан", "color": "#cccccc", "walkable": false, "damage": 0, "interactive": true, "resource": false },
{ "id": 7, "name": "ore-deposit", "nameRu": "Рудное месторождение", "color": "#b87333", "walkable": true, "damage": 0, "interactive": false, "resource": true }
],
"generation": {
"elevationScale": 0.05,
"detailScale": 0.18,
"elevationRules": [
{ "below": 0.15, "tileId": 3 },
{ "below": 0.25, "tileId": 5 },
{ "below": 0.50, "tileId": 0 },
{ "below": 0.68, "tileId": 1 },
{ "below": 0.82, "tileId": 2 },
{ "below": 1.00, "tileId": 4 }
],
"geyserThreshold": 0.92,
"mineralThreshold": 0.88,
"geyserOnTile": 5,
"mineralOnTiles": [0, 1, 2]
}
},
{
"id": "verdant-forests",
"name": "Verdant Forests",
"nameRu": "Вердантовые Леса",
"description": "A multi-layered living forest teeming with biodiversity. Underground mycorrhizal networks, towering canopies, and bioluminescent clearings.",
"descriptionRu": "Многоярусный живой лес, кишащий биоразнообразием. Подземные микоризные сети, высочайшие кроны и биолюминесцентные поляны.",
"tileSize": 32,
"mapWidth": 80,
"mapHeight": 80,
"tiles": [
{ "id": 0, "name": "forest-floor", "nameRu": "Лесная подстилка", "color": "#1a3a0e", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 1, "name": "dense-undergrowth", "nameRu": "Густой подлесок", "color": "#0d2b06", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 2, "name": "mycelium-carpet", "nameRu": "Мицелиевый ковёр", "color": "#4a2a5a", "walkable": true, "damage": 0, "interactive": false, "resource": false },
{ "id": 3, "name": "bog", "nameRu": "Трясина", "color": "#2a4a1a", "walkable": true, "damage": 4, "interactive": false, "resource": false },
{ "id": 4, "name": "toxic-bloom", "nameRu": "Ядовитый цвет", "color": "#9a3a6a", "walkable": false, "damage": 8, "interactive": false, "resource": false },
{ "id": 5, "name": "ancient-tree", "nameRu": "Древо-Великан", "color": "#1a2a0a", "walkable": false, "damage": 0, "interactive": false, "resource": false },
{ "id": 6, "name": "hollow-stump", "nameRu": "Полый пень", "color": "#5a4a2a", "walkable": true, "damage": 0, "interactive": true, "resource": false },
{ "id": 7, "name": "herb-patch", "nameRu": "Лекарственная поляна", "color": "#2a6a1a", "walkable": true, "damage": 0, "interactive": false, "resource": true }
],
"generation": {
"elevationScale": 0.07,
"detailScale": 0.12,
"elevationRules": [
{ "below": 0.18, "tileId": 3 },
{ "below": 0.28, "tileId": 4 },
{ "below": 0.55, "tileId": 0 },
{ "below": 0.72, "tileId": 1 },
{ "below": 0.86, "tileId": 2 },
{ "below": 1.00, "tileId": 5 }
],
"geyserThreshold": 0.91,
"mineralThreshold": 0.87,
"geyserOnTile": 2,
"mineralOnTiles": [0, 1, 2]
}
} }
] ]

View File

@@ -198,5 +198,319 @@
"description": "Explosive mixture of saltpeter, sulfur, and charcoal. The discovery that changed civilizations.", "description": "Explosive mixture of saltpeter, sulfur, and charcoal. The discovery that changed civilizations.",
"descriptionRu": "Взрывчатая смесь селитры, серы и угля. Открытие, изменившее цивилизации.", "descriptionRu": "Взрывчатая смесь селитры, серы и угля. Открытие, изменившее цивилизации.",
"gameEffects": ["explosive", "propellant", "signal_flare"] "gameEffects": ["explosive", "propellant", "signal_flare"]
},
{
"id": "NH3", "formula": "NH₃", "name": "Ammonia", "nameRu": "Аммиак",
"mass": 17.031, "state": "gas", "color": "#aaccff",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Pungent gas. Key to fertilizer production (Haber process). Essential biological nitrogen carrier.",
"descriptionRu": "Едкий газ. Основа производства удобрений (процесс Габера). Важнейший биологический переносчик азота.",
"gameEffects": ["fertilizer", "cleaning", "refrigerant"]
},
{
"id": "HF", "formula": "HF", "name": "Hydrofluoric Acid", "nameRu": "Плавиковая кислота",
"mass": 20.006, "state": "liquid", "color": "#ccff66",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": true, "basic": false, "oxidizer": false, "corrosive": true },
"description": "Etches glass! One of the most dangerous acids — penetrates skin and attacks bones.",
"descriptionRu": "Растворяет стекло! Одна из опаснейших кислот — проникает через кожу и разрушает кости.",
"gameEffects": ["glass_etching", "damage", "dissolve_stone"]
},
{
"id": "HBr", "formula": "HBr", "name": "Hydrobromic Acid", "nameRu": "Бромоводородная кислота",
"mass": 80.912, "state": "liquid", "color": "#cc6633",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": true, "basic": false, "oxidizer": false, "corrosive": true },
"description": "Strong acid formed from hydrogen and bromine. Stronger than HCl.",
"descriptionRu": "Сильная кислота из водорода и брома. Сильнее соляной кислоты.",
"gameEffects": ["dissolve_metal", "damage"]
},
{
"id": "HI", "formula": "HI", "name": "Hydroiodic Acid", "nameRu": "Йодоводородная кислота",
"mass": 127.912, "state": "liquid", "color": "#993399",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": true, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Strongest of the hydrohalic acids. Powerful reducing agent.",
"descriptionRu": "Самая сильная из галогеноводородных кислот. Мощный восстановитель.",
"gameEffects": ["reducing_agent", "dissolve_metal"]
},
{
"id": "LiOH", "formula": "LiOH", "name": "Lithium Hydroxide", "nameRu": "Гидроксид лития",
"mass": 23.948, "state": "solid", "color": "#e8e8ff",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": true, "oxidizer": false, "corrosive": true },
"description": "Lightest alkali hydroxide. Used in spacecraft CO₂ scrubbers and lithium batteries.",
"descriptionRu": "Легчайший гидроксид щелочного металла. Используется для очистки воздуха на космических кораблях и в литиевых батареях.",
"gameEffects": ["co2_scrubber", "battery_material"]
},
{
"id": "LiCl", "formula": "LiCl", "name": "Lithium Chloride", "nameRu": "Хлорид лития",
"mass": 42.394, "state": "solid", "color": "#e0e0e0",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Extremely hygroscopic salt. Absorbs moisture from air. Used as desiccant.",
"descriptionRu": "Крайне гигроскопичная соль. Поглощает влагу из воздуха. Используется как осушитель.",
"gameEffects": ["desiccant", "dehumidifier"]
},
{
"id": "TiO2", "formula": "TiO₂", "name": "Titanium Dioxide", "nameRu": "Диоксид титана",
"mass": 79.866, "state": "solid", "color": "#ffffff",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Brilliant white pigment. UV blocker. Photocatalyst that breaks down pollutants in sunlight.",
"descriptionRu": "Ярко-белый пигмент. УФ-блокатор. Фотокатализатор, расщепляющий загрязнители на свету.",
"gameEffects": ["pigment", "sun_protection", "photocatalyst"]
},
{
"id": "Cr2O3", "formula": "Cr₂O₃", "name": "Chromium(III) Oxide", "nameRu": "Оксид хрома(III)",
"mass": 151.99, "state": "solid", "color": "#336633",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Deep green pigment. Extremely hard and heat-resistant. Used in armor and abrasives.",
"descriptionRu": "Насыщенный зелёный пигмент. Крайне твёрд и термостоек. Используется в броне и абразивах.",
"gameEffects": ["pigment", "armor_material", "abrasive"]
},
{
"id": "MnO2", "formula": "MnO₂", "name": "Manganese Dioxide", "nameRu": "Диоксид марганца",
"mass": 86.937, "state": "solid", "color": "#333333",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": true, "corrosive": false },
"description": "Natural catalyst and oxidizer. Key component of dry cell batteries. Accelerates many reactions.",
"descriptionRu": "Природный катализатор и окислитель. Ключевой компонент батареек. Ускоряет многие реакции.",
"gameEffects": ["catalyst", "battery_material", "oxidizer"]
},
{
"id": "CoO", "formula": "CoO", "name": "Cobalt(II) Oxide", "nameRu": "Оксид кобальта(II)",
"mass": 74.932, "state": "solid", "color": "#336699",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Deep blue compound. Used in pottery glazes since ancient Egypt. Magnetic.",
"descriptionRu": "Тёмно-синее соединение. Используется в керамических глазурях со времён Древнего Египта. Магнитно.",
"gameEffects": ["pigment", "magnetic"]
},
{
"id": "NiCl2", "formula": "NiCl₂", "name": "Nickel(II) Chloride", "nameRu": "Хлорид никеля(II)",
"mass": 129.60, "state": "solid", "color": "#00cc66",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Bright green salt. Key reagent in electroplating. Catalyst for organic reactions.",
"descriptionRu": "Ярко-зелёная соль. Ключевой реагент для гальванопокрытий. Катализатор органических реакций.",
"gameEffects": ["electroplating", "catalyst"]
},
{
"id": "As2O3", "formula": "As₂O₃", "name": "Arsenic Trioxide", "nameRu": "Оксид мышьяка(III)",
"mass": 197.841, "state": "solid", "color": "#f0f0f0",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "The 'King of Poisons'. Odorless, tasteless, lethal. Used as a rat poison for centuries.",
"descriptionRu": "«Король ядов». Без запаха, вкуса, смертелен. Веками использовался как крысиный яд.",
"gameEffects": ["deadly_poison", "rat_poison", "glass_clarifier"]
},
{
"id": "AgCl", "formula": "AgCl", "name": "Silver Chloride", "nameRu": "Хлорид серебра",
"mass": 143.321, "state": "solid", "color": "#e0e0e0",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "White solid that darkens in light (basis of photography). Antimicrobial wound dressing.",
"descriptionRu": "Белое вещество, темнеющее на свету (основа фотографии). Антимикробная раневая повязка.",
"gameEffects": ["photography", "antimicrobial", "light_sensor"]
},
{
"id": "BaO", "formula": "BaO", "name": "Barium Oxide", "nameRu": "Оксид бария",
"mass": 153.326, "state": "solid", "color": "#f5f5cc",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": true, "oxidizer": false, "corrosive": true },
"description": "Powerful desiccant and getter. Reacts violently with water. Produces green flame.",
"descriptionRu": "Мощный осушитель и геттер. Бурно реагирует с водой. Даёт зелёное пламя.",
"gameEffects": ["desiccant", "green_flame"]
},
{
"id": "WO3", "formula": "WO₃", "name": "Tungsten Trioxide", "nameRu": "Оксид вольфрама(VI)",
"mass": 231.84, "state": "solid", "color": "#cccc00",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Yellow powder. Electrochromic — changes color with voltage. Smart glass technology.",
"descriptionRu": "Жёлтый порошок. Электрохромный — меняет цвет при напряжении. Технология умного стекла.",
"gameEffects": ["smart_glass", "electrochromic", "pigment"]
},
{
"id": "PbO", "formula": "PbO", "name": "Lead(II) Oxide", "nameRu": "Оксид свинца(II)",
"mass": 223.2, "state": "solid", "color": "#cc9933",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Yellow-orange powder (litharge). Used in lead-acid batteries and ancient pottery glazes.",
"descriptionRu": "Жёлто-оранжевый порошок (глёт). Используется в свинцовых аккумуляторах и древних керамических глазурях.",
"gameEffects": ["battery_material", "pigment", "radiation_shield"]
},
{
"id": "PbS", "formula": "PbS", "name": "Lead(II) Sulfide", "nameRu": "Сульфид свинца (галенит)",
"mass": 239.27, "state": "solid", "color": "#333344",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Galena — the principal ore of lead. First semiconductor discovered. Used in early radio crystal detectors.",
"descriptionRu": "Галенит — основная руда свинца. Первый обнаруженный полупроводник. Применялся в ранних радиоприёмниках.",
"gameEffects": ["semiconductor", "radio_detector", "lead_source"]
},
{
"id": "Bi2O3", "formula": "Bi₂O₃", "name": "Bismuth Trioxide", "nameRu": "Оксид висмута(III)",
"mass": 465.959, "state": "solid", "color": "#ffffcc",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Yellow powder with medicinal properties. Active ingredient in stomach remedies. Low toxicity.",
"descriptionRu": "Жёлтый порошок с лечебными свойствами. Действующее вещество желудочных средств. Малотоксичен.",
"gameEffects": ["medicine", "stomach_remedy", "pigment"]
},
{
"id": "UO2", "formula": "UO₂", "name": "Uranium Dioxide", "nameRu": "Диоксид урана",
"mass": 270.028, "state": "solid", "color": "#333300",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Nuclear fuel. Incredibly dense. A single pellet contains energy equivalent to a tonne of coal.",
"descriptionRu": "Ядерное топливо. Невероятно плотный. Один стержень содержит энергию, эквивалентную тонне угля.",
"gameEffects": ["nuclear_fuel", "energy_source", "radiation"]
},
{
"id": "CH3COOH", "formula": "CH₃COOH", "name": "Acetic Acid", "nameRu": "Уксусная кислота",
"mass": 60.052, "state": "liquid", "color": "#eeeedd",
"properties": { "flammable": true, "toxic": false, "explosive": false, "acidic": true, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Vinegar. Natural product of fermentation. Solvent, preservative, and creature bait.",
"descriptionRu": "Уксус. Природный продукт брожения. Растворитель, консервант и приманка для существ.",
"gameEffects": ["solvent", "preservative", "creature_bait", "descaler"]
},
{
"id": "C6H12O6", "formula": "C₆H₁₂O₆", "name": "Glucose", "nameRu": "Глюкоза",
"mass": 180.156, "state": "solid", "color": "#ffffee",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Simple sugar. Universal biological fuel. Feed to microorganisms or use as fast energy source.",
"descriptionRu": "Простой сахар. Универсальное биологическое топливо. Корм для микроорганизмов или быстрый источник энергии.",
"gameEffects": ["energy_food", "microorganism_feed", "fermentation_base"]
},
{
"id": "H2S", "formula": "H₂S", "name": "Hydrogen Sulfide", "nameRu": "Сероводород",
"mass": 34.08, "state": "gas", "color": "#cccc66",
"properties": { "flammable": true, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Rotten egg smell. Toxic in high concentrations. Natural hot spring emission.",
"descriptionRu": "Запах тухлых яиц. Токсичен в высоких концентрациях. Газ горячих источников.",
"gameEffects": ["poison_gas", "indicator", "hot_spring"]
},
{
"id": "H2SO4", "formula": "H₂SO₄", "name": "Sulfuric Acid", "nameRu": "Серная кислота",
"mass": 98.079, "state": "liquid", "color": "#ffee00",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": true, "basic": false, "oxidizer": true, "corrosive": true },
"description": "King of chemicals. Most produced chemical worldwide. Violently exothermic with water.",
"descriptionRu": "Царь химикатов. Самое производимое химическое вещество в мире. Бурно реагирует с водой.",
"gameEffects": ["dissolve_metal", "dissolve_organic", "battery_acid", "damage"]
},
{
"id": "HNO3", "formula": "HNO₃", "name": "Nitric Acid", "nameRu": "Азотная кислота",
"mass": 63.012, "state": "liquid", "color": "#ff6600",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": true, "basic": false, "oxidizer": true, "corrosive": true },
"description": "Fuming corrosive acid. Dissolves most metals. Component of aqua regia (with HCl) to dissolve gold.",
"descriptionRu": "Дымящая кислота. Растворяет большинство металлов. Компонент царской водки (с HCl) для растворения золота.",
"gameEffects": ["dissolve_metal", "oxidizer", "damage", "aqua_regia_component"]
},
{
"id": "CuO", "formula": "CuO", "name": "Copper(II) Oxide", "nameRu": "Оксид меди(II)",
"mass": 79.545, "state": "solid", "color": "#1a1a1a",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Black powder. Reducible by carbon or hydrogen — ancient copper smelting.",
"descriptionRu": "Чёрный порошок. Восстанавливается углеродом или водородом — древняя медеплавка.",
"gameEffects": ["pigment", "smelting_ore", "catalyst"]
},
{
"id": "NaF", "formula": "NaF", "name": "Sodium Fluoride", "nameRu": "Фторид натрия",
"mass": 41.988, "state": "solid", "color": "#f0f0f0",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Active ingredient in toothpaste. Strengthens tooth enamel. Toxic in large doses.",
"descriptionRu": "Активный компонент зубной пасты. Укрепляет зубную эмаль. Токсичен в больших дозах.",
"gameEffects": ["dental_protection", "water_treatment"]
},
{
"id": "NaBr", "formula": "NaBr", "name": "Sodium Bromide", "nameRu": "Бромид натрия",
"mass": 102.894, "state": "solid", "color": "#e8e8e8",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "White crystalline salt. Historical sedative and anticonvulsant. Photography reagent.",
"descriptionRu": "Белая кристаллическая соль. Исторический седативный и противосудорожный препарат.",
"gameEffects": ["sedative", "photography"]
},
{
"id": "KF", "formula": "KF", "name": "Potassium Fluoride", "nameRu": "Фторид калия",
"mass": 58.097, "state": "solid", "color": "#e0e0e0",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": true },
"description": "Strong fluorinating agent. Used in organic synthesis. Corrosive.",
"descriptionRu": "Сильный фторирующий агент. Используется в органическом синтезе. Едкий.",
"gameEffects": ["fluorinating_agent"]
},
{
"id": "KBr", "formula": "KBr", "name": "Potassium Bromide", "nameRu": "Бромид калия",
"mass": 119.002, "state": "solid", "color": "#e0e0e0",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Photography essential. Historical anticonvulsant medicine. Transparent to infrared.",
"descriptionRu": "Необходим для фотографии. Исторический противосудорожный препарат. Прозрачен для инфракрасного.",
"gameEffects": ["photography", "medicine", "optics"]
},
{
"id": "AgBr", "formula": "AgBr", "name": "Silver Bromide", "nameRu": "Бромид серебра",
"mass": 187.772, "state": "solid", "color": "#e8e8cc",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Pale yellow, darkens in light. The basis of photographic film. More light-sensitive than AgCl.",
"descriptionRu": "Бледно-жёлтый, темнеет на свету. Основа фотоплёнки. Светочувствительнее AgCl.",
"gameEffects": ["photography", "light_sensor"]
},
{
"id": "NH4Cl", "formula": "NH₄Cl", "name": "Ammonium Chloride", "nameRu": "Хлорид аммония",
"mass": 53.491, "state": "solid", "color": "#f5f5f5",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Sal ammoniac. White smoke when heated. Used in batteries, flux, and cough medicine.",
"descriptionRu": "Нашатырь. Белый дым при нагревании. Используется в батарейках, флюсе и от кашля.",
"gameEffects": ["flux", "battery_material", "smoke_screen"]
},
{
"id": "MgCl2", "formula": "MgCl₂", "name": "Magnesium Chloride", "nameRu": "Хлорид магния",
"mass": 95.211, "state": "solid", "color": "#e0e0e0",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "De-icing salt. Dust suppressant. Source of magnesium metal via electrolysis.",
"descriptionRu": "Противогололёдная соль. Подавитель пыли. Источник металлического магния через электролиз.",
"gameEffects": ["de_icing", "dust_control", "magnesium_source"]
},
{
"id": "CaCl2", "formula": "CaCl₂", "name": "Calcium Chloride", "nameRu": "Хлорид кальция",
"mass": 110.984, "state": "solid", "color": "#f0f0f0",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Powerful desiccant and de-icer. Exothermic when dissolved — can melt ice below -50°C.",
"descriptionRu": "Мощный осушитель и антигололёдный реагент. Экзотермичен при растворении — плавит лёд ниже -50°C.",
"gameEffects": ["desiccant", "de_icing", "heat_source"]
},
{
"id": "BaCl2", "formula": "BaCl₂", "name": "Barium Chloride", "nameRu": "Хлорид бария",
"mass": 208.233, "state": "solid", "color": "#f0f0f0",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Toxic barium salt. Burns with characteristic green flame. Chemical analysis reagent.",
"descriptionRu": "Токсичная соль бария. Горит характерным зелёным пламенем. Реагент для химического анализа.",
"gameEffects": ["green_flame", "analysis_reagent"]
},
{
"id": "FeCl3", "formula": "FeCl₃", "name": "Iron(III) Chloride", "nameRu": "Хлорид железа(III)",
"mass": 162.204, "state": "solid", "color": "#663300",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": true },
"description": "Dark brown, corrosive. Etches copper (circuit boards). Water purification agent.",
"descriptionRu": "Тёмно-коричневый, едкий. Травит медь (печатные платы). Реагент для очистки воды.",
"gameEffects": ["copper_etching", "water_purification", "coagulant"]
},
{
"id": "CuCl2", "formula": "CuCl₂", "name": "Copper(II) Chloride", "nameRu": "Хлорид меди(II)",
"mass": 134.452, "state": "solid", "color": "#006633",
"properties": { "flammable": false, "toxic": true, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Bright green crystals. Turns blue in water. Catalyst. Gives green-blue flame.",
"descriptionRu": "Ярко-зелёные кристаллы. Синеет в воде. Катализатор. Даёт зелёно-голубое пламя.",
"gameEffects": ["catalyst", "pigment", "blue_green_flame"]
},
{
"id": "FeCl2", "formula": "FeCl₂", "name": "Iron(II) Chloride", "nameRu": "Хлорид железа(II)",
"mass": 126.751, "state": "solid", "color": "#669966",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": false },
"description": "Greenish solid. Product of iron dissolved in HCl. Reducing agent.",
"descriptionRu": "Зеленоватое твёрдое вещество. Продукт растворения железа в HCl. Восстановитель.",
"gameEffects": ["reducing_agent", "water_treatment"]
},
{
"id": "ZnCl2", "formula": "ZnCl₂", "name": "Zinc Chloride", "nameRu": "Хлорид цинка",
"mass": 136.286, "state": "solid", "color": "#e0e0e0",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": false, "oxidizer": false, "corrosive": true },
"description": "Powerful flux for soldering. Dehydrating agent. Used in fireproofing fabric.",
"descriptionRu": "Мощный флюс для пайки. Обезвоживающий агент. Огнезащита тканей.",
"gameEffects": ["flux", "desiccant", "fireproofing"]
},
{
"id": "Na2O", "formula": "Na₂O", "name": "Sodium Oxide", "nameRu": "Оксид натрия",
"mass": 61.979, "state": "solid", "color": "#f5f5f5",
"properties": { "flammable": false, "toxic": false, "explosive": false, "acidic": false, "basic": true, "oxidizer": false, "corrosive": true },
"description": "White powder. Reacts violently with water to form NaOH. Key component in glass making.",
"descriptionRu": "Белый порошок. Бурно реагирует с водой, образуя NaOH. Ключевой компонент стекловарения.",
"gameEffects": ["glass_making", "caustic"]
} }
] ]

View File

@@ -4,6 +4,7 @@
"name": "Crystallid", "name": "Crystallid",
"nameRu": "Кристаллид", "nameRu": "Кристаллид",
"speciesId": 0, "speciesId": 0,
"biome": "catalytic-wastes",
"description": "Slow, armored creature that feeds on mineral deposits. Its silicon-rich body refracts light into prismatic patterns. When killed, it shatters into valuable crystalline fragments.", "description": "Slow, armored creature that feeds on mineral deposits. Its silicon-rich body refracts light into prismatic patterns. When killed, it shatters into valuable crystalline fragments.",
"descriptionRu": "Медленное бронированное существо, питающееся минеральными отложениями. Его кремниевое тело преломляет свет в призматические узоры. При гибели рассыпается на ценные кристаллические осколки.", "descriptionRu": "Медленное бронированное существо, питающееся минеральными отложениями. Его кремниевое тело преломляет свет в призматические узоры. При гибели рассыпается на ценные кристаллические осколки.",
"color": "#88ccff", "color": "#88ccff",
@@ -40,6 +41,7 @@
"name": "Acidophile", "name": "Acidophile",
"nameRu": "Ацидофил", "nameRu": "Ацидофил",
"speciesId": 1, "speciesId": 1,
"biome": "catalytic-wastes",
"description": "Mid-sized creature that thrives in acidic environments. Consumes mineral deposits and excretes hydrochloric acid, gradually reshaping the landscape. Territorial but not predatory.", "description": "Mid-sized creature that thrives in acidic environments. Consumes mineral deposits and excretes hydrochloric acid, gradually reshaping the landscape. Territorial but not predatory.",
"descriptionRu": "Среднеразмерное существо, процветающее в кислотной среде. Поглощает минералы и выделяет соляную кислоту, постепенно изменяя ландшафт. Территориальное, но не хищное.", "descriptionRu": "Среднеразмерное существо, процветающее в кислотной среде. Поглощает минералы и выделяет соляную кислоту, постепенно изменяя ландшафт. Территориальное, но не хищное.",
"color": "#44ff44", "color": "#44ff44",
@@ -76,6 +78,7 @@
"name": "Reagent", "name": "Reagent",
"nameRu": "Реагент", "nameRu": "Реагент",
"speciesId": 2, "speciesId": 2,
"biome": "catalytic-wastes",
"description": "Fast, aggressive predator that hunts in pairs. Contains unstable chemical compounds — when two Reagents collide, they trigger an exothermic reaction. Feeds on other creatures.", "description": "Fast, aggressive predator that hunts in pairs. Contains unstable chemical compounds — when two Reagents collide, they trigger an exothermic reaction. Feeds on other creatures.",
"descriptionRu": "Быстрый агрессивный хищник, охотящийся парами. Содержит нестабильные химические соединения — при столкновении двух Реагентов происходит экзотермическая реакция. Питается другими существами.", "descriptionRu": "Быстрый агрессивный хищник, охотящийся парами. Содержит нестабильные химические соединения — при столкновении двух Реагентов происходит экзотермическая реакция. Питается другими существами.",
"color": "#ff4444", "color": "#ff4444",
@@ -106,5 +109,227 @@
"maxPopulation": 8, "maxPopulation": 8,
"spawnWeight": 0.25, "spawnWeight": 0.25,
"preferredTiles": ["scorched-earth", "ground"] "preferredTiles": ["scorched-earth", "ground"]
},
{
"id": "pendulum",
"name": "Pendulum",
"nameRu": "Маятник",
"speciesId": 3,
"biome": "kinetic-mountains",
"description": "Flying creature with strictly periodic motion. Swings back and forth on invisible pivot points. Can be used as a clock or platform. Docile unless struck mid-swing.",
"descriptionRu": "Летающее существо со строго периодичным движением. Качается взад-вперёд на невидимых опорных точках. Можно использовать как часы или платформу. Мирное, если не ударить в полёте.",
"color": "#77aadd",
"radius": 9,
"radiusYouth": 5,
"health": 90,
"speed": 60,
"damage": 10,
"armor": 0.15,
"diet": "mineral",
"dietTiles": ["ore-deposit", "gear-floor"],
"excretionElement": 26,
"energyMax": 90,
"energyPerFeed": 22,
"energyDrainPerSecond": 1.8,
"hungerThreshold": 0.45,
"aggressionRadius": 0,
"fleeRadius": 100,
"wanderRadius": 220,
"attackRange": 22,
"attackCooldown": 1800,
"eggDuration": 7000,
"youthDuration": 14000,
"matureDuration": 55000,
"agingDuration": 18000,
"reproductionEnergy": 55,
"offspringCount": 2,
"maxPopulation": 10,
"spawnWeight": 0.4,
"preferredTiles": ["bare-rock", "gear-floor"]
},
{
"id": "mechanoid",
"name": "Mechanoid",
"nameRu": "Механоид",
"speciesId": 4,
"biome": "kinetic-mountains",
"description": "Half-living automaton. Can be repaired, reprogrammed, or scavenged for metal parts. Patrols ancient machinery and attacks intruders near gear mechanisms.",
"descriptionRu": "Полуживой автомат. Можно починить, перепрограммировать или разобрать на металлические детали. Патрулирует древние механизмы и атакует чужаков у шестерёнок.",
"color": "#aaaacc",
"radius": 11,
"radiusYouth": 7,
"health": 150,
"speed": 35,
"damage": 18,
"armor": 0.4,
"diet": "mineral",
"dietTiles": ["ore-deposit"],
"excretionElement": 29,
"energyMax": 120,
"energyPerFeed": 30,
"energyDrainPerSecond": 1.0,
"hungerThreshold": 0.3,
"aggressionRadius": 120,
"fleeRadius": 0,
"wanderRadius": 150,
"attackRange": 26,
"attackCooldown": 2200,
"eggDuration": 10000,
"youthDuration": 18000,
"matureDuration": 80000,
"agingDuration": 25000,
"reproductionEnergy": 70,
"offspringCount": 1,
"maxPopulation": 8,
"spawnWeight": 0.3,
"preferredTiles": ["gear-floor", "iron-ridge"]
},
{
"id": "resonator",
"name": "Resonator",
"nameRu": "Резонатор",
"speciesId": 5,
"biome": "kinetic-mountains",
"description": "Vibrates at fixed frequencies. Dangerous if its frequency matches your gear — resonance shatters equipment. Can be used to break barriers or stun other creatures.",
"descriptionRu": "Вибрирует на фиксированных частотах. Опасен, если его частота совпадает с вашим снаряжением — резонанс разрушает оборудование. Может ломать барьеры или оглушать существ.",
"color": "#ff88ff",
"radius": 7,
"radiusYouth": 4,
"health": 50,
"speed": 70,
"damage": 25,
"armor": 0.0,
"diet": "creature",
"dietTiles": [],
"excretionElement": 0,
"energyMax": 55,
"energyPerFeed": 25,
"energyDrainPerSecond": 2.8,
"hungerThreshold": 0.55,
"aggressionRadius": 130,
"fleeRadius": 70,
"wanderRadius": 280,
"attackRange": 20,
"attackCooldown": 1200,
"eggDuration": 5000,
"youthDuration": 10000,
"matureDuration": 40000,
"agingDuration": 13000,
"reproductionEnergy": 35,
"offspringCount": 1,
"maxPopulation": 6,
"spawnWeight": 0.3,
"preferredTiles": ["magnetic-field", "bare-rock"]
},
{
"id": "symbiote",
"name": "Symbiote",
"nameRu": "Симбионт",
"speciesId": 6,
"biome": "verdant-forests",
"description": "Always appears in bonded pairs. Separating them weakens both — one may die without the other. Feeds on forest floor decomposition. Peaceful but resilient in pairs.",
"descriptionRu": "Всегда появляется связанными парами. Разделение ослабляет обоих — один может погибнуть без другого. Питается лесной подстилкой. Мирные, но в паре стойкие.",
"color": "#44ddaa",
"radius": 8,
"radiusYouth": 5,
"health": 70,
"speed": 45,
"damage": 6,
"armor": 0.2,
"diet": "mineral",
"dietTiles": ["herb-patch", "mycelium-carpet"],
"excretionElement": 7,
"energyMax": 85,
"energyPerFeed": 20,
"energyDrainPerSecond": 1.6,
"hungerThreshold": 0.4,
"aggressionRadius": 0,
"fleeRadius": 90,
"wanderRadius": 180,
"attackRange": 18,
"attackCooldown": 2000,
"eggDuration": 7000,
"youthDuration": 13000,
"matureDuration": 50000,
"agingDuration": 17000,
"reproductionEnergy": 45,
"offspringCount": 2,
"maxPopulation": 14,
"spawnWeight": 0.4,
"preferredTiles": ["forest-floor", "dense-undergrowth"]
},
{
"id": "mimic",
"name": "Mimic",
"nameRu": "Мимикр",
"speciesId": 7,
"biome": "verdant-forests",
"description": "Master of disguise. Can appear as a plant, resource, or even a fungal node. Only reveals itself when approached too closely. Ambush predator with potent venom.",
"descriptionRu": "Мастер маскировки. Может выглядеть как растение, ресурс или грибной узел. Раскрывает себя только при близком приближении. Засадный хищник с мощным ядом.",
"color": "#33cc33",
"radius": 8,
"radiusYouth": 5,
"health": 65,
"speed": 55,
"damage": 22,
"armor": 0.05,
"diet": "creature",
"dietTiles": [],
"excretionElement": 0,
"energyMax": 65,
"energyPerFeed": 28,
"energyDrainPerSecond": 2.2,
"hungerThreshold": 0.5,
"aggressionRadius": 60,
"fleeRadius": 80,
"wanderRadius": 200,
"attackRange": 16,
"attackCooldown": 1400,
"eggDuration": 6000,
"youthDuration": 11000,
"matureDuration": 42000,
"agingDuration": 14000,
"reproductionEnergy": 42,
"offspringCount": 1,
"maxPopulation": 7,
"spawnWeight": 0.25,
"preferredTiles": ["forest-floor", "mycelium-carpet"]
},
{
"id": "spore-bearer",
"name": "Spore-bearer",
"nameRu": "Споровик",
"speciesId": 8,
"biome": "verdant-forests",
"description": "Fungal creature, avatar of the Mycelium. Peaceful and slow. If harmed, the entire forest turns hostile. Deposits knowledge into fungal nodes when passing near them.",
"descriptionRu": "Грибное существо, аватар Мицелия. Мирное и медленное. Если обидеть — весь лес становится враждебным. Откладывает знания в грибные узлы, проходя мимо них.",
"color": "#9966cc",
"radius": 12,
"radiusYouth": 7,
"health": 200,
"speed": 20,
"damage": 5,
"armor": 0.25,
"diet": "mineral",
"dietTiles": ["mycelium-carpet", "herb-patch"],
"excretionElement": 15,
"energyMax": 150,
"energyPerFeed": 35,
"energyDrainPerSecond": 0.8,
"hungerThreshold": 0.3,
"aggressionRadius": 0,
"fleeRadius": 60,
"wanderRadius": 160,
"attackRange": 24,
"attackCooldown": 3000,
"eggDuration": 12000,
"youthDuration": 20000,
"matureDuration": 90000,
"agingDuration": 30000,
"reproductionEnergy": 80,
"offspringCount": 1,
"maxPopulation": 5,
"spawnWeight": 0.35,
"preferredTiles": ["mycelium-carpet", "forest-floor"]
} }
] ]

View File

@@ -25,6 +25,32 @@
"description": "Noble gas. Completely inert — refuses to react with anything. Lighter than air.", "description": "Noble gas. Completely inert — refuses to react with anything. Lighter than air.",
"descriptionRu": "Благородный газ. Абсолютно инертен — не реагирует ни с чем. Легче воздуха." "descriptionRu": "Благородный газ. Абсолютно инертен — не реагирует ни с чем. Легче воздуха."
}, },
{
"symbol": "Li",
"name": "Lithium",
"nameRu": "Литий",
"atomicNumber": 3,
"atomicMass": 6.941,
"electronegativity": 0.98,
"category": "alkali-metal",
"state": "solid",
"color": "#cc80ff",
"description": "Lightest metal. Soft enough to cut with a knife. Key component of modern batteries. Burns crimson red.",
"descriptionRu": "Легчайший металл. Настолько мягкий, что режется ножом. Ключевой компонент современных аккумуляторов. Горит малиновым пламенем."
},
{
"symbol": "B",
"name": "Boron",
"nameRu": "Бор",
"atomicNumber": 5,
"atomicMass": 10.811,
"electronegativity": 2.04,
"category": "metalloid",
"state": "solid",
"color": "#ffb5b5",
"description": "Hard metalloid. Essential for borosilicate glass (heat-resistant). Boron compounds are used as neutron absorbers.",
"descriptionRu": "Твёрдый металлоид. Основа боросиликатного стекла (термостойкого). Соединения бора поглощают нейтроны."
},
{ {
"symbol": "C", "symbol": "C",
"name": "Carbon", "name": "Carbon",
@@ -64,6 +90,32 @@
"description": "Essential for combustion and respiration. Highly reactive oxidizer. 21% of air.", "description": "Essential for combustion and respiration. Highly reactive oxidizer. 21% of air.",
"descriptionRu": "Необходим для горения и дыхания. Сильный окислитель. 21% воздуха." "descriptionRu": "Необходим для горения и дыхания. Сильный окислитель. 21% воздуха."
}, },
{
"symbol": "F",
"name": "Fluorine",
"nameRu": "Фтор",
"atomicNumber": 9,
"atomicMass": 18.998,
"electronegativity": 3.98,
"category": "halogen",
"state": "gas",
"color": "#90e050",
"description": "Most reactive element in existence. Attacks almost everything, even glass. Handle with extreme caution.",
"descriptionRu": "Самый реактивный элемент в природе. Атакует почти всё, даже стекло. Обращаться с предельной осторожностью."
},
{
"symbol": "Ne",
"name": "Neon",
"nameRu": "Неон",
"atomicNumber": 10,
"atomicMass": 20.180,
"electronegativity": 0,
"category": "noble-gas",
"state": "gas",
"color": "#b3e3f5",
"description": "Noble gas. Produces iconic red-orange glow in discharge tubes. Completely inert.",
"descriptionRu": "Благородный газ. Даёт культовое красно-оранжевое свечение в газоразрядных трубках. Полностью инертен."
},
{ {
"symbol": "Na", "symbol": "Na",
"name": "Sodium", "name": "Sodium",
@@ -155,6 +207,19 @@
"description": "Toxic yellow-green gas. Powerful disinfectant. Combines readily with metals to form salts.", "description": "Toxic yellow-green gas. Powerful disinfectant. Combines readily with metals to form salts.",
"descriptionRu": "Ядовитый жёлто-зелёный газ. Мощный дезинфектант. Легко соединяется с металлами, образуя соли." "descriptionRu": "Ядовитый жёлто-зелёный газ. Мощный дезинфектант. Легко соединяется с металлами, образуя соли."
}, },
{
"symbol": "Ar",
"name": "Argon",
"nameRu": "Аргон",
"atomicNumber": 18,
"atomicMass": 39.948,
"electronegativity": 0,
"category": "noble-gas",
"state": "gas",
"color": "#80d1e3",
"description": "Third most abundant gas in atmosphere (0.93%). Used as shielding gas in welding. Completely inert.",
"descriptionRu": "Третий по распространённости газ в атмосфере (0,93%). Защитный газ при сварке. Полностью инертен."
},
{ {
"symbol": "K", "symbol": "K",
"name": "Potassium", "name": "Potassium",
@@ -181,6 +246,45 @@
"description": "Essential for bones and shells. Reacts with water, but less violently than sodium. Component of limestone and cement.", "description": "Essential for bones and shells. Reacts with water, but less violently than sodium. Component of limestone and cement.",
"descriptionRu": "Необходим для костей и раковин. Реагирует с водой, но менее бурно, чем натрий. Компонент известняка и цемента." "descriptionRu": "Необходим для костей и раковин. Реагирует с водой, но менее бурно, чем натрий. Компонент известняка и цемента."
}, },
{
"symbol": "Ti",
"name": "Titanium",
"nameRu": "Титан",
"atomicNumber": 22,
"atomicMass": 47.867,
"electronegativity": 1.54,
"category": "transition-metal",
"state": "solid",
"color": "#bfc2c7",
"description": "Strong as steel but 45% lighter. Corrosion-resistant. Used in aerospace, implants, and armor.",
"descriptionRu": "Прочен как сталь, но на 45% легче. Коррозионностойкий. Применяется в авиации, имплантах и броне."
},
{
"symbol": "Cr",
"name": "Chromium",
"nameRu": "Хром",
"atomicNumber": 24,
"atomicMass": 51.996,
"electronegativity": 1.66,
"category": "transition-metal",
"state": "solid",
"color": "#8a99c7",
"description": "Hardest pure metal. Chrome plating resists corrosion. Stainless steel contains 10-20% chromium.",
"descriptionRu": "Самый твёрдый чистый металл. Хромирование защищает от коррозии. Нержавеющая сталь содержит 10-20% хрома."
},
{
"symbol": "Mn",
"name": "Manganese",
"nameRu": "Марганец",
"atomicNumber": 25,
"atomicMass": 54.938,
"electronegativity": 1.55,
"category": "transition-metal",
"state": "solid",
"color": "#9c7ac7",
"description": "Essential for steel production. MnO₂ is a natural catalyst and battery material. Biological enzyme cofactor.",
"descriptionRu": "Необходим для производства стали. MnO₂ — природный катализатор и материал батарей. Кофактор биологических ферментов."
},
{ {
"symbol": "Fe", "symbol": "Fe",
"name": "Iron", "name": "Iron",
@@ -194,6 +298,32 @@
"description": "Strong, abundant metal. Rusts in moist air. Core of Earth is mostly iron. Magnetic.", "description": "Strong, abundant metal. Rusts in moist air. Core of Earth is mostly iron. Magnetic.",
"descriptionRu": "Прочный, распространённый металл. Ржавеет на влажном воздухе. Ядро Земли в основном из железа. Магнитен." "descriptionRu": "Прочный, распространённый металл. Ржавеет на влажном воздухе. Ядро Земли в основном из железа. Магнитен."
}, },
{
"symbol": "Co",
"name": "Cobalt",
"nameRu": "Кобальт",
"atomicNumber": 27,
"atomicMass": 58.933,
"electronegativity": 1.88,
"category": "transition-metal",
"state": "solid",
"color": "#f090a0",
"description": "Source of brilliant blue pigment since antiquity. Magnetic. Essential in vitamin B12.",
"descriptionRu": "Источник насыщенного синего пигмента с древности. Магнитен. Входит в состав витамина B12."
},
{
"symbol": "Ni",
"name": "Nickel",
"nameRu": "Никель",
"atomicNumber": 28,
"atomicMass": 58.693,
"electronegativity": 1.91,
"category": "transition-metal",
"state": "solid",
"color": "#50d050",
"description": "Corrosion-resistant metal. Key alloy component. Excellent catalyst for hydrogenation reactions.",
"descriptionRu": "Коррозионностойкий металл. Важный компонент сплавов. Превосходный катализатор гидрирования."
},
{ {
"symbol": "Cu", "symbol": "Cu",
"name": "Copper", "name": "Copper",
@@ -220,6 +350,45 @@
"description": "Protects iron from rusting (galvanization). Zinc sulfide glows under UV light. Essential trace nutrient.", "description": "Protects iron from rusting (galvanization). Zinc sulfide glows under UV light. Essential trace nutrient.",
"descriptionRu": "Защищает железо от ржавчины (гальванизация). Сульфид цинка светится в УФ-свете. Необходимый микроэлемент." "descriptionRu": "Защищает железо от ржавчины (гальванизация). Сульфид цинка светится в УФ-свете. Необходимый микроэлемент."
}, },
{
"symbol": "As",
"name": "Arsenic",
"nameRu": "Мышьяк",
"atomicNumber": 33,
"atomicMass": 74.922,
"electronegativity": 2.18,
"category": "metalloid",
"state": "solid",
"color": "#bd80e3",
"description": "Infamous poison. 'Inheritance powder' of the Borgias. Also a semiconductor used in LEDs and lasers.",
"descriptionRu": "Печально известный яд. «Порошок наследников» Борджиа. Также полупроводник для светодиодов и лазеров."
},
{
"symbol": "Br",
"name": "Bromine",
"nameRu": "Бром",
"atomicNumber": 35,
"atomicMass": 79.904,
"electronegativity": 2.96,
"category": "halogen",
"state": "liquid",
"color": "#a62929",
"description": "Only non-metallic element that is liquid at room temperature. Dark red, fuming, and corrosive.",
"descriptionRu": "Единственный неметалл, жидкий при комнатной температуре. Тёмно-красный, дымящий, едкий."
},
{
"symbol": "Ag",
"name": "Silver",
"nameRu": "Серебро",
"atomicNumber": 47,
"atomicMass": 107.868,
"electronegativity": 1.93,
"category": "transition-metal",
"state": "solid",
"color": "#c0c0c0",
"description": "Best electrical and thermal conductor of all metals. Natural antimicrobial. Tarnishes in sulfur-containing air.",
"descriptionRu": "Лучший проводник электричества и тепла среди металлов. Природный антисептик. Темнеет в воздухе с серой."
},
{ {
"symbol": "Sn", "symbol": "Sn",
"name": "Tin", "name": "Tin",
@@ -233,6 +402,58 @@
"description": "Soft, malleable metal. Resists corrosion. Used for solder and tin plating. Alloy with copper makes bronze.", "description": "Soft, malleable metal. Resists corrosion. Used for solder and tin plating. Alloy with copper makes bronze.",
"descriptionRu": "Мягкий, ковкий металл. Устойчив к коррозии. Используется для пайки и лужения. Сплав с медью — бронза." "descriptionRu": "Мягкий, ковкий металл. Устойчив к коррозии. Используется для пайки и лужения. Сплав с медью — бронза."
}, },
{
"symbol": "I",
"name": "Iodine",
"nameRu": "Йод",
"atomicNumber": 53,
"atomicMass": 126.904,
"electronegativity": 2.66,
"category": "halogen",
"state": "solid",
"color": "#940094",
"description": "Purple-black crystals that sublimate into violet vapor. Essential for thyroid function. Powerful disinfectant.",
"descriptionRu": "Пурпурно-чёрные кристаллы, сублимирующие в фиолетовый пар. Необходим для щитовидной железы. Мощный антисептик."
},
{
"symbol": "Ba",
"name": "Barium",
"nameRu": "Барий",
"atomicNumber": 56,
"atomicMass": 137.327,
"electronegativity": 0.89,
"category": "alkaline-earth",
"state": "solid",
"color": "#00c900",
"description": "Alkaline earth metal. Burns with bright green flame (fireworks!). BaSO₄ used in X-ray contrast imaging.",
"descriptionRu": "Щёлочноземельный металл. Горит ярко-зелёным пламенем (фейерверки!). BaSO₄ используется при рентгеновской диагностике."
},
{
"symbol": "W",
"name": "Tungsten",
"nameRu": "Вольфрам",
"atomicNumber": 74,
"atomicMass": 183.84,
"electronegativity": 2.36,
"category": "transition-metal",
"state": "solid",
"color": "#2194d6",
"description": "Highest melting point of any element (3422°C). Extremely hard and dense. Light bulb filaments.",
"descriptionRu": "Самая высокая температура плавления среди элементов (3422°C). Крайне твёрд и плотен. Нити накаливания ламп."
},
{
"symbol": "Pt",
"name": "Platinum",
"nameRu": "Платина",
"atomicNumber": 78,
"atomicMass": 195.084,
"electronegativity": 2.28,
"category": "transition-metal",
"state": "solid",
"color": "#d0d0e0",
"description": "Noble metal and supreme catalyst. Resists corrosion. Catalytic converters, lab equipment, jewelry.",
"descriptionRu": "Благородный металл и превосходный катализатор. Не поддаётся коррозии. Каталитические нейтрализаторы, лаборатории, ювелирные изделия."
},
{ {
"symbol": "Au", "symbol": "Au",
"name": "Gold", "name": "Gold",
@@ -258,5 +479,44 @@
"color": "#b8b8d0", "color": "#b8b8d0",
"description": "Only metal that is liquid at room temperature. Extremely toxic — damages brain and kidneys. Handle with extreme care.", "description": "Only metal that is liquid at room temperature. Extremely toxic — damages brain and kidneys. Handle with extreme care.",
"descriptionRu": "Единственный металл, жидкий при комнатной температуре. Крайне токсичен — поражает мозг и почки. Обращаться с предельной осторожностью." "descriptionRu": "Единственный металл, жидкий при комнатной температуре. Крайне токсичен — поражает мозг и почки. Обращаться с предельной осторожностью."
},
{
"symbol": "Pb",
"name": "Lead",
"nameRu": "Свинец",
"atomicNumber": 82,
"atomicMass": 207.2,
"electronegativity": 2.33,
"category": "post-transition-metal",
"state": "solid",
"color": "#575961",
"description": "Dense, soft, toxic metal. Shields against radiation. Used in batteries. Cumulative neurotoxin.",
"descriptionRu": "Плотный, мягкий, токсичный металл. Экранирует от радиации. Используется в аккумуляторах. Кумулятивный нейротоксин."
},
{
"symbol": "Bi",
"name": "Bismuth",
"nameRu": "Висмут",
"atomicNumber": 83,
"atomicMass": 208.980,
"electronegativity": 2.02,
"category": "post-transition-metal",
"state": "solid",
"color": "#9e4fb5",
"description": "Least toxic heavy metal. Forms beautiful iridescent crystals. Used in Pepto-Bismol and cosmetics.",
"descriptionRu": "Наименее токсичный тяжёлый металл. Образует красивые радужные кристаллы. Применяется в медицине и косметике."
},
{
"symbol": "U",
"name": "Uranium",
"nameRu": "Уран",
"atomicNumber": 92,
"atomicMass": 238.029,
"electronegativity": 1.38,
"category": "actinide",
"state": "solid",
"color": "#008fff",
"description": "Radioactive element. Enormous energy density — 1 kg equals 3000 tonnes of coal. Powers nuclear reactors.",
"descriptionRu": "Радиоактивный элемент. Колоссальная плотность энергии — 1 кг равен 3000 тоннам угля. Питает ядерные реакторы."
} }
] ]

View File

@@ -322,5 +322,822 @@
"description": "Lime burning: heating limestone drives off CO₂, leaving quicklime. Ancient building technology.", "description": "Lime burning: heating limestone drives off CO₂, leaving quicklime. Ancient building technology.",
"descriptionRu": "Обжиг извести: нагрев известняка выгоняет CO₂, оставляя негашёную известь. Древняя строительная технология.", "descriptionRu": "Обжиг извести: нагрев известняка выгоняет CO₂, оставляя негашёную известь. Древняя строительная технология.",
"difficulty": 3 "difficulty": 3
},
{
"id": "synth_hf", "type": "synthesis",
"reactants": [{ "id": "H", "count": 1 }, { "id": "F", "count": 1 }],
"products": [{ "id": "HF", "count": 1 }],
"energyChange": -3,
"description": "Hydrogen + fluorine combine to form hydrofluoric acid — dissolves glass!",
"descriptionRu": "Водород + фтор образуют плавиковую кислоту — растворяет стекло!",
"difficulty": 1
},
{
"id": "synth_hbr", "type": "synthesis",
"reactants": [{ "id": "H", "count": 1 }, { "id": "Br", "count": 1 }],
"products": [{ "id": "HBr", "count": 1 }],
"energyChange": -4,
"description": "Hydrogen + bromine → hydrobromic acid, a strong acid",
"descriptionRu": "Водород + бром → бромоводородная кислота, сильная кислота",
"difficulty": 1
},
{
"id": "synth_hi", "type": "synthesis",
"reactants": [{ "id": "H", "count": 1 }, { "id": "I", "count": 1 }],
"products": [{ "id": "HI", "count": 1 }],
"energyChange": -3,
"description": "Hydrogen + iodine → hydroiodic acid. Strongest hydrohalic acid",
"descriptionRu": "Водород + йод → йодоводородная кислота. Самая сильная галогенводородная кислота",
"difficulty": 1
},
{
"id": "synth_licl", "type": "synthesis",
"reactants": [{ "id": "Li", "count": 1 }, { "id": "Cl", "count": 1 }],
"products": [{ "id": "LiCl", "count": 1 }],
"energyChange": -38,
"description": "Lithium + chlorine → lithium chloride. Hygroscopic desiccant",
"descriptionRu": "Литий + хлор → хлорид лития. Гигроскопичный осушитель",
"difficulty": 1
},
{
"id": "synth_lioh", "type": "synthesis",
"reactants": [{ "id": "Li", "count": 1 }, { "id": "O", "count": 1 }, { "id": "H", "count": 1 }],
"products": [{ "id": "LiOH", "count": 1 }],
"energyChange": -45,
"description": "Lithium hydroxide synthesis. Used in spacecraft CO₂ scrubbers",
"descriptionRu": "Синтез гидроксида лития. Используется для очистки воздуха на космических кораблях",
"difficulty": 2
},
{
"id": "synth_agcl", "type": "synthesis",
"reactants": [{ "id": "Ag", "count": 1 }, { "id": "Cl", "count": 1 }],
"products": [{ "id": "AgCl", "count": 1 }],
"energyChange": -13,
"description": "Silver + chlorine → silver chloride. Darkens in light — basis of photography",
"descriptionRu": "Серебро + хлор → хлорид серебра. Темнеет на свету — основа фотографии",
"difficulty": 2
},
{
"id": "synth_agbr", "type": "synthesis",
"reactants": [{ "id": "Ag", "count": 1 }, { "id": "Br", "count": 1 }],
"products": [{ "id": "AgBr", "count": 1 }],
"energyChange": -10,
"description": "Silver + bromine → silver bromide. More light-sensitive than AgCl",
"descriptionRu": "Серебро + бром → бромид серебра. Светочувствительнее AgCl",
"difficulty": 2
},
{
"id": "synth_pbs", "type": "synthesis",
"reactants": [{ "id": "Pb", "count": 1 }, { "id": "S", "count": 1 }],
"products": [{ "id": "PbS", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -10,
"description": "Lead + sulfur → galena (lead sulfide). First semiconductor",
"descriptionRu": "Свинец + сера → галенит (сульфид свинца). Первый полупроводник",
"difficulty": 2
},
{
"id": "synth_nicl2", "type": "synthesis",
"reactants": [{ "id": "Ni", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "NiCl2", "count": 1 }],
"energyChange": -31,
"description": "Nickel + chlorine → green nickel chloride. Electroplating reagent",
"descriptionRu": "Никель + хлор → зелёный хлорид никеля. Реагент для гальваники",
"difficulty": 2
},
{
"id": "synth_naf", "type": "synthesis",
"reactants": [{ "id": "Na", "count": 1 }, { "id": "F", "count": 1 }],
"products": [{ "id": "NaF", "count": 1 }],
"energyChange": -57,
"description": "Sodium + fluorine → sodium fluoride. Active ingredient in toothpaste",
"descriptionRu": "Натрий + фтор → фторид натрия. Активный компонент зубной пасты",
"difficulty": 1
},
{
"id": "synth_nabr", "type": "synthesis",
"reactants": [{ "id": "Na", "count": 1 }, { "id": "Br", "count": 1 }],
"products": [{ "id": "NaBr", "count": 1 }],
"energyChange": -36,
"description": "Sodium + bromine → sodium bromide. Historical sedative",
"descriptionRu": "Натрий + бром → бромид натрия. Историческое седативное средство",
"difficulty": 1
},
{
"id": "synth_kf", "type": "synthesis",
"reactants": [{ "id": "K", "count": 1 }, { "id": "F", "count": 1 }],
"products": [{ "id": "KF", "count": 1 }],
"energyChange": -56,
"description": "Potassium + fluorine → potassium fluoride",
"descriptionRu": "Калий + фтор → фторид калия",
"difficulty": 1
},
{
"id": "synth_kbr", "type": "synthesis",
"reactants": [{ "id": "K", "count": 1 }, { "id": "Br", "count": 1 }],
"products": [{ "id": "KBr", "count": 1 }],
"energyChange": -39,
"description": "Potassium + bromine → potassium bromide. Photography essential",
"descriptionRu": "Калий + бром → бромид калия. Незаменим в фотографии",
"difficulty": 1
},
{
"id": "synth_mgcl2", "type": "synthesis",
"reactants": [{ "id": "Mg", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "MgCl2", "count": 1 }],
"energyChange": -64,
"description": "Magnesium + chlorine → magnesium chloride. De-icing salt",
"descriptionRu": "Магний + хлор → хлорид магния. Противогололёдная соль",
"difficulty": 1
},
{
"id": "synth_cacl2", "type": "synthesis",
"reactants": [{ "id": "Ca", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "CaCl2", "count": 1 }],
"energyChange": -80,
"description": "Calcium + chlorine → calcium chloride. Powerful desiccant",
"descriptionRu": "Кальций + хлор → хлорид кальция. Мощный осушитель",
"difficulty": 1
},
{
"id": "synth_bacl2", "type": "synthesis",
"reactants": [{ "id": "Ba", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "BaCl2", "count": 1 }],
"energyChange": -86,
"description": "Barium + chlorine → barium chloride. Green flame reagent",
"descriptionRu": "Барий + хлор → хлорид бария. Реагент зелёного пламени",
"difficulty": 1
},
{
"id": "synth_fecl3", "type": "synthesis",
"reactants": [{ "id": "Fe", "count": 1 }, { "id": "Cl", "count": 3 }],
"products": [{ "id": "FeCl3", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -40,
"description": "Iron + excess chlorine → iron(III) chloride. Etches copper circuit boards",
"descriptionRu": "Железо + избыток хлора → хлорид железа(III). Травит медные платы",
"difficulty": 2
},
{
"id": "synth_fecl2", "type": "synthesis",
"reactants": [{ "id": "Fe", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "FeCl2", "count": 1 }],
"energyChange": -34,
"description": "Iron + chlorine → iron(II) chloride. Reducing agent",
"descriptionRu": "Железо + хлор → хлорид железа(II). Восстановитель",
"difficulty": 2
},
{
"id": "synth_cucl2", "type": "synthesis",
"reactants": [{ "id": "Cu", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "CuCl2", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -22,
"description": "Copper + chlorine at heat → green copper(II) chloride crystals",
"descriptionRu": "Медь + хлор при нагреве → зелёные кристаллы хлорида меди(II)",
"difficulty": 2
},
{
"id": "synth_zncl2", "type": "synthesis",
"reactants": [{ "id": "Zn", "count": 1 }, { "id": "Cl", "count": 2 }],
"products": [{ "id": "ZnCl2", "count": 1 }],
"energyChange": -42,
"description": "Zinc + chlorine → zinc chloride. Soldering flux",
"descriptionRu": "Цинк + хлор → хлорид цинка. Паяльный флюс",
"difficulty": 1
},
{
"id": "synth_na2o", "type": "synthesis",
"reactants": [{ "id": "Na", "count": 2 }, { "id": "O", "count": 1 }],
"products": [{ "id": "Na2O", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -42,
"description": "Sodium burns in limited oxygen → sodium oxide. Key to glass making",
"descriptionRu": "Натрий горит в ограниченном кислороде → оксид натрия. Ключ к стекловарению",
"difficulty": 2
},
{
"id": "synth_nh3", "type": "synthesis",
"reactants": [{ "id": "N", "count": 1 }, { "id": "H", "count": 3 }],
"products": [{ "id": "NH3", "count": 1 }],
"conditions": { "minTemp": 500, "catalyst": "Fe" },
"energyChange": -5,
"description": "Haber process: nitrogen + hydrogen with iron catalyst → ammonia. Nobel Prize reaction",
"descriptionRu": "Процесс Габера: азот + водород с железным катализатором → аммиак. Нобелевская реакция",
"difficulty": 3
},
{
"id": "synth_h2s", "type": "synthesis",
"reactants": [{ "id": "H", "count": 2 }, { "id": "S", "count": 1 }],
"products": [{ "id": "H2S", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -2,
"description": "Hydrogen + sulfur → hydrogen sulfide. Rotten egg gas",
"descriptionRu": "Водород + сера → сероводород. Газ с запахом тухлых яиц",
"difficulty": 2
},
{
"id": "synth_h2so4", "type": "synthesis",
"reactants": [{ "id": "S", "count": 1 }, { "id": "O", "count": 3 }, { "id": "H", "count": 2 }],
"products": [{ "id": "H2SO4", "count": 1 }],
"conditions": { "catalyst": "Pt" },
"energyChange": -14,
"description": "Contact process: sulfur, oxygen, hydrogen with platinum catalyst → sulfuric acid",
"descriptionRu": "Контактный процесс: сера, кислород, водород с платиновым катализатором → серная кислота",
"difficulty": 4
},
{
"id": "synth_hno3", "type": "synthesis",
"reactants": [{ "id": "N", "count": 1 }, { "id": "O", "count": 3 }, { "id": "H", "count": 1 }],
"products": [{ "id": "HNO3", "count": 1 }],
"conditions": { "catalyst": "Pt" },
"energyChange": -5,
"description": "Ostwald process: nitrogen, oxygen, hydrogen with platinum catalyst → nitric acid",
"descriptionRu": "Процесс Оствальда: азот, кислород, водород с платиновым катализатором → азотная кислота",
"difficulty": 4
},
{
"id": "synth_nh4cl", "type": "synthesis",
"reactants": [{ "id": "NH3", "count": 1 }, { "id": "HCl", "count": 1 }],
"products": [{ "id": "NH4Cl", "count": 1 }],
"energyChange": -18,
"description": "Ammonia + HCl → white smoke of ammonium chloride! Classic demonstration",
"descriptionRu": "Аммиак + HCl → белый дым хлорида аммония! Классическая демонстрация",
"difficulty": 2
},
{
"id": "synth_ch3cooh", "type": "synthesis",
"reactants": [{ "id": "C", "count": 2 }, { "id": "H", "count": 4 }, { "id": "O", "count": 2 }],
"products": [{ "id": "CH3COOH", "count": 1 }],
"conditions": { "catalyst": "Cu" },
"energyChange": -5,
"description": "Acetic acid synthesis with copper catalyst. The chemistry of vinegar",
"descriptionRu": "Синтез уксусной кислоты с медным катализатором. Химия уксуса",
"difficulty": 4
},
{
"id": "synth_c6h12o6", "type": "synthesis",
"reactants": [{ "id": "C", "count": 6 }, { "id": "H", "count": 12 }, { "id": "O", "count": 6 }],
"products": [{ "id": "C6H12O6", "count": 1 }],
"conditions": { "requiresEnergy": true },
"energyChange": 28,
"description": "Artificial photosynthesis: assembling glucose from its elements. Requires enormous energy",
"descriptionRu": "Искусственный фотосинтез: сборка глюкозы из элементов. Требует огромной энергии",
"difficulty": 5
},
{
"id": "comb_tio2", "type": "combustion",
"reactants": [{ "id": "Ti", "count": 1 }, { "id": "O", "count": 2 }],
"products": [{ "id": "TiO2", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -94,
"description": "Titanium burns brilliantly in pure oxygen. Produces white titanium dioxide",
"descriptionRu": "Титан ярко горит в чистом кислороде. Образует белый диоксид титана",
"difficulty": 4
},
{
"id": "comb_cr2o3", "type": "combustion",
"reactants": [{ "id": "Cr", "count": 2 }, { "id": "O", "count": 3 }],
"products": [{ "id": "Cr2O3", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -113,
"description": "Chromium oxidation at extreme heat → green chromium oxide. Hard as corundum",
"descriptionRu": "Окисление хрома при экстремальном нагреве → зелёный оксид хрома. Твёрд как корунд",
"difficulty": 4
},
{
"id": "comb_mno2", "type": "combustion",
"reactants": [{ "id": "Mn", "count": 1 }, { "id": "O", "count": 2 }],
"products": [{ "id": "MnO2", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -52,
"description": "Manganese + oxygen → manganese dioxide. Nature's battery material and catalyst",
"descriptionRu": "Марганец + кислород → диоксид марганца. Природный материал батарей и катализатор",
"difficulty": 3
},
{
"id": "comb_coo", "type": "combustion",
"reactants": [{ "id": "Co", "count": 1 }, { "id": "O", "count": 1 }],
"products": [{ "id": "CoO", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -24,
"description": "Cobalt burns to form cobalt oxide — brilliant blue ceramic pigment",
"descriptionRu": "Кобальт горит, образуя оксид кобальта — великолепный синий керамический пигмент",
"difficulty": 2
},
{
"id": "comb_cuo", "type": "combustion",
"reactants": [{ "id": "Cu", "count": 1 }, { "id": "O", "count": 1 }],
"products": [{ "id": "CuO", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -16,
"description": "Copper oxidation → black copper(II) oxide. Basis of ancient smelting",
"descriptionRu": "Окисление меди → чёрный оксид меди(II). Основа древней металлургии",
"difficulty": 2
},
{
"id": "comb_bao", "type": "combustion",
"reactants": [{ "id": "Ba", "count": 1 }, { "id": "O", "count": 1 }],
"products": [{ "id": "BaO", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -56,
"description": "Barium burns with brilliant GREEN flame → barium oxide",
"descriptionRu": "Барий горит ярко-ЗЕЛЁНЫМ пламенем → оксид бария",
"difficulty": 2
},
{
"id": "comb_wo3", "type": "combustion",
"reactants": [{ "id": "W", "count": 1 }, { "id": "O", "count": 3 }],
"products": [{ "id": "WO3", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -84,
"description": "Tungsten slowly oxidizes only at extreme temperatures. Highest melting point element",
"descriptionRu": "Вольфрам окисляется лишь при экстремальных температурах. Элемент с наивысшей температурой плавления",
"difficulty": 5
},
{
"id": "comb_pbo", "type": "combustion",
"reactants": [{ "id": "Pb", "count": 1 }, { "id": "O", "count": 1 }],
"products": [{ "id": "PbO", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -22,
"description": "Lead oxidation → litharge (yellow lead oxide). Battery material",
"descriptionRu": "Окисление свинца → глёт (жёлтый оксид свинца). Материал аккумуляторов",
"difficulty": 2
},
{
"id": "comb_bi2o3", "type": "combustion",
"reactants": [{ "id": "Bi", "count": 2 }, { "id": "O", "count": 3 }],
"products": [{ "id": "Bi2O3", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -58,
"description": "Bismuth burns → bismuth trioxide. Medicinal compound",
"descriptionRu": "Висмут горит → оксид висмута(III). Лекарственное соединение",
"difficulty": 3
},
{
"id": "comb_uo2", "type": "combustion",
"reactants": [{ "id": "U", "count": 1 }, { "id": "O", "count": 2 }],
"products": [{ "id": "UO2", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -109,
"description": "Uranium oxidation → uranium dioxide. Nuclear fuel pellets",
"descriptionRu": "Окисление урана → диоксид урана. Таблетки ядерного топлива",
"difficulty": 5
},
{
"id": "comb_as2o3", "type": "combustion",
"reactants": [{ "id": "As", "count": 2 }, { "id": "O", "count": 3 }],
"products": [{ "id": "As2O3", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -66,
"description": "Arsenic combustion → arsenic trioxide. The 'King of Poisons'",
"descriptionRu": "Горение мышьяка → оксид мышьяка(III). «Король ядов»",
"difficulty": 3
},
{
"id": "comb_ch4", "type": "combustion",
"reactants": [{ "id": "CH4", "count": 1 }, { "id": "O", "count": 4 }],
"products": [{ "id": "CO2", "count": 1 }, { "id": "H2O", "count": 2 }],
"conditions": { "minTemp": 500 },
"energyChange": -89,
"description": "Methane combustion: natural gas burning. Clean energy source",
"descriptionRu": "Горение метана: сжигание природного газа. Чистый источник энергии",
"difficulty": 2
},
{
"id": "comb_c2h5oh", "type": "combustion",
"reactants": [{ "id": "C2H5OH", "count": 1 }, { "id": "O", "count": 6 }],
"products": [{ "id": "CO2", "count": 2 }, { "id": "H2O", "count": 3 }],
"conditions": { "minTemp": 500 },
"energyChange": -137,
"description": "Ethanol burns with blue flame. Clean-burning biofuel",
"descriptionRu": "Этанол горит синим пламенем. Чистое биотопливо",
"difficulty": 3
},
{
"id": "comb_h2s", "type": "combustion",
"reactants": [{ "id": "H2S", "count": 1 }, { "id": "O", "count": 3 }],
"products": [{ "id": "SO2", "count": 1 }, { "id": "H2O", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -52,
"description": "Hydrogen sulfide burns → sulfur dioxide + water. Converting one toxic gas to another",
"descriptionRu": "Сероводород горит → сернистый газ + вода. Превращение одного токсичного газа в другой",
"difficulty": 2
},
{
"id": "comb_co_full", "type": "combustion",
"reactants": [{ "id": "CO", "count": 1 }, { "id": "O", "count": 1 }],
"products": [{ "id": "CO2", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -28,
"description": "Carbon monoxide burns to carbon dioxide. Converting deadly poison to harmless gas",
"descriptionRu": "Угарный газ горит до углекислого. Превращение смертельного яда в безвредный газ",
"difficulty": 1
},
{
"id": "comb_glucose", "type": "combustion",
"reactants": [{ "id": "C6H12O6", "count": 1 }, { "id": "O", "count": 12 }],
"products": [{ "id": "CO2", "count": 6 }, { "id": "H2O", "count": 6 }],
"conditions": { "minTemp": 500 },
"energyChange": -280,
"description": "Glucose combustion — same as cellular respiration. Maximum energy release from sugar",
"descriptionRu": "Горение глюкозы — то же, что клеточное дыхание. Максимальное выделение энергии из сахара",
"difficulty": 3
},
{
"id": "repl_li_h2o", "type": "single-replacement",
"reactants": [{ "id": "Li", "count": 1 }, { "id": "H2O", "count": 1 }],
"products": [{ "id": "LiOH", "count": 1 }, { "id": "H", "count": 1 }],
"energyChange": -50,
"description": "Lithium fizzes gently in water → lithium hydroxide + hydrogen. Less violent than sodium",
"descriptionRu": "Литий тихо шипит в воде → гидроксид лития + водород. Менее бурно, чем натрий",
"difficulty": 1
},
{
"id": "repl_mg_hcl", "type": "single-replacement",
"reactants": [{ "id": "Mg", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "MgCl2", "count": 1 }, { "id": "H", "count": 2 }],
"energyChange": -46,
"description": "Magnesium dissolves in acid with vigorous hydrogen bubbling",
"descriptionRu": "Магний растворяется в кислоте с бурным выделением пузырьков водорода",
"difficulty": 2
},
{
"id": "repl_zn_hcl", "type": "single-replacement",
"reactants": [{ "id": "Zn", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "ZnCl2", "count": 1 }, { "id": "H", "count": 2 }],
"energyChange": -15,
"description": "Zinc dissolves in hydrochloric acid → zinc chloride + hydrogen gas",
"descriptionRu": "Цинк растворяется в соляной кислоте → хлорид цинка + водород",
"difficulty": 2
},
{
"id": "repl_fe_hcl", "type": "single-replacement",
"reactants": [{ "id": "Fe", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "FeCl2", "count": 1 }, { "id": "H", "count": 2 }],
"energyChange": -9,
"description": "Iron dissolves in acid → pale green iron(II) chloride + hydrogen",
"descriptionRu": "Железо растворяется в кислоте → бледно-зелёный хлорид железа(II) + водород",
"difficulty": 2
},
{
"id": "repl_ni_hcl", "type": "single-replacement",
"reactants": [{ "id": "Ni", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "NiCl2", "count": 1 }, { "id": "H", "count": 2 }],
"energyChange": -8,
"description": "Nickel dissolves slowly in HCl → green nickel chloride solution",
"descriptionRu": "Никель медленно растворяется в HCl → зелёный раствор хлорида никеля",
"difficulty": 2
},
{
"id": "repl_fe_cucl2", "type": "single-replacement",
"reactants": [{ "id": "Fe", "count": 1 }, { "id": "CuCl2", "count": 1 }],
"products": [{ "id": "FeCl2", "count": 1 }, { "id": "Cu", "count": 1 }],
"energyChange": -15,
"description": "Iron displaces copper from solution. Activity series: Fe > Cu",
"descriptionRu": "Железо вытесняет медь из раствора. Ряд активности: Fe > Cu",
"difficulty": 2
},
{
"id": "repl_zn_cucl2", "type": "single-replacement",
"reactants": [{ "id": "Zn", "count": 1 }, { "id": "CuCl2", "count": 1 }],
"products": [{ "id": "ZnCl2", "count": 1 }, { "id": "Cu", "count": 1 }],
"energyChange": -22,
"description": "Zinc displaces copper — red copper deposits on zinc surface",
"descriptionRu": "Цинк вытесняет медь — красная медь осаждается на поверхности цинка",
"difficulty": 2
},
{
"id": "repl_zn_fecl2", "type": "single-replacement",
"reactants": [{ "id": "Zn", "count": 1 }, { "id": "FeCl2", "count": 1 }],
"products": [{ "id": "ZnCl2", "count": 1 }, { "id": "Fe", "count": 1 }],
"energyChange": -7,
"description": "Zinc displaces iron from solution. Zinc is more reactive",
"descriptionRu": "Цинк вытесняет железо из раствора. Цинк активнее",
"difficulty": 2
},
{
"id": "repl_mg_cucl2", "type": "single-replacement",
"reactants": [{ "id": "Mg", "count": 1 }, { "id": "CuCl2", "count": 1 }],
"products": [{ "id": "MgCl2", "count": 1 }, { "id": "Cu", "count": 1 }],
"energyChange": -60,
"description": "Magnesium violently displaces copper. Extreme activity difference",
"descriptionRu": "Магний бурно вытесняет медь. Огромная разница активности",
"difficulty": 1
},
{
"id": "ab_lioh_hcl", "type": "acid-base",
"reactants": [{ "id": "LiOH", "count": 1 }, { "id": "HCl", "count": 1 }],
"products": [{ "id": "LiCl", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -55,
"description": "Neutralization: lithium hydroxide + hydrochloric acid → lithium chloride + water",
"descriptionRu": "Нейтрализация: гидроксид лития + соляная кислота → хлорид лития + вода",
"difficulty": 2
},
{
"id": "ab_naoh_hf", "type": "acid-base",
"reactants": [{ "id": "NaOH", "count": 1 }, { "id": "HF", "count": 1 }],
"products": [{ "id": "NaF", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -68,
"description": "Neutralizing deadly HF with lye → safe sodium fluoride + water",
"descriptionRu": "Нейтрализация опасного HF щёлочью → безопасный фторид натрия + вода",
"difficulty": 2
},
{
"id": "ab_naoh_hbr", "type": "acid-base",
"reactants": [{ "id": "NaOH", "count": 1 }, { "id": "HBr", "count": 1 }],
"products": [{ "id": "NaBr", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -56,
"description": "Neutralization: NaOH + HBr → sodium bromide + water",
"descriptionRu": "Нейтрализация: NaOH + HBr → бромид натрия + вода",
"difficulty": 2
},
{
"id": "ab_koh_hf", "type": "acid-base",
"reactants": [{ "id": "KOH", "count": 1 }, { "id": "HF", "count": 1 }],
"products": [{ "id": "KF", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -68,
"description": "Potassium hydroxide neutralizes hydrofluoric acid",
"descriptionRu": "Гидроксид калия нейтрализует плавиковую кислоту",
"difficulty": 2
},
{
"id": "ab_koh_hbr", "type": "acid-base",
"reactants": [{ "id": "KOH", "count": 1 }, { "id": "HBr", "count": 1 }],
"products": [{ "id": "KBr", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -56,
"description": "KOH + HBr → potassium bromide + water",
"descriptionRu": "KOH + HBr → бромид калия + вода",
"difficulty": 2
},
{
"id": "ab_caco3_hcl", "type": "acid-base",
"reactants": [{ "id": "CaCO3", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "CaCl2", "count": 1 }, { "id": "H2O", "count": 1 }, { "id": "CO2", "count": 1 }],
"energyChange": -12,
"description": "Limestone + acid → fizzing! Calcium chloride + water + CO₂. The cave dissolving reaction",
"descriptionRu": "Известняк + кислота → шипение! Хлорид кальция + вода + CO₂. Реакция растворения пещер",
"difficulty": 2
},
{
"id": "ab_cuo_hcl", "type": "acid-base",
"reactants": [{ "id": "CuO", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "CuCl2", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -13,
"description": "Copper oxide + acid → blue-green copper chloride solution + water",
"descriptionRu": "Оксид меди + кислота → сине-зелёный раствор хлорида меди + вода",
"difficulty": 2
},
{
"id": "ab_zno_hcl", "type": "acid-base",
"reactants": [{ "id": "ZnO", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "ZnCl2", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -14,
"description": "Zinc oxide + acid → zinc chloride + water. Classic oxide-acid reaction",
"descriptionRu": "Оксид цинка + кислота → хлорид цинка + вода. Классическая реакция оксида с кислотой",
"difficulty": 2
},
{
"id": "ab_mgo_hcl", "type": "acid-base",
"reactants": [{ "id": "MgO", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "MgCl2", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -15,
"description": "Antacid reaction: magnesium oxide neutralizes stomach acid",
"descriptionRu": "Антацидная реакция: оксид магния нейтрализует желудочную кислоту",
"difficulty": 2
},
{
"id": "ab_bao_hcl", "type": "acid-base",
"reactants": [{ "id": "BaO", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "BaCl2", "count": 1 }, { "id": "H2O", "count": 1 }],
"energyChange": -17,
"description": "Barium oxide + acid → toxic barium chloride. Handle carefully",
"descriptionRu": "Оксид бария + кислота → токсичный хлорид бария. Осторожно",
"difficulty": 2
},
{
"id": "ab_caoh2_hcl", "type": "acid-base",
"reactants": [{ "id": "CaOH2", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "CaCl2", "count": 1 }, { "id": "H2O", "count": 2 }],
"energyChange": -58,
"description": "Slaked lime + acid → calcium chloride + water. Water treatment",
"descriptionRu": "Гашёная известь + кислота → хлорид кальция + вода. Очистка воды",
"difficulty": 2
},
{
"id": "ab_na2o_hcl", "type": "acid-base",
"reactants": [{ "id": "Na2O", "count": 1 }, { "id": "HCl", "count": 2 }],
"products": [{ "id": "NaCl", "count": 2 }, { "id": "H2O", "count": 1 }],
"energyChange": -60,
"description": "Sodium oxide + acid → table salt + water",
"descriptionRu": "Оксид натрия + кислота → поваренная соль + вода",
"difficulty": 2
},
{
"id": "repl_na2o_h2o", "type": "single-replacement",
"reactants": [{ "id": "Na2O", "count": 1 }, { "id": "H2O", "count": 1 }],
"products": [{ "id": "NaOH", "count": 2 }],
"energyChange": -70,
"description": "Sodium oxide dissolves in water → caustic soda (NaOH). Exothermic!",
"descriptionRu": "Оксид натрия растворяется в воде → каустическая сода (NaOH). Экзотермическая!",
"difficulty": 1
},
{
"id": "decomp_nh3", "type": "decomposition",
"reactants": [{ "id": "NH3", "count": 1 }],
"products": [{ "id": "N", "count": 1 }, { "id": "H", "count": 3 }],
"conditions": { "minTemp": 1000 },
"energyChange": 5,
"description": "Ammonia decomposes at extreme heat → nitrogen + hydrogen. Reversed Haber process",
"descriptionRu": "Аммиак разлагается при экстремальном нагреве → азот + водород. Обратный процесс Габера",
"difficulty": 3
},
{
"id": "decomp_h2s", "type": "decomposition",
"reactants": [{ "id": "H2S", "count": 1 }],
"products": [{ "id": "H", "count": 2 }, { "id": "S", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": 2,
"description": "Thermal decomposition of hydrogen sulfide → hydrogen + sulfur",
"descriptionRu": "Термическое разложение сероводорода → водород + сера",
"difficulty": 3
},
{
"id": "decomp_hno3", "type": "decomposition",
"reactants": [{ "id": "HNO3", "count": 1 }],
"products": [{ "id": "N", "count": 1 }, { "id": "O", "count": 3 }, { "id": "H", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": 5,
"description": "Nitric acid decomposes under heat → brown toxic fumes",
"descriptionRu": "Азотная кислота разлагается при нагреве → бурые токсичные пары",
"difficulty": 3
},
{
"id": "decomp_h2so4", "type": "decomposition",
"reactants": [{ "id": "H2SO4", "count": 1 }],
"products": [{ "id": "S", "count": 1 }, { "id": "O", "count": 3 }, { "id": "H", "count": 2 }],
"conditions": { "minTemp": 1000 },
"energyChange": 10,
"description": "Sulfuric acid decomposition at extreme heat. Very endothermic",
"descriptionRu": "Разложение серной кислоты при экстремальном нагреве. Сильно эндотермическое",
"difficulty": 4
},
{
"id": "decomp_nacl_electro", "type": "decomposition",
"reactants": [{ "id": "NaCl", "count": 1 }],
"products": [{ "id": "Na", "count": 1 }, { "id": "Cl", "count": 1 }],
"conditions": { "requiresEnergy": true },
"energyChange": 41,
"description": "Electrolysis of molten salt → pure sodium + chlorine gas. Industrial sodium production",
"descriptionRu": "Электролиз расплава соли → чистый натрий + хлор. Промышленное получение натрия",
"difficulty": 3
},
{
"id": "decomp_mgcl2", "type": "decomposition",
"reactants": [{ "id": "MgCl2", "count": 1 }],
"products": [{ "id": "Mg", "count": 1 }, { "id": "Cl", "count": 2 }],
"conditions": { "requiresEnergy": true },
"energyChange": 64,
"description": "Electrolysis of molten MgCl₂ → magnesium metal + chlorine. Dow process",
"descriptionRu": "Электролиз расплава MgCl₂ → металлический магний + хлор. Процесс Дау",
"difficulty": 3
},
{
"id": "decomp_cacl2", "type": "decomposition",
"reactants": [{ "id": "CaCl2", "count": 1 }],
"products": [{ "id": "Ca", "count": 1 }, { "id": "Cl", "count": 2 }],
"conditions": { "requiresEnergy": true },
"energyChange": 80,
"description": "Electrolysis of molten CaCl₂ → pure calcium metal",
"descriptionRu": "Электролиз расплава CaCl₂ → чистый металлический кальций",
"difficulty": 3
},
{
"id": "decomp_al2o3", "type": "decomposition",
"reactants": [{ "id": "Al2O3", "count": 1 }],
"products": [{ "id": "Al", "count": 2 }, { "id": "O", "count": 3 }],
"conditions": { "requiresEnergy": true },
"energyChange": 84,
"description": "Hall-Héroult process: alumina electrolysis → aluminum. Most energy-intensive industrial process",
"descriptionRu": "Процесс Холла-Эру: электролиз глинозёма → алюминий. Самый энергоёмкий промышленный процесс",
"difficulty": 4
},
{
"id": "decomp_fecl3", "type": "decomposition",
"reactants": [{ "id": "FeCl3", "count": 1 }],
"products": [{ "id": "Fe", "count": 1 }, { "id": "Cl", "count": 3 }],
"conditions": { "minTemp": 1000 },
"energyChange": 40,
"description": "Iron(III) chloride thermal decomposition → iron + chlorine gas",
"descriptionRu": "Термическое разложение хлорида железа(III) → железо + хлор",
"difficulty": 3
},
{
"id": "redox_cr2o3_al", "type": "redox",
"reactants": [{ "id": "Cr2O3", "count": 1 }, { "id": "Al", "count": 2 }],
"products": [{ "id": "Cr", "count": 2 }, { "id": "Al2O3", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -54,
"description": "Chromium thermite: aluminium reduces chromium oxide. Used to produce pure chromium",
"descriptionRu": "Хромовый термит: алюминий восстанавливает оксид хрома. Производство чистого хрома",
"difficulty": 5
},
{
"id": "redox_wo3_al", "type": "redox",
"reactants": [{ "id": "WO3", "count": 1 }, { "id": "Al", "count": 2 }],
"products": [{ "id": "W", "count": 1 }, { "id": "Al2O3", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -70,
"description": "Tungsten extraction: aluminum reduces tungsten oxide to pure metal",
"descriptionRu": "Извлечение вольфрама: алюминий восстанавливает оксид вольфрама до чистого металла",
"difficulty": 5
},
{
"id": "redox_cuo_c", "type": "redox",
"reactants": [{ "id": "CuO", "count": 1 }, { "id": "C", "count": 1 }],
"products": [{ "id": "Cu", "count": 1 }, { "id": "CO", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -13,
"description": "Ancient copper smelting: carbon reduces copper ore to pure copper",
"descriptionRu": "Древняя медеплавка: углерод восстанавливает медную руду до чистой меди",
"difficulty": 3
},
{
"id": "redox_pbo_c", "type": "redox",
"reactants": [{ "id": "PbO", "count": 1 }, { "id": "C", "count": 1 }],
"products": [{ "id": "Pb", "count": 1 }, { "id": "CO", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -11,
"description": "Lead smelting: carbon reduces lead oxide to metallic lead",
"descriptionRu": "Свинцовая плавка: углерод восстанавливает оксид свинца до металлического свинца",
"difficulty": 3
},
{
"id": "redox_fe2o3_c", "type": "redox",
"reactants": [{ "id": "Fe2O3", "count": 1 }, { "id": "C", "count": 3 }],
"products": [{ "id": "Fe", "count": 2 }, { "id": "CO", "count": 3 }],
"conditions": { "minTemp": 1000 },
"energyChange": -49,
"description": "Iron smelting: carbon reduces iron ore. Foundation of civilization",
"descriptionRu": "Выплавка железа: углерод восстанавливает железную руду. Основа цивилизации",
"difficulty": 4
},
{
"id": "redox_coo_c", "type": "redox",
"reactants": [{ "id": "CoO", "count": 1 }, { "id": "C", "count": 1 }],
"products": [{ "id": "Co", "count": 1 }, { "id": "CO", "count": 1 }],
"conditions": { "minTemp": 1000 },
"energyChange": -10,
"description": "Carbon reduces cobalt oxide → pure cobalt. Blue pigment source",
"descriptionRu": "Углерод восстанавливает оксид кобальта → чистый кобальт. Источник синего пигмента",
"difficulty": 3
},
{
"id": "redox_fe2o3_co", "type": "redox",
"reactants": [{ "id": "Fe2O3", "count": 1 }, { "id": "CO", "count": 3 }],
"products": [{ "id": "Fe", "count": 2 }, { "id": "CO2", "count": 3 }],
"conditions": { "minTemp": 1000 },
"energyChange": -25,
"description": "Blast furnace: CO reduces iron ore to iron + CO₂. Industrial steelmaking",
"descriptionRu": "Доменная печь: CO восстанавливает железную руду до железа + CO₂. Промышленная металлургия",
"difficulty": 4
},
{
"id": "redox_cuo_h", "type": "redox",
"reactants": [{ "id": "CuO", "count": 1 }, { "id": "H", "count": 2 }],
"products": [{ "id": "Cu", "count": 1 }, { "id": "H2O", "count": 1 }],
"conditions": { "minTemp": 500 },
"energyChange": -13,
"description": "Hydrogen reduces copper oxide → shiny red copper appears + water",
"descriptionRu": "Водород восстанавливает оксид меди → появляется блестящая красная медь + вода",
"difficulty": 3
},
{
"id": "ferment_glucose", "type": "decomposition",
"reactants": [{ "id": "C6H12O6", "count": 1 }],
"products": [{ "id": "C2H5OH", "count": 2 }, { "id": "CO2", "count": 2 }],
"energyChange": -7,
"description": "Fermentation: yeast converts glucose → ethanol + CO₂. Birth of brewing and baking",
"descriptionRu": "Брожение: дрожжи превращают глюкозу → этанол + CO₂. Рождение пивоварения и хлебопечения",
"difficulty": 3
},
{
"id": "decomp_ch3cooh", "type": "decomposition",
"reactants": [{ "id": "CH3COOH", "count": 1 }],
"products": [{ "id": "C", "count": 2 }, { "id": "H", "count": 4 }, { "id": "O", "count": 2 }],
"conditions": { "minTemp": 1000 },
"energyChange": 5,
"description": "Thermal decomposition of acetic acid at extreme heat",
"descriptionRu": "Термическое разложение уксусной кислоты при экстремальном нагреве",
"difficulty": 3
} }
] ]

View File

@@ -8,7 +8,9 @@
import Phaser from 'phaser'; import Phaser from 'phaser';
import schoolsData from '../data/schools.json'; import schoolsData from '../data/schools.json';
import biomeDataArray from '../data/biomes.json';
import type { SchoolData, MetaState } from '../run/types'; import type { SchoolData, MetaState } from '../run/types';
import type { BiomeData } from '../world/types';
import { isSchoolUnlocked } from '../run/meta'; import { isSchoolUnlocked } from '../run/meta';
import { GAME_WIDTH, GAME_HEIGHT } from '../config'; import { GAME_WIDTH, GAME_HEIGHT } from '../config';
import { getAvailableBonuses, purchaseBonus, canAffordBonus, resetShopSession } from '../mycelium/shop'; import { getAvailableBonuses, purchaseBonus, canAffordBonus, resetShopSession } from '../mycelium/shop';
@@ -16,11 +18,14 @@ import { getGraphStats } from '../mycelium/graph';
import type { BonusEffect } from '../mycelium/types'; import type { BonusEffect } from '../mycelium/types';
const schools = schoolsData as SchoolData[]; const schools = schoolsData as SchoolData[];
const biomes = biomeDataArray as BiomeData[];
export class CradleScene extends Phaser.Scene { export class CradleScene extends Phaser.Scene {
private meta!: MetaState; private meta!: MetaState;
private selectedIndex = 0; private selectedIndex = 0;
private selectedBiomeIndex = 0;
private schoolCards: Phaser.GameObjects.Container[] = []; private schoolCards: Phaser.GameObjects.Container[] = [];
private biomeCards: { bg: Phaser.GameObjects.Rectangle; label: Phaser.GameObjects.Text }[] = [];
private particles: { x: number; y: number; vx: number; vy: number; alpha: number; radius: number }[] = []; private particles: { x: number; y: number; vx: number; vy: number; alpha: number; radius: number }[] = [];
private particleGraphics!: Phaser.GameObjects.Graphics; private particleGraphics!: Phaser.GameObjects.Graphics;
private introTimer = 0; private introTimer = 0;
@@ -36,7 +41,9 @@ export class CradleScene extends Phaser.Scene {
init(data: { meta: MetaState }): void { init(data: { meta: MetaState }): void {
this.meta = data.meta; this.meta = data.meta;
this.selectedIndex = 0; this.selectedIndex = 0;
this.selectedBiomeIndex = 0;
this.schoolCards = []; this.schoolCards = [];
this.biomeCards = [];
this.introTimer = 0; this.introTimer = 0;
this.introComplete = false; this.introComplete = false;
this.purchasedEffects = []; this.purchasedEffects = [];
@@ -124,7 +131,7 @@ export class CradleScene extends Phaser.Scene {
const cx = GAME_WIDTH / 2; const cx = GAME_WIDTH / 2;
// Title // Title
const title = this.add.text(cx, 60, 'СПОРОВАЯ КОЛЫБЕЛЬ', { const title = this.add.text(cx, 30, 'СПОРОВАЯ КОЛЫБЕЛЬ', {
fontSize: '28px', fontSize: '28px',
color: '#00ff88', color: '#00ff88',
fontFamily: 'monospace', fontFamily: 'monospace',
@@ -134,7 +141,7 @@ export class CradleScene extends Phaser.Scene {
title.setAlpha(0); title.setAlpha(0);
title.setDepth(10); title.setDepth(10);
const subtitle = this.add.text(cx, 100, 'Выбери свой путь', { const subtitle = this.add.text(cx, 65, 'Выбери биом и школу', {
fontSize: '14px', fontSize: '14px',
color: '#557755', color: '#557755',
fontFamily: 'monospace', fontFamily: 'monospace',
@@ -145,10 +152,13 @@ export class CradleScene extends Phaser.Scene {
this.tweens.add({ targets: [title, subtitle], alpha: 1, duration: 800 }); this.tweens.add({ targets: [title, subtitle], alpha: 1, duration: 800 });
// Biome selection row
this.createBiomeSelector(cx, 105);
// School cards // School cards
const cardWidth = 320; const cardWidth = 320;
const cardHeight = 260; const cardHeight = 220;
const startY = 160; const startY = 150;
const unlockedSchools = schools.filter(s => isSchoolUnlocked(this.meta, s.id)); const unlockedSchools = schools.filter(s => isSchoolUnlocked(this.meta, s.id));
for (let i = 0; i < unlockedSchools.length; i++) { for (let i = 0; i < unlockedSchools.length; i++) {
@@ -361,16 +371,98 @@ export class CradleScene extends Phaser.Scene {
} }
} }
/** Create the biome selection row */
private createBiomeSelector(cx: number, y: number): void {
const btnWidth = 200;
const btnHeight = 36;
const spacing = 12;
const totalWidth = biomes.length * (btnWidth + spacing) - spacing;
const startX = cx - totalWidth / 2 + btnWidth / 2;
const biomeColors: Record<string, number> = {
'catalytic-wastes': 0x886622,
'kinetic-mountains': 0x5577aa,
'verdant-forests': 0x228833,
};
for (let i = 0; i < biomes.length; i++) {
const biome = biomes[i];
const bx = startX + i * (btnWidth + spacing);
const isSelected = i === this.selectedBiomeIndex;
const color = biomeColors[biome.id] ?? 0x444444;
const bg = this.add.rectangle(bx, y, btnWidth, btnHeight,
isSelected ? color : 0x0a1a0f, 0.9);
bg.setStrokeStyle(isSelected ? 3 : 1, color);
bg.setDepth(10);
const label = this.add.text(bx, y, biome.nameRu, {
fontSize: '13px',
color: isSelected ? '#ffffff' : '#888888',
fontFamily: 'monospace',
fontStyle: isSelected ? 'bold' : 'normal',
});
label.setOrigin(0.5);
label.setDepth(10);
bg.setInteractive({ useHandCursor: true });
bg.on('pointerdown', () => {
this.selectedBiomeIndex = i;
this.refreshBiomeButtons();
});
bg.on('pointerover', () => {
if (i !== this.selectedBiomeIndex) {
bg.setStrokeStyle(2, 0x00ff88);
}
});
bg.on('pointerout', () => {
const sel = i === this.selectedBiomeIndex;
bg.setStrokeStyle(sel ? 3 : 1, color);
});
// Fade in
bg.setAlpha(0);
label.setAlpha(0);
this.tweens.add({ targets: [bg, label], alpha: 1, duration: 600, delay: 100 + i * 100 });
this.biomeCards.push({ bg, label });
}
}
/** Refresh biome button visual states */
private refreshBiomeButtons(): void {
const biomeColors: Record<string, number> = {
'catalytic-wastes': 0x886622,
'kinetic-mountains': 0x5577aa,
'verdant-forests': 0x228833,
};
for (let i = 0; i < this.biomeCards.length; i++) {
const card = this.biomeCards[i];
const biome = biomes[i];
const isSelected = i === this.selectedBiomeIndex;
const color = biomeColors[biome.id] ?? 0x444444;
card.bg.setFillStyle(isSelected ? color : 0x0a1a0f, 0.9);
card.bg.setStrokeStyle(isSelected ? 3 : 1, color);
card.label.setColor(isSelected ? '#ffffff' : '#888888');
card.label.setFontStyle(isSelected ? 'bold' : 'normal');
}
}
private startRun(school: SchoolData): void { private startRun(school: SchoolData): void {
// Flash effect // Flash effect
this.cameras.main.flash(300, 0, 255, 136); this.cameras.main.flash(300, 0, 255, 136);
const selectedBiome = biomes[this.selectedBiomeIndex];
this.time.delayedCall(400, () => { this.time.delayedCall(400, () => {
this.scene.start('GameScene', { this.scene.start('GameScene', {
meta: this.meta, meta: this.meta,
schoolId: school.id, schoolId: school.id,
runId: this.meta.totalRuns + 1, runId: this.meta.totalRuns + 1,
purchasedEffects: this.purchasedEffects, purchasedEffects: this.purchasedEffects,
biomeId: selectedBiome.id,
}); });
}); });
} }

View File

@@ -132,7 +132,10 @@ export class GameScene extends Phaser.Scene {
// Purchased bonuses from Cradle shop // Purchased bonuses from Cradle shop
private purchasedEffects: import('../mycelium/types').BonusEffect[] = []; private purchasedEffects: import('../mycelium/types').BonusEffect[] = [];
init(data: { meta: MetaState; schoolId: string; runId: number; purchasedEffects?: import('../mycelium/types').BonusEffect[] }): void { // Biome selection
private biomeId = 'catalytic-wastes';
init(data: { meta: MetaState; schoolId: string; runId: number; purchasedEffects?: import('../mycelium/types').BonusEffect[]; biomeId?: string }): void {
this.meta = data.meta; this.meta = data.meta;
this.runState = createRunState(data.runId, data.schoolId); this.runState = createRunState(data.runId, data.schoolId);
this.crisisState = null; this.crisisState = null;
@@ -141,6 +144,7 @@ export class GameScene extends Phaser.Scene {
this.hasDepositedThisRun = false; this.hasDepositedThisRun = false;
this.memoryFlashTimer = 0; this.memoryFlashTimer = 0;
this.purchasedEffects = data.purchasedEffects ?? []; this.purchasedEffects = data.purchasedEffects ?? [];
this.biomeId = data.biomeId ?? 'catalytic-wastes';
} }
create(): void { create(): void {
@@ -149,8 +153,8 @@ export class GameScene extends Phaser.Scene {
this.bridge = new PhaserBridge(this); this.bridge = new PhaserBridge(this);
this.projectileData = new Map(); this.projectileData = new Map();
// 2. Generate world // 2. Generate world — use selected biome
const biome = biomeDataArray[0] as BiomeData; const biome = (biomeDataArray as BiomeData[]).find(b => b.id === this.biomeId) ?? biomeDataArray[0] as BiomeData;
this.worldSeed = Date.now() % 1000000; this.worldSeed = Date.now() % 1000000;
const worldData = generateWorld(biome, this.worldSeed); const worldData = generateWorld(biome, this.worldSeed);
@@ -172,17 +176,18 @@ export class GameScene extends Phaser.Scene {
this.gameWorld.world, worldData.grid, biome, this.worldSeed, this.gameWorld.world, worldData.grid, biome, this.worldSeed,
); );
// 6. Initialize creature systems // 6. Initialize creature systems — filter by biome
const allSpecies = speciesDataArray as SpeciesData[]; const allSpecies = speciesDataArray as SpeciesData[];
this.speciesRegistry = new SpeciesRegistry(allSpecies); const biomeSpecies = allSpecies.filter(s => s.biome === biome.id);
this.speciesRegistry = new SpeciesRegistry(biomeSpecies);
this.speciesLookup = new Map<number, SpeciesData>(); this.speciesLookup = new Map<number, SpeciesData>();
for (const s of allSpecies) { for (const s of biomeSpecies) {
this.speciesLookup.set(s.speciesId, s); this.speciesLookup.set(s.speciesId, s);
} }
// 7. Spawn creatures across the map // 7. Spawn creatures across the map
this.creatureData = spawnInitialCreatures( this.creatureData = spawnInitialCreatures(
this.gameWorld.world, worldData.grid, biome, this.worldSeed, allSpecies, this.gameWorld.world, worldData.grid, biome, this.worldSeed, biomeSpecies,
); );
// 8. Create player at spawn position + inventory with starting kit // 8. Create player at spawn position + inventory with starting kit

View File

@@ -47,21 +47,27 @@ function determineTile(elevation: number, detail: number, biome: BiomeData): num
} }
} }
// Geyser overlay: on acid-shallow + very high detail noise // Interactive overlay (geysers / steam vents / hollow stumps) on specific base tile + high detail noise
if (baseTileId === gen.geyserOnTile && detail > gen.geyserThreshold) { if (baseTileId === gen.geyserOnTile && detail > gen.geyserThreshold) {
return findTileIdByName(biome, 'geyser'); return findInteractiveTileId(biome);
} }
// Mineral overlay: on walkable ground + high detail noise // Resource overlay (mineral veins / ore deposits / herb patches) on walkable ground + high detail noise
if (gen.mineralOnTiles.includes(baseTileId) && detail > gen.mineralThreshold) { if (gen.mineralOnTiles.includes(baseTileId) && detail > gen.mineralThreshold) {
return findTileIdByName(biome, 'mineral-vein'); return findResourceTileId(biome);
} }
return baseTileId; return baseTileId;
} }
/** Find tile ID by name, falling back to 0 if not found */ /** Find the interactive tile (geyser/steam-vent/hollow-stump), falling back to 0 */
function findTileIdByName(biome: BiomeData, name: string): number { function findInteractiveTileId(biome: BiomeData): number {
const tile = biome.tiles.find(t => t.name === name); const tile = biome.tiles.find(t => t.interactive);
return tile ? tile.id : 0;
}
/** Find the resource tile (mineral-vein/ore-deposit/herb-patch), falling back to 0 */
function findResourceTileId(biome: BiomeData): number {
const tile = biome.tiles.find(t => t.resource);
return tile ? tile.id : 0; return tile ? tile.id : 0;
} }

View File

@@ -39,9 +39,9 @@ export function spawnResources(
): Map<number, ResourceInfo> { ): Map<number, ResourceInfo> {
const resourceData = new Map<number, ResourceInfo>(); const resourceData = new Map<number, ResourceInfo>();
// Find tile IDs for resource types // Find tile IDs for resource types (generic: resource + interactive tiles)
const mineralTile = biome.tiles.find(t => t.name === 'mineral-vein'); const mineralTile = biome.tiles.find(t => t.resource);
const geyserTile = biome.tiles.find(t => t.name === 'geyser'); const geyserTile = biome.tiles.find(t => t.interactive);
const configs: ResourceTileConfig[] = []; const configs: ResourceTileConfig[] = [];

View File

@@ -8,8 +8,8 @@ import { ReactionEngine } from '../src/chemistry/engine';
// ============================================================================= // =============================================================================
describe('ElementRegistry', () => { describe('ElementRegistry', () => {
it('should load all 20 elements', () => { it('should load all 40 elements', () => {
expect(ElementRegistry.count()).toBe(20); expect(ElementRegistry.count()).toBe(40);
}); });
it('should look up elements by symbol', () => { it('should look up elements by symbol', () => {
@@ -59,6 +59,39 @@ describe('ElementRegistry', () => {
expect(ElementRegistry.isElement('NaCl')).toBe(false); expect(ElementRegistry.isElement('NaCl')).toBe(false);
expect(ElementRegistry.isElement('H2O')).toBe(false); expect(ElementRegistry.isElement('H2O')).toBe(false);
}); });
it('should have all 20 new Phase 9 elements', () => {
const newSymbols = ['Li', 'B', 'F', 'Ne', 'Ar', 'Ti', 'Cr', 'Mn', 'Co', 'Ni', 'As', 'Br', 'Ag', 'I', 'Ba', 'W', 'Pt', 'Pb', 'Bi', 'U'];
for (const sym of newSymbols) {
expect(ElementRegistry.has(sym), `Element ${sym} not found`).toBe(true);
}
});
it('should have correct data for new elements (real periodic table)', () => {
const li = ElementRegistry.getBySymbol('Li')!;
expect(li.atomicNumber).toBe(3);
expect(li.category).toBe('alkali-metal');
const f = ElementRegistry.getBySymbol('F')!;
expect(f.atomicNumber).toBe(9);
expect(f.category).toBe('halogen');
expect(f.state).toBe('gas');
expect(f.electronegativity).toBeCloseTo(3.98, 1); // Most electronegative
const br = ElementRegistry.getBySymbol('Br')!;
expect(br.state).toBe('liquid'); // Only liquid non-metal at room temp
const w = ElementRegistry.getBySymbol('W')!;
expect(w.atomicNumber).toBe(74);
expect(w.name).toBe('Tungsten');
const u = ElementRegistry.getBySymbol('U')!;
expect(u.atomicNumber).toBe(92);
expect(u.category).toBe('actinide');
const pt = ElementRegistry.getBySymbol('Pt')!;
expect(pt.category).toBe('transition-metal');
});
}); });
// ============================================================================= // =============================================================================
@@ -106,6 +139,32 @@ describe('CompoundRegistry', () => {
expect(CompoundRegistry.isCompound('H2O')).toBe(true); expect(CompoundRegistry.isCompound('H2O')).toBe(true);
expect(CompoundRegistry.isCompound('Na')).toBe(false); expect(CompoundRegistry.isCompound('Na')).toBe(false);
}); });
it('should load all 64 compounds', () => {
expect(CompoundRegistry.count()).toBe(64);
});
it('should have new Phase 9 compounds', () => {
const newIds = ['NH3', 'HF', 'HBr', 'TiO2', 'MnO2', 'As2O3', 'H2SO4', 'HNO3', 'CuO', 'FeCl3', 'CaCl2', 'NH4Cl', 'C6H12O6', 'CH3COOH'];
for (const id of newIds) {
expect(CompoundRegistry.has(id), `Compound ${id} not found`).toBe(true);
}
});
it('should correctly flag new dangerous compounds', () => {
const hf = CompoundRegistry.getById('HF')!;
expect(hf.properties.acidic).toBe(true);
expect(hf.properties.corrosive).toBe(true);
expect(hf.properties.toxic).toBe(true);
const h2so4 = CompoundRegistry.getById('H2SO4')!;
expect(h2so4.properties.acidic).toBe(true);
expect(h2so4.properties.oxidizer).toBe(true);
const as2o3 = CompoundRegistry.getById('As2O3')!;
expect(as2o3.properties.toxic).toBe(true);
expect(as2o3.name).toContain('Arsenic');
});
}); });
// ============================================================================= // =============================================================================
@@ -204,6 +263,104 @@ describe('ReactionEngine — success', () => {
expect(result.reaction!.energyChange).toBeGreaterThan(0); // Endothermic expect(result.reaction!.energyChange).toBeGreaterThan(0); // Endothermic
}); });
it('should produce HF from H + F', () => {
const result = ReactionEngine.react([
{ id: 'H', count: 1 },
{ id: 'F', count: 1 },
]);
expect(result.success).toBe(true);
expect(result.products).toEqual([{ id: 'HF', count: 1 }]);
});
it('should produce NH3 via Haber process (N + 3H with Fe catalyst + heat)', () => {
const result = ReactionEngine.react(
[
{ id: 'N', count: 1 },
{ id: 'H', count: 3 },
],
{ minTemp: 500, catalyst: 'Fe' },
);
expect(result.success).toBe(true);
expect(result.products).toEqual([{ id: 'NH3', count: 1 }]);
});
it('should produce TiO2 from Ti + 2O with extreme heat', () => {
const result = ReactionEngine.react(
[
{ id: 'Ti', count: 1 },
{ id: 'O', count: 2 },
],
{ minTemp: 1000 },
);
expect(result.success).toBe(true);
expect(result.products).toEqual([{ id: 'TiO2', count: 1 }]);
});
it('should produce tungsten via WO3 + Al redox', () => {
const result = ReactionEngine.react(
[
{ id: 'WO3', count: 1 },
{ id: 'Al', count: 2 },
],
{ minTemp: 1000 },
);
expect(result.success).toBe(true);
expect(result.products).toContainEqual({ id: 'W', count: 1 });
expect(result.products).toContainEqual({ id: 'Al2O3', count: 1 });
});
it('should neutralize HF with NaOH (acid-base)', () => {
const result = ReactionEngine.react([
{ id: 'NaOH', count: 1 },
{ id: 'HF', count: 1 },
]);
expect(result.success).toBe(true);
expect(result.products).toContainEqual({ id: 'NaF', count: 1 });
expect(result.products).toContainEqual({ id: 'H2O', count: 1 });
});
it('should dissolve Zn in HCl (single-replacement)', () => {
const result = ReactionEngine.react([
{ id: 'Zn', count: 1 },
{ id: 'HCl', count: 2 },
]);
expect(result.success).toBe(true);
expect(result.products).toContainEqual({ id: 'ZnCl2', count: 1 });
expect(result.products).toContainEqual({ id: 'H', count: 2 });
});
it('should displace Cu with Fe from CuCl2', () => {
const result = ReactionEngine.react([
{ id: 'Fe', count: 1 },
{ id: 'CuCl2', count: 1 },
]);
expect(result.success).toBe(true);
expect(result.products).toContainEqual({ id: 'Cu', count: 1 });
expect(result.products).toContainEqual({ id: 'FeCl2', count: 1 });
});
it('should ferment glucose into ethanol + CO2', () => {
const result = ReactionEngine.react([
{ id: 'C6H12O6', count: 1 },
]);
expect(result.success).toBe(true);
expect(result.products).toContainEqual({ id: 'C2H5OH', count: 2 });
expect(result.products).toContainEqual({ id: 'CO2', count: 2 });
});
it('should produce H2SO4 via Contact process (Pt catalyst)', () => {
const result = ReactionEngine.react(
[
{ id: 'S', count: 1 },
{ id: 'O', count: 3 },
{ id: 'H', count: 2 },
],
{ catalyst: 'Pt' },
);
expect(result.success).toBe(true);
expect(result.products).toEqual([{ id: 'H2SO4', count: 1 }]);
});
it('reactant order should not matter (key is sorted)', () => { it('reactant order should not matter (key is sorted)', () => {
const r1 = ReactionEngine.react([ const r1 = ReactionEngine.react([
{ id: 'Cl', count: 1 }, { id: 'Cl', count: 1 },
@@ -234,6 +391,16 @@ describe('ReactionEngine — failures', () => {
expect(result.failureReasonRu).toContain('благородный газ'); expect(result.failureReasonRu).toContain('благородный газ');
}); });
it('should reject reactions with new noble gases (Ne, Ar)', () => {
const ne = ReactionEngine.react([{ id: 'Ne', count: 1 }, { id: 'F', count: 1 }]);
expect(ne.success).toBe(false);
expect(ne.failureReason).toContain('noble gas');
const ar = ReactionEngine.react([{ id: 'Ar', count: 1 }, { id: 'Cl', count: 1 }]);
expect(ar.success).toBe(false);
expect(ar.failureReason).toContain('noble gas');
});
it('should reject gold reactions with explanation', () => { it('should reject gold reactions with explanation', () => {
const result = ReactionEngine.react([ const result = ReactionEngine.react([
{ id: 'Au', count: 1 }, { id: 'Au', count: 1 },
@@ -309,8 +476,8 @@ describe('ReactionEngine — failures', () => {
// ============================================================================= // =============================================================================
describe('ReactionEngine — metadata', () => { describe('ReactionEngine — metadata', () => {
it('should have 30+ registered reactions', () => { it('should have 100+ registered reactions', () => {
expect(ReactionEngine.count()).toBeGreaterThanOrEqual(30); expect(ReactionEngine.count()).toBeGreaterThanOrEqual(100);
}); });
it('should look up reactions by id', () => { it('should look up reactions by id', () => {

View File

@@ -71,8 +71,8 @@ function createPlayerEntity(world: World, x: number, y: number): number {
// ─── Species Data ──────────────────────────────────────────────── // ─── Species Data ────────────────────────────────────────────────
describe('Species Data', () => { describe('Species Data', () => {
it('loads 3 species from JSON', () => { it('loads 9 species from JSON (3 per biome)', () => {
expect(allSpecies).toHaveLength(3); expect(allSpecies).toHaveLength(9);
}); });
it('has Crystallid with correct properties', () => { it('has Crystallid with correct properties', () => {
@@ -128,7 +128,7 @@ describe('Species Registry', () => {
}); });
it('has correct count', () => { it('has correct count', () => {
expect(registry.count).toBe(3); expect(registry.count).toBe(9);
}); });
it('looks up by string ID', () => { it('looks up by string ID', () => {
@@ -148,7 +148,27 @@ describe('Species Registry', () => {
it('returns all species', () => { it('returns all species', () => {
const all = registry.getAll(); const all = registry.getAll();
expect(all).toHaveLength(3); expect(all).toHaveLength(9);
});
it('can look up new Phase 9 species', () => {
expect(registry.get('pendulum')?.biome).toBe('kinetic-mountains');
expect(registry.get('mechanoid')?.biome).toBe('kinetic-mountains');
expect(registry.get('resonator')?.biome).toBe('kinetic-mountains');
expect(registry.get('symbiote')?.biome).toBe('verdant-forests');
expect(registry.get('mimic')?.biome).toBe('verdant-forests');
expect(registry.get('spore-bearer')?.biome).toBe('verdant-forests');
});
it('each biome has exactly 3 species', () => {
const all = registry.getAll();
const byBiome = new Map<string, number>();
for (const s of all) {
byBiome.set(s.biome, (byBiome.get(s.biome) ?? 0) + 1);
}
expect(byBiome.get('catalytic-wastes')).toBe(3);
expect(byBiome.get('kinetic-mountains')).toBe(3);
expect(byBiome.get('verdant-forests')).toBe(3);
}); });
}); });

View File

@@ -4,8 +4,9 @@ import { createSeededNoise, sampleNoise } from '../src/world/noise';
import { generateWorld } from '../src/world/generator'; import { generateWorld } from '../src/world/generator';
import type { BiomeData } from '../src/world/types'; import type { BiomeData } from '../src/world/types';
const allBiomes = biomeDataArray as BiomeData[];
// Load the first biome — structural compatibility with BiomeData // Load the first biome — structural compatibility with BiomeData
const biome = biomeDataArray[0] as BiomeData; const biome = allBiomes[0];
// ─── Noise ────────────────────────────────────────────────────── // ─── Noise ──────────────────────────────────────────────────────
@@ -181,3 +182,139 @@ describe('World Generation', () => {
} }
}); });
}); });
// ─── Multi-Biome Support (Phase 9) ──────────────────────────────
describe('Multi-Biome Data', () => {
it('has 3 biomes loaded', () => {
expect(allBiomes).toHaveLength(3);
});
it('each biome has a unique id', () => {
const ids = allBiomes.map(b => b.id);
expect(new Set(ids).size).toBe(3);
expect(ids).toContain('catalytic-wastes');
expect(ids).toContain('kinetic-mountains');
expect(ids).toContain('verdant-forests');
});
it('each biome has 8 tile types with sequential IDs', () => {
for (const b of allBiomes) {
expect(b.tiles).toHaveLength(8);
b.tiles.forEach((tile, index) => {
expect(tile.id, `${b.id}: tile ${index}`).toBe(index);
});
}
});
it('each biome has an interactive tile and a resource tile', () => {
for (const b of allBiomes) {
const interactive = b.tiles.find(t => t.interactive);
const resource = b.tiles.find(t => t.resource);
expect(interactive, `${b.id}: no interactive tile`).toBeDefined();
expect(resource, `${b.id}: no resource tile`).toBeDefined();
}
});
it('each biome has valid elevation rules covering [0, 1]', () => {
for (const b of allBiomes) {
const rules = b.generation.elevationRules;
expect(rules.length).toBeGreaterThan(0);
expect(rules[rules.length - 1].below).toBe(1);
const validIds = new Set(b.tiles.map(t => t.id));
for (const rule of rules) {
expect(validIds.has(rule.tileId), `${b.id}: invalid tileId ${rule.tileId}`).toBe(true);
}
}
});
});
describe('Kinetic Mountains Generation', () => {
const mtns = allBiomes.find(b => b.id === 'kinetic-mountains')!;
it('generates correct-size grid', () => {
const world = generateWorld(mtns, 42);
expect(world.grid).toHaveLength(mtns.mapHeight);
expect(world.grid[0]).toHaveLength(mtns.mapWidth);
});
it('all tile IDs are valid', () => {
const world = generateWorld(mtns, 42);
const validIds = new Set(mtns.tiles.map(t => t.id));
for (const row of world.grid) {
for (const tileId of row) {
expect(validIds.has(tileId)).toBe(true);
}
}
});
it('has diverse tiles with no single type > 60%', () => {
const world = generateWorld(mtns, 42);
const counts = new Map<number, number>();
for (const row of world.grid) {
for (const t of row) counts.set(t, (counts.get(t) ?? 0) + 1);
}
const total = mtns.mapWidth * mtns.mapHeight;
expect(counts.size).toBeGreaterThanOrEqual(4);
for (const count of counts.values()) {
expect(count / total).toBeLessThan(0.6);
}
});
it('generates chasms (low elevation)', () => {
const world = generateWorld(mtns, 42);
const chasmId = mtns.tiles.find(t => t.name === 'chasm')?.id;
expect(world.grid.some(row => row.includes(chasmId!))).toBe(true);
});
it('generates ore deposits (resources)', () => {
const world = generateWorld(mtns, 42);
const oreId = mtns.tiles.find(t => t.resource)?.id;
expect(world.grid.some(row => row.includes(oreId!))).toBe(true);
});
});
describe('Verdant Forests Generation', () => {
const forest = allBiomes.find(b => b.id === 'verdant-forests')!;
it('generates correct-size grid', () => {
const world = generateWorld(forest, 42);
expect(world.grid).toHaveLength(forest.mapHeight);
expect(world.grid[0]).toHaveLength(forest.mapWidth);
});
it('all tile IDs are valid', () => {
const world = generateWorld(forest, 42);
const validIds = new Set(forest.tiles.map(t => t.id));
for (const row of world.grid) {
for (const tileId of row) {
expect(validIds.has(tileId)).toBe(true);
}
}
});
it('has diverse tiles with no single type > 60%', () => {
const world = generateWorld(forest, 42);
const counts = new Map<number, number>();
for (const row of world.grid) {
for (const t of row) counts.set(t, (counts.get(t) ?? 0) + 1);
}
const total = forest.mapWidth * forest.mapHeight;
expect(counts.size).toBeGreaterThanOrEqual(4);
for (const count of counts.values()) {
expect(count / total).toBeLessThan(0.6);
}
});
it('generates bogs (low elevation)', () => {
const world = generateWorld(forest, 42);
const bogId = forest.tiles.find(t => t.name === 'bog')?.id;
expect(world.grid.some(row => row.includes(bogId!))).toBe(true);
});
it('generates herb patches (resources)', () => {
const world = generateWorld(forest, 42);
const herbId = forest.tiles.find(t => t.resource)?.id;
expect(world.grid.some(row => row.includes(herbId!))).toBe(true);
});
});