Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dd8a78c
fix(server-list): a server of a group the list does not have no longe…
Mosch0512 Oct 22, 2026
99541e6
feat(server-list): the login screen's server groups come from ServerL…
Mosch0512 Oct 22, 2026
de59075
chore(server-list): remove ServerList.bmd and its one-time comparison
Mosch0512 Oct 22, 2026
d3d360d
feat(editor): a Server List window for the login screen's server groups
Mosch0512 Oct 22, 2026
7a07304
docs: the server list file and its editor window
Mosch0512 Oct 22, 2026
959096b
fix(editor): the Server List window's undo keys only while the keyboa…
Mosch0512 Oct 22, 2026
be743f2
fix(editor): Save stays off after the server list was read with errors
Mosch0512 Oct 22, 2026
13f2a43
fix(editor): the server select window lets go of a group the editor r…
Mosch0512 Oct 22, 2026
f86a535
fix(editor): the login screen keeps its open group when the Server Li…
Mosch0512 Oct 22, 2026
ff0d39b
fix(server-list): name and description limits count UTF-16 units
Mosch0512 Oct 22, 2026
0a3a37f
docs(server-list): a test server group stays at its place in the list
Mosch0512 Oct 22, 2026
e2be005
fix(editor): a "##" in a group name shows in the Server List window
Mosch0512 Oct 22, 2026
7f9d274
test(server-list): the login screen's groups as CServerListManager bu…
Mosch0512 Oct 22, 2026
5dbfd65
refactor(server-list): one function for the channel suffixes of the l…
Mosch0512 Oct 22, 2026
e8638af
refactor(server-list): the group name is copied with wcsncpy_s
Mosch0512 Oct 22, 2026
50d4b48
perf(editor): the Server List window maps the connect server's channe…
Mosch0512 Oct 22, 2026
f8fe9cd
feat(editor): the editor bar's Undo and Redo also undo the Server Lis…
Mosch0512 Oct 22, 2026
c4286d7
docs(server-list): Save stays off after the file was read with errors
Mosch0512 Oct 22, 2026
aaaeb87
refactor(editor): the Server List window's long functions in smaller …
Mosch0512 Oct 22, 2026
d8f4da0
refactor(server-list): the group header is ServerListGroup.h
Mosch0512 Oct 22, 2026
d60a5cf
style(server-list): clang-format ReadText's parameters
Mosch0512 Oct 22, 2026
f8b374e
fix(editor): a closed tool leaves the bar's Undo and Redo to the item…
Mosch0512 Oct 22, 2026
42de110
feat(editor): the bar's Undo and Redo tooltips name the Server List step
Mosch0512 Oct 22, 2026
f9f5b94
docs(editor): the bar's Undo and Redo act on the tool used last
Mosch0512 Oct 22, 2026
f96eca0
style(ui): SyncRmlModel's comment sits above SyncRmlModel again
Mosch0512 Oct 22, 2026
487c7cd
docs(server-list): wrap the comparison with the original client
Mosch0512 Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ src/shaders/compiled/*.msl text eol=lf whitespace=-blank-at-eof
src/bin/Data/Items/**/*.json text eol=lf
# The effect catalogue is checked against the format its writer produces (LF).
src/bin/Data/Effects/*.json text eol=lf
# The server list is written by the editor's Server List window with LF.
src/bin/Data/Local/ServerList.json text eol=lf
# The creation baseline of the effect recorder is compared line by line on every platform.
tests/effects/baseline/*.txt text eol=lf

Expand Down
30 changes: 17 additions & 13 deletions docs/dev-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,23 @@ the game window; **Close Editor** is on the right of the editor window's menu
bar.

The editor opens in a window of its own, beside the game window where the
screen has room (else over its right side), and stays in front of the game.
Its **Windows** menu opens the tool windows: Item, Skill, Dev and Map Editor,
the Effect Browser and the console. They open as tabs docked in the editor
window, the console along the bottom. Drag a tab out to float a tool window
anywhere, over the game window too, or onto another window to dock it there;
**Windows > Reset Layout** docks them all back. The layout and the windows'
places are kept between sessions (`imgui.ini` in the game folder).

The editor window's bar has the **Windows** menu, **Undo** and **Redo** of the
item tools, the UI scale and the language. A window of tool windows floating
outside the editor window has the same bar once, on the tab shown at its top
left when several are docked in it, so it can be worked with from another
monitor; its **Windows > Fullscreen** switches that window to full screen.
screen has room (else over its right side), and stays in front of the game. Its
**Windows** menu opens the tool windows: Item, Server List
([server-list.md](server-list.md)), Skill, Dev and Map Editor, the Effect
Browser and the console. They open as tabs docked in the editor window, the
console along the bottom. Drag a tab out to float a tool window anywhere, over
the game window too, or onto another window to dock it there; **Windows > Reset
Layout** docks them all back. The layout and the windows' places are kept
between sessions (`imgui.ini` in the game folder).

The editor window's bar has the **Windows** menu, **Undo** and **Redo**, the UI
scale and the language. Undo and Redo act on the tool used last: after a click
into the Server List window on its changes, after a click into an item tool on
item edits; while the Server List window is closed, on item edits. A window of
tool windows floating outside the editor window has the same bar once, on the
tab shown at its top left when several are docked in it, so it can be worked
with from another monitor; its **Windows > Fullscreen** switches that window to
full screen.

The editor window, and a tool window floating outside the game window, are
ordinary windows of the system, with its title bar, buttons and window
Expand Down
110 changes: 110 additions & 0 deletions docs/server-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Server List

The server groups on the login screen (Valhalla, Helheim, ...) and the names
and colors of their channels come from `Data/Local/ServerList.json`. It
replaced the encrypted `Data/Local/ServerList.bmd` of the original client. The
game reads it at start; with errors in it the game shows them and stops, as it
does for broken item data. All problems are also written to the log.

## How the login screen uses it

The connect server sends the IDs of its game servers and their load. The
client splits each ID into a group and a channel:

- group = server ID / 20
- channel = server ID % 20 + 1

So servers 0 to 19 are the channels 1 to 20 of group 0, servers 20 to 39 those
of group 1, and so on. On OpenMU the ID is the game server's *Server ID* in the
admin panel; to put a server into a second group, give it an ID from 20 to 39.

- **Groups:** one button per group, in the order of the list. A server whose
group is not in the list is not shown at all.
- **Test server:** of the groups marked as test server, the login screen
shows only the first, at its place in the list; the others are hidden.
- **Channels:** each channel is shown as `<group name>-<channel>`, followed by
its type:

| Type | Shown as | Button |
|-----------|------------------------|---------|
| `normal` | `Valhalla-1` | gray |
| `nonPvp` | `Valhalla-1(Non-PVP)` | default |
| `goldPvp` | `Valhalla-1(Gold PVP)` | orange |
| `gold` | `Valhalla-1(Gold)` | orange |

The type only names and colors the channel; whether PvP is on is decided by
the server.
- **PvP notice:** the warning about crowded PvP servers is shown for a group
that has no `nonPvp` and no `gold` channel.
- **Description:** shown below the channels while the group is selected.

## The file

```json
{
"formatVersion": 1,
"groups": [
{
"id": 0,
"name": "Valhalla",
"channels": {"1": "gold", "5": "goldPvp", "6": "nonPvp"}
},
{
"id": 1,
"name": "Helheim",
"description": "PvP everywhere"
},
{
"id": 9,
"name": "Test",
"testServer": true
}
]
}
```

| Field | Meaning |
|---------------|--------------------------------------------------------------------------|
| `id` | The group: server ID / 20, from 0 to 3276. Each group once. |
| `name` | The button text and the start of each channel name; up to 32 characters. |
| `description` | Optional; up to 254 characters. |
| `testServer` | Optional; `true` marks a test server group: only the first is shown. |
| `channels` | Optional; the type of a channel by its number (1 to 20). Channels not listed are `normal`. |

A name or description that is too long is cut (a warning in the log). Most
emoji count as two characters, as the client stores them on Windows.

## Editing in MU Editor

**Windows → Server List** shows the groups in their order on the left and the
selected group on the right: its ID (with the server IDs it covers), name,
description, the test server mark, and a type for each of the 20 channels with
the name the login screen gives it.

- The login screen shows each change right away, while the window is open.
- **Add**, **Remove**, **Move up** and **Move down** change the list.
- When the connect server sent servers of groups the list does not have, the
window lists them with their server IDs; **Add** there adds a group with that
ID. The channel table shows which channels the connect server sent, with
their load.
- **Save** writes `Data/Local/ServerList.json` in the folder the game runs
from. It refuses a list with errors (a group without a name, an ID used
twice) and lists them. When the file itself had errors as it was read
(changed by hand while the game ran), the window has only the groups that
could be read: Save stays off then, so it cannot remove the others, until
the file is fixed and **Revert** reads it again.
- **Revert** reads the file again.
- **Undo** and **Redo** in the editor bar (or Ctrl+Z and Ctrl+Y in the window)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking. This describes the shared Undo and Redo, but docs/dev-editor.md:47 (outside the diff) still says the editor window's bar has "Undo and Redo of the item tools", and item-data.md:823 points there for the bar's Undo. Since f8fe9cd they act on the tool used last, the item tools or the Server List window. One sentence there, like the last one of this item, would match. Rule 11 of docs/CODING_RULES.md: "New, changed, or removed systems get a docs update".

work through the changes of the session. The bar's buttons act on the tool
used last: after a click into the Server List window they undo server list
changes, after a click into an item tool item edits.

## Compared to the original client

`ServerList.bmd` held the same groups, encrypted, with channel types for the
first 15 channels only and a left, right or center position for each button.
The original screen drew the center one, a test server, as a button of its own;
the login screen now lists all groups in one column in the list's order, so
only "test server" is kept, for the rule that only the first is shown. The
original loader read each group's description but never kept it, so the login
screen showed none; the JSON description is shown.
114 changes: 114 additions & 0 deletions src/Localization/Editor.de.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1852,4 +1852,118 @@
<data name="Apply or revert the changes first." xml:space="preserve">
<value>Erst die Änderungen anwenden oder zurücksetzen.</value>
</data>
<data name="Server List" xml:space="preserve">
<value>Serverliste</value>
</data>
<data name="Save" xml:space="preserve">
<value>Speichern</value>
</data>
<data name="Reads {0} again; unsaved changes are lost." xml:space="preserve">
<value>Liest {0} neu ein; ungespeicherte Änderungen gehen verloren.</value>
</data>
<data name="Unsaved changes" xml:space="preserve">
<value>Ungespeicherte Änderungen</value>
</data>
<data name="Saved to {0}" xml:space="preserve">
<value>In {0} gespeichert</value>
</data>
<data name="Not saved, see the problems below." xml:space="preserve">
<value>Nicht gespeichert, siehe die Probleme unten.</value>
</data>
<data name="Problems in {0}:" xml:space="preserve">
<value>Probleme in {0}:</value>
</data>
<data name="New Group" xml:space="preserve">
<value>Neue Gruppe</value>
</data>
<data name="Group ID" xml:space="preserve">
<value>Gruppen-ID</value>
</data>
<data name="Servers {0} to {1}" xml:space="preserve">
<value>Server {0} bis {1}</value>
</data>
<data name="Another group has the ID {0}." xml:space="preserve">
<value>Eine andere Gruppe hat die ID {0}.</value>
</data>
<data name="A group needs a name." xml:space="preserve">
<value>Eine Gruppe braucht einen Namen.</value>
</data>
<data name="Description" xml:space="preserve">
<value>Beschreibung</value>
</data>
<data name="Description note" xml:space="preserve">
<value>Steht unter den Kanälen, solange die Gruppe gewählt ist.</value>
</data>
<data name="Test server" xml:space="preserve">
<value>Testserver</value>
</data>
<data name="Test server note" xml:space="preserve">
<value>Der Anmeldebildschirm zeigt nur die erste Testserver-Gruppe, an ihrem Platz in der Liste.</value>
</data>
<data name="Channel" xml:space="preserve">
<value>Kanal</value>
</data>
<data name="Type" xml:space="preserve">
<value>Art</value>
</data>
<data name="On the login screen" xml:space="preserve">
<value>Auf dem Anmeldebildschirm</value>
</data>
<data name="Connect server" xml:space="preserve">
<value>Connect-Server</value>
</data>
<data name="Normal" xml:space="preserve">
<value>Normal</value>
</data>
<data name="Non-PvP" xml:space="preserve">
<value>Kein PvP</value>
</data>
<data name="Gold PvP" xml:space="preserve">
<value>Gold-PvP</value>
</data>
<data name="Gold" xml:space="preserve">
<value>Gold</value>
</data>
<data name="Sent, {0}% load" xml:space="preserve">
<value>Gemeldet, {0} % Last</value>
</data>
<data name="Groups the list does not have" xml:space="preserve">
<value>Der Connect-Server meldet Server von Gruppen, die die Liste nicht hat; der Anmeldebildschirm zeigt sie nicht:</value>
</data>
<data name="Group {0}: servers {1}" xml:space="preserve">
<value>Gruppe {0}: Server {1}</value>
</data>
<data name="Pick a group in the list." xml:space="preserve">
<value>Wählen Sie eine Gruppe in der Liste.</value>
</data>
<data name="Server list order note" xml:space="preserve">
<value>Die Reihenfolge der Liste ist die der Schaltflächen auf dem Anmeldebildschirm, der jede Änderung sofort zeigt. Speichern schreibt {0}.</value>
</data>
<data name="Save off after read errors" xml:space="preserve">
<value>Die Datei hatte beim Lesen Fehler, daher enthält die Liste nur die Gruppen, die gelesen werden konnten. Speichern bleibt aus, bis die Datei korrigiert ist und Zurücksetzen sie neu einliest; es würde die anderen Gruppen aus der Datei entfernen.</value>
</data>
<data name="Step add" xml:space="preserve">
<value>{0} hinzufügen</value>
</data>
<data name="Step remove" xml:space="preserve">
<value>{0} entfernen</value>
</data>
<data name="Step move" xml:space="preserve">
<value>{0} verschieben</value>
</data>
<data name="Step name" xml:space="preserve">
<value>{0}: Name</value>
</data>
<data name="Step ID" xml:space="preserve">
<value>{0}: ID</value>
</data>
<data name="Step description" xml:space="preserve">
<value>{0}: Beschreibung</value>
</data>
<data name="Step test server" xml:space="preserve">
<value>{0}: Testserver</value>
</data>
<data name="Step channel" xml:space="preserve">
<value>{0}: Kanal {1}</value>
</data>
</root>
114 changes: 114 additions & 0 deletions src/Localization/Editor.en.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1873,4 +1873,118 @@
<data name="Apply or revert the changes first." xml:space="preserve">
<value>Apply or revert the changes first.</value>
</data>
<data name="Server List" xml:space="preserve">
<value>Server List</value>
</data>
<data name="Save" xml:space="preserve">
<value>Save</value>
</data>
<data name="Reads {0} again; unsaved changes are lost." xml:space="preserve">
<value>Reads {0} again; unsaved changes are lost.</value>
</data>
<data name="Unsaved changes" xml:space="preserve">
<value>Unsaved changes</value>
</data>
<data name="Saved to {0}" xml:space="preserve">
<value>Saved to {0}</value>
</data>
<data name="Not saved, see the problems below." xml:space="preserve">
<value>Not saved, see the problems below.</value>
</data>
<data name="Problems in {0}:" xml:space="preserve">
<value>Problems in {0}:</value>
</data>
<data name="New Group" xml:space="preserve">
<value>New Group</value>
</data>
<data name="Group ID" xml:space="preserve">
<value>Group ID</value>
</data>
<data name="Servers {0} to {1}" xml:space="preserve">
<value>Servers {0} to {1}</value>
</data>
<data name="Another group has the ID {0}." xml:space="preserve">
<value>Another group has the ID {0}.</value>
</data>
<data name="A group needs a name." xml:space="preserve">
<value>A group needs a name.</value>
</data>
<data name="Description" xml:space="preserve">
<value>Description</value>
</data>
<data name="Description note" xml:space="preserve">
<value>Shown below the channels while the group is selected.</value>
</data>
<data name="Test server" xml:space="preserve">
<value>Test server</value>
</data>
<data name="Test server note" xml:space="preserve">
<value>The login screen shows only the first test server group, at its place in the list.</value>
</data>
<data name="Channel" xml:space="preserve">
<value>Channel</value>
</data>
<data name="Type" xml:space="preserve">
<value>Type</value>
</data>
<data name="On the login screen" xml:space="preserve">
<value>On the login screen</value>
</data>
<data name="Connect server" xml:space="preserve">
<value>Connect server</value>
</data>
<data name="Normal" xml:space="preserve">
<value>Normal</value>
</data>
<data name="Non-PvP" xml:space="preserve">
<value>Non-PvP</value>
</data>
<data name="Gold PvP" xml:space="preserve">
<value>Gold PvP</value>
</data>
<data name="Gold" xml:space="preserve">
<value>Gold</value>
</data>
<data name="Sent, {0}% load" xml:space="preserve">
<value>Sent, {0}% load</value>
</data>
<data name="Groups the list does not have" xml:space="preserve">
<value>The connect server sent servers of groups the list does not have; the login screen does not show them:</value>
</data>
<data name="Group {0}: servers {1}" xml:space="preserve">
<value>Group {0}: servers {1}</value>
</data>
<data name="Pick a group in the list." xml:space="preserve">
<value>Pick a group in the list.</value>
</data>
<data name="Server list order note" xml:space="preserve">
<value>The order of the list is the order of the buttons on the login screen, which shows each change right away. Save writes {0}.</value>
</data>
<data name="Save off after read errors" xml:space="preserve">
<value>The file had errors when it was read, so the list has only the groups that could be read. Save is off until the file is fixed and Revert reads it again; it would remove the other groups from the file.</value>
</data>
<data name="Step add" xml:space="preserve">
<value>Add {0}</value>
</data>
<data name="Step remove" xml:space="preserve">
<value>Remove {0}</value>
</data>
<data name="Step move" xml:space="preserve">
<value>Move {0}</value>
</data>
<data name="Step name" xml:space="preserve">
<value>{0}: name</value>
</data>
<data name="Step ID" xml:space="preserve">
<value>{0}: ID</value>
</data>
<data name="Step description" xml:space="preserve">
<value>{0}: description</value>
</data>
<data name="Step test server" xml:space="preserve">
<value>{0}: test server</value>
</data>
<data name="Step channel" xml:space="preserve">
<value>{0}: channel {1}</value>
</data>
</root>
Loading
Loading