Commit Graph

113 Commits

Author SHA1 Message Date
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
a143ed8a80 refactor: save & load 2026-02-06 21:51:55 +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
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
4thfever
0315dca6e6 Feat/hidden domain (#113)
Summary
新增秘境探索,属于多人活动,每N年触发一次
Closes #105
2026-01-31 20:43:42 +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
4thfever
84027fc1d7 Feat/retreat (#104)
* feat: add retreat
2026-01-26 23:18:11 +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
bridge
bf13cdf2d2 fix: incorrect relationship for new avatar 2026-01-19 21:14:20 +08:00
bridge
094a8fdd00 feat: data reload system 2026-01-18 16:47:54 +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
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
95e1f11502 Refactor/history (#25)
add multi process history modification
2026-01-12 23:25:53 +08:00
bridge
488758764e fix pytest for new awaken avatars 2026-01-11 21:03:02 +08:00
bridge
58486f95e8 fix pytest bugs 2026-01-08 20:22:03 +08:00
Zihao Xu
06d1bed987 fix: integrate SQLite event storage into load/save system
- Fix load_game to use World.create_with_db() for SQLite event storage
- Add get_events_db_path() to compute event database path from save path
- Add JSON to SQLite migration for backward compatibility with old saves
- Close old EventManager before loading new save to prevent connection leaks
- Add events_db metadata to save file
- Add comprehensive tests for database switching bug and save/load cycle
2026-01-07 23:22:17 -08:00
Zihao Xu
a6b8198c3f Merge branch 'main' into xzhseh/sqlite-event-manager 2026-01-07 20:05:02 -08:00
bridge
b2a021bf8a rename item -> material & refactor buying action 2026-01-07 22:43:26 +08:00
Zihao Xu
37518342fc fix: prevent character age from exceeding realm lifespan on creation 2026-01-07 01:08:12 -08:00
Zihao Xu
a1f08dd0ab feat: SQLite event storage with pagination and filtering
Implement SQLite-based event persistence as specified in sqlite-event-manager.md.

## Changes

### Backend
- **EventStorage** (`src/classes/event_storage.py`): New SQLite storage layer
  - Cursor-based pagination with compound cursor `{month_stamp}_{rowid}`
  - Avatar filtering (single and pair queries)
  - Major/minor event separation
  - Cleanup API with `keep_major` and `before_month_stamp` filters

- **EventManager** (`src/classes/event_manager.py`): Refactored to use SQLite
  - Delegates to EventStorage for persistence
  - Memory fallback mode for testing
  - New `get_events_paginated()` method

- **API** (`src/server/main.py`):
  - `GET /api/events` - Paginated event retrieval with filtering
  - `DELETE /api/events/cleanup` - User-triggered cleanup

### Frontend
- **EventPanel.vue**: Scroll-to-load pagination, dual-person filter UI
- **world.ts**: Event state management with pagination
- **game.ts**: New API client methods

### Testing
- 81 new tests for EventStorage, EventManager, and API
- Added `pytest-asyncio` and `httpx` to requirements.txt

## Known Issues: Save/Load is Currently Broken

After loading a saved game, the following issues occur:

1. **Wrong database used**: API returns events from the startup database instead
   of the loaded save's `_events.db` file
2. **Events from wrong time period**: Shows events from year 115 when loaded
   save is at year 114
3. **Pagination broken after load**: `has_more` returns `False` despite hundreds
   of events in the saved database
4. **Filter functionality broken**: Character selection filter stops working
   after loading a game

Root cause: `load_game.py` does not properly switch the EventManager's database
connection to the loaded save's events database.
2026-01-07 00:40:34 -08:00
bridge
e4ff312f58 fix action being executed 3 times bug 2026-01-06 23:41:21 +08:00
bridge
fbb32adbf6 refactor normalize and resolution 2026-01-06 22:13:47 +08:00
bridge
b60481c99c fix death bug 2026-01-06 21:23:06 +08:00
bridge
3f980d4593 fix a bug 2026-01-06 20:42:53 +08:00
bridge
8d7e11b021 add elixir 2026-01-05 23:04:55 +08:00
bridge
2a68f352bc add elixir 2026-01-05 22:26:16 +08:00
Zihao Xu
8c8e28264f fix: handle null action_params from LLM response
LLM sometimes returns null instead of {} for action_params when an
action doesn't require parameters (e.g., ["Cultivate", null]). This
caused AttributeError when calling .items() on None.

Changes:
- Add defensive check in ai.py to convert null to {}
- Update prompt to explicitly require {} instead of null
2026-01-05 01:36:50 -08:00
bridge
b74014f9f2 add emotion 2026-01-04 22:49:20 +08:00
bridge
5b5cd79cb5 add circulation manager 2026-01-03 22:15:25 +08:00
bridge
f499f63c50 update 2026-01-03 22:05:45 +08:00
bridge
7197dd1acb refactor equip 2025-12-31 23:18:47 +08:00
bridge
17ca0cbbce add misfortune 2025-12-30 23:09:29 +08:00
bridge
6a4059280a refactor death 2025-12-29 21:46:26 +08:00
bridge
6e380f1161 remove mp 2025-12-22 00:30:09 +08:00
bridge
162ea8efe2 refactor llm 2025-12-20 22:13:26 +08:00
bridge
e8489fcc25 fix bugs 2025-12-20 21:43:18 +08:00
bridge
3c586f936c add event handler auto go down logic 2025-12-20 21:25:57 +08:00
bridge
57c669be47 fix bugs 2025-12-20 21:16:09 +08:00
bridge
8fb81c3473 refactor relation add and cancel 2025-12-20 20:30:30 +08:00
bridge
3d117c2fb2 fix tile region = none bug 2025-12-20 19:26:53 +08:00
bridge
3ca5333246 fix save bugs 2025-12-15 00:12:21 +08:00
bridge
30a10bbb1c add pytest 2025-12-14 15:13:48 +08:00
bridge
6b0bf25699 fix pngs 2025-12-14 14:59:25 +08:00
bridge
a51f0a0ad2 add occupy action 2025-12-10 22:48:52 +08:00
bridge
5590b83487 add occupy action 2025-12-10 22:34:14 +08:00
bridge
303bffe413 decide only one avatar each time 2025-12-08 22:08:53 +08:00
bridge
31ab56251b refactor map 2025-12-02 23:00:09 +08:00