December 15, 2017, 11:42:08 PM
News: Hey, we have forums!
  Pages: [1] 2
Print
Author Topic: Guide to Creating New Songs  (Read 28218 times)
Edwards
Bit Bit
****
Posts: 93


vernagovi
View Profile
« on: January 10, 2009, 07:13:48 AM »

This stuff is currently all over a couple other threads, but I figured it might be a good idea to put it all in one place, nicely labelled, in case of future forum searches (Hi there, future mod-makers! Tongue ). [EDIT] I guess pinning it would also work.  Thanks!

- Edwards


Guide to Creating New Songs
To create a new song, you will need three files:
1) An xml file, named "songs.xml", which will contain the notes and other non-scripting information for your song.
2) A lua script, named "songs.lua", which will contain the scripts for all new songs you have.
3) An image file, which will contain the symbol to show up when the song is sung.


Part I: songs.xml

The file should be placed directly in the scripts folder of your mod.  If you wish to see an example of a songs.xml file, one is located in the "data" subfolder of the game's data folder.  The file has a very simple structure: it consists of a series of Song tags, each of which is formatted as detailed below:

Format of a Song tag:
<Song idx="1" vox="Naija_Song_EnergyForm" slot="2" name="Energy Form" notes="7 6 5" script="0"/>

  • idx: An arbitrary number to identify your song.  This number is used for learning songs with learnSong(), and is the number passed when castSong() is called (see below).  The indices 0-15 are used by the existing songs.
  • vox: The name of the audio and subtitle file to be played when the song is clicked on in the pause screen.  Both the sound file and the text file must be directly in the sounds folder of your mod (this will correctly override any existing sound or text files with the same name).  Note that although a sound file without subtitles will work, in order to display subtitles, you need to have a sound file (note that any sound file will work).
  • name: The name that shows up on the right when the song is moused over in the pause screen.  This can include line breaks, although I do not recommend it, as the text is not vertically centered (two lines looks a bit odd, and more will overflow into other areas of the pause screen).
  • slot: This determines both where on the list on the pause screen the song appears, and what image is displayed when the song is sung.  Songs in slots 0-9 will appear on the menu, and can be sung using the number keys on the keyboard (although be warned that if you attempt to add a new image for these slots, or slot 10, you will need to either call reloadTextures() in your mod-init.lua file, or add the a Properties tag with a recache attribute set to "1" to the mod's xml file, or else the new images will not show up).  Songs in slots 10 and up will not appear on the menu, and will not have keyboard hotkeys, although they will still work if you sing them normally.  There is some order to the positioning of the slots on the menu screen (see following image for the nominal layout), but when you add new songs in the existing slots 0-9, the ordering can become very messed up- I've even seen songs with different slots stacked on top of each other.
  • notes: This is the song itself.  The notes are numbered from 0 to 7, starting at the bottom and running counter-clockwise (see image below).  Songs can be as long as you want, as far as I can tell (I've set up Happy Birthday with no ill effects).
  • script: If the content of this tag is "1", then the game will call castSong() in songs.lua when the song is sung.


Part II: songs.lua

This file should be placed directly in the scripts folder of your mod.  It should contain a function called castSong(), which will be called with the idx of the sung song as an argument.  The file can contain as many helper functions as you wish.  Note that it is re-compiled every time a song is sung that calls castSong(), so it likely will not work to try to make the script have persistent variables (I have not tested this, though).

Example of songs.lua:
function castSong(songIdx)
   if songIdx == 100 then
      -- Script for song 100
   elseif songIdx == 101 then
      -- Script for song 101
   end
   -- If song 102 is played, nothing happens
end



Part III: songslot-*.png

This image file should be a 128x128 png image with a transparent background, named songslot-X.png, where X is the number of the slot this image is associated with (so images should be named songslot-1.png, songslot-35.png, etc.).  The file should be placed in the graphics/song directory of your mod.  Once again, be warned that if you attempt to replace the existing songslot images (for slots 0-10), you will need to force the game to reload all of its cached images either by calling reloadTextures() in mod-init.lua, or by adding a Properties tag to your mod's xml file, with the attribute recache="1" (i.e. <Properties recache="1"/>).  Be further warned that if someone loads a saved game for your mod from the main title screen, the images will not be recached (as of version 1.1.1), so you may want to warn players to only load saved games from your mod's title screen.


Part IV: Tips

My suggestion for creating a new song is to simply play around with the note wheel until you find a 3-5 note sequence that sounds good (and is fairly easy to play, if it's a song that the player will be using often), write it down, and then keep going.  When you have a good set of note sequences, check them against the incorrect note behavior listed below, and select a handful that are clearly distinct from each other and whichever of the pre-existing songs you are keeping.

Behaviour of incorrect notes in the song system:
- There can be any number of incorrect notes before the first correct note.
- There can be up to two wrong notes between a pair of consecutive notes.
- There is no limit on the total number of wrong notes allowed.
- The last note must not be wrong.

Priority seems to be placed on the song sung that is closest to correct.  For example, try combining the shield and bind songs in various ways, or the fish and nature forms.  However, I have run into some issues when mod-added songs are similar to the built-in songs, with the built-in song overriding the new song even if it had a wrong note, and the new song did not (note: this may be an index issue instead, or something else entirely- I have not doe detailed testing).  So, when designing your songs, try to ensure that as few as possible end on the same note (especially the same last note as a built-in song), and if they do end on the same note, make sure that the preceding few notes have as little in common as possible.
« Last Edit: January 11, 2009, 08:18:24 PM by Edwards » Logged

You should only need one canister shell to bag your deer using your howitzer, but assemble more than one if  you have a mind to.1
Alec
Administrator
Dream Bit
**********
Posts: 2211



View Profile Email
« Reply #1 on: January 10, 2009, 12:33:57 PM »

Awesome, great work! Smiley
Logged

Danger Mouse
Hero Bit
*********
Posts: 624


Shush.

3302048 dmousefan dangermouse
View Profile WWW
« Reply #2 on: January 10, 2009, 06:19:08 PM »

OUTSTANDING!! THANK YOU!!!

Alec: Can we TAC this one up to the top threads for the Modding section?
Logged
Chibi
Dream Bit
**********
Posts: 1443


Deus Ex Aquaria


View Profile WWW
« Reply #3 on: January 10, 2009, 09:22:29 PM »

Definitely sticky this thread - people who take the effort to consolidate all the information into one post are forum gods.  Grin Good work, Edwards!
Logged


Life is a sexually transmitted disease with a 100% mortality rate. [Click the signature for +1 health!]
Danger Mouse
Hero Bit
*********
Posts: 624


Shush.

3302048 dmousefan dangermouse
View Profile WWW
« Reply #4 on: January 10, 2009, 11:14:57 PM »

Thank you Alec, and yes, thank you again Edwards!
Logged
Guy
Bit Bit
****
Posts: 62


View Profile
« Reply #5 on: January 10, 2009, 11:22:50 PM »

Nice work Edwards Smiley. Have you added this to the wiki? Also, do you know if the SONG entries in entityinclude.lua have any relevance?
Another point about the behaviour of incorrect notes (though it may not be relevant): You can play as many incorrect notes as you like at the start, before playing the correct song.
« Last Edit: January 10, 2009, 11:26:53 PM by Guy » Logged
Edwards
Bit Bit
****
Posts: 93


vernagovi
View Profile
« Reply #6 on: January 11, 2009, 08:16:10 PM »

Nice work Edwards Smiley. Have you added this to the wiki? Also, do you know if the SONG entries in entityinclude.lua have any relevance?
I'll add it to the wiki as soon as I have an internet connection long enough to do so, unless someone beats me to it.  As for the SONG_WHATEVER entries in entityinclude.lua, they're just constants containing the indices of the built-in songs.  No real need to change or add to them, but if you're replacing (not recommended!) or adding several songs, it may be a good idea to do so.  That way, existing scripts will break loudly instead of silently if they refer to a replaced song, and you'll be able to have a mnemonic to remember, rather than a random number.  Unfortunately, my attempts to change entityinclude.lua have only occasionally been reflected in files that reference it.  I haven't worked out exactly what's going on there (it may just be a caching issue), but I'm not recommending this in the guide until I know that entityinclude.lua can be reliably modified.

Another point about the behaviour of incorrect notes (though it may not be relevant): You can play as many incorrect notes as you like at the start, before playing the correct song.
Good point.  That would be relevant in some cases, so I'll add it.

@Everyone: You're welcome.  *bows*

@Alec: Thanks for pinning this!

- Edwards
« Last Edit: January 11, 2009, 08:21:08 PM by Edwards » Logged

You should only need one canister shell to bag your deer using your howitzer, but assemble more than one if  you have a mind to.1
ryos
Bit Bit
****
Posts: 57


View Profile
« Reply #7 on: January 12, 2009, 02:39:46 AM »

Heh, I almost forgot that I still needed to enable uploads. That's done now, and in order to test that it works, I took the liberty of adding these images to the page you made on the Wiki.
Logged
Particlese
Bit Bit
****
Posts: 85



View Profile
« Reply #8 on: January 12, 2009, 11:45:25 PM »

Thanks a lot, Edwards, and excellent timing.  I was just beginning to experiment with this myself, mostly mimicking the files in the Guert mod and main data folders, but I couldn't get it to work.  Now I have some new stuff to play with.  Smiley
Logged
Tarami
Mini Bit
**
Posts: 8


View Profile
« Reply #9 on: February 24, 2009, 04:51:59 PM »

There's a "bug" (or a hack  Cheesy) related to songs - the one with the highest index will not raise script events. This is probably to hide Anima (the song in Sunken City) from showing up with effects and such. The simple workaround is to add a song to the end with a higher index than anything else;

<Song idx="200" name="placeholder" slot="200" notes="" vox=""/>
Logged
Edwards
Bit Bit
****
Posts: 93


vernagovi
View Profile
« Reply #10 on: February 27, 2009, 06:50:34 AM »

There's a "bug" (or a hack  Cheesy) related to songs - the one with the highest index will not raise script events. This is probably to hide Anima (the song in Sunken City) from showing up with effects and such. The simple workaround is to add a song to the end with a higher index than anything else;
I cannot replicate that (Mac version 1.1.0).  What version are you using, and can you send me a simple mod that demonstrates the problem?  This would explain the issues I had at one point with certain indices apparently not working, but I can't get the system to break now.

- Edwards
Logged

You should only need one canister shell to bag your deer using your howitzer, but assemble more than one if  you have a mind to.1
Tarami
Mini Bit
**
Posts: 8


View Profile
« Reply #11 on: February 27, 2009, 08:36:10 AM »

I'm running Win 1.1.1, but if it's for the reason I'm assuming it should be across all versions. Of course, I can't be sure it is for this exact reason; this is just the way it appears to me and the workaround I suggested above works (for me.)  Smiley

I'll investigate and post what I find, code if  I can reproduce the bug.
Logged
calebj
Bit
***
Posts: 28


View Profile Email
« Reply #12 on: November 17, 2009, 01:41:42 AM »

This is great, very helpful.  I want to make a song where it reloads the current map (I can get it to load a specific map).  Is there a code for getting the current map?  It would be helpful to have in a mod if you got to a place where you were stuck and didn't want to go through the whole dying sequence.
Logged
Kasofa
Bit
***
Posts: 16

A whale in a manger...


View Profile
« Reply #13 on: December 02, 2009, 12:57:29 AM »

Very good work, thanks for consolidating this, Edwards! If you're who I think you are, I'm pretty sure I saw you on the ASW forums.
Mainly hacking SKF4KA and EV Nova.
Impressive, I must say.

-K
Logged

(Har har puns.)
Edwards
Bit Bit
****
Posts: 93


vernagovi
View Profile
« Reply #14 on: December 20, 2009, 08:07:12 PM »

Sorry abut not noticing these posts for a couple of months- I was completely swamped with schoolwork until a couple days ago (you really don't want to see what my RSS reader looked like...).

This is great, very helpful.  I want to make a song where it reloads the current map (I can get it to load a specific map).  Is there a code for getting the current map?  It would be helpful to have in a mod if you got to a place where you were stuck and didn't want to go through the whole dying sequence.
I actually use this one a lot when testing new entity scripts:
-- Reload level (debug song)
elseif songIdx == 105 then
    loadMap(getMapName())


Very good work, thanks for consolidating this, Edwards! If you're who I think you are, I'm pretty sure I saw you on the ASW forums.
Mainly hacking SKF4KA and EV Nova.
Impressive, I must say.
Yep, that's me.  *Bows*

- Edwards
Logged

You should only need one canister shell to bag your deer using your howitzer, but assemble more than one if  you have a mind to.1
  Pages: [1] 2
Print
Jump to: