|
| 1 | +--- |
| 2 | +title: WukongMP SDK 0.3.0 released |
| 3 | +description: Server-side scripting, custom component sync, a Network view in the admin panel, and co-op fixes |
| 4 | +slug: wukongmp-sdk-030 |
| 5 | +authors: readym |
| 6 | +tags: [wukongmp, adminPanel] |
| 7 | +hide_table_of_contents: false |
| 8 | +--- |
| 9 | + |
| 10 | +Server-side scripting is here. A mod can now run its own code inside the relay server: register components on server entities, tick systems on the server loop, and answer requests from clients over RPC. This is the piece we said was coming and the co-op mod already runs on it. |
| 11 | + |
| 12 | +Custom components now sync both ways too, so a mod can put its own state on an entity and have the server and every client agree on it without writing any messaging code. |
| 13 | + |
| 14 | +This release also adds a Network view to the admin panel, which shows what the relay is actually sending, broken down per ECS component. Alongside that, three co-op fixes, including NPCs that could turn hostile and block quests. |
| 15 | + |
| 16 | +Update your server binaries to `0.3.0`. Client mods built on `0.2.4` need a rebuild and a few small code changes, see the [Migration guide](/releases/wukongmp-sdk-030#migration-guide). |
| 17 | + |
| 18 | +<!-- truncate --> |
| 19 | + |
| 20 | +## Server-side mods |
| 21 | + |
| 22 | +A server-side mod is a .NET class library that the relay server loads from its `server_mods/` directory, separate from the client-facing `mods/` folder. Drop the assembly in and the server picks it up on startup. |
| 23 | + |
| 24 | +What it can do: |
| 25 | + |
| 26 | +* **[Components on server entities](/wukong-mp/docs/Server-development/archetypes)**, local (server-only) or networked, attached to the built-in archetypes or to new ones your mod registers. |
| 27 | +* **[Systems](/wukong-mp/docs/Server-development/systems)** that tick on the server's update loop, for logic that has to run continuously rather than in response to a single client. |
| 28 | +* **[Server RPC](/wukong-mp/docs/Server-development/custom-rpc)**, a request and response channel between a client mod and the server, declared once as a contract shared by both halves. |
| 29 | + |
| 30 | +Start with [Getting started](/wukong-mp/docs/Server-development/getting-started), and read [Archetypes and components](/wukong-mp/docs/Server-development/archetypes) for what the built-in entities carry. The [co-op mod](https://github.com/readycodeio/WukongMP-co-op-mod) is a small worked example of all three: two systems, one RPC handler, and a shared contract project. |
| 31 | + |
| 32 | +The API reference now covers the server SDK as well, under `ReadyM.Relay.Server.Sdk` and `ReadyM.Wukong.Common`. |
| 33 | + |
| 34 | +## Custom data sync |
| 35 | + |
| 36 | +Networked components replicate both ways in `0.3.0`. Declare a `partial struct` with `[DeriveINetworkedComponent]` in a project both halves of your mod reference, register it on each side, attach it to an archetype, and the values keep themselves in sync. No messaging code, no manual serialization. |
| 37 | + |
| 38 | +```csharp title="The component, in the shared project" |
| 39 | +[DeriveINetworkedComponent] |
| 40 | +[StructLayout(LayoutKind.Auto)] |
| 41 | +public partial struct BountyComponent |
| 42 | +{ |
| 43 | + private int _kills; |
| 44 | + private float _multiplier; |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +The server mod registers it in `RegisterComponents` and attaches it in `Init`: |
| 49 | + |
| 50 | +```csharp |
| 51 | +registry.RegisterComponent<BountyComponent>(); |
| 52 | +// ... |
| 53 | +archetypeRegistry.ModifyArchetype(WukongArchetypes.GlobalPlayerArchetype, b => b.Add<BountyComponent>()); |
| 54 | +``` |
| 55 | + |
| 56 | +The client mod does the same from its `Initialize`, through `IComponentApi` and an `IArchetypeRegistration`: |
| 57 | + |
| 58 | +```csharp |
| 59 | +services.Resolve<IComponentApi>().RegisterComponent<BountyComponent>(); |
| 60 | +services.RegisterSingleton<IArchetypeRegistration, BountyRegistration>(); |
| 61 | +``` |
| 62 | + |
| 63 | +Both sides name the same archetype: `WukongArchetypes` on the server, `WukongApi.Archetypes` on the client. See [Custom components](/wukong-mp/docs/Development/APIs/custom-components) for the client side and [Registering components and archetypes](/wukong-mp/docs/Server-development/getting-started#registering-components-and-archetypes) for the server side. |
| 64 | + |
| 65 | +The one rule worth internalising: register the same components in the same order on both sides. Component IDs are positional and travel as a byte on the wire, so a mismatch misreads the stream rather than failing loudly. Keeping the definitions in the shared project and doing the registration in one place per side is enough to stay safe. |
| 66 | + |
| 67 | +If the client has no business seeing a value, skip all of this and use a [local component](/wukong-mp/docs/Server-development/getting-started#local-components) instead. Those never leave the server and cost nothing on the wire. |
| 68 | + |
| 69 | +## Network view in the admin panel |
| 70 | + |
| 71 | +The panel has a new **Network** tab, showing live relay traffic in one second windows: ingress and egress, connected peers, server tick timing, and protocol overhead. |
| 72 | + |
| 73 | +The part worth your attention as a mod author is the per-component breakdown. It attributes payload bytes to individual ECS components, with fan-out per component, so you can see what a component that replicates every tick actually costs before you ship it. The tick duration chart covers the same update your systems run inside, which makes it the first place a system doing too much per tick shows up. |
| 74 | + |
| 75 | +Viewing it needs the Dashboard access permission. See [Network stats](/wukong-mp/docs/Server/network-stats) for how to read the numbers, in particular the difference between wire bytes and payload bytes. |
| 76 | + |
| 77 | +## Co-op fixes |
| 78 | + |
| 79 | +* **NPCs could turn hostile and block quests.** Monsters were created in the shared world with a default team ID instead of the team the game assigns them, so quest NPCs could end up hostile and leave the quest unfinishable. They now keep their real team. |
| 80 | +* **Pagoda debuff sync.** The periodic Beguiling Chant debuff in the Pagoda region in act 3 now stays in sync between players. Its cycle runs on the server, so everyone in the area gets the same warning and the same active window. |
| 81 | +* **Boss HP scaling moved to the server, with a new default.** Scaling elite and boss HP by player count is now a server-side system rather than client logic, and the default changed. It used to be 100% plus 150% for every extra player: 100% solo, 250% for two, 400% for three. It is now a flat 100% per player: 100% solo, 200% for two, 300% for three. |
| 82 | +* **New `bosshp` command.** `bosshp <percent>` sets the per-player multiplier, so `bosshp 150` gives you 150% per player. It applies server-wide and confirms the new value in chat. |
| 83 | + |
| 84 | +## What's next? |
| 85 | + |
| 86 | +We are continuing to move the PvP mod's logic into a server-side mod. Once that is done, the temporary PvP and Cheats APIs introduced in `0.2.0` can go away, as planned. |
| 87 | + |
| 88 | +Further out, we plan to open-source the SDKs themselves, both client-side and server-side. The [co-op and PvP mods have been public since May](/releases/wukongmp-mods-open-source), and opening the layer underneath them is the logical next step: you get to read the code your mod is built on, and fixes stop having to wait for us. More on that when we have a date. |
| 89 | + |
| 90 | +## Migration guide {#migration-guide} |
| 91 | + |
| 92 | +Updating a client mod from `0.2.4` to `0.3.0`: |
| 93 | + |
| 94 | +* Update your server binaries to `0.3.0`. Older servers cannot load mods built on the `0.3.0` SDK. |
| 95 | +* Rebuild your mod against the `0.3.0` SDK. Download the latest [mod template](https://github.com/readycodeio/wukongmp-mod-template) and copy your mod files over, then update the minimum SDK version in your `manifest.json` dependencies. |
| 96 | +* **RPC classes changed base class.** `RpcClassBase` is now [`ClientRpcHandler`](/wukong-mp/api-reference/ReadyM.Api.Multiplayer.RPC/ReadyM.Api.Multiplayer.RPC.ClientRpcHandler), and it no longer takes `IRpcClient` and `IRelaySerializer` in the constructor, since the SDK injects them. Replace `public partial class MyRpc(IRpcClient client, IRelaySerializer serializer) : RpcClassBase(client, serializer)` with `public partial class MyRpc : ClientRpcHandler`. |
| 97 | +* **`RunOnMainThread` is gone.** `[RpcEvent]` handlers are now scheduled onto the game thread for you, so unwrap those callbacks and put the body straight in the handler. See [Custom RPC](/wukong-mp/docs/Development/custom-rpc#threading). |
| 98 | +* **Save file API types moved.** [`SaveFileType`](/wukong-mp/api-reference/ReadyM.Api.Saves/ReadyM.Api.Saves.SaveFileType) and [`FileInfo`](/wukong-mp/api-reference/ReadyM.Api.Saves/ReadyM.Api.Saves.FileInfo) are no longer in `WukongMp.Sdk`, they now live in `ReadyM.Api.Saves`, shared with the server. Update your `using` directives. |
| 99 | +* If you write a class extending `ServerRpcClient` to talk to a server-side mod, it must be annotated with `[ServerRpcFor(typeof(YourContracts))]` naming the contract class it implements. Same for `ServerRpcHandlersBase` on the server. Classes using only `[RpcEvent]` are unaffected. |
0 commit comments