Multiplicity 2.6.2
See the version list below for details.
dotnet add package Multiplicity --version 2.6.2
NuGet\Install-Package Multiplicity -Version 2.6.2
<PackageReference Include="Multiplicity" Version="2.6.2" />
<PackageVersion Include="Multiplicity" Version="2.6.2" />
<PackageReference Include="Multiplicity" />
paket add Multiplicity --version 2.6.2
#r "nuget: Multiplicity, 2.6.2"
#:package Multiplicity@2.6.2
#addin nuget:?package=Multiplicity&version=2.6.2
#tool nuget:?package=Multiplicity&version=2.6.2
Multiplicity
Multiplicity.Packets is a low-level C# library for reading and writing Terraria network packets.
NuGet package id: Multiplicity. The assembly and public namespace remain Multiplicity.Packets.
Protocol support
The current baseline is Terraria 1.4.5.7 / protocol 325.
- connection handshake:
Terraria325; - vanilla desktop
MessageID.Count:163; - vanilla desktop packet ids:
0..162; - highest vanilla packet id:
DamageNPCAck (162); ServerInfo (163)andPlayerPlatformInfo (164)are Multiplicity/TSAPI-family extension ids and are not part of vanilla desktopMessageID.
Important protocol-325 changes covered by the library include:
- NPC slot + generation identity in NPC synchronization and damage packets;
- 32-bit
ProjectileKeyidentity in projectile create/destroy synchronization; - current world-item sync and item ownership layouts;
RemoveItemOwner (39)force-assignment flag;DamageNPCAck (162);- additional
WorldInfoseed/world flags used by 1.4.5.7; - current
NetManagermodule registration order, including restoredNetCreativeUnlocksModule; - packet ids
145and148are treated as deprecated in protocol 325 and are not registered for normal runtime deserialization.
KillPortal (95) uses the vanilla wire layout ushort PlayerId + byte PortalColor, so its payload is 3 bytes. The old ProjectileIndex property is retained only as an obsolete source-compatibility alias.
What the library provides
- packet serialization and deserialization;
- typed packet models;
- a zero-copy
ReadOnlySpan<byte>view layer for server hot paths; - packet and view names aligned with the TSAPI/Terraria naming where practical;
- no external runtime dependencies.
Target framework: net9.0.
Install
Install-Package Multiplicity
Object model
Use the object model when a packet needs to be stored, modified or serialized again.
using Multiplicity.Packets;
byte[] receiveBuffer = GetPacketBytes();
TerrariaPacket packet = TerrariaPacket.Deserialize(receiveBuffer, 0, receiveBuffer.Length);
switch (packet)
{
case PlayerInfo playerInfo:
Console.WriteLine($"Player #{playerInfo.PlayerId}: {playerInfo.Name}");
break;
case PlayerUpdate update:
Console.WriteLine($"Player #{update.PlayerId}: X={update.PositionX}, Y={update.PositionY}");
break;
}
Main entry points:
TerrariaPacket.Deserialize(...);TerrariaPacket.DeserializePayload(...);TerrariaPacket.ToArray(...);TerrariaPacket.ToPayloadArray();TerrariaPacket.ToStream(...).
For hooks such as TSAPI/TShock NetGetData, where the packet id is already known and the receive buffer contains a payload slice:
PacketTypes packetType = PacketTypes.ProjectileNew;
TerrariaPacket packet = TerrariaPacket.DeserializePayload(
packetType,
readBuffer,
payloadOffset,
payloadLength);
Zero-copy packet views
Use Multiplicity.Packets.Views when the receive path only needs to inspect a few fields and should avoid materializing a full packet object.
using Multiplicity.Packets;
using Multiplicity.Packets.Views;
ReadOnlySpan<byte> buffer = receiveBuffer.AsSpan(offset, availableBytes);
if (PacketViewParser.TryParse(buffer, out PacketView packetView, out int consumed))
{
if (packetView.PacketType == PacketTypes.PlayerUpdate)
{
PlayerUpdateView view = packetView.AsPlayerUpdateView();
Console.WriteLine($"Player #{view.PlayerId}: X={view.PositionX}, Y={view.PositionY}");
}
}
For payload-only buffers:
PacketView packetView = PacketViewParser.ParsePayload(
PacketTypes.PlayerUpdate,
receiveBuffer,
payloadOffset,
payloadLength);
PlayerUpdateView view = packetView.AsPlayerUpdateView();
TryParsePayload(...) treats the supplied length as the exact payload length. TryParsePayloadBounded(...) treats it as an upper bound, which is useful for receive buffers that may contain trailing data.
A payload-only PacketView has no complete Terraria packet header, so HasPacketSpan is false. Use SourceSpan when code should work with either full-packet or payload-only views.
Net modules
LoadNetModule and TerrariaNetModule use the Terraria 1.4.5.7 registration order. The currently registered module ids are:
| Id | Module |
|---|---|
| 0 | NetLiquidModule |
| 1 | NetTextModule |
| 2 | NetPingModule |
| 3 | NetAmbienceModule |
| 4 | NetBestiaryModule |
| 5 | NetCreativeUnlocksModule |
| 6 | NetCreativePowersModule |
| 7 | NetCreativeUnlocksPlayerReportModule |
| 8 | NetTeleportPylonModule |
| 9 | NetParticlesModule |
| 10 | NetCreativePowerPermissionsModule |
| 11 | NetBannersModule |
| 12 | NetCraftingRequestsModule |
| 13 | LeashedEntityModule |
| 14 | UnbreakableWallScanModule |
The older TagEffectModule is not part of the protocol-325 registration table and has been removed from the active API.
Project layout
Multiplicity.Packets/Core- packet framing, metadata and protocol registration;Multiplicity.Packets/Packets- typed packet object models;Multiplicity.Packets/NetModules-NetManagermodule models;Multiplicity.Packets/Views- low-allocation packet views;Multiplicity.Packets.Tests- protocol and serialization regression tests.
Summary
Multiplicity provides both a conventional packet object model and a low-allocation view API, with the current wire baseline set to Terraria 1.4.5.7 / protocol 325.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Multiplicity:
| Package | Downloads |
|---|---|
|
TZ.RegionExt.Core
Core plugin and API for RegionExt modules |
GitHub repositories
This package is not used by any popular GitHub repositories.