Status: Proposed. Source review confirms a viable BC-client mechanism for room-admin teleports to another online character. Veratown does not yet expose character-targeted movement or pathfinding. The recommended no-server-change route mode is explicitly a sequence of teleports, not native BC walking.
Use the existing Bondage Club MapViewTeleport hidden-message behavior to move
an explicitly selected character who is online in the configured room, then
reconcile every change from BC map-position syncs:
walk only in the user-facing command if it is accompanied by
a clear notice that it is simulated with teleports.This is the most viable approach under the constraint that BC server-side code
cannot be changed. It supports the existing BC behavior for compatible clients
and reuses current BC packet types. It is not a way to forcibly change another
member’s server-side MapData when their client cannot or will not process the
admin message.
The Bondage-College checkout was clean at commit
614937bb8856713d18dc6709af09638b276f465e (R133), which matches the protocol
baseline recorded by Veratown.
BondageClub/Screens/Online/ChatRoom/CommandsDefault.js, command maptp,
requires room-admin privileges and map mode. It resolves a target character
and supports /maptp <player> <x> <y> as well as a self teleport.ChatRoomMapViewTeleport() in
BondageClub/Screens/Online/ChatRoom/ChatRoomMapView.js sends a ChatRoomChat
message with Type: "Hidden", Content: "ChatRoomMapViewTeleport", a
Target, and a MapViewTeleport dictionary entry containing the position.ChatRoomMapViewTeleportHiddenMessage() checks that the sender is an admin
in the recipient’s current room. If so, it cancels any current map movement
and sets the recipient’s local Player.Position; the ordinary map-data
update then synchronizes the recipient’s position to the room.BondageClub/Scripts/Messages.d.ts already include
ChatRoomChat, targeted messages, dictionaries, and the MapViewTeleport
entry. This does not require inventing a packet or editing the BC protocol.ChatRoomMapViewCanEnterTile() and
ChatRoomMapViewPositionIsBlocked() enforce ordinary map movement checks,
including bounds, immobilization, occupancy, and blocked map positions.
The admin teleport handler sets the position directly instead of calling
those checks. Thus neither a single teleport nor a sequence of teleports is
equivalent to walking under normal BC rules.BcClient.updateOwnMapPosition() sends
ChatRoomCharacterMapDataUpdate without a target member number and guards it
as a self-position update. It must not be repurposed to move another member.ChatRoomSyncMapData adapter already projects the updated
member number and position as an inbound map-position observation. That is
the right evidence for completion; the hidden-message dispatch itself is
not an acknowledgement.The checked-out BondageClub/Scripts/Server.js is part of the browser client
and wires Socket.IO events; it is not the authoritative BC server. This review
validates the shipped client-side /maptp flow and the pinned protocol
declarations, but cannot independently prove production-server routing,
availability, or behavior. Those points must be tested in a controlled room
with the actual BC server and representative target clients before release.
If native BC movement restrictions are a hard requirement, this feature cannot honestly promise them using the no-server-change design. A separately implemented client-side input driver would not make the headless bot control another character’s input. That requirement would need a supported BC server/client capability or a change to the constraint.
All commands that move another character require the requester to be a current room admin. The bot itself must also be a current room admin, because BC’s recipient-side handler checks the message sender’s admin status. These are separate checks: authorization of the requester does not make the bot an admin.
Use a member number for the character target so a nickname collision cannot select the wrong person. A target must be present in the current synchronized room roster and have an observed map position. Do not infer identity from a name or accept arbitrary member numbers that are absent from the roster.
Recommended command shape (both /bot map ... and !map ... through the
existing parser):
!map teleport @<memberNumber> to xy:<x>,<y>
!map teleport @<memberNumber> to key:<locationKey>
!map teleport @<memberNumber> to name:"<locationName>"
!map walk @<memberNumber> to xy:<x>,<y>
!map walk @<memberNumber> to key:<locationKey>
!map walk @<memberNumber> to name:"<locationName>"
walk is a compatibility-friendly command label for stepped teleport,
not a claim that the character walked. The response should disclose that
limitation, especially before the first step.
Resolution rules:
0..39 on each axis). Reject malformed, fractional,
negative, or out-of-range values before dispatch. Do not copy the BC
/maptp parser’s inclusive edge checks; use the existing Veratown
mapPositionSchema.key: by exact room-scoped key match. The location must exist and be
enabled.name: by an exact normalized name match in the configured room. If
no location matches, report not found. If more than one matches, report the
candidate keys and require an explicit key; never choose the first result or
use fuzzy/substring matching.Plan routes on the current room’s 40-by-40 tile grid, not a room/location graph. The path planner is a pure, bounded feature service that accepts the current observed position, observed room map data, selected goal tile(s), and a conservative passability projection. It must not own BC transport or mutate snapshots.
Use breadth-first search over the four cardinal neighbors because BC’s native
map controls move north, south, east, and west. The grid has at most 1,600
nodes, so BFS is bounded and simpler than A* or Dijkstra for an unweighted
stepped-teleport route. Search at most 1,600 cells and return a clear
no_route result if no goal is reached.
Passability should be derived from the latest BC room map (Tiles, Objects,
and relevant cell configuration) using the pinned BC catalog and reviewed
movement-blocking rules. Unknown object/tile definitions must fail closed for
route planning rather than being assumed walkable. Current observed character
positions may be considered as dynamic blockers, except where BC’s shared
teleporter tiles permit co-occupancy. Revalidate the next step immediately
before dispatch.
This projection is only a conservative route policy. The step itself remains a
teleport and bypasses target-specific movement checks in BC, including private
immobilization/effect state, movement speed, and server-side collision. It
cannot promise exact equivalence with ChatRoomMapViewCanEnterTile().
MapViewTeleport, and wait for a fresh
ChatRoomSyncMapData matching both the target member and that tile.Each tile changes BC-observed state and should be its own journaled
executeObserved action. A route orchestrator may coordinate the sequence but
must not introduce a second journal owner for the same packet. Serialize routes
per target member as well as using the existing global BcClient queue and
14-packet/1.2-second limiter. A route can be slow; observed syncs, not packet
dispatch speed, control the next step.
src/features/map/actions/ for direct
teleport and one observed route step. Use ActionCoordinator; retain
MapTeleportAction’s current bot-self use unless a coherent generalization
is made with tests for both self and target cases.BcClient method for the BC admin map-teleport hidden
message. It must validate the current connection/room, target presence,
coordinate bounds, and bot-admin status; construct the existing typed
ChatRoomChat message; and send through the existing queue. Do not call
socket.emit, io(), or generic dispatchPacket() from a feature.CharacterCommunicationApi.hidden() from inside that journaled action:
that API owns its own SendRoomMessageAction journal and would double-record
the same movement request.BcClient inbound mapPosition event/room snapshot as the sole live
state authority. Do not patch BcClient snapshots, persist duplicate
character positions in MongoDB, or treat action-journal data as position
evidence.src/app/start.ts; authorize the command sender separately from the bot’s
own BC room-admin state. Replies go by private whisper and must identify
uncertain completion honestly.Type, Content, Target, dictionary
tag and coordinate. Confirm all sends pass through the global queue.observed only after a matching
BC position observation. A dispatch with no matching sync remains
timed_out_unobserved.Before enabling in an operational room, use a dedicated test bot and at least two ordinary test clients in a non-production room to verify:
No live BC room or production account was used in this source review. The feature must remain disabled until these controlled checks pass.
The requester confirmed that the target may be any character in the room and that a step sequence of teleports is acceptable as a possible implementation; the requester also ruled out changes to BC server-side code. Accordingly, the proposal recommends room-admin-targeted teleports and a clearly disclosed stepped-teleport mode. If “walk” is later required to obey all normal BC movement restrictions, this proposal does not satisfy that requirement and must not be relabeled as genuine walking.