Skip to content

Server events, BaseManager and Skills refactor - #11

Merged
KoertLichtendonk merged 3 commits into
mainfrom
dev
Nov 5, 2026
Merged

KoertLichtendonk merged 3 commits into
mainfrom
dev

Conversation

@KoertLichtendonk

Copy link
Copy Markdown
Member

Merging this into main publishes a new OpenRP.Framework NuGet version.

Server events

  • [ServerEvent] handlers are matched by their ServerEventArgs parameter type instead of the method name, and are found automatically at startup. A new event only needs its args class and a PublishAsync call.
  • Invalid handlers (no or several args parameters, unregistered services) are logged at startup and ignored. async void handlers get a warning.
  • An error in a handler is logged with the real exception and the handler's name, and the other handlers still run.

BaseManager

  • Fixes deleted components coming back after their deletion was saved, and losing up to a minute of changes on shutdown (SaveNow in OnGameModeExit). Also fixes temporary entity ids being reused while still in use.
  • New CreateAndLoad and LoadById. A new character's inventory is available right away instead of after the next sync.
  • The external sync works for several servers on one database. Each cycle saves this server's changes first, then picks up inserts, updates and deletions made elsewhere. When two servers change the same row, the last save wins.
  • Saves are batched, with a per-row fallback. The cycle runs synchronously on the main thread.

Skills

  • New Skills feature: a CharacterSkills component loaded when a character is selected, and /skills with a details view. It's now a [ServerCommand], so it goes through the permission system.

Breaking changes for gamemodes

  • IServerEventAggregator.Subscribe, ServerEventAttribute.EventName and ServerEvents.EventParameterTypes are removed.
  • IInventoryService is removed. Use IInventoryManager.CreateInventory / LoadInventory.
  • BaseManager: ResetNewId is removed, and TComponent must implement IBaseDataComponent and IChangeable.
  • Character.GetCharacterModel() is no longer public. Use the Character getters instead.
  • IOpenCdnService gains Play(...); custom implementations need to add it.

Match [ServerEvent] handlers by their ServerEventArgs parameter type
instead of the method name, and find them automatically.

- ServerEventDispatcher registers every [ServerEvent] method of the
  registered IServerSystems at startup. A new event only needs its
  args class and a PublishAsync call.
- Invalid handlers (no or several args parameters, unregistered
  services) are logged at startup and ignored; async void handlers
  get a warning.
- Errors in a handler are logged with the real exception and the
  handler's name, and the other handlers still run.
- ServerEventAggregator resolves the dispatcher on first publish, so
  systems whose services publish events don't form a circular
  dependency.
- Remove the hand-written subscriptions, ServerEvents.EventParameterTypes,
  IServerEventAggregator.Subscribe and ServerEventAttribute.EventName.
Fix the persistence bugs and make the external sync work for several
servers sharing one database.

- Destroy a component once its deleted row is saved, instead of
  resetting its deleted flag (deleted items came back).
- Save on shutdown: InventorySystem calls SaveNow in OnGameModeExit.
- Never reset the temporary entity id counter, so ids still in use
  can't be handed out again.
- Add CreateAndLoad and LoadById. New characters' inventories are
  loaded right away, and InventoryService is replaced by
  IInventoryManager.CreateInventory/LoadInventory.
- Sync: save own changes first, pull inserts and updates with a
  high-water mark from the database timestamps, and remove components
  whose rows were deleted elsewhere. The last save wins.
- Save in batches, falling back to one row at a time on failure.
- The cycle runs synchronously on the main thread; generic constraints
  replace the runtime IChangeable/IBaseDataComponent checks.
Port Skills from the gamemode to the Framework and finish the
character refactor.

- Skills feature: CharacterSkills component loaded on
  OnCharacterSelected, SkillService, a /skills dialog with details and
  Back, and the existing 100 x level^2 XP formula. /skills is now a
  [ServerCommand], so it goes through the permission system.
- Character.GetCharacterModel() becomes the internal
  GetRawCharacterModel(), used only for saving.
- IOpenCdnService exposes the Play methods its implementation already
  had.
@KoertLichtendonk
KoertLichtendonk merged commit 8d26a9a into main Nov 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant