Repository navigation
v0.46.0
Wire protocol version 3 — "Core v3" (ADR-28..31). Needs
com.rpgmmo.shared-gamelogic sgl-v0.7.0 (does not compile against sgl-v0.6.0).
Added
LocalMovePredictor.Reconcile(Vec3, float verticalVelocity, long ackTick): the 3D form of the
two-argument reconcile, for callers that cannot supply the snapshot's base tick (the
com.cuvara.dotsprediction system). Without it the DOTS path could only reconcile the ground
plane, and a 3D motor's height was never corrected.- Wire protocol 3 bindings —
Runtime/Protocol/Generated/Wire.csis a byte copy of the
server's regeneratedGameServer/Net/Generated/RpgMmo/Wire/V1/Wire.cs(protoc 29.3).
MsgType.Command(32),CommandResult(33),ServerPush(34);GameEventType.StatusApplied
(7),StatusRemoved(8),ProjectileHit(9). - Snapshot v3 state —
EntitySnapshot.Z,VelX/VelY/VelZ,Owner(handle) /OwnerId
(its JSON twin),SpawnSeq,Stats/StatsRemoved,Statuses/StatusesRemoved, with new
StatValue/StatusEffectmessage types, decoded by both codecs (the pooled Protobuf decode
clears the lists per entity).ResolvedEntitycarries them through a new constructor taking
in ResolvedEntity coreplus every v3 field (HasVersion3Fields);SnapshotResolverresolves
the projectileownerand each statussourcehandle after the snapshot's own bindings land,
reporting an unbound one as null and counting it inUnresolvedEntityReferenceswithout
aborting the snapshot.WorldState.Applyhands them to Shared.GameLogic's
EntitySnapshotDatav3 constructor, soSnapshotMergermerges the new mask bits
(0x0200-0x2000).GameEvent.EffectId/ResolvedGameEvent.EffectId(new 7-argument
constructor). - Input v3 —
InputMessage.AimZ,RenderTick,RenderAlpha,Jump,SpawnSeq, and
InputMessage.SetRenderTime(double renderTick)to fill the render pair from
WorldViewBinder.RenderTick.GameSessionClient.SendInput(InputMessage)sends a full message.
All v3 fields are elided at zero in both encodings (a v2-shaped input is byte-identical). - Command channel (ADR-30) —
GameSessionClient.SendCommandAsync(uint opcode, byte[] payload, CancellationToken)/NetworkClient.SendCommandAsync(...)returnUniTask<CommandResult>
correlated by a per-connection seq starting at 1;CommandResultReceivedand
ServerPushReceivedevents on both. Channel failures complete withOk == falseand a
CommandChannelErrorsname instead of throwing or hanging:client_not_connected,
client_protocol_too_old(server echoed < 3; checked before sending) and
client_connection_closed(in flight when the connection ended, including a reconnect or
transfer).SupportsCommands,PendingCommandCount,UnmatchedCommandResultson the session.
CommandRequest/CommandResult/ServerPushmessages in both codecs (JSONpayloadis base64,
as Go marshals[]byte). - Character slots (ADR-31) —
NetworkClient.CharacterId(sent as
EnterWorldRequest.character_idon every connect, dungeon entry and transfer; a reconnect
rejoins as the character the lost session played),GameSessionClient.CharacterId/
NetworkClient.ActiveCharacterId(the server'sJoinTokenResponse.character_idecho),
GatewayClient.EnterWorldAsync(mapId, partyId, characterId, ct). Empty is omitted from the wire. - 3D prediction (ADR-28) —
LocalMovePredictor.UseServerProtocol(uint)selects
CharacterMotorfor a protocol 3 server and keeps the planarMovementSystempath for
protocol 2 / unversioned (the default, bit-identical to 0.45.0).SetMapGeometry,
SetMotorParams,RecordInput(tick, x, y, jump),Reconcile(Vec3, float verticalVelocity, long, long),Position3,SimulatedPosition3,VerticalVelocity,IsGrounded,
UsesCharacterMotor,Geometry,MotorParameters. An airborne body takes a passive motor step
on ticks nothing else steps, so gravity does not wait for input.WorldViewBinderreconciles
with height andvel_zwhen the predictor runs the motor. - Projectile prediction (ADR-29) —
ProjectilePredictor:Fireallocates thespawn_seq
and predicts withProjectileLogic;ApplySnapshot/TryHandOverhand over to the
authoritative entity with the samespawn_seq(HandedOver); an unclaimed prediction is
dropped afterHandoverTimeoutSeconds(Unconfirmed). WireProtocolVersion.MinimumServerVersion(2),CommandChannel(3),Motor3D(3),
Supports(serverVersion, feature).JsonValue.AsNumber.- EditMode tests:
CoreV3WireTests,CommandChannelTests,SnapshotV3ResolveTests,
PredictionModelSelectionTests(61 tests).
Changed
WireProtocolVersion.Currentis 3 (was 2), in step with the C# and Go servers.
IsCompatiblenow accepts a server echoing 2 or 3 (or nothing); a server ahead is still
refused. Rollout: a game server still on protocol 2 refuses a protocol 3 client by exact
match, so the server leg must be deployed before a client on this version ships.- DOTS Sample calls
LocalMovePredictor.UseServerProtocol(client.ServerProtocolVersion)after
each join, so it predicts with the motor against a protocol 3 server. - The JSON snapshot reader also reads
changed_fields(absent = 0 = every field present, as
before). GameEvent.ToString()/ResolvedGameEvent.ToString()includeeffect=.x-manualDependenciesand the CI rows pinsgl-v0.7.0(wassgl-v0.5.0inpackage.json,
sgl-v0.6.0in CI). CI fails until that tag exists, and thewirejob until the server's
protocol 3 bindings are on itsdevelop.- CI tests against the Shared.GameLogic the game ships - the package CI's
com.rpgmmo.shared-gamelogicpin movessgl-v0.5.0->sgl-v0.6.0(all three rows), matching
IndieRPGMMOAdventure'spackages-lock.json. sgl-v0.6.0 removes the ten-argument positional
EntitySnapshotDataconstructor (rpg-mmo-server #388);WorldState.Apply, the only call site, already
passesactionSeq:/changedFields:by name, so it compiles unchanged. Thecom.cuvara.dotspin
(v0.29.0) already matches the client. (Superseded by thesgl-v0.7.0move above.)