Add final progression to tiny sword, fixes and tweeks required

This commit is contained in:
2026-05-15 00:47:38 +02:00
parent 66666defcb
commit 738381a16b
43 changed files with 1127 additions and 339 deletions

View File

@@ -0,0 +1,388 @@
# Tiny Sword — Progression Plan
Full progression design for a playable idle game, from first click to victory.
## Overview
The game has 8 phases. Each phase is gated behind a goal. Completing the goal unlocks new buildings, buffs, or systems that accelerate progress toward the next phase.
The Devil Idol is visible from the start as a long-term goal — destroying it is the one-time win condition. Prestige loops make it asymptotically easier.
---
## Phase Table
| Phase | Goal | Threshold | Unlocks |
|---|---|---|---|
| 1 | *(none)* | Start | Gold Mine (click only, no auto-production) |
| 2 | `gold_total_30` | 30 total gold | Gold Clicker, Gold Dynamo, Summon Worker buffs |
| 3 | `gold_total_1300` | 1,300 total gold | Farm building (food economy begins) |
| 4 | `gold_total_13k` | 13,000 total gold | Forestry building (wood economy), Farm Dynamo, Forest Dynamo |
| 5 | `gold_350k_wood_20k` | 350K gold + 20K wood | **Prestige** (Castle) + **Research** (Monastery) |
| 6 | `gold_2M_food_200k_wood_200k` | 2M gold + 200K food + 200K wood | **Alchemy Tower** |
| 7 | *(post-alchemy)* | — | Alchemy buffs (spend mana stone / cognite / philosopher stone) |
| 8 | `gold_50M_food_5M_wood_5M` | 50M gold + 5M food + 5M wood | **Barracks** + **Devil Idol fight** |
> **Note**: Phase 7 has no dedicated goal — it unlocks implicitly when the Alchemy Tower is active and the player can craft alchemy resources. The Phase 8 goal only needs to be reachable after Alchemy buffs have been applied.
---
## Phase Details
### Phase 1 — Start
**State**: Gold Mine is visible and unlocked, 0 owned, 0 workers.
**Action**: Player clicks the Gold Mine to earn gold manually (1 gold / click, 0.2s cooldown).
**Exit**: Accumulate 30 total gold → Phase 2.
---
### Phase 2 — First Automation
**Goal**: `gold_total_30` (30 total gold)
**Unlocks**:
| Buff | Kind | Cost | Effect | Max Level |
|---|---|---|---|---|
| Gold Clicker | MANUAL_CLICK_MULTIPLIER | Gold | ×(1 + 1×level) click multiplier | 4 |
| Gold Dynamo | AUTO_PRODUCTION_MULTIPLIER | Food | ×(1 + 1×level) auto prod | 10 |
| Summon Worker | RESOURCE_PURCHASE | Gold | Grants 1 worker | ∞ |
**Design note**: Gold Dynamo costs food but Farm isn't unlocked until Phase 3. This is intentional — the buff is visible but unusable until food flows. It creates anticipation.
**Exit**: Buy Summon Worker (200 gold) → get 1 worker → buy first Gold Mine (1 worker) → auto-production begins at 20 gold/s. Accumulate 1,300 total gold → Phase 3.
---
### Phase 3 — Food Economy
**Goal**: `gold_total_1300` (1,300 total gold)
**Unlocks**:
- **Farm** building — starts with 1 owned, produces 20 food/s, purchasable with workers
**New loop**: Gold → workers → more Gold Mines + more Farms. Food accumulates. Gold Dynamo (unlocked in Phase 2) now becomes purchasable with food, multiplying gold mine output.
**Exit**: Accumulate 13,000 total gold → Phase 4.
---
### Phase 4 — Wood Economy
**Goal**: `gold_total_13k` (13,000 total gold)
**Unlocks**:
- **Forestry** building — starts with 1 owned, produces 20 wood/s, purchasable with workers
- **Farm Dynamo** buff — AUTO_PRODUCTION_MULTIPLIER for Farm, costs food, max 10
- **Forest Dynamo** buff — AUTO_PRODUCTION_MULTIPLIER for Forestry, costs food, max 10
**New loop**: Wood flows alongside gold and food. Three parallel production lines scale independently.
**Exit**: Accumulate 350,000 gold + 20,000 wood → Phase 5.
---
### Phase 5 — Prestige + Research
**Goal**: `gold_350k_wood_20k` (350,000 total gold + 20,000 total wood)
**Unlocks**:
- **Prestige panel** at Castle becomes visible and interactive
- **Research panel** at Monastery becomes visible and interactive
#### Prestige System
| Config Property | Value |
|---|---|
| Source basis | RUN_TOTAL (gold earned this run) |
| Formula | POWER, exponent 0.5, scale 1.0 |
| Threshold | 50,000 gold (per prestige point) |
| Rounding | FLOOR |
**First prestige estimate**: At 350K gold → `floor(sqrt(350000/50000))` = `floor(sqrt(7))` = `floor(2.64)` = **2 ascension points**.
**Second run**: With prestige buffs applied and ~500K gold → `floor(sqrt(10))` = **3 ascension points**.
`total_prestige_earned` persists across resets — it's a strictly increasing counter that never resets. It feeds the prestige multiplier (`base_multiplier + total_prestige_earned × multiplier_per_prestige`).
**Prestige Buff Graph** (purchasable with ascension points):
| Node | Cost | Prerequisites | Effect |
|---|---|---|---|
| Golden Touch | 1 ascension | *(none)* | Gold Mine ×2 production |
| Fertile Grounds | 2 ascension | Golden Touch | Farm ×2 production |
| Wood Touch | 3 ascension | Fertile Grounds | Forestry ×2 production |
| Martial Prowess | 5 ascension | Wood Touch | Barracks ×2 unit production *(Phase 8)* |
#### Research System
Three research tracks at the Monastery:
| Track | Linked Generator | XP Source |
|---|---|---|
| Gold Mine Research | Gold Mine | Gold production |
| Farm Research | Farm | Food production |
| Forestry Research | Forestry | Wood production |
One track active at a time. XP scales with workers assigned to research (`research_workers`). Default: 0.01 XP per currency unit, 100 XP for level 1, ×1.5 growth per level, +0.1 multiplier per level.
**Exit**: Accumulate 2M gold + 200K food + 200K wood → Phase 6.
---
### Phase 6 — Alchemy Tower
**Goal**: `gold_2M_food_200k_wood_200k` (2,000,000 total gold + 200,000 food + 200,000 wood)
**Unlocks**:
- **Alchemy Tower** building — passively produces Magic Gold
#### Alchemy Tower Mechanics
- Cycles of base 5 seconds, producing 1 Magic Gold per cycle
- Cycle time grows ×1.2 per completed cycle
- Workers can be assigned (1 worker each, up to 10) for +10% speed each
- Workers assigned here are separate from research workers (spent from worker currency)
#### Crafting Recipes
| Recipe | Input | Output |
|---|---|---|
| Mana Stone | 10 Magic Gold | 1 Mana Stone |
| Cognite | 25 Magic Gold | 1 Cognite |
| Philosopher Stone | 10 Mana Stone + 10 Cognite | 1 Philosopher Stone |
**Exit**: Build up alchemy resources → Phase 7 (implicit).
---
### Phase 7 — Alchemy Buffs
**Prerequisite**: Alchemy Tower active, player can craft resources.
Three new buffs, purchasable with alchemy resources:
| Buff | Cost Currency | Target | Effect | Max Level |
|---|---|---|---|---|
| Fertile Infusion | Mana Stone | Farm | ×2 production per level | 5 |
| Sylvan Cognite | Cognite | Forestry | ×2 production per level | 5 |
| Opus Magnum | Philosopher Stone | Gold Mine | ×3 production per level | 5 |
Added to the buff catalogue. Available via the existing buff purchase UI in each generator's panel.
**Exit**: Accumulate 50M gold + 5M food + 5M wood → Phase 8.
---
### Phase 8 — Devil Idol (Finale)
**Goal**: `gold_50M_food_5M_wood_5M` (50,000,000 total gold + 5,000,000 food + 5,000,000 wood)
**Unlocks**:
- **Barracks** building — produces Military Units (pure damage currency)
- **Devil Idol** becomes targetable
#### Barracks
| Property | Value |
|---|---|
| Produces | `unit` currency |
| Purchase cost | Workers |
| Unlock goal | Phase 8 goal |
| Research track | Shares with ? or none (TBD) |
| Prestige buff | Martial Prowess (×2 unit production) |
#### Devil Idol
| Property | Value |
|---|---|
| Visible from | Start (always visible in world) |
| Targetable from | Phase 8 |
| HP | `1e12` (1,000,000,000,000) — defined in an exported resource |
| Damage mechanic | Click idol to spend 1 unit → deal 1 damage. Or "Send Army" button for bulk spend. |
| Win condition | HP ≤ 0 → victory signal (TBD: victory screen, credits, etc.) |
#### Asymptotic Loop
Without prestige: defeating the idol would require 10^12 units, which with baseline production is essentially infinite.
With prestige: each loop applies Martial Prowess (+×2 per level) to Barracks production. A player with 5 ascension points in Martial Prowess produces ×32 units per cycle. As they earn more ascension points across runs, unit production scales multiplicatively, asymptotically reducing the "time to kill."
The idol HP never resets — it's persistent across prestige. Each prestige loop chips away at it.
---
## Currency Catalogue (Complete)
| Currency | ID | Produced By | Used For |
|---|---|---|---|
| Gold | `gold` | Gold Mine | Buff purchases, worker generation |
| Worker | `worker` | Summon Worker buff | Purchasing generators, research assignment, alchemy workers |
| Food | `food` | Farm | Buff purchases |
| Wood | `wood` | Forestry | Goal requirements |
| Ascension | `ascension` | Prestige resets | Prestige buff graph |
| Magic Gold | `magic_gold` | Alchemy Tower | Crafting mana stones + cognite |
| Mana Stone | `mana_stone` | Craft (10 magic gold) | Crafting philosopher stones, Fertile Infusion buff |
| Cognite | `cognite` | Craft (25 magic gold) | Crafting philosopher stones, Sylvan Cognite buff |
| Philosopher Stone | `philosoper_stone` | Craft (10 mana + 10 cognite) | Opus Magnum buff |
| Unit | `unit` | Barracks | Devil Idol damage |
---
## Buff Catalogue (Complete)
| Buff | ID | Kind | Cost | Unlock Goal | Max Lvl | Target |
|---|---|---|---|---|---|---|
| Gold Clicker | `gold_click_focus` | CLICK_MULT | Gold | `gold_total_30` | 4 | Gold Mine |
| Gold Dynamo | `gold_auto_flux` | AUTO_MULT | Food | `gold_total_30` | 10 | Gold Mine |
| Summon Worker | `summon_worker` | RESOURCE | Gold | `gold_total_30` | ∞ | Worker |
| Farm Dynamo | `farm_auto_flux` | AUTO_MULT | Food | `gold_total_13k` | 10 | Farm |
| Forest Dynamo | `forestry_auto_flux` | AUTO_MULT | Food | `gold_total_13k` | 10 | Forestry |
| Fertile Infusion | *(new)* | AUTO_MULT | Mana Stone | *(alchemy active)* | 5 | Farm |
| Sylvan Cognite | *(new)* | AUTO_MULT | Cognite | *(alchemy active)* | 5 | Forestry |
| Opus Magnum | *(new)* | AUTO_MULT | Philo Stone | *(alchemy active)* | 5 | Gold Mine |
---
## Goal Catalogue (Complete)
| Goal ID | Requirements | Unlock Behavior | Phase |
|---|---|---|---|
| `gold_total_30` | 30 gold | AUTOMATIC | 2 |
| `gold_total_1300` | 1,300 gold | MANUAL | 3 |
| `gold_total_13k` | 13,000 gold | MANUAL | 4 |
| `gold_350k_wood_20k` | 350,000 gold + 20,000 wood | MANUAL | 5 |
| `gold_2M_food_200k_wood_200k` *(new)* | 2M gold + 200K food + 200K wood | MANUAL | 6 |
| `gold_50M_food_5M_wood_5M` *(new)* | 50M gold + 5M food + 5M wood | MANUAL | 8 |
---
## Prestige Buff Graph (Complete)
```
Golden Touch (1pt)
Fertile Grounds (2pt)
Wood Touch (3pt)
Martial Prowess (5pt)
```
| Node | Cost | Prerequisites | Effect | Target |
|---|---|---|---|---|
| Golden Touch | 1 | none | ×2 production | Gold Mine |
| Fertile Grounds | 2 | Golden Touch | ×2 production | Farm |
| Wood Touch | 3 | Fertile Grounds | ×2 production | Forestry |
| Martial Prowess | 5 | Wood Touch | ×2 production | Barracks |
---
## Buildings (Complete)
| Building | Scene | Generates | Cost Currency | Unlock Goal |
|---|---|---|---|---|
| Gold Mine | `gold_mine.tscn` | Gold | Worker | *(none)* |
| Farm | `farm.tscn` | Food | Worker | `gold_total_1300` |
| Forestry | `forestry.tscn` | Wood | Worker | `gold_total_13k` |
| Monastery | `monastery.tscn` | *(none — Research UI)* | — | `gold_350k_wood_20k` (panel visible) |
| Castle | `castle.tscn` | *(none — Prestige UI)* | — | `gold_350k_wood_20k` (panel visible) |
| Alchemy Tower | `alchemy_tower.tscn` | Magic Gold | — | `gold_2M_food_200k_wood_200k` *(new)* |
| Barracks | `barracks.tscn` *(new)* | Unit | Worker | `gold_50M_food_5M_wood_5M` *(new)* |
| Devil Idol | `devil_idol.tscn` *(new)* | *(none — damage sink)* | — | `gold_50M_food_5M_wood_5M` (targetable) |
---
## Implementation Checklist
### Phase 12 (already exists)
- [x] Gold Mine building + generator
- [x] Gold Clicker, Gold Dynamo, Summon Worker buffs
- [x] `gold_total_30` goal
### Phase 34 (already exists)
- [x] Farm building + generator
- [x] `gold_total_1300` goal
- [x] Forestry building + generator
- [x] Farm Dynamo, Forest Dynamo buffs
- [x] `gold_total_13k` goal
### Phase 5 — Prestige + Research Visibility
- [ ] **`castle.gd`**: Uncomment `_prestige_panel.visible = true`, gate behind `gold_350k_wood_20k` goal completion
- [ ] **`primary_prestige.tres`**: Tune basis → RUN_TOTAL, source → `"gold"`, threshold → 50,000, exponent → 0.5
- [ ] **`monastery.gd`**: Gate `_research_panel.visible` behind `gold_350k_wood_20k` goal completion
- [ ] **`prestige_buff_catalogue.tres`**: Add Wood Touch + Martial Prowess nodes
- [x] `gold_350k_wood_20k` goal (already exists)
### Phase 6 — Alchemy Tower Gating
- [ ] **New goal `.tres`**: `gold_2M_food_200k_wood_200k`
- [ ] **`ts_goal_catalogue.tres`**: Register new goal
- [ ] **`alchemy_tower_data.tres`** or **`alchemy_tower.tscn`**: Add `unlock_goal` field
- [ ] Wire unlock to Alchemy Tower visibility
### Phase 7 — Alchemy Buffs
- [ ] **New buff `.tres`**: Fertile Infusion (mana stone → farm, ×2, max 5)
- [ ] **New buff `.tres`**: Sylvan Cognite (cognite → forestry, ×2, max 5)
- [ ] **New buff `.tres`**: Opus Magnum (philosopher stone → gold mine, ×3, max 5)
- [ ] **`ts_buff_catalogue.tres`**: Register the 3 new buffs
### Phase 8 — Barracks + Devil Idol
- [ ] **New goal `.tres`**: `gold_50M_food_5M_wood_5M`
- [ ] **`ts_goal_catalogue.tres`**: Register new goal
- [ ] **New currency `.tres`**: Unit (`unit`)
- [ ] **`ts_currency_catalogue.tres`**: Register unit currency
- [ ] **New generator data `.tres`**: `barracks_generator.tres`
- [ ] **New scene**: `barracks.tscn` (NG2D, sprite, Area2D, CurrencyGenerator, GeneratorContainer)
- [ ] **New scene**: `devil_idol.tscn` (NG2D, sprite, Area2D, click handler, HP display, win logic)
- [ ] **New prestige buff `.tres`**: Martial Prowess (×2 barracks production, cost 5 ascension, parent: Wood Touch)
- [ ] **`prestige_buff_catalogue.tres`**: Register Martial Prowess
- [ ] **`tiny_sword.tscn`**: Place Barracks + Devil Idol in world
- [ ] Victory condition handling (TBD: signal, screen, save state)
### Research (Phase 5+, already functional)
- [x] ResearchData for Gold Mine, Farm, Forestry
- [x] ResearchPanel at Monastery
- [x] ResearchRow UI
- [x] XP generation in CurrencyGenerator
- [ ] *(optional)*: Add Barracks research track
- [ ] *(optional)*: Tune per-track values (XP required, multiplier growth)
---
## File Map
```
docs/gyms/tiny_sword/
├── PROGRESSION.md ← this file
├── tiny_sword.tscn ← main scene (add Barracks + Devil Idol)
├── currencies/
│ ├── ts_currency_catalogue.tres ← register "unit" currency
│ └── unit.tres ← NEW: unit currency definition
├── buffs/
│ ├── ts_buff_catalogue.tres ← register alchemy buffs
│ ├── fertile_infusion_buff.tres ← NEW
│ ├── sylvan_cognite_buff.tres ← NEW
│ └── opus_magnum_buff.tres ← NEW
├── goals/
│ ├── ts_goal_catalogue.tres ← register new phase 6 + 8 goals
│ ├── gold_2M_food_200k_wood_200k.tres ← NEW
│ └── gold_50M_food_5M_wood_5M.tres ← NEW
├── prestige/
│ ├── primary_prestige.tres ← tune: RUN_TOTAL, gold, 50K threshold
│ ├── prestige_buff_catalogue.tres ← register Wood Touch + Martial Prowess
│ ├── prestige_buff_wood_boost.tres ← existing (may need cost/parent update)
│ └── prestige_buff_barracks_boost.tres ← NEW
├── buildings/
│ ├── barracks/ ← NEW
│ │ ├── barracks.tscn
│ │ └── barracks_generator.tres
│ ├── devil_idol/ ← NEW
│ │ └── devil_idol.tscn
│ └── ... (existing buildings)
└── research/
└── ts_research_catalogue.tres ← (optional) add barracks research
```

View File

@@ -0,0 +1,17 @@
[gd_resource type="Resource" script_class="GeneratorBuffData" format=3]
[ext_resource type="Script" path="res://core/generator/generator_buff_data.gd" id="1_buff"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="2_cost"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/food.tres" id="3_target"]
[resource]
script = ExtResource("1_buff")
id = &"fertile_infusion"
target_ids = Array[StringName]([&"farm"])
text = "Fertile Infusion"
max_level = 5
effect_increment = 1.0
cost_currency = ExtResource("2_cost")
base_cost_mantissa = 1.0
cost_multiplier = 1.5
resource_target_currency = ExtResource("3_target")

View File

@@ -0,0 +1,17 @@
[gd_resource type="Resource" script_class="GeneratorBuffData" format=3]
[ext_resource type="Script" path="res://core/generator/generator_buff_data.gd" id="1_buff"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/philosoper_stone.tres" id="2_cost"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/gold.tres" id="3_target"]
[resource]
script = ExtResource("1_buff")
id = &"opus_magnum"
target_ids = Array[StringName]([&"goldmine"])
text = "Opus Magnum"
max_level = 5
effect_increment = 2.0
cost_currency = ExtResource("2_cost")
base_cost_mantissa = 1.0
cost_multiplier = 2.0
resource_target_currency = ExtResource("3_target")

View File

@@ -0,0 +1,17 @@
[gd_resource type="Resource" script_class="GeneratorBuffData" format=3]
[ext_resource type="Script" path="res://core/generator/generator_buff_data.gd" id="1_buff"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/cognite.tres" id="2_cost"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/wood.tres" id="3_target"]
[resource]
script = ExtResource("1_buff")
id = &"sylvan_cognite"
target_ids = Array[StringName]([&"forestry"])
text = "Sylvan Cognite"
max_level = 5
effect_increment = 1.0
cost_currency = ExtResource("2_cost")
base_cost_mantissa = 1.0
cost_multiplier = 1.5
resource_target_currency = ExtResource("3_target")

View File

@@ -7,8 +7,11 @@
[ext_resource type="Resource" uid="uid://bjc6qmvr7pe12" path="res://docs/gyms/tiny_sword/buffs/spawn_worker_buff.tres" id="4_hnq3m"]
[ext_resource type="Resource" uid="uid://cg7os1rfknw05" path="res://docs/gyms/tiny_sword/buffs/farm_auto_flux_buff.tres" id="5_mii30"]
[ext_resource type="Resource" uid="uid://kamgujbqqhg3" path="res://docs/gyms/tiny_sword/buffs/forestry_auto_flux_buff.tres" id="6_k5yi4"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buffs/fertile_infusion_buff.tres" id="7_fertile"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buffs/sylvan_cognite_buff.tres" id="8_sylvan"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buffs/opus_magnum_buff.tres" id="9_opus"]
[resource]
script = ExtResource("2_iuxc1")
buffs = Array[ExtResource("1_up80l")]([ExtResource("2_dtvfl"), ExtResource("3_0bb41"), ExtResource("4_hnq3m"), ExtResource("5_mii30"), ExtResource("6_k5yi4")])
buffs = Array[ExtResource("1_up80l")]([ExtResource("2_dtvfl"), ExtResource("3_0bb41"), ExtResource("4_hnq3m"), ExtResource("5_mii30"), ExtResource("6_k5yi4"), ExtResource("7_fertile"), ExtResource("8_sylvan"), ExtResource("9_opus")])
metadata/_custom_type_script = "uid://ctc5yjlnvi0ok"

View File

@@ -1,6 +1,8 @@
class_name AlchemyTower
extends Node2D
const UNLOCK_GOAL_ID: StringName = &"gold_2M_food_200k_wood_200k"
## Emitted when production progress changes (0.0 to 1.0)
signal production_progress_updated(progress: float)
## Emitted when magic gold balance changes
@@ -16,6 +18,8 @@ signal production_completed(amount: BigNumber)
## Reference to game state
@onready var game_state: LevelGameState = find_parent("LevelGameState")
@onready var _alchemy_currencies_panel: AlchemyCurrenciesPanel = $AlchemyCurrenciesPanel
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _area: Area2D = $Area2D
## Current production state
var production_time_elapsed: float = 0.0
@@ -36,17 +40,23 @@ func _ready() -> void:
# Initialize production time
current_production_time = data.base_production_time_seconds
# Register this tower as an available generator
game_state.set_generator_available(get_generator_id(), true)
# Hide tower until unlock goal is completed
_sprite.visible = false
_area.monitoring = false
# Connect to magic gold balance changes
game_state.currency_changed.connect(_on_currency_changed)
game_state.goal_completed.connect(_on_goal_completed)
# Connect panel signals if available
if alchemy_panel:
alchemy_panel.craft_requested.connect(_on_craft_requested)
alchemy_panel.alchemy_workers_changed.connect(_on_alchemy_workers_changed)
# If goal was already completed in a previous session, unlock immediately
if game_state.is_goal_completed(UNLOCK_GOAL_ID):
_unlock_tower()
# Initial progress update
production_progress_updated.emit(0.0)
@@ -200,3 +210,15 @@ func _on_area_2d_mouse_entered() -> void:
func _on_area_2d_mouse_exited() -> void:
_alchemy_currencies_panel.visible = false
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == UNLOCK_GOAL_ID:
_unlock_tower()
func _unlock_tower() -> void:
_sprite.visible = true
_area.monitoring = true
game_state.set_generator_available(get_generator_id(), true)
game_state.register_generator(get_generator_id(), true, true, 1)

View File

@@ -26,10 +26,10 @@ shape = SubResource("RectangleShape2D_8pntr")
[node name="AlchemyCurrenciesPanel" parent="." unique_id=731368154 instance=ExtResource("2_8pntr")]
visible = false
offset_left = 65.0
offset_top = -75.0
offset_right = 65.0
offset_bottom = -75.0
offset_left = 44.0
offset_top = -81.0
offset_right = 444.0
offset_bottom = 219.0
currency = ExtResource("7_b8p5n")
craft_recipes = ExtResource("5_recipes")

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cx11iodvbcfb1"
path="res://.godot/imported/Barracks.png-6c10bd8efd919b8eb03e40d568e18cf1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://docs/gyms/tiny_sword/buildings/barracks/Barracks.png"
dest_files=["res://.godot/imported/Barracks.png-6c10bd8efd919b8eb03e40d568e18cf1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -0,0 +1,25 @@
extends Node2D
const UNLOCK_GOAL_ID: StringName = &"gold_50M_food_5M_wood_5M"
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _area: Area2D = $Area2D
@onready var _game_state: LevelGameState = find_parent("LevelGameState")
func _ready() -> void:
_sprite.visible = false
_area.monitoring = false
_game_state.goal_completed.connect(_on_goal_completed)
if _game_state.is_goal_completed(UNLOCK_GOAL_ID):
_unlock()
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == UNLOCK_GOAL_ID:
_unlock()
func _unlock() -> void:
_sprite.visible = true
_area.monitoring = true

View File

@@ -0,0 +1 @@
uid://xk7d3maod6uc

View File

@@ -0,0 +1,40 @@
[gd_scene format=3 uid="uid://cyvijgwj6l8vg"]
[ext_resource type="PackedScene" uid="uid://jeoiinukrrsp" path="res://core/generator/currency_generator.tscn" id="1_gen"]
[ext_resource type="Script" uid="uid://xk7d3maod6uc" path="res://docs/gyms/tiny_sword/buildings/barracks/barracks.gd" id="1_script"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/unit.tres" id="2_unit"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buildings/barracks/barracks_generator.tres" id="3_data"]
[ext_resource type="Texture2D" uid="uid://cx11iodvbcfb1" path="res://docs/gyms/tiny_sword/buildings/barracks/Barracks.png" id="4_ud3ae"]
[ext_resource type="PackedScene" uid="uid://ckos7f22pnmyh" path="res://core/generator/generator_container.tscn" id="5_panel"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_barracks"]
size = Vector2(160, 175)
[node name="Barracks" type="Node2D" unique_id=1061432510]
script = ExtResource("1_script")
[node name="CurrencyGenerator" parent="." unique_id=427948318 node_paths=PackedStringArray("info_generator_container") instance=ExtResource("1_gen")]
currency = ExtResource("2_unit")
data = ExtResource("3_data")
press_buys_generator = false
info_generator_container = NodePath("../GeneratorContainer")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1503773416]
texture = ExtResource("4_ud3ae")
[node name="Area2D" type="Area2D" parent="." unique_id=1808028142]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=614030143]
position = Vector2(1, 19.5)
shape = SubResource("RectangleShape2D_barracks")
[node name="GeneratorContainer" parent="." unique_id=1905754561 node_paths=PackedStringArray("_generator") instance=ExtResource("5_panel")]
visible = false
offset_left = 138.0
offset_top = -100.0
offset_right = 402.0
offset_bottom = 110.0
_generator = NodePath("../CurrencyGenerator")
[connection signal="mouse_entered" from="Area2D" to="CurrencyGenerator" method="_on_area_2d_mouse_entered"]
[connection signal="mouse_exited" from="Area2D" to="CurrencyGenerator" method="_on_area_2d_mouse_exited"]

View File

@@ -0,0 +1,18 @@
[gd_resource type="Resource" script_class="CurrencyGeneratorData" format=3]
[ext_resource type="Script" path="res://core/generator/currency_generator_data.gd" id="1_data"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/worker.tres" id="2_worker"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/goals/gold_50M_food_5M_wood_5M_goal.tres" id="3_goal"]
[resource]
script = ExtResource("1_data")
id = &"barracks"
name = "Barracks"
starts_unlocked = false
starts_available = false
initial_owned = 1
purchase_currency = ExtResource("2_worker")
unlock_goal = ExtResource("3_goal")
initial_cost = 1.0
coefficient = 1.0
initial_productivity = 1.0

View File

@@ -1,20 +1,26 @@
extends Node2D
const PRESTIGE_GOAL_ID: StringName = &"gold_350k_wood_20k"
@onready var _prestige_panel: PrestigePanel = $PrestigePanel
@onready var game_state: LevelGameState = find_parent("LevelGameState")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
if game_state:
game_state.goal_completed.connect(_on_goal_completed)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_area_2d_mouse_entered() -> void:
## TODO: remove this comment to enable prestige panel
#_prestige_panel.visible = true
pass
if game_state and game_state.is_goal_completed(PRESTIGE_GOAL_ID):
_prestige_panel.visible = true
func _on_area_2d_mouse_exited() -> void:
_prestige_panel.visible = false
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == PRESTIGE_GOAL_ID:
# Prestige is now unlocked — panel will show on next hover.
pass

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://rpedoq4102to"
path="res://.godot/imported/Castle.png-abe84e074a7668619903091d591ffce7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://docs/gyms/tiny_sword/buildings/devil_idol/Castle.png"
dest_files=["res://.godot/imported/Castle.png-abe84e074a7668619903091d591ffce7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -0,0 +1,135 @@
class_name DevilIdol
extends Node2D
const UNLOCK_GOAL_ID: StringName = &"gold_50M_food_5M_wood_5M"
const SAVE_KEY: String = "devil_idol_state"
const HP_KEY: String = "current_hp"
## Emitted when the idol takes damage.
signal idol_damaged(current_hp: BigNumber, max_hp: BigNumber)
## Emitted when the idol is destroyed (one-time win condition).
signal idol_destroyed()
## Maximum HP mantissa.
@export var max_hp_mantissa: float = 1.0
## Maximum HP exponent (default 1e12 = 1 trillion).
@export var max_hp_exponent: int = 12
@onready var game_state: LevelGameState = find_parent("LevelGameState")
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _area: Area2D = $Area2D
@onready var _panel: PanelContainer = $IdolPanel
@onready var _hp_value: Label = $IdolPanel/MarginContainer/VBoxContainer/HPValue
@onready var _damage_button: Button = $IdolPanel/MarginContainer/VBoxContainer/DamageButton
@onready var _victory_label: Label = $IdolPanel/MarginContainer/VBoxContainer/VictoryLabel
var _max_hp: BigNumber
var _current_hp: BigNumber
var _is_targetable: bool = false
var _is_destroyed: bool = false
func _ready() -> void:
assert(game_state != null, "DevilIdol: LevelGameState parent not found")
_max_hp = BigNumber.new(max_hp_mantissa, max_hp_exponent)
_current_hp = BigNumber.new(max_hp_mantissa, max_hp_exponent)
# Load persisted HP from save data
_load_state()
# Panel hidden by default; shown on hover if unlocked
_panel.visible = false
_victory_label.visible = false
_damage_button.pressed.connect(_on_damage_button_pressed)
# Connect to goal completion for unlocking
game_state.goal_completed.connect(_on_goal_completed)
# If goal was already completed in a previous session, unlock immediately
if game_state.is_goal_completed(UNLOCK_GOAL_ID):
_unlock_idol()
_update_ui()
func _on_area_2d_mouse_entered() -> void:
if _is_targetable and not _is_destroyed:
_panel.visible = true
func _on_area_2d_mouse_exited() -> void:
_panel.visible = false
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == UNLOCK_GOAL_ID:
_unlock_idol()
func _unlock_idol() -> void:
_is_targetable = true
func _on_damage_button_pressed() -> void:
if _is_destroyed:
return
var unit_balance: BigNumber = game_state.get_currency_amount_by_id(&"unit")
if unit_balance.mantissa <= 0.0:
return
# Spend all available units as damage
var damage: BigNumber = BigNumber.new(unit_balance.mantissa, unit_balance.exponent)
if game_state.spend_currency_by_id(&"unit", damage):
_current_hp = _current_hp.subtract(damage)
if _current_hp.mantissa <= 0.0:
_current_hp = BigNumber.new(0.0, 0)
_is_destroyed = true
idol_destroyed.emit()
_victory_label.visible = true
_panel.visible = true
idol_damaged.emit(_current_hp, _max_hp)
_save_state()
_update_ui()
func _update_ui() -> void:
if _is_destroyed:
_hp_value.text = "0 / %s — DESTROYED" % _max_hp.to_string_suffix(2)
_damage_button.disabled = true
_damage_button.text = "VICTORY!"
return
var progress_pct: float = 0.0
if _max_hp.mantissa > 0.0:
progress_pct = (1.0 - (_current_hp.mantissa / _max_hp.mantissa)) * pow(10.0, float(_current_hp.exponent - _max_hp.exponent))
progress_pct = clampf(progress_pct * 100.0, 0.0, 100.0)
_hp_value.text = "%s / %s (%.1f%%)" % [_current_hp.to_string_suffix(2), _max_hp.to_string_suffix(2), progress_pct]
var unit_balance: BigNumber = game_state.get_currency_amount_by_id(&"unit")
_damage_button.text = "Send Army (%s units)" % unit_balance.to_string_suffix(2)
_damage_button.disabled = unit_balance.mantissa <= 0.0
func _save_state() -> void:
if game_state == null:
return
var payload: Dictionary = {HP_KEY: _current_hp.serialize()}
game_state.set_external_save_data(SAVE_KEY, payload)
func _load_state() -> void:
if game_state == null:
return
var saved: Dictionary = game_state.get_external_save_data(SAVE_KEY)
if saved.has(HP_KEY):
var raw_hp: Variant = saved.get(HP_KEY)
if raw_hp is Dictionary:
_current_hp = BigNumber.deserialize(raw_hp)
if _current_hp.mantissa <= 0.0:
_current_hp = BigNumber.new(0.0, 0)
_is_destroyed = true
_victory_label.visible = true

View File

@@ -0,0 +1 @@
uid://blfof77kjp7x0

View File

@@ -0,0 +1,57 @@
[gd_scene format=3 uid="uid://d1cvlnd5vwjol"]
[ext_resource type="Script" uid="uid://blfof77kjp7x0" path="res://docs/gyms/tiny_sword/buildings/devil_idol/devil_idol.gd" id="1_script"]
[ext_resource type="Texture2D" uid="uid://rpedoq4102to" path="res://docs/gyms/tiny_sword/buildings/devil_idol/Castle.png" id="2_g7pcm"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_idol"]
size = Vector2(312, 198)
[node name="DevilIdol" type="Node2D" unique_id=797117647]
script = ExtResource("1_script")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=661703335]
texture = ExtResource("2_g7pcm")
[node name="Area2D" type="Area2D" parent="." unique_id=1812195052]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=1492517397]
position = Vector2(1, 22)
shape = SubResource("RectangleShape2D_idol")
[node name="IdolPanel" type="PanelContainer" parent="." unique_id=906038530]
offset_left = -200.0
offset_top = -120.0
offset_right = 200.0
offset_bottom = -10.0
[node name="MarginContainer" type="MarginContainer" parent="IdolPanel" unique_id=1952977282]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBoxContainer" type="VBoxContainer" parent="IdolPanel/MarginContainer" unique_id=1214756176]
layout_mode = 2
theme_override_constants/separation = 8
[node name="TitleLabel" type="Label" parent="IdolPanel/MarginContainer/VBoxContainer" unique_id=1268978638]
layout_mode = 2
text = "Devil Idol"
[node name="HPValue" type="Label" parent="IdolPanel/MarginContainer/VBoxContainer" unique_id=529436307]
layout_mode = 2
text = "??? / ???"
[node name="DamageButton" type="Button" parent="IdolPanel/MarginContainer/VBoxContainer" unique_id=1565608485]
layout_mode = 2
disabled = true
text = "Send Army"
[node name="VictoryLabel" type="Label" parent="IdolPanel/MarginContainer/VBoxContainer" unique_id=169309796]
layout_mode = 2
text = "THE DEVIL IDOL HAS BEEN DESTROYED!"
horizontal_alignment = 1
[connection signal="mouse_entered" from="Area2D" to="." method="_on_area_2d_mouse_entered"]
[connection signal="mouse_exited" from="Area2D" to="." method="_on_area_2d_mouse_exited"]

View File

@@ -0,0 +1,25 @@
extends Node2D
const UNLOCK_GOAL_ID: StringName = &"gold_total_1300"
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _area: Area2D = $Area2D
@onready var _game_state: LevelGameState = find_parent("LevelGameState")
func _ready() -> void:
_sprite.visible = false
_area.monitoring = false
_game_state.goal_completed.connect(_on_goal_completed)
if _game_state.is_goal_completed(UNLOCK_GOAL_ID):
_unlock()
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == UNLOCK_GOAL_ID:
_unlock()
func _unlock() -> void:
_sprite.visible = true
_area.monitoring = true

View File

@@ -0,0 +1 @@
uid://dnsblnjy82goo

View File

@@ -1,6 +1,7 @@
[gd_scene format=3 uid="uid://djedqovgngrx5"]
[ext_resource type="PackedScene" uid="uid://jeoiinukrrsp" path="res://core/generator/currency_generator.tscn" id="1_rvsna"]
[ext_resource type="Script" path="res://docs/gyms/tiny_sword/buildings/farm/farm.gd" id="1_script"]
[ext_resource type="Resource" uid="uid://bxg2au0ijp242" path="res://docs/gyms/tiny_sword/currencies/food.tres" id="2_djlc5"]
[ext_resource type="Resource" uid="uid://d08h51y0pnsnf" path="res://docs/gyms/tiny_sword/buildings/farm/farm_generator.tres" id="3_82rmq"]
[ext_resource type="Texture2D" uid="uid://dfdh8r03sj7qv" path="res://docs/gyms/tiny_sword/buildings/farm/House1.png" id="4_djlc5"]
@@ -10,6 +11,7 @@
size = Vector2(106, 157)
[node name="Farm" type="Node2D" unique_id=283335851]
script = ExtResource("1_script")
[node name="CurrencyGenerator" parent="." unique_id=967969064 node_paths=PackedStringArray("info_generator_container") instance=ExtResource("1_rvsna")]
currency = ExtResource("2_djlc5")

View File

@@ -1,13 +1,35 @@
extends Node2D
@onready var _generator_container: GeneratorPanel = $GeneratorContainer
const UNLOCK_GOAL_ID: StringName = &"gold_total_13k"
@onready var _generator_container: GeneratorPanel = $GeneratorContainer
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _area: Area2D = $Area2D
@onready var _game_state: LevelGameState = find_parent("LevelGameState")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_generator_container.visible = false
_sprite.visible = false
_area.monitoring = false
_game_state.goal_completed.connect(_on_goal_completed)
if _game_state.is_goal_completed(UNLOCK_GOAL_ID):
_unlock()
func _on_area_2d_mouse_entered() -> void:
_generator_container.visible = true
func _on_area_2d_mouse_exited() -> void:
_generator_container.visible = false
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == UNLOCK_GOAL_ID:
_unlock()
func _unlock() -> void:
_sprite.visible = true
_area.monitoring = true

View File

@@ -1,14 +1,37 @@
extends Node2D
@onready var _research_panel: ResearchPanel = $ResearchPanel
const RESEARCH_GOAL_ID: StringName = &"gold_350k_wood_20k"
@onready var _research_panel: ResearchPanel = $ResearchPanel
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _area: Area2D = $Area2D
@onready var game_state: LevelGameState = find_parent("LevelGameState")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_research_panel.visible = false
_sprite.visible = false
_area.monitoring = false
if game_state:
game_state.goal_completed.connect(_on_goal_completed)
if game_state.is_goal_completed(RESEARCH_GOAL_ID):
_unlock()
func _on_area_2d_mouse_entered() -> void:
_research_panel.visible = true
if game_state and game_state.is_goal_completed(RESEARCH_GOAL_ID):
_research_panel.visible = true
func _on_area_2d_mouse_exited() -> void:
_research_panel.visible = false
func _on_goal_completed(goal_id: StringName) -> void:
if goal_id == RESEARCH_GOAL_ID:
_unlock()
func _unlock() -> void:
_sprite.visible = true
_area.monitoring = true

View File

@@ -11,8 +11,9 @@
[ext_resource type="Resource" uid="uid://brctmnpmhjas6" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="8_p3urk"]
[ext_resource type="Resource" uid="uid://t6du7gm2ywbi" path="res://docs/gyms/tiny_sword/currencies/cognite.tres" id="9_ejnoj"]
[ext_resource type="Resource" uid="uid://co4fiqgluwit0" path="res://docs/gyms/tiny_sword/currencies/philosoper_stone.tres" id="10_ejnoj"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/currencies/unit.tres" id="11_unit"]
[resource]
script = ExtResource("2_hmju3")
currencies = Array[ExtResource("1_501l6")]([ExtResource("2_ucsji"), ExtResource("3_7hx6u"), ExtResource("4_c77gh"), ExtResource("5_gyp05"), ExtResource("6_ascension"), ExtResource("7_vu05v"), ExtResource("8_p3urk"), ExtResource("9_ejnoj"), ExtResource("10_ejnoj")])
currencies = Array[ExtResource("1_501l6")]([ExtResource("2_ucsji"), ExtResource("3_7hx6u"), ExtResource("4_c77gh"), ExtResource("5_gyp05"), ExtResource("6_ascension"), ExtResource("7_vu05v"), ExtResource("8_p3urk"), ExtResource("9_ejnoj"), ExtResource("10_ejnoj"), ExtResource("11_unit")])
metadata/_custom_type_script = "uid://621tus0uvbrd"

View File

@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="Currency" format=3]
[ext_resource type="Script" path="res://core/currency/currency.gd" id="1_script"]
[ext_resource type="Texture2D" path="res://sandbox/tiny_swords/UI Elements/UI Elements/Icons/Icon_05.png" id="2_icon"]
[resource]
script = ExtResource("1_script")
id = &"unit"
display_name = "Unit"
icon = ExtResource("2_icon")

View File

@@ -0,0 +1,30 @@
[gd_resource type="Resource" script_class="GoalData" format=3 uid="uid://bex2hsenbr54e"]
[ext_resource type="Script" uid="uid://r4js5eajolio" path="res://core/goals/goal_requirement_data.gd" id="1_req"]
[ext_resource type="Resource" uid="uid://w4u1hddplb4e" path="res://docs/gyms/tiny_sword/currencies/gold.tres" id="2_gold"]
[ext_resource type="Resource" uid="uid://bxg2au0ijp242" path="res://docs/gyms/tiny_sword/currencies/food.tres" id="3_food"]
[ext_resource type="Resource" uid="uid://bgsk8h4w80h45" path="res://docs/gyms/tiny_sword/currencies/wood.tres" id="4_wood"]
[ext_resource type="Script" uid="uid://dx4kmh33rrkpy" path="res://core/goals/goal_data.gd" id="5_goal"]
[sub_resource type="Resource" id="Resource_gold"]
script = ExtResource("1_req")
currency = ExtResource("2_gold")
amount_mantissa = 2.0
amount_exponent = 6
[sub_resource type="Resource" id="Resource_food"]
script = ExtResource("1_req")
currency = ExtResource("3_food")
amount_mantissa = 2.0
amount_exponent = 5
[sub_resource type="Resource" id="Resource_wood"]
script = ExtResource("1_req")
currency = ExtResource("4_wood")
amount_mantissa = 2.0
amount_exponent = 5
[resource]
script = ExtResource("5_goal")
id = &"gold_2M_food_200k_wood_200k"
requirements = Array[ExtResource("1_req")]([SubResource("Resource_gold"), SubResource("Resource_food"), SubResource("Resource_wood")])

View File

@@ -0,0 +1,30 @@
[gd_resource type="Resource" script_class="GoalData" format=3 uid="uid://bn4gm4sss85d0"]
[ext_resource type="Script" uid="uid://r4js5eajolio" path="res://core/goals/goal_requirement_data.gd" id="1_req"]
[ext_resource type="Resource" uid="uid://w4u1hddplb4e" path="res://docs/gyms/tiny_sword/currencies/gold.tres" id="2_gold"]
[ext_resource type="Resource" uid="uid://bxg2au0ijp242" path="res://docs/gyms/tiny_sword/currencies/food.tres" id="3_food"]
[ext_resource type="Resource" uid="uid://bgsk8h4w80h45" path="res://docs/gyms/tiny_sword/currencies/wood.tres" id="4_wood"]
[ext_resource type="Script" uid="uid://dx4kmh33rrkpy" path="res://core/goals/goal_data.gd" id="5_goal"]
[sub_resource type="Resource" id="Resource_gold"]
script = ExtResource("1_req")
currency = ExtResource("2_gold")
amount_mantissa = 5.0
amount_exponent = 7
[sub_resource type="Resource" id="Resource_food"]
script = ExtResource("1_req")
currency = ExtResource("3_food")
amount_mantissa = 5.0
amount_exponent = 6
[sub_resource type="Resource" id="Resource_wood"]
script = ExtResource("1_req")
currency = ExtResource("4_wood")
amount_mantissa = 5.0
amount_exponent = 6
[resource]
script = ExtResource("5_goal")
id = &"gold_50M_food_5M_wood_5M"
requirements = Array[ExtResource("1_req")]([SubResource("Resource_gold"), SubResource("Resource_food"), SubResource("Resource_wood")])

View File

@@ -6,7 +6,9 @@
[ext_resource type="Resource" uid="uid://cts0407h130d6" path="res://docs/gyms/tiny_sword/goals/gold_total_1300_goal.tres" id="3_wb626"]
[ext_resource type="Resource" uid="uid://bo463s6jt0ep7" path="res://docs/gyms/tiny_sword/goals/gold_total_13k_goal.tres" id="4_3oaoj"]
[ext_resource type="Resource" uid="uid://b6gb6vk0kgxnw" path="res://docs/gyms/tiny_sword/goals/gold_350k_wood_20k_goal.tres" id="5_or88d"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/goals/gold_2M_food_200k_wood_200k_goal.tres" id="6_alchemy"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/goals/gold_50M_food_5M_wood_5M_goal.tres" id="7_barracks"]
[resource]
script = ExtResource("2_84pbn")
goals = Array[ExtResource("1_6p6ue")]([ExtResource("2_xvtf2"), ExtResource("3_wb626"), ExtResource("4_3oaoj"), ExtResource("5_or88d")])
goals = Array[ExtResource("1_6p6ue")]([ExtResource("2_xvtf2"), ExtResource("3_wb626"), ExtResource("4_3oaoj"), ExtResource("5_or88d"), ExtResource("6_alchemy"), ExtResource("7_barracks")])

View File

@@ -0,0 +1,13 @@
[gd_resource type="Resource" script_class="PrestigeBuffNode" format=3]
[ext_resource type="Script" path="res://core/prestige/prestige_buff_node.gd" id="1_script"]
[resource]
script = ExtResource("1_script")
id = &"barracks_boost"
display_name = "Martial Prowess"
description = "Permanently increases barracks unit production."
parent_ids = Array[StringName]([&"wood_boost"])
effect_value = 2.0
target_id = &"barracks"
cost_mantissa = 5.0

View File

@@ -1,10 +1,12 @@
[gd_resource type="Resource" script_class="PrestigeBuffCatalogue" format=3]
[gd_resource type="Resource" script_class="PrestigeBuffCatalogue" format=3 uid="uid://dpt3j1c2ndgkj"]
[ext_resource type="Script" path="res://core/prestige/prestige_buff_node.gd" id="1_node"]
[ext_resource type="Script" path="res://core/prestige/prestige_buff_catalogue.gd" id="2_cat"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_gold_boost.tres" id="3_gold"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_farm_boost.tres" id="4_farm"]
[ext_resource type="Script" uid="uid://mjyig8xlgki0" path="res://core/prestige/prestige_buff_node.gd" id="1_node"]
[ext_resource type="Script" uid="uid://bjcvnyh2bc6l5" path="res://core/prestige/prestige_buff_catalogue.gd" id="2_cat"]
[ext_resource type="Resource" uid="uid://vl3ot4t876pc" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_gold_boost.tres" id="3_gold"]
[ext_resource type="Resource" uid="uid://cvogxo0msis2w" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_farm_boost.tres" id="4_farm"]
[ext_resource type="Resource" uid="uid://bif136o485oqh" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_wood_boost.tres" id="5_wood"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_barracks_boost.tres" id="6_barracks"]
[resource]
script = ExtResource("2_cat")
nodes = Array[ExtResource("1_node")]([ExtResource("3_gold"), ExtResource("4_farm")])
nodes = Array[ExtResource("1_node")]([ExtResource("3_gold"), ExtResource("4_farm"), ExtResource("5_wood"), ExtResource("6_barracks")])

View File

@@ -10,4 +10,5 @@ description = "Permanently increases farm food production."
parent_ids = Array[StringName]([&"gold_boost"])
effect_value = 2.0
target_id = &"farm"
cost_mantissa = 2.0
x_position = 1.0

View File

@@ -5,9 +5,13 @@
[ext_resource type="PackedScene" uid="uid://bqk8rwia7lpbg" path="res://core/prestige/prestige_buff_graph_tile.tscn" id="3_tile"]
[ext_resource type="Resource" uid="uid://vl3ot4t876pc" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_gold_boost.tres" id="4_gold"]
[ext_resource type="Resource" uid="uid://cvogxo0msis2w" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_farm_boost.tres" id="5_farm"]
[ext_resource type="Resource" uid="uid://bif136o485oqh" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_wood_boost.tres" id="6_pdyju"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_barracks_boost.tres" id="7_x62av"]
[node name="PrestigeBuffGraphPanel" type="PanelContainer" unique_id=947835716]
custom_minimum_size = Vector2(600, 400)
offset_right = 857.0
offset_bottom = 632.0
script = ExtResource("1_panel")
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=829451203]
@@ -56,14 +60,31 @@ script = ExtResource("2_overlay")
[node name="GoldBoostTile" parent="MarginContainer/VBoxContainer/TilesArea" unique_id=756192834 instance=ExtResource("3_tile")]
layout_mode = 0
offset_top = 27.0
offset_right = 220.0
offset_bottom = 100.0
offset_bottom = 127.0
prestige_buff = ExtResource("4_gold")
[node name="FarmBoostTile" parent="MarginContainer/VBoxContainer/TilesArea" unique_id=619283475 instance=ExtResource("3_tile")]
layout_mode = 0
offset_left = 3.0
offset_top = 121.0
offset_top = 198.0
offset_right = 223.0
offset_bottom = 221.0
offset_bottom = 298.0
prestige_buff = ExtResource("5_farm")
[node name="FarmBoostTile2" parent="MarginContainer/VBoxContainer/TilesArea" unique_id=582396224 instance=ExtResource("3_tile")]
layout_mode = 0
offset_left = 317.0
offset_top = 198.0
offset_right = 537.0
offset_bottom = 298.0
prestige_buff = ExtResource("6_pdyju")
[node name="FarmBoostTile3" parent="MarginContainer/VBoxContainer/TilesArea" unique_id=818264061 instance=ExtResource("3_tile")]
layout_mode = 0
offset_left = 317.0
offset_top = 382.0
offset_right = 537.0
offset_bottom = 482.0
prestige_buff = ExtResource("7_x62av")

View File

@@ -10,3 +10,4 @@ description = "Permanently increases forestry production."
parent_ids = Array[StringName]([&"farm_boost"])
effect_value = 2.0
target_id = &"forestry"
cost_mantissa = 3.0

View File

@@ -6,4 +6,6 @@
script = ExtResource("1_3tg3a")
id = &"ascension"
prestige_currency_id = &"ascension"
basis = 3
source_currency_id = &"gold"
basis = 1
threshold_mantissa = 5.0

View File

@@ -8,7 +8,7 @@
[ext_resource type="Resource" uid="uid://cgt1mjir1v4br" path="res://docs/gyms/tiny_sword/goals/ts_goal_catalogue.tres" id="4_x77df"]
[ext_resource type="Resource" uid="uid://umi37hotcq8m" path="res://docs/gyms/tiny_sword/research/ts_research_catalogue.tres" id="5_v0pty"]
[ext_resource type="Script" uid="uid://srkiu4qe8s2m" path="res://core/prestige/prestige_manager.gd" id="5_x77df"]
[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_catalogue.tres" id="6_asc"]
[ext_resource type="Resource" uid="uid://dpt3j1c2ndgkj" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_catalogue.tres" id="6_asc"]
[ext_resource type="Resource" uid="uid://dwmfvmusfskk6" path="res://docs/gyms/tiny_sword/prestige/primary_prestige.tres" id="6_xnhlc"]
[ext_resource type="PackedScene" path="res://docs/gyms/tiny_sword/currency_panel.tscn" id="9_cpnl"]
[ext_resource type="PackedScene" uid="uid://djedqovgngrx5" path="res://docs/gyms/tiny_sword/buildings/farm/farm.tscn" id="10_1lv5i"]
@@ -17,6 +17,8 @@
[ext_resource type="PackedScene" uid="uid://bf8lqbexvnx6e" path="res://docs/gyms/tiny_sword/buildings/monastery/monastery.tscn" id="13_no27p"]
[ext_resource type="PackedScene" uid="uid://rejxvjwybkll" path="res://sandbox/tiny_swords/Terrain/Resources/Wood/Trees/tree_1.tscn" id="14_0cs5o"]
[ext_resource type="PackedScene" uid="uid://bp5ng4vu4ot4a" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn" id="14_hum8s"]
[ext_resource type="PackedScene" uid="uid://cyvijgwj6l8vg" path="res://docs/gyms/tiny_sword/buildings/barracks/barracks.tscn" id="15_barracks"]
[ext_resource type="PackedScene" uid="uid://d1cvlnd5vwjol" path="res://docs/gyms/tiny_sword/buildings/devil_idol/devil_idol.tscn" id="16_idol"]
[ext_resource type="Script" uid="uid://b6systw05frh0" path="res://core/edge_scroll_camera.gd" id="17_x77df"]
[ext_resource type="PackedScene" uid="uid://dprbgokqitaav" path="res://docs/gyms/tiny_sword/prestige/prestige_buff_graph_panel.tscn" id="18_pnl"]
@@ -114,6 +116,12 @@ position = Vector2(105, 920)
[node name="AlchemyTower" parent="LevelGameState/World" unique_id=51852160 instance=ExtResource("14_hum8s")]
position = Vector2(1239, 775)
[node name="Barracks" parent="LevelGameState/World" unique_id=765432109 instance=ExtResource("15_barracks")]
position = Vector2(1597, 900)
[node name="DevilIdol" parent="LevelGameState/World" unique_id=876543210 instance=ExtResource("16_idol")]
position = Vector2(873, 1289)
[node name="Camera2D" type="Camera2D" parent="." unique_id=1494908331]
position = Vector2(5, 0)
offset = Vector2(960, 540)