Creating Stages
Stages are defined via XML files, similar to Creating characters. By creating an XML file in ./data/stages, you officially created a stage.
The default stage XML looks something like this:
<stage zoom="0.9" name="stage" folder="stages/default/" startCamPosY="600" startCamPosX="1000">
<sprite name="bg" x="-600" y="-200" sprite="stageback" scroll="0.9"/>
<sprite name="stageFront" x="-600" y="600" sprite="stagefront" scroll="0.9"/>
<girlfriend/>
<dad/>
<boyfriend/>
<sprite name="stageCurtains" x="-500" y="-300" sprite="stagecurtains" scroll="1.3"/>
</stage>
There's a lot to pack but we will explain what's going on here.
First, to start with the "parent node", which is the <stage> node, that is where stage options are being defined.
<stage zoom="0.9" name="stage" folder="stages/default/" startCamPosY="600" startCamPosX="1000">
Noting options that you can set there:
zoomwhich controls the default zoom of the stage.name, name of the stage when you look for it in the Chart Editor.folderwhich changes the destination of where the sprites are taken from (likeimages/stages/default/).startCamPosX, startCamPosYset the destination of where the camera starts from (before countdown)
As for the other nodes, there's about 7 types of them (and more if you script them in, see Character/Stage Scripts), we'll go through each of them.
(note that it's important which order you put them in because they will take the same order in-game too)
Sprite node (<sprite>, <spr>, <sparrow>)
The sprite node defines the basic sprites in a stage.
<sprite name="bg" x="-600" y="-200" sprite="stageback" scroll="0.9"/>
The options are:
namewhich defines the internal name used for scripting.xandydefine it's position in-game.spriteis the name of the sprite in the files. (keep in mind if you set this to point to a sparrow spritesheet it will automatically make an animation of all the frames in the spritesheet)scroll,scrollxandscrollydetermine the scrollFactor of the sprite (how much it moves with the camera)
Other options include:
skewxandskewyskews the sprite.antialiasingdetermines whether or not the sprite has antialiasing. (true by default)widthandheightdetermine the width and height of the sprite's hitbox. (does not affect the sprite itself)scale,scalexandscaleyare size multipliers for the sprite's width and height. (setting it to 2 means double the size)graphicSize,graphicSizexandgraphicSizeydetermine the width and height of the sprite.updateHitboxdetermines whether or not to update the sprite's hitbox.zoomFactordefines how much the sprite should scale with the camera's zoom. (setting it to 0 will make it stay to the original size no matter what)alphais the "opacity" of the spritecolortints the sprite in the color you set it to (example#FF0000will tint the sprite in full red)playOnCountdowntells the sprite whether or not to play it's animation during countdown or not.beatOffsetoffsets which beat to play the sprite animationbeatIntervalsets sprite's animation to play at a beat interval (basically the amount of beats to skip + 1)
You can also define animations by giving it a child node called <anim>. A sprite node with an animation node looks something like this:
<sprite name="dancer1" sprite="limoDancer" type="beat">
<anim name="danceLeft" anim="bg dancer sketch PINK" loop="false"/>
<anim name="danceRight" anim="bg dancer sketch PINK" loop="false"/>
</sprite>
An <anim> node can define these options:
namedefines the internal name of the animation (used for scripting)animis the prefix for finding the animation in the spritesheet.indicesindicates which frames to play from the previously found frames. (For a range you can type1..5to generate1,2,3,4,5)typedetermines the type of the animation. eitherbeatorloop.fpsis the framerate of your animation.xandyare the animation offset. (offset is only applied when the animation is played)forcedwhether or not to force animation playback while a different one is already playing.loopto make your animation loop.
Defining advanced properties is also possible. Like this:
<sprite name="clouds" sprite="clouds">
<property name="moves" type="bool" value="true">
<property name="velocity.x" type="float" value="40.0">
</sprite>
Solid node (<solid>, <box>)
Solid nodes are sprites that is, unlike a Sprite Node, composed of only one select color. This node has less parameters since it doesn't use images.
Creating one of these looks something like this:
<solid name="void" color="#FFFFFF" width="1280" height="720">
(there's a difference between using <solid> and <box>, while <solid> offers more performance, it might break with shaders and other stuff, so if that happens, use <box> instead)
Accepted parameters:
nameinternal name.colorwhich colors the solid/box.xandydetermine the position in the stage.widthandheightdefines the size of the solid/box.
Character nodes (<boyfriend>, <bf>, <player>, <girlfriend>, <gf>, <dad>, <opponent>, <character>, <char>)
Character nodes are used to position characters in the stage. A Character node looks something like this:
<boyfriend x="200" y="400"/>
Accepted parameters are:
xandyfor positioning.camxoffsetandcamyoffsetfor changing the character's camera point.skewxandskewyfor skewing.alphawhich determines the opacity of the character sprite.flipfor if you want to flip the character for specifically for the stage.scroll,scrollxandscrollyto change the scrollFactor of the character.
For the <character> and <char> nodes only use them if you want to change a specific character (ex. if you want to change pico's positions)
<character name="pico" x="400" y="200"/>
Keep in mind that where you put these nodes is important as the character will be layered depending on that.
<boyfriend/>
<sprite name="stageCurtains" x="-500" y="-300" sprite="stagecurtains" scroll="1.3"/>
(this will put boyfriend behind the stageCurtains sprite)
Ratings sprites node (<ratings>, <combo>)
This node is only used to position the rating sprites and does nothing else (atm). Positioning in nodes doesn't matter here.
<ratings x="200" y="400">
The only parameters are x and y.
Stage Extensions (<use-extension>, <extension>, <ext>)
<use-extension script="example" />
<extension script="example" />
<ext script="example" />
<ext script="example" folder="data/scripts/" isShortLived="true" importStageSprites="true" loadBefore="false" />
Accepted parameters:
scriptwhich is the name of the script to load.folderwhich is the folder to load the script from. (defaults to"data/scripts/")isShortLivedwhich determines whether or not the script is destroyed after the stage has finished loading. (defaults tofalse)importStageSpriteswhich determines whether or not to import the stage sprites into the script. (defaults tofalse)loadBeforewhich determines whether or not to load the script before going through the other stage's nodes, exactly like the default stage's script allowing for example to callonStageXMLParsed. If instead you want the script to load after a certain node or such, set this tofalse. (defaults totrue)
All of these attributes above get stored inside a list, singular Imported XML scripts can access their infos easily through a variable called scriptInfo (this variable uses a XMLImportedScriptInfo class and it's automatically imported into these scripts).
This allows you to load custom scripts for your stages, that allow for adding custom stage nodes, or whatever else you can think of.
Check out the Stage Extensions page for more information.