167 Commits

Author SHA1 Message Date
bridge
a7ab18ea1c fix: package bug 2026-01-19 21:26:09 +08:00
bridge
bf13cdf2d2 fix: incorrect relationship for new avatar 2026-01-19 21:14:20 +08:00
Zihao Xu
31d0c060e8 feat: enhance README with activity graph and contributor avatars (#65) 2026-01-19 20:50:33 +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
665d94addb test(web): add example frontend tests (#61)
* test(web): setup frontend test infrastructure

- Add testing dependencies (vitest, vue-test-utils, testing-library, jsdom, msw)
- Create vitest.config.ts with jsdom environment and coverage settings
- Create setup.ts with Pinia initialization and fake timers
- Add test scripts to package.json (test, test:run, test:coverage)

Closes #56, closes #57

* test(web): add example frontend tests

- Add system store tests (initial state, getters, togglePause)
- Add eventHelper utility tests (processNewEvents, mergeAndSortEvents, avatarIdToColor, highlightAvatarNames)

Closes #59
2026-01-19 20:48:43 +08:00
Zihao Xu
8bf5f64bc3 test(web): setup frontend test infrastructure (#60)
- Add testing dependencies (vitest, vue-test-utils, testing-library, jsdom, msw)
- Create vitest.config.ts with jsdom environment and coverage settings
- Create setup.ts with Pinia initialization and fake timers
- Add test scripts to package.json (test, test:run, test:coverage)

Closes #56, closes #57
2026-01-19 20:48:28 +08:00
Zihao Xu
9677055faa fix: use sect_id instead of sect in fortune technique filter (#55)
PR #32 changed Technique.sect (str) to Technique.sect_id (int), but
fortune.py was not updated. This caused AttributeError when fortune
event triggered and tried to access t.sect.

Error: 'Technique' object has no attribute 'sect'
2026-01-19 20:48:05 +08:00
Zihao Xu
8f7c2cfa66 docs: add Codecov coverage badge to README (#54)
Closes #49
2026-01-19 20:47:49 +08:00
Zihao Xu
ee2964e151 ci: add coverage reporting, 60% threshold, and Codecov integration (#53)
- Add pytest-cov to CI dependencies
- Generate coverage report (xml + terminal)
- Set minimum coverage threshold to 60% (current: 63%, target: 90%)
- Upload coverage to Codecov
- Add 10 minute timeout

Closes #46, closes #47, closes #48
2026-01-19 20:47:26 +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
Zihao Xu
ed2d8720aa chore: configure coverage settings in pyproject.toml (#51)
- Add [tool.coverage.run] with source and branch coverage
- Add [tool.coverage.report] with exclude patterns and show_missing

Closes #43
2026-01-19 20:46:42 +08:00
Zihao Xu
5a82a186a7 chore: add pytest-cov to requirements (#50)
Closes #42
2026-01-19 20:46:09 +08:00
Zihao Xu
1a34b7724b feat(web): make avatar names in event log clickable (#41)
When avatars overlap (e.g., during sparring, talking, dual cultivation),
it's hard to click on them directly. This adds the ability to click on
colored avatar names in the event panel to open their detail view.

- Modify highlightAvatarNames to include data-avatar-id attribute
- Add click event delegation in EventPanel
- Add hover styles for clickable names
2026-01-19 20:45:44 +08:00
bridge
2e04b718e8 update: splash 2026-01-18 21:49:13 +08:00
bridge
a075c1cc59 update: history prompt 2026-01-18 21:44:47 +08:00
bridge
bc6725b302 update: version 2026-01-18 17:25:27 +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
Zihao Xu
ce64c6b048 fix(web): decouple manual pause state from system pause behavior (#37)
The pause indicator was showing 'paused' while the game was still running
because isManualPaused was being modified by both user actions (clicking
pause button) and system actions (opening menu).

Changes:
- systemStore: pause()/resume() no longer modify isManualPaused, only
  togglePause() does (with optimistic update + rollback on failure)
- useGameControl: consolidate 3 overlapping watches into 1 clean watch
  that only handles menu open/close without polluting manual pause state
- App.vue: explicitly call resumeGame() API when game initializes
2026-01-18 16:59:44 +08:00
bridge
47ad330b35 feat: data reload system 2026-01-18 16:53:24 +08:00
bridge
094a8fdd00 feat: data reload system 2026-01-18 16:47:54 +08:00
bridge
eb2c715069 feat: data reload system 2026-01-18 16:37:08 +08:00
bridge
bd563b10f4 feat: add splash mp4 video 2026-01-18 16:11:34 +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
0acf72a313 fix: remove tmp 2026-01-18 14:42:45 +08:00
bridge
4fea4b6a9b update: contributing md 2026-01-15 09:35:34 +08:00
bridge
e5ed418949 update: readme 2026-01-15 09:01:02 +08:00
bridge
9b294ccba3 fix: game control bug 2026-01-15 08:55:01 +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
bb2e010930 refactor readme (#26)
refactor readme, simulate style of
https://github.com/vladelaina/Catime
Closes #23
2026-01-13 00:03:09 +08:00
4thfever
95e1f11502 Refactor/history (#25)
add multi process history modification
2026-01-12 23:25:53 +08:00
4thfever
176fa95425 Merge pull request #21 from AI-Cultivation/feat/history
Feat/history
2026-01-12 00:40:56 +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
19b9ddd8ba refactor frontend 2026-01-11 22:44:05 +08:00
bridge
879a3c0d1f refactor frontend (not done) 2026-01-11 22:29:53 +08:00
bridge
08e28f52c7 refactor frontend (not done) 2026-01-11 22:15:45 +08:00
bridge
f33cfab0d5 refactor frontend (not done) 2026-01-11 22:08:01 +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
5143266442 fix remove avatar bug 2026-01-11 20:40:53 +08:00
bridge
3a0e432b02 refactor gift 2026-01-11 20:33:54 +08:00
bridge
2056538375 uncomment protagonists 2026-01-11 19:56:26 +08:00
4thfever
2d9f073435 Merge pull request #20 from AI-Cultivation/fix-misorder-events
fix: incorrect order in event panel
2026-01-11 19:27:55 +08:00
bridge
ff6038b786 fix: incorrect order in event panel 2026-01-11 19:26:05 +08:00
bridge
88cc7cd966 feat: add color to map avatar names 2026-01-11 18:54:34 +08:00
bridge
ed7d16b4f3 feature: log print version 2026-01-11 18:27:41 +08:00
bridge
a0cfb3b9da make better conversation template 2026-01-10 01:41:13 +08:00
bridge
ac8c6c1c73 update tips 2026-01-10 00:50:30 +08:00
bridge
33b01fa0e9 fix web 2026-01-10 00:34:44 +08:00
bridge
92fc6d4b83 update protagonist 2026-01-10 00:01:58 +08:00
bridge
79c375802d update protagonist 2026-01-09 23:48:23 +08:00
bridge
da43adac96 update icon 2026-01-09 22:01:51 +08:00
bridge
1499c0cbc8 fix unittest bug 2026-01-09 01:07:52 +08:00
bridge
e5f96b7f43 update readme and tips 2026-01-09 00:50:39 +08:00
bridge
59824d9cd5 update readme and tips 2026-01-09 00:49:16 +08:00
bridge
ff6d1b5de7 add more protagonist 2026-01-08 23:19:35 +08:00
bridge
f8f0e8a59c update tips 2026-01-08 23:06:36 +08:00
bridge
f7d6554e9b update objective front end 2026-01-08 22:49:23 +08:00
bridge
a4dd29145f update tips 2026-01-08 22:35:42 +08:00
bridge
c6a574a2ac refactor: remove switch weapon action 2026-01-08 22:19:56 +08:00
bridge
9c21259577 refactor: add store mixin into city regions & refactor buying action 2026-01-08 22:16:33 +08:00
bridge
d1d7e7d7bd fix conflict with pr-16 2026-01-08 21:23:06 +08:00
Zihao Xu
9e75d8dd2e revert: remove SaveLoadPanel.vue changes 2026-01-08 21:12:18 +08:00
Zihao Xu
9485b62cfd feat: add loading screen with progress tracking
- Add async initialization with 6 phases: scanning_assets, loading_map,
  initializing_sects, generating_avatars, checking_llm, generating_initial_events
- Add /api/init-status endpoint for frontend polling
- Add /api/control/reinit endpoint for error recovery
- Add LoadingOverlay.vue component with:
  - Progress ring with gradient
  - Phase text in xianxia style (rotating messages for LLM phase)
  - Tips that rotate every 5 seconds
  - Time-based background transparency (fades to 80% over 20s)
  - Backdrop blur effect
  - Error state with retry button
- Preload map and avatars during LLM initialization for smoother UX
- Add comprehensive tests for init status API
2026-01-08 21:12:18 +08:00
Zihao Xu
8631be501b fix: prevent game from auto-starting to avoid stale initialization events
Problem:
When loading a save (e.g., from year 106), events from year 100 would appear.
This happened because the game auto-started on server startup and client
connection, generating initialization events before the user could load a save.

Solution:
1. Backend: Keep game paused on startup even if LLM check passes
2. Backend: Remove auto-resume on first WebSocket connection
3. Frontend: Start with game paused (isManualPaused = true)

Now the user must explicitly click 'resume' to start a new game, or load a
save first. This prevents the race condition where game_loop generates events
with stale world state.
2026-01-08 21:10:05 +08:00
Zihao Xu
624f697bee fix: pause game during save load to prevent stale events
The game loop could generate events with the old world's timestamp while
loading a save, causing 100年1月 events to appear after loading a 106年
save. Now we pause the game before loading and keep it paused after,
giving the frontend time to refresh state.
2026-01-08 21:06:34 +08:00
4thfever
6b99552f08 Merge pull request #19 from AI-Cultivation/pr-12
Pr 12
2026-01-08 20:47:50 +08:00
bridge
58486f95e8 fix pytest bugs 2026-01-08 20:22:03 +08:00
bridge
c4ca92efc9 update template 2026-01-08 20:16:22 +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
1647494c7d update 2026-01-08 01:06:10 +08:00
bridge
a007292b60 update pytest 2026-01-08 00:53:13 +08:00
bridge
fabae13e87 update readme 2026-01-08 00:49:46 +08:00
bridge
060708bd79 update readme 2026-01-08 00:46:42 +08:00
bridge
4e95b57152 modify price system 2026-01-08 00:42:40 +08:00
bridge
40d8a0425b refactor self heal system 2026-01-08 00:33:41 +08:00
bridge
b53f428cbb update unittest 2026-01-07 23:14:48 +08:00
bridge
ea9a873589 use uv instead pip in github actions 2026-01-07 22:48:41 +08:00
bridge
345b759fff use uv instead pip in github actions 2026-01-07 22:46:08 +08:00
bridge
b2a021bf8a rename item -> material & refactor buying action 2026-01-07 22:43:26 +08:00
bridge
73c50286b7 add refine action 2026-01-07 21:28:29 +08:00
bridge
7c69d612b0 add refine action 2026-01-07 21:15:04 +08:00
4thfever
2c8f73d290 Merge pull request #15 from xzhseh/xzhseh/fix-age-exceeds-lifespan
fix: prevent character age from exceeding realm lifespan on creation
2026-01-07 20:36:53 +08:00
bridge
968625d27b fix git action 2026-01-07 20:33:25 +08:00
bridge
1dfce734ef fix occupy & gift given bug 2026-01-07 20:11:01 +08:00
4thfever
8ee0c34f6f Merge pull request #11 from xzhseh/xzhseh/add-ci-workflow
feat: add GitHub Actions CI for pytest
2026-01-07 19:08:00 +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
2e5a2c3c12 style: add comment to separate state and functions in world.ts 2026-01-07 01:02:17 -08:00
Zihao Xu
355e4d0e3c docs: add sqlite-event-manager spec 2026-01-07 00:46:27 -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
Zihao Xu
f5c40bae3b feat: add GitHub Actions CI for pytest 2026-01-07 00:30:31 -08:00
bridge
e4ff312f58 fix action being executed 3 times bug 2026-01-06 23:41:21 +08:00
bridge
35c0756e85 refactor all gather logic 2026-01-06 23:17:21 +08:00
bridge
649f66213e refactor cast action 2026-01-06 23:06:28 +08:00
bridge
5793c4d2b9 add lode 2026-01-06 23:04:56 +08:00
bridge
8a23dc5576 add lode 2026-01-06 23:01:25 +08:00
bridge
db6df82ea8 refactor cast action 2026-01-06 22:28:25 +08:00
bridge
fbb32adbf6 refactor normalize and resolution 2026-01-06 22:13:47 +08:00
bridge
c266655af9 refactor can_start logic of all actions 2026-01-06 21:43:24 +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
fa909e5a2a update frontend 2026-01-06 01:08:51 +08:00
bridge
d25a84953b refactor log 2026-01-05 23:58:32 +08:00
bridge
9f5ad04e92 refactor buy and sell 2026-01-05 23:52:38 +08:00
bridge
6873746d29 refactor buy and sell 2026-01-05 23:37:52 +08:00
bridge
4bff8e503b add buy action 2026-01-05 23:16:58 +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
bridge
96c43c7cf5 Merge branch 'pr-10' 2026-01-05 20:46:43 +08:00
bridge
53459b9abe fix: use {{}} instead of {} 2026-01-05 20:46:17 +08:00
4thfever
cd40c1f201 Merge pull request #9 from xzhseh/xzhseh/fix-dead-avatar-actions
fix: prevent actions on dead avatars
2026-01-05 20:32:56 +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
Zihao Xu
8d985e0a2b fix: prevent actions on dead avatars
- Add validate_target_avatar() to TargetingMixin for unified validation.
- Update Attack and Assassinate to use the new validation method.
- Add comment to MutualAction.can_start() explaining why it uses inline check.
- Add tests for dead target validation.
2026-01-04 19:29:35 -08:00
4thfever
8727a4f29a Merge pull request #8 from xzhseh/xzhseh/fix-misleading-docstring
fix: correct misleading docstring in to_json_str_with_intent
2026-01-05 09:26:25 +08:00
Zihao Xu
8f99f3edb2 fix: correct misleading docstring in to_json_str_with_intent 2026-01-04 17:22:58 -08:00
bridge
77390fa647 fix pytest 2026-01-04 22:55:59 +08:00
bridge
b74014f9f2 add emotion 2026-01-04 22:49:20 +08:00
bridge
441f8c8e3a refactor battle strength system 2026-01-04 22:28:13 +08:00
bridge
4fc74b1531 refactor battle strength system 2026-01-04 22:25:25 +08:00
bridge
276902bca0 refactor effect system 2026-01-04 22:03:05 +08:00
bridge
806e2c1262 refactor price system 2026-01-04 21:49:58 +08:00
bridge
5429e25b1e update readme 2026-01-04 21:18:20 +08:00
bridge
c24c0819ce add issue template 2026-01-04 21:15:42 +08:00
bridge
7320773bfe update readme 2026-01-04 21:12:35 +08:00
bridge
9865bd170b update readme 2026-01-04 21:06:10 +08:00
bridge
5ffeef897a update readme 2026-01-04 21:05:03 +08:00
bridge
1ec3ec092b update readme 2026-01-04 20:57:28 +08:00
4thfever
5633d113f8 Merge pull request #7 from xzhseh/xzhseh/feat-avatar-name-highlighting
feat: highlight avatar names with unique colors in event panel
2026-01-04 20:52:34 +08:00
4thfever
5de69b8e6f Merge pull request #6 from xzhseh/xzhseh/add-pr-template
chore: add PR template
2026-01-04 20:51:57 +08:00
4thfever
21e56276cd Merge pull request #5 from xzhseh/xzhseh/fix-fortune-master-relation
fix: correct master-apprentice relation direction in fortune event
2026-01-04 20:51:09 +08:00
4thfever
f0290af13a Merge pull request #4 from xzhseh/xzhseh/fix-gender-display-chinese
fix: display gender in Chinese for avatar list API
2026-01-04 20:50:40 +08:00
4thfever
0b773b1726 Merge pull request #3 from xzhseh/xzhseh/fix-macos-npm-subprocess
fix: cross-platform subprocess compatibility for npm dev server
2026-01-04 20:49:59 +08:00
Zihao Xu
fafe1b5997 feat: highlight avatar names with unique colors in event panel 2026-01-04 02:07:47 -08:00
Zihao Xu
aca71bc2d4 chore: add PR template with Summary and Test Plan 2026-01-04 01:43:42 -08:00
Zihao Xu
354050e2b5 fix: correct master-apprentice relation in fortune event
The set_relation(from, to, rel) means "from views to as rel".
When avatar (student) takes master (teacher), avatar should view
master as MASTER, not APPRENTICE.

Before: avatar.set_relation(master, APPRENTICE) - wrong direction
After:  avatar.set_relation(master, MASTER) - correct direction
2026-01-04 01:22:34 -08:00
Zihao Xu
233aea47d3 fix: display gender in Chinese for avatar list API
Use str(a.gender) instead of a.gender.value to return Chinese
"男"/"女" instead of English "male"/"female" in the avatar_list
endpoint, consistent with other APIs that use get_structured_info().
2026-01-04 00:59:24 -08:00
Zihao Xu
1a94117607 fix: cross-platform subprocess compatibility for npm dev server
On macOS/Linux, using shell=True with a list argument doesn't work as expected.
Only the first element is passed to the shell, causing npm to print help instead
of running the dev command.

Changes:
- Use shell=False + list on macOS/Linux, shell=True + string on Windows.
- Use terminate() instead of taskkill on macOS/Linux for cleanup.
2026-01-03 23:53:31 -08:00
bridge
b8de42aeb3 add badge 2026-01-04 00:58:51 +08:00
bridge
367b09fac3 add badge 2026-01-04 00:52:26 +08:00
bridge
f6ebe7c037 add badge 2026-01-04 00:49:30 +08:00
bridge
450d38e15a update version 2026-01-04 00:01:22 +08:00
bridge
7245a89774 update readme 2026-01-03 23:59:44 +08:00
bridge
f9ad2dcd87 update readme 2026-01-03 23:59:30 +08:00
bridge
868e355e41 refactor cast 2026-01-03 23:54:47 +08:00
bridge
11cef02d74 add cast readme 2026-01-03 23:29:25 +08:00
bridge
ea0296f3e2 add cast readme 2026-01-03 23:28:55 +08:00
bridge
775d830ec3 add cast 2026-01-03 23:25:38 +08:00
bridge
6129e0f898 update choice helper 2026-01-03 22:30:33 +08:00
bridge
3a9a9fd6f0 add choice helper 2026-01-03 22:26:55 +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
6cc0c355dd add more emojis 2026-01-03 21:48:26 +08:00
bridge
5b5ea31d87 refactor avatar effect desc 2026-01-03 21:45:19 +08:00
bridge
e2d03b587d refactor world desc 2026-01-03 21:25:24 +08:00
bridge
f7a4fb23c8 refactor world desc 2026-01-03 20:25:25 +08:00
bridge
9cb98a61dd fix mutual action interact with self bug 2026-01-03 20:08:53 +08:00
bridge
f562d4ea81 update config 2026-01-01 18:31:47 +08:00
353 changed files with 19086 additions and 3802 deletions

19
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,19 @@
---
name: Bug Report 🐛
about: 报告一个问题 (Report a bug)
title: "[Bug] "
labels: bug
assignees: ''
---
**问题描述**
简要描述你遇到的问题。
**复现步骤**
1.
2.
**环境信息**
- OS:
- 报错信息 (如有):

View File

@@ -0,0 +1,14 @@
---
name: Feature Request 💡
about: 建议一个新功能 (Propose a feature)
title: "[Feat] "
labels: enhancement
assignees: ''
---
**功能描述**
你希望添加什么功能?
**解决什么问题**
这个功能解决了什么痛点?

7
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,7 @@
## Summary
<!-- Brief description of what this PR does -->
## Test Plan
<!-- How was this tested? -->

41
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: "requirements.txt"
- name: Install dependencies
run: |
uv pip install --system -r requirements.txt
uv pip install --system pytest pytest-cov
- name: Run tests with coverage
run: pytest -v --cov=src --cov-report=xml --cov-report=term --cov-fail-under=60
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: ./coverage.xml
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }} # Optional for public repos, but recommended

55
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,55 @@
# 贡献指南 (Contributing Guide)
感谢你对 **Cultivation World Simulator** (修仙模拟器) 感兴趣!欢迎任何形式的贡献,包括修复 Bug、改进文档或开发新功能。
> **重要**:任何新功能提交请务必提前在 issue 中讨论清楚,得到维护者确认后,再进行贡献。
为了保持代码库的健康和风格统一,请在贡献前阅读以下指南。
## 🛠️ 开发环境搭建
具体的安装和启动步骤请参考 [README.md](./README.md) 中的说明。
**项目结构说明:**
- **后端 (Python)**: 位于 `src/` 目录。
- **前端 (Vue 3)**: 位于 `web/` 目录。
## ✅ 测试要求 (必须)
在提交 Pull Request 之前,请务必确保所有测试通过。这是保证代码质量的关键。
**运行后端测试:**
```bash
pytest tests/
```
请确保所有测试用例都能通过PASS。如果你添加了新功能建议同时也添加相应的测试用例。
## 📝 代码规范
我们追求**简洁、优雅、清晰易读**的代码风格。
### Python 后端
- 遵循 PEP 8 风格指南。
- 如果新增了功能请加入对应的pytest测试。
### Vue 前端
- 使用 **TypeScript** 编写逻辑。
- 遵循 Vue 3 Composition API 的最佳实践。
- 组件命名清晰,保持单一职责。
## 🚀 提交 Pull Request (PR)
1. **Fork** 本仓库到你的 GitHub 账户。
2. **Clone** 你的 Fork 版本到本地。
3. 创建一个新的分支进行开发:
```bash
git checkout -b feature/你的功能名称
# 或者
git checkout -b fix/修复的问题
```
4. 提交你的更改 (Commit),请使用清晰的提交信息。
5. 推送 (Push) 到你的远程分支。
6. 在 GitHub 上发起 **Pull Request**
感谢你的贡献!一起打造更好的修仙世界。

View File

@@ -6,6 +6,29 @@
# Cultivation World Simulator
![GitHub stars](https://img.shields.io/github/stars/4thfever/cultivation-world-simulator?style=social)
[![Bilibili](https://img.shields.io/badge/Bilibili-Watch_Video-FB7299?logo=bilibili)](https://space.bilibili.com/527346837)
![QQ Group](https://img.shields.io/badge/QQ%20Group-1071821688-deepskyblue?logo=tencent-qq&logoColor=white)
![Last Commit](https://img.shields.io/github/last-commit/4thfever/cultivation-world-simulator)
![Commit Activity](https://img.shields.io/github/commit-activity/y/4thfever/cultivation-world-simulator)
![Repo Size](https://img.shields.io/github/repo-size/4thfever/cultivation-world-simulator)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
![Status](https://img.shields.io/badge/Status-Alpha-tomato)
![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
![Genre: Xianxia](https://img.shields.io/badge/Genre-Xianxia-red)
![Powered by LLM](https://img.shields.io/badge/Powered%20by-LLM-0077B5)
![AI Agent](https://img.shields.io/badge/AI-Agent-orange)
![OpenAI Compatible](https://img.shields.io/badge/OpenAI%20API-Compatible-412991)
![Python](https://img.shields.io/badge/Python-3.10%2B-blue?style=flat&logo=python&logoColor=white)
![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=flat&logo=fastapi&logoColor=white)
![Vue](https://img.shields.io/badge/Vue.js-3.x-4FC08D?style=flat&logo=vuedotjs&logoColor=white)
![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=flat&logo=typescript&logoColor=white)
![Vite](https://img.shields.io/badge/vite-%23646CFF.svg?style=flat&logo=vite&logoColor=white)
![PixiJS](https://img.shields.io/badge/PixiJS-E72264?style=flat&logo=pixijs&logoColor=white)
<p align="center">
<img src="assets/screenshot.gif" alt="Game Demo" width="100%">
</p>
@@ -28,34 +51,45 @@ You don't need to personally fight monsters or level up. Instead, you observe al
<table border="0">
<tr>
<td width="33%" valign="top">
<h4 align="center">Character Panel</h4>
<img src="assets/角色.png" width="100%" />
<br/><br/>
<h4 align="center">Personality Traits</h4>
<img src="assets/特质.png" width="100%" />
</td>
<td width="33%" valign="top">
<h4 align="center">Sect System</h4>
<img src="assets/宗门.png" width="100%" />
<img src="assets/screenshots/宗门.png" width="100%" />
<br/><br/>
<h4 align="center">City Regions</h4>
<img src="assets/screenshots/城市.png" width="100%" />
<br/><br/>
<h4 align="center">Life Experiences</h4>
<img src="assets/经历.png" width="100%" />
<img src="assets/screenshots/经历.png" width="100%" />
</td>
<td width="33%" valign="top">
<h4 align="center">Independent Thinking</h4>
<img src="assets/思考.png" width="100%" />
<h4 align="center">Character Panel</h4>
<img src="assets/screenshots/角色.png" width="100%" />
<br/><br/>
<h4 align="center">Short/Long Term Goals</h4>
<img src="assets/目标.png" width="100%" />
<h4 align="center">Personality Traits</h4>
<img src="assets/screenshots/特质.png" width="100%" />
<br/><br/>
<h4 align="center">Independent Thinking</h4>
<img src="assets/screenshots/思考.png" width="100%" />
<br/><br/>
<h4 align="center">Nicknames</h4>
<img src="assets/绰号.png" width="100%" />
<img src="assets/screenshots/绰号.png" width="100%" />
</td>
<td width="33%" valign="top">
<h4 align="center">Cave Exploration</h4>
<img src="assets/screenshots/洞府.png" width="100%" />
<br/><br/>
<h4 align="center">Short/Long Term Goals</h4>
<img src="assets/screenshots/目标.png" width="100%" />
<br/><br/>
<h4 align="center">Elixirs/Artifacts/Weapons</h4>
<img src="assets/screenshots/丹药.png" width="100%" />
<img src="assets/screenshots/法宝.png" width="100%" />
<img src="assets/screenshots/武器.png" width="100%" />
</td>
</tr>
</table>
### Why make this?
### 💭 Why make this?
The worlds in cultivation novels are fascinating, but readers can only ever observe a corner of them.
Cultivation games are either completely scripted or rely on simple state machines designed by humans, often resulting in forced and unintelligent behaviors.
@@ -64,13 +98,75 @@ With the advent of Large Language Models, the goal of making "every character al
I hope to create a pure, joyful, direct, and living sense of immersion in a cultivation world. Not a pure marketing tool for some game company, nor pure research like "Stanford Town", but an actual world that provides players with real immersion.
## Contact
## 📞 Contact
If you have any questions or suggestions, feel free to open an Issue or Pull Request.
You're also welcome to leave a message on my [Bilibili account](https://space.bilibili.com/527346837)!
You can also join the QQ group for discussion: 1071821688. Verification answer is my Bilibili nickname.
You can also join the QQ group for discussion: 1071821688. Verification answer: 肥桥今天吃什么
## Development Progress
## 🚀 Usage
### ⚙️ Run Steps
1. Clone the repo:
```bash
git clone https://github.com/your-username/cultivation-world-simulator.git
cd cultivation-world-simulator
```
2. Install dependencies:
```bash
# Backend dependencies
pip install -r requirements.txt
# Frontend dependencies (Node.js environment required)
cd web && npm install
```
3. Configure LLM:
Edit `static/config.yml`:
```yaml
llm:
key: "your-api-key-here" # your api key
base_url: "https://api.xxx.com" # API addr
model_name: "normal_model_name"
fast_model_name: "fast_model_name"
```
Supports all API providers compatible with OpenAI interface format (e.g., Qwen, DeepSeek, SiliconFlow, OpenRouter, etc.)
You can also configure LLM parameters directly in the frontend:
<img src="assets/llm_config.png" alt="Frontend LLM Config" width="100%">
4. Run:
```bash
# Start service (Recommended dev mode, automatically starts frontend)
python src/server/main.py --dev
```
The browser will automatically open the web frontend.
## 📊 Project Status
![Repobeats analytics](https://repobeats.axiom.co/api/embed/91667dce0fca651a7427022b2d819d20dd17c5e3.svg "Repobeats analytics image")
## ⭐ Star History
If you find this project interesting, please give us a Star ⭐! It will motivate us to keep improving and adding new features.
<div align="center">
<a href="https://star-history.com/#4thfever/cultivation-world-simulator&Date">
<img src="https://api.star-history.com/svg?repos=4thfever/cultivation-world-simulator&type=Date" alt="Star History Chart" width="600">
</a>
</div>
## 👥 Contributors
- Aku, for world design & discussion
- [@xzhseh](https://github.com/xzhseh), contributed code
## 🙏 Acknowledgments
- Referenced some UI elements from ailifeengine
## 📋 Development Progress
### 🏗️ Foundation
- ✅ World map basics, time, event system
@@ -81,6 +177,9 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
- ✅ Standalone release (packaged exe)
- ✅ Menu bar & Save & Load
- ✅ Flexible custom LLM interface
- ✅ Support macOS
- [ ] Support multi-language localization
- ✅ Start Game Page
### 🗺️ World System
- ✅ Basic tile mechanics
@@ -88,7 +187,6 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
- ✅ Same-tile NPC interactions
- ✅ Qi distribution and yields
- ✅ World event
- [ ] Dynamic worldview, map, history, sect, and notable figure generation
### 👤 Character System
- ✅ Core attributes
@@ -102,15 +200,17 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
- ✅ Effect system: buffs/debuffs
- ✅ Techniques
- ✅ Combat equipment & auxiliary equipment
- ✅ Elixir
- ✅ Short/Long term memory
- ✅ Character's short and long term objectives, supporting player active setting
- ✅ Avatar nicknames
- [ ] Character compatibility
- [ ] Skill learning system:
- [ ] Learnable skills
- [ ] Life professions (alchemy, formations, planting, forging, etc.)
- [ ] Life Skills
- ✅ Forging
- ✅ Refine
- [ ] Planting
- [ ] Taming
- [ ] Evolving skills
- [ ] Mortals
- [ ] Prodigies (stronger abilities and AI)
### 🏛️ Organizations
- [ ] Sect system
@@ -126,7 +226,7 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
### ⚡ Action System
- ✅ Basic movement
- ✅ Action execution framework
- ✅ Defined actions (rule-complete)
- ✅ Defined actions
- ✅ Long-duration actions and settlement
- ✅ Multi-month actions (cultivate, breakthrough, play, etc.)
- ✅ Auto-settlement upon completion
@@ -137,7 +237,7 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
### 🎭 Event System
- ✅ Heaven-earth Qi fluctuations
- [ ] World-scale events:
- [ ] Auctions
- Auctions
- [ ] Secret realm exploration
- [ ] Martial tournaments
- [ ] Sect grand competition
@@ -176,11 +276,10 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
- ✅ One-off choices (e.g., switch techniques or not)
### 🏛️ World Lore
- [ ] Lore framework
- [ ] Worldbuilding
- [ ] Ancient history generation
- ✅ Inject basic world knowledge
- ✅ User input history, dynamic generation of techniques, equipment, sects, and region info
### Specials
### Specials
- ✅ Fortuitous encounters
- ✅ Tribulations & Heart devils
- [ ] Possession & Rebirth
@@ -188,66 +287,13 @@ You can also join the QQ group for discussion: 1071821688. Verification answer i
- [ ] Divination & Prophecy
- [ ] Male appearance female traits & Female appearance male traits
- [ ] Character Secrets & Two-faced
- [ ] Ascension to Upper Realm
- [ ] Ascension to Heaven
- [ ] Formations
- [ ] Paths/Daos
- [ ] World Secrets & World Laws (Flexible customization)
- [ ] Gu Refining
- [ ] World-ending Crisis
- [ ] Become a Legend of Later Ages
### 🔭 Long-term
- [ ] ECS parallel toolkit
- [ ] Novelization/imagery/video for history and events
- [ ] Avatar calling MCP tools on their own
## Usage
### Run Steps
1. Clone the repo:
```bash
git clone https://github.com/your-username/cultivation-world-simulator.git
cd cultivation-world-simulator
```
2. Install dependencies:
```bash
# Backend dependencies
pip install -r requirements.txt
# Frontend dependencies (Node.js environment required)
cd web && npm install
```
3. Configure LLM:
Edit `static/config.yml`:
```yaml
llm:
key: "your-api-key-here" # your API key
base_url: "https://api.xxx.com" # API base URL
model_name: "model-name" # main model name
fast_model_name: "fast-model" # fast model name
```
Supports all API providers compatible with OpenAI interface format (e.g., Qwen, DeepSeek, SiliconFlow, OpenRouter, etc.)
You can also configure LLM parameters directly in the frontend:
<img src="assets/llm_config.png" alt="Frontend LLM Config" width="100%">
4. Run:
```bash
# Start service (Recommended dev mode, automatically starts frontend)
python src/server/main.py --dev
```
The browser will automatically open the web frontend.
## Contributors
- Aku, for world design & discussion
## Acknowledgments
- Referenced some UI elements from ailifeengine
## License
This project is licensed as specified in the [LICENSE](LICENSE) file.
- [ ] Avatar calling MCP tools on their own

228
README.md
View File

@@ -6,9 +6,29 @@
# 修仙世界模拟器 (Cultivation World Simulator)
![Python](https://img.shields.io/badge/Python-3.10%2B-blue)
![Vue](https://img.shields.io/badge/Vue.js-3.x-4FC08D)
![GitHub stars](https://img.shields.io/github/stars/4thfever/cultivation-world-simulator?style=social)
[![Bilibili](https://img.shields.io/badge/Bilibili-%E6%9F%A5%E7%9C%8B%E8%A7%86%E9%A2%91-FB7299?logo=bilibili)](https://space.bilibili.com/527346837)
![QQ Group](https://img.shields.io/badge/QQ%E7%BE%A4-1071821688-deepskyblue?logo=tencent-qq&logoColor=white)
![Last Commit](https://img.shields.io/github/last-commit/4thfever/cultivation-world-simulator)
![Commit Activity](https://img.shields.io/github/commit-activity/y/4thfever/cultivation-world-simulator)
![Repo Size](https://img.shields.io/github/repo-size/4thfever/cultivation-world-simulator)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![codecov](https://codecov.io/gh/AI-Cultivation/cultivation-world-simulator/graph/badge.svg)](https://codecov.io/gh/AI-Cultivation/cultivation-world-simulator)
![Status](https://img.shields.io/badge/Status-Alpha-tomato)
![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)
![Genre: Xianxia](https://img.shields.io/badge/Genre-Xianxia-red)
![Powered by LLM](https://img.shields.io/badge/Powered%20by-LLM-0077B5)
![AI Agent](https://img.shields.io/badge/AI-Agent-orange)
![OpenAI Compatible](https://img.shields.io/badge/OpenAI%20API-Compatible-412991)
![Python](https://img.shields.io/badge/Python-3.10%2B-blue?style=flat&logo=python&logoColor=white)
![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=flat&logo=fastapi&logoColor=white)
![Vue](https://img.shields.io/badge/Vue.js-3.x-4FC08D?style=flat&logo=vuedotjs&logoColor=white)
![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=flat&logo=typescript&logoColor=white)
![Vite](https://img.shields.io/badge/vite-%23646CFF.svg?style=flat&logo=vite&logoColor=white)
![PixiJS](https://img.shields.io/badge/PixiJS-E72264?style=flat&logo=pixijs&logoColor=white)
<p align="center">
@@ -33,34 +53,45 @@
<table border="0">
<tr>
<td width="33%" valign="top">
<h4 align="center">角色面板</h4>
<img src="assets/角色.png" width="100%" />
<br/><br/>
<h4 align="center">性格特质</h4>
<img src="assets/特质.png" width="100%" />
</td>
<td width="33%" valign="top">
<h4 align="center">宗门体系</h4>
<img src="assets/宗门.png" width="100%" />
<img src="assets/screenshots/宗门.png" width="100%" />
<br/><br/>
<h4 align="center">城市区域</h4>
<img src="assets/screenshots/城市.png" width="100%" />
<br/><br/>
<h4 align="center">生平经历</h4>
<img src="assets/经历.png" width="100%" />
<img src="assets/screenshots/经历.png" width="100%" />
</td>
<td width="33%" valign="top">
<h4 align="center">自主思考</h4>
<img src="assets/思考.png" width="100%" />
<h4 align="center">角色面板</h4>
<img src="assets/screenshots/角色.png" width="100%" />
<br/><br/>
<h4 align="center">长短期目标</h4>
<img src="assets/目标.png" width="100%" />
<h4 align="center">性格特质</h4>
<img src="assets/screenshots/特质.png" width="100%" />
<br/><br/>
<h4 align="center">自主思考</h4>
<img src="assets/screenshots/思考.png" width="100%" />
<br/><br/>
<h4 align="center">江湖绰号</h4>
<img src="assets/绰号.png" width="100%" />
<img src="assets/screenshots/绰号.png" width="100%" />
</td>
<td width="33%" valign="top">
<h4 align="center">洞府探秘</h4>
<img src="assets/screenshots/洞府.png" width="100%" />
<br/><br/>
<h4 align="center">长短期目标</h4>
<img src="assets/screenshots/目标.png" width="100%" />
<br/><br/>
<h4 align="center">丹药/法宝/武器</h4>
<img src="assets/screenshots/丹药.png" width="100%" />
<img src="assets/screenshots/法宝.png" width="100%" />
<img src="assets/screenshots/武器.png" width="100%" />
</td>
</tr>
</table>
### 为什么要做这个?
### 💭 为什么要做这个?
修仙网文中的世界很精彩,但读者永远只能观察到一隅。
修仙品类游戏要么是完全的预设剧本,要么依靠人工设计的简单规则状态机,有许许多多牵强和降智的表现。
@@ -69,12 +100,84 @@
希望能够创造出纯粹的、快乐的、直接的、活着的修仙世界的沉浸感。不是像一些游戏公司的纯粹宣传工具,也不是像斯坦福小镇那样的纯粹研究,而是能给玩家提供真实代入感和沉浸感的实际世界。
## 联系方式
## 📞 联系方式
如果您对项目有任何问题或建议,欢迎提交 Issue 或 Pull Request。
欢迎给我的[B站账号](https://space.bilibili.com/527346837)留言!
也可以加入QQ群进行讨论1071821688。进群需要输入我的B站昵称。
也可以加入QQ群进行讨论1071821688。进群问题的答案:肥桥今天吃什么
## 功能开发进度
## 🚀 使用方法
### ⚙️ 运行步骤
1. 克隆项目到本地:
```bash
git clone https://github.com/your-username/cultivation-world-simulator.git
cd cultivation-world-simulator
```
2. 安装依赖:
```bash
# 后端依赖
pip install -r requirements.txt
# 前端依赖 (需Node.js环境)
cd web && npm install
```
3. 配置LLM
在 `static/config.yml` 中配置LLM参数OpenAI格式
```yaml
llm:
key: "your-api-key-here" # 你的API密钥
base_url: "https://api.xxx.com" # API地址
model_name: "normal_model_name" # 智能模型名称
fast_model_name: "fast_model_name" # 快速模型名称
```
也支持在前端直接配入LLM参数
<img src="assets/llm_config.png" alt="前端LLM配置" width="100%">
4. 运行:
```bash
# 启动服务 (推荐开发模式,会自动启动前端)
python src/server/main.py --dev
```
浏览器会自动打开网页前端。
## 📊 项目状态
<div align="center">
<img src="https://github-readme-activity-graph.vercel.app/graph?username=4thfever&repo=cultivation-world-simulator&theme=github-compact&hide_border=true&area=true" width="100%" alt="Activity Graph" />
</div>
<br/>
![Repobeats analytics](https://repobeats.axiom.co/api/embed/91667dce0fca651a7427022b2d819d20dd17c5e3.svg "Repobeats analytics image")
## ⭐ Star History
如果你觉得这个项目有趣,请给我们一个 Star ⭐!这将激励我们持续改进和添加新功能。
<div align="center">
<a href="https://star-history.com/#4thfever/cultivation-world-simulator&Date">
<img src="https://api.star-history.com/svg?repos=4thfever/cultivation-world-simulator&type=Date" alt="Star History Chart" width="600">
</a>
</div>
## 👥 贡献者
<a href="https://github.com/4thfever/cultivation-world-simulator/graphs/contributors">
<img src="https://contrib.rocks/image?repo=4thfever/cultivation-world-simulator&max=100&columns=12" />
</a>
* **Aku** - 世界观 & 玩法设计与讨论
* **[@xzhseh](https://github.com/xzhseh)** - 贡献代码
## 🙏 致谢
- 参考了ai life engine部分ui
## 📋 功能开发进度
### 🏗️ 基础系统
- ✅ 基础世界地图、时间、事件系统
@@ -85,6 +188,9 @@
- ✅ release 一键即玩的exe
- ✅ 菜单栏 & 存档 & 读档
- ✅ 灵活自定义LLM接口
- ✅ 支持mac os
- [ ] 多语言本地化
- ✅ 开始游戏页
### 🗺️ 世界系统
- ✅ 基础tile地块系统
@@ -92,7 +198,6 @@
- ✅ 同地块NPC交互
- ✅ 灵气分布与产出设计
- ✅ 世界事件
- [ ] 动态世界观设定、地图、历史、宗门、名人生成
### 👤 角色系统
- ✅ 角色基础属性系统
@@ -106,15 +211,17 @@
- ✅ 角色Effects系统增益/减益效果
- ✅ 角色功法
- ✅ 角色兵器 & 辅助装备
- ✅ 丹药
- ✅ 角色长短期记忆
- ✅ 角色的长短期目标,支持玩家主动设定
- ✅ 角色绰号
- [ ] 角色间相性
- [ ] 技能学习系统:
- [ ] 可学习技能
- [ ] 生活职业丹药、阵法、种植、铸造etc
- [ ] 生活技能
- ✅ 铸造
- ✅ 炼丹
- [ ] 种植
- [ ] 饲养
- [ ] 技能可升级
- [ ] 凡人系统
- [ ] 天骄系统更强能力更强AI
### 🏛️ 组织系统
- [ ] 宗门系统
@@ -130,18 +237,18 @@
### ⚡ 动作系统
- ✅ 基础移动动作
- ✅ 动作执行框架
- ✅ 有明确规则的定义动作(Defined Action)
- ✅ 有明确规则的定义动作
- ✅ 长动作执行和结算系统
- ✅ 支持多月份持续的动作(如修炼、突破、游戏等)
- ✅ 动作完成时的自动结算机制
- ✅ 多人动作:动作发起与动作响应
- ✅ 影响人际关系的LLM动作(LLM Action)
- ✅ 影响人际关系的LLM动作
- ✅ 系统性的动作注册与运行逻辑
### 🎭 事件系统
- ✅ 天地灵气变动
- [ ] 世界范围大事件:
- [ ] 拍卖会
- ✅ 多人大事件:
- 拍卖会
- [ ] 秘境探索
- [ ] 比武大会
- [ ] 宗门大比
@@ -180,11 +287,10 @@
- ✅ 一次性选择(如是否要切换功法)
### 🏛️ 世界背景系统
- [ ] 背景故事框架
- [ ] 世界观生成
- [ ] 上古历史生成
- ✅ 注入基础世界知识
- ✅ 用户输入历史,动态生成功法、装备、宗门、区域信息
### 特殊
### 特殊
- ✅ 奇遇
- ✅ 天劫 & 心魔
- [ ] 夺舍 & 重生
@@ -198,59 +304,7 @@
- [ ] 世界秘密 & 世界法则 (可灵活自定义)
- [ ] 炼蛊
- [ ] 灭世危机
- [ ] 成为后世传奇
### 🔭 远期展望
- [ ] ECS并行
- [ ] 历史/事件的小说化&图片化&视频化
- [ ] MCP agent化修士自行调用工具
## 使用方法
### 运行步骤
1. 克隆项目到本地:
```bash
git clone https://github.com/your-username/cultivation-world-simulator.git
cd cultivation-world-simulator
```
2. 安装依赖:
```bash
# 后端依赖
pip install -r requirements.txt
# 前端依赖 (需Node.js环境)
cd web && npm install
```
3. 配置LLM
在 `static/config.yml` 中配置LLM参数OpenAI格式
```yaml
llm:
key: "your-api-key-here" # 你的API密钥
base_url: "https://api.xxx.com" # API地址
model_name: "qwen-plus" # 智能模型名称
fast_model_name: "qwen-turbo" # 快速模型名称
```
也支持在前端直接配入LLM参数
<img src="assets/llm_config.png" alt="前端LLM配置" width="100%">
4. 运行:
```bash
# 启动服务 (推荐开发模式,会自动启动前端)
python src/server/main.py --dev
```
浏览器会自动打开网页前端。
## 贡献者
- Aku, 世界观\玩法设计与讨论
## 致谢
- 参考了ai life engine部分ui
## 许可证
本项目采用 [LICENSE](LICENSE) 文件中指定的许可证。
- [ ] MCP agent化修士自行调用工具

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 208 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 263 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 244 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 238 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 218 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 357 KiB

After

Width:  |  Height:  |  Size: 357 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 348 KiB

After

Width:  |  Height:  |  Size: 348 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 335 KiB

After

Width:  |  Height:  |  Size: 335 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 325 KiB

After

Width:  |  Height:  |  Size: 325 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 230 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 292 KiB

After

Width:  |  Height:  |  Size: 292 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 281 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 255 KiB

After

Width:  |  Height:  |  Size: 255 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 275 KiB

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 867 KiB

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

Before

Width:  |  Height:  |  Size: 318 KiB

After

Width:  |  Height:  |  Size: 318 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 352 KiB

After

Width:  |  Height:  |  Size: 352 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 323 KiB

After

Width:  |  Height:  |  Size: 323 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Some files were not shown because too many files have changed in this diff Show More