108 Commits

Author SHA1 Message Date
Zihao Xu
67b559ac5a feat: improve save/load interface with custom names and metadata (#128)
* feat: improve save/load interface with custom names and metadata

- Add custom save name support with input validation
- Extend save metadata with avatar counts, protagonist info, and event count
- Add quick save button alongside named save option
- Enhance save list display with richer information
- Add sanitize_save_name and find_protagonist_name helpers
- Update API endpoints to support new features
- Add i18n translations for new UI elements

Closes #95

* test: add comprehensive tests for save custom name feature

- Add 37 tests for sanitize_save_name, find_protagonist_name
- Add tests for custom name API endpoints
- Add tests for enhanced metadata
- Fix unused NIcon import in SaveLoadPanel
- Add zh-TW translations for new save_load keys

* test(frontend): add SaveLoadPanel component tests

- Add 21 tests for SaveLoadPanel component
- Cover save mode, load mode, display, validation
- Mock naive-ui components, stores, and API
2026-02-06 22:03:41 +08:00
bridge
ef926594c7 feat: auto clear death avatar after 20 years 2026-02-06 22:03:15 +08:00
bridge
741a88d174 fix: death avatar gets alive after loading 2026-02-06 21:57:53 +08:00
bridge
07e9b40645 update: readme 2026-02-06 21:40:33 +08:00
bridge
2cc456f6b3 refactor: i18n archi 2026-02-06 00:43:08 +08:00
bridge
07d1cfbee2 feat(i18n): enhance localization with new actions and descriptions
- Added new action translations for "assassinate", "attack", "breakthrough", "cultivate", "escape", and "self-heal" in English, Simplified Chinese, and Traditional Chinese.
- Included detailed descriptions and requirements for each action to improve gameplay clarity.
- Updated the translation extraction and compilation process to utilize the polib library for better handling of PO files.
2026-02-05 22:41:01 +08:00
4thfever
7630174820 Feat/relation (#139)
* update relation

* feat: add relation_type to avatar info structure and update related components

- Added `relation_type` to the avatar structured info in `info_presenter.py`.
- Updated `AvatarDetail.vue` to utilize the new `relation_type` for displaying avatar relationships.
- Modified `RelationRow.vue` to accept `type` as a prop for enhanced relationship representation.
- Updated `core.ts` to include `relation_type` in the `RelationInfo` interface.

Closes #
2026-02-05 22:14:44 +08:00
Zihao Xu
bd6f7e67d5 feat(server): make server host and port configurable (#127)
* feat(server): make server host and port configurable

Support configuring server binding address via environment variables
and config files. Priority: ENV > local_config.yml > config.yml > default.

- Add host and port options to system section in config.yml
- Read SERVER_HOST and SERVER_PORT from environment variables
- Default to 127.0.0.1:8002 for security

Set host to "0.0.0.0" to allow LAN access.

* test(server): add comprehensive tests for server binding config

Add 28 test cases covering:
- Environment variable priority (SERVER_HOST, SERVER_PORT)
- Config file reading (system.host, system.port)
- Default value fallback
- OmegaConf integration
- Edge cases (IPv6, empty values, invalid ports)

* docs: add mobile/LAN access instructions

- Add mobile access section to README and EN_README
- Configure Vite to listen on 0.0.0.0 for LAN access in dev mode
- Link to Issue #130 for mobile UI compatibility tracking
2026-02-04 21:47:17 +08:00
bridge
a59f6837ca fix(battle): correct killer name in death handling logic
- Updated the killer name reference in the handle_death function to use the winner's name instead of the attacker's name, ensuring accurate death reason reporting in battle scenarios.
2026-02-03 20:53:59 +08:00
bridge
4f377551e8 feat(avatar): implement region ownership management in AvatarManager and Avatar classes
- Added `owned_regions` attribute to the Avatar class to track regions owned by avatars.
- Introduced `occupy_region` and `release_region` methods for managing region ownership and ensuring proper relationship handling.
- Updated AvatarManager to clear relationships when an avatar is released, ensuring no lingering references.
- Refactored region ownership logic in the Occupy action and Simulator to utilize the new methods for better clarity and maintainability.
- Enhanced game loading process to establish ownership relationships correctly during game state restoration.
2026-02-02 21:34:02 +08:00
teps3105
f0b6b62de5 feat(i18n): add Traditional Chinese (zh-TW) locale support (#116)
* feat(i18n): add zh-TW locale support (backend infrastructure)

- 新增 LanguageType.ZH_TW 枚舉值
- 擴展 _lang_to_locale() 映射支援 zh-TW
- 創建 zh_TW 翻譯檔案結構 (messages.po + game_configs.po)
Closes #114

* feat(i18n): add zh-TW locale support (translation completion)

完成繁體中文語言的完整翻譯工作:

## 後端翻譯
- 將 messages.po 和 game_configs.po 轉換為繁體中文
- 編譯生成對應的 .mo 檔案
- 使用 OpenCC 's2t' 轉換器進行簡繁轉換

## 前端翻譯
- 新增 zh-TW.json 語言檔案
- 更新 index.ts 註冊 zh-TW 語言
- 修正 UI 語言標籤為「繁體中文」

## 翻譯統計
- messages.po: 701 個 msgid(動態字串、戰鬥、奇遇等)
- game_configs.po: 2972 個 msgid(遊戲配置)
- zh-TW.json: 347 行(前端 UI)

* feat(i18n): add zh-TW optimizations and tests

## 可選優化 1:用語本地化
- 修正前端 UI 詞彙為台灣繁體習慣
- 主要修正項目:
  - 菜單 -> 選單
  - 設置 -> 設定
  - 加載 -> 載入
  - 保存 -> 儲存
  - 程序 -> 程式
  - 其他 UI 用語調整

## 可選優化 2:測試覆蓋
- 新增 test_i18n_zh_tw.py 測試檔案
- 涵蓋 13 個測試用例:
  - 語言枚舉驗證
  - 語言切換測試
  - 日期格式驗證
  - 動態翻譯測試
  - 境界/動作/情緒翻譯測試
  - 檔案完整性檢查
  - 翻譯覆蓋率驗證
  - 回退機制測試

## 測試結果
- 所有 13 個測試用例通過
- 翻譯覆蓋率 > 95%

* fix(i18n): add polib skip check to translation coverage test

* feat(i18n): add zh-TW column to glossary with Taiwan localization
2026-02-01 13:28:18 +08:00
bridge
666310e7b4 feat: enhance hidden domains with additional properties and UI updates
- Updated `HiddenDomainInfo` interface to include `cd_years` and `open_prob` properties for better domain management.
- Modified `serialize_active_domains` function to serialize new properties.
- Enhanced `StatusWidget` to display additional information about hidden domains, including cooldown years and open probability.
- Updated localization files for English and Chinese to reflect new status labels for hidden domains.
2026-02-01 12:41:47 +08:00
4thfever
bc3ebc006c Refactor/i18n (#115)
重构i18n,现在game configs的配表,除了姓名这种外,都是统一的配表了。
对应的配表的名称和desc需要去i18n里取,但是其他配置不需要重复配置了。
这大大简化了之后新增i18n的心智负担。
2026-02-01 01:09:24 +08:00
4thfever
0315dca6e6 Feat/hidden domain (#113)
Summary
新增秘境探索,属于多人活动,每N年触发一次
Closes #105
2026-01-31 20:43:42 +08:00
bridge
efa663febe add: i18n msgid test 2026-01-31 13:36:14 +08:00
teps3105
3ddd7868b6 feat: add avatar metrics tracking feature (#111)
* feat: add avatar metrics tracking feature (#110)

Add AvatarMetrics dataclass for tracking avatar state snapshots

- Add AvatarMetrics dataclass for recording monthly snapshots
- Add metrics_history field to Avatar with opt-in tracking
- Implement automatic monthly snapshot recording in Simulator
- Add backward compatibility support for existing save files
- Set default tracking limit to 1200 months (100 years)
- Add comprehensive tests with 100% coverage
- Move documentation to specs directory with simplified chinese

* fix: convert Traditional Chinese comments to Simplified Chinese

修正程式碼中的繁體中文註解為簡體中文,以符合專案規範。

Fix Traditional Chinese comments to Simplified Chinese in codebase.
2026-01-30 23:07:45 +08:00
4thfever
202de66654 Feat/play (#109)
* refactor: play
2026-01-29 22:52:35 +08:00
bridge
6cb9e5c4e9 fix: death rate to 100% after reaching max age 2026-01-29 21:12:12 +08:00
4thfever
84027fc1d7 Feat/retreat (#104)
* feat: add retreat
2026-01-26 23:18:11 +08:00
Zihao Xu
aaa636a08e fix: use str() instead of .value for realm i18n display (#98)
* fix: use str() instead of .value for realm i18n display

Fix bug where user-facing messages displayed raw enum values like
"FOUNDATION_ESTABLISHMENT" instead of translated names like "筑基".

The Realm and Stage classes already have __str__ methods that return
i18n translated text, but several places were incorrectly using
.value which returns the raw enum string.

Changed files:
- src/classes/single_choice.py: item exchange messages
- src/classes/kill_and_grab.py: loot messages
- src/classes/fortune.py: fortune discovery messages
- src/classes/avatar/inventory_mixin.py: purchase error messages

Also added unit tests and integration tests to prevent regression.

* test: add integration tests for all modified files

Add tests covering:
- kill_and_grab.py: context string realm display
- fortune.py: weapon/auxiliary intro realm display
- inventory_mixin.py: can_buy_item error message realm display
2026-01-25 18:44:13 +08:00
Zihao Xu
a2f2010ee5 feat: auto npm install in dev mode to sync dependencies (#94) 2026-01-24 17:19:44 -08:00
4thfever
e1091fdf5a Feat/i18n (#92)
* feat: add vue-i18n

* feat: add vue-i18n

* feat: add vue-i18n

* feat: add language class

* add: en templates and configs

* add: en names

* refactor: name gender id and sect id

* feat(i18n): add gettext infrastructure for dynamic text translation (#81)

* feat(i18n): add gettext infrastructure for dynamic text translation

- Add src/i18n/ module with t() translation function
- Add .po/.mo files for zh_CN and en_US locales
- Update LanguageManager to reload translations on language change
- Add comprehensive tests (14 tests, all passing)
- Add implementation spec at docs/specs/i18n-dynamic-text.md

Phase 1 of i18n dynamic text implementation.

* feat(i18n): expand .po files with comprehensive translation entries

Add translation messages for:
- Battle result messages (fatal/non-fatal outcomes)
- Fortune event messages (item discovery, cultivation gains)
- Misfortune event messages (losses, damage, regression)
- Death reason messages
- Item exchange messages (equip, sell, discard)
- Single choice context and option labels
- Common labels (weapon, auxiliary, technique, elixir)

Both zh_CN and en_US locales updated with matching entries.

* test: add .po file integrity tests

* feat: i18n for actions

* feat: i18n for effects

* feat: i18n for gathering

* feat: i18n for classes

* feat: i18n for classes

* feat: i18n for classes

* feat: i18n for classes

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* update csv

* update world info

* update prompt

* update prompt

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* update

* update

* update

* update

* update

* update

* update

---------

Co-authored-by: Zihao Xu <xzhseh@gmail.com>
2026-01-24 13:47:23 +08:00
Zihao Xu
00c8860c56 test: add edge case tests for game initialization (#83)
* test: add edge case tests for game initialization

* test: add 3 more edge case tests for game initialization

* test: add 8 more edge case tests for comprehensive coverage

* docs: add comprehensive coverage report to test file header
2026-01-21 00:18:52 -08:00
Zihao Xu
38327c1b10 test: add game initialization integration tests (#82)
Add 17 tests covering the complete init_game_async flow:
- Phase progress updates (4 tests)
- Full initialization success (2 tests)
- History processing (2 tests)
- LLM check failure handling (1 test)
- Avatar generation (2 tests)
- Error handling (3 tests)
- Sect initialization (1 test)
- Phase name constants (2 tests)

Closes #72
2026-01-21 00:03:42 -08:00
Zihao Xu
666e19215d test: add comprehensive LLM failure scenario tests (#79)
* test: add comprehensive LLM failure scenario tests

Add 29 tests covering:
- HTTP errors: 401, 403, 404, 500, timeout, connection refused
- Parse errors: invalid JSON, empty response, array instead of object
- Retry logic: retry on parse failure, max retries exceeded
- Connectivity test: friendly error messages for common failures
- Configuration validation: missing base URL, URL normalization
- Async call_llm: success and error propagation
- Exception classes: LLMError, ParseError

Closes #71

* refactor: add comment explaining unreachable code for type checker
2026-01-20 23:27:04 -08:00
Zihao Xu
189e675711 test: add comprehensive WebSocket handler tests (#78)
Add 31 tests covering:
- ConnectionManager: connect, disconnect, broadcast, auto-pause
- WebSocket endpoint: connection, ping/pong, LLM config required message
- Control API: pause, resume, reset endpoints
- State/Map API: error handling, data serialization
- Event serialization: empty list, full fields, minimal fields

Closes #70
2026-01-20 23:00:48 -08:00
Zihao Xu
a1241a9156 fix: make cooldown_action decorator properly await async finish() (#75)
* fix: make cooldown_action decorator properly await async finish()

The decorator was incorrectly wrapping the async finish() method with a sync
wrapper, causing cooldown to be recorded BEFORE the action actually executed.

This fix:
- Changes wrapper to async def finish()
- Awaits original_finish() before recording cooldown
- Ensures cooldown is only recorded on successful execution

Fixes #74

* test: add test to verify cooldown not recorded on failure

This test actually reveals the async/await bug:
- Creates a FailingAction that raises in finish()
- Verifies cooldown is NOT recorded when action fails
- Fails with buggy sync wrapper, passes with async fix
2026-01-20 15:32:14 +08:00
Zihao Xu
a8666950b1 test: add comprehensive tests for mutual actions (talk, spar, impart) (#73)
- Talk: 31% -> 98% coverage
- Spar: 49% -> 100% coverage
- Impart: 37% -> 95% coverage
- Add 30 new test cases
- Overall coverage: 58.64% -> 60% (meets CI threshold)

Testing strategy: Mock LLM calls via call_llm_with_task_name

Closes #69
2026-01-19 23:09:38 -08:00
bridge
bf13cdf2d2 fix: incorrect relationship for new avatar 2026-01-19 21:14:20 +08:00
Zihao Xu
7f31d9884f test: add comprehensive tests for ai.py (13% -> 98% coverage) (#64)
- Test LLM response parsing (list and dict formats)
- Test null params conversion to empty dict
- Test invalid format handling and skipping
- Test emotion update logic with all emotion types
- Test fallback to CALM on invalid/missing emotion
- Test batch avatar processing
- Test AI.decide wrapper returns NULL_EVENT
- Test thinking field variants (avatar_thinking vs thinking)
- Add testing strategy documentation to test file

Closes #63
2026-01-19 20:49:24 +08:00
Zihao Xu
daa7a20679 test: add fixed_random_seed fixture with autouse=True (#52)
Ensures all tests have deterministic random behavior by setting
random.seed(42) before each test. This prevents flaky tests caused
by random number generation.

Closes #44
2026-01-19 20:46:59 +08:00
4thfever
6185d314af refactor: remove region_names dict, use regions traversal instead (#40)
The region_names dictionary was a redundant index that needed manual
sync when HistoryManager modified region names. This caused bugs where
resolve_query couldn't find regions by their new (history-modified) names.

Instead of maintaining two data structures (regions[id] and region_names[name]),
we now only use regions[id] as the single source of truth. The _resolve_region
function iterates over regions.values() to find matches by name.

This approach:
- Eliminates the sync bug entirely
- Simplifies the codebase
- Has negligible performance impact (region count is small)

Co-authored-by: Zihao Xu <xzhseh@gmail.com>
2026-01-18 17:13:28 +08:00
Zihao Xu
b68403e601 fix: mock StoryTeller in mock_llm_managers to prevent flaky test (#36)
The test_passive_update_loop test was flaky because when misfortune
randomly triggers during sim.step(), it calls StoryTeller.tell_story
which wasn't mocked, causing real LLM API calls to fail in CI.

Added StoryTeller.tell_story to the mock_llm_managers fixture.
2026-01-18 17:00:42 +08:00
bridge
47ad330b35 feat: data reload system 2026-01-18 16:53:24 +08:00
Zihao Xu
e3bf36bcd4 test: add tests for Avatar._init_known_regions (#34)
Verify that:
1. Avatar without sect knows current location's region
2. Avatar with sect knows their sect headquarters
3. Avatar without sect does not automatically know sect regions
4. Avatar only knows their own sect's headquarters, not others
2026-01-18 15:31:41 +08:00
Zihao Xu
7edae9188b fix(misc): CSV column name mismatches in data loading (#32)
* fix: CSV column name mismatches in data loading

- sect.py: Fix headquarter_name/headquarter_desc -> name/desc when reading sect_region.csv
- sect.py: Move sid initialization before technique lookup to fix unbound variable bug
- technique.py: Change sect (name) to sect_id (int) to match technique.csv column
- elixir.py: Remove redundant get_int(row, "id") that reads non-existent column

These fixes ensure:
1. Sect headquarters display correct location names (e.g., "大千光极城" instead of "不夜城")
2. Sect techniques are correctly associated and displayed
3. Technique sect restrictions work properly

* fix: update main.py to use sect_id, add CSV loading tests

- main.py: Change technique.sect to technique.sect_id in API response
- Add tests/test_csv_loading.py to verify CSV column names match code

* test: add API test for /api/meta/game_data endpoint

Verify that techniques in API response use sect_id field (not sect)

* fix: add None check for hq_region in AvatarFactory

Remove redundant code that adds sect headquarters to known_regions.
This logic is already handled by Avatar._init_known_regions() which
uses sect_id matching (more reliable than name-based lookup).

The removed code was causing a flaky test (~1% failure rate) because
resolve_query returns None in test environments with simplified maps.
2026-01-18 15:31:15 +08:00
bridge
e900c3e098 fix pytest 2026-01-14 17:17:21 +08:00
4thfever
df8b1b9433 Refactor/event (#31)
重构事件机制和部分拍卖会机制
2026-01-14 16:58:50 +08:00
4thfever
63fc2f828e Feat/auction (#30)
Add gathering events, in which multiple avatars participate
Add auction event

Closes #24
2026-01-14 02:33:13 +08:00
4thfever
0d34b27fff Feat: Add splash layer (#29)
Add splash layer, support game start, settings, exit
Modify settings layer, add "go back to splash" and "exit"
Add character threshold for history input
Closes #28
2026-01-13 22:00:23 +08:00
bridge
224e3e76f0 fix: pytest llm error only existed in github online CI 2026-01-13 00:08:42 +08:00
4thfever
95e1f11502 Refactor/history (#25)
add multi process history modification
2026-01-12 23:25:53 +08:00
bridge
2caa5586be refactor history archi 2026-01-12 00:36:10 +08:00
bridge
287f9d2ae4 update history pytest 2026-01-12 00:20:15 +08:00
bridge
57cf5ca51a add history class 2026-01-11 23:53:26 +08:00
bridge
5241f70ef3 refactor item ids 2026-01-11 23:12:48 +08:00
bridge
fa4c0340fd fix pytest 2026-01-11 22:48:05 +08:00
bridge
488758764e fix pytest for new awaken avatars 2026-01-11 21:03:02 +08:00
bridge
090e8fe32c fix remove avatar bug 2026-01-11 20:45:51 +08:00
bridge
3a0e432b02 refactor gift 2026-01-11 20:33:54 +08:00