forum

[Skinning] unified textures

posted
Total Posts
10
This is a feature request. Feature requests can be voted up by supporters.
Current Priority: +0
Topic Starter
pixeldesu
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.

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

<?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>
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.

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.

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
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:
tree /a /f > tree.txt
Now 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.png
and NOT like this:
approachcircle.png
count1.png
count2.png
...because pasting the elements with newlines causes execution and then the cmd will open every file you pasted in it.
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.

Congratulations, you made your (first) own unified texture!
Bonus - Command for the complete "templateskin"-folder
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
Also, for bigger projects this could be made simpler with creating a batch file, which I won't explain here.

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>
So, what do you think about this idea, is it helpful or would it be annoying for you?
theowest
Seems pretty cool. It will be interesting to know how this could affect gameplay.
jemhuntr
this wouldn't affect gameplay ._.

good idea, tho. Why hasn't this been requested before?
About the cons:
1. If there's a tool to combine elements, it wouldn't be hard to make a tool to separate a unified texture.
2. The tool should do all the work, since it should be the one to make the xml files.
3. The unified texture should still have a lower file size compared to all those elements separated.

So basically, some programmer dude could just make a simple program for managing unified textures specifically for osu! purposes.
peppy
The only pro of this is performance. It doesn't help in any other way. And with a game like osu! performance is already well above necessary levels.

Also do keep in mind this will *not* help with load time, which is the one you apparently have issues with. This load time is due to the sheer amount of pixels being loaded. The only way to avoid this is using raw images (BMP etc.)
deadbeat
i prefer this request for sorting t/96865
karma_komodo
Also entering to the skin selection menu used to take me more than 10 seconds, and sometimes osu! crashed.
This has very little to do with loading a skin... its more an issue with loading the list of skins. The more skins you have, more time is needed to make the list.
The solution i made: renamed the Skins folder as SkinsOld and made a New Folder named Skins, and then copied there the skins i use the most.
5 pages of skins were reduced to only 1 and the loading time was almost instantaneous. :)
Tell me if this worked for you.
jemhuntr
The loading we're talking about here is per skin. Notice how osu! lags when you apply a skin (especially if it has a lot of elements)?
OsuMe65
.xml is pain in the ass, imo
Topic Starter
pixeldesu

OsuMe65 wrote:

.xml is pain in the ass, imo
Actually you can write it to another format if you'd like to, it just needs to be readable by the game.

And...pain in the ass? Imagine this with .ini-files:
UnifiedTextures as ini-Output
[UnifiedTextures]
// Sliderball elements
File= sliderball-0.png
x-position= x
y-position= y
width= a
height= b

File= sliderball-1.png
x-position= x
y-position= y
width= a
height= b
...
OsuMe65

pixeldesu wrote:

OsuMe65 wrote:

.xml is pain in the ass, imo
Actually you can write it to another format if you'd like to, it just needs to be readable by the game.

And...pain in the ass? Imagine this with .ini-files:
UnifiedTextures as ini-Output
[UnifiedTextures]
// Sliderball elements
File= sliderball-0.png
x-position= x
y-position= y
width= a
height= b

File= sliderball-1.png
x-position= x
y-position= y
width= a
height= b
...
(welp, for those who can't do some element sheets, then yes... it is pain)
Please sign in to reply.

New reply