Music Playlists


Back

How the Lua Code Calls Songs in a Playlist

Lua code from the xar package can call
ga_play_playlist("xar_small_yellow_flower")
for example. The system then looks for a playlist called "xar_small_yellow_flower". That is, it looks for a folder called xar_small_yellow_flower in a subdirectory of one of the following places: Actually, it can also search (in the subdirectories) of the Music folders in any package that xar depends on.

Lua code from any other package X can do the same. We just ask that the playlists that package X calls all start with the X prefix.

Once the playlist folder is found, a song from the playlist is played. If that folder is empty, it plays a song from the parent folder. If the parent folder is empty, then it uses the parent's parent, etc. That is, playlists are hierarchical. Theoretically you can arrange this hierarchy any way you want if you want to customize it (and/or do something really weird). For example, if you are committed to having at least one song in every playlist, you could have a flat hierarchy.

For example, suppose that the Music directory has a folder named xar_ying_world, and that has two subdirectories xar_small_yellow_flower and xar_jumbo_yellow_flower. You might consider putting one song into all three. Then where you are in the Ying World determines which songs are played, and each area has its signature song. Or you could put all three songs just into the top directory xar_ying_world. Then the music would be the same no matter where you go, but it would be a longer playlist.

Displaying the Current Song and Playlist in Game

If in the program you go to OPTIONS -> SYSTEM_HUD -> SIDE_DISPLAYS, you can turn on the displays called "Music Song" and "Music Playlists", which will during the game display the name of the current song being played by the playlist system as well as the name of the current playlist being played. If the playlist is displayed as the color red, that means it cannot be found.

If you do not have these for some reason, here are the playlist and song display scripts. Just download these files and place them in the directory "Input/HUD/SideDisplays".

Xar Empty Playlist Download

Here is the empty hierarchical music package for the Ying World. You can add .ogg and .mp3 music files to this to have them be played in your game. Read the Readme.txt file in the download for how to install it.

Note that if you rename the downloaded folder to "xar" and if you place it in Input/Packages, then when you start a game that uses the xar package, your music will be played.

If on the other hand you already have a package called Input/Packages/xar, then instead rename the downloaded package to xar_music_test, put it in Input/Packages, then go to Input/Packages/xar/dependencies.txt and add the following to this file:
wf __USER__xar_music_test

How Xar Chooses Which Playlist to Play

The Lua script
Data/Packages/xar/Game/game_music.lua
calls the function ga_play_playlist and thereby picks which playlist to play at any given time. Here is part of the code:
--Local data structures.
local initialized = false
local bt_to_playlist = {}

function p.add(bt, playlist)
    bt_to_playlist[bt] = playlist
end

--Will play a music, unless it is already being played.
function p.try_play_music_playlist(playlist_name)
    ga_play_playlist(playlist_name)
end

function p.play_music_maybe()
    p.init_maybe();

    local player_level = ga_get_viewer_level()
    local level = player_level - 1
    while(level >= 0) do
        local bt = ga_get_cocoon_block_of_chunk(level, std.bp(0,0,0))

        local new_playlist_name = bt_to_playlist[bt]
        if( new_playlist_name ~= nil ) then
            p.try_play_music_playlist(new_playlist_name)
            return
        end

        level = level - 1
    end
end

function p.init_maybe()
    if( initialized ) then return end
    initialized = true

    --Initializing the table.
    p.add("YW_2",                       "xar_ying_world") --The big ying shell.
    p.add("SMALL_YELLOW_FLOWER_ROOM",   "xar_small_yellow_flower")
    p.add("SMALL_CANNON_PYRAMID",       "xar_small_cannon_pyramid")
     
    --...
end
Let us digest what this code does. It is associating certain block types to playlists. Call such chunks "music nodes". The function p.play_music_maybe looks for the finest chunk which contains the player which is a music node, and it plays the associated playlist. However there is one catch: it ignores the finest chunk containing the player. That is, the first chunk it considers is the parent chunk of the chunk containing the player.

If you really wanted to do a different association of block types to playlists, you could do the following: Create your own game_music.lua file and put it in the Input/Packages/xar/Game folder. This would override the game_music.lua file in the Data/Packages/xar/Game folder.

Note that if you are making your own package from scratch, you may want to have a similar game_music.lua file in your Game directory of your package.

What if Path Names are Too Long?

Recall that if there is no music in a playlist folder in a mod, the system will use the parent folder as a playlist. There is a problem here because Windows limits the lengths of path names. So you have the following alternative: a playlist folder (which say is called F) can have a file called parent.txt which contains the name of the playlist which is to be played if the playlist F has no music in it.

Let us do an example. Suppose that the Music folder contains the folder A (which is therefore a playlist). Suppose that A contains the two subfolders B and C (which therefore are also playlists). Normally if B has no music files in it, then A will be used instead when the system tries to play B. However suppose that B contains a file called "parent.txt" (the spelling is important) which reads as follows:
C
Then if B has no music files in it, then C will be used instead when the system tries to play B.

Importing Songs From Other Playlists

Here is a feature added in 1.01.30. If your playlist has a file called import.txt, then all playlists listed in that file will be added to the current playlist. Specifically, the songs that are "locally" within those playlists will be added. For example, if the import.txt file is the following:
classic_rock
jazz
then all songs that are in those two playlists (not recursively) will be added to the current playlist.

Possible Song Choices for the Ying World

Here is can example of some songs you could use for the xar_ying_world directory. We are basically using the approach of one song per playlist. We are just listing the song names, not providing them. Some of these songs have words in them. You may want to stick to songs with no words.
xar_ying_world           -> Ray Lynch - Here and Never Found
xar_large_cannon_pyramid -> Mt Eden - Still Alive
xar_small_black_flower   -> Dan Deacon - Snookered
xar_small_cannon_pyramid -> Deadmau5 - Ghosts 'n Stuff (Instrumental)
xar_jumbo_yellow_flower  -> Alan Walker - The Spectre (Instrumental)
xar_small_yellow_flower  -> Dan Deacon - Woof Woof
xar_tutorial             -> Deadmau5 - Hit Save
xar_happy_land           -> Deadmau5 - HR 8938 Cephei
xar_happy_land_main      -> Rednex - Cotton Eye Joe
xar_ying_world_chambers  -> Deadmau5 - Ghosts 'n Stuff (Instrumental)
xar_noob_maze            -> EMPTY (will default to xar_ying_world_chambers).
xar_unremembered_tower   -> VAC - Ghost in the Circuit
xar_ying_cave_island1    -> VNV Nation - Perpetual
xar_ying_cave_island5    -> VNV Nation - Illusion (Andy Huang)
xar_ying_flower          -> Queen - We Will Rock You
xar_ying_forest          -> Ray Lynch - No Blue Thing
xar_forest_air           -> Ray Lynch - Clouds Below Your Knees
Note that xar_jumbo_yellow_flower is a subfolder of xar_small_cannon_pyramid. There are other cases of folders being subfolders of each other.

There are several sounds for non Ying World places that appear in the Ying World, so we will list some of them as well:
xar_sponge               -> Deadmau5 - Clockwork
xar_quicksand_grass      -> Alan Walker - Faded (Nightcore)
xar_boss                 -> FFVII Boss Remake