SongGuess
    Preparing search index...

    Hierarchy (View Summary)

    • Game
      • MultipleChoiceGame
    Index

    Constructors

    Properties

    currentQuestionIndex: number = -1

    The index of the current question. 0 based.

    gamePhase: GamePhase = GamePhase.PAUSE_MUSIC

    The current game phase

    hasPickingPhase: boolean = false

    Whether the game has a picking phase.

    isRunning: boolean = false

    Whether the game currently is running

    questions: MultipleChoiceQuestion[] = []

    The list of questions for the current game.

    questionStartTime: number = -1

    The timestamp when the current question started.

    questionTick: number = 0

    The current question round tick (in seconds).

    remainingSongs: {
        artist: string;
        audioURL: string;
        cover: string | null;
        hrefURL: string;
        name: string;
    }[] = []

    A list of songs still available for use in the next round. This pool is used to avoid repeating songs within a single game session.

    Type Declaration

    • artist: string

      The name of the song artist.

    • audioURL: string

      A URL to the audio file of the song. Currently only audio previews from Apple Music and SoundCloud are allowed.

    • cover: string | null

      Cover URL of the song.

    • hrefURL: string

      The URL users will be redirected to when clicking.

    • name: string

      The name of the song.

    room: ValidRoom
    roundCurrent: number = 0

    Current round number. 1 based.

    Accessors

    Methods

    • Ends the current game without returning to lobby and transitions to the results state.

      Parameters

      • sendUpdate: boolean = true

        whether to send an update that the game ended to the players.

      Returns void

    • Constructs an audio control load message.

      Parameters

      • action: "load"

        must be "load" for a load message.

      • OptionalaudioURL: string

        an ["audioURL"] to a music file that the client should preload.

      Returns
          | { action: "load"; audioURL: string; type: "audio_control" }
          | {
              action:
                  | "play"
                  | "pause"
                  | "play_countdown_running"
                  | "play_countdown_end";
              type: "audio_control";
          }

      a JSON string of the constructed AudioControlMessage

      • { 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"
    • Constructs an audio control message.

      Parameters

      • action: "play" | "pause" | "play_countdown_running" | "play_countdown_end"

        the ["action"] that should be performed.

      • OptionalaudioURL: undefined

        can only be provided for load action.

      Returns
          | { action: "load"; audioURL: string; type: "audio_control" }
          | {
              action:
                  | "play"
                  | "pause"
                  | "play_countdown_running"
                  | "play_countdown_end";
              type: "audio_control";
          }

      a JSON string of the constructed AudioControlMessage

      • { 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"
    • Should return an array of all required ServerMessages so clients know about the current game state.

      Parameters

      • OptionalsendPrevious: boolean

        whether to include all messages for the question. Useful when client joins.

      • Optional_player: Player

        an optional player that requested the game messages

      Returns (
          | { 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: (...) | (...);
                              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" }
      )[]

      • { 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: (...) | (...);
                            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: (...) | (...);
                          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"
    • Constructs a played songs update message with the songs played in the game.

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

      a JSON string of the constructed UpdatePlayedSongsMessage

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

        The songs that were played in this round.

      • type: "update_played_songs"
    • Generates a progress bar update message based on the current game phase.

      Returns { duration: number; offset: number; type: "progressbar_update" }

      ProgressbarUpdateMessage with duration, startAt, and elapsed time for the progress bar.

      • duration: number

        The duration of the progressbar.

      • offset: number

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

      • type: "progressbar_update"
    • Handles incoming client messages

      Parameters

      • player: Player

        the player that sent the message

      • msg:
            | { 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";
            }
            | {
                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 sent message

        • { type: "change_username"; username: string }
          • type: "change_username"
          • username: string

            The new username.

        • {
              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";
          }
          • playlists: {
                cover: string | null;
                hrefURL: string;
                name: string;
                songs: {
                    artist: string;
                    audioURL: string;
                    cover: string | null;
                    hrefURL: string;
                    name: string;
                }[];
                subtitle?: string;
            }[]

            The new playlist to add.

          • type: "add_playlists"
        • { index: number | null; type: "remove_playlist" }
          • index: number | null

            The playlist index to remove.

          • 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";
          }
          • 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"
        • { type: "start_game" }
        • { answer?: string; answerIndex?: number; type: "select_answer" }
          • Optionalanswer?: string

            Provided only for PlayerPicksGame. The string of the song name the player guessed.

          • OptionalanswerIndex?: number

            Provided only for MultipleChoiceGame. The index of the selected answer.

          • type: "select_answer"
        • { type: "return_to"; where: "lobby" | "results" }
          • type: "return_to"
          • where: "lobby" | "results"

            Where to send the player to.

        • { playerName: string; type: "transfer_host" }
          • playerName: string

            The name of the player that should get host.

          • type: "transfer_host"
        • {
              song: {
                  artist: string;
                  audioURL: string;
                  cover: string | null;
                  hrefURL: string;
                  name: string;
              };
              startPos: number;
              type: "player_pick_song";
          }
          • song: {
                artist: string;
                audioURL: string;
                cover: string | null;
                hrefURL: string;
                name: string;
            }

            The song the player picked in the choose step.

            • artist: string

              The name of the song artist.

            • audioURL: string

              A URL to the audio file of the song. Currently only audio previews from Apple Music and SoundCloud are allowed.

            • cover: string | null

              Cover URL of the song.

            • hrefURL: string

              The URL users will be redirected to when clicking.

            • name: string

              The name of the song.

          • startPos: number

            The selected start pos for the song.

            RoomConfigMessageSchema.audioStartPosition

          • type: "player_pick_song"
        • {
              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"

      Returns boolean

      whether the message was handled by this listener.

    • Save timestamp and answer, when user selects an answer.

      Parameters

      • player: Player

        the player that selected an answer.

      • msg: { answer?: string; answerIndex?: number; type: "select_answer" }
        • Optionalanswer?: string

          Provided only for PlayerPicksGame. The string of the song name the player guessed.

        • OptionalanswerIndex?: number

          Provided only for MultipleChoiceGame. The index of the selected answer.

        • type: "select_answer"

      Returns boolean