Defining cell-specific playlists for Better Music System

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
Tools used in this tutorial

Required

This article gives a brief description, plus sample code, of how to create custom playlists based on side777's well-known Better Music System mod and how to make them play automatically inside specific cells.

It requires some basic knowledge of scripting (including OBSE functions), and also some basic experience with using Wrye Bash.

Why this article?[edit | edit source]

Side777's Better Music System (short: BMS) is probably the most sophisticated music extension mod for TES IV. It allows you to completely redefine your own in-game background music. It is very popular and thus used by many people, but, at the same time, its effect on background music mechanisms is quite intrusive. This may lead to conflicts whenever you want to make your own mod play specific background music as well, because BMS simply overrules any attempts to play music tracks in the traditional way (e.g. with StreamMusic), or with other music extensions (like Sound Commands or Enhanced Music and Control).

To deal with this, BMS offers the possibility to create a custom esp that defines BMS-compatible playlists for your own mod. BMS will recognize these playlists and "link" them with the desired cells or regions, and then explicitely play tracks from these playlists whenever the player character enters these cells or regions. This solution has not been documented so far, however, so this article was created to fill the gap.

This sample can't cover the full potential of BMS usage, of course! Instead, it is focused on a well-understandable, simple "standard situation":

In this tutorial, you will

  • create a new esp file which will be the "container" for your custom playlist
  • define a custom playlist for BMS (called YourPlaylist) inside this esp
  • declare this playlist as background music for a specific cell (YourCell) in your mod (YourMod.esp)
  • bundle everything together with your mod

If you want to learn how to combine this BMS-centric solution with other methods of playing background music (SoundCommands, Enhanced Music Controls, vanilla music), in order to make your own mods better compatible with different user systems, then read this tutorial: Playing custom background music

Step 1: Prepare your music files[edit | edit source]

Let's assume that you have two custom music tracks, called track01.mp3 and track02.mp3, that you want to be playing automatically in YourCell and that both belong to the same playlist called YourPlaylist.

In this case you must place these tracks at the following locations under the Oblivion directory:

Data\Music\YourPlaylist\track01.mp3
Data\Music\YourPlaylist\track02.mp3

Note that the folder YourPlaylist must match the name of the playlist. If you want to organize your playlists in subfolders, the name of the playlist would have to include the name of the parent and the subfolders, e.g.:

  • the folder Data\Music\YourPlaylist\YourCell1 would be reflected by a playlist called YourPlaylist\YourCell1
  • the folder Data\Music\YourPlaylist\YourCell2 would be reflected by a playlist called YourPlaylist\YourCell2

Once again, because this is crucial: The name of the playlists must always match exactly the folder structure under Data\Music!

Step 2: Create a new esp file for your playlist[edit | edit source]

This step is easy, because we can reuse working solutions! The whole thing has already been implemented successfully for several big mods. The best known among them are already included as separate esp files in the latest release of BMS:

  • Better Music System for Shivering Isles: BetterMusicSystem(SI).esp
  • Better Music System for Elsweyr: BetterMusicSystem(Elsweyr).esp

You don't need to care about the fact that these two define multiple playlists for whole regions at once, and not only one playlist for one cell. From our point of view, there is no difference between defining music for one or multiple cells, interior or exterior cells, or even for whole world spaces. The mechanism is the same.

You simply need to copy one of these two esps (we'll choose the SI version in this sample), and rename it to match your own mod's name:

=> Copy BetterMusicSystem(SI).esp to Oblivion's Data folder

=> Rename it to BetterMusicSystem(YourMod).esp

Step 3: Declare your mod as parent[edit | edit source]

What you need to do now is transform the renamed SI plugin for BMS into the specific BMS plugin for YourCell defined in YourMod.

In order to link your music to YourCell, this cell needs to be known by the BMS plugin. This is why you have to declare YourMod.esp as a "parent" for the BetterMusicSystem(YourMod).esp.

The best method to declare an esp as parent to another is to use Wrye Bash. This method is called ESP Mastering. Read the preceeding link to understand how it works. If you are familiar with the basics of Wrye Bash, it's just a matter of two or three mouse-clicks!

=> Open Wrye Bash and declare YourMod.esp as parent file to BetterMusicSystem(YourMod).esp

When this is done, BetterMusicSystem(YourMod).esp should now list YourMod.esp as a parent file in Wrye Bash's right window (YourMod.esp must be selected in the mod list tab in order to see it).

In addition, you can check this by loading BetterMusicSystem(YourMod).esp in TES CS. If the parent dependency is defined correctly, YourMod.esp will be loaded automatically together with it (more details are given in the next step). You must also be able to find YourCell in the list of cells after loading, otherwise you have definitely done something wrong in this step!

Step 4: Adjust the script code[edit | edit source]

This step may seem to be the hardest, especially if your are not so familiar with TES scripting and OBSE. But it's much easier as it seems, if you follow the instructions given below.

=> Open TES CS and load BetterMusicSystem(YourMod).esp

=> Open the Quest window and locate the quest called BMSSI

=> Rename this quest to BMSYourMod

=> Open the quest's script (it is currently named 1BMSShiveringIslesScript)

You should now see the following script code in the script editor. Don't let the long code confuse you! You will only have to change some very small parts in it, and then compile/save it again. Please note the sections highlighted in bold letters, because they are those to be replaced. In addition, the lines starting with ar_Insert BMSUser.CustomRegions... should be removed completely, because they unnecessarily consume slots for "Custom Region Playlists" (see "Step 6: Resolving common mistakes"):

SCN 1BMSShiveringIslesScript

short	fquestdelaytime
short	init
short	i
array_var	tempArray


BEGIN GameMode

	if ( init == 1 && BMS777.State == 77 && emcPlaylistExists "Ring" )
		let tempArray := ar_List ManiaRegion01, ManiaCoastline
		if ( emcPlaylistExists "SI\Mania" == 0 )								
			if ( emcCreatePlaylist "SI\Mania" "Data\Music\SI\Mania\*.*" )
				ar_InsertRange BMS777.CellRefArray 0 tempArray
				let i := ar_Size tempArray
				while ( i ) 
					let i := i - 1
					ar_Insert	BMS777.AssignedPlaylist 0  "SI\Mania"
				loop
				ar_Insert BMSUser.CustomRegions 0 "SI\Mania" ; THIS LINE SHOULD be REMOVED!!
			else
				Print "Playlist error: SI\Mania"
			endif
		endif
		let tempArray := ar_Null

		let tempArray := ar_List DementiaRegion, DementiaCoastline01
		if ( emcPlaylistExists "SI\Dementia" == 0 )								
			if ( emcCreatePlaylist "SI\Dementia" "Data\Music \SI\Dementia\*.*" )
				ar_InsertRange BMS777.CellRefArray 0 tempArray
				let i := ar_Size tempArray
				while ( i ) 
					let i := i - 1
					ar_Insert	BMS777.AssignedPlaylist 0 "SI\Dementia"
				loop
				ar_Insert BMSUser.CustomRegions 0 "SI\Dementia" ; THIS LINE SHOULD be REMOVED!!
			else
				Print "Playlist error: SI\Dementia"
			endif
		endif
		let tempArray := ar_Null

		if ( BMS777.Debug )
			ar_Dump BMS777.AssignedPlaylist
			ar_Dump BMS777.CellRefArray
			ar_Dump BMSUser.CustomRegions
		endif

		set init to -1
		set BMS777.CurrentCell to 1
		set BMS777.RegionTimer to 0
		PrintC "BetterMusicSystem: Shivering Isles added."
	endif

	if ( GetGameLoaded || init == 0 )
		set init to 1
		set fquestdelaytime to 1
	endif


END


Now you need to apply the following modifications:

  1. Rename the script to 1BMSYourModScript --> do not forget this, otherwise you will cause in-game conflicts with the BMS SI plugin (given that you use it)
  2. There are two equally structured sections in the code: One for Mania, one for Dementia. Remove the lower section related to Dementia, because we will need only one block for our single cell of interest.
  3. Replace the list of assigned regions (ManiaRegion01, ManiaCostline) with the name of your cell (YourCell) --> this assigns the new playlist to this single cell only. Note that you can also add a comma-separated list of more than 1 cell here, but be aware that the ar_List function can't take more than 10 references, otherwise (though the script will compile without error!) any more than that will be cut off (see "Step 6: Resolving common mistakes")! Most important of all: Do not add quotes around the cell names (see next Step 5 below for details)!!
  4. Replace all occurrences of SI\Mania by the name of your playlist (YourPlaylist') --> this defines the name of the playlist. Be aware that the name of the playlist must match the folder structure under Data\Music (as described above). This means that in your case your custom music tracks must be located under <Oblivion Directory>\Data\Music\YourPlaylist. Also, due to a restiction in EMC, Italic textany playlist name longer than 18 characters will crash the CS (see "Step 6: Resolving common mistakes")!
  5. Replace Shivering Isles by YourMod (this serves only for debugging messages).
  6. Leave any other parts of the code untouched!

In the end, the whole code should look like this:

SCN 1BMSYourModScript

short	fquestdelaytime
short	init
short	i
array_var	tempArray


BEGIN GameMode

	if ( init == 1 && BMS777.State == 77 && emcPlaylistExists "Ring" )
		let tempArray := ar_List YourCell
		if ( emcPlaylistExists "YourPlaylist" == 0 )								
			if ( emcCreatePlaylist "YourPlaylist" "Data\Music\YourPlaylist\*.*" )
				ar_InsertRange BMS777.CellRefArray 0 tempArray
				let i := ar_Size tempArray
				while ( i ) 
					let i := i - 1
					ar_Insert BMS777.AssignedPlaylist 0 "YourPlaylist"
				loop
				ar_Insert BMSUser.CustomRegions 0 "YourPlaylist"
			else
				Print "Playlist error: YourPlaylist"
			endif
		endif
		let tempArray := ar_Null

		if ( BMS777.Debug )
			ar_Dump BMS777.AssignedPlaylist
			ar_Dump BMS777.CellRefArray
			ar_Dump BMSUser.CustomRegions
		endif

		set init to -1
		set BMS777.CurrentCell to 1
		set BMS777.RegionTimer to 0
		PrintC "BetterMusicSystem: YourMod added."
	endif

	if ( GetGameLoaded || init == 0 )
		set init to 1
		set fquestdelaytime to 1
	endif


END

Now here we are. If you have done all the replacements, hit the Save button inside the script editor to compile the script. If you receive any compilation errors now, read following Step 6!

If everything compiles fine, save the esp.

Step 5: Restore parent[edit | edit source]

After saving BetterMusicSystem(YourMod).esp, the parent relationship with YourMod.esp will be lost! So you have to restore it, following Step 4.

Step 6: Resolving common mistakes[edit | edit source]

There are several common mistakes that either lead to compilation errors within TES CS, or (even worse!) to hidden errors that go unnoticed until you enter the game.

To avoid as many issues in advance, always double-check if you have obeyed the following rules:

  • The cell name, or the list of cell names, may never be embraced by quotes! I.e. the following would compile without errors, but it would be wrong:
let tempArray := ar_List "YourCell" ;(this is wrong!!!)

The reason for this is that the script needs to reference the cell itself here (as a reference), and not only its name as a string! If this line won't compile without quotes, then you have done something wrong in Step 3 (Declare your mod as parent). Repeat step 3, then open the esp in TES CS again and repeat steps 4 and 5.

  • Once you save BetterMusicSystem(YourMod).esp, the parent relationship with YourMod.esp will be lost (see Step 5)! If you forget to restore the parent before the next time you load it for editing in TES CS, the plugin won't be able to recognize YourCell anymore. In this case, repeat Step 5.
  • The playlist name (YourPlaylist) needs to be put in quotes in some of the occurrences. Cross-check thoroughly with the sample code listed above.
  • The ar_List function can't take more than 10 arguments, otherwise any more than those 10 will be ignored during runtime! This applies to OBSE version 18 or older. As of OBSE 19, this limit has been extended to 20 elements.
  • BMS can assign any playlist to any cell with the 'power of music' spell, even playlists from custom plugins. But there's a limit of 10 playlists! So you should always consider removing the line ar_Insert BMSUser.CustomRegions 0 "YourPlaylist" from your code to exclude playlists from the 'power of music' to save slots.
  • emcCreatePlaylist can only take playlist names as an argument that aren't longer than 18 characters. Any longer names will crash the CS!

Step 7: Integrating your BMS plugin with your mod[edit | edit source]

In general, there are two ways to include your custom BMS patch into your mod:

  1. Pack BetterMusicSystem(YourMod).esp together with YourMod.esp into your installation archive.
  2. Merge it into YourMod.esp

The first solution is easier, but if forces users of your mod to "waste" an additional plugin slot. This can only be considered an appropriate solution as long as your mod adds lots of spedial music to the game. However, If it just adds very few tracks, you should prefer the "merge" solution. The merging can be done with TES4Gecko or TES4Edit. It may be a bit challenging, because you cannot easily merge the esp with its own parent esp, as long as it directly references a cell from the parent! One possible workaround for this is to set the cell names in 1BMSYourModScript in quotes temporarily, then do the merge, then open the merged esp in TES CS and remove the quotes again.

Step 8: Interference with general BMS mechanisms[edit | edit source]

Once you have done everything as described above, there may still be some unexpected effects in-game, because BMS always tries to apply its own rules, based on what has been configured in BetterMusicSystem.ini. For instance, if the cell music type for YourCell is set to Public, and playlists for Night and/or Night-Public are enabled in BMS, this may override the custom cell music during nights. Changing the music type to Dungeon will avoid this, but there may be many other "conflicts" like this. Sometimes it's not easy to find a good solution. Always keep in mind that BMS is a big overhaul that is not only designed for overruling music up to some degree, but that this is exactly the reasons why people use it! So your aim should never be to overrule BMS in turn, at any rate, because this would lower the acceptance of your own mod! Just be creative!

See also[edit | edit source]