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:
zoom
which controls the default zoom of the stage.name
, name of the stage when you look for it in the Chart Editor.folder
which changes the destination of where the sprites are taken from (likeimages/stages/default/
).startCamPosX, startCamPosY
set 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:
name
which defines the internal name used for scripting.x
andy
define it's position in-game.sprite
is 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
,scrollx
andscrolly
determine the scrollFactor of the sprite (how much it moves with the camera)
Other options include:
skewx
andskewy
skews the sprite.antialiasing
determines whether or not the sprite has antialiasing. (true by default)width
andheight
determine the width and height of the sprite's hitbox. (does not affect the sprite itself)scale
,scalex
andscaley
are size multipliers for the sprite's width and height. (setting it to 2 means double the size)graphicSize
,graphicSizex
andgraphicSizey
determine the width and height of the sprite.updateHitbox
determines whether or not to update the sprite's hitbox.zoomFactor
defines 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)alpha
is the "opacity" of the spritecolor
tints the sprite in the color you set it to (example#FF0000
will tint the sprite in full red)playOnCountdown
tells the sprite whether or not to play it's animation during countdown or not.beatInterval, beatOffset
, honestly, I don't even know what this shit is okay.
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:
name
defines the internal name of the animation (used for scripting)anim
is the prefix for finding the animation in the spritesheet.indices
indicates which frames to play from the previously found frames. (For a range you can type1..5
to generate1,2,3,4,5
)type
determines the type of the animation. eitherbeat
orloop
.fps
is the framerate of your animation.x
andy
are the animation offset. (offset is only applied when the animation is played)forced
whether or not to force animation playback while a different one is already playing.loop
to 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:
name
internal name.color
which colors the solid/box.x
andy
determine the position in the stage.width
andheight
defines 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:
x
andy
for positioning.camxoffset
andcamyoffset
for changing the character's camera point.skewx
andskewy
for skewing.alpha
which determines the opacity of the character sprite.flip
for if you want to flip the character for specifically for the stage.scroll
,scrollx
andscrolly
to 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:
script
which is the name of the script to load.folder
which is the folder to load the script from. (defaults to"data/scripts/"
)isShortLived
which determines whether or not the script is destroyed after the stage has finished loading. (defaults tofalse
)importStageSprites
which determines whether or not to import the stage sprites into the script. (defaults tofalse
)loadBefore
which 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.