SongGuess
    Preparing search index...

    Hierarchy

    • Server<Env>
      • SongGuessServer
    Index

    Constructors

    Properties

    __DURABLE_OBJECT_BRAND: never
    env: Env
    logger: Logger

    The main logger, logging messages to console and storage.

    tickInterval: Timeout | null = null

    The interval that ticks the room every second.

    validRoom?: ValidRoom

    Only set, if this room was created by a request to /createRoom

    options: { hibernate: boolean } = ...

    Accessors

    • get name(): string

      The name for this server.

      Resolves from this.ctx.id.name — the native DO id name, populated whenever the stub was created via idFromName() or getByName(). This is available inside every entry point (including the constructor, alarms, and hibernating websocket handlers).

      For alarm handlers firing on stale on-disk alarm records from older workerd versions that didn't persist name into the alarm record, the name is recovered from a storage fallback record.

      Throws if neither source is available — typically this means the DO was addressed via idFromString() or newUniqueId(), which is not supported by PartyServer.

      Returns string

    Methods

    • The alarm handler invoked by the Cloudflare Workers runtime.

      Returns Promise<void>

    • Send a message to all connected clients, except connection ids listed in without

      Parameters

      • msg: string | ArrayBuffer | ArrayBufferView<ArrayBufferLike>
      • Optionalwithout: string[]

      Returns void

    • Cancels a scheduled event by its identifier and removes it from storage.

      Parameters

      • id: "cleanup" | "host_transfer"

        The unique identifier of the event to cancel.

      Returns Promise<boolean>

      true if the event existed and was removed, false if not

    • Parameters

      Returns void | Promise<void>

    • Creates a ValidRoom instance, allowing players to connect to this room.

      Returns Promise<void>

    • Handle incoming requests to the server.

      Parameters

      Returns Promise<Response>

    • Calculates the current number of active WebSocket connections with the "player" tag in the room.

      Returns number

      The count of connected clients.

    • Get a connection by connection id

      Type Parameters

      • TState = unknown

      Parameters

      • id: string

      Returns Connection<TState> | undefined

    • Get all connections. Optionally, you can provide a tag to filter returned connections. Use Server#getConnectionTags to tag the connection on connect.

      Type Parameters

      • TState = unknown

      Parameters

      • Optionaltag: string

      Returns Iterable<Connection<TState>>

    • You can tag a connection to filter them in Server#getConnections. Each connection supports up to 9 tags, each tag max length is 256 characters.

      Parameters

      • conn: Connection<string>
      • ctx: ConnectionContext

      Returns string[]

    • Checks whether a connection has a specific connection tag assigned by getConnectionTags.

      Parameters

      • conn: Connection<string>

        The connection to check.

      • tag: string

        The tag that should be present.

      Returns boolean

      whether the connection has the tag or not.

    • Returns void | Promise<void>

    • Handles a WebSocket connection that was closed.

      Parameters

      • conn: Connection<string>

        The connection that closed.

      Returns Promise<void>

    • Handles a new WebSocket connection to the room.

      Parameters

      • conn: Connection<string>

        The new connection.

      • ctx: ConnectionContext

        The connection context.

      Returns Promise<void>

    • Handles errors for a connection. Currently just logs them as warnings.

      Parameters

      • conn: Connection<string>

        the connection that had an error

      • error: unknown

        the error that occured

      Returns void

    • Called when an exception occurs.

      Parameters

      • error: unknown

        the error that occurred

      Returns void

    • Handles incoming messages from a WebSocket connection.

      Parameters

      • conn: Connection<string>

        The connection that sent the message.

      • message: string

        The message content as a string.

      Returns Promise<void>

    • Called when the server is started for the first time.

      Parameters

      • Optionalprops: Record<string, unknown>

      Returns void | Promise<void>

    • Broadcasts a message to all connected clients, optionally filtered by a specific tag.

      Parameters

      • msg:
            | { action: "load"; audioURL: string; type: "audio_control" }
            | {
                action:
                    | "play"
                    | "pause"
                    | "play_countdown_running"
                    | "play_countdown_end";
                type: "audio_control";
            }
            | {
                advancedSongFiltering: boolean;
                audioStartPosition: number;
                distractionsPreferSameArtist: boolean;
                endWhenAnswered: boolean;
                gameMode: "multiple_choice"
                | "player_picks";
                playerPickTimeout: number;
                roundsCount: number;
                timePerQuestion: number;
                type: "room_config";
            }
            | {
                players: Record<
                    string,
                    {
                        answerData?: {
                            answer?: string;
                            answerIndex?: number;
                            answerSpeed: number;
                            answerTimestamp: number;
                            questionPoints: number;
                        };
                        color: string;
                        isHost: boolean;
                        isSpectator: boolean;
                        points: number;
                        username: string;
                    },
                >;
                state: "lobby"
                | "results"
                | "ingame";
                type: "room_state";
                uuid: string;
                version: string;
            }
            | {
                filteredSongsCount: number;
                playlists?: {
                    cover: string
                    | null;
                    hrefURL: string;
                    name: string;
                    songs: {
                        artist: string;
                        audioURL: string;
                        cover: string | null;
                        hrefURL: string;
                        name: string;
                    }[];
                    subtitle?: string;
                }[];
                type: "update_playlists";
            }
            | { countdown: number; type: "countdown" }
            | {
                gamePhase: GamePhase;
                question?:
                    | {
                        answerOptions: string[];
                        correctAnswerIndex?: number;
                        questionType: "multiple_choice";
                        startPos: number;
                    }
                    | {
                        correctAnswer?: {
                            artist: string;
                            audioURL: string;
                            cover: string
                            | null;
                            hrefURL: string;
                            name: string;
                        };
                        pickerId: string;
                        questionCount: number;
                        questionCurrent: number;
                        questionType: "player_picks";
                        startPos: number;
                    };
                roundCurrent: number;
                type: "round_state";
            }
            | {
                songs: {
                    artist: string;
                    audioURL: string;
                    cover: string
                    | null;
                    hrefURL: string;
                    name: string;
                }[];
                type: "update_played_songs";
            }
            | {
                entry: LogEntry;
                level: "error"
                | "info"
                | "warn"
                | "debug";
                type: "add_log_message";
            }
            | { messages: LoggerStorage; type: "update_log_messages" }
            | { duration: number; offset: number; type: "progressbar_update" }
            | {
                error?: string;
                sourceMessage:
                    | { action: "load"; audioURL: string; type: "audio_control" }
                    | {
                        action:
                            | "play"
                            | "pause"
                            | "play_countdown_running"
                            | "play_countdown_end";
                        type: "audio_control";
                    }
                    | { type: "change_username"; username: string }
                    | {
                        playlists: {
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                            songs: {
                                artist: string;
                                audioURL: string;
                                cover: string | null;
                                hrefURL: string;
                                name: string;
                            }[];
                            subtitle?: string;
                        }[];
                        type: "add_playlists";
                    }
                    | { index: number
                    | null; type: "remove_playlist" }
                    | {
                        advancedSongFiltering: boolean;
                        audioStartPosition: number;
                        distractionsPreferSameArtist: boolean;
                        endWhenAnswered: boolean;
                        gameMode: "multiple_choice" | "player_picks";
                        playerPickTimeout: number;
                        roundsCount: number;
                        timePerQuestion: number;
                        type: "room_config";
                    }
                    | { type: "start_game" }
                    | { answer?: string; answerIndex?: number; type: "select_answer" }
                    | { type: "return_to"; where: "lobby" | "results" }
                    | { playerName: string; type: "transfer_host" }
                    | {
                        song: {
                            artist: string;
                            audioURL: string;
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                        };
                        startPos: number;
                        type: "player_pick_song";
                    }
                    | {
                        players: Record<
                            string,
                            {
                                answerData?: {
                                    answer?: string;
                                    answerIndex?: number;
                                    answerSpeed: number;
                                    answerTimestamp: number;
                                    questionPoints: number;
                                };
                                color: string;
                                isHost: boolean;
                                isSpectator: boolean;
                                points: number;
                                username: string;
                            },
                        >;
                        state: "lobby"
                        | "results"
                        | "ingame";
                        type: "room_state";
                        uuid: string;
                        version: string;
                    }
                    | {
                        filteredSongsCount: number;
                        playlists?: {
                            cover: string
                            | null;
                            hrefURL: string;
                            name: string;
                            songs: {
                                artist: string;
                                audioURL: string;
                                cover: string | null;
                                hrefURL: string;
                                name: string;
                            }[];
                            subtitle?: string;
                        }[];
                        type: "update_playlists";
                    }
                    | { countdown: number; type: "countdown" }
                    | {
                        gamePhase: GamePhase;
                        question?:
                            | {
                                answerOptions: string[];
                                correctAnswerIndex?: number;
                                questionType: "multiple_choice";
                                startPos: number;
                            }
                            | {
                                correctAnswer?: {
                                    artist: string;
                                    audioURL: string;
                                    cover: string
                                    | null;
                                    hrefURL: string;
                                    name: string;
                                };
                                pickerId: string;
                                questionCount: number;
                                questionCurrent: number;
                                questionType: "player_picks";
                                startPos: number;
                            };
                        roundCurrent: number;
                        type: "round_state";
                    }
                    | {
                        songs: {
                            artist: string;
                            audioURL: string;
                            cover: string
                            | null;
                            hrefURL: string;
                            name: string;
                        }[];
                        type: "update_played_songs";
                    }
                    | {
                        entry: LogEntry;
                        level: "error"
                        | "info"
                        | "warn"
                        | "debug";
                        type: "add_log_message";
                    }
                    | { messages: LoggerStorage; type: "update_log_messages" }
                    | { duration: number; offset: number; type: "progressbar_update" }
                    | { type: "other" };
                type: "confirmation";
            }
            | { seq: number; type: "ping" }
            | { seq: number; type: "pong" }

        The message object to be broadcasted to the connections.

        • { action: "load"; audioURL: string; type: "audio_control" }
          • action: "load"
            • "load": Downloads the music.
          • audioURL: string

            URL to load music from.

          • type: "audio_control"
        • {
              action:
                  | "play"
                  | "pause"
                  | "play_countdown_running"
                  | "play_countdown_end";
              type: "audio_control";
          }
          • action: "play" | "pause" | "play_countdown_running" | "play_countdown_end"
            • "play": Starts playback of the music.
            • "pause": Pauses playback of the music.
            • "play_countdown_running": Plays the countdown_running sound effect on a secondary audio player.
            • "play_countdown_end": Plays the countdown_end sound effect on a secondary audio player.
          • type: "audio_control"
        • {
              advancedSongFiltering: boolean;
              audioStartPosition: number;
              distractionsPreferSameArtist: boolean;
              endWhenAnswered: boolean;
              gameMode: "multiple_choice" | "player_picks";
              playerPickTimeout: number;
              roundsCount: number;
              timePerQuestion: number;
              type: "room_config";
          }
          • advancedSongFiltering: boolean

            Whether to perform advanced filtering tactics when generating the songs array. Currently just ignores parens when filtering for identical song names.

          • audioStartPosition: number

            The music start position.

            • 0: start of audio
            • 1: close to middle of audio
            • 2: close to end of audio
            • 3: random of the above

            Used as default value in PlayerPicksGame, used as forced position in MultipleChoiceGame.

          • distractionsPreferSameArtist: boolean

            Whether to prefer distractions by the same artist.

          • endWhenAnswered: boolean

            Whether to directly end the round after all players answered.

          • gameMode: "multiple_choice" | "player_picks"

            The game mode being played.

            • multiple_choice: the server selects random songs from the provided playlist and provides a multiple choice question with distractions.
            • player_picks: a player from the room picks a song for other players to guess each round. other players have to guess the song title by typing.
          • playerPickTimeout: number

            The amount of time a player should have to pick a song.

          • roundsCount: number

            The amount of rounds to play.

          • timePerQuestion: number

            The time per question in each round.

          • type: "room_config"
        • {
              players: Record<
                  string,
                  {
                      answerData?: {
                          answer?: string;
                          answerIndex?: number;
                          answerSpeed: number;
                          answerTimestamp: number;
                          questionPoints: number;
                      };
                      color: string;
                      isHost: boolean;
                      isSpectator: boolean;
                      points: number;
                      username: string;
                  },
              >;
              state: "lobby"
              | "results"
              | "ingame";
              type: "room_state";
              uuid: string;
              version: string;
          }
          • players: Record<
                string,
                {
                    answerData?: {
                        answer?: string;
                        answerIndex?: number;
                        answerSpeed: number;
                        answerTimestamp: number;
                        questionPoints: number;
                    };
                    color: string;
                    isHost: boolean;
                    isSpectator: boolean;
                    points: number;
                    username: string;
                },
            >

            A map of all active (online, non-spectating) players. Key is server generated uuid, NOT connection id.

          • state: "lobby" | "results" | "ingame"

            The current game state

          • type: "room_state"
          • uuid: string

            The player's unique identifier generated by the server. Not connection id!

          • version: string

            The current version of the server.

        • {
              filteredSongsCount: number;
              playlists?: {
                  cover: string | null;
                  hrefURL: string;
                  name: string;
                  songs: {
                      artist: string;
                      audioURL: string;
                      cover: string | null;
                      hrefURL: string;
                      name: string;
                  }[];
                  subtitle?: string;
              }[];
              type: "update_playlists";
          }
          • filteredSongsCount: number

            The count of filtered songs.

            filterSongs

          • Optionalplaylists?: {
                cover: string | null;
                hrefURL: string;
                name: string;
                songs: {
                    artist: string;
                    audioURL: string;
                    cover: string | null;
                    hrefURL: string;
                    name: string;
                }[];
                subtitle?: string;
            }[]

            Currently selected playlist(s)

          • type: "update_playlists"
        • { countdown: number; type: "countdown" }
          • countdown: number

            The current countdown number. 0 to hide.

          • type: "countdown"
        • {
              gamePhase: GamePhase;
              question?:
                  | {
                      answerOptions: string[];
                      correctAnswerIndex?: number;
                      questionType: "multiple_choice";
                      startPos: number;
                  }
                  | {
                      correctAnswer?: {
                          artist: string;
                          audioURL: string;
                          cover: string
                          | null;
                          hrefURL: string;
                          name: string;
                      };
                      pickerId: string;
                      questionCount: number;
                      questionCurrent: number;
                      questionType: "player_picks";
                      startPos: number;
                  };
              roundCurrent: number;
              type: "round_state";
          }
          • gamePhase: GamePhase

            The current game phase.

            GamePhase

          • Optionalquestion?:
                | {
                    answerOptions: string[];
                    correctAnswerIndex?: number;
                    questionType: "multiple_choice";
                    startPos: number;
                }
                | {
                    correctAnswer?: {
                        artist: string;
                        audioURL: string;
                        cover: string
                        | null;
                        hrefURL: string;
                        name: string;
                    };
                    pickerId: string;
                    questionCount: number;
                    questionCurrent: number;
                    questionType: "player_picks";
                    startPos: number;
                }
          • roundCurrent: number

            The round number.

          • type: "round_state"
        • {
              songs: {
                  artist: string;
                  audioURL: string;
                  cover: string | null;
                  hrefURL: string;
                  name: string;
              }[];
              type: "update_played_songs";
          }
          • songs: {
                artist: string;
                audioURL: string;
                cover: string | null;
                hrefURL: string;
                name: string;
            }[]

            The songs that were played in this round.

          • type: "update_played_songs"
        • {
              entry: LogEntry;
              level: "error" | "info" | "warn" | "debug";
              type: "add_log_message";
          }
          • entry: LogEntry

            The added log message.

          • level: "error" | "info" | "warn" | "debug"

            The log level of the added message.

          • type: "add_log_message"
        • { messages: LoggerStorage; type: "update_log_messages" }
        • { duration: number; offset: number; type: "progressbar_update" }
          • duration: number

            The duration of the progressbar.

          • offset: number

            The number of seconds to offset the progress bar start point.

          • type: "progressbar_update"
        • {
              error?: string;
              sourceMessage:
                  | { action: "load"; audioURL: string; type: "audio_control" }
                  | {
                      action:
                          | "play"
                          | "pause"
                          | "play_countdown_running"
                          | "play_countdown_end";
                      type: "audio_control";
                  }
                  | { type: "change_username"; username: string }
                  | {
                      playlists: {
                          cover: string | null;
                          hrefURL: string;
                          name: string;
                          songs: {
                              artist: string;
                              audioURL: string;
                              cover: string | null;
                              hrefURL: string;
                              name: string;
                          }[];
                          subtitle?: string;
                      }[];
                      type: "add_playlists";
                  }
                  | { index: number
                  | null; type: "remove_playlist" }
                  | {
                      advancedSongFiltering: boolean;
                      audioStartPosition: number;
                      distractionsPreferSameArtist: boolean;
                      endWhenAnswered: boolean;
                      gameMode: "multiple_choice" | "player_picks";
                      playerPickTimeout: number;
                      roundsCount: number;
                      timePerQuestion: number;
                      type: "room_config";
                  }
                  | { type: "start_game" }
                  | { answer?: string; answerIndex?: number; type: "select_answer" }
                  | { type: "return_to"; where: "lobby" | "results" }
                  | { playerName: string; type: "transfer_host" }
                  | {
                      song: {
                          artist: string;
                          audioURL: string;
                          cover: string | null;
                          hrefURL: string;
                          name: string;
                      };
                      startPos: number;
                      type: "player_pick_song";
                  }
                  | {
                      players: Record<
                          string,
                          {
                              answerData?: {
                                  answer?: string;
                                  answerIndex?: number;
                                  answerSpeed: number;
                                  answerTimestamp: number;
                                  questionPoints: number;
                              };
                              color: string;
                              isHost: boolean;
                              isSpectator: boolean;
                              points: number;
                              username: string;
                          },
                      >;
                      state: "lobby"
                      | "results"
                      | "ingame";
                      type: "room_state";
                      uuid: string;
                      version: string;
                  }
                  | {
                      filteredSongsCount: number;
                      playlists?: {
                          cover: string
                          | null;
                          hrefURL: string;
                          name: string;
                          songs: {
                              artist: string;
                              audioURL: string;
                              cover: string | null;
                              hrefURL: string;
                              name: string;
                          }[];
                          subtitle?: string;
                      }[];
                      type: "update_playlists";
                  }
                  | { countdown: number; type: "countdown" }
                  | {
                      gamePhase: GamePhase;
                      question?:
                          | {
                              answerOptions: string[];
                              correctAnswerIndex?: number;
                              questionType: "multiple_choice";
                              startPos: number;
                          }
                          | {
                              correctAnswer?: {
                                  artist: string;
                                  audioURL: string;
                                  cover: string
                                  | null;
                                  hrefURL: string;
                                  name: string;
                              };
                              pickerId: string;
                              questionCount: number;
                              questionCurrent: number;
                              questionType: "player_picks";
                              startPos: number;
                          };
                      roundCurrent: number;
                      type: "round_state";
                  }
                  | {
                      songs: {
                          artist: string;
                          audioURL: string;
                          cover: string
                          | null;
                          hrefURL: string;
                          name: string;
                      }[];
                      type: "update_played_songs";
                  }
                  | {
                      entry: LogEntry;
                      level: "error"
                      | "info"
                      | "warn"
                      | "debug";
                      type: "add_log_message";
                  }
                  | { messages: LoggerStorage; type: "update_log_messages" }
                  | { duration: number; offset: number; type: "progressbar_update" }
                  | { type: "other" };
              type: "confirmation";
          }
          • Optionalerror?: string

            Optional error message if the requested action could not be performed.

          • sourceMessage:
                | { action: "load"; audioURL: string; type: "audio_control" }
                | {
                    action:
                        | "play"
                        | "pause"
                        | "play_countdown_running"
                        | "play_countdown_end";
                    type: "audio_control";
                }
                | { type: "change_username"; username: string }
                | {
                    playlists: {
                        cover: string | null;
                        hrefURL: string;
                        name: string;
                        songs: {
                            artist: string;
                            audioURL: string;
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                        }[];
                        subtitle?: string;
                    }[];
                    type: "add_playlists";
                }
                | { index: number
                | null; type: "remove_playlist" }
                | {
                    advancedSongFiltering: boolean;
                    audioStartPosition: number;
                    distractionsPreferSameArtist: boolean;
                    endWhenAnswered: boolean;
                    gameMode: "multiple_choice" | "player_picks";
                    playerPickTimeout: number;
                    roundsCount: number;
                    timePerQuestion: number;
                    type: "room_config";
                }
                | { type: "start_game" }
                | { answer?: string; answerIndex?: number; type: "select_answer" }
                | { type: "return_to"; where: "lobby" | "results" }
                | { playerName: string; type: "transfer_host" }
                | {
                    song: {
                        artist: string;
                        audioURL: string;
                        cover: string | null;
                        hrefURL: string;
                        name: string;
                    };
                    startPos: number;
                    type: "player_pick_song";
                }
                | {
                    players: Record<
                        string,
                        {
                            answerData?: {
                                answer?: string;
                                answerIndex?: number;
                                answerSpeed: number;
                                answerTimestamp: number;
                                questionPoints: number;
                            };
                            color: string;
                            isHost: boolean;
                            isSpectator: boolean;
                            points: number;
                            username: string;
                        },
                    >;
                    state: "lobby"
                    | "results"
                    | "ingame";
                    type: "room_state";
                    uuid: string;
                    version: string;
                }
                | {
                    filteredSongsCount: number;
                    playlists?: {
                        cover: string
                        | null;
                        hrefURL: string;
                        name: string;
                        songs: {
                            artist: string;
                            audioURL: string;
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                        }[];
                        subtitle?: string;
                    }[];
                    type: "update_playlists";
                }
                | { countdown: number; type: "countdown" }
                | {
                    gamePhase: GamePhase;
                    question?:
                        | {
                            answerOptions: string[];
                            correctAnswerIndex?: number;
                            questionType: "multiple_choice";
                            startPos: number;
                        }
                        | {
                            correctAnswer?: {
                                artist: string;
                                audioURL: string;
                                cover: string
                                | null;
                                hrefURL: string;
                                name: string;
                            };
                            pickerId: string;
                            questionCount: number;
                            questionCurrent: number;
                            questionType: "player_picks";
                            startPos: number;
                        };
                    roundCurrent: number;
                    type: "round_state";
                }
                | {
                    songs: {
                        artist: string;
                        audioURL: string;
                        cover: string
                        | null;
                        hrefURL: string;
                        name: string;
                    }[];
                    type: "update_played_songs";
                }
                | {
                    entry: LogEntry;
                    level: "error"
                    | "info"
                    | "warn"
                    | "debug";
                    type: "add_log_message";
                }
                | { messages: LoggerStorage; type: "update_log_messages" }
                | { duration: number; offset: number; type: "progressbar_update" }
                | { type: "other" }

            The message that is being confirmed.

          • type: "confirmation"
        • { seq: number; type: "ping" }
          • seq: number

            The sequence number the pong should respond with

          • type: "ping"
        • { seq: number; type: "pong" }
          • seq: number

            The sequence number asked for in the ping packet.

          • type: "pong"
      • Optionaltag: string

        An optional filter to target a specific subset of connections.

      Returns void

    • Safely sends a JSON-serialized message over a connection if it is currently open.

      Parameters

      • conn: Connection<string>

        The active party connection object used to send the data.

      • msg:
            | { action: "load"; audioURL: string; type: "audio_control" }
            | {
                action:
                    | "play"
                    | "pause"
                    | "play_countdown_running"
                    | "play_countdown_end";
                type: "audio_control";
            }
            | {
                advancedSongFiltering: boolean;
                audioStartPosition: number;
                distractionsPreferSameArtist: boolean;
                endWhenAnswered: boolean;
                gameMode: "multiple_choice"
                | "player_picks";
                playerPickTimeout: number;
                roundsCount: number;
                timePerQuestion: number;
                type: "room_config";
            }
            | {
                players: Record<
                    string,
                    {
                        answerData?: {
                            answer?: string;
                            answerIndex?: number;
                            answerSpeed: number;
                            answerTimestamp: number;
                            questionPoints: number;
                        };
                        color: string;
                        isHost: boolean;
                        isSpectator: boolean;
                        points: number;
                        username: string;
                    },
                >;
                state: "lobby"
                | "results"
                | "ingame";
                type: "room_state";
                uuid: string;
                version: string;
            }
            | {
                filteredSongsCount: number;
                playlists?: {
                    cover: string
                    | null;
                    hrefURL: string;
                    name: string;
                    songs: {
                        artist: string;
                        audioURL: string;
                        cover: string | null;
                        hrefURL: string;
                        name: string;
                    }[];
                    subtitle?: string;
                }[];
                type: "update_playlists";
            }
            | { countdown: number; type: "countdown" }
            | {
                gamePhase: GamePhase;
                question?:
                    | {
                        answerOptions: string[];
                        correctAnswerIndex?: number;
                        questionType: "multiple_choice";
                        startPos: number;
                    }
                    | {
                        correctAnswer?: {
                            artist: string;
                            audioURL: string;
                            cover: string
                            | null;
                            hrefURL: string;
                            name: string;
                        };
                        pickerId: string;
                        questionCount: number;
                        questionCurrent: number;
                        questionType: "player_picks";
                        startPos: number;
                    };
                roundCurrent: number;
                type: "round_state";
            }
            | {
                songs: {
                    artist: string;
                    audioURL: string;
                    cover: string
                    | null;
                    hrefURL: string;
                    name: string;
                }[];
                type: "update_played_songs";
            }
            | {
                entry: LogEntry;
                level: "error"
                | "info"
                | "warn"
                | "debug";
                type: "add_log_message";
            }
            | { messages: LoggerStorage; type: "update_log_messages" }
            | { duration: number; offset: number; type: "progressbar_update" }
            | {
                error?: string;
                sourceMessage:
                    | { action: "load"; audioURL: string; type: "audio_control" }
                    | {
                        action:
                            | "play"
                            | "pause"
                            | "play_countdown_running"
                            | "play_countdown_end";
                        type: "audio_control";
                    }
                    | { type: "change_username"; username: string }
                    | {
                        playlists: {
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                            songs: {
                                artist: string;
                                audioURL: string;
                                cover: string | null;
                                hrefURL: string;
                                name: string;
                            }[];
                            subtitle?: string;
                        }[];
                        type: "add_playlists";
                    }
                    | { index: number
                    | null; type: "remove_playlist" }
                    | {
                        advancedSongFiltering: boolean;
                        audioStartPosition: number;
                        distractionsPreferSameArtist: boolean;
                        endWhenAnswered: boolean;
                        gameMode: "multiple_choice" | "player_picks";
                        playerPickTimeout: number;
                        roundsCount: number;
                        timePerQuestion: number;
                        type: "room_config";
                    }
                    | { type: "start_game" }
                    | { answer?: string; answerIndex?: number; type: "select_answer" }
                    | { type: "return_to"; where: "lobby" | "results" }
                    | { playerName: string; type: "transfer_host" }
                    | {
                        song: {
                            artist: string;
                            audioURL: string;
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                        };
                        startPos: number;
                        type: "player_pick_song";
                    }
                    | {
                        players: Record<
                            string,
                            {
                                answerData?: {
                                    answer?: string;
                                    answerIndex?: number;
                                    answerSpeed: number;
                                    answerTimestamp: number;
                                    questionPoints: number;
                                };
                                color: string;
                                isHost: boolean;
                                isSpectator: boolean;
                                points: number;
                                username: string;
                            },
                        >;
                        state: "lobby"
                        | "results"
                        | "ingame";
                        type: "room_state";
                        uuid: string;
                        version: string;
                    }
                    | {
                        filteredSongsCount: number;
                        playlists?: {
                            cover: string
                            | null;
                            hrefURL: string;
                            name: string;
                            songs: {
                                artist: string;
                                audioURL: string;
                                cover: string | null;
                                hrefURL: string;
                                name: string;
                            }[];
                            subtitle?: string;
                        }[];
                        type: "update_playlists";
                    }
                    | { countdown: number; type: "countdown" }
                    | {
                        gamePhase: GamePhase;
                        question?:
                            | {
                                answerOptions: string[];
                                correctAnswerIndex?: number;
                                questionType: "multiple_choice";
                                startPos: number;
                            }
                            | {
                                correctAnswer?: {
                                    artist: string;
                                    audioURL: string;
                                    cover: string
                                    | null;
                                    hrefURL: string;
                                    name: string;
                                };
                                pickerId: string;
                                questionCount: number;
                                questionCurrent: number;
                                questionType: "player_picks";
                                startPos: number;
                            };
                        roundCurrent: number;
                        type: "round_state";
                    }
                    | {
                        songs: {
                            artist: string;
                            audioURL: string;
                            cover: string
                            | null;
                            hrefURL: string;
                            name: string;
                        }[];
                        type: "update_played_songs";
                    }
                    | {
                        entry: LogEntry;
                        level: "error"
                        | "info"
                        | "warn"
                        | "debug";
                        type: "add_log_message";
                    }
                    | { messages: LoggerStorage; type: "update_log_messages" }
                    | { duration: number; offset: number; type: "progressbar_update" }
                    | { type: "other" };
                type: "confirmation";
            }
            | { seq: number; type: "ping" }
            | { seq: number; type: "pong" }

        The message object to be stringified and transmitted to the client.

        • { action: "load"; audioURL: string; type: "audio_control" }
          • action: "load"
            • "load": Downloads the music.
          • audioURL: string

            URL to load music from.

          • type: "audio_control"
        • {
              action:
                  | "play"
                  | "pause"
                  | "play_countdown_running"
                  | "play_countdown_end";
              type: "audio_control";
          }
          • action: "play" | "pause" | "play_countdown_running" | "play_countdown_end"
            • "play": Starts playback of the music.
            • "pause": Pauses playback of the music.
            • "play_countdown_running": Plays the countdown_running sound effect on a secondary audio player.
            • "play_countdown_end": Plays the countdown_end sound effect on a secondary audio player.
          • type: "audio_control"
        • {
              advancedSongFiltering: boolean;
              audioStartPosition: number;
              distractionsPreferSameArtist: boolean;
              endWhenAnswered: boolean;
              gameMode: "multiple_choice" | "player_picks";
              playerPickTimeout: number;
              roundsCount: number;
              timePerQuestion: number;
              type: "room_config";
          }
          • advancedSongFiltering: boolean

            Whether to perform advanced filtering tactics when generating the songs array. Currently just ignores parens when filtering for identical song names.

          • audioStartPosition: number

            The music start position.

            • 0: start of audio
            • 1: close to middle of audio
            • 2: close to end of audio
            • 3: random of the above

            Used as default value in PlayerPicksGame, used as forced position in MultipleChoiceGame.

          • distractionsPreferSameArtist: boolean

            Whether to prefer distractions by the same artist.

          • endWhenAnswered: boolean

            Whether to directly end the round after all players answered.

          • gameMode: "multiple_choice" | "player_picks"

            The game mode being played.

            • multiple_choice: the server selects random songs from the provided playlist and provides a multiple choice question with distractions.
            • player_picks: a player from the room picks a song for other players to guess each round. other players have to guess the song title by typing.
          • playerPickTimeout: number

            The amount of time a player should have to pick a song.

          • roundsCount: number

            The amount of rounds to play.

          • timePerQuestion: number

            The time per question in each round.

          • type: "room_config"
        • {
              players: Record<
                  string,
                  {
                      answerData?: {
                          answer?: string;
                          answerIndex?: number;
                          answerSpeed: number;
                          answerTimestamp: number;
                          questionPoints: number;
                      };
                      color: string;
                      isHost: boolean;
                      isSpectator: boolean;
                      points: number;
                      username: string;
                  },
              >;
              state: "lobby"
              | "results"
              | "ingame";
              type: "room_state";
              uuid: string;
              version: string;
          }
          • players: Record<
                string,
                {
                    answerData?: {
                        answer?: string;
                        answerIndex?: number;
                        answerSpeed: number;
                        answerTimestamp: number;
                        questionPoints: number;
                    };
                    color: string;
                    isHost: boolean;
                    isSpectator: boolean;
                    points: number;
                    username: string;
                },
            >

            A map of all active (online, non-spectating) players. Key is server generated uuid, NOT connection id.

          • state: "lobby" | "results" | "ingame"

            The current game state

          • type: "room_state"
          • uuid: string

            The player's unique identifier generated by the server. Not connection id!

          • version: string

            The current version of the server.

        • {
              filteredSongsCount: number;
              playlists?: {
                  cover: string | null;
                  hrefURL: string;
                  name: string;
                  songs: {
                      artist: string;
                      audioURL: string;
                      cover: string | null;
                      hrefURL: string;
                      name: string;
                  }[];
                  subtitle?: string;
              }[];
              type: "update_playlists";
          }
          • filteredSongsCount: number

            The count of filtered songs.

            filterSongs

          • Optionalplaylists?: {
                cover: string | null;
                hrefURL: string;
                name: string;
                songs: {
                    artist: string;
                    audioURL: string;
                    cover: string | null;
                    hrefURL: string;
                    name: string;
                }[];
                subtitle?: string;
            }[]

            Currently selected playlist(s)

          • type: "update_playlists"
        • { countdown: number; type: "countdown" }
          • countdown: number

            The current countdown number. 0 to hide.

          • type: "countdown"
        • {
              gamePhase: GamePhase;
              question?:
                  | {
                      answerOptions: string[];
                      correctAnswerIndex?: number;
                      questionType: "multiple_choice";
                      startPos: number;
                  }
                  | {
                      correctAnswer?: {
                          artist: string;
                          audioURL: string;
                          cover: string
                          | null;
                          hrefURL: string;
                          name: string;
                      };
                      pickerId: string;
                      questionCount: number;
                      questionCurrent: number;
                      questionType: "player_picks";
                      startPos: number;
                  };
              roundCurrent: number;
              type: "round_state";
          }
          • gamePhase: GamePhase

            The current game phase.

            GamePhase

          • Optionalquestion?:
                | {
                    answerOptions: string[];
                    correctAnswerIndex?: number;
                    questionType: "multiple_choice";
                    startPos: number;
                }
                | {
                    correctAnswer?: {
                        artist: string;
                        audioURL: string;
                        cover: string
                        | null;
                        hrefURL: string;
                        name: string;
                    };
                    pickerId: string;
                    questionCount: number;
                    questionCurrent: number;
                    questionType: "player_picks";
                    startPos: number;
                }
          • roundCurrent: number

            The round number.

          • type: "round_state"
        • {
              songs: {
                  artist: string;
                  audioURL: string;
                  cover: string | null;
                  hrefURL: string;
                  name: string;
              }[];
              type: "update_played_songs";
          }
          • songs: {
                artist: string;
                audioURL: string;
                cover: string | null;
                hrefURL: string;
                name: string;
            }[]

            The songs that were played in this round.

          • type: "update_played_songs"
        • {
              entry: LogEntry;
              level: "error" | "info" | "warn" | "debug";
              type: "add_log_message";
          }
          • entry: LogEntry

            The added log message.

          • level: "error" | "info" | "warn" | "debug"

            The log level of the added message.

          • type: "add_log_message"
        • { messages: LoggerStorage; type: "update_log_messages" }
        • { duration: number; offset: number; type: "progressbar_update" }
          • duration: number

            The duration of the progressbar.

          • offset: number

            The number of seconds to offset the progress bar start point.

          • type: "progressbar_update"
        • {
              error?: string;
              sourceMessage:
                  | { action: "load"; audioURL: string; type: "audio_control" }
                  | {
                      action:
                          | "play"
                          | "pause"
                          | "play_countdown_running"
                          | "play_countdown_end";
                      type: "audio_control";
                  }
                  | { type: "change_username"; username: string }
                  | {
                      playlists: {
                          cover: string | null;
                          hrefURL: string;
                          name: string;
                          songs: {
                              artist: string;
                              audioURL: string;
                              cover: string | null;
                              hrefURL: string;
                              name: string;
                          }[];
                          subtitle?: string;
                      }[];
                      type: "add_playlists";
                  }
                  | { index: number
                  | null; type: "remove_playlist" }
                  | {
                      advancedSongFiltering: boolean;
                      audioStartPosition: number;
                      distractionsPreferSameArtist: boolean;
                      endWhenAnswered: boolean;
                      gameMode: "multiple_choice" | "player_picks";
                      playerPickTimeout: number;
                      roundsCount: number;
                      timePerQuestion: number;
                      type: "room_config";
                  }
                  | { type: "start_game" }
                  | { answer?: string; answerIndex?: number; type: "select_answer" }
                  | { type: "return_to"; where: "lobby" | "results" }
                  | { playerName: string; type: "transfer_host" }
                  | {
                      song: {
                          artist: string;
                          audioURL: string;
                          cover: string | null;
                          hrefURL: string;
                          name: string;
                      };
                      startPos: number;
                      type: "player_pick_song";
                  }
                  | {
                      players: Record<
                          string,
                          {
                              answerData?: {
                                  answer?: string;
                                  answerIndex?: number;
                                  answerSpeed: number;
                                  answerTimestamp: number;
                                  questionPoints: number;
                              };
                              color: string;
                              isHost: boolean;
                              isSpectator: boolean;
                              points: number;
                              username: string;
                          },
                      >;
                      state: "lobby"
                      | "results"
                      | "ingame";
                      type: "room_state";
                      uuid: string;
                      version: string;
                  }
                  | {
                      filteredSongsCount: number;
                      playlists?: {
                          cover: string
                          | null;
                          hrefURL: string;
                          name: string;
                          songs: {
                              artist: string;
                              audioURL: string;
                              cover: string | null;
                              hrefURL: string;
                              name: string;
                          }[];
                          subtitle?: string;
                      }[];
                      type: "update_playlists";
                  }
                  | { countdown: number; type: "countdown" }
                  | {
                      gamePhase: GamePhase;
                      question?:
                          | {
                              answerOptions: string[];
                              correctAnswerIndex?: number;
                              questionType: "multiple_choice";
                              startPos: number;
                          }
                          | {
                              correctAnswer?: {
                                  artist: string;
                                  audioURL: string;
                                  cover: string
                                  | null;
                                  hrefURL: string;
                                  name: string;
                              };
                              pickerId: string;
                              questionCount: number;
                              questionCurrent: number;
                              questionType: "player_picks";
                              startPos: number;
                          };
                      roundCurrent: number;
                      type: "round_state";
                  }
                  | {
                      songs: {
                          artist: string;
                          audioURL: string;
                          cover: string
                          | null;
                          hrefURL: string;
                          name: string;
                      }[];
                      type: "update_played_songs";
                  }
                  | {
                      entry: LogEntry;
                      level: "error"
                      | "info"
                      | "warn"
                      | "debug";
                      type: "add_log_message";
                  }
                  | { messages: LoggerStorage; type: "update_log_messages" }
                  | { duration: number; offset: number; type: "progressbar_update" }
                  | { type: "other" };
              type: "confirmation";
          }
          • Optionalerror?: string

            Optional error message if the requested action could not be performed.

          • sourceMessage:
                | { action: "load"; audioURL: string; type: "audio_control" }
                | {
                    action:
                        | "play"
                        | "pause"
                        | "play_countdown_running"
                        | "play_countdown_end";
                    type: "audio_control";
                }
                | { type: "change_username"; username: string }
                | {
                    playlists: {
                        cover: string | null;
                        hrefURL: string;
                        name: string;
                        songs: {
                            artist: string;
                            audioURL: string;
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                        }[];
                        subtitle?: string;
                    }[];
                    type: "add_playlists";
                }
                | { index: number
                | null; type: "remove_playlist" }
                | {
                    advancedSongFiltering: boolean;
                    audioStartPosition: number;
                    distractionsPreferSameArtist: boolean;
                    endWhenAnswered: boolean;
                    gameMode: "multiple_choice" | "player_picks";
                    playerPickTimeout: number;
                    roundsCount: number;
                    timePerQuestion: number;
                    type: "room_config";
                }
                | { type: "start_game" }
                | { answer?: string; answerIndex?: number; type: "select_answer" }
                | { type: "return_to"; where: "lobby" | "results" }
                | { playerName: string; type: "transfer_host" }
                | {
                    song: {
                        artist: string;
                        audioURL: string;
                        cover: string | null;
                        hrefURL: string;
                        name: string;
                    };
                    startPos: number;
                    type: "player_pick_song";
                }
                | {
                    players: Record<
                        string,
                        {
                            answerData?: {
                                answer?: string;
                                answerIndex?: number;
                                answerSpeed: number;
                                answerTimestamp: number;
                                questionPoints: number;
                            };
                            color: string;
                            isHost: boolean;
                            isSpectator: boolean;
                            points: number;
                            username: string;
                        },
                    >;
                    state: "lobby"
                    | "results"
                    | "ingame";
                    type: "room_state";
                    uuid: string;
                    version: string;
                }
                | {
                    filteredSongsCount: number;
                    playlists?: {
                        cover: string
                        | null;
                        hrefURL: string;
                        name: string;
                        songs: {
                            artist: string;
                            audioURL: string;
                            cover: string | null;
                            hrefURL: string;
                            name: string;
                        }[];
                        subtitle?: string;
                    }[];
                    type: "update_playlists";
                }
                | { countdown: number; type: "countdown" }
                | {
                    gamePhase: GamePhase;
                    question?:
                        | {
                            answerOptions: string[];
                            correctAnswerIndex?: number;
                            questionType: "multiple_choice";
                            startPos: number;
                        }
                        | {
                            correctAnswer?: {
                                artist: string;
                                audioURL: string;
                                cover: string
                                | null;
                                hrefURL: string;
                                name: string;
                            };
                            pickerId: string;
                            questionCount: number;
                            questionCurrent: number;
                            questionType: "player_picks";
                            startPos: number;
                        };
                    roundCurrent: number;
                    type: "round_state";
                }
                | {
                    songs: {
                        artist: string;
                        audioURL: string;
                        cover: string
                        | null;
                        hrefURL: string;
                        name: string;
                    }[];
                    type: "update_played_songs";
                }
                | {
                    entry: LogEntry;
                    level: "error"
                    | "info"
                    | "warn"
                    | "debug";
                    type: "add_log_message";
                }
                | { messages: LoggerStorage; type: "update_log_messages" }
                | { duration: number; offset: number; type: "progressbar_update" }
                | { type: "other" }

            The message that is being confirmed.

          • type: "confirmation"
        • { seq: number; type: "ping" }
          • seq: number

            The sequence number the pong should respond with

          • type: "ping"
        • { seq: number; type: "pong" }
          • seq: number

            The sequence number asked for in the ping packet.

          • type: "pong"
      • log: boolean = true

        Whether to log the sended message

      Returns void

    • (Re-)Schedules a one-time or recurring event.

      Parameters

      • id: "cleanup" | "host_transfer"

        The unique identifier for the event.

      • runAfter: number

        The time (in milliseconds) after which the event should execute.

      • repeatMs: number | null = null

        The repetition interval in milliseconds, or null if one-time.

      Returns Promise<void>

    • (Re-)Schedules a host transfer to another player after ROOM_HOST_TRANSFER_TIMEOUT seconds.

      Returns Promise<void>

    • Establish this server's name and trigger onStart().

      Use cases:

      1. Framework-level bootstrap of DOs where ctx.id.name is undefined — e.g. DOs addressed via idFromString() / newUniqueId(). setName() stashes the name in memory and persists it under __ps_name so cold-wake invocations recover it via #ensureInitialized()'s legacy fallback.
      2. Delivering initial props to onStart() via the optional second argument.

      For DOs addressed via idFromName() / getByName(), calling setName() is redundant — this.name is available automatically from ctx.id.name. The normal initialization path also persists a fallback record so old-compat alarm handlers can recover the name. Throws if name does not match ctx.id.name.

      Not appropriate for facets. Cloudflare Agents and any other framework using ctx.facets.get(...) should pass an explicit id in FacetStartupOptions so the facet has its own ctx.id.name:

      const stub = ctx.facets.get(facetKey, () => ({
      class: ChildClass,
      id: ctx.exports.SomeBoundDOClass.idFromName(facetName),
      }));

      Without an explicit id, the facet inherits the parent DO's ctx.id (including ctx.id.name), and setName() will throw the ctx.id.name-mismatch error because the facet's intended name differs from the parent's. See https://developers.cloudflare.com/dynamic-workers/usage/durable-object-facets/ for the FacetStartupOptions.id semantics.

      Parameters

      • name: string
      • Optionalprops: Record<string, unknown>

      Returns Promise<void>

      for callers that address DOs via idFromName() / getByName(). Still the supported API for framework-level bootstrap of header/newUniqueId-addressed DOs and for delivering initial props to onStart().

    • Execute SQL queries against the Server's database

      Type Parameters

      • T = Record<string, string | number | boolean | null>

        Type of the returned rows

      Parameters

      • strings: TemplateStringsArray

        SQL query template strings

      • ...values: (string | number | boolean | null)[]

        Values to be inserted into the query

      Returns T[]

      Array of query results

    • Parameters

      • ws: WebSocket
      • code: number
      • reason: string
      • wasClean: boolean

      Returns Promise<void>

    • Parameters

      Returns Promise<void>

    • Parameters

      Returns Promise<void>