Post by djlastnight on Apr 8, 2013 18:33:05 GMT
You will need three programs:
- Autodesk's 3D Studio Max 2012 (3ds max) + direct x exporter
- Adobe's Photoshop CS6
- My PS XML Editor: dwsk.proboards.com/thread/2281/ps-theme-editor-windows-application
---------------------------------------------------------------------------------------------------------------------------------------
- Warning: Photoshop and 3ds max are shareware and you have to buy them or you can use similar freeware software. -
---------------------------------------------------------------------------------------------------------------------------------------
Static subfolder in any theme contains 3d models, textures and sound files (sfx).
If you want your theme to be good, you should create models from scratch for it.
You will learn how to create hardest of them - meters.
Phase shift have 7 meters: Meter Accuracy, Meter Chunk Bar, Meter Energy Bar, Meter Main, Meter Multiplier, Meter PS Bar 1, Meter PS Bar 2.
There are specific meters for real keys, that will not be discussed for now.
All of this meters uses 3d model file, that define their place, shape and behavior.
i.e 3d model file contains at least one 3d object
That 3d object must be "skinned" with some texture.
Phase Shift uses direct x MODELS (with *.X extension) and Portable Network Graphics TEXTURES (with *.png extension).
With 3ds max we can create direct x models using Panda DirectX Exporter.
It's freeware plugin for 3ds max, so google it and get it.
If you look into default theme folder .\themes\default\static\meters you will find *.X file for each meter and related to it *.png files.
For example Meter Multiplier uses 10 files total:
1 model file: Meter_Multiplier_Bar.X
9 texture files: Meter_Multiplier_1.png, Meter_Multiplier_2.png, Meter_Multiplier_3.png, Meter_Multiplier_4.png, Meter_Multiplier_5.png, Meter_Multiplier_6.png, Meter_Multiplier_8.png, Meter_Multiplier_10.png, Meter_Multiplier_12.png
Imagine that model Meter_Multiplier_Bar.X has a square shape. Its area is filled with 1st png file - Meter_Multiplier_1.png by default.
When you hit notes enough your multiplier raises and then 3d model's area will be filled with next texture - Meter_Multiplier_2.png.
Game will load the approriate texture automatically everytime your multiplier changes, so all you have to do is to create 1 model and 9 textures (in this case).
Model file defines place, shape and behaviour of Phase Shift's meter as you already know.
The exact place of model is related to coordinate system of 3D program that creates it.
In our case that program is 3ds max 2012. Good starting point for placing our newly model is Phase Shift's board.
Every player has own board and meters.
Imagine that we have one player. The game automatically place its board in the center of screen.
If we have 5 players, third player's board will be in the center of screen again, but his\her board will be smaller than board in previous case.
Important here is that board and meters are related each other. Game will scale all boards automatically to fit the screen,
so all you have to do is to place your meters according to board.
3ds max can't import directx models (it can only export it), so you will need another program to do that properly.
I already done that, so you can use my 3ds project with imported board. Look at thread's bottom for file download (password is djlastnight).
But if you want to give a try to import it yourself, board model file is located here: .\themes\default\static\board\board.X
We already have board imported in 3ds max, so let's create our first meter.
Let's create meter multiplier, because it's easy to create. Make a copy of "default" theme folder and rename "default - copy" to "new theme".
Here's what you should do step by step:
a. Open my 3ds project and create standart primitive -> plane, near the board.
By default plane is alongside the board.
Adjust view angle similar to Phase Shift's angle and Rotate the plane, so you can see all the area of plane (perpendicular to board).
That area will be filled with your texture later.
b. Select created plane and go to modify (top right corner)
c. From modifier list select Unwrap UVW, click on "+" and select Face.
d. Click "Open UV Editor" (bottom right corner) - here you should select all (ctrl+a) and freeform all the parts of plane together (by default they must be 4x4 parts).
e. When desired shape is ready, click tools->Render UVW Template...
f. Settings for template:
mode = solid
show overlap = no
visible edges = no
invisible edges = yes
seam edges = no
g. Click Render UV Template and save template as *.png.
h. Open that texture in Photoshop, paint it what you like and save it as *.png to .\themes\new theme\static\meters\ folder with name Meter_Multiplier_TEMPLATE.png
*** Save your Photoshop project. You have to create 9 textures for multiplier with this template.
Hint: You can also import default multiplier textures to photoshop and resize them over template, just for the test. Save them and go on to the next step.
i. When your textures are done, Go back to 3ds max. Restore 3ds max main window (so you can drag over it) and Open Material editor.
Click on modes - compact material editor. Drag Meter_Multiplier_1.png to empty slot.
j. Now you got ready for use material. Drag this material over plane.
k. Save your project
l. Delete board
m. Export as (pandax) *.X your meter to .\themes\new theme\static\meters folder with name Meter_multiplier.X
n. Start Phase Shift and see the result.
If you don't like the positioning of meter go back to 3ds max and move, rotate or resize the plane.
If you don't like the vision of meter go back to photoshop.
You must restart Phase Shift everytime you made some change, because it loads models and related to them textures once, when you start the game.
When your meter multiplier is completely done, and you realize what you exactly do, you can go on to the next steps.
Meters in Phase Shift can be divided into two groups.
Simple meters: Meter Accuracy, Meter Chunk Bar, Meter Main, Meter Multiplier.
Advanced meters: Meter Energy Bar, Meter PS Bar 1, Meter PS Bar 2
The main difference is that Simple meters are always shown "as is". They always shows whole textures.
Advanced meters shows only parts of related to them textures.
Imagine Meter Energy Bar in default theme. When you hit all notes and you don't break your combo
this meter shows all of its texture. When you stop playing texture starts disappear, until it is completly invisible when you "die".
Maybe you already note that .\themes\default\static\meters folder contains file called "Meter_Energy_Bar_Mask.png"
That is the mask for that meter. But how it works?
Let's open mask image and take a look into it. Left size is filled with white. Right size is transparent.
Filled part means - visible, Transparent part - invisible. Colour does not matter, it will work with any other colour too.
Important here is visible - invisible.
If we create advanced meter in the same way we already used for creating simple meter (Meter Multiplier) it will not work.
But why? That's because of mask. We need to relate the mask to the meter. It's needed for it to work properly.
You have to know that actual advanced meter size is double than size that you see ingame.
3d object size is the same as you can see it, but it's UVW Map size is double.
UVW Map covers the object. Map is exact projection of object by default, ie UVW Map covers all of the object. But remember what was our mask.
It's half visible, that's why our meter will be half visible too. We should fix this.
We can add several UVW Maps to one 3d object in different UVW Map channels.
Default channel is channel 1. Our meter will not work if we use channel 1,
because channel 1 is already used by Unwrap UVW (that's our texture for meter).
We have to add UVW Map to channel 2.
So what actually advanced meter is? That is simple meter with added UVW Map to channel 2. That's it.
Adding UVW Map in 3ds is simply like adding Unwrap UWV.
a. Select created object and go to modify (top right corner)
b. From modifier list select UVW Map
c. Change Map channel to 2
Click on "+" and select Gizmo.
Move map, until arrows of coordinate system aligns with object's edge.
Be careful how is your Map rotated:
End of map is green line,
Beginning - opposite to green line.
Resize map until "opposite" line touches the other object edge.
UVW Mapping on channel 2 relates object to mask.
OK, meter is ready, But how that works ingame?
Game controlls mask. If we play well and our meter is 100% then visible part of mask will
cover object 100% and we will see whole texture. If we miss some notes, game will start sliding mask toward "opposite" uvw map line.
Part of mask will not cover our object (it will cover it, but with its invisible part), so that part will be invisible for us ingame.
That's how mask works.
Remember: Mask only "says" which part of object will be shown. Map must cover whole object.
If your map is smaller than your object, game will automatically fill uncovered area with another mask(s).
Example: If you create map 2 times smaller than your object, you will have 2 moving masks ingame.
You can modify mask texture for your needs. For WoR theme I used custom mask.
I was the first person that modified Phase Shift's 3d objects (all meters, loading fireball and online remote wait cube uses 3d models).
It was 1 year hard work (for whole theme: 3d objects, theme system, texture and image editing).
I was trying to invent how to create that Green, Yellow, Red lights needed for theme's energy bar.
How to add slider bar then. How to change behavior of chunk bar (it changes it colours, which is not supported in Phase Shift).
How to change PS bars textures in exact moment...how to add lighning..etc.
I have to learn 3ds max and Photoshop for this goal.
Recently, I was asked to reveal how that things actually works.
Even If you know all the stuff you read above it's not so easy to recreate WoR meters.
Firstable my idea was to make mask very tiny, because of slider bar.
Slider bar worked very well. The problem was that energy bar was't.
I had to add more and more meters one over another. They was shifted in coordinate space.
When one meter turns on, another meter turns off.
Meters was grouped in 3 sections - one for green, one for yellow and one for red.
Each section contained 16 shifted meters. Therefore 3 sections x 16 meters = 48 meters + 1 slider bar = 49 meters used only
for recreating Energy bar. This is related to many mathematical calculation of course.
Meter PS Bar 1 and 2 also contains tons of meters one over other..
Game worked very well in Quickplay. Meters was great.
Problem was when you want to play online. Game has stared crashing..
1-2 months I was thinking that something went wrong in theme system,
so I've checked my ini files a lot of times. Nothing..
Damarus95 was helping me a lot at this period. He suggested to remove some of that meters.
I've tried to remove them and game stoped crash. Many thanks to Damarus95 for him proposal.
I had to bang my head how to fix this. Game was too heavy.
One day I decided to tweak the mask. There was a quite simple solution.
Two masks? No. Phase Shift uses only one mask for all advanced meters.
The key was to keep old tiny mask (for slider bar) and to add old half mask.
So I made current mask for WoR theme. It looks like that ____|.....
where dots are transparent right half. Bottom of left half is used for Energy Bar, PS1 and PS2.
Top left is used for Energy Slider. I had to recreate all meters. I shifted maps on left for the 3 meters
and right for slider bar. That trick works. Current WoR theme uses that mask.
Ok that was good solution, because I do not have to create tons of meters, each with complicated calculations
for where exact map should be. I needed only 4 meters for Energy Bar: Green, Yellow, Red and Slider.
That were easy calculations compared to previous dozens of meters.
I put meters one over another. I have rotated their maps to 90 degrees, so they can disappear in exact time.
Slider is on top, next are Green, Yellow, Red. Slider is always visible (expect you "die"). Red too.
When you are in green all meters works and are visible, but you can not see yellow and red, because they are under green.
Green texture is designed to show bright green, dark yellow and dark red. When it disapper, you see yellow.
Yellow texture - dark green, bright yellow and dark red. When it disapper, you see red.
Red texture - dark green, dark yellow and bright red.
How simple you will say. Everything is simple, we people made it complicated
Secret of chunk bar: Chunk bar in Phase Shift does not change its colour by default.
It was constantly yellow in old theme version.
I had to invent how to create it multicolored. It's simple.
I related chunkbar and meter multiplier textures.
When multiplier changes a texture, along with it additional texture changes too. It is placed under "real" chunk bar texture.
Important here is that multiplier meter contanins two objects, so texture must be splitted for each object.
If you look into my textures, you will find that left side is for multiplier texture, right side is for chunkbar underlay.
By default chunk bar textures are shown in ascending order - from 0 filled block to 10 filled blocks.
If I was used this method what will game will show? Colored underlay that gradually disappears and fills with only one colour.
I wanted exactly opsite - multicolored underlay that gradually appears. So I painted them all chunks black.
Also I filled chunk bar 0 texture with 10 black blocks instead of 10 transparent blocks,
chunk bar 1 texture with 9 black blocks (9 from top to bottom)
chunk bar 2 texture with 8 black blocks (8 from top to bottom)
... etc.
How it actually works: When you hit a note one black block disappears and you see related to mulitiplier coloured texture underlay.
Secret of Lighning:
Creating Lightning is simple, too.
What's going on when you earn star power in default theme? All lanes glows.
I used that just like trigger. I've changed textures for lane.
Here's some of textures used by Lane.X model:
Lane_Normal.png - default lane texture
Lane_Miss.png - flicker once when you miss a note
Lane_PS.png - replaces Lane_Normal.png during Star power is active
Lane_Glow.png - flicker once when you earn star power.
I created new Lane.X model because of importing Lighning.
It contains two objects. One plane for lanes and another for lighning.
Key is in making proper UVW Unwrap to both objects.
Lanes object uses left side of textures.
Lighning uses right side of textures.
Right side for all textures, except Lane_Glow.png is transparent.
Left side for Lane_Glow.png is transparent.
If they are not transparent what will game show?
Imagine that Lane_Miss.png is filled with red colour on both sides (left and right)
When you miss a note, you will see not only all lanes flicker red, but Lighning object too.
My textures and images are edited in Photoshop. I grabbed them from youtube hd videos. Youtube automatically convers videos, so they are not actually hd.
Their bitrate is lower than originally uploaded hd videos and this affects screenshots quality.
Anyway, I do not own PlayStation 3, Xbox 360 or Nintendo Wii so that's the best I can do for now.
If you are good in painting, that's good for you. You can create your own theme.
I can not paint at all, so I prefer to edit screenshots.
You have to know something about your textures/images. They should be RGB 16 bit png-s.
It's desirable to add black underlay to image with 1% opacity.
Farthest from the screen images should be added first in theme system, except in special cases like image masking or other.
In dynamic folder of each Phase Shift theme there are a lot of ini files.
The name "INI file" comes from the commonly used filename extension, .INI, which stands for "initialization".
That files contains information for videos, images, lists, text, effects and models.
Let's take a look into all ini files and explain what exacty they do ingame.
Ini files can be grouped in 3 groups
a. Game inis- their name starts with game_*****.ini They are usable when song is played.
b. Menu inis- their name starts with menu_*****.ini They are usable when navigating through menus (not playing a song).
c. Special inis- with random names. There are only 2 ini files in that group:
achievement_box.ini - this is most rarely used ini file. It is used only when some achievment is unlocked.
message_box.ini - it is used when game ask you something or give you some specific information (like what is your IP in example).
Game inis:
game_fail_holder.ini - used when song fails
game_options_game.ini - This is Pause submenu called Game Options
game_options_profile.ini - This is Pause submenu called Profile Options
game_options_song.ini - This is Pause submenu called Song Options
game_osd.ini - osd = On-Screen Display. Here you can tweak countdown, Song name , artist name and button helper. It appears when you wait 3 seconds for game to resume from pause menu or when song ends.
game_osd_alert.ini - Last Man Standing game mode should be activated. Here you can tweak the way that game warns players that speed change is coming.
game_osd_calibration.ini - Here you can tweak osd during calibrating song is played.
game_osd_lyrics.ini - tweak lyrics osd
game_osd_main.ini - tweak main osd meter (scores, rank, game time progress)
game_osd_practice.ini - tweak practice osd
game_osd_remote_wait.ini - tweak osd when waiting for remote players
game_pass_holder.ini - used when song is passed
game_pause.ini - tweak pause menu
game_player_solo.ini - tweak player solo. Visible during solo.
game_playerbox.ini - tweak playerbox. Visible when song complete or some player is "dead".
game_practice_background.ini - tweaks practice background. Video or image can be used here.
game_practice_menu.ini - tweaks practice pause menu.
Menu inis:
menu_achievements.ini - tweaks achievments menu. Visible through Main menu -> Extras -> Achievments, also Pause menu -> Achievments
menu_audio.ini - tweaks audio menu. Visible through Main menu -> Options -> Audio Options
menu_calibration.ini - tweaks calibration menu. Visible through Main menu -> Options -> Calibration
menu_career.ini - tweaks career menu. Visible through Main Menu -> Career
menu_career_profile.ini - visible when Phase Shift default career or custom career is chosen. There is submenu when new profile is created.
menu_container.ini - That menu is main background for all other menus. It is active when song is not playing. Supports video background.
menu_display.ini - tweaks graphics menu. Visible through Main menu -> Options -> Graphic Options
menu_dropdownbox.ini - tweaks controller dropdown menu
menu_extras.ini - tweaks extras menu. Visible through Main menu -> Extras
menu_lobby.ini - tweaks lobby. Network game should be hosted or joined. Visible through Main menu -> network -> host game
menu_main.ini - tweaks main menu.
menu_midilink.ini - tweaks midi link menu. Visible through dropdownbox (press start/tab, when not playing a song) -> midilink
menu_network.ini - tweaks network menu. Visible through Main menu -> Network
menu_options.ini - tweaks options menu. Visible through Main menu -> Options
menu_osd.ini - tweaks osd menu. Visible through Main menu -> Options -> OSD Options
menu_overlay.ini - tweaks buttons in all menus.
menu_playerselect.ini - tweaks menu player select. Visible when song is chosen. Playerselect is not active in career mode (in current Phase Shift version 1.19)
menu_playerslot.ini - tweaks player slot. Visible in Playerselect screen.
menu_profile.ini - tweaks profile menu. Visible through dropdownbox (press start/tab, when not playing a song), navigate to desired profile and hit select/backspace -> Edit profile
menu_search.ini - this file is not used by current version of Phase Shift (1.19), but maybe it will be seach menu for songselect screen
menu_serverlist.ini - tweaks server list menu. Visible through Main menu -> Network -> Find games
menu_songload.ini - tweaks song loading screen. Visible when game loads a song.
menu_songselect.ini - tweaks song select screen. Visible when choosing a song.
Theme system works with images, texts, lists and models. You can apply effects to all of this items.
You should use script language with proper syntax, that "tells" to game what object to use and how.
Each object has own tag and you should learn them.
Here are "main" or "root" tags:
<image> - opening image tag. That tag tells to theme system that image will be inserted in game
</image> - closing image tag
<text> - opening text tag. That tag will insert text into your theme.
</text> - closing text tag
<list> - opening list tag. It inserts list into your theme.
</list> - closing list tag
<model> - opening model tag. It inserts model into your theme.
</model> - closing model tag
<fx> - opening effect tag. This tag applying effect to any of the root tags.
</fx> - closing effect tag
<background> - opening background tag. This tag applying image or video as background.
</background> - closing background tag
As you can see root tags should be opened and then closed.
Each root tag has its own specific "sub" tags. We will call them just tags.
All tags has specific syntax for its values.
Let us summarize this with following example code.
<image>
<path>images\my_image.png</path>
<scale>90,95,100</scale>
</image>
I will explain what that code tells to theme system.
<image> is root tag. It tells that we want to insert image.
<path> is image (sub) tag, that tells to theme system where is our image file placed.
In this case it is placed in .\themes\new theme\dynamic\images folder and its name is my_image.png
As you can see there is no need to use full path to our image. Theme system "knows" that our content is placed in dynamic folder.
By selecting theme through main menu options, you also tells to theme system where is its folder (just to mention that theme's folder name defines theme name)
So all we need is to tell where exactly in dynamic folder our file is.
Therefore path will be "images\my_image.png"
Text in quotes is called value. It is <path> tag value.
Value is situated between opening and closing tag.
No spaces are used.
In third line we have <scale> tag and its value "90,95,100"
This is value with special syntax (3 comma separated values).
In this case first value means x, second y, and third means z.
We can scale to 3 dimensions. For images 3rd dimensions does not really matter, but <scale> tag works for 3d models, texts and lists too (because <scale> is global tag).
Now you already know how theme system works.
Let's meet and learn all tags and their values:
| Values | Syntax | Description | Example | Tag Group |
--- | --- | --- | --- | --- | --- |
<path> | exact file location | - | path to background image or video | <path>images\my_image.png</path> | background |
<bg_type> | image, video. "image" is default value | - | Sets type of background | <bg_type>video</bg_type> | background |
--- | --- | --- | --- | --- | --- |
<screen_pos> | numbers from 0 to 100 by default. "50,50,0" is default value | three comma separated values | Sets screen location of object in percents. Value 50 means center of screen | <screen_pos>50,90,0</screen_pos> | global |
<position> | any number is allowed. "0,0,0" is default value | three comma separated values | Sets location of object. Positive and Negative values are allowed. 0 means center of screen | <position>0,200,-10</position> | global |
<alpha> | numbers from 0 to 100 by default, but any positive and negative numbers could be used, when <additive_alpha> fx tag is used. "100" is default value | - | Sets object's opacity. 0 means invisible object | <alpha>50</alpha> | global |
<rotate> | numbers from 0 to 360 by default, but bigger numbers could be used in some reason. "0,0,0" is default value | three comma separated values | Rotates object in 3 dimensions | <rotate>180,90,0</rotate> | global |
<scale> | any positive number. "100,100,100" is default value | three comma separated values | Scales object in 3 dimensions | <scale>100,120,100</scale> | global |
--- | --- | --- | --- | --- | --- |
<path> | exact file location | - | path to image file | <path>images\my_image.png</path> | image |
<selector> | true, false. "false" is default value | boolean | Makes image selector for list | <selector>true</selector> | image |
<scrollbar> | true, false. "false" is default value | boolean | Makes image scrollbar for list | <scrollbar>true</scrollbar> | image |
<replace_id> | exact item name, that should be replaced | - | Image replaces certain item. This image tag can be used to replace list item or dynamic text value with image | <replace_id>quickplay</replace_id> | image |
<generic_replacer> | true, false. "false" is default value | boolean | When this tag is used image replaces not only certain item, but all object items | <generic_replacer>true</generic_replacer> | image |
Remark: all global tags could be used for images. |
|
|
|
|
|
--- | --- | --- | --- | --- | --- |
<english> | free text | - | Inserts text that you type as value | <english>This is my text</english> | text |
<dynamic> | true, false. "false" is default value | boolean | Sets text as dynamic | <dynamic>true</dynamic> | text |
<id> | each ini has specific id values | exact id | Defines dynamic text id | <id>lyrics_0</id> | text |
<font> | exact font name. "default" is default value | - | Force text to use certain font. Font name is equal to its folder name (located in dynamic\font folder) | <font>Wor_menu</font> | text |
<size> | any positive number. "10" is default value | - | Sets text's font size | <size>16</size> | text |
<case> | lower, normal, upper. "normal" is default value | - | Sets text's case. | <case>upper</case> | text |
<justification> | left, center, right. "left" is default value | - | Sets text's justification | <justification>center</justification> | text |
<max_length> | any positive integer | - | Sets text's max length. When this tag is not used max text length is unlimited | <max_length>35</max_length> | text |
Remark: all global tags could be used for text. |
|
|
|
| |
--- | --- | --- | --- | --- | --- |
<list_align> | top, middle, bottom. "top" is default value | - | Sets list's vertical align | <list_align>middle</list_align> | list |
<leading> | any positive number. "50" is default value | - | Sets list's vertical spacing | <leading>70</leading> | list |
<view_count> | any positive integer | - | Sets list's view count | <view_count>8</view_count> | list |
<horizontal> | true, false. "false" is default value | boolean | By default list is vertical. That tag will make it horizontal if true value is used | <horizontal>true</horizontal> | list |
Remark: all global and text tags except <dynamic> could be used for list. |
|
|
|
| |
--- | --- | --- | --- | --- | |
<fx_type> | linear, sine, ping_pong, switch, random | - | Sets type of effect | <fx_type>linear</fx_type> | FX |
<target> | colour_(r|g|b), alpha, position_(x|y|z), scale_(x|y|z), texture_(u|v), rotate_(x|y|z) | - | Sets fx's target | <target>colour_r</target> | FX |
<additive_alpha> | true, false. "false" is default value | boolean | Makes alpha additive, accumulative. | <additive_alpha>true</additive_alpha> | FX |
<id> | each ini has specific id values | exact id | Defines fx id. Each ini has it own id-s. | <id>state</id> | FX |
<sub_id> | any positive integer. The most commonly used values are 0-5 | - | Defines fx sub id. This tag is used along with <id> tag. Not all inis uses sub_id tag | <sub_id>2</sub_id> | FX |
<inherit_sub_id> | true, false. "false" is default value | boolean | Usable when applying fx for list. Fx will controll currently selected item only | <inherit_sub_id>true</inherit_sub_id> | FX |
<sub_id_wild> | true, false. "false" is default value | boolean | Usable when applying fx for list. Fx will controll all list items | <sub_id_wild>true</sub_id_wild> | FX |
<start> | any number | - | Sets start value for fx. Used in all fx types except "set", which has only end value | <start>100</start> | FX |
<end> | any number | - | Sets end value for fx. Note that "set" fx type has only end value | <end>0</end> | FX |
<loop> | true, false. "true" is default value | boolean | When <end> value is reached fx could be stopped if "false" used. Often this tag is used along with <trigger> tag | <loop>false</loop> | FX |
<speed> | any positive number. Extremely big numbers are not recommended. Use numbers smaller than 10000 | - | Sets fx's speed. Could be used with linear or ping_pong effects only | <speed>100</speed> | FX |
<rate> | any positive number. Extremely small numbers are not recommended | - | Sets fx's rate (tempo) in miliseconds. Value 1000 means 1 second. Could be used with switch, sine or random effects only | <rate>1000</rate> | FX |
<delay> | any positive number | - | Sets fx's delay time in miliseconds. Value 1000 means 1 second. Often this tag is used along with <trigger> tag to avoid bugs | <delay>2000</delay> | FX |
<loop_delay> | any positive number | - | Sets fx's delay time in miliseconds before repeating (looping). Value 1000 means 1 second. Often this tag is used along with <trigger> tag to avoid bugs | <loop_delay>5000</loop_delay> | FX |
<trigger> | specific for each ini | exact trigger name | Fx will running only when trigger is activated. Some exaple trigger values are active_(on|off), select_(on|off), hover_(on|off), edit_(on|off), disable_on, loading_(on|off), change_(a|b) | <trigger>hover_on</trigger> | FX |
Remark: Effects doesn't work for <background> root tag. |
|
|
| Effects should be applied as sub tag of any root tag (except background). Here's example with <image> root tag: | |
--- | --- | --- | --- | --- | --- |
<path> | exact file location | - | path to 3d model | <path>3d\my_model.X</path> | model |
Remark: all global tags could be used for models. |
|
|
|
|
|
--- | --- | --- | --- | --- | --- |
Specific id-s, sub_id-s and triggers for each ini will be explained if this thread is interesting enough for forum users or if someone ask for that.
If you look into default font folder (.\themes\default\fonts\default) you will see that this folder contains images. Their names are numbers for 32 to 126 and of course they are in png format. This numbers are not accidental, actually they are ASCII Codes.
Each ASCII number means specific symbol. 32 is used for space, 65 for capital "A", 66 for capital "B", etc..
So if you want to create new font, you should edit that images. If you create them in new folder remember that: Font name is equal to its folder name.
i.e if your font images are located here .\themes\new theme\dynamic\fonts\SomeFont your font name will be "SomeFont".
First of all, please make a copy of "default" theme folder and rename "default - copy" to "new theme" (I'm using Windows 8, but if you use older Operating System "default - copy" maybe "copy of default". Rename it to "new theme")
Open menu_container.ini from .\themes\new theme\dynamic folder and clear it all. Save it and close it.
Open menu_main.ini from .\themes\new theme\dynamic folder and clear it all too, but do not close it.
We will "tell" to theme system that we want image to be shown in Phase Shift's main menu.
The code for that is <image>. When game "sees" that code it will insert image (in main menu in our case)
If you want to insert image in playerselect screen in example, you have to edit menu_playerselect.ini
i.e Each menu has it own ini file.
Write this code to your empty menu_main.ini
<image>
Now we should tell the game where is that image in our computer. code for that is <path>
<image>
<path>
Phase shift knows that files for your theme are in its folder, so we will put all image files in .\themes\new theme\dynamic\images folder.
Let's assume that our image name is my_image.png and we put that image file in images folder.
We already know the name of file and its location, so here is our code
<image>
<path>images\my_image.png</path>
</image>
Note that every command have beginning and end preceded by /
So open command for image is <image> and close command for image is </image>
for path: open = <path>, close = </path>
Spaces are not used.
We can make comments, so we know what we are doing at this moment.
This is very useful when you edit your ini files in future.
<!-- this is a comment -->
Phase shift will ignore this line. This line is for you. You can write what you want between <!-- and -->
Let's edit our code:
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
Save that ini file.
Open phase shift and test your theme. (You should change theme to "my theme" first)
Main menu contains only one image. There is nothing else.
We will add lists in next step. Close game using ALT+F4 or navigate to bottom (Quit) and hit F1.
Our main menu is unusable when we don't have main list in it.
Let's import that list. Command for that is <list>. Each list has specific id. It's something like its name.
Id for main list in menu_main.ini is called "list_name". We should use that id. Let's edit our code.
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
</list>
The code above inserts list into main menu. Start Phase Shift to see your list. By default it is placed in center of the screen. List's font is default font with font size 10.
All list items are visible and their leading is 50. There is no selector, so we can not see what item is currenly selected.
Do you know why list is placed right there, its font is default font with size 10 and leading is 50. This is because of default tag values.
When you do not specify a tag, its default value will be used. We do not want to use default values, so
let's change them with following code:
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
<screen_pos>70,75,0</screen_pos>
<font>default</font>
<size>15</size>
<leading>75</leading>
<view_count>5</view_count>
</list>
There is no need to restart Phase Shift everytime you made some change to code. All you have to do is enable debug mode in options menu. When you hit F12 from keyboard,
game will automatically reload your code. Of course you should save ini file before that.
Warning: Sometimes Phase Shift crashes when you hit F12. That's because you hit it different menu. Hit F12 only when you are in menu that you edit.
Hitting F12 in loading song screen will crash you game immediately. That's because of running trigger loading_on. To avoid crash just wait song to complete loading.
Now back to our code. It inserts image called "my_image.png", also inserts main list.
That list is placed in 70% of horizontal part of screen and 75% of vertical part of screen.
Horizontal is measured from left to right. Vertical - from top to bottom.
By default in that screen position is placed top of our list, because "list_align" default value is "top".
You already know how to override(change) that value. Actually <font>default</font> is unnecessarily. Why?
Because of default font value - it is "default". There is no need to write that, because Phase Shift will use default value automatically.
Let's go ahead. Our font size is 15, leading is set to 75, view_count is set to 5. Main menu list in Phase Shift 1.19 version contains 7 items.
If we do not use view_count tag, game will display all 7 items. If all list items are displayed there is no need of scrollbar. We will keep view_count value 5, because
in next step we will insert selector and scrollbar to our list. Let's assume that our selector and scrollbar images are located in images folder and their names are selector.png and scrollbar.png
Let's write a code for that.
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
<screen_pos>70,75,0</screen_pos>
<font>default</font>
<size>15</size>
<leading>75</leading>
<view_count>5</view_count>
<image>
<path>images\selector.png</path>
<selector>true</selector>
<scale>150,60,100</scale>
</image>
<image>
<path>images\scrollbar.png</path>
<scrollbar>true</scrollbar>
<scale>70,70,100</scale>
</image>
</list>
Let's analyze it. So far we used image as root tag. Image could be used as "sub" tag too. This is possibe when we use special image tags like selector, scrollbar, replace_id, generic_replacer..
What we have in our main menu? Image called "my_image.png", main list with specified screen position, font size, leading, view_count and two images used as scrollbar and selector for that list.
All image tags are valid here (when using image as sub tag). Let's try to replace certain list item with image.
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
<screen_pos>70,75,0</screen_pos>
<font>default</font>
<size>15</size>
<leading>75</leading>
<view_count>5</view_count>
<image>
<path>images\selector.png</path>
<selector>true</selector>
<scale>150,60,100</scale>
</image>
<image>
<path>images\scrollbar.png</path>
<scrollbar>true</scrollbar>
<scale>70,70,100</scale>
</image>
<image>
<path>images\quickplay.png</path>
<replace_id>quickplay</replace_id>
<scale>110,110,100</scale>
</image>
</list>
That additional image code will replace "quickplay" item list with image called quickplay.png (placed in images folder).
You will be not able to see quickplay text anymore. It will be completely replaced by image.
What will show the game if "generic_replacer" tag was used instead of "replace_id"?
All list items will be replaced with quickplay.png We will not try this in tutorial. You can try yourself if you are curious.
It's time to apply some effect to our list. We should use "fx" root tag for this. Let's apply linear effect to current selected item.
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
<screen_pos>70,75,0</screen_pos>
<font>default</font>
<size>15</size>
<leading>75</leading>
<view_count>5</view_count>
<image>
<path>images\selector.png</path>
<selector>true</selector>
<scale>150,60,100</scale>
</image>
<image>
<path>images\scrollbar.png</path>
<scrollbar>true</scrollbar>
<scale>70,70,100</scale>
</image>
<image>
<path>images\quickplay.png</path>
<replace_id>quickplay</replace_id>
<scale>110,110,100</scale>
</image>
<fx>
<id>list_name</id>
<trigger>hover_on</trigger>
<inherit_sub_id>true</inherit_sub_id>
<fx_type>linear</fx_type>
<target>position_x</target>
<start>0</start>
<end>-100</end>
<speed>100</speed>
<loop>false</loop>
</fx>
</list>
Let's analyze fx section.
<id>list_name</id> - this say to theme system that effect will be applied to main list (which id is list_name)
<trigger>hover_on</trigger> - this will activate effect when you hit up or down. i.e when you change current list item.
<inherit_sub_id>true</inherit_sub_id> - this will inherit the current list item. fx will be applied only to this item.
<fx_type>linear</fx_type> - this tells to theme system that linear effect will be used.
<target>position_x</target> - this is effect target. in our case currently selected item will be moved in x axis.
<start>0</start> - sets start point of effect. in our case item will stays at its normal place. this line is unnecessarily, because "start" default value is 0, but it clarifies to you what is the starting point of fx.
<end>-100</end> - sets end point of effect. in our case this is item's x position (our target). When fx finishes current item x position will be -100.
<speed>100</speed> - sets speed for our effect. Smaller value means slow speed and vice versa.
<loop>false</loop> - in our case effect will be applied only once until you hit up/down button. This time effect will be applied for next/previous list item (again only once).
Let's import text in our main menu (final tutorial step)
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
<screen_pos>70,75,0</screen_pos>
<font>default</font>
<size>15</size>
<leading>75</leading>
<view_count>5</view_count>
<image>
<path>images\selector.png</path>
<selector>true</selector>
<scale>150,60,100</scale>
</image>
<image>
<path>images\scrollbar.png</path>
<scrollbar>true</scrollbar>
<scale>70,70,100</scale>
</image>
<image>
<path>images\quickplay.png</path>
<replace_id>quickplay</replace_id>
<scale>110,110,100</scale>
</image>
<fx>
<id>list_name</id>
<trigger>hover_on</trigger>
<inherit_sub_id>true</inherit_sub_id>
<fx_type>linear</fx_type>
<target>position_x</target>
<start>0</start>
<end>-100</end>
<speed>100</speed>
<loop>false</loop>
</fx>
</list>
<text>
<english>This is my theme!</english>
<screen_pos>30,50,0</screen_pos>
<size>20</size>
<scale>100,200,100</scale>
<justification>center<justification>
<max_length>16</max_lenght>
</text>
This additional code will insert text as you already know. Interesting here is max_length tag. Our value for <english> tag is "This is my theme!", but game will show only first 16 symbols.
Note that spaces should be counted too. Our total lenght is 17 symbols, so the game will cut only last symbol which is "!"
Now let's apply 2 different effects to text.
<!-- I'm editing my first theme -->
<image>
<path>images\my_image.png</path>
</image>
<list>
<id>list_name</id>
<screen_pos>70,75,0</screen_pos>
<font>default</font>
<size>15</size>
<leading>75</leading>
<view_count>5</view_count>
<image>
<path>images\selector.png</path>
<selector>true</selector>
<scale>150,60,100</scale>
</image>
<image>
<path>images\scrollbar.png</path>
<scrollbar>true</scrollbar>
<scale>70,70,100</scale>
</image>
<image>
<path>images\quickplay.png</path>
<replace_id>quickplay</replace_id>
<scale>110,110,100</scale>
</image>
<fx>
<id>list_name</id>
<trigger>hover_on</trigger>
<inherit_sub_id>true</inherit_sub_id>
<fx_type>linear</fx_type>
<target>position_x</target>
<start>0</start>
<end>-100</end>
<speed>100</speed>
<loop>false</loop>
</fx>
</list>
<text>
<english>This is my theme!</english>
<dynamic>true</dynamic>
<screen_pos>30,50,0</screen_pos>
<size>20</size>
<scale>100,200,100</scale>
<justification>center<justification>
<max_length>16</max_lenght>
<fx>
<fx_type>ping_pong</fx_type>
<target>colour_g</target>
<start>100</start>
<end>-100</end>
<speed>100</speed>
</fx>
<fx>
<fx_type>sine</fx_type>
<target>scale_y</target>
<start>100</start>
<end>30</end>
<rate>30</rate>
</fx>
</text>
First fx will change colour of our text, second will scale it.
That's all. Good luck with your new theme. I wish you a lot of spare time, because you will need it.
djlastnight
---------------------------------------------------------------------------------------------------------------------------------------
Files for download: Phase Shift Board + Advanced meter sample (3D Studio Max Project file)
---------------------------------------------------------------------------------------------------------------------------------------