Skip to content

Conversation

@tibetiroka
Copy link
Member

Music format for the game, covering both the data format and the engine behaviour.

@tibetiroka tibetiroka added the enhancement New feature or request label Jul 24, 2025
Copy link
Contributor

@MCOfficer MCOfficer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some first thoughts. Obviously I haven't been part of the music thread at all, so some of these points may have been raised/addressed already.

- For the "combat" soundtrack, do the same but with the inverse "combative" `condition`.
- For each `track` that has both a "combat" and "relaxed" version, create a `variant`.

A `variant` is basically a pairing of two `tracks` that tells the engine "these are pretty much the same, don't fade them, just switch them out and keep playing from the same position". When the current `track` changes, their `variant` status is checked. If they are `variants`, there is no fade.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that the defining feature of a Variant is the ability to switch back and forth between tracks without resetting playback position, not the lack of fade. In fact, some amount of fade (~1s transition) might be a good idea.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having fade would simplify the code. I said "no fade" here as that's what the composers voted for, but I don't think it would make a huge difference.

Comment on lines +113 to +118
When the player enters a system with a music node defined, the following happens:
1. All normal `playlists` are treated as invalid.
2. The system's `track` is treated as if it were used in a single-`track` `playlist` - the only valid playlist.
3. The new playlist is chosen, which is inevitably the system's pseudo-`playlist`. All `variant`-related playback rules are adhered to as usual.
4. If the player stays in the system long enough for the `track` to finish, a new `playlist` is chosen - and as before, the only option is the system's music.
5. Upon leaving the system, the `playlist` becomes invalid as any other would. At this time, the standard `playlists` would no longer be treated as invalid, and would be chosen to replace the system's music.
Copy link
Contributor

@MCOfficer MCOfficer Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fair amount of complexity for upholding the old system. My latest impression (a good while ago) was that it was rarely used by plugin authors. Is the complexity worth it, or are you better off just abandoning the old system and ignoring music nodes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This basically boils down to "Are we in a system with music? Yes? Play that. No? Behave normally." Everything else is the normal behaviour of the system in that case, if the model in my head is accurate.

# Drawbacks
Having multiple music `layers` increases complexity and file I/O operations. It can also increase the number of audio output sinks used, though we can mix the music samples before sending them to the operating system if necessary.

As music is often streamed, there is no easy way to guarantee that an audio file begins playback immediately. Therefore there is no way to keep the foreground layers in sync with the background layer completely without using cached WAV samples. (The foreground layers are meant to provide ambience, not orchestral playback, so this is probably a non-issue.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until this point I was unsure what foreground layers are intended for, so you should probably move this explanation to the abstract.

That aside, the priorities of the proposed system strike me as strange. There's a a lot of capabilities for ambience - at first glance, more than necessary - yet I feel like there are a lot of benefits to a similar system for sounds that require syncing.

If an artist wants to create a more energetic variant, or one geared for combat, using only foreground layers that must not be anchored to the rythm seems prohibitively restrictive. They could still use the background layer, but that would mean having two almost-duplicate files, which undermines variants as a concept.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combat music would generally still need a different background layer from what I've seen so far, though I'm not a composer myself.

The latency issue can be fixed by having a caching layer for the music files, so we wouldn't need to wait for the files to load. This is a long-term goal for both images and sounds, but I didn't want to lock the music system behind it.

- As it isn't reasonable to expect every `track` to have a combat `variant`, the new approach enables playing dedicated combat music in scenarios where previously regular music would have been played. This is helped by moving the combat `variants` to another `playlist` from the file specification of `tracks`.
- `Tracks` can have multiple audio layers playing concurrently.
- This choice was made based on the results of the creator survey, and was not known at the time of the previous discussions.
- `Playlists` are now "play once", not "play forever". This fixes various issues where players could get stuck listening to the same few songs when many others were also available.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't fully align with what I'd expect from the common definition of a playlist. Perhaps there's a more fitting term?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a playlist without looping?

# Unresolved Questions
Should `variant` support more than two `tracks` for convenience? Is there a real need?

Should `playlists` have playback modes other than "shuffle"? Though we have experienced extensive issues with ordered playback, some other playback modes still might be viable.
Copy link
Contributor

@MCOfficer MCOfficer Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On that note: is shuffle defined as true random, or is there some bias against recently-played tracks? Bear in mind that tracks could be referenced in multiple playlists, so with true random it's possible to go from one playlist to another and getting the same track.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of this is in the penultimate unresolved question, but yeah, good point about the tracks being present in multiple playlists. It's not specified at the moment.

It's probably fine to just randomize the tracks for now, and leave the fancy mechanics for later, though.


Should `playlists` keep track of which of their `tracks` have been played, and only re-shuffle when they have all been played an equal number of times? How would this interact with `variant`-based `playlist` switching?

`Playlists` could have a `priority` node that allows forcibly terminating the current `playlist` in favor of another when its conditions become valid. This would simplify the condition setup for combat `playlists`, but would make it more difficult to control when these prioritized `playlists` would yield to the non-prioritized `playlists`. These are also more difficult to extend with plugins, as various plugin-made priority `playlists` could easily clash with each other. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That idea feels a lot like CSS !important, which if used by the base implementation, is bad news for extensibility. If the base game uses priority anywhere, plugins' playlists cannot gain priority over the base game's (short of overriding the playlist itself, i guess?). If you want to go that way, consider priority as an integer, where bigger = more important.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, integer priorities were the idea, but they could still clash with plugins... what we would really need is float priorities so you could always slot something in between two playlists, but WeightedList doesn't support that.

@tibetiroka
Copy link
Member Author

Further tweaks to the rfc based on MCO's comments:

  • The purpose of playlists, layers and variants was clarified
  • variant now supports any number of tracks
  • Caching foreground tracks is now recommended

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants