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.
socket.emit means only that the Socket.IO client accepted the packet.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 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. |
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. |
true.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.requested → dispatched → observed when a later sync matches; on timeout record timed_out_unobserved and reconcile before retrying.dispatched_unconfirmed; never label it delivered or persisted without an independent signal.SourceMemberNumber, MemberNumber, room name, target/group, Query, and chat MsgId are scoped hints, not universal operation IDs.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.