Platypus Level File

The level files in Platypus are simple top to bottom lists of commands that are executed asynchronously as the level progresses. It is responsible for setting up audio, visuals, the level itself and control flow to the next areas/stages

"wait" "command"

Pauses execution of the level file for the specified amount of ticks. 60 ticks equals 1 second in Platypus This is not technically a command and does not count towards commands that skip commands!

"importLevel" command

This command inserts another level file (within the same mod) at the point it is called, this can act as a shortcut for frequently used commands, loop segments or to set up defaults used by other level files

A common usecase is importLevel("fileName": "level_defaults"); where level_defaults.plat is a file holding a bunch of boilerplate variable initializations that are common to most stages.

Comments

All text on a line after // is considered to be a comment and removed before parsing This includes when // is used within a string

0 wait initialization

On load, before the screen clears, the game executes all commands until the first wait instruction is reached, use these for initialization to avoid objects from poping in while the player is watching

Metadata

Set via the "metadata" command at the top of the level file, this command is special as each level file needs exactly one of them with Data in it being applied at the start, no matter what any delays say

  • "name", string: Name of the level file. Take care that this is the exact same name as the file!
  • "hackStage3Clouds", bool: Triggers Scenery/Common/cloud5-16 and Scenery/Common/cloud3-16 being spawned continuously at the end of Stage 3, legacy for original game behaviour
  • "enableWaterfalls", bool: Makes tile layers consider waterfall requests made by the makeWaterfall command
  • "firewait", int: It's complicated, for some entities this controlls the speed of the bullet, while for other it controlls fire timings
  • "skyRise", float: The speed of the day, night cycle, as well as the starting direction, generally a very low value
  • "skyDayAmount", float: How far into the day are we? 0-1 value
  • "groundSprite", string: Path to the sprite used on the ground
  • "clearBackground", bool: Instead of showing sky and ground, clear the background with the selected clearColor
  • "clearColor", string: Color used to clear when clearBackground is true. ex: "#483528"
  • "tileInitialFrontGroup", array<int>: Determines which tiles should be used when randomly choosing for the foreground layer 0
  • "tileInitialMidGroup", array<int>: Determines which tiles should be used when randomly choosing for layer 1-7
  • "tileInitialBackGroup", array<int>: Determines which tiles should be used when randomly choosing for the background layer 8
  • "tileOverrides", dict<string, array<int>>: Forces the tile order for the selected layer by suspending random choice with the selected index
  • "dynamicTileScaling", bool: Flag for notifying the tile system that tiles are prescaled, legacy for original game behaviour
  • "tilesetPath", string: Path to the actual tiles

Commands

metadata()

Specifies the level metadata, see "Metadata" section for more information Required command

fastForwardStop(string id)

Acts as a marker to stop fast forwarding if the target matches id

fastForwardTo(string id)

Starts fast forwarding to the specified marker if we aren't already fast forwarding

fastForwardSpeedOverAccuracy()

Counterpart to: fastForwardAccuracyOverSpeed. Sets fast forwarding to skip wait commands this speeds up the fast forwarding process significantly. The downside is that the level is not taking the same amount of ticks to advance, meaning some entity logic or tiles might incorrectly show

fastForwardAccuracyOverSpeed()

Counterpart to: fastForwardSpeedOverAccuracy. Sets fast forwarding to act as if the game was played slowly, minus not executing some commands. This means that the level tick count is largely as it was if we had not fast forwarded

changeMusicTrack(string tune)

Changes the music to loop an audio event defined in audio.json

achievementMessage(string message)

Let's the achievement system know of some event that happened in the level file This command works together closly with hardcoded values

destroyText()

Triggers removal of the following UI elements (spawned through various other commands) "StageText", "AreaText", "EvaluationText", "BonusCreditsText", "TargetsPrimaryText", "TargetsSecondaryText", "SuccessText", "FleetBadge", "DifficultyIcon", "BonusDisplay", "EndBonusDisplay"

sayLevel(int level, int area)

Displays the "level x area y" text using "UI.Level" and "UI.Area" as a text base respectively

sayEvaluation()

Implicitly waits for no enemy and no "evaluation stopper" to be on screen Displays the evaluation text header (UI.Evaluation)

sayPrimaryTargets()

Displays the primary target kill percentage: UI.PrimaryTargets

saySecondaryTargets()

Displays the secondary target kill percentage: UI.SecondaryCrafts

sayTheEnd()

Displays the end text: UI.TheEnd

sayMissionFailed()

Displays mission failed text: UI.MissionFailed Supports up to 2 lines

sayMissionOver()

Displays mission over text: UI.MissionOver

sayLevelOver()

Displays level over text: UI.LevelOver (or UI.DemoOver in demo mode)

sayTotal()

Displays the total target kill percentage: UI.OverallSuccess

nextArea()

Clears area specific counters, exits on practice mode and bumps the area counter by one Marks the area as completed

fastForwardToTargetCheckpoint()

If a checkpoint was provided going into the level, fast forward is triggered with the target checkpoint as a stop condition This should be called once, early in the level before the first wait condition so that fast forwarding happens while the loading screen is still up

checkpoint(string name)

Acts as a fast forward stop for checkpoints

If not already fast forwarding: It will set "name" up to be the new checkpoint target and trigger a snapshot save

killGame()

Ends the current run, loading the score scene or main menu depending on game mode Triggers saving of "all area" level scores and marks the level and current area as completed

forceGameOver()

Fast forwards the game over sequence to trigger as if the player ran out of lives and waited enough ticks to skip the continue sequence Even if the player is still alive or has continues

endStage(string nextLevel)

Triggers saving of "all area" level scores and marks the level and current area as completed Will stop all fast forwarding

Queues nextLevel up to be loaded next and triggers the loading screen

setDeathCounterSpeed(int speed)

Determines how many ticks per tick (speed) the death counter advances, this is mostly useful to avoid game overs in menus, as they already follow all conditions for game overs (no player alive)

setDeathCounterValue(int value)

Sets the death counter to the specified value

shootOutPlayers()

Plays the end of level animation for all players, the player is no longer allowed to control the ship after this call

setFiringChanceSaucer(DiffDict<int> values)

Usage: setFiringChanceSaucer("veryEasy": 0, "easy": 0, "normal": 0, "hard": 50, "nasty": 70) Determines the firing chance of certain saucer enemies 0-100

setFiringChanceRandomFishFighter(DiffDict<int> values)

Usage: setFiringChanceRandomFishFighter("veryEasy": 0, "easy": 0, "normal": 0, "hard": 50, "nasty": 70) Determines the firing chance of random fish fighters enemies 0-100 The ones that use the RandomFishFighter Behaviour

toggleFiring(bool enabled)

Sets whether or not the player characters are allowed to fire

setLayerOffsetY(int layer, int offset)

Sets the y position of the specified layer

setLayerReflections(int layer, bool enabled)

Sets the reflection shader parameter for the specified layer

setReflectionTintColors(Color horizonColor, Color baseColor, float blendDuration)

Usage: setReflectionTintColors("horizonColor": "#2058A800", "baseColor": "#103898F0", "blendDuration": 0); Blends between the old and the new reflection tint for blendDuration seconds

defineTileGroup(string name, int[] tiles)

Defines a named group of tiles, can be used to redefine the same group

switchTileGroup(int layer, string name, int transitionTile = -1)

Changes tile spawner on the specified layer to only spawn tiles from the specified tile group If a transition tile is given, the tile at that index will be spawned one time before the new group will have an affect

Example use case is Stage 1, where the hills have a transition tile that elevates the tile baseline up

switchTileGroupMid(string name)

Shortcut for calling switchTileGroup on all layers except for the very front and very back layers

switchTileGroupBack(string name)

Shortcut for calling switchTileGroup on the very back layer

switchTileGroupFront(string name)

Shortcut for calling switchTileGroup on the very front layer

setStarOrder(string name, int[] weapons)

Changes the order of weapon stars that appear when shooting a specified star setStarOrder("name": "OriginalMultiStar", "order": [2, 3, 4, 5]);

Available weapons: BasicGuns = 1 // Has no star WideShot = 2 AutoFire = 3 SonicPulse = 4 Rockets = 5 Lightning = 6 Fireball = 7 Bomb = 8 TailGun = 10 BoxingGlove = 11 HomingMissiles = 12 Fish = 13 Sausages = 14 Hotdog = 15 RiceBall = 16 Hearts = 17 Pretzels = 18 Beans = 19 Burgers = 20 Donut = 21 Cheese = 22

setEnemyShotSpeed(float multiplier)

Sets the enemy shot speed multiplier, what exactly this does is dependent on the behaviours themselves

setWaterSplashes(bool enabled)

Sets wether or not certain behaviours should generate water splashes when they reach pass the horizon line

forceTile(int layer, int tile)

Forces the next tile for the tile spawner on layer to spawn the tile index specified

setSkyRise(float value)

Sets the speed in which the day/night cycle transitions

setSkyDayAmount(float value)

Sets the current position in the day/night cycle 0-1

setFishFire(bool enabled)

Sets wether or not certain fish fighters are allowed to fire

increaseDifficulty()

Bumps the difficulty up one, if it can't enemy shot speed multiplier is instead increased by 20%

setHillpop(int layer)

Set hillpop variable on the specified layer (for use with waitForHillpop)

waitForHillpop(int layer)

Waits for the hillpop variable previously set by setHillpop to reset The value is reset the moment the next time the tile spawner spawns a tile

Useful to force a tile to spawn and wait until the tile in question is actually spawned

waitForNoEnemies(int timeout = -1)

Stops execution of the level until no enemy is on screen or a total of "timeout" ticks have been waited

musicFadeOut()

Switches the music track out to nothing

nufzenuf()

Does absolutely nothing, seriously, don't waste your time looking for secrets

importLevel(string fileName)

Insert the specified level file at the current point

forcePlayerWarnings(int ticks)

Fire the player warning event for the specified amount of ticks. The same ones used when the player is underneath rocks

expositionText(string textID, int x, int y, int duration)

Displays text for the specified duration on screen

makeWaterfall(int layer)

Triggers the next waterfall supported tile on the specified layer to spawn with a waterfall This is set to be tile 51, in reclayed every tile 51 spawns a waterfall regardless of this command Only layer 1 and layer 3 are supported at this time

setMountedGuns(int pattern)

Sets the next mountedGuns pattern to be spawned on Layer 1. Which tile is needed to spawn them is set via setGunMountSettings

setGunMountSettings(int spawnTile, float xOffset, float yOffset)

Sets up some additional settings used by gun mount spawning when using setMountedGuns

giveBonusCredit()

Sets bonus credits depending on the player count And displays UI.BonusCredit or UI.BonusCredits text

Note: This does not give credits, it simply gives "bonus credits" these will have to be converted via convertBonusCreditsToCredits

giveMissionCompleteEndBonus()

Sets endBonus to 250000

giveAreaBonus()

Sets bonus depending on what the total hit percentage and difficulty is. It will also display text depending on a few conditions such as:

  • passive resistance: UI.SpecialBonus
  • 100% total completion: UI.PerfectBonus
  • Getting a bonus: UI.Bonus
  • Not getting a bonus: UI.NoBonus

convertBonusCreditsToCredits()

Converts bonus credits gained by giveBonusCredit to credits This command will repeat with a wait time of 20 ticks for each bonus credit given

convertCreditsToEndBonus()

Converts credits to endBonus This command will repeat with a wait time of 30 ticks for each credit converted

convertLivesToEndBonus()

Converts lives to endBonus This command will repeat with a wait time of 15 ticks for each life converted

convertEndBonusToPoints()

Converts a random amount of endBonus to score This command will repeat with a wait time of 1 tick until all endBonus is converted to score

convertBonusToPoints()

Converts a random amount of bonus to score This command will repeat with a wait time of 1 tick until all bonus is converted to score

setBestScoreToLevelScore()

Sets the "previous best" score that you would see after a continue to whatever the level score is This is used for endless to display the previous score

unlockNastyDifficulty()

Triggers nasty difficulty to unlock

setBackgroundSpeedMultiplier(float multiplier)

Set the speed multiplier of background tiles

setSmok(bool enabled)

Enables/Disables the smoke shown at the top of the screen

setSmokScrollMultiplier(float value)

Set the speed changes applied per layer on background smoke

setSmokLayerOffset(float value)

Set the smoke y-offset applied per layer on background smoke

setSmokConstantOffset(float value)

Sets the general constant y offset applied to background smoke

setBonusCounter(int bonus, int value)

Sets the amount of kills needed to trigger the bonus on the specified bonus index

setBonusReward(int bonus, int type)

Sets the bonus on the specified index to give a specified about of points (type)

setBonusReward(int bonus, string type)

Sets the bonus on the specified index to give a specified star (type)

setDayTintColor(Color color)

Set the tint color used while it is daytime

setNightTintColor(Color color)

Set the tint color used while it is nighttime

setFogColor(Color color)

Set the fog tint applied to layers in the distance applied to background elements

setFogDensity(float value)

Set the density of the fog applied to background elements

setFrontLayerFadeoutParams(float startPos, float endPos, float startAlpha, float endAlpha)

startPos: When the fadeout starts lerping from startAlpha to endAlpha endPos: When the fadeout reaches endAlpha, 100 for all the way at the bottom Sets parameters used for fading out the foreground layer (the layer that is above the player ship)

resetPassiveResistance()

Resets passive resistance such that we can be awarded it again

monorailStart()

Spawns the initial monorail piece

monorailSetHeight(int height)

Sets the target height for the monorail, any existing monorail instances will try to move up and down to reach it Keep in mind that due to tiling, not all heights can be achieved

monorailEnd()

Queues the monorail to move down and despawn once hitting the end

orangeFish(int x, int y, string name = "orangeFish", int scriptIndex = 0)

Spawns an entity, by default "orangeFish" scriptIndex refers to the index used in setFighterScript command

saucer(int x, int y, string name = "saucer", float speedY = entityData[speed], float maxSpeedY = entityData[speed] * 1.25)

Spawns an entity, by default "saucer"

goldfish(int x, int y, string name = "goldFish", float mx = -7, float my = 0, int fireCount = 1)

Spawns an entity, by default "goldFish"

blackFish(int x, int y, string name = "blackFish")

Spawns an entity, by default "blackFish"

squid(int x, int y, string name = "squid", float focus_y = 500, float focus_x = 350)

Spawns an entity, by default "squid"

bigSquid(int x, int y, string name = "bigSquid", float focus_y = 500, float focus_x = 350)

Spawns an entity, by default "bigSquid"

laserSquid(int x, int y, string name = "laserSquid", float focus_y = 550, float focus_x = 300)

Spawns an entity, by default "laserSquid"

randSaucers(int minX, int maxX, int minY, int maxY, int amount, float speedY = entityData[speed], float maxSpeedY = entityData[speed] * 1.25)

Spawns amount count of "saucer" entities randomly between the min and max position values

randFish(int minX, int maxX, int minY, int maxY, int amount)

Spawns amount count of "randFish" entities randomly between the min and max position values

monorailCart(float railSpeed = 0.03, string childEntity = "", Dict childArgs = )

Spawns a "monorailCart" entity

makeTanksAndBuilding(int tanks, int item)

Create tanks "tank" entities and one building with the specified item in it (fruit set)

makePylons()

Create a collection of "pylon" and "powerLine" entities

balloon(int x, int y, int bonus_type, float mx = 0.5, float my = 0, int bframe = 0, int boxtype = 0, int invultime = 60)

Spawns a balloon entity with the specified box content bonus_type: 0: No box 1: Coins 2: Doubler Item 3: Weapon Pods

safe(int x, int y, int bonus_type, float mx = 0.5, float my = 0, int bframe = 0, int boxtype = 0, int invultime = 60)

Spawns a safeBalloon entity with the specified box content bonus_type: 0: No box 1: Coins 2: Doubler Item 3: Weapon Pods

fastShip(int bonus = -1, float mx = -8, float my = 0)

Spawns a fastShip entity, this command will skip every x executions based on the player selected difficulty

makeEruption()

Spawns a bunch of rocks both in the background and foreground When supported, will create a bunch of background rocks on a "VulcanoBehaviour" flying upwards

spawnEntity(string entity, int x = 0, int y = 0, bool skipInFastForward = true)

Spawns the specified entity, all arguments passed to this command are passed to the underlying entity. So spawnEntity("entity": "balloon", "x": 200, "y": 100, "skipInFastForward": true, "boxtype": 1) will spawn a balloon with a box

makeBirds(int number, float xdir = random(-1, 1), float ydir = random(-0.5, 0.5))

Spawns a specified amount of birds

makeParrots(int number, float xdir = random(-1, 1), float ydir = random(0, 2), int counter = 0)

Spawns a specified amount of parrots

spawnBackgroundSprite(float x = -1, float y = -1, float mx = -1, float my = -1, int layer = 12, string sprite = "")

Spawns a "moon" entity with the specified arguments

redSaucer1(float x = -1, float y = -1, string name = "redSaucer", float speedY = entityData[speed], float maxSpeedY = entityData[speed] * 1.25)

The value of x is "automagically" increased by 660 for your "convenience"

greenBigUn(float x = -100, float y = -1, string name = "greenBigUn", float acceleration = 0.002)

Spawns an entity, by default "greenBigUn"

redBigUn(float x = -100, float y = -1, string name = "redBigUn")

Spawns an entity, by default "redBigUn"

purpleBigUn(float x = -200, float y = -1, string name = "purpleBigUn")

Spawns an entity, by default "purpleBigUn"

flipPlane(float x = -100, float y = -1, string name = "flipPlane")

Spawns an entity, by default "flipPlane"

gunship(float x = -200, float y = -1, string name = "gunship", int position_adjust = 0)

Spawns an entity, by default "gunship"

bigThrusterShip(float x = -100, float y = -1, string name = "bigThrusterShip", float mx = 5, float my = 0)

Spawns an entity, by default "bigThrusterShip"

homingShip(float x = 740, float y = -1, string name = "homingShip", float mx = -5.5)

Spawns an entity, by default "homingShip"

dragonfly(float x = -100, float y = -1, string name = "dragonfly", float acceleration = 0.01, string starType = "")

Spawns an entity, by default "dragonfly"

bomb(float x = -1, float y = -1, string name = "floatingBomb", float mx = 0, float my = 0, float string_length = 150, float start_length = string_length, int invulnCounter = 0, int deadly = 0)

Spawns an entity, by default "floatingBomb"

backBomb(float x = 700, float y = -1, string name = "back_bomb", float mx = rand(-0.55, -0.45))

Spawns an entity, by default "back_bomb"

backBoss2(float x = -360, float y = 500, int layer = 6, string name = "back_boss2", float mx = 0.25, float my = 0)

Spawns an entity, by default "back_boss2"

distantIsland(float x = 750, float y = 450, string name = "distant_island")

Spawns an entity, by default "distant_island"

ray(float x = rand(700, 800), float y = rand(150, 450), string name = "ray", int direction = 0)

Spawns an entity, by default "ray" Directions: 0=Random, 1=Up, 2=Down

missileBoat(float x = -80, float y = 546, string name = "missileBoat")

Spawns an entity, by default "missileBoat"

cannonBoat(float x = -150, float y = 520, string name = "cannonBoat")

Spawns an entity, by default "cannonBoat"

cargoBoat(float x = 900, float y = 370, string name = "cargoBoat", float mx = 0)

Spawns an entity, by default "cargoBoat"

distantBoat(float x = 700, float y = rand(150, 450), string name = "distantBoat", float mx = rand(-0.2, -0.1))

Spawns an entity, by default "distantBoat"

blimp(float x = 700, float y = -1, string name = "blimp", string message)

Spawns an entity, by default "blimp" "message" is the localized text string to use

backGreenBigUn(float x = -40, float y = -1, float mx = rand(0.25, 0.35), string name = "backGreenBigUn")

Spawns an entity, by default "backGreenBigUn"

backRedBigUn(float x = -40, float y = -1, float mx = rand(0.45, 0.55), string name = "backRedBigUn")

Spawns an entity, by default "backRedBigUn"

makeTrain(string[] carts, int[] cartFruitSets)

Triggers boss1, with the specified carts and specified fruit sets within those carts Make sure these two arrays are of the same size

bigPlane(int targetX, int targetY)

Spawns the initial bigPlane entity, starting the boss2 fight

sub()

Spawns the sub entity, starting the boss3 fight

squidMother()

Spawns the squidMother entity, starting the boss4 fight

ifPassiveResistance(int places)

Only execute the next places commands, if passive resistance is currently in affect

ifMultiplayer(int places)

Only execute the next places commands, if multiple players are connected at the time of execution

ifSingleplayer(int places)

Only execute the next places commands, if only one player is connected at the time of execution

skipIfNoDemo(int places)

Only execute the next places commands, if we are in demo mode

skipIfDiffAbove()

Only execute the next places commands, if the current difficulty is higher than the specified one Valid difficulty names are: "VeryEasy" (Easy), "Easy" (Regular), "Medium" (Hard), "Hard" (Expert) and "Nasty" (Nasty)

skipIfDiffBelow(GameDifficulty difficulty, int places)

Only execute the next places commands, if the current difficulty is lower than the specified one Valid difficulty names are: "VeryEasy" (Easy), "Easy" (Regular), "Medium" (Hard), "Hard" (Expert) and "Nasty" (Nasty)

skipIfDiffEqual(GameDifficulty difficulty, int places)

Only execute the next places commands, if the current difficulty is not the specified one Valid difficulty names are: "VeryEasy" (Easy), "Easy" (Regular), "Medium" (Hard), "Hard" (Expert) and "Nasty" (Nasty)

ifDifficultyIs(GameDifficulty difficulty, int places)

Only execute the next places commands, if the current difficulty is the specified one Valid difficulty names are: "VeryEasy" (Easy), "Easy" (Regular), "Medium" (Hard), "Hard" (Expert) and "Nasty" (Nasty)

skipIfLevelTimeAbove(int value, int places)

Only execute the next places commands, if the time spent in the level is lower than the specified value Value in ticks since start of the level

skipIfLevelTimeBelow(int value, int places)

Only execute the next places commands, if the time spent in the level is higher than the specified value Value in ticks since start of the level

ifNoEnemyOnScreen(int places)

Only execute the next places commands, if no entity marked "isEnemy" is alive

ifEnemyOnScreen()

Only execute the next places commands, if an entity marked "isEnemy" is alive

ifSpecificEntityOnScreen(string entity, int places)

Only execute the next places commands, if a specific entity is alive This can be used to extend longer fights with more enemies if the main enemy is still alive

ifPracticeMode(int places)

Only execute the next places commands, if the current game mode is practice

ifNotFastForwarding(int places)

Only execute the next places commands, if we are not currently fast forwarding for whatever reason

ifFastForwarding(int places)

Only execute the next places commands, if we are fast forwarding