Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
162 commits
Select commit Hold shift + click to select a range
4effac2
feat(config): allow to deactivate maps, classes, monsters, items and …
claude Oct 2, 2026
9859463
feat(config): respect inactive content in class evolution and invasions
claude Oct 2, 2026
ec9e2e9
feat(config): add the game version which introduced the content
claude Oct 2, 2026
f5334c4
feat(config): use the patch versions of the history before Season 1
claude Oct 2, 2026
afc8305
docs(items): add concept for data-driven item price rules
claude Oct 3, 2026
5d6ae8a
test(items): compare item prices with a frozen copy of the calculator
claude Oct 3, 2026
f1dcb68
Merge remote-tracking branch 'origin/master' into claude/openmu-issue…
claude Oct 3, 2026
75f8e37
feat(items): add item price definitions to the data model
claude Oct 3, 2026
b286c6b
feat(items): initialize the item price definitions
claude Oct 3, 2026
92baca2
refactor(items): calculate item prices by their price definitions
claude Oct 3, 2026
9e75b06
docs(items): fix markdownlint findings in the price rules concept
claude Oct 3, 2026
0bb390f
Merge remote-tracking branch 'origin/master' into claude/openmu-issue…
claude Oct 3, 2026
3b4e700
Merge branch 'master' into claude/sweet-hamilton-v6sy9a
claude Oct 4, 2026
1c44319
fix(config): list the Magic Gladiator as introduced in 0.95d
claude Oct 4, 2026
2275374
feat(localization): add German translations for the content activation
claude Oct 4, 2026
1d15cfa
Merge branch 'master' into claude/sweet-hamilton-v6sy9a
claude Oct 8, 2026
37b202f
chore: remove accidentally committed build output
claude Oct 8, 2026
11bde37
fix(skills): correct the swapped fire scream requirements
Dutch77 Oct 22, 2026
c41dbe4
Merge pull request #1266 from Dutch77/fix/fire-scream-requirements
sven-n Oct 23, 2026
c3e3cb0
test(castle-siege): complete regression testing strategy
Zylkien Oct 23, 2026
0c10986
docs(castle-siege): wrap testing commands to satisfy line limits
Zylkien Oct 23, 2026
432c690
fix(guilds): reconcile rivalry caches after alliance changes
Zylkien Oct 23, 2026
fe67d71
fix(guilds): reconcile rivalry caches across guild reconnects
Zylkien Oct 23, 2026
59fa740
Merge pull request #1269 from Zylkien/castle-siege/734-testing-strategy
sven-n Oct 23, 2026
4f5b91d
feat(mcp): add read-only admin MCP server
sven-n Oct 23, 2026
4702b72
fix(mcp): address review findings and Codacy issues
sven-n Oct 23, 2026
d29f64b
fix(mcp): qualify fixture disposal interface for static analysis
sven-n Oct 23, 2026
ded62e2
feat(persistence): an update can run on a new database
ezequielzacca Oct 23, 2026
10256e6
test(persistence): updates on a new database, unit and end to end
ezequielzacca Oct 23, 2026
60e4bdc
test(persistence): the order test's updates are sealed, each with its…
ezequielzacca Oct 23, 2026
28bb4a3
test(persistence): the test updates add a marker item, which the test…
ezequielzacca Oct 23, 2026
69fce83
test(discord): await queue validation rendering
sven-n Oct 24, 2026
3107667
fix(mcp): address proxy, configuration and guild review findings
sven-n Oct 24, 2026
d4cd40b
fix(mcp): preserve proxy upgrades and resolve static analysis
sven-n Oct 24, 2026
b6e3d15
fix(mcp): handle concurrent edits and bind admin ports to loopback
sven-n Oct 24, 2026
749c6b1
refactor(mcp): make the configuration retry bound explicit
sven-n Oct 24, 2026
2dd2b83
Merge pull request #1271 from MUnique/feat/1257-read-only-mcp
sven-n Oct 24, 2026
32a9190
Merge remote-tracking branch 'origin/master' into feat/updates-on-new…
ezequielzacca Oct 24, 2026
ad2b66b
fix(persistence): a new database installs updates in their dependency…
ezequielzacca Oct 24, 2026
172460f
fix(persistence): a broken optional update doesn't stop a new databas…
ezequielzacca Oct 24, 2026
f488213
test(persistence): no arguments that repeat their default
ezequielzacca Oct 24, 2026
e6ede3e
Merge pull request #1272 from ezequielzacca/feat/updates-on-new-database
sven-n Oct 24, 2026
e80e754
fix(discord): revoke the Linked Player role after an admin unlink, al…
claude Oct 24, 2026
b6266c4
fix(discord): an older role removal can't undo a newer link
claude Oct 24, 2026
784eb69
fix(discord): role updates of different users don't wait for each other
claude Oct 24, 2026
43b504e
feat(mcp): add audited operational tools
sven-n Oct 24, 2026
d9103be
fix(discord): a late unlink event doesn't remove the role of a re-lin…
claude Oct 24, 2026
732e609
style(discord): resolve the Codacy findings of the pending role removals
claude Oct 24, 2026
68874e2
fix(discord): pending role removals survive changed Discord settings
claude Oct 24, 2026
bdedad2
fix(discord): a pending role removal keeps its Discord server
claude Oct 24, 2026
95a5e8b
docs(discord): wrap the paragraph about the role removals
claude Oct 24, 2026
d9f67d7
fix(discord): a role removal for an unreachable server stays pending
claude Oct 24, 2026
3bf40c0
Merge pull request #1274 from MUnique/claude/sweet-cray-w8crms
sven-n Oct 24, 2026
625ffba
fix(remoteview): send master stats of extended clients without 16 bit…
claude Oct 24, 2026
4e4937d
fix(mcp): address operational review findings
sven-n Oct 24, 2026
8feaf25
fix(admin): contain account creation operation errors
sven-n Oct 24, 2026
092a9c6
feat(crafting): add a configurable bonus to the crafting success rate
claude Oct 24, 2026
283a655
build(deps): bump body-parser from 1.20.6 to 1.20.9 in /docs-website
dependabot[bot] Oct 24, 2026
b40ed9e
build(deps): bump fast-uri from 3.1.8 to 3.1.9 in /docs-website
dependabot[bot] Oct 24, 2026
a153b0d
build(deps): bump undici from 7.30.0 to 7.30.1 in /docs-website
dependabot[bot] Oct 24, 2026
48847c2
Merge pull request #1282 from MUnique/dependabot/npm_and_yarn/docs-we…
sven-n Oct 24, 2026
3270633
Merge pull request #1281 from MUnique/dependabot/npm_and_yarn/docs-we…
sven-n Oct 24, 2026
1fc2d7e
Merge pull request #1280 from MUnique/dependabot/npm_and_yarn/docs-we…
sven-n Oct 24, 2026
d8c9800
fix(admin): restrict panel attribution to active circuits
sven-n Oct 24, 2026
0be9a37
Merge pull request #1278 from icheat2win/fix/master-stats-extended-ov…
sven-n Oct 24, 2026
b620a4a
Merge branch 'master' into feature/crafting-bonus-percentage
icheat2win Oct 24, 2026
9371c96
test(admin): exercise siege errors through panel controls
sven-n Oct 24, 2026
0412327
fix(crafting): resolve Codacy findings
claude Oct 24, 2026
c5f7218
feat(admin): show key columns like Number in item tables
claude Oct 24, 2026
47ebd84
Merge branch 'master' into feature/item-table-columns
icheat2win Oct 24, 2026
4f6d679
Merge pull request #1283 from icheat2win/feature/crafting-bonus-perce…
sven-n Oct 24, 2026
5970887
Merge pull request #1276 from MUnique/feat/1257-mcp-operations
sven-n Oct 24, 2026
6c9da12
Merge branch 'MUnique:master' into feature/item-table-columns
icheat2win Oct 24, 2026
ababd56
refactor(admin): use DisplayAttribute.AutoGenerateField for item tabl…
claude Oct 24, 2026
abcd453
feat(discord): hosted guild channels for linked guild masters, with c…
claude Oct 24, 2026
0201b2f
style(discord): resolve the Codacy findings of the hosted guild channels
claude Oct 24, 2026
d2b9025
feat(admin): add mini game leaderboards
claude Oct 24, 2026
ecb428b
fix(admin): resolve Codacy findings of the leaderboards page
claude Oct 24, 2026
2aabb69
fix(discord): hosted guild channels stay private and don't replace ot…
claude Oct 24, 2026
c8c684e
refactor(admin): move the mini game leaderboards into the operations …
claude Oct 24, 2026
053ce15
feat(items): add item stat profiles as configuration data
Mosch0512 Oct 24, 2026
6fa6e17
test(items): the update test checks that a changed profile keeps its …
Mosch0512 Oct 24, 2026
4b5136d
fix(discord): replace the overwrites of hosted channels in one request
claude Oct 24, 2026
4baf5aa
feat(mcp): add confirmed configuration changes
sven-n Oct 24, 2026
0f69093
test(admin): add a PostgreSQL leaderboard test and resolve Codacy fin…
claude Oct 24, 2026
da8f620
fix(sockets): derive the socket option level from the seed sphere tier
claude Oct 21, 2026
9d9b40e
test(sockets): verify socket options from crafting to serialization
claude Oct 24, 2026
d65793e
docs(admin): mention the number columns of the configuration sub-lists
claude Oct 24, 2026
86e3723
docs(sockets): explain why the seed sphere numbers are constants
claude Oct 24, 2026
96c72fb
Merge pull request #1277 from icheat2win/fix/seed-sphere-socket-level
sven-n Oct 24, 2026
7d3ecbd
fix(mcp): address configuration review findings
sven-n Oct 24, 2026
f2137d1
fix(items): profile names are unique within a configuration
Mosch0512 Oct 25, 2026
dc94db6
fix(items): the summary of a requirement formula shows the level requ…
Mosch0512 Oct 25, 2026
7e39a52
test(items): pin the numbers of the built-in profiles which compute d…
Mosch0512 Oct 25, 2026
51e393f
refactor(items): the rule which profile an item gets is in the game l…
Mosch0512 Oct 25, 2026
ce3ff0b
refactor(items): find the level bonus table of a profile by its resou…
Mosch0512 Oct 25, 2026
a3d9286
refactor(items): the drop level bonuses of a new configuration come f…
Mosch0512 Oct 25, 2026
590f8f4
test(items): the profile tests which only read the data share one con…
Mosch0512 Oct 25, 2026
34727e6
Merge remote-tracking branch 'fork/feat/item-formulas-data' into feat…
Mosch0512 Oct 25, 2026
43a37ba
Merge branch 'master' into feature/minigame-leaderboard
icheat2win Oct 25, 2026
e1d6765
Merge branch 'master' into feature/item-table-columns
icheat2win Oct 25, 2026
7a80eee
test(sockets): don't shadow the crafting helper in the test handlers
claude Oct 25, 2026
0afa6bd
test(admin): dispose the database recreation without an empty block
claude Oct 25, 2026
0e555f1
Merge pull request #1288 from Mosch0512/feat/item-formulas-data
sven-n Oct 25, 2026
d03e4d8
Merge branch 'master' into feature/minigame-leaderboard
icheat2win Oct 25, 2026
26b9d23
fix(mcp): guard editors against invalidated contexts
sven-n Oct 25, 2026
a00e4a5
fix(sockets): allow every option of a seed sphere as its item level
claude Oct 25, 2026
7b1e775
fix(admin): preserve editor dispatcher across async waits
sven-n Oct 25, 2026
bc9433f
Merge pull request #1291 from icheat2win/test/seed-sphere-helper-name
sven-n Oct 25, 2026
2aa2c9d
Merge pull request #1287 from MUnique/claude/sweet-cray-w8crms
sven-n Oct 25, 2026
b308f6e
Merge branch 'master' into claude/sweet-hamilton-v6sy9a
claude Oct 25, 2026
4fcfb29
fix(admin): resolve resource conflicts with master
sven-n Oct 25, 2026
dc103c7
Merge pull request #1289 from MUnique/feat/1257-mcp-configuration
sven-n Oct 25, 2026
e76cc13
Merge branch 'master' into claude/sweet-hamilton-v6sy9a
claude Oct 25, 2026
d5b0096
fix(admin): reject replayed authenticator codes across time steps
claude Oct 25, 2026
51b1512
refactor(admin): share the content activation through AdminPanel.Oper…
claude Oct 25, 2026
6dee313
fix(crafting): localize the name of the crafting bonus update
claude Oct 25, 2026
6fb02a0
style: address the Codacy findings of the content activation
claude Oct 25, 2026
3d51bd1
Merge branch 'master' into fix/seed-sphere-maximum-item-level
icheat2win Oct 25, 2026
4482433
refactor(items): the profile names are static read-only properties
Mosch0512 Oct 25, 2026
1bc8805
refactor(items): name the 0.95d update of the item stat profiles in P…
Mosch0512 Oct 25, 2026
4788803
fix(items): profiles get the level bonus tables which their items use
Mosch0512 Oct 25, 2026
88f4829
test(items): a PostgreSQL round trip of the migration, the update and…
Mosch0512 Oct 25, 2026
492b065
test(items): the settings provider of the PostgreSQL test honors the …
Mosch0512 Oct 25, 2026
a8e4c34
style: format the version letter with the invariant culture
claude Oct 25, 2026
d49f27f
fix(game): keep inactive content out of mini games, creation and resp…
claude Oct 25, 2026
fec84ed
Merge branch 'master' into feature/minigame-leaderboard
sven-n Oct 25, 2026
be35f8a
fix(game): keep inactive content out of events, rewards and special w…
claude Oct 25, 2026
68fef2b
Merge pull request #1048 from MUnique/claude/sweet-hamilton-v6sy9a
sven-n Oct 25, 2026
4cd7ff8
fix(items): items with another level bonus table get a variant of the…
Mosch0512 Oct 25, 2026
0d04d77
Merge pull request #1285 from icheat2win/feature/minigame-leaderboard
sven-n Oct 25, 2026
c38d98d
Merge pull request #1284 from icheat2win/feature/item-table-columns
sven-n Oct 25, 2026
b22a696
Merge branch 'master' into fix/seed-sphere-maximum-item-level
sven-n Oct 25, 2026
26ed83b
Merge pull request #1294 from icheat2win/fix/seed-sphere-maximum-item…
sven-n Oct 25, 2026
710106d
Merge remote-tracking branch 'origin/master' into feat/item-formulas-…
Mosch0512 Oct 25, 2026
53bd2d2
fix(admin): consume authenticator time steps atomically
claude Oct 25, 2026
69fd746
refactor(items): the built-in profiles and the profile rule are part …
Mosch0512 Oct 25, 2026
438e707
style(admin): resolve the Codacy findings of the atomic TOTP step
claude Oct 25, 2026
4ac3659
test(mcp): count the mini game leaderboard among the read tools
claude Oct 25, 2026
5f2766c
Merge pull request #1292 from MUnique/claude/focused-meitner-k9hxlu
sven-n Oct 25, 2026
732f1e7
Merge remote-tracking branch 'origin/master' into claude/openmu-issue…
claude Oct 25, 2026
1cdb49b
fix(items): don't start a game server without item price definitions
claude Oct 25, 2026
c6e071e
fix(items): reject item price formula results which aren't valid prices
claude Oct 25, 2026
d70ad4b
feat(items): translatable captions for the item price definitions
claude Oct 25, 2026
b790ac9
test(items): price the stackable item of the buy test by its value
claude Oct 25, 2026
38b34d4
test(items): compare the item prices of a PostgreSQL database
claude Oct 25, 2026
2f02c3e
docs(items): update the price rules concept to the implementation
claude Oct 25, 2026
8e80fb8
refactor(items): the terms and requirement formulas of a profile are …
Mosch0512 Oct 25, 2026
4199843
Merge remote-tracking branch 'origin/master' into feat/item-formulas-…
Mosch0512 Oct 25, 2026
4bc248f
fix(items): an item with several own tables gets one variant which na…
Mosch0512 Oct 25, 2026
15796c8
fix(drops): never select socket items for excellent drops
openmubr Oct 25, 2026
53d6361
Merge branch 'master' of https://github.com/MUnique/OpenMU into fix/c…
claude Oct 25, 2026
732358c
test(mcp): count the mini game leaderboard among the read tools
claude Oct 25, 2026
48e7dd1
fix(updates): show the names of the crafting bonus and seed sphere up…
claude Oct 25, 2026
1463943
test(drops): verify excellent drops without sockets on every path
openmubr Oct 25, 2026
ab96ef3
Merge pull request #1299 from icheat2win/test/mcp-read-tool-count
sven-n Oct 25, 2026
e399916
Merge pull request #1298 from openmubr/fix/excellent-drop-without-soc…
sven-n Oct 25, 2026
6cc9a16
fix(items): prevent overflows of item prices
claude Oct 25, 2026
bb9a5ea
Merge branch 'master' into fix/crafting-bonus-update-localization
icheat2win Oct 25, 2026
9bd56ca
Merge pull request #1293 from icheat2win/fix/crafting-bonus-update-lo…
sven-n Oct 25, 2026
8365a70
Merge pull request #1064 from MUnique/claude/openmu-issue-75-concept-…
sven-n Oct 25, 2026
f168a21
Merge remote-tracking branch 'origin/master' into feat/item-formulas-…
Mosch0512 Oct 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 2 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,5 @@ Don't perform large retroactive cleanups of existing code to fit the rules unles
the user explicitly asks for it. Apply the rules going forward; pre-existing code
can be refactored opportunistically when you're already touching it.

Some parts of the codebase knowingly violate the rules and say so in a comment
(for example `ItemPriceCalculator`). Leave them alone unless fixing them is the
task.
Some parts of the codebase knowingly violate the rules and say so in a comment.
Leave them alone unless fixing them is the task.
2 changes: 1 addition & 1 deletion deploy/all-in-one/docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
dockerfile: Startup/Dockerfile
restart: "no"
ports:
- "8081:8080"
- "127.0.0.1:8081:8080"

database:
ports:
Expand Down
2 changes: 1 addition & 1 deletion deploy/all-in-one/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
image: munique/openmu
container_name: openmu-startup
ports:
- "8080"
- "127.0.0.1::8080"
- "45901:45901"
- "45902:45902"
- "45903:45903"
Expand Down
4 changes: 4 additions & 0 deletions deploy/all-in-one/nginx/nginx.prod443.conf
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ http {
}

location / {
# Defining headers here replaces the server-level header configuration.
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://openmu-startup:8080;
}
}
Expand Down
2 changes: 1 addition & 1 deletion deploy/distributed/docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ services:
environment:
ASPNETCORE_ENVIRONMENT: Development
ports:
- "88:8080"
- "127.0.0.1:88:8080"
2 changes: 1 addition & 1 deletion deploy/distributed/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ services:
database:
condition: service_healthy
ports:
- "8080"
- "127.0.0.1::8080"
environment:
DAPR_HTTP_ENDPOINT: http://adminPanel-dapr:3500
DAPR_GRPC_ENDPOINT: http://adminPanel-dapr:50001
Expand Down
4 changes: 4 additions & 0 deletions deploy/distributed/nginx.prod443.conf
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ http {
}

location ~ (/admin)(.*) {
# Defining headers here replaces the server-level header configuration.
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://adminPanel:8080/admin$2;
# The login cookie has to be sent along with the requests of the other applications, like Grafana, too.
proxy_cookie_path ~^/admin /;
Expand Down
52 changes: 48 additions & 4 deletions docs-website/docs/admin-panel/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,16 @@ application's configuration yet. **Delete** removes it for good.
### What a key may do

A key has the same [roles](#roles) as a user, and defaults to **Viewer**. A key
can also get the role **Cash shop coins only**, which allows nothing but the cash
can also get the role **Cash shop coins only**, which allows nothing but the
cash
shop endpoints — that's the right one for a payment provider. Administrators
have this role implicitly.

| Endpoint | Needs |
|---|---|
| `GET /api/status` | Viewer |
| `GET /api/is-online/{account}` | Viewer |
| `GET /api/send/{server}?msg=` | Operator |
| `POST /api/send/{server}?msg=` | Operator |
| `POST /api/accounts` | Operator |
| `GET /api/accounts/{account}/cash-shop` | Cash shop |
| `POST /api/accounts/{account}/cash-shop/grants` | Cash shop |
Expand Down Expand Up @@ -258,10 +259,12 @@ grant the coins twice. The answer is:

The game server applies the grant to the balance the next time the player opens
the cash shop, even when the player is online at that moment.
`GET /api/accounts/{account}/cash-shop` returns the saved balances and the latest
`GET /api/accounts/{account}/cash-shop` returns the saved balances and the
latest
grants, where `appliedAt` is empty for the pending ones.

Like the panel itself, the API is open as long as [no user exists at all](#the-first-user).
Like the panel itself, the API is open as long as [no user exists at
all](#the-first-user).

## Keeping the sessions alive across restarts

Expand All @@ -287,3 +290,44 @@ The location can be changed with `AdminPanel:Auth:DataProtectionKeyPath`.
through a VPN or an SSH tunnel instead.
* Remember that admin panel access means full access to your players' account
data.

## AI agents through MCP

API keys with the Viewer role can also access the optional read-only
[MCP endpoint](mcp.md). It is disabled by default and accepts API keys only.

### Phase two MCP and API upgrade notes

The panel still permits anonymous initial setup until the first admin user
exists or a bootstrap user is configured. Setup operations are attributed to
`setup`; when admin audit storage is unavailable they use sanitized log-only
auditing.

If the host restarts while the admin database is unreachable, it cannot
distinguish a previous installation from initial setup and may allow anonymous
setup actions with log-only auditing. Configure a bootstrap user with
`OPENMU_ADMIN_USER` and `OPENMU_ADMIN_PASSWORD` to prevent that fallback.

Explicit `-demo` mode also uses log-only panel auditing. MCP and API
writes always require authentication and durable admin audit storage.

Outside demo mode and initial setup, panel operations including **Stop** require
the admin audit database. An outage blocks the action and displays an error. Use
the host's service manager or orchestrator for emergency shutdown during an
audit outage.

External applications must update announcement requests from GET to
`POST /api/send/{id}?msg=...`. The identifier is now the actual game server ID,
rather than its position in a list. Operational APIs no longer allow anonymous
requests during initial setup. See [MCP](mcp.md#phase-two-upgrade-notes) for the
operational HTTP error statuses and uncertain-outcome handling.

### Restrict MCP tools per key

The optional **Allowed MCP tools** field accepts comma-separated exact names
or area wildcards, such as `accounts_search,players_*,server_overview`.
Empty keeps the key's existing role-based access. The allowlist further limits
MCP discovery and direct calls; it never grants a tool beyond the key's role
and does not alter REST API permissions. See
[MCP configuration changes](mcp.md#configuration-and-offline-character-changes)
for the preview/apply workflow.
27 changes: 27 additions & 0 deletions docs-website/docs/admin-panel/configuration-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,33 @@ The updates take effect after a restart of the server process. Until then, the
running server still works with the configuration it loaded at startup.
:::

Some updates are required before the game servers can run. For example, a game
server doesn't start without the item price definitions, which the update *Add
item price definitions* adds to databases from before they existed. Otherwise
it would sell special items like jewels at the price of equipment. The game
server logs the reason and stays stopped, while the admin panel keeps running,
so you can apply the update here. Then use **Reload configuration and restart
all game servers** on the [Servers page](servers.md), or restart the server
process.

## On a new database

A new database already contains the changes of OpenMU's own updates, because the
initialization creates the current configuration. It therefore marks them as
applied, and this page starts empty.

Plugins can bring configuration updates too, for example one which adds the
plugin's own item. Their changes are not part of OpenMU's initialization, so such
an update declares `RunsOnNewDatabase`, and a new database applies it right away,
after the updates it depends on. On an existing database it is listed here like
any other update.

An optional update of that kind is not applied on a new database: it is listed
here as pending, as on an existing database, so you decide whether to apply it.
The same goes for the updates which would be applied and depend on it. Their
dependencies are checked when you apply them, so an optional plugin update with a
missing dependency doesn't stop the creation of a new database.

## Preconditions

If the database is not installed yet, or a schema update is pending, this page
Expand Down
99 changes: 97 additions & 2 deletions docs-website/docs/admin-panel/game-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,31 @@ Item definitions with their requirements, level tables, possible options, socket
and the classes which may equip them. Items use a dedicated editor with a
graphical representation instead of the plain generic form.

### Item prices

The price of an item is used by the NPC merchants (buying, selling, repairing)
and by the success rate of some crafting recipes. By default, an item gets the
price of usual equipment: a base price from its drop level, increased by its
skill and options. Items with a different price reference a *price definition*
(the `PriceDefinition` of the item). The price definitions are in the full
configuration tree (`ItemPriceDefinitions` of the game configuration), and one
can be shared by several items.

| Setting | Meaning |
|---|---|
| Base price formula | The price of one unit, for example `9000000`, or `(level + 1) * 200000`. Without a formula, the equipment price is used. |
| Price per level | Fixed prices for specific item levels. They take precedence over the formula. |
| Quantity scaling | `PerPiece` multiplies the price by the number of pieces (potions), `ByFillRatio` by the fill ratio (arrows). |
| Modifiers | Which options increase the price, like for equipment: skill, luck, option, wing option, excellent. |
| Selling price rounding | `Tens` rounds the selling price to tens and ignores the durability, like for potions. |
| Crafting reference price | A different price for the success rate of crafting (e.g. the jewels). |

The formula can use the variables `level`, `durability`, `maxDurability`,
`value` (the value of the item), `dropLevel`, `optionLevel`, `optionCount`,
`healthRecoveryOptionLevel` and `automaticPrice` (the equipment price). The game
client calculates the prices it shows by itself, so changed prices only show up
correctly in clients which calculate them the same way.

## Item options, option types and item sets

The game configuration menu provides separate entries for these lists:
Expand Down Expand Up @@ -174,10 +199,77 @@ Route `edit-config-grid/…JewelMix/`

The jewel stacking (mix/unmix) definitions.

## Content activation

Route `content-activation`

Maps, character classes, monsters, items and mini games can be deactivated
without deleting them from the configuration. This is how a server can be
restricted to the content of a certain season: deactivate everything which was
introduced later, and activate it again when you want to offer it.

Each entry knows in which version of the original game it was introduced, from
the early version numbers before Season 1 (like 0.34, 0.95k or 0.99G+, as listed
by the [MU Online history](https://github.com/Khdoop/mu-online-history)) up to
Season 6 Episode 3. Content of patches without a known version number counts
as introduced in the next version with a known number.
Select a version at the top and click **Restrict to game version** to activate
all content up to this version and to deactivate everything which was
introduced later — for example *Season 2* for a server without Summoners,
Raklion, socket items and the other later content. Entries with an unknown
version are left unchanged, so check them afterwards with the version column.
The page shows how many entries will be activated and deactivated, and changes
them after you confirm.

:::note[The versions are best effort]
The versions were compiled from the original patch notes and OpenMU's data of
the older versions. Some entries, like a few event items, are *Unknown*. You can
correct the version of an entry with *Introduced In* on its edit page.
:::

Pick the kind of content in the second row. The list can be narrowed down
by its active state and by a search text (which also matches the version),
and **Activate all shown** / **Deactivate all shown** change all entries of
the narrowed list at once — for example, search for `Kanturu` and deactivate
all shown entries. The changes are only stored after **Save changes** and the
confirmation; **Discard changes** drops them. Save or discard them before
restricting to a game version.

Both actions are recorded in the
[audit history](mcp.md#operational-safety-and-audit-history), and they are
the same operations which agents use through the
[MCP tools](mcp.md#configuration-and-offline-character-changes)
`content_restrict_to_version` and `content_set_active`. Like other configuration
changes, they require the *Administrator* role.

What an inactive entry means in the game:

| Content | Effect when inactive |
|---|---|
| Map | It can't be entered by warps or gates, no instance of it is created, and invasions skip it. A character which logs in on an inactive map is moved to the safezone map of it, or to the home map of its class. |
| Character class | No new character of this class can be created, and its creation isn't unlocked on the character selection screen. Quests which would evolve a character into it aren't offered and can't be completed. Existing characters stay playable. |
| Monster / NPC | It isn't spawned on the maps, also not by invasions. Monsters which are already spawned remain until the game server is restarted. |
| Item | Monsters and item boxes don't drop it, and merchants don't offer it. Existing items stay usable. |
| Mini game | It can't be entered, and its periodic start doesn't open it. |

Entries are active by default, also after updating an existing installation;
the configuration update *Set the game versions of the content* adds the versions
to an existing installation. The settings are also available as *Is Active* and
*Introduced In* on the edit page of each entry.

:::tip[Deactivate the plugins, too]
Invasions and the periodic starts of the mini games skip inactive content and
don't announce an event when nothing of it is active. Other features are
implemented as plugins without such content, for example the chat commands or
the custom gameplay plugins. Deactivate them on the [Plugins](plugins.md) page
if they don't fit the season of your server.
:::

## Plugins, chat commands, map editor

The lower part of the drop-down leads to [Plugins](plugins.md),
[Chat commands](chat-commands.md) and the [Map editor](map-editor.md).
The lower part of the drop-down leads to [Content activation](#content-activation),
[Plugins](plugins.md), [Chat commands](chat-commands.md) and the
[Map editor](map-editor.md).

## Full configuration

Expand Down Expand Up @@ -210,6 +302,9 @@ actions per row:
A form with one input per property of the object, grouped by category. Referenced
objects are shown as drop-downs, collections as editable sub-lists which lead
deeper into the tree. The breadcrumb at the top is how you find your way back.
The sub-lists of items, monsters, skills and maps additionally show their number
(and the group of an item) next to the name, so that entries with similar
names are easy to tell apart.

Some types have a specialized editor instead of (or in addition to) the generic
form — items, item storages and maps.
Expand Down
Loading
Loading