I had this idea in mind while playing around with the PSM-devsuite.
Let's say, great problems with skins/skinning at the moment are:
- Skin folder is kinda bloated with files (over 200 elements) and only sorted with names
- the skin-selection is quite buggy (and crashes) while loading
- Loading/Changing skins causes freezes
So, I had the idea of unified textures, which can cause less load of skin elements and a bit more sorting, but also some disadvantages, I'm going to explain everything down below with samples.
A example for a unified texture + xml-file:
Sorting with unified elements:
I'll take an code-snippet from my example to explain the easiest sorting method with unified textures.
With this, skinner could easily build their skins and leave elements they haven't finished yet (because you can just leave this value while creating) and the skinner could sort everything in folders (for gamemodes and stuff, like fonts in my example) if wanted to. So it would be sorted while making the skin and afterwards, when the skin is going to be released.
Reducing elements:
This is likely self-explaning. If you create a unified texture for each gamemode and maybe for ranks and fonts (or just place that under "gameplay", like osu! does at the moment) you'll get less files as before (reducing from +200 to around 20 with the xml-files included).
- Less files
- Reduces CPU/GPU load
- Possibility of better sorting
- Better managing of skin projects
// like I said before, Skinners are able to build their skins and release them with or without parts they want to, with all the above advantages
Contra:
- (Taking files from skins (for skin mixes for example) gets really hard and annoying)
- If implemented, it would be a lot of coding work
- the unified textures gets big (in size and resolution) really fast
It runs in a console and you need to specify all images in the --output argument.
Example:
Congratulations, you made your (first) own unified texture!
So, what do you think about this idea, is it helpful or would it be annoying for you?
Let's say, great problems with skins/skinning at the moment are:
- Skin folder is kinda bloated with files (over 200 elements) and only sorted with names
- the skin-selection is quite buggy (and crashes) while loading
- Loading/Changing skins causes freezes
So, I had the idea of unified textures, which can cause less load of skin elements and a bit more sorting, but also some disadvantages, I'm going to explain everything down below with samples.
unified textures
What are unified textures?
Unified textures are a set of multiple textures/images inside one, this is used by a lot of games, so loading is easier and not every image is loading single. Mostly these are generated with a tool, which drops out a additional file (in .xml-format) that contains every filename and specification of the images inside the unified texture.A example for a unified texture + xml-file:
Example - unified textures
As you see, the elements are declared in that xml-file, so any program could easily read them and render them into a game for example. Also, you don't need the original files in the skins then, just the unified textures are needed, because everything is in them.<?xml version="1.0" encoding="utf-8"?>
<root version="1.0">
<info w="512" h="256" />
<textures>
<texture filename="fonts/score-percent.png" x="0" y="0" w="57" h="60" />
<texture filename="fonts/default-4.png" x="58" y="0" w="50" h="54" />
<texture filename="fonts/score-9.png" x="58" y="55" w="45" h="60" />
<texture filename="fonts/score-4.png" x="0" y="61" w="45" h="60" />
<texture filename="fonts/score-3.png" x="104" y="55" w="44" h="60" />
<texture filename="fonts/score-8.png" x="149" y="55" w="43" h="60" />
<texture filename="fonts/default-8.png" x="109" y="0" w="47" h="54" />
<texture filename="fonts/default-5.png" x="157" y="0" w="47" h="54" />
<texture filename="fonts/default-6.png" x="193" y="55" w="47" h="54" />
<texture filename="fonts/score-5.png" x="193" y="110" w="42" h="60" />
<texture filename="fonts/default-3.png" x="58" y="116" w="46" h="54" />
<texture filename="fonts/default-2.png" x="104" y="116" w="46" h="54" />
<texture filename="fonts/score-2.png" x="151" y="116" w="41" h="60" />
<texture filename="fonts/score-0.png" x="0" y="122" w="41" h="60" />
<texture filename="fonts/default-x.png" x="205" y="0" w="44" h="54" />
<texture filename="fonts/score-6.png" x="58" y="171" w="39" h="60" />
<texture filename="fonts/score-x.png" x="98" y="171" w="39" h="60" />
<texture filename="fonts/default-7.png" x="151" y="177" w="43" h="54" />
<texture filename="fonts/default-9.png" x="195" y="177" w="43" h="54" />
<texture filename="fonts/score-7.png" x="0" y="183" w="38" h="60" />
<texture filename="fonts/default-percent.png" x="236" y="110" w="40" h="54" />
<texture filename="fonts/score-1.png" x="239" y="177" w="34" h="60" />
<texture filename="fonts/default-1.png" x="241" y="55" w="34" h="54" />
<texture filename="fonts/score-comma.png" x="39" y="183" w="19" h="60" />
<texture filename="fonts/score-dot.png" x="274" y="177" w="18" h="60" />
<texture filename="fonts/default-comma.png" x="250" y="0" w="19" h="54" />
<texture filename="fonts/default-dot.png" x="270" y="0" w="18" h="54" />
</textures>
</root>
Usage in osu!
Unified textures could make a lot of things simpler in osu!, like sorting skins and reducing the elements.Sorting with unified elements:
I'll take an code-snippet from my example to explain the easiest sorting method with unified textures.
<texture filename="fonts/score-dot.png" x="274" y="177" w="18" h="60" />As you see, the element score-dot.png is in a subfolder called fonts, where I generated the texture from. After the unified texture is generated, you don't have any folders, just one element and it's xml-file.
With this, skinner could easily build their skins and leave elements they haven't finished yet (because you can just leave this value while creating) and the skinner could sort everything in folders (for gamemodes and stuff, like fonts in my example) if wanted to. So it would be sorted while making the skin and afterwards, when the skin is going to be released.
Example - Sorting
The folders fonts, ranks and mania are the folders where the skin elements from the unified textures are originated.
The folders fonts, ranks and mania are the folders where the skin elements from the unified textures are originated.
Reducing elements:
This is likely self-explaning. If you create a unified texture for each gamemode and maybe for ranks and fonts (or just place that under "gameplay", like osu! does at the moment) you'll get less files as before (reducing from +200 to around 20 with the xml-files included).
Pro/Contra
Pro:- Less files
- Reduces CPU/GPU load
- Possibility of better sorting
- Better managing of skin projects
// like I said before, Skinners are able to build their skins and release them with or without parts they want to, with all the above advantages
Contra:
- (Taking files from skins (for skin mixes for example) gets really hard and annoying)
- If implemented, it would be a lot of coding work
- the unified textures gets big (in size and resolution) really fast
How can I make unified textures?
Unified textures are made with a little tool called UnifyTextures. You can get it here.It runs in a console and you need to specify all images in the --output argument.
Example:
{osu_path}\Skins\your skin\UnifyTextures.exe --output approachcircle.png hitcircle.png ...
Quick Tip - Arranging a list of all skin files
After you successfully entered all the elements to the argument and executed it, you'll get a image and a xml-document, these are the 2 main files of a unified texture.Because it would be really a lot of work to manually type all elements into the console, you can do a little trick here. It works like this:
1. Open a cmd and navigate to the skin folder you want to have all filenames from.
2. Enter following into the commandline:
Warning: Now you need to change the text a bit before pasting into the cmd!
1. Remove all newlines from the skinelement listing and replace them with one space only.
// That means you should list your elements like this:
1. Open a cmd and navigate to the skin folder you want to have all filenames from.
2. Enter following into the commandline:
tree /a /f > tree.txtNow you successfully generated a list with all your skinelements inside a tree.txt
Warning: Now you need to change the text a bit before pasting into the cmd!
1. Remove all newlines from the skinelement listing and replace them with one space only.
// That means you should list your elements like this:
approachcircle.png count1.png count2.pngand NOT like this:
approachcircle.png...because pasting the elements with newlines causes execution and then the cmd will open every file you pasted in it.
count1.png
count2.png
Congratulations, you made your (first) own unified texture!
Bonus - Command for the complete "templateskin"-folder
Also, for bigger projects this could be made simpler with creating a batch file, which I won't explain here.UnifyTexture.exe --output approachcircle.png button-left.png button-middle.png button-right.png comboburst.png count1.png count2.png count3.png cursor.png cursortrail.png default-0.png default-1.png default-2.png default-3.png default-4.png default-5.png default-6.png default-7.png default-8.png default-9.png default-comma.png default-dot.png default-percent.png default-x.png failbackground.png followpoint.png fruit-apple-overlay.png fruit-apple.png fruit-bananas-overlay.png fruit-bananas.png fruit-drop.png fruit-grapes-overlay.png fruit-grapes.png fruit-orange-overlay.png fruit-orange.png fruit-pear-overlay.png fruit-pear.png fruit-plate.png fruit-ryuuta.png go.png hit0.png hit100.png hit100k.png hit300.png hit300g.png hit300k.png hit50.png hitcircle.png hitcircleoverlay.png hitcircleselect.png lighting-0.png lighting-1.png lighting-10.png lighting-11.png lighting-12.png lighting-13.png lighting-2.png lighting-3.png lighting-4.png lighting-5.png lighting-6.png lighting-7.png lighting-8.png lighting-9.png lighting.png lightingL-0.png lightingL-1.png lightingL-2.png lightingL-3.png lightingL-4.png lightingL-5.png lightingL-6.png lightingL-7.png lightingL-8.png lightingL-9.png lightingN.png lobby-background.png mania-hit100.png mania-hit200.png mania-hit300.png mania-hit300g.png mania-hit50.png mania-key1.png mania-key1D.png mania-key2.png mania-key2D.png mania-keyS.png mania-keySD.png mania-note1.png mania-note1H.png mania-note1L-0.png mania-note1L-1.png mania-note1L-2.png mania-note1L-3.png mania-note1L-4.png mania-note1L-5.png mania-note2.png mania-note2H.png mania-note2L-0.png mania-note2L-1.png mania-note2L-2.png mania-note2L-3.png mania-note2L-4.png mania-note2L-5.png mania-noteS.png mania-noteSH.png mania-noteSL-0.png mania-noteSL-1.png mania-noteSL-2.png mania-noteSL-3.png mania-noteSL-4.png mania-noteSL-5.png mania-stage-hint.png mania-stage-left.png mania-stage-light.png mania-stage-right.png matchsetup-background.png menu-back.png menu-button-background.png pause-back.png pause-continue.png pause-overlay.png pause-retry.png pippidonclear0.png pippidonclear1.png pippidonclear2.png pippidonclear3.png pippidonclear4.png pippidonclear5.png pippidonclear6.png pippidonclear7.png pippidonclear8.png pippidonfail0.png pippidonfail1.png pippidonfail2.png pippidonidle0.png pippidonidle1.png pippidonkiai0.png pippidonkiai1.png play-skip.png play-unranked.png play-warningarrow.png playfield.png ranking-A-small.png ranking-A.png ranking-accuracy.png ranking-B-small.png ranking-B.png ranking-back.png ranking-C-small.png ranking-C.png ranking-D-small.png ranking-D.png ranking-graph.png ranking-maxcombo.png ranking-panel.png ranking-perfect.png ranking-replay.png ranking-retry.png ranking-S-small.png ranking-S.png ranking-SH-small.png ranking-SH.PNG ranking-title.png ranking-winner.png ranking-X-small.png ranking-X.png ranking-XH-small.png ranking-XH.png ready.png reversearrow.png score-0.png score-1.png score-2.png score-3.png score-4.png score-5.png score-6.png score-7.png score-8.png score-9.png score-comma.png score-dot.png score-percent.png score-x.png scorebar-bg.png scorebar-colour-0.png scorebar-colour-1.png scorebar-colour-2.png scorebar-colour-3.png scorebar-ki.png scorebar-kidanger.png scorebar-kidanger2.png search-background.png section-fail.png section-pass.png selection-mod-autoplay.png selection-mod-doubletime.png selection-mod-easy.png selection-mod-flashlight.png selection-mod-halftime.png selection-mod-hardrock.png selection-mod-hidden.png selection-mod-nightcore.png selection-mod-nofail.png selection-mod-novideo.png selection-mod-perfect.png selection-mod-relax.png selection-mod-relax2.png selection-mod-spunout.png selection-mod-suddendeath.png selection-mod-taiko.png selection-mods-over.png selection-mods.png selection-options-over.png selection-options.png selection-random-over.png selection-random.png selection-selectoptions-over.png selection-selectoptions.png selection-tab.png sliderb0.png sliderb1.png sliderb2.png sliderb3.png sliderb4.png sliderb5.png sliderb6.png sliderb7.png sliderb8.png sliderb9.png sliderfollowcircle.png sliderpoint10.png sliderpoint30.png sliderscorepoint.png special-fruits.png special-mania.png special-taiko.png spinner-approachcircle.png spinner-background.png spinner-circle.png spinner-clear.png spinner-metre.png spinner-osu.png spinner-rpm.png spinner-spin.png spinner-warning.png star.png star2.png taiko-bar-left.png taiko-bar-right-glow.png taiko-bar-right.png taiko-barline.png taiko-drum-inner.png taiko-drum-outer.png taiko-flower-group.png taiko-glow.png taiko-hit0.png taiko-hit100.png taiko-hit100k.png taiko-hit300.png taiko-hit300g.png taiko-hit300k.png taiko-hit50.png taiko-roll-end.png taiko-roll-middle.png taiko-slider-fail.png taiko-slider.png taikobigcircle.png taikobigcircleoverlay-0.png taikobigcircleoverlay-1.png taikohitcircle.png taikohitcircleoverlay-0.png taikohitcircleoverlay-1.png
Examples for more unified textures
Example - Mania-elements
<?xml version="1.0" encoding="utf-8"?>
<root version="1.0">
<info w="4096" h="2048" />
<textures>
<texture filename="mania/lightingL-6.png" x="0" y="0" w="480" h="480" />
<texture filename="mania/lightingL-9.png" x="481" y="0" w="480" h="480" />
<texture filename="mania/lightingL-7.png" x="0" y="481" w="480" h="480" />
<texture filename="mania/lightingL-8.png" x="481" y="481" w="480" h="480" />
<texture filename="mania/lighting-7.png" x="962" y="0" w="400" h="480" />
<texture filename="mania/lighting-6.png" x="962" y="481" w="400" h="480" />
<texture filename="mania/lighting-8.png" x="1363" y="0" w="400" h="480" />
<texture filename="mania/lighting-1.png" x="1363" y="481" w="400" h="480" />
<texture filename="mania/lighting-9.png" x="0" y="962" w="400" h="480" />
<texture filename="mania/lighting-13.png" x="401" y="962" w="400" h="480" />
<texture filename="mania/lighting-10.png" x="802" y="962" w="400" h="480" />
<texture filename="mania/lighting-11.png" x="1203" y="962" w="400" h="480" />
<texture filename="mania/lighting-12.png" x="1604" y="962" w="400" h="480" />
<texture filename="mania/lighting-3.png" x="0" y="1443" w="400" h="480" />
<texture filename="mania/lighting-4.png" x="401" y="1443" w="400" h="480" />
<texture filename="mania/lighting-2.png" x="802" y="1443" w="400" h="480" />
<texture filename="mania/lighting-5.png" x="1203" y="1443" w="400" h="480" />
<texture filename="mania/mania-hit300.png" x="1604" y="1443" w="256" h="256" />
<texture filename="mania/mania-hit300g.png" x="1764" y="0" w="256" h="256" />
<texture filename="mania/mania-hit50.png" x="1764" y="257" w="256" h="256" />
<texture filename="mania/mania-hit100.png" x="1764" y="514" w="256" h="256" />
<texture filename="mania/mania-hit200.png" x="1604" y="1700" w="256" h="256" />
<texture filename="mania/lightingL-2.png" x="1861" y="1443" w="192" h="192" />
<texture filename="mania/lightingL-1.png" x="1861" y="1636" w="192" h="192" />
<texture filename="mania/lightingL-0.png" x="1861" y="1829" w="192" h="192" />
<texture filename="mania/lightingL-3.png" x="2005" y="962" w="192" h="192" />
<texture filename="mania/lightingL-5.png" x="2005" y="1155" w="192" h="192" />
<texture filename="mania/lightingN.png" x="2021" y="0" w="192" h="192" />
<texture filename="mania/lightingL-4.png" x="2021" y="193" w="192" h="192" />
<texture filename="mania/mania-note2L-0.png" x="0" y="1924" w="256" h="82" />
<texture filename="mania/mania-note2L-1.png" x="257" y="1924" w="256" h="82" />
...
Example - Ranks
<?xml version="1.0" encoding="utf-8"?>
<root version="1.0">
<info w="2048" h="1024" />
<textures>
<texture filename="ranks/ranking-X.png" x="0" y="0" w="420" h="482" />
<texture filename="ranks/ranking-XH.png" x="421" y="0" w="420" h="482" />
<texture filename="ranks/ranking-A.png" x="0" y="483" w="370" h="482" />
<texture filename="ranks/ranking-D.png" x="371" y="483" w="370" h="482" />
<texture filename="ranks/ranking-SH.PNG" x="742" y="483" w="370" h="482" />
<texture filename="ranks/ranking-S.png" x="842" y="0" w="370" h="482" />
<texture filename="ranks/ranking-C.png" x="1113" y="483" w="370" h="482" />
<texture filename="ranks/ranking-B.png" x="1213" y="0" w="370" h="482" />
<texture filename="ranks/ranking-XH-small.png" x="1484" y="483" w="41" h="49" />
<texture filename="ranks/ranking-X-small.png" x="1526" y="483" w="41" h="49" />
<texture filename="ranks/ranking-S-small.png" x="1484" y="533" w="33" h="43" />
<texture filename="ranks/ranking-B-small.png" x="1518" y="533" w="33" h="43" />
<texture filename="ranks/ranking-C-small.png" x="1484" y="577" w="33" h="43" />
<texture filename="ranks/ranking-SH-small.png" x="1518" y="577" w="33" h="43" />
<texture filename="ranks/ranking-D-small.png" x="1484" y="621" w="33" h="43" />
</textures>
</root>