Skip to content

Doors and contextual interactions have no server-side RPC surface #21

Description

@eaxiumnet

The README lists this under known issues:

Doors and other contextual interactions work intermittently.

Reading main (84cbb97), the district has no interaction RPC surface at all — no handler, no field index, no decoder branch. Whatever the client currently does with a door is unacknowledged local prediction. The intermittency is separately explained by the decoder aborting a bunch on any unknown field (#20).

There is no interaction handling

A repo-wide search for ServerUse, cDoor, Usable, InteractableActor, ServerInteract, UseKey, ClientDoor returns zero matches across the whole tree. A search for any field constant matching kField*(Use|Door|Interact|Trigger)* likewise returns none.

The complete handled-field vocabulary is declared in one block, DistrictServer/DistrictServer.cpp:2600-2674, and it is worth reading as a whole because it shows precisely where the boundary sits:

  • player state and pawn: PRI 21, Pawn 22, GivePawn 39, ClientRestart 74, ClientSetViewTarget 76, ControllerDead 185
  • movement: DualServerMove 53, OldServerMove 54, ServerMove 55, ClientAckGoodMove 59
  • district entry: AnsDistrictEnter 133, UpdateLevelStreaming 89, FlushLevelStreaming 93
  • HUD and startup: ClientSetHud 41, ClientSetInitialState 538, ClientGotoState 37, ClientIgnoreMoveInput 82
  • character data: CharacterInfo 487, ServerRequestCharacterData 489, CharacterData 490, CharacterStats 491/492, RolesData 498/499, ClientPrecacheCustomisation 279
  • spawn selection: 369, 371, 372; HUD markers 392, 394
  • inventory containers: HoldableItemManager 164, Inventory 165, and the storage ranges under kStorageInventoryFieldMax = 3594

Nothing in that list concerns world interaction. So a ServerUse-equivalent arriving from the client is not mishandled — it is unmeasurable (its parameter width is not in the decoder's table) and therefore aborts the rest of its bunch.

What "intermittently" most likely means

Because the decoder's unknown-field path stops parsing and returns success (ApbUdp.cpp:3478-3494, see #20), an interaction RPC batched ahead of, say, a movement or streaming RPC will silently take that RPC with it. Nothing is logged. The resulting behaviour is frame-dependent and would present as flaky rather than absent — consistent with the README wording, and with the README already listing "Doors and contextual interactions" under Experimental rather than Working.

This is a hypothesis about the symptom, not a measurement: no live-client session was run for this report.

Suggested direction

The decoder fix is the prerequisite, not an optional first step — without it there is no way to learn the field index.

  1. Fix the unknown-field logging first (Unknown controller field aborts bunch parsing and silently discards its own diagnostic #20). Then trigger a door in-game and read the warning: it prints the field index and bit offset directly.
  2. Confirm the index against the client's FClassNetCache for the controller (kPlayerControllerFieldMax = 634 is already the established bound for this build, :2600), so the number can be named rather than guessed.
  3. Measure the parameter width from the capture and add a decoder branch in the established style. If the parameter is an object reference, the ServerSelectSpawnZone branch (ApbUdp.cpp:3305-3350) is the pattern to copy — it already handles the presence bit plus the by-channel/by-NetIndex selector split.
  4. Only then decide what the server does with it. Doors are likely to need a replicated actor state and a client-side confirmation RPC, which is a larger piece of work than the parse.

Steps 1-3 are cheap and produce durable protocol knowledge regardless of when step 4 is tackled.

Line numbers are from 84cbb97. The absence of interaction handling is a clean, repo-wide negative; the causal link to the reported intermittency is reasoned from the decoder's control flow rather than observed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions