Skip to content

Escape Room hotfix: prevent opening two rooms / closing venue prematurely (1.4.1.0) - #364

Open
waldo (waldo1001) wants to merge 4 commits into
microsoft:masterfrom
waldo1001:hotfix/escaperoom-room-opening
Open

waldo (waldo1001) wants to merge 4 commits into
microsoft:masterfrom
waldo1001:hotfix/escaperoom-room-opening

Conversation

@waldo1001

Copy link
Copy Markdown
Contributor

Problem

During a workshop with many participants, several attendees ended up with two rooms open after finishing the last task of a room, and in some cases the venue was closed while rooms were still in progress.

Root cause

"Escape Room".UpdateStatus() on an already Completed room re-ran OpenNextRoom() unconditionally. That procedure looked for the next Locked room after the current one, so with Room 2 in progress it skipped Room 2 and opened Room 3. Once no locked room was left, its else-branch called Venue.Stop(), which had no guard, so the venue closed prematurely. "Update Status", "Get Hint" and "Solve" on a completed room card (reachable from the room list and the task-completed notification) all triggered this.

A second path made it worse: task completion fires from event subscribers, and the concurrency simulations run background sessions that insert the same records, so the same room completion could run in several sessions at once. Stop() only checked the in-memory status, and the completion image was shown modally before the next room was opened.

Fix (app version 1.4.1.0)

  • OpenNextRoom() is idempotent: exits when a later room is already InProgress, otherwise opens the first Locked room, and closes the venue only via CloseVenueIfCompleted() (all rooms Completed).
  • Room Start()/Stop(), task Stop() and venue Stop() re-read the row under an update lock (ReadIsolation = UpdLock) and re-check status before modifying.
  • Room completion and next-room start are committed before any UI is shown.
  • Venue.Stop() / CloseVenueIfCompleted() return Boolean and no longer show UI; Room.Stop() shows the completion images. No venue app called these directly.
  • Renamed a local variable Key in codeunit 73925 "Escape Room Telemetry" (reserved word in current AL compilers, blocked the build).
  • CHANGELOG and Docs/Framework/Architecture.md updated.

Note on included commits

This branch is stacked on feature/escaperoom-custom-telemetry-events (the 1.4.0.0 custom telemetry events API), which is not merged yet. The hotfix commit depends on it (version numbering, changelog, telemetry codeunit), so those three commits are included here.

Verification

  • Framework compiles with AL 18 compiler: 0 errors, 0 warnings.
  • OptimAL venue app compiles against the new framework package: 0 errors.
  • Not yet executed against a live sandbox; manual scenarios: press "Update Status"/"Get Hint"/"Solve" repeatedly on a completed room (later locked rooms must stay locked); complete all rooms but the last and press "Update Status" on a completed room (venue Stop DateTime must stay empty).

🤖 Generated with Claude Code

waldo and others added 4 commits June 10, 2026 16:03
Add 4 public LogCustomEvent overloads (task-scoped and room-scoped,
with/without ExtraDimensions) enabling room extensions to emit custom
telemetry events that participate in leaderboard scoring.

- Score clamped to -5..+5 to keep leaderboards balanced
- Fixed event name EscapeRoomCustomEvent with EventId dimension
- EventSource=Custom distinguishes from built-in events
- Caller dimensions cannot overwrite standard keys
- Version bumped to 1.4.0.0 (new public API, no breaking changes)
- Add ALEscapeRoomCustomEvent to all scoring KQL queries and dashboard
- Add CustomEvents/CustomEventPoints columns to breakdowns
- Add new 'Custom Events Overview' audit query for facilitators
- Telemetry-Integration.md: add event type #8, custom events section
- Creating-Rooms.md: add custom scoring subsection
- API-Reference.md: add LogCustomEvent procedure docs
- LeaderboardSetup.md: mention custom events in event types
- CHANGELOG.md: add v1.4.0.0 entry
UpdateStatus() on an already Completed room re-ran OpenNextRoom()
unconditionally. Because that procedure searched for the next *Locked*
room, it skipped the room already in progress and opened the one after
it; once no locked room was left it stopped the venue even though rooms
were still in progress. "Update Status", "Get Hint" and "Solve" on a
completed room card all triggered it.

- OpenNextRoom() is now idempotent: exits when a later room is already
  InProgress; closes the venue only via CloseVenueIfCompleted().
- Room/task/venue status transitions re-read the row under an update
  lock and re-check status before modifying, closing the race where the
  same completion ran in several sessions (event subscribers fired from
  the concurrency simulations' background sessions).
- Room completion and next-room start are committed before the
  completion image is shown, so an interrupted session can no longer
  leave the next room locked.
- Venue.Stop()/CloseVenueIfCompleted() return Boolean and no longer show
  UI themselves; Room.Stop() shows the completion images.
- Rename local variable `Key` in codeunit 73925 (reserved word in
  current AL compilers; blocked the build).
- Version 1.4.1.0, CHANGELOG and Architecture.md updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant