Frontier has no baked *_GameRuleWrapperCircuit; real Rec Room delivered
Rec Royale's rule chip in the room blob, and without it there is no
BattleRoyaleManager and no match. A newer-client export of a custom Rec
Royale room shows the saved RecRoyaleSquads chip is minimal — prefab id,
palette tag (prefab name lower-cased, 25 chars), circuit node id and an
EMPTY GameRuleWrapperData (field 41) — so the stub can generate it.
Prefab ids read from the client's spawnable-tool table in resources.assets
(SpawnableTool_Runtime_<ENUM> → 20-byte hash → two u32 → 16-byte id), the
Squads id cross-checked against the real save: Solos 983db81a…, Squads
857f7500…. The stub for a room whose name contains RecRoyaleSolos /
RecRoyaleSquads carries the matching chip as a fourth persistence view.
Test: Rec_royale_stub_carries_its_game_rule_chip (both rooms).
Enable + co-owner still gave no Maker Pen. The 2023 client grants Maker
Pen / save / spawn rights off the player's GameRole
(ICreatorRole.CreatorRoleCanUseMakerPen on RecRoom.Systems.PlayerRoles
.GameRole), and game roles are persisted OBJECTS in the room blob: every
real save inspected (Rec Center room_100_v1.dat, Stunt Runner
room_125_v1.dat) carries three GameRoleNode chips — a default role named
after the room plus the built-in "In-Game" and "Eliminated" roles, with
well-known GUIDs shared by every room. A blob with none leaves a co-owner
with no role to hold, so MakerPen.CheckMakerPenPermissionAndUpdateMode
fails regardless of the room-role collection.
BuildRroEditableBlob now emits Rec Royale's own three role objects, laid
out field-for-field like the client's writer (including the always-present
empty Overridable submessages), with view ids derived from the activity id
so repeated downloads describe the same objects. The default role sets
can_use_maker_pen, matching the permissive room-role overlay. Test pins
three persistence views and the three role GUIDs.
An enabled baked room still had no Maker Pen: the client fetched the CDN's
synthetic stub for room_{id}_dorknet_v8.dat and silently loaded the room
with no room roles. Measured against Rec Center's working room_100_v1.dat
(10,930 bytes, the same client loads it with Maker Pen), the old 1,872-byte
roles-only stub was stamped PersistedRoomVersion 19 — past the March-2023
client's ceiling of 16, which only the S3-hit path clamped — and lacked the
skeleton every real save carries (last_save_time, activity_id = the room's
LocationReplicationId, connectable graph, scene settings, object model,
room_mood_* blocks).
RoomDataBlobService.BuildRroEditableBlob now emits that skeleton per room
at version 16 (untyped fields appended on the wire; payloads are Rec
Center's defaults verbatim). CdnController resolves the RRO room for the
miss path, passes its location id, and clamps synthesised blobs the same
way it clamps S3 hits. Tests pin version 16, the activity id and
CanUseMakerPen on every role.
- Updated the RoomsController to utilize synthetic CDN keys for data blobs.
- Introduced methods for determining current or synthetic data blob names.
- Adjusted room role permissions to align with new game role definitions.
- Enhanced the SanitizeController with a new endpoint for purity checks.
- Modified Match and PlayerPresence services to handle deferred presence commits.
- Improved RoomDataBlobService to support new game role and tool tag settings.
- Added support for boot dorm grace period in PlayerPresenceService.
- Updated protobuf definitions to reflect new room role and game role structures.
You are now able to go into dorm and the rec center!
- Updated Bulk method to parse incoming JSON object arrays for UGC item IDs.
- Introduced ReadBulkIdsAsync to handle both object arrays and flat GUID lists.
- Added synthetic placeholder responses for missing UGC items to prevent client errors.
feat: Implement MatchmakeRoom and MatchmakeSubRoom endpoints in GoToController
- Added MatchmakeRoom and MatchmakeSubRoom methods to facilitate joining public and sub-rooms by numeric ID.
- Enhanced ApplySubRoomMutation to ensure proper state transitions for sub-rooms.
- Improved logging for matchmaking actions.
fix: Refactor PlayerSettingsController to handle database save exceptions
- Introduced SaveSettingsChangesAsync to manage DbUpdateException for busy SQLite scenarios.
- Updated methods to call SaveSettingsChangesAsync instead of direct SaveChangesAsync.
chore: Update URL coverage documentation for new matchmaking endpoints
- Documented new MatchmakeRoom and MatchmakeSubRoom endpoints in url-coverage.md.
chore: Add default room data file for room loading
- Included default_room.room to serve as a fallback for missing room data.
fix: Improve SQLite concurrency handling in DatabaseBootstrap
- Configured SQLite to use WAL mode and set a busy timeout for better concurrency.
chore: Create SqliteErrors utility for handling SQLite exceptions
- Added SqliteErrors class to encapsulate logic for detecting busy SQLite exceptions.
refactor: Update RoomDataBlobService to serve default room data
- Modified GetDefaultBlob to load and serve a default room blob with proper role data.
Targets Rec Room 2020.12.18 client.
Re-import after adding:
- DorkNet.ClientMod/dorknet-clientmod.json.template — config schema
the launcher's manifest-driven patcher renders into UserData/.
- tools/build-patcher-zip.ps1 — produces the dorknet-clientpatch-{key}.zip
Release asset the launcher fetches.
- .github/workflows/release.yml — auto-publishes both Release assets
on v1-december-* tag push.
Scrubbed via maintainer-side scrub-for-public.ps1: same drop rules as
the prior import, plus build-patcher-zip.ps1 added to the tools/
allow-list so it survives the scrub.