diff --git a/src/dehacked.c b/src/dehacked.c
index 37bd529504b18f06cef5631975997ec63532428c..9529486ae3dd239791490287df7a45ad4fd446a7 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -1950,6 +1950,63 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
 	(void)savesfxnames;
 }
 
+//yellowtd: readmusic: may be a clone but does its desired purpose c:
+static void readmusic(MYFILE *f, UINT16 num, const char *savemusicnames[])
+{
+	char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
+	char *word;
+	char *tmp;
+	INT32 value;
+
+	do
+	{
+		if (myfgets(s, MAXLINELEN, f))
+		{
+			if (s[0] == '\n')
+				break;
+
+			tmp = strchr(s, '#');
+			if (tmp)
+				*tmp = '\0';
+
+			value = searchvalue(s);
+
+			word = strtok(s, " ");
+			if (word)
+				strupr(word);
+			else
+				break;
+
+/*			if (fastcmp(word, "OFFSET"))
+			{
+				value -= 150360;
+				if (value <= 64)
+					value /= 8;
+				else if (value <= 260)
+					value = (value+4)/8;
+				else
+					value = (value+8)/8;
+				if (value >= -1 && value < sfx_freeslot0 - 1)
+					S_sfx[num].name = savesfxnames[value+1];
+				else
+					deh_warning("Sound %d: offset out of bounds", num);
+			}
+			else */if (fastcmp(word, "DUMMYVAL"))
+			{
+                
+				DEH_WriteUndoline(word, va("%d", S_music[num].dummyval), UNDO_NONE);
+				S_music[num].dummyval = value;
+			}
+			else
+				deh_warning("Music %d : unknown word '%s'",num,word);
+		}
+	} while (!myfeof(f));
+
+	Z_Free(s);
+
+	(void)savemusicnames;
+}
+
 /** Checks if a game data file name for a mod is good.
  * "Good" means that it contains only alphanumerics, _, and -;
  * ends in ".dat"; has at least one character before the ".dat";
@@ -3168,7 +3225,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 	//XBOXSTATIC actionf_t saveactions[NUMSTATES];
 	//XBOXSTATIC const char *savesprnames[NUMSPRITES];
 	XBOXSTATIC const char *savesfxnames[NUMSFX];
-
+	XBOXSTATIC const char *savemusicnames[NUMMUSIC];
+	
 	if (!deh_loaded)
 		initfreeslots();
 
@@ -3182,7 +3240,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
 	*/
 	for (i = 0; i < NUMSFX; i++)
 		savesfxnames[i] = S_sfx[i].name;
-
+		
+	for (i = 0; i < NUMMUSIC; i++)
+		savemusicnames[i] = S_music[i].name;
+		
 	gamedataadded = false;
 
 	// it doesn't test the version of SRB2 and version of dehacked file
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index 2c968218c6e0af332e1c194e0f42b9e1de64e913..d1bbf96e960c2b84b5ec21e6f2785029ede50ebc 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -52,6 +52,39 @@ const char *const sfxinfo_wopt[] = {
 	"flags",
 	NULL};
 
+
+//====================
+enum musicinfo_read {
+	musicinfor_name,
+	musicinfor_lumpnum,
+	musicinfor_data,
+	musicinfor_handle,
+	musicinfor_dummyval
+};
+const char *const musicinfo_ropt[] = {
+	"name",
+	"lumpnum",
+	"data",
+	"handle",
+	"dummyval",
+	NULL};
+
+enum musicinfo_write {
+	musicinfow_name,
+	musicinfow_lumpnum,
+	musicinfow_data,
+	musicinfow_handle,
+	musicinfow_dummyval
+};
+const char *const musicinfo_wopt[] = {
+	"name",
+	"lumpnum",
+	"data",
+	"handle",
+	"dummyval",
+	NULL};
+//====================
+	
 //
 // Sprite Names
 //
@@ -846,6 +879,116 @@ static int sfxinfo_num(lua_State *L)
 	return 1;
 }
 
+//////////////
+// MUS INFO //
+//////////////
+static int lib_getMusicInfo(lua_State *L)
+{
+	UINT32 i;
+	lua_remove(L, 1);
+
+	i = luaL_checkinteger(L, 1);
+	LUA_PushUserdata(L, &S_music[i], META_MUSICINFO);
+	return 1;
+}
+static int lib_setMusicInfo(lua_State *L)
+{
+	musicinfo_t *info;
+
+	lua_remove(L, 1);
+	info = &S_music[luaL_checkinteger(L, 1)]; // get the mobjinfo to assign to.
+	luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
+	lua_remove(L, 1); // pop mobjtype num, don't need it any more.
+	lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo.
+    
+    
+    
+	if (hud_running)
+		return luaL_error(L, "Do not alter musicinfo in HUD rendering code!");
+
+	lua_pushnil(L);
+	while (lua_next(L, 1)) {
+		enum musicinfo_write i;
+
+		if (lua_isnumber(L, 2))
+			i = lua_tointeger(L, 2) - 1; // lua is one based, this enum is zero based.
+		else
+			i = luaL_checkoption(L, 2, NULL, musicinfo_wopt);
+
+		switch(i)
+		{
+		case musicinfow_dummyval:
+			info->dummyval = (INT32)luaL_checkinteger(L, 3);
+			break;
+		default:
+			break;
+		}
+		lua_pop(L, 1);
+	}
+
+	return 0;
+}
+
+static int lib_musiclen(lua_State *L)
+{
+	lua_pushinteger(L, NUMMUSIC);
+	return 1;
+}
+
+// musicinfo_t *, field
+static int musicinfo_get(lua_State *L)
+{
+	musicinfo_t *music = *((musicinfo_t **)luaL_checkudata(L, 1, META_MUSICINFO));
+	enum musicinfo_read field = luaL_checkoption(L, 2, NULL, musicinfo_ropt);
+
+	I_Assert(music != NULL);
+
+	switch (field)
+	{
+	case musicinfor_dummyval:
+		lua_pushinteger(L, music->dummyval);
+		return 1;
+	default:
+		return luaL_error(L, "impossible error");
+	}
+	return 0;
+}
+static int musicinfo_set(lua_State *L)
+{
+	musicinfo_t *music = *((musicinfo_t **)luaL_checkudata(L, 1, META_MUSICINFO));
+	enum musicinfo_write field = luaL_checkoption(L, 2, NULL, musicinfo_wopt);
+
+	if (hud_running)
+		return luaL_error(L, "Do not alter S_music in HUD rendering code!");
+
+	I_Assert(music != NULL);
+
+	lua_remove(L, 1); // remove sfxinfo
+	lua_remove(L, 1); // remove field
+	lua_settop(L, 1); // leave only one value
+
+	switch (field)
+	{
+	case musicinfow_dummyval:
+		music->dummyval = luaL_checkinteger(L, 1);
+		break;
+	default:
+		return luaL_error(L, "impossible error");
+	}
+	return 0;
+}
+
+static int musicinfo_num(lua_State *L)
+{
+	musicinfo_t *music = *((musicinfo_t **)luaL_checkudata(L, 1, META_MUSICINFO));
+
+	I_Assert(music != NULL);
+	I_Assert(music >= S_music);
+
+	lua_pushinteger(L, (UINT32)(music-S_music));
+	return 1;
+}
+
 //////////////////////////////
 //
 // Now push all these functions into the Lua state!
@@ -893,7 +1036,18 @@ int LUA_InfoLib(lua_State *L)
 		lua_pushcfunction(L, sfxinfo_num);
 		lua_setfield(L, -2, "__len");
 	lua_pop(L, 1);
+	
+	luaL_newmetatable(L, META_MUSICINFO);
+		lua_pushcfunction(L, musicinfo_get);
+		lua_setfield(L, -2, "__index");
+
+		lua_pushcfunction(L, musicinfo_set);
+		lua_setfield(L, -2, "__newindex");
 
+		lua_pushcfunction(L, musicinfo_num);
+		lua_setfield(L, -2, "__len");
+	lua_pop(L, 1);
+	
 	lua_newuserdata(L, 0);
 		lua_createtable(L, 0, 2);
 			lua_pushcfunction(L, lib_getSprname);
@@ -944,6 +1098,21 @@ int LUA_InfoLib(lua_State *L)
 	lua_pushvalue(L, -1);
 	lua_setglobal(L, "S_sfx");
 	lua_setglobal(L, "sfxinfo");
+
+	lua_newuserdata(L, 0);
+		lua_createtable(L, 0, 2);
+			lua_pushcfunction(L, lib_getMusicInfo);
+			lua_setfield(L, -2, "__index");
+
+			lua_pushcfunction(L, lib_setMusicInfo);
+			lua_setfield(L, -2, "__newindex");
+
+			lua_pushcfunction(L, lib_musiclen);
+			lua_setfield(L, -2, "__len");
+		lua_setmetatable(L, -2);
+	lua_pushvalue(L, -1);
+	lua_setglobal(L, "S_music");
+	lua_setglobal(L, "musicinfo");	
 	return 0;
 }
 
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 9a42a888c6a63758ff007334c4aba02670cde8f1..074b585dffd4c81ff97c0353ab9ac092f9c02a2b 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -22,6 +22,7 @@ extern lua_State *gL;
 #define META_STATE "STATE_T*"
 #define META_MOBJINFO "MOBJINFO_T*"
 #define META_SFXINFO "SFXINFO_T*"
+#define META_MUSICINFO "MUSICINFO_T*"
 
 #define META_MOBJ "MOBJ_T*"
 #define META_MAPTHING "MAPTHING_T*"
diff --git a/src/sounds.c b/src/sounds.c
index c03d6cea25fc66558237903ea4bc1e52cefb0d7e..5d543fade1d2cb92e923dd0a7d24fe59ed1985e6 100644
--- a/src/sounds.c
+++ b/src/sounds.c
@@ -1532,14 +1532,17 @@ sfxinfo_t S_sfx[NUMSFX] =
 };
 
 char freeslotnames[sfx_freeslot0 + NUMSFXFREESLOTS + NUMSKINSFXSLOTS][7];
+char musicfreeslotnames[mus_frees0 + NUMMUSFREESLOTS][7];
 
-// Prepare free sfx slots to add sfx at run time
+// Prepare free sfx slots to add sfx at run time  (yellowtd: Include musics too~!)
 void S_InitRuntimeSounds (void)
 {
 	sfxenum_t i;
+	musicenum_t x;
 	INT32 value;
 	char soundname[7];
-
+	char musicname[7];
+	
 	for (i = sfx_freeslot0; i <= sfx_lastskinsoundslot; i++)
 	{
 		value = (i+1) - sfx_freeslot0;
@@ -1566,6 +1569,28 @@ void S_InitRuntimeSounds (void)
 		S_sfx[i].usefulness = -1;
 		S_sfx[i].lumpnum = LUMPERROR;
 	}
+	
+	for (x = mus_frees0; x <= mus_lstfre; x++)
+	{
+		value = (x+1) - mus_frees0;
+
+		if (value < 10)
+			sprintf(musicname, "fre00%d", value);
+		else if (value < 100)
+			sprintf(musicname, "fre0%d", value);
+		else if (value < 1000)
+			sprintf(musicname, "fre%d", value);
+		else
+			sprintf(musicname, "fr%d", value);
+
+		strcpy(musicfreeslotnames[value-1], musicname);
+
+		S_music[x].name = musicfreeslotnames[value-1];
+		S_music[x].data = NULL;
+		S_music[x].lumpnum = 0;
+		S_music[x].handle = -1;
+		S_music[x].dummyval = 0;
+	}
 }
 
 // Add a new sound fx into a free sfx slot.
@@ -1601,6 +1626,31 @@ sfxenum_t S_AddSoundFx(const char *name, boolean singular, INT32 flags, boolean
 	return 0;
 }
 
+musicenum_t S_AddMusic(const char *name, INT32 dummyval)
+{
+	musicenum_t i, slot;
+
+	slot = mus_frees0;
+
+	for (i = slot; i < NUMMUSIC; i++)
+	{
+        //Dummy value because no .priority exists
+		if (!S_music[i].dummyval)
+		{
+			strncpy(musicfreeslotnames[i-mus_frees0], name, 6);
+			S_music[i].dummyval = dummyval;
+            S_music[i].handle = -1;
+			S_music[i].lumpnum = 0;
+
+			/// \todo if precached load it here
+			S_music[i].data = NULL;
+			return i;
+		}
+	}
+	CONS_Alert(CONS_WARNING, M_GetText("No more free music slots\n"));
+	return 0;
+}
+
 void S_RemoveSoundFx(sfxenum_t id)
 {
 	if (id >= sfx_freeslot0 && id <= sfx_lastskinsoundslot
diff --git a/src/sounds.h b/src/sounds.h
index ee1e60ba13ed373b35ae90b9bdc6abfe43dd2cf1..a2650b378b9cff5cabcd4a95f02c54a67a4ce72d 100644
--- a/src/sounds.h
+++ b/src/sounds.h
@@ -103,6 +103,11 @@ typedef struct
 
 	// music handle once registered
 	INT32 handle;
+	
+	//yellowtd: Music has no options unlike sfxinfo_t
+	//So we apply a dummy value for such
+	INT32 dummyval;
+	
 } musicinfo_t;
 
 // the complete set of sound effects
@@ -115,6 +120,8 @@ extern musicinfo_t S_music[];
 // Identifiers for all music in game.
 //
 
+#define NUMMUSFREESLOTS 800
+
 // Music list (don't edit this comment!)
 typedef enum
 {
@@ -1170,7 +1177,15 @@ typedef enum
 	mus_credit, // credits
 	mus_racent, // Race Results
 	mus_stjr,   // Sonic Team Jr. Presents
-
+	
+	//yellowtd: Freeslots for musics. The magic begins elsewhere
+	// free slots for S_AddMusic() at run-time --------------------
+	mus_frees0,
+	//
+	// ... 60 free musics here ...
+	//
+	mus_lstfre = mus_frees0 + NUMMUSFREESLOTS-1,
+	// end of freeslots ---------------------------------------------
 	NUMMUSIC
 } musicenum_t;
 // Note: song number should be a UINT16, as mapmusic only uses 16 bits for music slot number.