Commit graph

1348 commits

Author SHA1 Message Date
autocommit
db5b2cd3ce ui(screenshots): 💄 Replace autoplay victory turn screenshot with corrected visual asset
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 19:30:32 -07:00
autocommit
8d4a1111eb ui(screenshots): 💄 Replace outdated autoplay screenshots for turns 41–50 with updated visual assets
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 19:24:39 -07:00
autocommit
63af9ae01c docs(screenshots): 📝 Add/update project screenshots for visual documentation
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 19:18:51 -07:00
Natalie
9db0c6ef81 feat(auto-play): build walls, settlers, forge — match AI strategy
Our auto-play now mirrors the AI's build order:
1. Walls (defense first)
2. Settler to expand to 3 cities
3. Forge (+2 production)
4. Warriors for military

Settlers move away from existing cities (5+ hex distance) before founding.
Removed debug prints from production tracking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 19:17:42 -07:00
autocommit
7d74bde835 perf(physics): Update x86_64 physics engine library with performance optimizations and bug fixes
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 19:13:19 -07:00
autocommit
4daa0bfb66 chore(none-root-level-config): 🔧 Update .gitignore to exclude build outputs, logs, and sensitive data files
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 19:13:19 -07:00
Natalie
99ff12292f debug: log production progress 2026-04-12 19:06:47 -07:00
Natalie
1ef1c53caa debug: log AI set_production actions 2026-04-12 19:04:59 -07:00
Natalie
c9c5dcf2a9 feat: increase city center yields + smarter AI production priorities
City center now produces 2 food, 2 production, 1 gold, 1 science (was 2/1/0/0).
This doubles the pace of the game — warriors in ~20 turns instead of ~40,
walls in ~35 instead of ~70.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 19:00:00 -07:00
Natalie
ef65fb3dc2 feat(ai): smarter production — walls, settlers, forge, castle priority
AI production now follows a priority chain:
1. Build walls (defense first — every city gets walls)
2. Build settler if < 3 cities (expansion)
3. Build warriors to maintain 2 per city (military)
4. Build forge (+2 production for faster future builds)
5. Build castle (upgrades walls, enables bombard)
6. Build any remaining available building
7. Fallback: more military

This makes the AI significantly more challenging:
- Cities have walls (0.75x melee penalty, +50 HP)
- AI expands to 2-3 cities (domination requires capturing ALL)
- Forge accelerates subsequent production
- Castle adds city bombardment capability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:53:35 -07:00
Natalie
6b03eca49d feat(city-defense): active city bombardment — cities attack once per turn
- Cities can bombard one enemy unit within range (2 hexes) per turn
- Human player: click own city → click enemy within range to bombard
- AI player: automatically bombards nearest enemy in range
- Damage formula: 20 * (city_str / def_str), clamped [5, 40]
- city_str = population * 3 + castle bonus (12)
- has_bombarded flag resets each turn via city.refresh_turn()
- New AI action type: "city_bombard" in simple_heuristic_ai + ai_turn_bridge

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:30:26 -07:00
Natalie
08abd276c5 feat(city-defense): population HP scaling + garrison combat strength boost
- City max_hp scales with population: base 200 + 10 per pop (pop 1 = 210)
- max_hp recalculated on growth/starvation, building bonuses preserved
- Garrison unit's attack adds to city bombard combat strength
- Renamed DEFAULT_CITY_HP → BASE_CITY_HP, added HP_PER_POP constant

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:22:25 -07:00
Natalie
9bbd80a426 feat(city-defense): city bombard retaliation + building HP bonuses
- City bombard: melee attackers take 5-30 damage based on city population
  and castle bombard bonus (city_str = pop*3 + castle bonus)
- Building HP bonuses: when walls/castle complete, increase city max_hp
  and heal by hp_bonus value from building data
- Castle data: added city_bombard_strength: 12, city_bombard_range: 2

Combined with prior commit's city healing (20 HP/turn) and tiered wall
penalties (walls=0.75x, castle=0.60x), cities now require sustained
multi-turn sieges instead of 1-2 turn captures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:04:28 -07:00
Natalie
00aa2ef601 feat(city-defense): city healing, tiered wall penalties, bombard damage function
- Cities heal 20 HP per turn (heal_per_turn in Rust, exposed via GDExtension,
  called from turn_processor after unit healing)
- Wall penalty scales by tier: none=1.0, walls=0.75, castle=0.60
- Added city_bombard_damage() function: 15 * (city_str/attacker_str), [5,30]
- Fixed "fortress"→"castle" references in combat_resolver.gd and combat_preview.gd
- Fixed defender.city_hp→defender.hp already done in prior commit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:01:45 -07:00
Natalie
0dc1fa5db8 refactor: rename hammer→production throughout codebase
Production is production, hammers are weapons. Single source of truth.

Rust: hammer_cost→production_cost, hammers_invested→production_invested,
hammers params→production (with serde aliases for JSON backward compat)
GDScript: hammers vars→prod, comments updated
Guide: "Hammers" label→"Production"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:56:17 -07:00
Natalie
d67d94e440 fix(combat): use defender.hp instead of nonexistent defender.city_hp
The City class has no 'city_hp' property — it uses 'hp' (backed by Rust
GDExtension). The combat resolver was reading/writing 'city_hp' which
created a dynamic property that never affected real city health. This
caused:
- City HP always passed as 0 to Rust resolver
- City damage never applied to actual city HP
- Cities could never be captured (HP never decreased)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:36:50 -07:00
Natalie
0a79576b5d fix(auto-play): use hex_distance for attack range instead of neighbor iteration
Neighbor-based enemy detection failed due to normalize_position changing
coordinates on wrapped maps. Now simply checks hex_distance <= 1 for all
enemy units and cities.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:26:24 -07:00
Natalie
60d4128dd5 fix: check same-hex enemies in _try_attack_adjacent 2026-04-12 16:20:06 -07:00
Natalie
0b5dd48db6 fix(auto-play): attack adjacent enemies immediately instead of moving first
When already adjacent to the target, skip movement and attack directly.
Previously the deadlock-breaker would move the warrior AWAY from the
adjacent enemy to a random hex.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:15:33 -07:00
Natalie
dd966bea93 debug: log nearby enemies in _try_attack_adjacent 2026-04-12 16:13:42 -07:00
Natalie
962c9ea857 fix: allow attacking adjacent enemies even with 0 movement remaining 2026-04-12 16:07:51 -07:00
Natalie
f9f85937fa fix: attack with 2+ warriors (can't accumulate more in stalemate) 2026-04-12 16:01:57 -07:00
Natalie
3b2e07eef3 fix: set num_players=2 after initialize_game runs 2026-04-12 15:54:54 -07:00
Natalie
115d7e84dd fix(auto-play): force 2-player game for fair domination match
Default settings create 4 players even on a Duel (2) map. With 3 AI vs 1
human, we're permanently outnumbered. Force 2 players for a 1v1 match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:48:40 -07:00
Natalie
9e4c96faed debug: simplify combat handler to avoid crashes 2026-04-12 15:45:25 -07:00
Natalie
f3a7f486aa debug: log all combat involving Player 0 2026-04-12 15:43:23 -07:00
Natalie
d9d819b338 fix(auto-play): instant max fortification for garrison warriors
Set fortified_turns=2 immediately instead of waiting 2 turns to build up.
With max fortification (+4 defense), a warrior should take only ~3 damage
per enemy attack instead of ~34, allowing accumulation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:37:35 -07:00
Natalie
aeda438bf3 feat(auto-play): defensive counter-attacks + garrison until 5 warriors
- Build phase: attack adjacent enemies before fortifying (counter-attack)
- Only march when 5+ warriors accumulated (no more premature attacks)
- Warriors at city fortify for defense bonus AND fight back

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:29:43 -07:00
Natalie
156efa5692 fix(auto-play): only target enemies reachable by land path
Warriors were marching toward enemies across water with no land path.
Now uses PathfinderScript.find_path with budget=999 to verify land
reachability before selecting attack targets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:23:29 -07:00
Natalie
53e01682e0 fix(auto-play): lock attack target, break movement deadlocks
- Lock onto one enemy target instead of switching every turn
- When stuck (no closer hex), try any valid move to break deadlock
- Verify locked target still exists before continuing march

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:17:10 -07:00
Natalie
51e163983f feat(auto-play): attack adjacent enemies after moving, increase to 500 turns
Warriors now check for adjacent enemy units/cities after moving and
initiate combat via CombatResolver. Also increased max turns to 500
and added unit position logging during attack phase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:04:18 -07:00
Natalie
7de6b6fd65 fix(auto-play): attack with 1+ warriors after turn 30 (can't accumulate 4)
With 1 hammer/turn and 40 cost warriors, accumulating 4 warriors is impossible
since each gets killed within ~20 turns. Attack with any available warrior
after turn 30 to make progress toward domination.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:58:23 -07:00
Natalie
f4ce0babe3 fix(ai): look up production cost in _apply_set_production
The AI's set_production action set queue items without a cost field, causing
all production to complete instantly (cost defaults to 0, progress >= 0 is
always true). This made AI warriors spawn every turn while the human player
waited 40 turns per warrior.

Now looks up cost from DataLoader for both units and buildings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:53:08 -07:00
Natalie
1ac301ec53 debug: add production tracking per turn 2026-04-12 14:50:58 -07:00
Natalie
dd40a998df feat(auto-play): fortify warriors at city during build phase
Warriors now fortify at the city position (+2 def/turn, max +4) instead of
sitting idle. This should help them survive enemy attacks while building up
to the 4-unit threshold for the attack march.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:48:39 -07:00
Natalie
1feeaccaec feat(auto-play): build-then-attack strategy — accumulate 4 warriors before marching
- Early game: found city, build warriors, keep military at home for defense
- Only scout explores (other units garrison)
- Once 4+ warriors accumulated, march all toward nearest enemy city
- Should survive enemy attacks with numerical advantage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:43:44 -07:00
Natalie
241391ddb4 debug: simplify combat logging 2026-04-12 14:41:25 -07:00
Natalie
4aefa304a2 debug: add combat result logging to auto_play 2026-04-12 14:38:54 -07:00
Natalie
040f53b09b fix: use EnvConfig.get_var not get_string for AUTO_PLAY_DIR 2026-04-12 14:33:50 -07:00
Natalie
2ea8da2479 fix(auto-play): use .visible instead of is_visible_in_tree for CanvasLayer nodes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:32:53 -07:00
Natalie
3823b6510b feat(auto-play): switch to autoload mode — fixes all autoload resolution errors
The -s SceneTree mode caused scripts to compile before autoloads were
registered, breaking any file referencing autoloads by name. Now auto_play
runs as a regular autoload that activates only when AUTO_PLAY=true env var
is set. All GameState, DataLoader, EventBus, EnvConfig references work
because autoloads are fully initialized before _ready() runs.

Also includes tile.gd lazy accessor fixes for DataLoader and EnvConfig.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:31:31 -07:00
Natalie
e3c7bd9832 fix(tile): also replace EnvConfig autoload with lazy accessor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:28:44 -07:00
Natalie
39216a1649 fix(tile): replace bare DataLoader autoload with lazy scene tree accessor
tile.gd referenced DataLoader by autoload name, which fails during initial
script compilation before autoloads are registered. This cascaded to break
game_map.gd, pathfinder.gd, and prevented tile creation during map generation.

Replace with static _data_loader() that resolves via Engine.get_main_loop().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:27:24 -07:00
Natalie
9d6d1e1da3 debug: log tiles count at frame 10 2026-04-12 14:24:46 -07:00
Natalie
1f6263c819 fix(auto-play): call _fix_start_positions at frame 10 when map tiles are loaded
The game_map.tiles dictionary is empty in _play_turn on the first frame
but populated by frame 10 when the world_map scene has fully initialized.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:24:02 -07:00
Natalie
0a51879f0f debug: early print in _fix_start_positions 2026-04-12 14:22:33 -07:00
Natalie
49e9a8caf1 fix(auto-play): use biome_id instead of get_terrain_flags for land tile detection
get_terrain_flags() calls DataLoader which fails in -s script context
due to class_name resolution order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:21:54 -07:00
Natalie
7a06d49bd7 debug: explicit size check for start_positions 2026-04-12 14:20:44 -07:00
Natalie
fbe3b24329 fix(auto-play): fix missing start positions by scanning for land tiles
The map generator's start position selection returns empty on some maps.
When detected, spread players across available land tiles and relocate
their units to the assigned positions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 14:19:32 -07:00
Natalie
dc5539d333 debug: print start positions and all player units 2026-04-12 14:16:29 -07:00