veratown-prototype

Bondage Club Socket API And Acknowledgements

Appearance qualification caveat: the pinned browser implementation of ChatRoomCharacterItemUpdate explicitly states that single-item updates are not sent back to the source member. A ChatRoomSyncItem broadcast is therefore not a guaranteed sender receipt. Phase 1 uses guarded full-character updates and later matching observations; no echo remains timed_out_unobserved. See the appearance qualification guide.

Protocol baseline: Bondage-College 51df6acc01f8fa185079d8deebf591fe3642a148 (R133), especially BondageClub/Scripts/Messages.d.ts and MessagesPatch.d.ts.

The latest pin adds MapViewTether to BC’s in-band chat-message dictionary and tether data to map state/configuration. It does not add a Socket.IO event or acknowledgement. The 26 client-to-server and 30 server-to-client event names and the acknowledgement/observation classifications below are unchanged. Teleport pads still use existing map configuration and position packets, not a new teleport acknowledgement. Stored destinations, tether metadata, map revisions/backups, and refreshed creation templates are not evidence of live movement or map state. See the 2026-11-03 source review.

This document covers every event in the pinned ClientToServerEvents and ServerToClientEvents maps: 26 client-to-server events and 30 server-to-client events. The declarations specify event names and payload shapes; they do not, by themselves, promise an acknowledgement, delivery, persistence, or causal correlation.

Terms

Operational evidence standard

BC room/character updates are intentionally loosely correlated. A matching inbound update is sufficient to complete a state-observed action as observed; strict causal proof, a request ID, a particular source member, a separate helper observer, and a second corroborating update are not required. Use the latest BC-derived snapshot for already_satisfied. Match the intended target and desired state, respecting the action’s connection/freshness guards, rather than requiring proof that this client caused the update.

This standard applies to feature requirements, including shower removal and restoration. It does not weaken permission checks, permit optimistic snapshot writes, turn dispatch alone into observation, or imply account persistence. Without a matching signal, the action still times out as timed_out_unobserved; reconcile against BC state before another mutation.

ABCL mod messages use the dispatch-only ChatRoomChat transport with strictly validated, mod-owned Hidden dictionary extensions. Neither ABCLMsg nor ABCL:sync adds a BC acknowledgement or request ID. A bounded sync reply may inform a later decision, but it does not confirm delivery or completion of the preceding mod command.

Client-To-Server Matrix

Client event Response or later observation Classification API completion rule
AccountLogin LoginQueue may report queue position; LoginResponse returns account data or InvalidNamePassword; ForceDisconnect can reject/terminate the session. Direct login result plus interim progress. Resolve login only on a valid LoginResponse; wait for room join and ChatRoomSync separately. A fresh LoginResponse is the available full account snapshot, including FriendList.
AccountCreate CreationResponse. Direct result. Match its result union (AccountCreated, account error, or validation/rate-limit error); do not infer creation from socket connection.
PasswordReset PasswordResetResponse. Direct result. Resolve from that response; no account-session snapshot is implied.
PasswordResetProcess PasswordResetResponse. Direct result. Resolve from that response; it shares the response event with PasswordReset, so serialize reset operations.
AccountUpdate No general acknowledgement. Some fields can cause unrelated domain events; no AccountUpdateResponse is declared. One-way write. Report dispatched_unconfirmed. Claim persistence only after a supported read-back, such as a fresh LoginResponse or a narrower query that returns the specific state.
AccountUpdateEmail AccountQueryResult with Query: "EmailUpdate" and a boolean result. Direct result on a shared query-result event. Match the Query discriminator and serialize concurrent email/query operations; there is no request ID.
AccountQuery AccountQueryResult; supported query discriminators are EmailStatus, EmailUpdate, and OnlineFriends. Direct result on a shared query-result event. Match Query; allow only one pending request per query kind (or serialize all queries) because the protocol has no request ID. OnlineFriends is a current online subset, not a full friend-list snapshot.
AccountBeep Recipient receives AccountBeep; the sender has no declared delivery acknowledgement. One-way notification to another account. Resolve as dispatched_unconfirmed after local emit. Do not claim that the recipient saw it.
AccountOwnership AccountOwnership with status, ownership data, or clear-state data. Relationship result/state event; may involve a multi-step exchange. Match by target member and expected result; serialize operations for the same member. There is no request ID, so unrelated ownership changes may interleave.
AccountLovership AccountLovership with status or lovership data. Relationship result/state event; may involve a multi-step exchange. Match by target member and expected result; serialize operations for the same member. There is no request ID.
AccountDifficulty No dedicated result event is declared. A server policy failure may instead disconnect the client. One-way setting. Report dispatch only unless a fresh account snapshot or documented state event verifies the setting.
AccountDisconnect Socket disconnect and possibly ForceDisconnect; no successful-disconnect response packet is declared. Transport/lifecycle action. Complete on the local transport close if needed; distinguish that from server-side account cleanup confirmation.
ChatRoomSearch ChatRoomSearchResult containing search results. Direct search result. Resolve the pending search; requests have no ID, so serialize searches or match using the original query if the protocol provides enough data.
ChatRoomCreate ChatRoomCreateResponse; successful creation is followed by ChatRoomSync. Direct create result plus required state snapshot. Treat ChatRoomCreated as create acknowledgement, then wait for ChatRoomSync before declaring the room ready.
ChatRoomJoin ChatRoomSearchResponse (JoinedRoom or a failure); successful join is followed by ChatRoomSync. Direct join result plus required state snapshot. Resolve the join result, then wait for a room snapshot matching the requested room. Do not treat JoinedRoom alone as complete initialization.
ChatRoomLeave Other occupants receive ChatRoomSyncMemberLeave; the leaving client may transition locally without a dedicated response. No direct acknowledgement; room broadcast to observers. Report local leave dispatch/transport state. Use room state or transport lifecycle if the caller needs evidence of departure; do not wait for an event guaranteed only to other occupants.
ChatRoomChat ChatRoomMessage fanout/echo may be observed by room clients or the target. Message delivery event, not a reliable acknowledgement. Report dispatched_unconfirmed after actual local emit. A MsgId identifies the chat message metadata; it is not a general request/receipt ID.
ChatRoomCharacterUpdate ChatRoomSyncCharacter or ChatRoomSyncSingle can carry updated character state. Asynchronous state echo/broadcast. Match member and desired fields in a later snapshot. SourceMemberNumber helps identify origin but does not uniquely identify an operation.
ChatRoomCharacterExpressionUpdate ChatRoomSyncExpression. Asynchronous state event. Match member, group, and expression; no request ID or guaranteed response deadline.
ChatRoomCharacterPoseUpdate ChatRoomSyncPose. Asynchronous state event. Match member and pose in a later event/snapshot; no request ID.
ChatRoomCharacterArousalUpdate ChatRoomSyncArousal may broadcast updated arousal values. Asynchronous state event. Treat it as observation, not a correlated acknowledgement; sensitive/game-state policy may suppress or alter what is visible.
ChatRoomCharacterItemUpdate ChatRoomSyncItem carries the updated item and source. Asynchronous state echo/broadcast. Reconcile by target/group/item state. The packet has no operation ID; target + group + short time window is only heuristic correlation. ChatRoomCharacterItemUpdate is not a declared server-to-client event.
ChatRoomCharacterMapDataUpdate ChatRoomSyncMapData carries member and map data. Asynchronous state echo/broadcast. Reconcile the member’s observed position/state. It can be absent or delayed; no request ID is present. The bot’s guarded startup teleport preserves observed PrivateState and completes only on a matching bot-position observation; convergence is not causal proof.
ChatRoomAdmin For Action: "Update", ChatRoomUpdateResponse returns Updated, RoomAlreadyExist, or InvalidRoomData; room settings may later appear in ChatRoomSyncRoomProperties/ChatRoomSync. Other admin actions use room/member events. Conditional direct result plus asynchronous state changes. The generic update response has no request ID. Serialize room updates. ApplyRoomSettingsAction requires a matching room sync; Updated alone is not completion. Map actions may use the response as weak acknowledgement. For non-update admin actions use their appropriate state event or no-ack status.
ChatRoomAllowItem ChatRoomAllowItem response includes MemberNumber and AllowItem. Direct query response. Correlate by member number and permit only one outstanding query per member. Timeout as unknown; do not infer denial from a missing response.
ChatRoomGame ChatRoomGameResponse carries game data. Game-specific response/event; it can also represent game activity from other participants. Match expected game/session state where possible. No generic request ID exists; serialize same-session transitions and reconcile the game payload.

Server-To-Client Inventory

This table classifies every declared event in ServerToClientEvents; “not an acknowledgement” means the event can arrive without a corresponding request from this client.

Server event Role Correlation notes
ServerInfo Server heartbeat/status. Unsolicited; not an application acknowledgement.
ServerMessage Server-originated notice. Unsolicited; content is not a request result.
ForceDisconnect Server-directed disconnect/failure (ErrorRateLimited, ErrorDuplicatedLogin). Session-level failure, not a successful operation result.
CreationResponse Result of AccountCreate. Direct pair; no request ID, so only one create request should be pending.
PasswordResetResponse Result of either password-reset request. Direct pair but shared by both reset operations; serialize.
LoginResponse Result and full account snapshot for AccountLogin. Direct pair; this is the complete account read-back exposed by the declared protocol.
LoginQueue Login queue position/progress. Interim status, not successful login.
AccountQueryResult Result for AccountQuery and email-update/status workflows. Match the Query discriminator; no request ID.
AccountLovership Ownership/relationship workflow result or state notification. May be unsolicited or part of a multi-step request; correlate by member/action, not request ID.
AccountOwnership Ownership workflow result or state notification. May be unsolicited or multi-step; correlate by member/action, not request ID.
AccountBeep Incoming beep notification for this account. Recipient-side event; not an acknowledgement to the sender.
ChatRoomSearchResult Results of ChatRoomSearch. Search response, but no request ID.
ChatRoomCreateResponse Result of ChatRoomCreate. Direct result; still wait for ChatRoomSync before using the created room.
ChatRoomSearchResponse Result of ChatRoomJoin. Direct result; JoinedRoom is followed by the required room snapshot.
ChatRoomMessage Chat, emote, whisper, hidden, status, or server message. Fanout/targeted content; not a delivery receipt. Sender/target/message ID do not correlate arbitrary other requests.
ChatRoomGameResponse Game data/activity. May be response or broadcast; interpret in game/session context.
ChatRoomSync Full room snapshot, usually join/create/reconnect. State snapshot, not a per-mutation acknowledgement.
ChatRoomSyncCharacter Character state update. State observation; source/member fields are not operation IDs.
ChatRoomSyncMemberJoin Occupant joined the room. Unsolicited room event.
ChatRoomSyncMemberLeave Occupant left the room. Unsolicited room event; may follow leave, disconnect, kick, or ban.
ChatRoomSyncRoomProperties Room settings/map snapshot. State observation; can verify convergence, but cannot prove which update caused it.
ChatRoomSyncReorderPlayers Room player ordering. Room event, not a generic admin-action acknowledgement.
ChatRoomSyncSingle Single character snapshot. State observation; no operation ID.
ChatRoomSyncExpression Expression state change. State event; no operation ID.
ChatRoomSyncPose Pose state change. State event; no operation ID.
ChatRoomSyncArousal Arousal state change. State event; no operation ID.
ChatRoomSyncItem Item state update. State echo/broadcast; reconcile target/group/item properties.
ChatRoomSyncMapData Character map position/private map state. State echo/broadcast; reconcile member/position.
ChatRoomUpdateResponse Result for room-settings ChatRoomAdmin update. Generic result with no request ID; serialize updates. ApplyRoomSettingsAction treats Updated as nonterminal and requires a matching room sync.
ChatRoomAllowItem Result of ChatRoomAllowItem query. Correlate by MemberNumber; no unique request ID.

API Rules

  1. Request/response events: register the pending waiter before enqueueing the packet. Use a typed matcher and deadline. Serialize requests when BC provides no unique correlation ID; return the response payload/result, not just true.
  2. Read-after-write queries: model AccountQueryResult as a query-specific response. For OnlineFriends, return server-observed online relation data and mark only a matching Type: "Friend" as persisted_observed. An absent result means persistence_not_observed, not rejection, because the target may be offline or the response may race.
  3. State-changing packets: use a dedicated action with a desired-state predicate. Record requested → dispatched → observed when a later sync matches; on timeout record timed_out_unobserved and reconcile before retrying.
  4. One-way packets: resolve only after the local queue emits. Return dispatched_unconfirmed; never label it delivered or persisted without an independent signal.
  5. Correlations are weak: BC does not attach general request IDs to these events. SourceMemberNumber, MemberNumber, room name, target/group, Query, and chat MsgId are scoped hints, not universal operation IDs.
  6. Retry by semantics: idempotent desired-state writes can be safely re-evaluated against fresh observed state. Chat, beep, account updates, password operations, and other non-idempotent actions must not be blindly resent after a timeout.

Ropeybot provides useful implementation patterns: pending promises for login/join/create/search, maps keyed by member number for item-permission queries, and short-window target/group matching for item updates. Its local item-update request ID is not transmitted to BC, so that match is heuristic; this document treats it as an observation, not a true correlated acknowledgement.