Quick answer: mixer.music.queue() only holds one next track. For playlists, use set_endevent(MUSIC_END) and queue the next song from the event handler.

A puzzle game queues several background tracks via mixer.music.queue() at startup. Only the second one plays. Loop never advances. The library accepts the calls without error but silently overwrites.

How queue() Actually Works

pygame.mixer.music.load('track1.ogg')
pygame.mixer.music.play()
pygame.mixer.music.queue('track2.ogg')
pygame.mixer.music.queue('track3.ogg')   # overwrites track2!

queue() doesn’t append — it replaces. Only the most recent queued track will follow the current one.

Build a Playlist Manager

MUSIC_END = pygame.USEREVENT + 1
pygame.mixer.music.set_endevent(MUSIC_END)

playlist = ['track1.ogg', 'track2.ogg', 'track3.ogg']
index = 0

pygame.mixer.music.load(playlist[index])
pygame.mixer.music.play()

while running:
    for event in pygame.event.get():
        if event.type == MUSIC_END:
            index = (index + 1) % len(playlist)
            pygame.mixer.music.load(playlist[index])
            pygame.mixer.music.play()

Music end event fires when current finishes. Load and play the next track.

Gapless via queue + endevent

For seamless transitions, combine: queue the next track for gapless playback, then in the end event queue the one after:

pygame.mixer.music.load(playlist[0])
pygame.mixer.music.play()
pygame.mixer.music.queue(playlist[1])
index = 1

if event.type == MUSIC_END:
    index = (index + 1) % len(playlist)
    pygame.mixer.music.queue(playlist[index])

queue() ensures the buffer overlap so playback is gapless. The end event handles further advancement.

Verifying

Start playback. Listen through several tracks. Order matches playlist. No gaps between tracks (with the gapless variant). Loop returns to track 1 after the last.

“Queue is one slot. For playlists, listen for the end event and advance manually.”

Beyond 3–4 tracks, use a real audio library like FMOD or OpenAL via PyOpenAL — better mixing, gapless, crossfade.