Alchemic Cutie Logo

Setting up

To get started with modding in Alchemic Cutie, you’ll need to download the following:

  • Tiled

  • Alchemic Cutie Modding Toolkit

Tiled

Download and install the latest Tiled version from here.

Alchemic Cutie Modding Toolkit

TODO: Doc here

Creating a mod

Directory Structure

The following directory structure is used for mods.

.cache/                    -- Cache files generated by the toolkit (Do not touch)
_generated/                -- Files generated by the toolkit (Do not touch)
_jelly_sprites/            -- Base sprites for generating Jelly sprites
config/
  egg-types/               -- Jelly egg type XML data
  item-effect-templates/   -- Item effect template XML data
  items/                   -- Item XML data
  item-spawn-templates/    -- Item spawn template XML data
  jelly-palettes/          -- Jelly color palette XML data
  jelly-shapes/            -- Jelly shape XML data
  jelly-traits/            -- Jelly trait XML data
  jelly-spawn-templates/   -- Jelly spawn template XML data
  npcs/                    -- NPC XML data
  resource-node-templates/ -- Resource node template XML data
  shops/                   -- Shop XML data
  stamps/                  -- Quest stamps XML data
l10n/                      -- Localisation data
maps/                      -- Tiled maps/tilesets/objects
music/                     -- Music files
scripts/                   -- Lua scripts
sfx/                       -- Sound effect files
textures/
  characters/              -- Character textures, each subdirectory represents 1 NPC
  items/                   -- Item textures
  resourceNodes/           -- Resource node textures
  maps/                    -- Copies of additional tilesets used
  jellies/                 -- Jelly textures
mod.xml                    -- Mod information

Testing your mod

Publishing your mod

Game World

Tiled is the world editor used in Alchemic Cutie.

World Layout

In Alchemic Cutie, the game world is a 200x200 grid of maps, ranging from coordinates -100,100 to 99,99.

Any maps placed between -100,-100 and -50,-50 are considered indoor maps. These maps will not render their surrounding maps.

Tile Layers

Collisions

A Collisions tile layer is required on every map. This layer marks where the player will collide with non-interactable collisions, e.g. buildings, non-resource bushes, etc.

This layer also marks determines when the player will be rendered. Layers below this layer are rendered below the player and any layers above this layer are rendered above the player.

Bridge

A Bridge tile layer is required on any map that uses a fixed bridge in which the player can walk over and under. The layer, when defined, must be 1 layer higher than the Collisions layer. Paint the bridge tiles to this layer and define the correspond objects to trigger the layer change for the player.

Warning: Bridge is a reserved tile layer name. Using this for bridges that cannot be walked under will have unintented side effects.

Map Properties

The following properties can be set on each Tiled map.

Property Name Required Description

outsideLocation

No

On indoor maps, this is the name of the waypoint representing the outdoor location. This is used for tracking NPCs on the world map when they go indoors.

coopX

No

The tile X of the Jelly farm area on this map (Note: only one farm is allowed in the world)

coopY

No

The tile Y of the Jelly farm area on this map (Note: only one farm is allowed in the world)

coopWidth

No

The width in tiles of the Jelly farm area

coopHeight

No

The height in tiles of the Jelly farm area

ambience

No

See ambience section of mod guide

disableInWaterOverlay

No

When added and enabled, it will prevent in water overlay being shown

World Objects

Alchemic Cutie makes use of Tiled object templates feature to define objects in the game world.

The following object templates are provided and can be used to place objects in the game world. These can be placed on any Object Layer in Tiled as long the properties are set correctly.

Note that object layers should be uniquely name to avoid map loading errors.

Note that the game engine does not support rotated Tiled objects.

Bed Tile

This object type defines a bed zone the player can use to sleep to pass the time and regain energy. Upon entering the area the player will be prompted to sleep for a given period of time.

Property Name Sample Value Description

type

bed

This must be set to bed

Trees

This object type defines a tree on the map.

Note: If using a tileset to visually place the trees, this tileset needs to be ignored by the game engine. To do so, create your objects as Tiled Object Templates.

Property Name Sample Value Description

type

tree

This must be set to tree

treeType

OAK

Can be OAK or PINE

large

true

Sets to false for a regular sized tree.

Shadow

This object type defines a shadow zone. Entities will be shadowed if intersecting or contained in the area. Shadow zones will be generated for trees automatically.

Property Name Sample Value Description

type

shadow

This must be set to shadow

Tall Grass

This object type defines a patch of tall grass. Does not regrow in autumn.

Property Name Sample Value Description

type

grass

This must be set to grass

up

tallGrass/grassClumpB00

The default texture who no character is touching the grass

up

tallGrass/grassClumpB00down

The texture to show when a character has stepped on the grass

Leaf Pile

This object type defines a pile of leaves. It will regrow over time.

Property Name Sample Value Description

type

leaf-pile

This must be set to leaf-pile

size

LARGE

The size of the pile, can be: SMALL, MEDIUM or LARGE

Balloon Stalks

This object type defines a balloon stalk plant. It will regrow over time.

Property Name Sample Value Description

type

balloon-stalk

This must be set to balloon-stalk

color

GREEN

The color of the stalk when alchemy is used, can be: BLUE, GREEN or ORANGE

Energetic Sprouts

This object type defines a group of energetic sprout plants. They will regrow over time.

Property Name Sample Value Description

type

energetic-sprouts

This must be set to energetic-sprouts

sproutType

C

The sprout type, can be: A, B, C or D

Stinker

This object type defines a stinker plant. It can only be regrown by alchemy.

Property Name Sample Value Description

type

stinker

This must be set to stinker

Warps

This object type defines warp points between maps. All warps are uni-directional.

Property Name Sample Value Required Description

type

warp

Yes

This must be set to warp

targetLocation

house-titus

No

The waypoint location to warp to (Note: overrides targetMapX, targetMapY, targetTileX, targetTileY)

targetMapX

-50

No

The world X coordinate of the target map to warp to

targetMapY

-50

No

The world Y coordinate of the target map to warp to

targetTileX

47

No

The tile X coordinate on the target map to warp the player to

targetTileY

31

No

The tile Y coordinate on the target map to warp the player to

arrowDirection

SOUTH

No

When indoors for a long period of time, a small arrow will appear on the warp tile. Value can be NORTH, SOUTH, EAST or WEST.

questKey

skeezer-quest-1

No

The quest that this warp tile depends on

questState

ACTIVATED,COMPLETE

No

The quest states required to activate the warp tile. Can be: HIDDEN, ACTIVATED or COMPLETE. Multiple states must be seperated by a comma.

daysActive

*, 0, 2-4, 0,2,4,6

No

The days (0 = Monday, 1 = Tuesday, etc.) that this warp tile is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

hoursActive

*, 9, 16-23, 0,10,17,20

No

The hours (0 to 23) that this warp tile is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

Decoration Objects

This object type defines map decorations that are non-interactable. Note that the textures for each season must be the same dimensions.

Note: If using a tileset to visually place the objects, this tileset needs to be ignored by the game engine. To do so, create your objects as Tiled Object Templates.

Property Name Sample Value Description

type

decoration

This must be set to warp

decorationType

CHRISTMAS_LIGHTS

Internal name for caching textures, can be any value

texturePath

decorations/lights.png

The texture to use for all seasons (overrides all seasonal values)

springTexturePath

decorations/lights.png

The texture to use during Spring

summerTexturePath

decorations/lights.png

The texture to use during Summer

autumnTexturePath

decorations/lights.png

The texture to use during Autumn

winterTexturePath

decorations/lights.png

The texture to use during Winter

zIndex

0

Determines render layer. 0 = same layer as player, -1,-2,etc. = below player, 1,2,etc. = above player

frameWidth

32

The width of an individual animation frame from the texture. If not specified, will default to tiled object width.

frameHeight

32

The height of an individual animation frame from the texture. If not specified, will default to tiled object height.

frameDurations

0.1,0.15,0.1

The duration (in seconds) of each frame of the animation separated by commas. Must match total frames.

collidable

true

True if the player collides with this decoration.

disable

false

If false the decoration will render and have a collision if collidable. If true won’t render and is not collidable. This value is not required. Defaults to false if not included. Can be controlled through scripts.

uniqueId

Test_Decoration

A unique id used to identify the decoration for scripting purposes.

collisionAnchor

CENTER

Where the collision box is anchored to, relative to the tiled object. Can be TOP, BOTTOM, LEFT, RIGHT, CENTER, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT or BOTTOM_RIGHT

collisionXOffset

0

The X offset of the collision box after anchoring

collisionYOffset

0

The Y offset of the collision box after anchoring

collisionWidth

32

The collision box width. If not specified, will default to tiled object width.

collisionHeight

32

The collision box height. If not specified, will default to tiled object height.

spriteAnchor

CENTER

Where the sprite is anchored to, relative to the collision box. This is useful if the sprite is larger than the collision area. Can be TOP, BOTTOM, LEFT, RIGHT, CENTER, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT or BOTTOM_RIGHT.

Box Storage

This object type defines a storage box that the player can place items into. Optionally, the box can be marked for weekly item deliveries and lost and found.

Property Name Sample Value Required Description

type

storage

Yes

This must be set to storage

tabs

1

Yes

The storage capacity in tabs (each tab can store 25 items). The capacity will determine the sprite used.

disableSprite

false

No

true if no sprite should be generated and the object position/size should be used directly as an interaction

weeklyDelivery

false

No

true if the storage is for weekly deliveries (only 1 allowed in game world)

lostAndFound

false

No

true if storage is for lost and found items (only 1 allowed in game world)

postInteractScript

scripts/example.lua

No

Script to invoke after the player has finished interacting with the box

Item

This object type places a single item in the game world. Once the player has collected this item, it will no longer appear.

Property Name Sample Value Description

type

item

This must be set to item

item

Gritberry

The internal name of the item to spawn

Hidden Item

This object type places a treasure marker in the game world that requires a Jelly with the Explorer trait to find and alchemy to dig up.

Property Name Sample Value Required Description

type

hidden-item

Yes

This must be set to hidden-item

item

Gritberry

Yes

The internal name of the item that is hidden

quantity

1

Yes

The number of items to spawn when "dug up"

questKey

skeezer-quest-1

No

The quest that this trigger depends on

objectiveKey

skeezer-quest-1-obj-1

No

The quest objective that this trigger depends on

questState

ACTIVATED,COMPLETE

No

The quest states required to activate the trigger. Can be: HIDDEN, ACTIVATED or COMPLETE if no objective key is set. Can be: ACTIVATED, SKIPPED, SUCCESS, or FAILED if an objective key is set. Multiple states must be seperated by a comma.

daysActive

*, 0, 2-4, 0,2,4,6

No

The days (0 = Monday, 1 = Tuesday, etc.) that this trigger is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

hoursActive

*, 9, 16-23, 0,10,17,20

No

The hours (0 to 23) that this trigger is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

Resource Node

This object type defines a fixed position resource node in the game world.

Property Name Sample Value Description

type

resource

This must be set to resource

template

Flower

The internal name of the resource node template to use

Jelly Spawn Areas

This object type defines an area where Jellies will spawn. When adding templates to a spawn area more specific templates have priority over less specific templates.

Property Name Sample Value Description

type

spawn-jellies

This must be set to spawn-jellies

minJellies

0

The minimum number of jellies to spawn

maxJellies

3

The maximum number of jellies to spawn

spawnEvent

earthquake

(Optional) The event that triggers this spawn area

template

fields

This is a utility property for setting Jelly Spawn Template for all seasons

springTemplate

fieldsSpring

The internal name of the Jelly Spawn Template to use for Spring

springMorningTemplate

fieldsSpringMorning

The internal name of the Jelly Spawn Template to use for morning time in Spring.

springAfternoonTemplate

fieldsSpringAfternoon

The internal name of the Jelly Spawn Template to use for afternoon in Spring

springEveningTemplate

fieldsSpringEvening

The internal name of the Jelly Spawn Template to use for evening in Spring

springNightTemplate

fieldsSpringNight

The internal name of the Jelly Spawn Template to use for night in Spring

summerTemplate

fieldsSummer

The internal name of the Jelly Spawn Template to use for Summer

summerMorningTemplate

fieldsSummerMorning

The internal name of the Jelly Spawn Template to use for morning time in Summer

summerAfternoonTemplate

fieldsSummerAfternoon

The internal name of the Jelly Spawn Template to use for afternoon in Summer

summerEveningTemplate

fieldsSummerEvening

The internal name of the Jelly Spawn Template to use for evening in Summer

summerNightTemplate

fieldsSummerNight

The internal name of the Jelly Spawn Template to use for night in Summer

autumnTemplate

fieldsAutumn

The internal name of the Jelly Spawn Template to use for Autumn

autumnMorningTemplate

fieldsAutumnMorning

The internal name of the Jelly Spawn Template to use for morning time in Autumn

autumnAfternoonTemplate

fieldsAutumnAfternoon

The internal name of the Jelly Spawn Template to use for afternoon in Autumn

autumnEveningTemplate

fieldsAutumnEvening

The internal name of the Jelly Spawn Template to use for evening in Autumn

autumnNightTemplate

fieldsAutumnNight

The internal name of the Jelly Spawn Template to use for night in Autumn

winterTemplate

fieldsWinter

The internal name of the Jelly Spawn Template to use for Winter

winterMorningTemplate

fieldsWinterMorning

The internal name of the Jelly Spawn Template to use for morning time in Winter

winterAfternoonTemplate

fieldsWinterAfternoon

The internal name of the Jelly Spawn Template to use for afternoon in Winter

winterEveningTemplate

fieldsWinterEvening

The internal name of the Jelly Spawn Template to use for evening in Winter

winterNightTemplate

fieldsWinterNight

The internal name of the Jelly Spawn Template to use for night in Winter

Item Spawn Areas

This object type defines an area where Items will spawn.

Property Name Sample Value Description

type

spawn-items

This must be set to spawn-items

hidden

true

If set to true all items that spawn from this area will be hidden.

minItems

0

The minimum number of items to spawn

maxItems

3

The maximum number of items to spawn

template

fields

This is a utility property for setting Item Spawn Template for all seasons

springTemplate

fieldsSpring

The internal name of the Item Spawn Template to use for Spring

summerTemplate

fieldsSummer

The internal name of the Item Spawn Template to use for Summer

autumnTemplate

fieldsAutumn

The internal name of the Item Spawn Template to use for Autumn

winterTemplate

fieldsWinter

The internal name of the Item Spawn Template to use for Winter

Resource Node Spawn Areas

This object type defines an area where Resource Nodes will spawn.

Property Name Sample Value Description

type

spawn-resource-nodes

This must be set to spawn-resource-nodes

minNodes

0

The minimum number of resource nodes to spawn

maxNodes

3

The maximum number of resource nodes to spawn

resourceNodeTemplateNames

berry grass,dustroot

The names of the resource node templates that can spawn.

resourceNodePercentages

60,40

The percentage chance for each possible resource node (must total to 100)

Ghost Spawn Areas

This object type defines an area where Jelly ghosts will spawn. Note that ghosts will change area every 24 hours unless spawned via a script.

Property Name Sample Value Description

type

spawn-ghosts

This must be set to spawn-ghosts

Forest Trigger

This object type defines the area where the the forest overlay fades in/out.

Property Name Sample Value Description

type

forest-shadow

This must be set to forest-shadow

fadeInDirection

SOUTH

The direction the player will be moving when the trigger fades in, e.g. when set to SOUTH, the overlay will be invisible when the player is at the top of the object then fully visible when at the bottom.

Mountain Steam Trigger

This object type defines the area where the the mountain steam overlay fades in/out.

Property Name Sample Value Description

type

mountain-steam

This must be set to mountain-steam

fadeInDirection

SOUTH

The direction the player will be moving when the trigger fades in, e.g. when set to SOUTH, the overlay will be invisible when the player is at the top of the object then fully visible when at the bottom.

Mountain Top Steam Trigger

This object type defines the area where the the mountain top steam layer fades in/out.

Property Name Sample Value Description

type

mountain-steam

This must be set to mountain-steam

fadeOutDirection

SOUTH

The direction the player will be moving when the layer fades out, e.g. when set to SOUTH, the layer will be invisible when the player is at the bottom of the object then fully visible when at the top.

Waypoints

This object type is a utility type allowing for locations to be referenced by name rather than a map coordinate.

Property Name Sample Value Description

type

waypoint

This must be set to waypoint

location

house-tim

The location name that can be referenced in scripts and other objects.

Pathfinding

This object type provides hints to the pathfinding system to increase/decrease likelihood of the area being used during pathfinding. For example, we increase the likelihood of a path being used by decreasing the weight of the path areas.

Property Name Sample Value Description

type

pathfinding

This must be set to pathfinding

weight

0.5

The cost/weight of the using area for a path (higher values increase the cost). Defaults to 1.0 if not provided.

Shrines

This object type defines the shrine map object, used for plinths and altars in game. Altars are generally used to progress to the next major area. Plinths are generally used to unlock shortcuts. A script is required for altars, as it controlls what happens when the altar is finished. For plinths, the script is optional.

Property Name Sample Value Description

type

shrine

This must be set to shrine

groupId

testGroup

The name of the group the shrine belongs to.

internalName

testAltar

The internal name of the shrine itself, which should be unique.

script

altar-complete.lua

The path to the script to play once the shrine is complete.

shrineType

altar

This should be set to altar or plinth.

Shrine Lights

This object type defines the shrine light map object. There are two types of shrine lights, progression and temple_linked. The number of progression lights in a group determine the amount of times the shrine must be activated before it will complete. Altars should have exactly two shrine lights of the temple_linked type in the same shrine group, usually one where the Altar is, and one at the temple the altar is linked to. The reveal order for these temple_linked should be set to 1 and 2. The reveal order for progression lights should be squential starting at 1. For example if you had 3 progression lights in a groupd they should have reveal orders, 1, 2, and 3.

Property Name Sample Value Description

type

shrine-light

This must be set to shrine-light

cameraTargetWaypoint

targetWaypoint

The waypoint the camera will move to when the light is lighting.

groupId

testGroup

The name of the group the shrine light belongs to.

internalName

testLight

The internal name of the shrine light itself, which should be unique.

lightType

progression

The type of the light, this should be progression or temple_linked

revealOrder

1

This is the order that the lights are turned on. Minimum value of 1.

templeTargetWaypoint

templeTargetWaypoint

The waypoint the camera will move to when the altar is complete.

Temple Doors

This object type defines the temple door map object. The door will only be interactable once all the shrine groups it is attached to are completed. In most cases there are three shrine groups to complete before the door will become interactable.

Property Name Sample Value Description

type

temple-door

This must be set to temple-door

internalName

testTempleDoor

The internal name of the templedoor itself, which should be unique.

script

testTempleScript.lua

The script that is invoked once the door is interacted with.

shrineGroups

testGroup1:testGroup2:testGroup3

The shrine group ids of the groups related to this temple. The should be separated by the : symbol.

Shortcuts

This object type defines the area used for a shortcut. Each shortcut should be linked to a plinth by a groupId. Shortcuts should be 32 pixels wide along their shortest side. Layer change objects will be generated automatically, their position and thickness can be customised using the properties described below.

Property Name Sample Value Description

type

shortcut

This must be set to shortcut

internalName

testGroupShortcut1

The internal name of the shortcut itself, which should be unique.

groupId

testGroup

The name of the group the shortcut belongs to. More than one shortcut can belong to a group.

orientation

horizontal

The orientation should be set to horizontal or vertical.

revealDirection

east

This should be set to a cardinal direction, north or south for vertical, east or west for horizontal.

shortcutColor

blue

This is the color of the shortcut clouds should be pink, purple, or blue. Will default to blue.

The properties below are optional and used to customise the layer changes that will be generated for the shortcut.

Property Name Default Value Description

offsetBottom

0

Offset of the bottom two layer changes, positive values move the layer changes down.

offsetLeft

0

Offset of the left two layer changes, positive values move the layer changes right.

offsetRight

0

Offset of the right two layer changes, positive values move the layer changes right.

offsetTop

0

Offset of the top two layer changes, positive values move the layer changes down.

widthBottomInner

8

The width of the inner of the bottom two layer changes.

widthBottomOuter

8

The width of the outer of the bottom two layer changes.

widthLeftInner

8

The width of the inner of the left two layer changes.

widthLeftOuter

8

The width of the outer of the left two layer changes.

widthRightInner

8

The width of the inner of the right two layer changes.

widthRightOuter

8

The width of the outer of the right two layer changes.

widthTopInner

8

The width of the inner of the top two layer changes.

widthTopOuter

8

The width of the outer of the top two layer changes.

These images show the default layer changes that are created for a shortcut.

Shortcut Example 2 Shortcut Example 1

The left layer changes, 3 and 4, are by default created so that the left edge of 3 lines up with the left hand edge of the shortcut as seen in the second image above.

Note: Changing the left offset will change the position of the left edge of 3, negative values will move it to the left, positive values will move it to the right.

The right layer changes, 5 and 6, are by default created so that the right edge of 6 lines up with the right hand edge of the shortcut as seen in the second image above.

Note: Changing the right offset will change the position of the right edge of 6, negative values will move it to the left, positive values will move it to the right.

The top layer changes, 1 and 2, are by default created so that the bottom edge of 2 lines up with the top edge of the shortcut as seen in the second image above. The lenght of the top layer changes is the distance between 4 and 5.

Note: Changing the top offset will change the position of the bottom edge of 2, negative values will move it upwards, positive values will move it downwards.

The bottom layer changes, 7 and 8, are by default created so that the top edge of 7 lines up with the bottom edge of the shortcut as seen in the second image above. The lenght of the top layer changes is the distance between 4 and 5.

Note: Changing the bottom offset will change the position of the top edge of 7, negative vaules will move it upwards, positive values will move it downwards.

In the example above, when walking onto the shortcut from either of the short ends, when the player collision box hits 4 or 5, the players layer position will be changed to be above the shortcut. While this is the case 2 and 7 become impassable to the player, stopping them from walking off the edge of the shortcut. As the player is leaving the bridge they will hit either 3 or 6, which will set their layer position back to default.

When walking under the shortcut from either of the long ends, when the player collision box hits 2 or 7, the players layer position will be changed to be below the shortcut. While this is the case 4 and 5 become impassable to the player, stopping them from walking out under the ends of the shortcut. As the player is leaving under the bridge they will hit either 1 or 8, which will set their layer position back to default.

Script Trigger

This object defines an area that will trigger a script when the player collides with it.

Property Name Sample Value Required Description

type

script

Yes

This must be set to script

script

scripts/example.lua

Yes

The path to the lua script to invoke

collision

false

No

true if the player should collide with the object or is allowed to move inside it

disableMovementInput

false

No

true if movement input should be immediately disabled when the script is triggered

repeatable

true

No

false if the player can only trigger this once per playthrough of the game. true if the trigger should be re-enabled each day. (Defaults to false)

questKey

skeezer-quest-1

No

The quest that this trigger depends on

objectiveKey

skeezer-quest-1-obj-1

No

The quest objective that this trigger depends on

questState

ACTIVATED,COMPLETE

No

The quest states required to activate the trigger. Can be: HIDDEN, ACTIVATED or COMPLETE if no objective key is set. Can be: ACTIVATED, SKIPPED, SUCCESS, or FAILED if an objective key is set. Multiple states must be seperated by a comma.

daysActive

*, 0, 2-4, 0,2,4,6

No

The days (0 = Monday, 1 = Tuesday, etc.) that this trigger is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

hoursActive

*, 9, 16-23, 0,10,17,20

No

The hours (0 to 23) that this trigger is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

priority

1

No

The execution priority of the trigger’s script (0 to 4). Attached scripts default to interactive priority (4) which is the highest and shouldn’t be changed if the script contains dialogue. Priority 4 allows for only one script of this priority executing at one time, otherwise it will be queued and executed when possible.

customId

event_blockStairsForPlayer

No

Unique identifier for script trigger. Used in the setScriptTrigger(String customId, boolean triggeredValue) function in the lua scripts. In order for a script trigger to be always repeatable, the triggeredValue must be set to false.

Interaction

This object defines an area that will trigger a script when interacted with (player presses action button).

Property Name Sample Value Required Description

type

interaction

Yes

This must be set to interaction

script

scripts/example.lua

Yes

The path to the lua script to invoke

collidable

false

No

true if the player should collide with the object or move inside it or is allowed to move inside it

questKey

skeezer-quest-1

No

The quest that this trigger depends on

objectiveKey

skeezer-quest-1-obj-1

No

The quest objective that this trigger depends on

questState

ACTIVATED,COMPLETE

No

The quest states required to activate the trigger. Can be: HIDDEN, ACTIVATED or COMPLETE if no objective key is set. Can be: ACTIVATED, SKIPPED, SUCCESS, or FAILED if an objective key is set. Multiple states must be seperated by a comma.

daysActive

*, 0, 2-4, 0,2,4,6

No

The days (0 = Monday, 1 = Tuesday, etc.) that this trigger is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

hoursActive

*, 9, 16-23, 0,10,17,20

No

The hours (0 to 23) that this trigger is active on. Supports wildcard (*), ranges (0-3) and individual values seperated by commas.

priority

1

No

The execution priority of the attached script (0 to 4). Attached scripts default to interactive priority (4) which is the highest and shouldn’t be changed if the script contains dialogue. Priority 4 allows for only one script of this priority executing at one time, otherwise it will be queued and be executed when possible.

Small bird

This object type defines a single small bird. When player gets near it will fly away with near birds. Will respawn over time.

Property Name Sample Value Required Description

type

bird

true

This must be set to bird

color

blue

true

The bird color, can be: blue, brown, grey, pink, red, white or yellow

despawnHour

19

false

The hour at which the bird should automatically fly away

flyAwayScatterMinutes

20

false

The time interval (in minutes) during which the bird can fly away

spawnHour

5

false

The hour at which the bird should automatically fly back

flyBackScatterMinutes

20

false

The time interval (in minutes) during which the bird can fly back

Bugs

Bugs guide the player to nearby objects when alchemy is used on them. All the different bug types share some common properties

Property Name Sample Value Required Description

despawnHour

19

false

The hour at which the bug should despawn

spawnHour

5

false

The hour at which the bug should spawn

Note: different bug types have different defaults for optional attributes

Butterfly

This object type defines a single butterfly. When player uses alchemy it will fly to the nearest wild jelly.

Property Name Sample Value Required Description

type

butterfly

true

This must be set to butterfly

color

blue

true

The butterfly color, can be: blue, brown, pink, white or yellow

Property Name Default Value

despawnHour

18

spawnHour

6

Moth

This object type defines a single butterfly. When player uses alchemy it will fly to the nearest ghost.

Property Name Sample Value Required Description

type

moth

true

This must be set to moth

Property Name Default Value

despawnHour

5

spawnHour

21

Firefly

This object type defines a single firefly. When player uses alchemy it will fly to the nearest wild jelly.

Property Name Sample Value Required Description

type

firefly

true

This must be set to firefly

Property Name Default Value

despawnHour

5

spawnHour

21

Jellies

Jellies can be randomly spawned in the world via spawn zones.

Jelly Needs

Jellies have two main values for players to maintain; Food and Happiness.

Every game minute a Jelly loses 0.04 Food.

If Food drops below 25%, the Jelly loses 0.07 Happiness per game minute. If Food goes above 75%, the Jelly gains 0.3 Happiness per game minute.

Both of the values can be changed through Item Effects.

Jelly Traits

Jellies can be spawned with any of the following traits.

Trait Description

Anti-Hero

Applause

Archive

Blast Bowel

Boring

Bottom Feeder

Chroma Coach

Cuddly

Dead End

Dispel

Distill

Encore

Eterna-Jelly

Explorer

Extra Credit

Feedback

Fired Up

Friend Finder

Gifted

Glutton

Gotcha Gacha

Grump

Hibernate

Jackpot

Little Extra

Love Drunk

Love Machine

Luminous

Pillow Pooper

Power Nap

Quick Learner

Regret

Rival

Romantic

Smell Vendor

Solar Skin

Spirit Sense

Static Skin

Stress Eater

Sweet Dreams

Touchy-color

Transfer

Trendy

Trust Fund

Turbo Tummy

Were-jelly

Workaholic

Color Palettes

Jellies can be spawned with any of the following colors.

aqua

berry

blue

cake

carbon

cherry

coal

dart

dew

fruity

garbj

gb01

grape

gum

holo

lime

marble

mint

muk

oak

orange

pluto

rain

star

sunny

swamp

swirl

tropic

velvet

yella

yogi

zest

It is possible to add new color palettes via XML files in config/jelly-palettes/. The following is a sample color palette. Note: <bean><colorMix><basicColor> fields are optional. <bean> field allows to specify what kind of a bean a jelly of this colour will poop. Leaving it out will result in a plain Smelly Bean <colorMix> field allows to specify the resulting colour when a jelly of this colour and specified one breed as per below example <basicColor> field allows to specify if a colour can be obtained via touchy colours. All colours will be set to basic if not set manually to false!

<data>
  <id>-1</id>
  <internalName>aqua</internalName>
  <name>Aqua</name>
  <checklistStyle>winter</checklistStyle>
  <checklistDiscoveredIcon>ui/icons/checkList/icoCheckAqua</checklistDiscoveredIcon>
  <checklistUndiscoveredIcon>ui/icons/checkList/icoCheckAquaOff</checklistUndiscoveredIcon>
  <swatches length="8">
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>249.0</red>
      <green>254.0</green>
      <blue>216.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>210.0</red>
      <green>248.0</green>
      <blue>160.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>135.0</red>
      <green>240.0</green>
      <blue>180.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>6.0</red>
      <green>211.0</green>
      <blue>214.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>10.0</red>
      <green>182.0</green>
      <blue>187.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>14.0</red>
      <green>153.0</green>
      <blue>160.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>32.0</red>
      <green>132.0</green>
      <blue>133.0</blue>
      <alpha>1.0</alpha>
    </value>
    <value class="com.alchemiccutie.api.jelly.Swatch">
      <red>71.0</red>
      <green>91.0</green>
      <blue>79.0</blue>
      <alpha>1.0</alpha>
    </value>
  </swatches>
  <bean>Aqua Bean</bean>
  <basicColor>true</basicColor>
</data>

Jelly Shapes

Jellies can be spawned with any of the following shapes.

antz

axl

bleat

brella

bunny

cub

curio

donta

dowse

drip

eddy

fids

flum

joble

jolt

kit

melon

nits

oofoe

pig

pokey

pom

prong

purs

scene

smuth

spark

sprig

sprout

tedy

took

toro

It is possible to add new jelly shapes via XML files in config/jelly-shapes/. The following is a sample jelly shape. Note that all paths are relative to the textures directory.

<data>
  <id>-1</id>
  <internalName>fids</internalName>
  <name>Fids</name>
  <checklistStyle>summer</checklistStyle>
  <checklistDiscoveredIcon>ui/icons/checkList/icoCheckFids</checklistDiscoveredIcon>
  <checklistUndiscoveredIcon>ui/icons/checkList/icoCheckFidsOff</checklistUndiscoveredIcon>
  <eggType>quartz</eggType>
  <baseSpriteSheet>../_jelly_sprites/overworld/jelly/fids.png</baseSpriteSheet>
  <baseBagNorthSpriteSheet>../_jelly_sprites/bag/jelly/fids-n.png</baseBagNorthSpriteSheet>
  <baseBagEastSpriteSheet>../_jelly_sprites/bag/jelly/fids-e.png</baseBagEastSpriteSheet>
  <baseBagWestSpriteSheet>../_jelly_sprites/bag/jelly/fids-w.png</baseBagWestSpriteSheet>
  <baseHudImages>
    <entry>
      <key>IDLE</key>
      <value>../_jelly_sprites/hud/jelly/fids-idle.png</value>
    </entry>
    <entry>
      <key>BLINK</key>
      <value>../_jelly_sprites/hud/jelly/fids-blink.png</value>
    </entry>
  </baseHudImages>
  <basePortraitImage>../_jelly_sprites/dialogue/jelly/fids.png</basePortraitImage>
  <relicSpriteSheet>../_jelly_sprites/overworld/relic/fids.png</relicSpriteSheet>
  <relicBagNorthSpriteSheet>../_jelly_sprites/bag/relic/fids-n.png</relicBagNorthSpriteSheet>
  <relicBagEastSpriteSheet>../_jelly_sprites/bag/relic/fids-e.png</relicBagEastSpriteSheet>
  <relicBagWestSpriteSheet>../_jelly_sprites/bag/relic/fids-w.png</relicBagWestSpriteSheet>
  <relicHudImages>
    <entry>
      <key>IDLE</key>
      <value>../_jelly_sprites/hud/relic/fids-idle.png</value>
    </entry>
  </relicHudImages>
  <ghostPortraitImage>../_jelly_sprites/dialogue/ghost/fids.png</ghostPortraitImage>
  <ghostSpriteSheet>../_jelly_sprites/overworld/ghost/fids.png</ghostSpriteSheet>
</data>

Eggs

Jellies can breed and make eggs. Egg types hatch into a specific Jelly shape as defined in the Jelly Shape XML.

New egg types can be defined via XML files in config/egg-types/. It is also possible to shift the color palette for the egg type via the shift parameter in the XML file.

<data>
  <internalName>quartz</internalName>
  <baseSpriteSheet>../_jelly_sprites/overworld/egg/quartz.png</baseSpriteSheet>
  <baseBagNorthSpriteSheet>../_jelly_sprites/bag/egg/quartz-n.png</baseBagNorthSpriteSheet>
  <baseBagEastSpriteSheet>../_jelly_sprites/bag/egg/quartz-e.png</baseBagEastSpriteSheet>
  <baseBagWestSpriteSheet>../_jelly_sprites/bag/egg/quartz-w.png</baseBagWestSpriteSheet>
  <baseHudImages>
    <entry>
      <key>IDLE</key>
      <value>../_jelly_sprites/hud/egg/quartz-idle.png</value>
    </entry>
    <entry>
      <key>BLINK</key>
      <value>../_jelly_sprites/hud/egg/quartz-blink.png</value>
    </entry>
  </baseHudImages>
  <basePortraitImage>../_jelly_sprites/dialogue/egg/fids.png</basePortraitImage>
  <shift>1</shift>
</data>

Breeding

When two Jellies breed, the following logic determines the egg’s properties.

  1. Determine the Color, Shape and Nature

    1. If a parent has the Clone buff, use that Jelly’s Color, Shape and Nature

    2. Else, pick a Color and Shape from the parents with a random Nature

  2. Determine the stats

    1. If one parent is happier than the other, weight the selection of stats towards that parent by 10%

    2. For each stat, (weighted) randomly pick EXP from one of the parents

  3. Determine the max Food value

    1. If one parent is happier than the other, weight the selection of max Food towards that parent by 10%

    2. Randomly (weighted) pick the max Food from one of the parents

  4. Determine the Traits

    1. Pick a target amount of traits between 1 and the largest amount traits of the parents + 1

    2. For each trait slot, random choose between the corresponding trait slots in the parents

      1. If a parent has an Archive trait, it is applied

      2. If a parent has a Dead End trait, it is applied

      3. If a parent has an empty slot, the other parent is selected

      4. If both parents have an empty slot, a random trait is selected

  5. If a parent has the Transfer trait, it is applied

  6. If a parent has the Egg Hatch buff, it is applied

NPCs

Non-player characters (NPCs) are the villagers who wander Wimba Island. Apart from dialogue, NPCs can provide quests, items, shops and more to the player.

NPC XML

To add an NPC, an XML file must be created in the npcs directory. The following shows an example of an NPC XML file.

<data>
  <internalName>Skeezer</internalName>
  <name>Skeezer</name>
  <description>Skeezer travels the islands bartering with anyone who has a crystal to their internalName.</description>
  <age>10</age>
  <male>false</male>
  <jobTitle>Salesman</jobTitle>
  <homeLocation>Nowhere</homeLocation>
  <spriteInternalName>Skeezer</spriteInternalName>
  <speechPitch>HIGH</speechPitch>
  <animal>WOLF</animal>
  <dialogueScript>scripts/npc/skeezer.lua</dialogueScript>
  <competitionBlackListed>false</competitionBlackListed>
  <shopInternalName>skeezer</shopInternalName>
  <jellyFamiliar>
    <npcInternalName>rick</npcInternalName>
    <accessories length="1">
      <value>Aqua Flower</value>
    </accessories>
    <color>aqua</color>
    <shape>pig</shape>
    <blobLevel>50</blobLevel>
    <socialLevel>25</socialLevel>
    <tummyLevel>10</tummyLevel>
  </jellyFamiliar>
  <schedule length="0"/>
</data>
Attribute Required Description

name

Yes

The name of the NPC presented to the player (e.g. Grummin)

internalName

Yes

The name of the NPC used internally by the game engine. If you need to change the NPC’s name later on, only change the name field.

description

Yes

The description of the character that appears in the player’s notebook

age

Yes

The character’s age (-1 will display ???)

male

No

true if the character is male and the male sound banks should be used

jobTitle

Yes

The character’s job title to show in the player’s notebook

homeLocation

Yes

The character’s home location to show in the player’s notebook

spriteInternalName

Yes

The internal name of which sprite to use

speechPitch

Yes

The pitch of the character’s voice (LOW, MIDDLE_LOW, MIDDLE_HIGH, HIGH)

animal

Yes

The animal of the character (HUMAN, WOLF, PARROT, etc.). This is matched up to the speech configuration.

dialogueScript

Yes

The lua script to use for dialogue

sleepingScript

No

If used, the lua script to use while this NPC is sleeping and the player interacts, falls back to a default script.

shopInternalName

No

The internal name of the shop associated with this NPC.

schedule

Yes

The NPC’s schedule (see NPC Schedule section below)

jellyFamiliar

No

The NPC’s Jelly familiar data (see NPC Jelly Familiar section below)

NPC Schedule

Every NPC must have a schedule specified for them to follow. The following is an example of an NPC’s schedule file.

<schedule>
  <value class="com.alchemiccutie.api.npc.NpcScheduleEntry">
    <daysOfWeek>
      <value>4</value>
    </daysOfWeek>
    <hour>0</hour>
    <minute>0</minute>
    <mapX>-50</mapX>
    <mapY>-50</mapY>
    <tileX>41</tileX>
    <tileY>30</tileY>
    <facing>EAST</facing>
    <viaMapX>0</viaMapX>
    <viaMapY>0</viaMapY>
    <viaTileX>20</viaTileX>
    <viaTileY>21</viaTileY>
  </value>
  <value class="com.alchemiccutie.api.npc.NpcScheduleEntry">
    <daysOfWeek>
      <value>0</value>
      <value>1</value>
      <value>2</value>
      <value>3</value>
      <value>5</value>
      <value>6</value>
    </daysOfWeek>
    <hour>0</hour>
    <minute>0</minute>
    <location>house-tidus</location>
    <moveRandomly>true</moveRandomly>
    <requirements>
      <value class="com.alchemiccutie.api.npc.NpcScheduleEntryRequiredFlag">
        <flag>questComplete00</flag>
        <set>true</set>
      </value>
    </requirements>
  </value>
</schedule>

As seen, the schedule consists of a number of entries with each entry describing a set of requirements.

Property Required Description

daysOfWeek

Yes

The days of the week that this schedule entry should be applied. 0 = Monday, 1 = Tuesday, etc.

hour

Yes

The hour of the day that this entry should be applied from. Note this is in a 24 hour format where 0 = midnight, 1 = 1am, 2 = 2am, 12 = midday, 13 = 1pm, etc.

minute

Yes

The minute of the hour that this entry should be applied from

location

No

The waypoint to move to (Note: this overrides the mapX, mapY, tileX, tileY properties)

mapX

No

The world map X coordinate to move to (if location is not set)

mapY

No

The world map Y coordinate to move to (if location is not set)

tileX

No

The tile X coordinate on the map to move to (if location is not set)

tileY

No

The tile Y coordinate on the map to move to (if location is not set)

moveRandomly

No

True if the NPC should move randomly once they get to the target coordinate (Note: this overrides the facing property)

facing

No

The direction to face when at the target coordinate (NORTH, SOUTH, EAST, WEST)

viaMapX

No

When moving to the target coordinate, the NPC must go through this coordinate first

viaMapY

No

When moving to the target coordinate, the NPC must go through this coordinate first

viaTileX

No

When moving to the target coordinate, the NPC must go through this coordinate first

viaTileY

No

When moving to the target coordinate, the NPC must go through this coordinate first

sleeping

No

True if the NPC should sleep once it gets to the destination.

requirements

No

Additional requirements to check before activating this entry (see table below)

NPC Schedule Entry Requirements

The follow are all possible entry requirement types.

<!-- Require an NPC's flag to be set/unset to activate the entry -->
<value class="com.alchemiccutie.api.npc.NpcScheduleEntryRequiredFlag">
  <flag>questComplete00</flag>
  <set>true</set>
</value>

<!-- Require an NPC's counter to be a minimum value to activate the entry -->
<value class="com.alchemiccutie.api.npc.NpcScheduleEntryRequiredMinCounter">
  <counter>beans</counter>
  <minValue>2</minValue>
</value>

<!-- Require a quest to be a specific state to activate the entry -->
<value class="com.alchemiccutie.api.npc.NpcScheduleEntryRequiredQuest">
  <questKey>qkey</questKey>
  <!-- Set to true if the check should be negated, e.g. NOT ACTIVATED -->
  <negate>false</negate>
  <allowedStates>
    <value>HIDDEN</value>
    <value>ACTIVATED</value>
    <value>COMPLETE</value>
  </allowedStates>
</value>

<!-- Require a quest objective to be a specific state to activate the entry -->
<value class="com.alchemiccutie.api.npc.NpcScheduleEntryRequiredQuestObjective">
  <questKey>qkey</questKey>
  <objectiveKey>objKey</objectiveKey>
  <!-- Set to true if the check should be negated, e.g. NOT ACTIVATED -->
  <negate>false</negate>
  <allowedStates>
    <value>ACTIVATED</value>
    <value>SKIPPED</value>
    <value>SUCCESS</value>
    <value>FAILED</value>
  </allowedStates>
</value>

NPC Jelly Familiar

<data>
  <npcInternalName>rick</npcInternalName>
  <accessories length="1">
    <value>Aqua Flower</value>
  </accessories>
  <color>aqua</color>
  <shape>pig</shape>
  <blobLevel>50</blobLevel>
  <socialLevel>25</socialLevel>
  <tummyLevel>10</tummyLevel>
</data>

Every NPC can have an optional Jelly familiar. This configuration is for competitions only. The familiar itself must be set up as another NPC in the game world.

Attribute Description

color

The internal name Jelly’s color

shape

The internal name Jelly’s shape

blobLevel

The Jelly’s blob level (1 - 100)

socialLevel

The Jelly’s social level (1 - 100)

tummyLevel

The Jelly’s tummy level (1 - 100)

accessories

The list of accessories this Jelly wears (item internal names)

NPC Speech Sounds

The sounds used for NPC speech are configured via XML files in config/speech. The following is a sample configuration.

<data>
  <characterConfigs length="1">
    <value class="com.alchemiccutie.api.sfx.SpeechSoundCharacterConfig">
      <soundPath>sfx/vox_letter_a.ogg</soundPath>
      <textCharacter>a</textCharacter>
      <pitch>HIGH</pitch>
      <male>false</male>
      <soundInterval>0.0</soundInterval>
      <animal>WOLF</animal>
    </value>
  </characterConfigs>
  <emoteConfigs length="1">
    <value class="com.alchemiccutie.api.sfx.SpeechSoundEmoteConfig">
      <soundPath>sfx/vox_letter_wolf_sad.ogg</soundPath>
      <emote>sad</emote>
      <male>false</male>
      <animal>WOLF</animal>
      <pitch>MIDDLE_HIGH</pitch>
      <soundInterval>0.0</soundInterval>
    </value>
  </emoteConfigs>
  <soundInterval>0.08</soundInterval>
</data>

The configuration consists of emote sounds and/or text letter sounds. Depending on the configuration, sounds can be marked as exclusive to certain animals or game characters.

Attribute Required Description

soundInterval

Yes

The interval between each letter/emote sound.

The following fields are configurable for text character sounds.

Attribute Required Description

animal

No

Sets the animal that this sound is exclusive to. Do not include if this sound applies to all NPCs.

gameCharacter

No

The internalName of the NPC that this sound is exclusive to. Do not include if this sound applies to all NPCs.

male

Yes

true if the text character applies to male NPCs, otherwise false.

pitch

Yes

The pitch group this sound applies to. Can be VERY_LOW, LOW, MIDDLE_LOW, MIDDLE_HIGH, HIGH

soundInterval

No

Overrides the interval between this letter and the next

soundPath

Yes

The relative mod path to the sound file, e.g. sfx/vox_a.ogg

textCharacter

Yes

The letter that this sound applies to

The following fields are configurable for emote sounds.

Attribute Required Description

animal

Yes

Sets the animal that this emote applies to

emote

Yes

excited, happy, heart, music, question or sad. Corresponds to dialogue commands.

male

Yes

true if the text character applies to male NPCs, otherwise false.

pitch

Yes

The pitch group this sound applies to. Can be VERY_LOW, LOW, MIDDLE_LOW, MIDDLE_HIGH, HIGH

soundInterval

No

Overrides the interval between this letter and the next

soundPath

Yes

The relative mod path to the sound file, e.g. sfx/vox_a.ogg

Dialogue Commands

The table below outlines commands available to modify the sounds played during dialogue.

They can be placed inside dialogue text as follows:

chat:say(npc,"_mlow_Hi there_mlow_!_heart_")

Note that some commands require a second command to deactivate the effect.

Command Requires Deactivate Description

_loud_

Yes

Increases speech voice volume

_quiet_

Yes

Decreases speech sound volume

_spooky_

Yes

Makes text characters shake

_sing_

Yes

Make text characters animate in wave motion

_low_

Yes

Changes speech sound to LOW pitch relative to NPC’s gender/animal

_mlow_

Yes

Changes speech sound to MIDDLE_LOW pitch relative to NPC’s gender/animal

_mhigh_

Yes

Changes speech sound to MIDDLE_HIGH pitch relative to NPC’s gender/animal

_high_

Yes

Changes speech sound to HIGH pitch relative to NPC’s gender/animal

_lowm_

Yes

Changes speech sound to male LOW pitch relative to NPC’s animal

_mlowm_

Yes

Changes speech sound to male MIDDLE_LOW pitch relative to NPC’s animal

_mhighm_

Yes

Changes speech sound to male MIDDLE_HIGH pitch relative to NPC’s animal

_highm_

Yes

Changes speech sound to male HIGH pitch relative to NPC’s animal

_lowf_

Yes

Changes speech sound to female LOW pitch relative to NPC’s animal

_mlowf_

Yes

Changes speech sound to female MIDDLE_LOW pitch relative to NPC’s animal

_mhighf_

Yes

Changes speech sound to female MIDDLE_HIGH pitch relative to NPC’s animal

_highf_

Yes

Changes speech sound to female HIGH pitch relative to NPC’s animal

_excited_

No

Plays excited emote sound for NPC/gender/animal

_happy_

No

Plays happy emote sound for NPC/gender/animal

_heart_

No

Plays heart emote sound for NPC/gender/animal

_music_

No

Plays music emote sound for NPC/gender/animal

_question_

No

Plays question emote sound for NPC/gender/animal

_sad_

No

Plays sad emote sound for NPC/gender/animal

_shout_

No

Plays shout emote sound for NPC/gender/animal

Shops

Shops are configured via XML files in the config/shops and config/shop-items folders.

Below is an example of the Shop XML in config/shops.

<data>
  <internalName>Skeezer's Travelling Imporium</internalName>
  <name>Skeezer's Travelling Imporium</name>
  <sellMultiplier>0.5</sellMultiplier>
</data>
Property Name Description

internalName

The internal name of the Shop that NPC data will reference.

name

The shop name displayed to the player

sellMultiplier

Item values will be multiplied by this value when the player is selling items to the shop. (default to 1.0)

The items that a shop sells are configured in seperate files. Since items may unlock as the story progresses, multiple Shop Item XML files can be associated with a shop, specifying different requirements to enable the items.

Below is an example of the Shop Items XML in config/shop-items.

<data>
  <shopInternalName>skeezer</shopInternalName>
  <priority>7</priority>
  <requirements length="3">
    <value class="com.alchemiccutie.api.shop.NpcFlagItemsRequirement">
      <npcInternalName>gert</npcInternalName>
      <flagName>scared</flagName>
      <flagSet>true</flagSet>
    </value>
    <value class="com.alchemiccutie.api.shop.NpcMinCounterItemsRequirement">
      <npcInternalName>gert</npcInternalName>
      <counterName>crystals</counterName>
      <counterMinValue>10</counterMinValue>
    </value>
    <value class="com.alchemiccutie.api.shop.QuestCompleteItemsRequirement">
      <questKey>quest-key-1</questKey>
    </value>
  </requirements>
  <items length="1">
    <value class="com.alchemiccutie.api.shop.ShopItem">
      <internalItemName>Gritberry</internalItemName>
      <buyMultiplier>1.2</buyMultiplier>
    </value>
  </items>
</data>
Property Name Description

shopInternalName

The internal name of the Shop that these items belong to.

priority

Shop Items files with higher priority value for this shop will override this file if requirements are met.

requirements

List of requirements that are required to enable these items.

items

The items

Each item must have the following values.

Property Name Description

internalItemName

The internal name of the Item

buyMultiplier

This value is multiplied by Item value when the player is buying this item. (default to 1.0)

There are 3 types of Shop Items requirement:

  • NPC Quest Complete

  • NPC Flag Set/Unset

  • NPC Counter Minimum Value

<value class="com.alchemiccutie.api.shop.NpcFlagItemsRequirement">
  <npcInternalName>gert</npcInternalName>
  <flagName>scared</flagName>
  <flagSet>true</flagSet>
</value>
Property Name Description

npcInternalName

The NPC to check the flag on

flagName

The name of the flag to check

flagSet

true if the flag is required to be set, false if it is required to be unset

<value class="com.alchemiccutie.api.shop.NpcMinCounterItemsRequirement">
  <npcInternalName>gert</npcInternalName>
  <counterName>scared</counterName>
  <counterMinValue>4</counterMinValue>
</value>
Property Name Description

npcInternalName

The NPC to check the counter on

counterName

The name of the counter to check

counterMinValue

The mimumum value the counter must be for the requirement to pass

<value class="com.alchemiccutie.api.shop.QuestCompleteItemsRequirement">
  <questKey>quest-key-1</questKey>
</value>
Property Name Description

npcInternalName

The NPC to check the quest on

questKey

The key for the quest of the NPC that must be completed

Cutiepedia

Cutiepedia entries can be configured through XML and plain text files.

Each XML file describers where the entry details and must be placed in config/cutiepedia. Below is a sample XML file.

<data>
  <id>desmond-backstory</id>
  <title>Desmond's Adventure</title>
  <contentPath>cutiepedia/desmonds-backstory.txt</contentPath>
  <groupIndex>-1</groupIndex>
  <villager>false</villager>
</data>
Attribute Required Description

id

yes

The ID used in scripting to unlock the entry

title

yes

The entry title displayed to the player.

content

yes

The path relative to the mod/game data directory for the content file.

group

no

The name of the group the entry should be in

groupIndex

no

The index inside the group. The lowest index in a group must be 0 and the indices in a group must be sequential and unique.

groupIndex is required if group is defined and vice versa.

The content file is a simple text format that supports the following:

  • Headers

  • Paragraphs

  • Images

Below is a sample content file.

# This is a header

This is a regular paragraph. You
don't need to worry about line breaks.

But a double line break will make a new
paragraph.

[[path/to/image.png

---
# This will be on a new page

It is a very basic format.

As seen there are certain keywords that can be used to format content. A line must start with the keyword for it to be parsed.

Keyword Description

#

Headers

[[

Path to image relative to textures directory.

---

Page break.

/n

Forces a line break.

The mod packing tool will also generate a layout preview in your mod directory in the _writing/cutipedia-preview directory

Quests

Quests are defined via XML files and can then be activated/completed via the NPC scripting API.

The quests are visible to the player in the character’s notebook as a list.

The quest data must be placed in config/quests/. An example Quest XML file can be found below.

<data>
  <questKey>gert_quest_1</questKey>
  <icon>quests/questAIcon</icon>
  <title>A haunted mansion</title>
  <objectives length="1">
    <value class="com.alchemiccutie.api.quest.QuestObjective">
      <key>gert_quest_1_obj1</key>
      <description>Meet Gert at the mansion</description>
    </value>
  </objectives>
</data>
Property Name Description

questKey

The key to use when referencing this quest in scripts

icon

Texture path (relative to textures folder) to the icon that is displayed in the notebook

title

The title of the quest

objectives

The list of objectives in the quest (minimum 1 required)

Each objective has the following properties. Only one of the two optional targets can be present at once.

Property Name Description

key

The key to use when referencing this objective in scripts

description

The description of the objective

targetWaypoint

Optional target waypoint for the quest.

targetNpc

Optional target Npc for the quest.

Variable Counters

In some instances it might be desirable to have a variable counter in a objective description, for example to track the amount of jellies handed in for a quest. This can be done by including commons text substitution using the following notation ${npcInternalName.counterName}. Referencing a counter on the player can be done similarly with text substitution using the following notation ${player.counterName}. The struction of the variable should always be the npc internalName and the counterName, separated by a period.

For example if gabby has a counter called deliveredJellies with a value of 3, and a description like this as a quest objective

<description>Deliver more jellies to the shop for Gerba’s landfill. (${gabby.deliveredJellies}/25)</description>

The output string seen in the quest details tab of the notebook will be:

Deliver more jellies to the shop for Gerba’s landfill. (3/25)

Jelly Delivery Quests

Jelly Delivery Quest Lines are defined via XML files. They are activated by talking to Gabby, where she will give you a new quest line once per calendar week. Subsequent quests in the quest line are activated by interacting with the mail box at the farm.

The quests are visible to the player in the character’s notebook as a list.

The quest data must be placed in _config/questData/jellyOrderConfig/data.

Quest line fields are described below.

Property Name Description

questLine

A unique string for the quest line.

thankInterval

The scheduled time that the thank you letter arrives after the final quest in the quest line. Takes in a scheduled time.

cutiepediaThank

The cutiepedia id of the entry that is revealed as the thank you letter at the end of the quest line.

thankItem

Optional. The item that is given to the player at the end of the quest line.

thankItemAmount

Optional, minimum value 1. The amout of the thank item given to the player at the end of the quest line.

questTemplates

An array of quest templates, each being a quest in the overall quest line.

Quest templates have the following properties.

Property Name Description

questKey

The key to use when referencing this quest in scripts

objectiveKey1

The key to use when referencing the first objective in the quest.

objectiveKey2

The key to use when referencing the second objective in the quest.

cutiepediaEntry

The cutiepedia id of the entry that is revealed when starting this quest in the quest line.

npc

The name of the npc this quest is for.

crystalReward

The amount of crystals given to the player by Gabby when handing in the required jelly.

nextStepInterval

The scheduled time that the next step letter is available at the mail box, after completing the previous step. Takes in a scheduled time.

additionalTrigger

An additional lua scripting trigger that is checked to see weather this quest is activated.

mailFlag

A boolean if this can be picked up from the mail box. Should be false for the first quest in a quest line, and true for every subsequent quest.

The following are optional properties for each quest.

Property Name Description

itemReward

The item given to the player by Gabby when handing in a jelly.

trait1

A required trait the jelly must have to be handed in.

trait2

A required trait the jelly must have to be handed in.

trait3

A required trait the jelly must have to be handed in.

blobLevel

The required blob level the jelly must have to be handed in.

tummyLevel

The required blob level the jelly must have to be handed in.

socialLevel

The required blob level the jelly must have to be handed in.

nature

The required nature the jelly must have to be handed in.

color

The required color the jelly must have to be handed in.

shape

The required shape the jelly must have to be handed in.

ageInDays

The required age in days the jelly must have to be handed in.

foodMaxValue

The required food max value the jelly must have to be handed in.

happiness

The required happiness the jelly must have to be handed in.

buffetMedals

The required buffet competition medals the jelly must have to be handed in. Max 5.

splashMedals

The required splash competition medals the jelly must have to be handed in. Max 5.

sumoMedals

The required sumo competition medals the jelly must have to be handed in. Max 5.

vogueMedals

The required vogue competition medals the jelly must have to be handed in. Max 5.

totalMedals

The required total competition medals the jelly must have to be handed in. Max 20.

totalChampionMedals

The required total champion competition medals the jelly must have to be handed in. Max 4.

Items

Items can be configured through XML files - one file per item.

The following is an example of the an Item. The table below explains the properties and which are required.

<data>
  <internalName>Gritberry</internalName>
  <name>Gritberry</name>
  <description>A delicious berry</description>
  <uiTexturePath>items/gritberry</uiTexturePath>
  <overworldTexturePath>items/gritberry</overworldTexturePath>
  <maxPerSlot>99</maxPerSlot>
  <valueModifier>0</valueModifier>
  <value>200</value>
  <calculatedValue>-1</calculatedValue>
  <collisionDisabled>false</collisionDisabled>
  <keyItem>false</keyItem>
  <hudItem>false</hudItem>
  <digestionDuration>60</digestionDuration>
  <transitionItemName>Dull Bean</transitionItemName>
  <transitionItemQuantity>2</transitionItemQuantity>
  <poopItemName>Smelly Bean</poopItemName>
  <poopItemQuantity>2</poopItemQuantity>
  <shopCategory>FOOD</shopCategory>
  <effects length="1">
    <value class="com.alchemiccutie.api.jelly.effect.RejectAllDigestionEffect">
      <durationGameMinutes>0</durationGameMinutes>
      <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
    </value>
  </effects>
  <additionalProperties length="1">
    <value class="com.alchemiccutie.api.domain.ItemAdditionalProperty">
      <propertyKey>exampleKey</propertyKey>
      <propertyValue>exampleValue</propertyValue>
    </value>
  </additionalProperties>
  <script>path/to/script.lua</script>
  <hiddenInCodex>false</hiddenInCodex>
</data>
Property Name Required Sample Value Description

name

Yes

Gritberry

The name of the item. This can be localised via PO files.

internalName

Yes

Gritberry

The name of the item - this is name used by the game engine internally. If you need to change the item name later on, only change the name.

description

Yes

A sample description

The description of the item.

uiTexturePath

No

items/gritberry

The path to the item’s texture (without its file extension) to render in the UI. If this value is not provided, the game will fallback to the overworldTexturePath.

overworldTexturePath

Yes

items/gritberry

The path to the item’s texture (without its file extension) to render in the overworld.

value

no

200

If this is present, and not -1, this is the value of the item used in game, otherwise the calculatedValue will be used

calculatedValue

no

200

The calculated value of the item base on a formula, already includes valueModifier.

valueModifier

no

-50

Additive value used to modify the calculatedValue. Can be positive or negative.

maxPerSlot

Yes

99

Maximum number of items per bag slot.

collisionDisabled

No

true

True when this item should block the player’s movement when dropped on the overworld.

keyItem

No

true

True if the item cannot be sold or fed to a Jelly.

digestionDuration

No

1

The time (in game minutes (1 or 1m), hours (1h or 1H) or days (1d or 1D)) it takes for a Jelly to digest the item.

transitionItemName

No

Dull Bean

The name of the item to transition to when a Morph Qwirb is used. If this field is missing, the item does not transition.

transitionItemQuantity

No

1

The number of items to output from Morph Qwirb.

poopItemName

No

Smelly Bean

The name of the item to spawn when this item is digested. If this field is missing, no item is spawned. Items can also use the key word "Color Bean" which will turn into a bean of the jelly’s current color or just a regular Smelly Bean.

poopItemQuantity

No

1

The number of items to output from digestion.

shopCategory

Yes

FOOD

What category this item belongs to when shown in a shop. Values can be FOOD, POTIONS, EQUIPMENT or VALUABLES.

applyEffectTemplates

No

tummy ache

Internal name referencing an Item Effect Template. Effects from the template are appended to the effects list.

effects

No

<effects />

The list of item effects to apply to the Jelly when the item is digested. (See XML sample above and see below for all possible item effects)

additionalProperties

No

<additionalProperties />

Additional key/values to use for scripting. See XML sample above.

script

No

path/to/script.lua

Path to a script to invoke when the player collects this item for first time. Path is relative to root of mod directory.

hiddenInCodex

No

false

True when this item should be hidden from the Codex. Defaults to false

Item Effects

Item effects are applied once the digestion of an item is completed.

Most item effects share the following common fields.

<relative>true</relative>
<durationGameMinutes>1</durationGameMinutes>
<delayOnsetGameMinutes>0</delayOnsetGameMinutes>
Property Name Type Description

relative

bool

When relative is set to true, the value is applied relatively (i.e. increases or decreases the existing value). When set to false, the current value is replaced with the value specified in the effect.

durationGameMinutes

int

Sets how long the effect lasts (based on the game clock)

delayOnsetGameMinutes

int

Sets how long before the effect is activated (based on the game clock)

For example if durationGameMinutes is set to 5 and relative is set to true, the value is increased/decreased every game minute for 5 minutes.

When effects complete, any values they have modified will remain applied.

Age Effect

Changes the Jelly’s current age.

<value class="com.alchemiccutie.api.jelly.effect.AgeEffect">
  <valueModifier>1</valueModifier>
  <relative>false</relative>
</value>
Property Name Type Description

valueModifier

int

The amount of days

Awake Effect

Wake’s up the Jelly immediately. Note that the duration and delay values are only used.

<value class="com.alchemiccutie.api.jelly.effect.AwakeEffect">
  <relative>false</relative>
  <durationGameMinutes>360</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

This value should not be specified by modders as it will be overriden at runtime

Barf Effect

Applies the Barf effect to the Jelly stomach. This will cause the jelly to spit out all items in its stomach.

<value class="com.alchemiccutie.api.jelly.effect.BarfEffect"/>

Digestion Rate Effect

Increase/decrease the Jelly’s digestion speed by a specified multiplier.

<value class="com.alchemiccutie.api.jelly.effect.DigestionRateEffect">
  <multiplier>1.2</multiplier>
  <durationGameMinutes>0</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

multiplier

float

The amount to multiply by

Dim Effect

If the Jelly is currently a light source, the light source is removed.

<value class="com.alchemiccutie.api.jelly.effect.DimEffect"/>

Dye Effect

Changes the Jelly’s current color.

<value class="com.alchemiccutie.api.jelly.effect.DyeEffect">
  <colorPalette>normal</colorPalette>
</value>
Property Name Type Description

colorPalette

string

The color palette to set

Energy Max Value Effect

Increase/decrease/set the Jelly’s maximum Energy value. By default, Jellies have a maximum of 100.

<value class="com.alchemiccutie.api.jelly.effect.EnergyMaxValueEffect">
  <valueModifier>1.0</valueModifier>
  <relative>true</relative>
  <durationGameMinutes>1</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

The amount to modify the value by every game minute

Energy Value Effect

Increase/decrease/set the Jelly’s Energy value.

<value class="com.alchemiccutie.api.jelly.effect.EnergyValueEffect">
  <valueModifier>-1.0</valueModifier>
  <relative>true</relative>
  <durationGameMinutes>1</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

The amount to modify the value by every game minute

Food Max Value Effect

Increase/decrease/set the Jelly’s maximum Food value. By default, Jellies have a maximum of 100.

<value class="com.alchemiccutie.api.jelly.effect.FoodMaxValueEffect">
  <valueModifier>-8.0</valueModifier>
  <relative>true</relative>
  <durationGameMinutes>1</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

The amount to modify the value by every game minute

Food Value Effect

Increase/decrease/set the Jelly’s Food value.

<value class="com.alchemiccutie.api.jelly.effect.FoodValueEffect">
  <valueModifier>-8.0</valueModifier>
  <relative>true</relative>
  <durationGameMinutes>1</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

The amount to modify the value by every game minute

Glow Effect

Activates a light source on the Jelly if not already present.

<value class="com.alchemiccutie.api.jelly.effect.GlowEffect"/>

Grouped Effect

Utility effect for grouping effects into a single effect.

<value class="com.alchemiccutie.api.jelly.effect.GroupedEffect">
  <name>groupName</name>
  <effects length="0"/>
</value>
Property Name Type Description

name

string

The name of this group to display to the player

labelColor

string

The color of this effect; GREY, YELLOW, GREEN, ORANGE, PURPLE, BLUE or RED

effects

xml

The XML for the effects

Happiness Value Effect

Increase/decrease/set the Jelly’s happiness value.

<value class="com.alchemiccutie.api.jelly.effect.HappinessValueEffect">
  <valueModifier>1.0</valueModifier>
  <relative>true</relative>
  <durationGameMinutes>1</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

The amount to modify the value by every game minute

Love Effect

Activates mating for Jelly for a specific duration.

<value class="com.alchemiccutie.api.jelly.effect.LoveEffect">
  <durationGameMinutes>60</durationGameMinutes>
</value>

Probable Effect

Utility effect for wrapper another Item Effect with a probability of occurrance.

<value class="com.alchemiccutie.api.jelly.effect.ProbableEffect">
  <probability>0.5</probability>
  <effect class="com.alchemiccutie.api.jelly.effect.DyeEffect">
    <colorPalette>normal</colorPalette>
  </effect>
</value>
Property Name Type Description

probability

float

The probability; 0.1 == 10% chance

Reject All Digestion Effect

Causes the Jelly to immediately spit out all newly fed food for a specified duration.

<value class="com.alchemiccutie.api.jelly.effect.RejectAllDigestionEffect">
  <durationGameMinutes>0</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>

Relic Meter Effect

Increases/decreases or sets the Relic meter. Positive number progresses jellies towards becoming a relic. Negative number regresses jellies from becoming a relic. Items with this effect do NOT count towards Relic progression.

<value class="com.alchemiccutie.api.jelly.effect.RelicMeterEffect">
  <valueModifier>1</valueModifier>
  <relative>true</relative>
</value>

Relic Max Meter Effect

Increases/decreases or sets the max value of the Relic meter. Positive number increases total amount of items needed for a jelly to become a relic. Negative number decreases total amount of items needed for a jelly to become a relic. Items with this effect do NOT count towards Relic progression.

<value class="com.alchemiccutie.api.jelly.effect.RelicMaxMeterEffect">
  <valueModifier>1</valueModifier>
  <relative>true</relative>
</value>

Salt Effect

Immediately kills the Jelly :(

<value class="com.alchemiccutie.api.jelly.effect.SaltEffect"/>

Shape Reset Effect

Resets the Jelly’s shape to the one that it was caught with.

<value class="com.alchemiccutie.api.jelly.effect.ShapeResetEffect"/>

Shape Set Effect

Sets the Jelly’s shape to a specific one.

<value class="com.alchemiccutie.api.jelly.effect.ShapeSetEffect">
  <shape>yella</shape>
</value>
Property Name Type Description

shape

int

The shape ID to set the Jelly’s shape to

Sleep Effect

Causes the Jelly to immediately fall asleep. Note that the duration and delay values are only used.

<value class="com.alchemiccutie.api.jelly.effect.SleepEffect">
  <relative>false</relative>
  <durationGameMinutes>360</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

valueModifier

float

This value should not be specified by modders as it will be overriden at runtime

Stat Exp Effect

Increase/decrease/set a specific stat’s experience points. An experience points value between 1 and 5 (inclusive) is recommend.

<value class="com.alchemiccutie.api.jelly.effect.StatExpEffect">
  <stat>BLOB</stat>
  <exp>3</exp>
  <relative>true</relative>
</value>
Property Name Type Description

stat

string

BLOB, SOCIAL or TUMMY

exp

int

The value to modify the experience by

Stat Exp Gain Effect

Applies a multiplier to all experience points gained.

<value class="com.alchemiccutie.api.jelly.effect.StatExpGainEffect">
  <multiplier>1.2</multiplier>
  <stat>BLOB</stat>
  <durationGameMinutes>0</durationGameMinutes>
  <delayOnsetGameMinutes>0</delayOnsetGameMinutes>
</value>
Property Name Type Description

stat

string

BLOB, SOCIAL or TUMMY

multiplier

float

The value to multiply all experience gains by

Stat Level Effect

Increase/decrease/set a specific stat’s level (auto-calculates experience points).

<value class="com.alchemiccutie.api.jelly.effect.StatLevelEffect">
  <stat>BLOB</stat>
  <level>1</level>
  <relative>true</relative>
</value>
Property Name Type Description

stat

string

BLOB, SOCIAL or TUMMY

level

int

The value to modify the level by

Trait Forget Effect

Forgets a random trait.

<value class="com.alchemiccutie.api.jelly.effect.TraitForgetEffect"/>

Trait Learn Effect

Causes the Jelly to learn a specific trait.

<value class="com.alchemiccutie.api.jelly.effect.TraitLearnEffect">
  <trait>nocturnal</trait>
</value>
Property Name Type Description

trait

string

The name of the trait to learn

Trait Mutate Effect

Selects one of the Jelly’s traits and replaces it with a random trait.

<value class="com.alchemiccutie.api.jelly.effect.TraitMutateEffect"/>

Unlove Effect

Deactivates mating for the Jelly.

<value class="com.alchemiccutie.api.jelly.effect.UnloveEffect"/>

Wash Effect

Reset’s the Jelly’s color palette to the original one it was caught with.

<value class="com.alchemiccutie.api.jelly.effect.WashEffect"/>

Contraptions

Contraptions are machines that can be configured to execute actions. The player can build them at their workbench.

<data>
  <powerPerPipeline>1.0</powerPerPipeline>
  <autoActionPerGameMinute>0</autoActionPerGameMinute>
  <autoBox>false</autoBox>
  <actions length="4">
    <value class="com.alchemiccutie.api.contraptions.action.NearestJellyAction">
      <zone>
        <pixelWidth>128</pixelWidth>
        <pixelHeight>129</pixelHeight>
        <offsetX>-16</offsetX>
        <offsetY>-16</offsetY>
        <texturePath>contraptions/zonePattern</texturePath>
        <textureSliceSize>8</textureSliceSize>
        <borderRgba>255,255,255,128</borderRgba>
      </zone>
      <outputKey>jelly</outputKey>
    </value>
    <value class="com.alchemiccutie.api.contraptions.action.NearestBoxStorageAction">
      <zone>
        <pixelWidth>128</pixelWidth>
        <pixelHeight>129</pixelHeight>
        <offsetX>-16</offsetX>
        <offsetY>-16</offsetY>
        <texturePath>contraptions/zonePattern</texturePath>
        <textureSliceSize>8</textureSliceSize>
        <borderRgba>255,255,255,128</borderRgba>
      </zone>
      <outputKey>box</outputKey>
    </value>
    <value class="com.alchemiccutie.api.contraptions.action.TakeItemAction">
      <inputKey>box</inputKey>
      <outputKey>item</outputKey>
      <allowedItems length="0"/>
    </value>
    <value class="com.alchemiccutie.api.contraptions.action.FeedItemAction">
      <inputItemKey>item</inputItemKey>
      <inputJellyKey>jelly</inputJellyKey>
    </value>
  </actions>
  <internalName>Jelly Feeder</internalName>
  <name>Jelly Feeder</name>
  <description>Feeds Jellies items dropped on the farm</description>
  <texturePath>contraptions/jelly-feeder</texturePath>
  <requiredBlueprintItem>Jelly Feeder Blueprint</requiredBlueprintItem>
  <requiredItems length="1">
    <value class="com.alchemiccutie.api.contraptions.ContraptionItemData">
      <itemInternalName>Garbage</itemInternalName>
      <quantity>5</quantity>
    </value>
  </requiredItems>
  <refundItems length="1">
    <value class="com.alchemiccutie.api.contraptions.ContraptionItemData">
      <itemInternalName>Garbage</itemInternalName>
      <quantity>1</quantity>
    </value>
  </refundItems>
  <requiredRelic>
    <relicMeter>-1</relicMeter>
    <maxFood>-1</maxFood>
    <happiness>70</happiness>
    <blobLevel>10</blobLevel>
    <socialLevel>1</socialLevel>
    <tummyLevel>-1</tummyLevel>
    <traitNames length="0"/>
  </requiredRelic>
  <refundRelic>true</refundRelic>
</data>
Property Name Required Sample Value Description

name

Yes

Jelly Feeder

The name of the contraption. This can be localised via PO files.

internalName

Yes

Jelly Feeder

The name of the contraption - this is name used by the game engine internally. If you need to change the item name later on, only change the name.

description

Yes

A sample description

The description of the contraption.

texturePath

Yes

contraptions/feeder

The path to the contraption’s texture (without its file extension) to render.

requiredBlueprintItem

No

Jelly Feeder Blueprint

The item that the player must collect to be able to craft this contraption.

requiredItems

No

<requiredItems />

The items required to craft this contraption.

refundItems

No

<refundItems />

The items refunded if the player destroys the contraption.

requiredRelic

No

<requiredRelic />

The relic required to craft this contraption.

refundRelic

No

true

true if the relic should be refunded when player destroys the contraption.

autoBox

No

true

true if fixed boxes should be automatically generated for actions. The boxes will be automatically configured for allowed items.

powerPerPipeline

No

1

The amount of power consumed by running the action pipeline of this contraption.

autoActionPerGameMinute

No

1

0 if the contraption is manually activated. Otherwise, the frequency in game minutes that the action pipeline runs.

actions

No

<actions />

The action pipeline of this contraption. If no actions, the contraption is effectively decorative.

Contraption Zones

Many contraption actions require zones to be specified. These are source or target areas for actions and can be optionally displayed to the player.

  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
Property Name Required Sample Value Description

pixelWidth

Yes

64

The width of the zone in pixels.

pixelHeight

Yes

64

The height of the zone in pixels

offsetX

No

0

The X offset of the zone relative to center X of the contraption.

offsetY

No

0

The Y offset of the zone relative to center Y of the contraption.

texturePath

No

zones/pattern

The texture to display the zone to the player. This can optionally be an equal sided ninepatch.

textureSliceSize

No

8

If a non-zero value, treats the texture as a ninepatch.

borderRgba

No

255,255,255,128

If specified, draws a 1 pixel wide rectangle around the zone area in the specified color.

Contraption Actions

The actions pipeline for a contraption executes by first finding an active power source. If a power source is found, the contraption deducts `` from its power and executes the actions in order.

Actions can pass data through the pipeline using keys. These are specified by input and output key fields by actions.

If actions expect a key to be a specific object type and it is not, the action is skipped.

Apply Item Effect Action

Applies an Item Effect to a specified Jelly.

<value class="com.alchemiccutie.api.contraptions.action.ApplyItemEffectAction">
  <inputKey>jelly</inputKey>
  <itemEffect class="com.alchemiccutie.api.jelly.effect.BarfEffect"/>
</value>
Property Name Description

inputKey

The jelly to apply the effect to

itemEffect

The effect to apply

Check Item Action

Checks if a specified item is a specific item. If this check fails, the action pipeline stops.

<value class="com.alchemiccutie.api.contraptions.action.CheckItemAction">
  <inputKey>item</inputKey>
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
</value>
Property Name Description

inputKey

The item to check

allowedItems

The list of items allowed by this action

Consume Power Action

Consumes additional power than the amount specified by the contraption. If the specified amount of power cannot be consumed, the action pipeline stops.

<value class="com.alchemiccutie.api.contraptions.action.ConsumePowerAction">
  <amount>5</amount>
</value>
Property Name Description

amount

The amount to consume

Destroy Item Action

Destroys a specified item.

<value class="com.alchemiccutie.api.contraptions.action.DestroyItemAction">
  <inputKey>item</inputKey>
</value>
Property Name Description

inputKey

The item to destroy

Drop Item Action

Drops a specified item to a zone.

<value class="com.alchemiccutie.api.contraptions.action.DropItemAction">
  <inputKey>item</inputKey>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
</value>
Property Name Description

inputKey

The item to drop

zone

The zone to drop the item into

Execute Script Action

Executes a lua script.

<value class="com.alchemiccutie.api.contraptions.action.ExecuteScriptAction">
  <scriptPath>scripts/action.lua</scriptPath>
  <scriptPriority>0</scriptPriority>
</value>
Property Name Description

scriptPath

The path to the lua script

scriptPriority

(optional) The script priority (0 to 4)

Farm Box Storage Action

Finds the farm box storage and stores it in a specified key

<value class="com.alchemiccutie.api.contraptions.action.FarmBoxStorageAction">
  <outputKey>box</outputKey>
</value>
Property Name Description

outputKey

The key to store into

Feed Item Action

Feeds an item to a Jelly

<value class="com.alchemiccutie.api.contraptions.action.FeedItemAction">
  <inputItemKey>item</inputItemKey>
  <inputJellyKey>jelly</inputJellyKey>
</value>
Property Name Description

inputItemKey

The item to feed

inputJellyKey

The jelly to feed

Feed Item Action

Applies a flute/alchemy effect to an object

<value class="com.alchemiccutie.api.contraptions.action.FluteEffectAction">
  <inputKey>jelly</inputKey>
</value>
Property Name Description

inputKey

The object to apply the effect to

Nearest Any Action

Finds the nearest object in a specified zone. This will find the nearest entity of the following types:

  • Jelly

  • Egg

  • Relic

  • Item

  • Resource Node

  • BoxStorage

<value class="com.alchemiccutie.api.contraptions.action.NearestAnyAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>any</outputKey>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Nearest Box Storage Action

Finds the nearest box in a specified zone.

<value class="com.alchemiccutie.api.contraptions.action.NearestBoxStorageAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>box</outputKey>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Nearest Egg Action

Finds the nearest egg in a specified zone.

<value class="com.alchemiccutie.api.contraptions.action.NearestEggAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>egg</outputKey>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Nearest Item Action

Finds the nearest item in a specified zone.

<value class="com.alchemiccutie.api.contraptions.action.NearestItemAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>item</outputKey>
  <allowedItems length="0"/>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Nearest Jelly Action

Finds the nearest captured jelly in a specified zone.

<value class="com.alchemiccutie.api.contraptions.action.NearestJellyAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>jelly</outputKey>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Nearest Relic Action

Finds the nearest relic in a specified zone.

<value class="com.alchemiccutie.api.contraptions.action.NearestRelicAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>relic</outputKey>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Nearest Resource Node Action

Finds the nearest resource node in a specified zone.

<value class="com.alchemiccutie.api.contraptions.action.NearestResourceNodeAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <outputKey>resource</outputKey>
</value>
Property Name Description

outputKey

The key to store the result into

zone

The zone to search in

Pet Effect Action

Simulates the player using the pet action on the object.

<value class="com.alchemiccutie.api.contraptions.action.PetEffectAction">
  <inputKey>jelly</inputKey>
</value>
Property Name Description

inputKey

The object to pet

Put Item Action

Puts an item into a box storage.

<value class="com.alchemiccutie.api.contraptions.action.PutItemAction">
  <inputBoxKey>box</inputBoxKey>
  <inputItemKey>item</inputItemKey>
</value>
Property Name Description

inputBoxKey

The box to put the item into

inputItemKey

The item reference to put into the box

Spawn Bug Action

Spawns a bug in the specified zone.

<value class="com.alchemiccutie.api.contraptions.action.SpawnBugAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <bugType>butterfly</bugType>
</value>
Property Name Description

bugType

The bug to spawn (butterfly, moth, firefly)

zone

The zone to spawn in

Spawn Captured Jelly Action

Spawns a captured jelly in the specified zone.

<value class="com.alchemiccutie.api.contraptions.action.SpawnCapturedJellyAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <jellyName>bob</jellyName>
  <jellySpawnTemplate>winter-jellies</jellySpawnTemplate>
</value>
Property Name Description

zone

The zone to spawn in

jellyName

(Optional) Jelly name. If a Jelly already has this name, a random one is chosen.

jellySpawnTemplate

The jelly spawn template to use

Spawn Ghost Action

Spawns a random ghost in one of Wimba Island’s ghost spawn areas.

<value class="com.alchemiccutie.api.contraptions.action.SpawnGhostAction"/>

Spawn Item Action

Spawns an item in the specified zone

<value class="com.alchemiccutie.api.contraptions.action.SpawnGhostAction"/>
Property Name Description

zone

The zone to spawn in

itemSpawnTemplate

The item spawn template to use

Spawn Visual Effect Action

Spawns a visual effect in the specified zone.

<value class="com.alchemiccutie.api.contraptions.action.SpawnVisualEffectAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <effectType>SMOKE_BIG</effectType>
</value>
Property Name Description

zone

The zone to spawn in

effectType

FIREWORK, GLITTER, SMOKE_BIG, SMOKE_SMALL, SMOKE_POOF, DIAMOND_BURST, DOOR_BURST, CHARGE_UP, SHORTCUT_POOF, ALERT_BAD, ALERT_GOOD, STINKER_POOF

Spawn Wild Jelly Action

Spawns a wild jelly in the specified zone.

<value class="com.alchemiccutie.api.contraptions.action.SpawnWildJellyAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <jellySpawnTemplate>winter-jellies</jellySpawnTemplate>
</value>
Property Name Description

zone

The zone to spawn in

jellySpawnTemplate

The jelly spawn template to use

Take Item Action

Takes an item from a box storage and stores it in a specified key.

<value class="com.alchemiccutie.api.contraptions.action.SpawnWildJellyAction">
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <jellySpawnTemplate>winter-jellies</jellySpawnTemplate>
</value>
Property Name Description

inputKey

The box storage to take from

outputKey

The key to store in

allowedItems

Optional list of items to take. Items not in this list will be ignored.

Trigger Item Spawn Event Action

Triggers all item spawns configured to respond to an event.

<value class="com.alchemiccutie.api.contraptions.action.TriggerItemSpawnEventAction">
  <event>earthquake</event>
</value>
Property Name Description

event

The event configured in the item spawn template

Power Supplies

Power Supplies provide power to contraptions. The player can build them at their workbench.

<data>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <maxPower>100</maxPower>
  <fuel class="com.alchemiccutie.api.contraptions.power.ContraptionWeatherFuelData">
    <weather length="3">
      <value>CLOUDY</value>
      <value>STORM</value>
      <value>RAIN</value>
    </weather>
    <powerPerActivation>10.0</powerPerActivation>
  </fuel>
  <internalName>Windmill</internalName>
  <name>Windmill</name>
  <description>Generates power during windy days</description>
  <texturePath>contraptions/windmill</texturePath>
  <requiredBlueprintItem>Windmill Blueprint</requiredBlueprintItem>
  <requiredItems length="1">
    <value class="com.alchemiccutie.api.contraptions.ContraptionItemData">
      <itemInternalName>Garbage</itemInternalName>
      <quantity>5</quantity>
    </value>
  </requiredItems>
  <refundItems length="1">
    <value class="com.alchemiccutie.api.contraptions.ContraptionItemData">
      <itemInternalName>Garbage</itemInternalName>
      <quantity>1</quantity>
    </value>
  </refundItems>
  <requiredRelic>
    <relicMeter>-1</relicMeter>
    <maxFood>-1</maxFood>
    <happiness>70</happiness>
    <blobLevel>10</blobLevel>
    <socialLevel>1</socialLevel>
    <tummyLevel>-1</tummyLevel>
    <traitNames length="0"/>
  </requiredRelic>
  <refundRelic>true</refundRelic>
</data>
Property Name Required Sample Value Description

name

Yes

Windmill

The name of the power supply. This can be localised via PO files.

internalName

Yes

Windmill

The name of the power supply - this is name used by the game engine internally. If you need to change the item name later on, only change the name.

description

Yes

A sample description

The description of the power supply.

texturePath

Yes

contraptions/windmill

The path to the power supply’s texture (without its file extension) to render.

requiredBlueprintItem

No

Windmill Blueprint

The item that the player must collect to be able to craft this contraption.

requiredItems

No

<requiredItems />

The items required to craft this power supply.

refundItems

No

<refundItems />

The items refunded if the player destroys the power supply.

requiredRelic

No

<requiredRelic />

The relic required to craft this power supply.

refundRelic

No

true

true if the relic should be refunded when player destroys the power supply.

zone

Yes

<zone />

All contraptions within this zone will be powered by this power supply.

fuelData

Yes

<fuelData />

The fuel for this power supply (see below).

Power Supply Fuel

A power supply must have a source of fuel. Below are the possible fuel sources.

Power supplies activate each game minute to consume fuel.

Each fuel specifies how much power it generates using the powerPerActivation field.

Item Fuel

The item fuel supply will take items from a Box in a specified zone and convert them to power.

<fuel class="com.alchemiccutie.api.contraptions.power.ContraptionItemFuelData">
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <powerPerActivation>1.0</powerPerActivation>
</fuel>
Property Name Required Sample Value Description

allowedItems

No

<allowedItems />

The list of items allowed. If empty, any item will be consumed.

zone

Yes

<zone />

The zone to search for the box to take from.

powerPerActivation

Yes

0.5

The amount of power generated per item consumed.

Position Fuel

The position fuel supply will generate power if the power supply is within the specified areas.

<fuel class="com.alchemiccutie.api.contraptions.power.ContraptionItemFuelData">
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <powerPerActivation>1.0</powerPerActivation>
</fuel>
Property Name Required Sample Value Description

areas

Yes

<areas />

The list of areas power is generated in (at least 1 required).

powerPerActivation

Yes

0.5

The amount of power generated per game minute.

Store Fuel

The store fuel supply will consume power from other power supplies and store in this one.

<fuel class="com.alchemiccutie.api.contraptions.power.ContraptionItemFuelData">
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <powerPerActivation>1.0</powerPerActivation>
</fuel>
Property Name Required Sample Value Description

zone

Yes

<zone />

The area this power supply searches for power supplies to take from.

powerPerActivation

Yes

0.5

The amount of power to take and store per game minute per power supply found.

Time Fuel

The time fuel supply will generate power based on the time of day and day of the month.

The power will be generated each game minute during the specified time period.

<fuel class="com.alchemiccutie.api.contraptions.power.ContraptionItemFuelData">
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <powerPerActivation>1.0</powerPerActivation>
</fuel>
Property Name Required Sample Value Description

minDayOfMonth

Yes

1

The first day of the month that it will activate (min 0, max 27)

maxDayOfMonth

Yes

28

The last day of the month that it will activate (min 0, max 27)

minHourOfDay

Yes

1

The first hour of the day that it will activate (min 0, max 23)

maxHourOfDay

Yes

23

The last hour of the day that it will activate (min 0, max 23)

powerPerActivation

Yes

0.5

The amount of power generated per game minute active

Weather Fuel

The weather fuel supply will generate weather based on the current weather.

<fuel class="com.alchemiccutie.api.contraptions.power.ContraptionItemFuelData">
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
  <zone>
    <pixelWidth>128</pixelWidth>
    <pixelHeight>129</pixelHeight>
    <offsetX>-16</offsetX>
    <offsetY>-16</offsetY>
    <texturePath>contraptions/zonePattern</texturePath>
    <textureSliceSize>8</textureSliceSize>
    <borderRgba>255,255,255,128</borderRgba>
  </zone>
  <powerPerActivation>1.0</powerPerActivation>
</fuel>
Property Name Required Sample Value Description

weather

Yes

CLOUDY

The list of weather that this is active (minimum 1). Values can be; BLOOM, CLOUDY, RAIN, SNOW, STARFALL, STORM, SUNNY.

powerPerActivation

Yes

0.5

The amount of power generated per game minute active

Boxes

Boxes are used as player storage and can be connected to contraptions and power supplies. The player can build them at their workbench.

<data>
  <totalSlots>10</totalSlots>
  <allowedItems length="1">
    <value>Smelly Bean</value>
  </allowedItems>
  <internalName>Small Box</internalName>
  <name>Small Box</name>
  <description>A small portable box for contraptions</description>
  <texturePath>contraptions/smallbox</texturePath>
  <requiredItems length="1">
    <value class="com.alchemiccutie.api.contraptions.ContraptionItemData">
      <itemInternalName>Garbage</itemInternalName>
      <quantity>5</quantity>
    </value>
  </requiredItems>
  <refundItems length="1">
    <value class="com.alchemiccutie.api.contraptions.ContraptionItemData">
      <itemInternalName>Garbage</itemInternalName>
      <quantity>1</quantity>
    </value>
  </refundItems>
  <requiredRelic>
    <relicMeter>-1</relicMeter>
    <maxFood>-1</maxFood>
    <happiness>70</happiness>
    <blobLevel>10</blobLevel>
    <socialLevel>1</socialLevel>
    <tummyLevel>-1</tummyLevel>
    <traitNames length="0"/>
  </requiredRelic>
  <refundRelic>true</refundRelic>
</data>
Property Name Required Sample Value Description

name

Yes

Windmill

The name of the box. This can be localised via PO files.

internalName

Yes

Windmill

The name of the box - this is name used by the game engine internally. If you need to change the item name later on, only change the name.

description

Yes

A sample description

The description of the box.

texturePath

Yes

contraptions/windmill

The path to the box’s texture (without its file extension) to render.

requiredBlueprintItem

No

Windmill Blueprint

The item that the player must collect to be able to craft this contraption.

requiredItems

No

<requiredItems />

The items required to craft this box.

refundItems

No

<refundItems />

The items refunded if the player destroys the box.

requiredRelic

No

<requiredRelic />

The relic required to craft this box.

refundRelic

No

true

true if the relic should be refunded when player destroys the box.

totalSlots

Yes

10

The total item slots in this box

allowedItems

No

<allowedItems />

When specified, only these items can be placed in the box.

Weekly Deliveries

Weekly deliveries are defined via XML files.

The weekly deliveries are visible to the player when they interact with the delivery box on the farm.

The quest data must be placed in config/deliveries/. An example of a weekly delivery XML can be seen below.

<data>
  <year>1</year>
  <season>SUMMER</season>
  <week>2</week>
  <requiredItems length="2">
    <value>Cherry Dye</value>
    <value>Aqua Dye</value>
  </requiredItems>
  <requiredItemAmounts length="2">
    <value>5</value>
    <value>10</value>
  </requiredItemAmounts>
  <rewardCrystals>100</rewardCrystals>
  <calculatedRewardCrystals>0</calculatedRewardCrystals>
  <rewardItems length="5">
    <value>Squintberry</value>
    <value>Gritsprout</value>
    <value>Blobite Gem</value>
    <value>Blob Butter</value>
    <value>Velvet Moss</value>
  </rewardItems>
  <rewardItemAmounts length="5">
    <value>5</value>
    <value>4</value>
    <value>3</value>
    <value>1</value>
    <value>2</value>
  </rewardItemAmounts>
  <requiredItemsSuccessScript>scripts/deliveries/regular-success.lua</requiredItemsSuccessScript>
  <requiredItemsFailureScript>scripts/deliveries/regular-failed.lua</requiredItemsFailureScript>
  <requiredStarItems length="2">
    <value>Chromacrush</value>
    <value>Smelly Bean</value>
  </requiredStarItems>
  <requiredStarItemAmounts length="2">
    <value>1</value>
    <value>3</value>
  </requiredStarItemAmounts>
  <rewardStarCrystals>500</rewardStarCrystals>
  <calculatedRewardStarCrystals>0</calculatedRewardStarCrystals>
  <rewardStarItems length="2">
    <value>Blob Butter</value>
    <value>Velvet Moss</value>
  </rewardStarItems>
  <rewardStarItemAmounts length="2">
    <value>1</value>
    <value>2</value>
  </rewardStarItemAmounts>
  <starItemsSuccessScript>scripts/deliveries/star-success.lua</starItemsSuccessScript>
  <starItemsFailureScript>scripts/deliveries/star-failed.lua</starItemsFailureScript>
</data>
Property Name Description

year

The year for the delivery (0 or greater)

season

The season for the delivery (SPRING, SUMMER, AUTUMN, WINTER)

week

The week for the delivery, must be between 0 and 3 inclusive.

requiredItems

An array of the items required for the delivery

requiredItemAmounts

An array of the amount of each of the items required. Should be the same lenght as requiredItems.

rewardCrystals

The amount of crystals the player will get once the delivery is complete.

rewardItems

An array of the items the player will get once the delivery is complete.

rewardItemAmounts

An array of the amount of each item the player will get once the delivery is complete.

requiredItemsSuccessScript

The script to invoke if the player successfully delivered the regular items. The following script variables will be available: arg0 = year, arg1 = season (spring, summer, autumn, winter), arg2 = week (0 - 4)

requiredItemsFailureScript

The script to invoke if the player failed to deliver regular items. The script variable arg0 will represent the amount of crystals the player should receive.

The following properties are optional, but add an extra layer of requirements and rewards.

Property Name Description

requiredStarItems

An array of the star items required for the delivery

requiredStarItemAmounts

An array of the amount of each of the star items required. Should be the same lenght as requiredItems.

rewardStarCrystals

The amount of crystals the player will get once the star part delivery is complete.

rewardStarItems

An array of the star items the player will get once the delivery is complete.

rewardStarItemAmounts

An array of the amount of each star item the player will get once the delivery is complete.

starItemsSuccessScript

The script to invoke if the player successfully delivered the star items. The following script variables will be available: arg0 = year, arg1 = season (spring, summer, autumn, winter), arg2 = week (0 - 4)

starItemsFailureScript

The script to invoke if the player failed to deliver star items. The script variable arg0 will represent the amount of crystals the player should receive.

Ambience

There are two types of ambience in Alchemic Cutie; Global Ambience and Spot Ambience.

Global ambience is used to set non-directional background ambience such as woodland ambience, spring ambience, etc.

Spot ambience is used to set ambience that will pan depending on the sound’s direction relative to the camera (i.e. you’ll hear the sound from your right headphone if the sound source is to the right of the camera).

Volumetric ambience is used to set spot ambience that will move along a track (e.g. riviers).

Ambience Template

Ambience templates determine which sound should play given the season and time of day. The configuration is stored as XML files in config/ambience-templates.

Of course, it is possible to use the same sound for all times of day and season.

<data>
  <internalName>pastoral</internalName>
  <springAmbience>
    <morningAmbience>sfx/amb_springs_spring_morning.ogg</morningAmbience>
    <afternoonAmbience>sfx/amb_springs_spring_afternoon.ogg</afternoonAmbience>
    <eveningAmbience>sfx/amb_springs_spring_evening.ogg</eveningAmbience>
    <nightAmbience>sfx/amb_springs_spring_night.ogg</nightAmbience>
  </springAmbience>
  <summerAmbience>
    <morningAmbience>sfx/amb_springs_summer_morning.ogg</morningAmbience>
    <afternoonAmbience>sfx/amb_springs_summer_afternoon.ogg</afternoonAmbience>
    <eveningAmbience>sfx/amb_springs_summer_evening.ogg</eveningAmbience>
    <nightAmbience>sfx/amb_springs_summer_night.ogg</nightAmbience>
  </summerAmbience>
  <autumnAmbience>
    <morningAmbience>sfx/amb_springs_autumn_morning.ogg</morningAmbience>
    <afternoonAmbience>sfx/amb_springs_autumn_afternoon.ogg</afternoonAmbience>
    <eveningAmbience>sfx/amb_springs_autumn_evening.ogg</eveningAmbience>
    <nightAmbience>sfx/amb_springs_autumn_night.ogg</nightAmbience>
  </autumnAmbience>
  <winterAmbience>
    <morningAmbience>sfx/amb_springs_winter_morning.ogg</morningAmbience>
    <afternoonAmbience>sfx/amb_springs_winter_afternoon.ogg</afternoonAmbience>
    <eveningAmbience>sfx/amb_springs_winter_evening.ogg</eveningAmbience>
    <nightAmbience>sfx/amb_springs_winter_night.ogg</nightAmbience>
  </winterAmbience>
</data>
Property Name Required Description

internalName

Yes

The internal name used by maps and objects to refer to this template

ambience

No

Sets the ambience type for all seasons and time of day

springAmbience

No

Configures the ambience for Spring

summerAmbience

No

Configures the ambience for Summer

autumnAmbience

No

Configures the ambience for Autumn

winterAmbience

No

Configures the ambience for Winter

Each season’s ambience then has the following properties.

Property Name Required Description

ambience

No

Sets the ambience type for all times of day

morningAmbience

No

Configures (or overrides if ambience is set) the ambience audio file for morning

afternoonAmbience

No

Configures (or overrides if ambience is set) the ambience audio file for afternoon

eveningAmbience

No

Configures (or overrides if ambience is set) the ambience audio file for evening

winterAmbience

No

Configures (or overrides if ambience is set) the ambience audio file for winter

Pre-configured Ambience Templates

The following ambience templates have been pre-configured.

birds

internal-small

internal-medium

internal-large

lake

mountain

ocean

pastoral

shrine

springs

waterfall

woodland

Global Ambience

To set the Global Ambience for a map, add a Tiled map property named ambience. The value must specify an ambience template’s internal name.

Spot Ambience

To place a Spot Ambience on a map, create a square shaped Tiled Object with the following properties. The area within the square will be the 100% volume area.

Property Name Sample Value Required Description

type

spot-ambience

Yes

This must be set to spot-ambience

ambience

waterfall

Yes

The internal name of an ambience template

rampUp

160

No

The distance (in pixels) from the 100% zone that the object can be heard (defaults to 160)

Volumetric Ambience

To place a Volumetric Ambience on a map, create a polyline or polygon Tiled Object with the following properties.

Property Name Sample Value Required Description

type

volumetric-ambience

Yes

This must be set to volumetric-ambience

ambience

waterfall

Yes

The internal name of an ambience template

radius

64

No

The radius (in pixels) for the 100% volume zone (defaults to 64)

rampUp

160

No

The distance (in pixels) from the 100% zone that the object can be heard (defaults to 160)

Accessory Templates

Accessory template provides configuration to the engine on how to render Jelly accessories in-game.

Accessory Template XML

<data>
  <overworldTexturePath>accessories/overworld/acc_debug.png</overworldTexturePath>
  <hudTexturePath>accessories/hud/acc_debug.png</hudTexturePath>
  <dialogueTexturePath>accessories/dialogue/acc_debug.png</dialogueTexturePath>
  <id>-1</id>
  <slot>minorA</slot>
  <itemInternalName>flower</itemInternalName>
  <renderConfig>
    <entry>
      <key>EAST</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>false</flip>
        <priority>-10</priority>
      </value>
    </entry>
    <entry>
      <key>WEST</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>true</flip>
        <priority>-10</priority>
      </value>
    </entry>
    <entry>
      <key>NORTH</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>false</flip>
        <priority>10</priority>
      </value>
    </entry>
    <entry>
      <key>NORTH_EAST</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>false</flip>
        <priority>10</priority>
      </value>
    </entry>
    <entry>
      <key>NORTH_WEST</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>true</flip>
        <priority>10</priority>
      </value>
    </entry>
    <entry>
      <key>SOUTH</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>false</flip>
        <priority>-10</priority>
      </value>
    </entry>
    <entry>
      <key>SOUTH_EAST</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>false</flip>
        <priority>-10</priority>
      </value>
    </entry>
    <entry>
      <key>SOUTH_WEST</key>
      <value class="com.alchemiccutie.api.jelly.AccessoryRenderConfig">
        <flip>true</flip>
        <priority>-10</priority>
      </value>
    </entry>
  </renderConfig>
  <forceDefaultShape>false</forceDefaultShape>
</data>
Property Name Required Description

itemInternalName

Yes

The internal name of the Item corresponding to this template

slot

Yes

The slot the item occupies. Only one item can be in a slot at a time. Takes in an arbitrary string, if empty it will default to an empty string.

overworldTexturePath

Yes

The texture to use for the overworld sprite. Is NOT required if at least one of the directional TexturePaths is set

overworldTexturePathNorth

No

The texture to use for the overworld sprite when facing North, North-West and North-East

overworldTexturePathSouth

No

The texture to use for the overworld sprite when facing South, South-West and South-East

overworldTexturePathEast

No

The texture to use for the overworld sprite when facing East

overworldTexturePathWest

No

The texture to use for the overworld sprite when facing West

hudTexturePath

Yes

The texture to use for when the Jelly is in the player’s pouch

dialogueTexturePath

Yes

The texture to use for when the Jelly is in a dialogue

renderConfig

Yes

The render behavior depending on the Jelly’s direction. flip will horizontally flip the texture. priority is the render priority of this accessory in relation to other accessories (sorted by numerical order), with numbers greater than 0 being infront of the jelly.

forceDefaultShape

No

Indicates if a jelly wearing the accessory should be rendered with the default shape for animation purposes

Item Spawn Templates

Item spawn templates provide information to the spawning system as to what items spawn at different times of day. The templates can be reused for multiple spawn areas.

Item Spawn Template XML

<data>
  <overallPercentage>-1</overallPercentage>
  <morningItemNames length="3">
    <value>crystal</value>
    <value>blobite gem</value>
    <value>bloada blast</value>
  </morningItemNames>
  <morningItemPercentages length="3">
    <value>10.0</value>
    <value>20.0</value>
    <value>70.0</value>
  </morningItemPercentages>
  <afternoonItemNames length="3">
    <value>crystal</value>
    <value>blobite gem</value>
    <value>bloada blast</value>
  </afternoonItemNames>
  <afternoonItemPercentages length="3">
    <value>10.0</value>
    <value>30.0</value>
    <value>60.0</value>
  </afternoonItemPercentages>
  <eveningItemNames length="3">
    <value>crystal</value>
    <value>socialite gem</value>
    <value>bloada blast</value>
  </eveningItemNames>
  <eveningItemPercentages length="3">
    <value>30.0</value>
    <value>20.0</value>
    <value>50.0</value>
  </eveningItemPercentages>
  <nightItemNames length="3">
    <value>crystal</value>
    <value>tummite gem</value>
    <value>Plutostone</value>
  </nightItemNames>
  <nightItemPercentages length="3">
    <value>25.0</value>
    <value>5.0</value>
    <value>70.0</value>
  </nightItemPercentages>
  <internalName>Fields Template 1</internalName>
  <name>Field Template 1</name>
</data>
Property Name Required Description

internalName

Yes

The internal name of the template

name

No

The name for developer notetaking (not used by engine)

description

No

The description for developer notetaking (not used by engine)

overallPercentage

No

The percentage chance that any items are spawned. If set to -1 then items will always spawn. Otherwise must be set to 0-100 inclusive.

morningItemNames

No

The internal names of possible items to spawn in the morning (case-insensitive)

morningItemPercentages

No

The percentage chance for each possible morning item (must total to 100)

afternoonItemNames

No

The internal names of possible items to spawn in the afternoon (case-insensitive)

afternoonItemPercentages

No

The percentage chance for each possible afternoon item (must total to 100)

eveningItemNames

No

The internal names of possible items to spawn in the evening (case-insensitive)

eveningItemPercentages

No

The percentage chance for each possible evening item (must total to 100)

nightItemNames

No

The internal names of possible items to spawn at night (case-insensitive)

nightItemPercentages

No

The percentage chance for each possible item at night (must total to 100)

Overall Percentage Examples

If the spawn area has a min of 2 and a max of 4, and you set the overall percentage to 70. Then there is a 70 percent chance of between 2 and 4 items spawning.

If you want only a single item to have a chance of spawning, set the min and max items to 1 in the item spawn area in tiled, and then set the overall percentage to the chance you want that item to spawn.

Jelly Spawn Templates

Jelly spawn templates provide possible jelly properties to the spawning system. The templates can be reused for multiple spawn areas.

Jelly Spawn Template XML

<data>
  <minLevels length="3">
    <value>10</value>
    <value>15</value>
    <value>20</value>
  </minLevels>
  <maxLevels length="3">
    <value>15</value>
    <value>17</value>
    <value>25</value>
  </maxLevels>
  <palettes length="3">
    <value>berry</value>
    <value>dew</value>
    <value>grape</value>
  </palettes>
  <palettePercentages length="3">
    <value>70.0</value>
    <value>20.0</value>
    <value>10.0</value>
  </palettePercentages>
  <shapes length="3">
    <value>cub</value>
    <value>joble</value>
    <value>scene</value>
  </shapes>
  <shapePercentages length="3">
    <value>60.0</value>
    <value>20.0</value>
    <value>20.0</value>
  </shapePercentages>
  <slotOneTraits length="3">
    <value>insomniac</value>
    <value>touchy-color</value>
    <value>glutton</value>
  </slotOneTraits>
  <slotOneTraitPercentages length="3">
    <value>50.0</value>
    <value>30.0</value>
    <value>20.0</value>
  </slotOneTraitPercentages>
  <overallPercentage>-1</overallPercentage>
  <slotTwoProbability>100</slotTwoProbability>
  <slotTwoTraits length="3">
    <value>trendy</value>
    <value>sweet dreams</value>
    <value>romantic</value>
  </slotTwoTraits>
  <slotTwoTraitPercentages length="3">
    <value>20.0</value>
    <value>20.0</value>
    <value>60.0</value>
  </slotTwoTraitPercentages>
  <slotThreeProbability>100</slotThreeProbability>
  <slotThreeTraits length="3">
    <value>glutton</value>
    <value>love machine</value>
    <value>friend finder</value>
  </slotThreeTraits>
  <slotThreeTraitPercentages length="3">
    <value>10.0</value>
    <value>50.0</value>
    <value>40.0</value>
  </slotThreeTraitPercentages>
  <internalName>Fields Template 1</internalName>
  <name>Field Template 1</name>
  <maxRelicMeterRange>10-20</maxRelicMeterRange>
  <currentRelicMeterRange>1-10</currentRelicMeterRange>
</data>
Property Name Required Description

internalName

Yes

The internal name of the template

name

No

The name for developer notetaking (not used by engine)

description

No

The description for developer notetaking (not used by engine)

ageRange

No

The possible age range for the wild jelly to spawn with. Can be passed in as a single number to make the jellies spawn with that value or can be passed in as "1-50" for jellies to spawn with a random value in that range (inclusive)

maxRelicMeterRange

No

The possible Max Relic Meter set on the spawned wild jellies. Can be passed in as a single number to make jellies spawn with that value or can be passed in as "1-50" for the jellies to spawn with a random value in that range (inclusive)

currentRelicMeterRange

No

The possible progress on the Relic Meter set on the spawned wild jellies. Can be passed in as a single number to make jellies spawn with that value or can be passed in as "1-50" for the jellies to spawn with a random value in that range (inclusive)

minLevels

Yes

The minimum levels of the jelly stats. One value per stat ordered alphabetically (Blob, Social, Tummy).

maxLevels

Yes

The maximum levels of the jelly stats. One value per stat ordered alphabetically (Blob, Social, Tummy).

overallPercentage

No

The percentage chance that any jellies are spawned. If set to -1 then jellies will always spawn. Otherwise must be set to 0-100 inclusive.

palettes

Yes

The possible jelly palette internal names

palettesPercentages

Yes

The percentage chance for each possible palette (must total to 100)

shapes

Yes

The possible jelly shape internal names

shapesPercentages

Yes

The percentage chance for each possible shape (must total to 100)

slotOneTraits

Yes

The possible jelly traits for the first trait slot. * means any trait can spawn. Alternatively it is the internal name of individual traits that can spawn.

slotOneTraitsPercentages

Yes

The percentage chance for each possible trait for slot one(must total to 100).

slotTwoProbability

No

The chance that a second trait will be present. Must be between 0 and 100. If this property is missing, but slotTwoTraits is populated, this will default to 100.

slotTwoTraits

No

The possible jelly traits for the second trait slot. * means any trait can spawn. Alternatively it is the internal name of individual traits that can spawn.

slotTwoTraitPercentages

No

Required if slotTwoTraits is populated. The percentage chance for each possible trait for slot two(must total to 100).

slotThreeProbability

No

The chance that a third trait will be present. Must be between 0 and 100. A third trait will only have a chance of being populated if a second trait is. If this property is missing, but slotThreeTraits is populated, this will default to 100.

slotThreeTraits

No

The possible jelly traits for the third trait slot. * means any trait can spawn. Alternatively it is the internal name of individual traits that can spawn.

slotThreeTraitPercentages

No

Required if slotThreeTraits is populated. The percentage chance for each possible trait for slot three(must total to 100).

Overall Percentage Examples

If the spawn area has a min of 2 and a max of 4, and you set the overall percentage to 70. Then there is a 70 percent chance of between 2 and 4 jellies spawning.

If you want only a single jelly to have a chance of spawning, set the min and max jellys to 1 in the jelly spawn area in tiled, and then set the overall percentage to the chance you want that item to spawn.

Resource Node Templates

Resource Nodes act as sources for items to the player (e.g. plants that can have fruit picked from them). They can (optionally) be picked multiple times and will regenerate over a fixed period of time.

Resource Node Templates are used to generate the Resource Nodes placed in a Tiled map. These templates are defined via XML - one Resource Node per template file. Currently there are 3 types of Resource Nodes that provide different behaviors; Simple, Time of Day and Quantity.

Resource Node Template XML

All Resource Node Template types share a common XML format and a properties provides the type-specific information. The following is a sample:

<data>
  <regrowthSeasons length="0"/>
  <internalName>Flower</internalName>
  <name>Flower</name>
  <description>This is a flower</description>
  <mode>simple</mode>
  <collision>true</collision>
  <destroyWhenEmpty>false</destroyWhenEmpty>
  <maxHarvest>3</maxHarvest>
  <regenTime>60</regenTime>
  <properties>
    <entry>
      <key>spriteDefault</key>
      <value>resourceNodes/burpWeedOn</value>
    </entry>
    <entry>
      <key>spriteRegen</key>
      <value>resourceNodes/burpWeedRe</value>
    </entry>
    <entry>
      <key>spriteHarvest</key>
      <value>resourceNodes/burpWeedEmpty</value>
    </entry>
  </properties>
  <touchSounds length="0"/>
</data>
Property Name Required Description

name

Yes

The name of the resource node

description

No

The description of the resource node

mode

Yes

Can be simple, time or quantity (see below)

collision

No

true if the player collides with this resource node, otherwise false

destroyWhenEmpty

No

true if the resource node should be destroyed when empty, otherwise false

maxHarvest

Yes

The maximum number of items available for harvesting

regenTime

Yes

The time taken for 1 item to be regenerated in the node. Write as 1m for one minute. 1 for one hour or 1d for one day.

touchSounds

No

An list of sounds played when the node is touched. Takes in file path, or GameSound name. If not specified then no sound will be played on touch.

properties

Yes

The mode specific properties (see below)

Simple Resource Nodes

Simple resource nodes have 5 graphical states.

Property Name Required Description

itemHarvested

Yes

The name of the item that can be harvested from this resource node

spriteDefault

Yes

This is the default sprite when at least 1 item is available to be picked

spriteTouch

No

This is the sprite when at least 1 item is available to be picked and the player has collided with the node

spriteHarvest

Yes

This is the sprite when no items are available to be picked

spriteRegen

No

This is the sprite when at least 1 item is nearly available to be picked

spriteRegenTouch

No

This is the sprite when items are nearly available to be picked and the player has collided with the node

The item available

Time of Day Resource Nodes

Time of Day resource nodes can change graphical states and item availability depending on time of day. They use the same properties as Simple Resource Nodes, except the following properties are available for overriding values based on time of day.

Property Name Required Description

itemHarvested

Yes

The name of the item that can be harvested from this resource node

spriteDefault

Yes

This is the default sprite when at least 1 item is available to be picked

spriteTouch

No

This is the sprite when at least 1 item is available to be picked and the player has collided with the node

spriteHarvest

Yes

This is the sprite when no items are available to be picked

spriteRegen

No

This is the sprite when at least 1 item is nearly available to be picked

spriteRegenTouch

No

This is the sprite when items are nearly available to be picked and the player has collided with the node

morningItemHarvested

No

Overrides itemHarvested during morning. This can be left empty to disable item harvesting during this time.

morningSpriteDefault

No

Overrides spriteDefault during morning

morningSpriteTouch

No

Overrides spriteTouch during morning

morningSpriteHarvest

No

Overrides spriteHarvest during morning

morningSpriteRegen

No

Overrides spriteRegen during morning

morningSpriteRegenTouch

No

Overrides spriteRegenTouch during morning

afternoonItemHarvested

No

Overrides itemHarvested during afternoon. This can be left empty to disable item harvesting during this time.

afternoonSpriteDefault

No

Overrides spriteDefault during afternoon

afternoonSpriteTouch

No

Overrides spriteTouch during afternoon

afternoonSpriteHarvest

No

Overrides spriteHarvest during afternoon

afternoonSpriteRegen

No

Overrides spriteRegen during afternoon

afternoonSpriteRegenTouch

No

Overrides spriteRegenTouch during afternoon

eveningItemHarvested

No

Overrides itemHarvested during evening. This can be left empty to disable item harvesting during this time.

eveningSpriteDefault

No

Overrides spriteDefault during evening

eveningSpriteTouch

No

Overrides spriteTouch during evening

eveningSpriteHarvest

No

Overrides spriteHarvest during evening

eveningSpriteRegen

No

Overrides spriteRegen during evening

eveningSpriteRegenTouch

No

Overrides spriteRegenTouch during evening

nightItemHarvested

No

Overrides itemHarvested during night. This can be left empty to disable item harvesting during this time.

nightSpriteDefault

No

Overrides spriteDefault during night

nightSpriteTouch

No

Overrides spriteTouch during night

nightSpriteHarvest

No

Overrides spriteHarvest during night

nightSpriteRegen

No

Overrides spriteRegen during night

nightSpriteRegenTouch

No

Overrides spriteRegenTouch during night

Quantity Resource Nodes

Quantity resource nodes are similar to Simple Resources Nodes except that the sprites can be overriden depending on the current quantity of available items.

The following properties must have the N replaced with a digit value. Note that not all digits are needed as the resource node will search downwards towards 0 for the nearest available sprite corresponding to the current amount of items available for picking.

Property Name Required Description

itemHarvestedN

Yes

The name of the item that can be harvested from this resource node when the total items equals N

spriteDefaultN

Yes

This is the default sprite when the total items available to be picked equals N

spriteTouchN

No

This is the sprite when the total items available to be picked equals N and the player has collided with the node

spriteHarvest0

Yes

This is the sprite when no items are available to be picked

spriteRegenN

No

This is the sprite when the total items available equals N - 1 and N is nearly available to be picked

spriteRegenTouchN

No

This is the sprite when the total items available equals N - 1 and N is nearly available to be picked and the player has collided with the node

Scripting

Rough Draft Tool

The mod packing tool includes a utility to quickly draft a rough lua script from a text file. While it does not handle dialogue choices, loops or choreography, it is useful for quickly converting a writer’s script into a half-finished scene.

To use the tool, create the path _writing/input in your mod directory. This is where you can place your text files. When the mod is packed, it will output the rough lua scripts to _writing/output. Again, these are rough drafts and won’t run out-of-the-box.

Below is an example of an input text file. The following rules are used:

  • Any line starting with a character name followed by a semi-colon will be turned into a dialogue line

  • Character names are not case-sensitive as these are transformed into lua variables that require initialising in a scene

  • Any line not starting with a letter will be turned into a comment in the lua script

  • Indentation is ignored

(desmond, player move to wait at titus)
Titus: Papers
Vira: Ahoy there!
    (titus is acting odd)
    Titus: ...

This generates the following unfinished scene script.

--(desmond, player move to wait at titus)
chat:say(titus, "Papers"):waitForCompletion()
chat:say(vira, "Ahoy there!"):waitForCompletion()
--(titus is acting odd)
chat:say(titus, "..."):waitForCompletion()

Futures

Most scripting functions return futures. These act as hooks to the asynchronous nature of scripting - that is, when you execute a line of the script it may not complete immediately. All futures implement a waitForCompletion() function if you wish to block further execution of the script until a scripting task has completed.

future:waitForCompletion()

Global Variables

The following variables are available in all scripts.

Variable Binds To

audio

Audio API

camera

Camera API

chat

Camera API

clock

Clock API

items

Items API

jellies

Jellies API

npcs

NPCs API

player

Player API

quests

Quests API

shops

Shops API

shrines

Shrines API

utils

Utils API

Audio API

The audio variable provides access to audio system for playing music and sound effects. See section below for a list of possible game sounds and music tracks.

-- Returns a future to play a sound effect at full volume
audio:playSoundEffect("sfx/sfx_coin.ogg")

-- Returns a future to play a sound effect at a specified volume (0.0 - 1.0)
audio:playSoundEffect("sfx/sfx_coin.ogg", 1.0)

-- Returns a future to play (or resume) a selected music track
-- The second parameter should be set to true to fade in the track, false otherwise.
audio:playOrResumeMusic("SUMMER_MORNING", true)

-- Returns a future to play (or resume) a selected music track
-- The second parameter should be set to true to fade in the track.
-- Third parameter can be then passed in to have a custom fade in duration.
audio:playOrResumeMusic("SUMMER_MORNING", true, 2.0)

-- Returns a future to play (or resume) the current time of day music
-- The parameter should be set to true to fade in the track, false otherwise.
audio:resumeCurrentTimeOfDayMusic(true)

-- Returns a future to play (or resume) the current time of day music
-- The parameter should be set to true to fade in the track.
-- Third parameter can be then passed in to have a custom fade in duration.
audio:resumeCurrentTimeOfDayMusic(true, 10.0)

-- Returns a future to stop the currently playing music.
-- The first parameter should be set to true to fade out the track, false otherwise.
audio:stopMusic(true)

-- Returns a future to stop the currently playing music.
-- The first parameter should be set to true to fade out the track, false otherwise.
-- A second parameter can be used to set a custom value for fade out duration
audio:stopMusic(true, 2)

-- Enables/disables audio system automatic music track switching
-- This can be used to prevent new track automatically starting after stopping previous music.
audio:setAutomaticMusic(false)

Game Music

The following is the list of all playable game music tracks.

"INTRO_FLUTE"

"ACTION"
"FAMILY"
"SHRINE"

"AUTUMN_MORNING"
"AUTUMN_AFTERNOON"
"AUTUMN_EVENING"
"AUTUMN_NIGHT"

"SPRING_MORNING"
"SPRING_AFTERNOON"
"SPRING_EVENING"
"SPRING_NIGHT"

"SUMMER_MORNING"
"SUMMER_AFTERNOON"
"SUMMER_EVENING"
"SUMMER_NIGHT"

"WINTER_MORNING"
"WINTER_AFTERNOON"
"WINTER_EVENING"
"WINTER_NIGHT"

Camera API

The camera variable provides access to game camera and its effects.

local mapX = 0
local mapY = 1
local tileX = 20
local tileY = 10

-- Duration values are always in seconds
local duration = 1.0

-- Returns a future to immediately center the camera on the specified coordinate
camera:setTo(mapX, mapY, tileX, tileY)

-- Returns a future to immediately center the camera on the specified warpoint
camera:setTo("waypoint")

-- Returns a future to immediately center the camera on the specified warpoint
camera:setTo(npc)

-- Returns a future to immediately center the camera on the specified warpoint
camera:setTo(jelly)

-- Returns a future to immediately center the camera on the player
camera:setToPlayer()

-- Returns a future to pan to the specified coordinate
-- The duration parameter specifies how long the pan should take
camera:panTo(mapX, mapY, tileX, tileY, duration)

-- Returns a future to pan the camera to the position of an NPC
-- The duration parameter specifies how long the pan should take
camera:panTo(npc, duration)

-- Returns a future to pan the camera to the position of a Jelly
-- The duration parameter specifies how long the pan should take
camera:panTo(jelly, duration)

-- Returns a future to pan the camera to the position of the Player
-- The duration parameter specifies how long the pan should take
camera:panToPlayer(duration)

-- Returns a future to set the camera to an NPCs position and follow the NPC
camera:lockTo(npc)

-- Returns a future to set the camera to an Jelly's position and follow the Jelly
camera:lockTo(jelly)

-- Returns a future to set the camera to the player's position and follow the player
camera:lockToPlayer()

-- Returns a future that detaches the camera from what it is currently following
camera:detach()

-- Returns a future to pan the camera to the position of an NPC and then follow the NPC
-- The duration parameter specifies how long the pan should take
camera:panAndLockTo(npc, duration)

-- Returns a future to pan the camera to the position of a Jelly and then follow the Jelly
-- The duration parameter specifies how long the pan should take
camera:panAndLockTo(jelly, duration)

-- Returns a future to pan the camera to the position of the player and then follow the player
-- The duration parameter specifies how long the pan should take
camera:panAndLockToPlayer(duration)

-- Returns a future to fade in the camera over 0.25 seconds. Completes immediately if already faded in.
camera:fadeIn()

-- Returns a future to fade out the camera over 0.25 seconds. Completes immediately if already faded out.
camera:fadeOut()

-- Returns a future to fade in the camera over a specified duration. Completes immediately if already faded in.
camera:fadeIn(duration)

-- Returns a future to fade out the camera over a specified duration. Completes immediately if already faded out.
camera:fadeOut(duration)

-- Returns a future to fade in the camera over 0.25 seconds using the passed in rgb value. Completes immediately if already faded in.
-- Note: Clamps values if below 0 or above 255
camera:fadeIn(255, 255, 255)

-- Returns a future to fade out the camera over 0.25 seconds using the passed in rgb value. Completes immediately if already faded out.
-- Note: Clamps values if below 0 or above 255
camera:fadeOut(255, 255, 255)

-- Returns a future to fade in the camera over a specified duration and passed in rgb value. Completes immediately if already faded in.
-- Note: Clamps values if below 0 or above 255
camera:fadeIn(10, 255, 255, 255)

-- Returns a future to fade out the camera over a specified duration and passed in rgb value. Completes immediately if already faded out.
-- Note: Clamps values if below 0 or above 255
camera:fadeOut(10, 255, 255, 255)

-- Returns a future to white in the camera over 0.25 seconds. Completes immediately if already whited in.
camera:whiteIn()

-- Returns a future to white out the camera over 0.25 seconds. Completes immediately if already whited out.
camera:whiteOut()

-- Returns a future to white in the camera over a specified duration. Completes immediately if already whited in.
camera:whiteIn(duration)

-- Returns a future to white out the camera over a specified duration. Completes immediately if already whited out.
camera:whiteOut(duration)

-- Returns a future for a cinematic letterbox to slide in over 0.25 seconds. Completes immediately if letterbox is already visible.
camera:letterboxIn()

-- Returns a future for a cinematic letterbox to slide out over 0.25 seconds. Completes immediately if letterbox is already hidden.
camera:letterboxOut()

-- Returns a future for a cinematic letterbox to slide in over a specified duration. Completes immediately if letterbox is already visible.
camera:letterboxIn(duration)

-- Returns a future for a cinematic letterbox to slide out over a specified duration. Completes immediately if letterbox is already hidden.
camera:letterboxOut(duration)

-- Returns a future to shake the camera for a specified duration.
camera:shake(duration)

-- Returns a future to slide in the camera for a specified duration from a specific direction.
-- direction in {"up", "down", "left", "right"}
camera:slideIn(duration, direction)

-- Returns a future to slide out the camera for a specified duration to a specific direction.
-- direction in {"up", "down", "left", "right"}
camera:slideOut(duration, direction)

-- Returns a future to bounce the camera for a specified number of times with a "bouncyness" of 0.6
camera:bounceIn(bounces)

-- Returns a future to bounce the camera for a specified number of times with the specified "bouncyness"
-- 0 < bouncyness < 1
camera:bounceIn(bounces, bouncyness)

-- Returns a future to wipe the camera across the screen for a specified number of times with the specified direction
-- Direction in {"ltr", "rtl"}
camera:windshieldWipe(duration, times, direction)

-- Returns a boolean, true if the player is in view of the camera.
camera:isPlayerInView()

-- Returns a boolean, true if the specified game character is in view of the camera.
Takes in the npc idOrKey as a string, an npc scripting wrapper, or a jelly scripting wrapper.
camera:isGameCharacterInView("Vira")

-- Returns a boolean, true if the map (map X/Y) is currently rendering on screen
camera:isMapRendering(32, 37)

-- Clears any overlays set on the camera (Forest Shadow and Mountain Steam)
-- Notes: this should be used when moving a player from a map with overlay to a map with no overlay
camera:clearOverlays()

-- Stores current camera overlays so they can be restored
-- Notes: this should be used BEFORE moving player from a map with overlay to a map with no overlay
camera:storeOverlays()

-- Restores stored camera overlays
-- Notes: this should be used AFTER moving player back to a map with overlay
camera:restoreOverlays()

-- Applies forest shadow overlay (Note: will remove mountain overlays)
camera:applyForestShadowOverlay()

-- Applies mountain steam overlay (Note: will remove forest + mountain top overlays)
camera:applyMountainSteamOverlay()

-- Applies mountain top steam overlay (Note: will remove forest + mountain overlays)
camera:applyMountainTopSteamOverlay()

Chat API

The chat variable is only available during dialogue scripts.

-- Returns a scripting wrapper for a npc. Takes in a non negative integer index. The local variable, called npc here, can be used with other commands below.
local npc = chat:getNpc(0)

-- Returns a future to have an NPC say something.
-- Note: Calling wait for completion will wait for the player's prompt to advance the dialogue.
chat:say(npc,"Hey there stink butt!")
chat:say(npc,"Hey there stink butt!"):waitForCompletion()
chat:sayWithArgs(npc,"I'm {0} and I'm {1} years old", {name, age})

-- Returns a future to have an NPC say something and change the NPC's expression
-- Note: Calling wait for completion will wait for the player's prompt to advance the dialogue.
chat:say(npc,"Hey there stink butt!", "scared"):waitForCompletion()
chat:sayWithArgs(npc,"I'm {0} and I'm {1} years old", "scared", {name, age})

-- Returns a future to have an NPC change expression while keeping already displayed dialogue
-- Note: Calling wait for completion will wait for the player's prompt to advance the dialogue, otherwise expression will be skipped and overritten by default one.
chat:expression(npc, "scared"):waitForCompletion()

-- Returns a future to have the player say something
-- Note: Calling wait for completion will wait for the player's prompt to advance the dialogue.
chat:say(player,"Awwwh yeah!")
chat:say(player,"Awwwh yeah!"):waitForCompletion()
chat:sayWithArgs(player,"I'm {0} and I'm {1} years old", {name, age})

-- Returns a future to have the player say something and change the player's expression
-- Note: Calling wait for completion will wait for the player's prompt to advance the dialogue.
chat:say(player,"Awwwh yeah!", "scared"):waitForCompletion()
chat:sayWithArgs(player,"I'm {0} and I'm {1} years old", "scared", {name, age})

-- Returns a future to have the player change expression while keeping already displayed dialogue
-- Note: Calling wait for completion will wait for the player's prompt to advance the dialogue, otherwise expression will be skipped and overritten by default one.
chat:expression(player, "scared"):waitForCompletion()

-- Returns a future that presents a choice to the player.
-- The first variable in the choice function is the character who will appear in the dialogue portrait.
local choices = {"Yes.", "No."}
local choiceResult = chat:choice(npc, "Got a present for me?", choices)
choiceResult:waitForCompletion()
if choiceResult:getSelection() == 0 then
    -- Player picked Yes
else
    -- Player picked No
end

-- Returns a future that presents a choice to the player.
-- The first variable in the choice function is the character who will appear in the dialogue portrait.
-- The second variable is the expression of the character in the portrait
chat:choice(npc, "sad", "Got a present for me?", choices)

-- Similar to sayWithArgs except the args are applied both to the choice text and the choices
chat:choiceWithArgs(npc, "sad", "Got a present for me {0}?", choices, {name})

-- Returns a future with a changed dialogue portrait background
chat:changeBackground("happy")

-- Returns a future with the dialogue window hidden
chat:hide()

-- Returns a future with the dialogue window shown
chat:show()

-- Returns a future to open the NPC's shop (if they have one)
-- Note: Calling wait for completion will wait for the player to finish using the shop
chat:openShop()
chat:openShop():waitForCompletion()

-- Returns a future to open and close the Notebook.
-- Note: This shows/hides all other hud elements.
chat:openNotebook():waitForCompletion()
chat:closeNotebook():waitForCompletion()

-- Returns a future to open and close the Notebook for tutorial purposes.
-- Note: Disables dialogue leave hotkey, switching between notebook tabs and shows/hides limited amount of hud elements.
chat:openNotebookTutorial():waitForCompletion()
chat:closeNotebookTutorial():waitForCompletion()

-- Returns true if notebook is currently open or false if closed
chat:isNotebookOpen()

-- Returns a future to open the notebook to a specific page. Note the notebook must be open for these to have any result.
chat:openNotebookMapTab():waitForCompletion()
chat:openNotebookQuestList():waitForCompletion()
chat:openNotebookJellyList():waitForCompletion()
chat:openNotebookCodexList():waitForCompletion()
chat:openNotebookCutiepediaList():waitForCompletion()

-- Returns a future to open the notebook jelly details page for the specified captured jelly.
-- Note: Takes in a JellyScriptingWrapper
chat:openNotebookJellyDetails(jelly)

local jellyFromFarm = jellies:getRandomFarmJelly()
chat:openNotebookJellyDetails(jellyFromFarm)

-- Returns a future to open the character details page. This takes in a local variable, like the one described above.
chat:openNotebookCharacterDetails(npc):waitForCompletion()

-- Returns a future to clear the dialogue. Wait for completion should be called with this.
chat:clearDialogue():waitForCompletion()

-- Destroys the chat instance and re-enables player interaction
-- Should only be used if npcs:beginMultiChat() was used during the script
-- Re-enables the dialogue leave hotkey
chat:dispose():waitForCompletion()

-- Returns a future that hides and disables the leave dialogue key
-- Note: leave key gets re-enabled after calling chat:dispose()
chat:disableLeaveKey():waitForCompletion()

-- Returns a future that shows and enables the leave dialogue key
chat:enableLeaveKey():waitForCompletion()

-- Returns a future which opens a specific cutiepedia page. Takes in a string, and optionally a boolean. If the optional boolean is true the script will wait until the player closes the notebook.
chat:openCutiepediaPage(cutiepedia_page)

local waitForClose = true
chat:openCutiepediaPage(cutiepedia_page, waitForClose)

-- Returns a future which opens Player's box storage, on the shipment page, during the tutorial
chat:openShipmentDeliveryTabTutorial()

-- Returns a future which closes Player's box storage during the tutorial
chat:closeShipmentDeliveryTabTutorial()

Note: The following character expressions are available for use. Usage is not case-sensitive. If the character expression is not available, it will fallback to the default expression.

        DEFAULT,
        SCARED,
        HAPPY,
        SAD,
        STERN,
        LAUGHING,
        CRYING,
        SLEEPING,
        THINKING,
        CURIOUS,
        CONFUSED,
        SMIRKING,
        ANNOYED,
        BITTER,
        SALTY,
        SOUR,
        SPICEY,
        SWEET,
        JUST_RIGHT,
        PERFECT,
        CHEER,
        WHATEVER,
        NYAH,
        OOPS,
        SMUG,
        PANCAKE,
        ACTUALLY,
        NO_WAY,
        HUH,
        UNDERSTAND,
        ABOUT_THAT,
        SHUCKS,
        EYEROLL,
        HM,
        NOT_REALLY,
        POG,
        SHOCKING,
        YEAH_YEAH,
        ITS_OKAY,
        GOOD_BOY,
        HUFF,
        CLOSE,
        QUIT_IT,
        NERVOUS,
        ALARM,
        MELT,
        NOT_ME,
        SQUINT,
        WINK,
        CHARGIN,
        DETERMINED,
        DOHKAY,
        DONT_GO,
        HOORAY,
        IS_THAT_SO,
        WHAT_NOW,
        WOW,
        GIGGLE,
        NO_YOU,
        WUT,
        SNEER,
        BAHA,
        EMERGENCY,
        FUMING,
        FURY,
        MWAHAHA,
        OH_SURE,
        PSST,
        TATA,
        ULIKE,
        SLOT0,
        SLOT1,
        SLOT2,
        SLOT3,
        SLOT4,
        SLOT5,
        SLOT6,
        SLOT7,
        SLOT8,
        SLOT9,
        SLOT10,
        SLOT11,
        SLOT12,
        SLOT13,
        SLOT14,
        SLOT15

Note: The following portrait backgrounds are available. Usage is not case-sensitive.

        DEFAULT,
        DEBUG,
        DESPAIR,
        STINK,
        WHITE,
        YAY,
        HEART,
        NO,
        YES

Clock API

The clock variable provides access to game clock.

-- Returns an int representing how many years have passed in-game, 0 = first year
local year = clock:getYear()

-- Returns an int representing the current season in-game
-- 0 = Spring, 1 = Summer, 2 = Autumn, 3 = Winter
local season = clock:getSeason()

-- Returns the day of the current month/season (0 - 27)
local dayOfMonth = clock:getDayOfMonth()

-- Returns the day of the current week (0 - 6)
-- 0 = Monday, 1 = Tuesday, etc.
local dayOfWeek = clock:getDayOfWeek()

-- Returns the hour of the current day (0 - 23)
-- 0 = Midnight, 1 = 1am, 12 = Midday, 13 = 1pm, etc.
local hourOfDay = clock:getHourOfDay()

-- Returns the minute of the current hour (0 - 59)
local minuteOfHour = clock:getMinuteOfHour()

-- Returns the absolute time in game minutes that have passed since Year 0
local absoluteTimeInMinutes = clock:getAbsoluteTimeInMinutes()

-- Returns the absolute time in game days that have passed since Year 0
local absoluteTimeInDays = clock:getAbsoluteTimeInDays()

-- Returns true if hour on the clock is between 6 and 11 inclusive
clock:isMorning()

-- Returns true if hour on the clock is between 12 and 17 inclusive
clock:isAfternoon()

-- Returns true if hour on the clock is between 18 and 23 inclusive
clock:isEvening()

-- Returns true if hour on the clock is between 0 and 5 inclusive
clock:isNight()

-- Returns true if hour on the clock is 6
clock:isWakingHour()

-- Returns true if hour on the clock is 22
clock:isSleepingHour()

-- Skips time by hours and minutes entered, as integer values. Fades in and out.
-- NOTE: Does not work during dialogue. Call chat:hide():waitForCompletion() then skipTime and re-show dialogue
clock:skipTime(hours,minutes):waitForCompletion()

-- Skips time by hours and minutes entered, as integer values, without fading in/out.
-- NOTE: Does not work during dialogue. Call chat:hide():waitForCompletion() then skipTime and re-show dialogue
clock:skipTimeNoFade(hourOfDay, minuteOfHour):waitForCompletion()

-- Sleep screen is brought up and time skips forward to the specific hour of day and minute of hour, as integer values
-- NOTE: Does not work during dialogue. Call chat:hide():waitForCompletion() then skipTime and re-show dialogue
clock:sleepTo(hourOfDay, minuteOfHour):waitForCompletion()

-- Skips forward to the specific hour of day and minute of hour, as integer values
-- NOTE: Does not work during dialogue. Call chat:hide():waitForCompletion() then skipTime and re-show dialogue
clock:skipTo(hourOfDay, minuteOfHour):waitForCompletion()

-- Returns a future to pause the game clock
clock:pause():waitForCompletion()

-- Returns a future to resume the game clock
clock:resume():waitForCompletion()

-- Returns if the game clock is paused
local isClockPaused = clock:isPaused()

-- Sets the clock to a specific time
-- Note: Only daylight/weather systems will update
-- Year (0 = first year), Season (0 - 3), Day (0 - 27), Hour (0 - 23), Minute (0 - 59)
clock:setTo(year, season, day, hour, minute):waitForCompletion()

-- Sets the clock to a specific time in the current year
-- Note: Only daylight/weather systems will update
-- Season (0 - 3), Day (0 - 27), Hour (0 - 23), Minute (0 - 59)
clock:setTo(season, day, hour, minute):waitForCompletion()

-- Sets the clock to a specific time in the current year and season
-- Note: Only daylight/weather systems will update
-- Day (0 - 27), Hour (0 - 23), Minute (0 - 59)
clock:setTo(day, hour, minute):waitForCompletion()

-- Sets the clock to a specific time in the current year, season and day
-- Note: Only daylight/weather systems will update
-- Hour (0 - 23), Minute (0 - 59)
clock:setTo(hour, minute):waitForCompletion()

-- Returns a future with meal times disabled
clock:disableMealTime()

-- Returns a future with meal times enabled
clock:enableMealTime()

-- Returns true/false if meal time is enabled/disabled
clock:isMealTimeEnabled()

Cutiepedia API

The pedia variable provides access to the Cutiepedia.

-- Returns a boolean, true if entry is revealed to the player. Takes in the entryId as a string, e.g. "pedia_pooPatrol1Start".
local revealed = pedia:isCutiepediaEntryRevealed("pedia_pooPatrol1Start")

-- Returns a future which reveals an entry in the cutiepedia. Takes in the entryId as a string.
pedia:setCutiepediaEntryRevealed("pedia_pooPatrol1Start")

-- Returns a future which hides an entry in the cutiepedia. Takes in the entryId as a string.
pedia:setCutiepediaEntryHidden("pedia_pooPatrol1Start")

-- Returns a future which reveals an entry in cutiepedia. Takes in the group as a string and the index as as int.
pedia:setCutiepediaEntryRevealed("sampleGroup", 5)

-- Returns a future which reveals all the entries in a cutiepedia group up to a certain index. Takes in the group as a string and the lastRevealIndex as as int.
pedia:setMultipleCutiepediaEntriesRevealed("sampleGroup", 7)

-- Returns a future which reveals the next entry in the group. Takes in the group as a string.
pedia:revealNextCutiepediaEntry("sampleGroup")

-- Returns a future which opens a specific cutiepedia page. Takes in a string, and optionally a boolean. If the optional boolean is true the script will wait until the player closes the notebook.
pedia:openCutiepediaPage(cutiepedia_page)

local waitForClose = true
pedia:openCutiepediaPage(cutiepedia_page, waitForClose)

Decorations API

The deco variable provides access to decorations.

-- Returns a boolean, true if the decoration is rendering on-screen
deco:isDecorationRendering("uniqueId")

-- Returns a future which disables the decoration specified by it's uniqueId. Takes in a string.
-- Note: Waits until the decoration is not on-screen
deco:disableDecoration("uniqueId")

-- Returns a future which enables the decoration specified by it's uniqueId. Takes in a string.
-- Note: Waits until the decoration is not on-screen
deco:enableDecoration("uniqueId")

-- Returns a future which disables the decoration specified by it's uniqueId. Takes in a string.
-- Note: Passing in true will disable the decoration even if it is on-screen
deco:disableDecoration("uniqueId", true)

-- Returns a future which enables the decoration specified by it's uniqueId. Takes in a string.
-- Note: Passing in true will enable the decoration even if it is on-screen
deco:enableDecoration("uniqueId", true)

Ghosts API

The ghosts variable provides functions to spawn Jelly ghosts. There is a default script which is invoked when a player dispels a ghost. A custom script can be invoked instead, and can be set using the script bindings below.

local mapX = 0
local mapY = 1
local tileX = 23
local tileY = 24

local name = "Billy"
local color = 1; -- or color = "White"
local shape = 1; -- or shape = "Ants"

local scriptPath = "dud/path/script.lua"

-- NOTE: all below bindings can take an int at the end to set the crystals that will be awarded when ghost will be dispelled

-- Returns a future to spawn a random ghost (color, shape, etc.) in a random ghost spawn area.
ghosts:spawnRandomGhostRandomLocation()

-- Returns a future to spawn a random ghost (color, shape, etc.) in a fixed location. Useful for quests etc, as the ghost will stay at the location specified.
ghosts:spawnRandomGhostFixedLocation(mapX, mapY, tileX, tileY)

-- Returns a future to spawn a random ghost (color, shape, etc.) at a waypoint. Useful for quests etc, as the ghost will stay at the location specified.
ghosts:spawnRandomGhostFixedLocation("waypoint")

-- Returns a future to spawn a defined ghost in a fixed location. Takes in both the ids or names for color and shape.
ghosts:spawnDefinedGhostFixedLocation("Ghost Name", mapX, mapY, tileX, tileY, color, shape)

-- Returns a future to spawn a defined ghost in a fixed location. Takes in both the ids or names for color and shape.
ghosts:spawnDefinedGhostFixedLocation("Ghost Name", "waypoint", color, shape)

-- Returns a future to spawn a random ghost (color, shape, etc.) in a random ghost spawn area, with a custom script that is invoked when the ghost is dispelled.
ghosts:spawnRandomGhostRandomLocationCustomScript(scriptPath)

-- Returns a future to spawn a random ghost (color, shape, etc.) in a fixed location. Useful for quests etc, as the ghost will stay at the location specified, with a custom script that is invoked when the ghost is dispelled.
ghosts:spawnRandomGhostFixedLocationCustomScript(mapX, mapY, tileX, tileY, scriptPath)

-- Returns a future to spawn a defined ghost in a fixed location. Takes in both the ids or names for color and shape, with a custom script that is invoked when the ghost is dispelled.
ghosts:spawnDefinedGhostFixedLocationCustomScript(name, mapX, mapY, tileX, tileY, color, shape, scriptPath)

-- Returns a future to spawn a random ghost (color, shape, etc.) at a waypoint. Useful for quests etc, as the ghost will stay at the location specified, with a custom script that is invoked when the ghost is dispelled.
ghosts:spawnRandomGhostFixedLocationCustomScript("waypoint", scriptPath)

-- Returns a future to spawn a defined ghost at a waypoint. Takes in both the ids or names for color and shape, with a custom script that is invoked when the ghost is dispelled.
ghosts:spawnDefinedGhostFixedLocationCustomScript("Ghost Name", "waypoint", color, shape, scriptPath)

Items API

The items variable provides access to Item data and allows for spawning of Items within the game world.

local mapX = 0
local mapY = 1
local tileX = 23
local tileY = 24

-- Gets an item by its name
local item = items:getItemByName("Grandma's Flute")

-- Returns a future to spawn an item by its name at a specified coordinate
items:spawnItem("abc123", mapX, mapY, tileX, tileY)

-- Triggers an item spawn event. All item spawn areas with the corresponding spawnEvent property will be activated.
items:eventItemSpawn("earthquake")

Item bindings

local item = items:getItemByName("Grandma's Flute")
local anotherItem = items:getItemByName("Grandma's Flute")

-- Returns a future to multiply all of an item's effects by a float value
item:multiplyEffectsBy(1.2):waitForCompletion()

-- Returns a future to swap the effects with another item
item:swapEffectsWith(anotherItem):waitForCompletion()

-- Returns a future to add a prefix to the item's name
item:prefixName("sample_")

-- Returns a future to add a suffix to the item's name
item:suffixName("_sample")

-- Returns a future to replace the prefix on an item's name
item:replaceNamePrefix(oldPrefix, "sample_")

-- Returns a future to replace the suffix on an item's name
item:replaceNameSuffix(oldSuffix, "_sample")

-- Returns if the item's internal name contains a string
item:internalNameContains("Flute")

-- Returns if the item's internal name starts with a string
item:internalNameStartsWith("Flute")

-- Returns if the item's internal name ends with a string
item:internalNameEndsWith("Flute")

-- Returns if the item's internal name equals a string
item:internalNameEquals("Grandma's Flute")

-- Returns the item's internal name
item:getInternalName()

-- Sets the item's internal name
item:getInternalName("newInternalName")

-- Returns if the item's name contains a string
item:nameContains("Flute")

-- Returns if the item's name starts with a string
item:nameStartsWith("Flute")

-- Returns if the item's name ends with a string
item:nameEndsWith("Flute")

-- Returns if the item's name equals a string
item:nameEquals("Grandma's Flute")

-- Returns the item's name
item:getName()

-- Sets the item's name
item:getName("newInternalName")

-- Returns the item's description
item:getDescription()

-- Sets the item's description
item:setDescription("This is the new item description.")

-- Returns the item's value
item:getValue()

-- Sets the item's value
item:setValue(100)

-- Returns the item's max quantity per slot
item:getMaxPerSlot()

-- Sets the item's max quantity per slot
item:setMaxPerSlot(16)

-- Returns the item's digestion duration
item:getDigestionDuration()

-- Sets the item's digestion duration
-- 1d = 1 day in minutes: 1 * 24 * 60
-- 1h = 1 hour in minutes: 1 * 60
-- 1m = 1 minute
-- 1 = 1 minute
item:setDigestionDuration("15m")

-- Returns the item's transition item name
item:getTransitionItemName()

-- Sets the item's transition item name
item:setTransitionItemName("Another item's name")

-- Returns the item's poop item name
item:getPoopItemName()

-- Sets the item's poop item name
item:setPoopItemName("Another item's name")

-- Returns the item's shop category
item:getShopCategory()

-- Sets the item's shop category
-- category must be one of "food", "potions", "equipment", "valuables"
item:setShopCategory("food")

-- Returns if the item is equal to another one
item:equals(anotherItem)

-- Returns a future to push the specified quantity of the item to lost & found
item:pushToLostAndFound(5)

-- Returns a future to push the item to lost & found. It's the same as item:pushToLostAndFound(1)
item:pushToLostAndFound()

-- Returns a future to reveal the item in codex
item:revealInCodex()

Jellies API

The jellies variable provides functions to spawn captured and wild jellies.

local mapX = 0
local mapY = 1
local tileX = 23
local tileY = 24
local location = "waypointName"
local color = 1; -- or color = "White"
local shape = 1; -- or shape = "Ants"

-- Returns a future to spawn a random captured jelly
local jellyFuture1 = jellies:spawnRandomCapturedJelly()
jellyFuture1:waitForCompletion()
local jelly1 = jellyFuture1:getJelly()

-- Returns a future to spawn a random wild jelly on a random tile on a specified map
jellies:spawnRandomWildJelly(mapX, mapY)
-- Example
local jellyFuture2 = jellies:spawnRandomWildJelly(32, 26)
jellyFuture2:waitForCompletion()
local jelly2 = jellyFuture2:getJelly()

-- Returns a future to spawn a random wild jelly on a specified tile on a specified map
jellies:spawnRandomWildJelly(mapX, mapY, tileX, tileY)
-- Example
local jellyFuture3 = jellies:spawnRandomWildJelly(32, 26, 0, 0)
jellyFuture3:waitForCompletion()
local jelly3 = jellyFuture3:getJelly()

-- Returns a future to spawn a random wild jelly on a specified waypoint location
local jellyFuture4 = jellies:spawnRandomWildJelly(location)
-- Example
local jellyFuture4 = jellies:spawnRandomWildJelly("waypointName")
jellyFuture4:waitForCompletion()
local jelly4 = jellyFuture4:getJelly()

-- Returns a future to spawn a jelly with the specified features on a specified tile on a specified map
-- Note: 'nature' can be entered as "" to spawn a jelly with a random nature.
-- 'traitsString' can be entered as "" to give no traits
-- You can get spawned jelly's id by calling :getJellyId()
jellies:spawnWildJelly(mapX, mapY, tileX, tileY, age, shape, color, nature, statsString, traitsString)
-- Example
local jellyFuture5 = jellies:spawnWildJelly(32, 26, 23, 20, 3, "purs", "cherry", 0, "", "1,1,1", "")
jellyFuture5::waitForCompletion()
local jelly5 = jellyFuture5:getJelly()

-- Returns a future to spawn a jelly with the specified features on a specified waypoint location
jellies:spawnWildJelly(location, age, shape, color, nature, statsString, traitsString)
-- Example
local jellyFuture6 = jellies:spawnWildJelly("waypointName", 3, "purs", "cherry", 0, "", "1,1,1", "")
jellyFuture6:waitForCompletion()
local jelly6 = jellyFuture6:getJelly()

-- Returns total number of captured eggs, jellies and relics
jellies:getTotalCaptured()

-- Returns total number of captured eggs
jellies:getTotalCapturedEggs()

-- Returns total number of captured jellies
jellies:getTotalCapturedJellies()

-- Returns total number of captured jellies that are currently on the farm
jellies:getTotalCapturedJelliesOnFarm()

-- Returns total number of captured relics
jellies:getTotalCapturedRelics()

-- Waits for a Jelly feed event
local feedEvent = jellies:waitForJellyFeedFuture()
feedEvent:waitForCompletion()

if feedEvent:isFeedSuccessful() then
    -- Do something when feeding Jelly was successful
else
    -- Do something when feeding Jelly failed
end

-- Returns the Jelly that was fed
local fedJelly = feedEvent:getFedJelly()

-- Returns a future that will wait for a Jelly charmed event
local jellyCharmedFuture = jellies:waitForJellyCharmedFuture()
jellyCharmedFuture:waitForCompletion()

-- Returns a future that will wait for a Jelly catch (balloon) event
local jellyCaughtFuture = jellies:waitForJellyCaughtFuture()
jellyCaughtFuture:waitForCompletion()

-- Returns a future that will wait for an Egg to be laid
local eggLaidFuture = jellies:waitForEggLaidFuture()
eggLaidFuture:waitForCompletion()

-- Returns a random color palette ID
local colorPaletteId = jellies:getRandomColorPaletteId()

-- Returns a random shape ID
local shapeId = jellies:getRandomShapeId()

-- Returns a random color palette (internal) name
local colorPaletteName = jellies:getRandomColorPaletteName()

-- Returns a random shape (internal) name
local shapeName = jellies:getRandomShapeName()

-- Returns a random jelly's Jelly Scripting Wrapper from the farm
jellies:getRandomFarmJelly()

-- Returns a future that moves a jelly to the center of the farm coop
jellies:transportJellyToFarm(jellyId)

-- Returns a future that moves a jelly to a random tile within the farm coop
jellies:transportJellyToRandomFarmPosition(jellyId)

-- Returns a future that moves all jellies within the jelly coop, with few tiles of padding, to a debug map.
-- Note: future stores a list of all moved jellies
jellies:moveFarmJelliesToDebugMap()

-- Returns a future that removes a jelly, captured or wild, of the given ID
jellies:removeJelly(jellyIdToRemove)

Jelly/Egg/Relic Bindings

Some functions in the API (such as jelly selection prompts) will return a binding to a Jelly, Egg or Relic.

See the Scripting Wrappers section for more information.

NPCs API

The npcs variable provides access to NPCs within the game world and a mechanism for spawning them.

-- Returns an NPC binding (see section below)
local npc = npcs:getByInternalName("Tim")

-- Returns a dialogue future for beginning a dialogue with npcs. Here rolf, desmond, and martha are defined by npcs:getByInternalName()
-- The player does not need to be included in the characters list
-- Note: scriptId is a special variable provided by the engine that must be passed to the function
local characters = {rolf, desmond, martha}
local dialogueFuture = npcs:beginChat(scriptId, characters)
dialogueFuture:waitForCompletion()
local chat = dialogueFuture:getDialogueContainer()

-- Returns a future that plays Vira's blast off animation from where Vira is standing.
-- Note: Vira has to be warped off screen so she is standing when the animation plays
local viraBlastOffFuture = npcs:playViraBlastOff()
vira:set("location_off_screen")
viraBlastOffFuture:waitForCompletion()

-- Returns a future that plays Vira's landing animation at the jail and enables the Roof_Hole decoration half way through the animation.
local viraLandingFuture = npcs:playViraLanding()
viraLandingFuture:waitForCompletion()

NPC Bindings

Each npc has the following scripting functions available.

local npc = npcs:getByInternalName("TIM")

local mapX = 0
local mapY = 1
local tileX = 23
local tileY = 24

-- Check if the npc is on a specific map
if npc:isOnMap(mapX, mapY) then
    -- DO SOMETHING HERE
end

-- Puts the NPC into cutscene mode so that it ignores its schedule behavior
npc:beginCutsceneMode()

-- Makes the NPC return to following its schedule
npc:endCutsceneMode()

-- Returns a future to start talking to the player based on the NPC's current dialogue script
-- Note: scriptId is a special variable provided by the engine that must be passed to the function
npc:beginChat(scriptId)

-- Returns a future to move the NPC to a specified waypoint - completes when the NPC reaches the coordinate
-- Note: use skipFuture() to immediately move the npc to the destination
npc:moveTo("waypoint-name")

-- Returns a future to move the NPC to a specified coordinate - completes when the NPC reaches the coordinate
-- Note: use skipFuture() to immediately move the npc to the destination
npc:moveTo(mapX, mapY, tileX, tileY)

-- Returns a future to set the NPC position immediately to a specified coordinate
npc:set(mapX, mapY, tileX, tileY)

-- Returns a future to set the NPC position immediately to a specified waypoint
npc:set("waypoint-name")

-- Returns a future that stores the NPC's current position in its scripting state
npc:storePosition()

-- Returns a future that sets the NPC's position from the previously stored position
npc:restorePosition()

-- Returns a future to set the NPC to face a specified direction (NORTH, SOUTH, EAST or WEST)
npc:faceDirection("NORTH")

-- Returns a future to set the NPC to face the direction of player
npc:faceDirectionOf(player)

-- Returns a future to set the NPC to face the direction of another NPC
local npc2 = npcs:getById("BOB")
npc:faceDirectionOf(npc2)

-- Returns a future to set the NPC to face the direction of a Jelly
local jelly = ...
npc:faceDirectionOf(jelly)

-- Returns a future that forces an NPC's direction until cleared
npc:overrideDirection("NORTH")

-- Returns a future that clears an NPC's override direction
npc:clearOverrideDirection()

-- Returns a future that plays the fall over animation (non-looped) until stopped
npc:playFallOverAnimation()

-- Returns a future that stops the fall over animation state
npc:stopFallOverAnimation()

-- Returns true if the NPC is behind the player (and player is looking opposite direction)
if npc:isBehind(player) then
    -- DO SOMETHING HERE
end

-- Returns true if the NPC is behind another NPC (and NPC is looking opposite direction)
local npc2 = npcs:getById("BOB")
if npc:isBehind(npc2) then
    -- DO SOMETHING HERE
end

-- Returns a future to have the NPC drop an item in the direction they are facing. Takes in the internal name of the item and a interger value for the quantity.
npc:dropItem("Meal Greens", 1)

-- Returns a future to have the NPC drop an item in a specified direction. Takes in the internal name of the item, an interger value for the quantity, and a string for the direction.
npc:dropItem("Meal Greens", 1, "south")

-- Returns a future that shows an emote above the NPC's head. The emote will stay until cleared.
-- Can be: VERY_HAPPY,        HAPPY, OK, SAD, VERY_SAD, ANGRY, SICK, HEART, BROKEN_HEART, DEATH, CONFUSED, EXCLAMATION_MARK, DOTS, QUESTION_MARK, SLEEPING, BLUE_FLAG,
-- RED_FLAG, GREEN_FLAG, YELLOW_FLAG, SMALL_NOTE_BLACK, SMALL_NOTE_COLOR, LARGE_NOTE, LARGE_DOUBLE, LARGE_NONE, SMALL_RELIC, LARGE_RELIC or STOMACH
npc:showEmote("EXCLAMATION_MARK")

-- Returns a future that shows an emote above the NPC's head for a specified amount of time, clamped to 10000 seconds.
-- Can be: VERY_HAPPY,        HAPPY, OK, SAD, VERY_SAD, ANGRY, SICK, HEART, BROKEN_HEART, DEATH, CONFUSED, EXCLAMATION_MARK, DOTS, QUESTION_MARK, SLEEPING, BLUE_FLAG,
-- RED_FLAG, GREEN_FLAG, YELLOW_FLAG, SMALL_NOTE_BLACK, SMALL_NOTE_COLOR, LARGE_NOTE, LARGE_DOUBLE, LARGE_NONE, SMALL_RELIC, LARGE_RELIC or STOMACH
-- Note: Emote will end rather than instantly disappear when display time is over. Can be overwritten with npc:clearEmote(true)
npc:showEmote("EXCLAMATION_MARK", 5)

-- Returns a future that removes the emote from above the NPC's head over time
npc:clearEmote()

-- Returns a future that removes the emote from above the NPC's head immediately
npc:clearEmote(true)

-- NPCs can store numeric values which are persisted between cutscenes/game sessions/etc.
npc:hasCounter("counterName")
npc:setCounter("counterName", 1)
npc:incrementCounter("counterName")
npc:incrementCounter("counterName", amount)
npc:decrementCounter("counterName")
npc:decrementCounter("counterName", amount)
local counterValue = npc:getCounter("counterName")
npc:resetAllCounters()

-- NPCs can store flags which are persisted between cutscenes/game sessions/etc.
npc:setFlag("flagName")
if npc:isFlagSet("flagName") then
    -- DO SOMETHING HERE
end

npc:unsetFlag("flagName")
if npc:isFlagUnset("flagName") then
    -- DO SOMETHING HERE
end

npc:unsetAllFlags()

-- NPCs have a special flag for if they have met the player or not. Returns true if the player has met the NPC
npc:hasMetPlayer()

-- NPCs can be shops
if npc:hasShop() then
    -- DO SOMETHING HERE
end

-- Returns the NPC internal name
local internalName = npc:getInternalName()

-- Returns the NPC's localised name
local name = npc:getName()

-- Returns a future to destroy and remove the NPC from the game world
npc:destroy()

Player API

The player variable provides access to individual player within the game world.

For convenience, the yvette variable also exists as an alias to player.

local mapX = 0
local mapY = 1
local tileX = 23
local tileY = 24

-- Check if the player is on a specific map
if player:isOnMap(mapX, mapY) then
    -- DO SOMETHING HERE
end

-- Returns a future to move the player to a specified coordinate - completes when the player reaches the coordinate
-- Note: use skipFuture() to immediately move the player to the destination
player:moveTo(mapX, mapY, tileX, tileY)

-- Returns a future to move the player to a specified waypoint - completes when the player reaches the coordinate
-- Note: use skipFuture() to immediately move the player to the destination
player:moveTo("waypoint-name")

-- Returns a future to set the player position immediately to a specified coordinate
player:set(mapX, mapY, tileX, tileY)

-- Returns a future to set the player position immediately to a specified waypoint
player:set("waypoint-name")

-- Returns a future to set the player to face a specified direction (NORTH, SOUTH, EAST or WEST)
player:faceDirection("NORTH")

-- Returns a future to set the player to face the direction of an NPC
local npc = npcs:getById("BOB")
player:faceDirectionOf(npc2)

-- Returns a future to set the player to face the direction of a Jelly
local jelly = ...
player:faceDirectionOf(jelly)

-- Returns a future that forces the player's direction until cleared
player:overrideDirection("NORTH")

-- Returns a future that clears the player's override direction
player:clearOverrideDirection()

-- Returns a future that plays the fall over animation (non-looped) until stopped
player:playFallOverAnimation()

-- Returns a future that stops the fall over animation state
player:stopFallOverAnimation()

-- Returns true if the player is behind an NPC (and NPC is looking opposite direction)
local npc = npcs:getById("BOB")
if player:isBehind(npc) then
    -- DO SOMETHING HERE
end

-- Returns a future that shows an emote above the player's head. The emote will stay until cleared.
-- Can be: VERY_HAPPY,        HAPPY, OK, SAD, VERY_SAD, ANGRY, SICK, HEART, BROKEN_HEART, DEATH, CONFUSED, EXCLAMATION_MARK, DOTS, QUESTION_MARK, SLEEPING, BLUE_FLAG,
-- RED_FLAG, GREEN_FLAG, YELLOW_FLAG, SMALL_NOTE_BLACK, SMALL_NOTE_COLOR, LARGE_NOTE, LARGE_DOUBLE, LARGE_NONE, SMALL_RELIC, LARGE_RELIC or STOMACH
player:showEmote("EXCLAMATION_MARK")

-- Returns a future that shows an emote above the player's head for a specified amount of time, clamped to 10000 seconds.
-- Can be: VERY_HAPPY,        HAPPY, OK, SAD, VERY_SAD, ANGRY, SICK, HEART, BROKEN_HEART, DEATH, CONFUSED, EXCLAMATION_MARK, DOTS, QUESTION_MARK, SLEEPING, BLUE_FLAG,
-- RED_FLAG, GREEN_FLAG, YELLOW_FLAG, SMALL_NOTE_BLACK, SMALL_NOTE_COLOR, LARGE_NOTE, LARGE_DOUBLE, LARGE_NONE, SMALL_RELIC, LARGE_RELIC or STOMACH
-- Note: Emote will end rather than instantly disappear when display time is over. Can be overwritten with player:clearEmote(true)
player:showEmote("EXCLAMATION_MARK", 5)

-- Returns a future that removes the emote from above the player's head over time
player:clearEmote()

-- Returns a future that removes the emote from above the player's head immediately
player:clearEmote(true)

-- Returns a future that disables the player's movement buttons
player:disableMovement()

-- Returns a future that enables the player's movement buttons
player:enableMovement()

-- Returns a future that disables the players bed.
player:disableBed()

-- Returns a future that enables the players bed.
player:enableBed()

-- Returns a future that disables the player's flute button
player:disableFlute()

-- Returns a future that enables the player's flute button
player:enableFlute()

-- Returns a future that disables the player's interact button
player:disableInteraction()

-- Returns a future that enables the player's interact button
player:enableInteraction()

-- Returns a boolean if player's interaction is enabled/disabled
player:isInteractionEnabled()

-- Returns a future that disables fast travel
player:disableFastTravel()

-- Returns a future that enables fast travel
player:enableFastTravel()

-- Returns a boolean if fast travel is enabled/disabled
player:isFastTravelEnabled()

-- Returns a future that disables the player's pickup button for jellies, eggs and relics
player:disableEntityPickup()

-- Returns a future that enables the player's pickup button for jellies, eggs and relics
player:enableEntityPickup()

-- Returns a future that disables the player's movement, flute, interact, and pickup buttons.
player:disableInput()

-- Returns a future that enables the player's movement, flute, interact, and pickup buttons.
player:enableInput()

-- Returns a future that disables the pause menu.
player:disablePauseMenu()

-- Returns a future that enables the pause menu.
player:enablePauseMenu()

-- Returns a future to wait for a specified duration
player:wait(1.0)

-- Check if the player has a specific item (by the item internal name) in their bag
-- NOTE: if specified item is a HUD item, items in the HUD area will be checked instead
if player:hasItemInBag("Grandma's Flute") then
    -- DO SOMETHING HERE
end

-- Check if the player has an empty slot in their bag
if player:hasEmptySlotInBag() then
    -- DO SOMETHING HERE
end

-- Returns the total amount of a specified item (by internal name) in the player's bag
local totalFlutesInBag = player:getTotalItems("Grandma's Flute")

-- Returns a future that restricts the players movement to inside the specified area.
-- Takes in integer values for minMapX, minMapY, minTileX, minTileY, maxMapX, maxMapY, maxTileX, maxTileY.
player:restrictMovement(29, 28, 10, 10, 30, 28, 30, 70)

-- Returns a future that restricts the players movement to inside the farm area
player:restrictMovementToFarm()

-- Returns a future the unrestricts the players movement.
player:unrestrictMovement()

-- Returns a future for giving a quantity of a specific item (by internal name) to the player
-- If the player doesn't have enough space in their bag, the items will be dropped near the player
-- NOTE: Items configured as HUD items will immediately appear in the top left (regardless of bag space) and trigger/queue
-- a script, if they were configured to have one.
-- Quantity is set to no exceed 999
player:receiveItem("Grandma's Flute", 1)

-- Returns a future for dropping an item (by internal name) from the player's bag into the overworld (drops 1)
player:dropItemFromBag("Grandma's Flute")

-- Returns a future for dropping a specified quantity of an item (by internal name) from the player's bag into the overworld
player:dropItemFromBag("Grandma's Flute", 7)

-- Returns a future for deleting an item (by internal name) from the player's bag (deletes 1)
-- NOTE: If specified item is configured as a HUD item, it will be removed from the HUD
player:destroyItemFromBag("Grandma's Flute")

-- Returns a future for deleting a specified quantity of an item (by internal name) from the player's bag
-- NOTE: If specified item is configured as a HUD item, it will be removed from the HUD, quantity will have no effect
player:destroyItemFromBag("Grandma's Flute", 7)

-- Returns a future that adds a specific number of crystals to the player
player:addCrystals(150)

-- Returns a future that removes a specific number of crystals from the player
player:removeCrystals(300)

-- Returns a future that sets a specific number of crystals on the player
player:setCrystals(1337)

-- Returns the current number of crystals from the player
player:getCrystals()

-- Returns a future that adds a specific number of alchemy charges to the player
player:addFluteCharges(3)

-- Returns a future that sets the number of alchemy charges to the max
player:fillFluteCharges()

-- Returns a future that adds an unfinished alchemy charge to the bar. Takes in a string, ideally the shrine group key for the associated shrine.
player:addUnfinishedCharge(shrineGroupKey)

-- Returns a future that increases an unfinished alchemy charge by a given amount. Takes in a string key, and a float amount. If the value is then greater or equal to 1, the charge will complete and become a full alchemy charge.
player:increaseUnfinishedCharge(shrineGroupKey, 0.4f)

-- Returns a future that limits player's speed to npc's speed.
player:beginCutsceneMode()

-- Returns a future that unlimits player's speed.
player:endCutsceneMode()

-- Player can store numeric values which are persisted between cutscenes/game sessions/etc.
player:hasCounter("counterName")
player:setCounter("counterName", 1)
player:incrementCounter("counterName")
player:decrementCounter("counterName")
local counterValue = player:getCounter("counterName")
player:resetAllCounters()

-- Player can store flags which are persisted between cutscenes/game sessions/etc.
player:setFlag("flagName")
if player:isFlagSet("flagName") then
    -- DO SOMETHING HERE
end

player:unsetFlag("flagName")
if player:isFlagUnset("flagName") then
    -- DO SOMETHING HERE
end

player:unsetAllFlags()

-- Check if the player has a hud item. Returns true if the player currently has the hud item.
player:hasHudItem(itemName)

-- Returns a future to remove a hud item from the player
player:removeHudItem(itemName)

-- Returns a future that waits for the player to drop an item.
-- future:getItem() to get the item dropped.
-- future:getItemKey() returns the item key string
-- future:getItemAmount()
local future = player:waitForItemDropFuture()
future:waitForCompletion()
local item = future:getItem()

-- Returns a future that waits for a player to pick up an item. Can take a itemKey to match against.
-- future:isMatchesRequired() returns true if optionalItemKey is null or if it matches the item key picked by player
local future = player:waitForItemPickUpFuture(optionalItemKey)
future:waitForCompletion()
future:isMatchesRequired()


-- Get the player's coordinates
local playerMapX = player:getMapX()
local playerMapY = player:getMapY()
local playerTileX = player:getTileX()
local playerTileY = player:getTileY()

-- Check if the player has a Jelly in their backpack pouch and get a variable representing the Jelly
if player:isJellyInBackpack() then
    local jelly = player:getJellyInBackpack()
    -- DO SOMETHING HERE
end

-- Check if the player has an Egg in their backpack pouch and get a variable representing the Egg
if player:isEggInBackpack() then
    local egg = player:getEggInBackpack()
    -- DO SOMETHING HERE
end

-- Check if the player has a Relic in their backpack pouch and get a variable representing the Relic
if player:isRelicInBackpack() then
    local relic = player:getRelicInBackpack()
    -- DO SOMETHING HERE
end

-- Check if the player has a Jelly in their hands and get a variable representing the Jelly
if player:isCarryingJelly() then
    local jelly = player:getCarriedJelly()
    -- DO SOMETHING HERE
end

-- Check if the player has an Egg in their hands and get a variable representing the Egg
if player:isCarryingEgg() then
    local egg = player:getCarriedEgg()
    -- DO SOMETHING HERE
end

-- Check if the player has a Relic in their hands and get a variable representing the Relic
if player:isCarryingRelic() then
    local relic = player:getCarriedRelic()
    -- DO SOMETHING HERE
end

-- Player will drop held entity if holding one
player:dropCarriedEntity()

-- Returns a future that waits for an item transmutation.
local transmute = player:waitForItemTransmuteFuture()
transmute:waitForCompletion()

-- Returns a future that waits for transmutation effect on a specific item.
local transmute = player:waitForSpecificItemTransmuteFuture("Aqua Flower")
transmute:waitForCompletion()

-- isTransmuteSuccessful() returns a boolean value.
transmute:isTransmuteSuccessful()

-- getReason() can be called to return an integer value that represents the failure reason.
-- -1 by default, 0 for not enough energy, 1 for no transmute outcome for that item.
local failureReason = transmute:getReason()

-- Returns the amount of crystals rewards for completing the regular items of a weekly delivery
-- Year >= 0, Season 0 - 3 (or SPRING, SUMMER, AUTUMN, WINTER), Week 0 - 3
-- Note: Does not give the crystals to the player
player:getRegularRewardCrystals(1, 0, 3)
player:getRegularRewardCrystals(1, "WINTER", 3)

-- Returns the amount of crystals rewards for completing the star items of a weekly delivery
-- Year >= 0, Season 0 - 3 (or SPRING, SUMMER, AUTUMN, WINTER), Week 0 - 3
-- Note: Does not give the crystals to the player
player:getStarRewardCrystals(1, 0, 3)
player:getStarRewardCrystals(1, "WINTER", 3)

-- Returns true if the player can receive all reward items to their bag
-- Year >= 0, Season 0 - 3 (or SPRING, SUMMER, AUTUMN, WINTER), Week 0 - 3
local completedRegularItems = true
local completedStarItems = true
if player:canAcceptDeliveryRewardToBag(1, 0, 3, completedRegularItems, completedStarItems) then
    -- Do something
end
if player:canAcceptDeliveryRewardToBag(1, "WINTER", 3, completedRegularItems, completedStarItems) then
    -- Do something
end

-- Returns true if the player can receive all reward items to the farm storage
-- Year >= 0, Season 0 - 3 (or SPRING, SUMMER, AUTUMN, WINTER), Week 0 - 3
local completedRegularItems = true
local completedStarItems = true
if player:canAcceptDeliveryRewardToStorage(1, 0, 3, completedRegularItems, completedStarItems) then
    -- Do something
end
if player:canAcceptDeliveryRewardToStorage(1, "WINTER", 3, completedRegularItems, completedStarItems) then
    -- Do something
end

-- Returns a future to receive the regular reward for a weekly item delivery
-- Year >= 0, Season 0 - 3 (or SPRING, SUMMER, AUTUMN, WINTER), Week 0 - 3
player:receiveWeeklyItemDeliveryReward(1, 0, 3)
player:receiveWeeklyItemDeliveryReward(1, "WINTER", 3)

-- Returns a future to receive the star reward for a weekly item delivery
-- Year >= 0, Season 0 - 3 (or SPRING, SUMMER, AUTUMN, WINTER), Week 0 - 3
player:receiveWeeklyItemDeliveryStarReward(1, 0, 2)
player:receiveWeeklyItemDeliveryStarReward(1, "WINTER", 3)

-- Returns a future to increase Farm Jelly Limit by a specific amount
-- Note: Cannot go above MAX_FARM_LIMIT(16)
player:increaseFarmLimit(5)

-- Returns a future to decrease Farm Jelly Limit by a specific amount
-- Note: Cannot go below 0
player:decreaseFarmLimit(4)

-- Returns a future to increase Farm Jelly Limit for opening a temple
-- Note: Cannot go above MAX_FARM_LIMIT(16)
player:templeIncreaseFarmLimit()

-- Returns the current Farm Jelly Limit
player:getFarmLimit()

-- Returns a future to set the current Farm Jelly Limit
-- Note: Cannot go above MAX_FARM_LIMIT(16)
player:setFarmLimit(10)

-- Returns a future that enables the gold flute
-- Note: can be disabled by passing in false
player:unlockGoldFlute(true)

-- Returns a future that sets the player's layer position
-- Layer position can be "ABOVE_BRIDGE", "BELOW_BRIDGE" or "NONE"
-- Note that this will also set carried entity layer position
player:setLayerPosition("ABOVE_BRIDGE")

-- Sends NO_INTERACTABLE_COLLISION message that will clear player input context and set it to the overworld one and
-- finally clear the quick info panel
-- Note: should be called after forcing player to drop an entity
player:clearPlayerInteraction()

-- Set/unset a flag on the player that enables/disables releasing jellies
player:setJellyReleaseDisabled(true)

-- Checks if repeat quest timer is set, and if, checks if it is a new day and returns true if quest
player:isDailySideQuestAvailable()

-- Sets the repeat quest timer to current day
player:setDailySideQuestAvailable()

-- Sets a flag on the player that prevents saving during the tutorial
player:disableSavingForTutorial()

-- Unsets a flag on the player that prevents saving during the tutorial
player:enableSavingAfterTutorial()

-- Sets/unsets flag on the player the indicates the player has created a relic for the first time
player:setCreatedFirstRelicFlag(true)

-- Returns true/false if flag on the player that indicates the player has created a relic for the first time is set/unset
player:hasCreatedFirstRelic()

-- Sets/unsets flag on the player to disable playing of leaving restricted area script
player:setNoLeavingAreaScriptFlag(true)

-- Returns true/false if flag on the player is set to enable/disable playing of leaving restricted area script
player:hasNoLeavingAreaScriptFlag()

Quests API

The quests variable provides access to quest status.

-- Returns a future that activates a quest objective (and in turn the quest if not already active)
quests:activateQuestObjective("QUEST KEY", "OBJECTIVE KEY")

-- Returns a future that skips a quest objective (and in turn the quest if not already active)
quests:skipQuestObjective("QUEST KEY", "OBJECTIVE KEY")

-- Returns a future that completes a quest objective (pass true if successfully completed, false is failed)
quests:completeQuestObjective("QUEST KEY", "OBJECTIVE KEY", true)

-- Checks if a quest is activated (any objective is activated or completed)
if quests:isQuestActivated("QUEST KEY") then
    -- DO SOMETHING HERE
end

-- Checks if a quest is completed (all objectives completed successfully or unsuccessfully)
if quests:isQuestComplete("QUEST KEY") then
    -- DO SOMETHING HERE
end

-- Checks if a quest objective is activated
if quests:isQuestObjectiveActivated("QUEST KEY", "OBJECTIVE KEY") then
    -- DO SOMETHING HERE
end

-- Checks if a quest objective is activated or completed (success, fail, skip)
if quests:isQuestObjectiveActivatedOrCompleted("QUEST KEY", "OBJECTIVE KEY") then
        -- DO SOMETHING HERE
end

-- Checks if a quest objective is completed (success or failure)
if quests:isQuestObjectiveComplete("QUEST KEY", "OBJECTIVE KEY") then
    -- DO SOMETHING HERE
end

-- Checks if a quest objective is completed successfully
if quests:isQuestObjectiveSuccess("QUEST KEY", "OBJECTIVE KEY") then
    -- DO SOMETHING HERE
end

-- Checks if a quest objective is completed unsuccessfully
if quests:isQuestObjectiveFailed("QUEST KEY", "OBJECTIVE KEY") then
    -- DO SOMETHING HERE
end

-- Checks if a quest objective is skipped
if quests:isQuestObjectiveSkipped("QUEST KEY", "OBJECTIVE KEY") then
    -- DO SOMETHING HERE
end

Shops API

The shops variable is used for registering shop data.

local shopFile = "internal://shops/fergus.xml"

-- Returns a future for registering shop data
shops:registerShop(shopFile)

-- Shops can then be applied to NPCs
local skeezer = npcs:getByUuid("SKEEZER")
skeezer:applyShop(shopFile):waitForCompletion()

Shrines API

The shrines variable provides access to the Shrine Groups and Temple Doors within the game world.

-- Returns the shrine group binding the player has last interacted with (see section below)
local shrineGroup = shrines:getLatestCompleteGroup()

-- Returns the temple door binding of the shrine group that the player last interacted with (see section below).
local templeDoor = shrines:getTempleDoor()

-- Returns the specified temple door binding, takes in a String of the temple door Uuid
local templeDoor = shrines:getTempleDoor(templeDoorUuid)

-- Returns a future for placing the relic the player is carrying onto the latest shrine the player has interacted with.
shrines:placeRelicOnShrine()

-- Activates all disabled shrines.
shrines:activateAllShrines()

-- Deactivates all shrines (sets to a disabled state) as long as they are not/have not despawned.
shrines:deactivateAllShrines()

-- Activates all disabled shrines in a specific shrine group. Takes in a string for the shrineGroupId or a shrine group scripting wrapper.
shrines:activateShrinesInGroup("plainsHideIsland")

-- Deactivates all shrines (sets to a disabled state) in a specific shrine group. Takes in a string for the shrineGroupId or a shrine group scripting wrapper.
shrines:deactivateAllShrinesInGroup("plainsHideIsland")

Shrine Group Bindings

Each shrine group has the following scripting functions available.

local shrineGroup = shrines:getLatestCompleteGroup()

-- Returns a string of the cameraTargetWaypoint for this shrine group.
local waypointOne = shrineGroup:getFirstWaypointString()

-- Returns a string of the templeTargetWaypoint for this shrine group.
local waypointTwo = shrineGroup:getSecondWaypointString()

-- Retuns a boolean, true if the shrine group is complete, false otherwise.
local isComplete = shrineGroup:isShrineProgressionComplete()

-- Returns a future that causes the latest interacted with shrine to animate, when the relic is placed on it.
shrineGroup:setShrineToShine()

-- Returns a future that runs until the latest interacted with shrine is removed.
-- NOTE: Will return immediate future if shrine/shortcut is NOT completed.
shrineGroup:setShrineToShine():waitForCompletion()

-- Returns a future that causes the first temple linked shrine light to turn on
shrineGroup:turnOnFirstShrineLight()

-- Returns a future that causes the second temple linked shrine light to turn on
shrineGroup:turnOnSecondShrineLight()

-- Returns a future that causes the next progression shrine light to turn on
shrineGroup:turnOnNextProgressLight()

-- Returns an int of the total number of shrines completed.
shrineGroup:getTotalCompletedShrines()

-- Returns an int of the temple shrines completed.
shrineGroup:getTempleCompletedShrines()

-- Returns an int of the shortcut shrines completed.
shrineGroup:getCutCompletedShrines()

-- Returns the shrine group id as a String.
shrineGroup:getGroupId()

Temple Door Bindings

Each temple door has the following scripting functions available.

local templeDoor = shrines:getTempleDoor()

-- Returns a boolean. Decrements the counter of remaining groups and returns true if the remaining is 0.
local lastGroup = templeDoor:isLastGroup()

-- Returns a future that reveals the text on the temple door once all shrine groups are complete. This will make the door interactable to the player.
templeDoor:revealText()

-- Returns a future that opens the temple door and makes it passable to the player
templeDoor:openTempleDoor()

Utils API

The utils variable provides access to various utility functions.

-- Tries to track a specified quest if such quest has been started or is not hidden.
-- Takes in a quest key and a boolean whether the map should be immediately opened.
utils:trackQuest("qkey_familyBusiness", false):waitForCompletion()

-- Temporarily disables quest notifications from being queued, updated and rendered
-- Takes in a boolean to enable/disable quest notifications. true = disable
utils:disableQuestNotifications(true):wfc()

-- Chooses a random dialogue string
local dialogue = utils:randomDialogue({"Dialogue 1", "Dialogue 2"})

-- Chooses randomly true or false
if utils:randomBool() then
    -- DO SOMETHING HERE
end

-- Chooses randomly true or false with a 1 in N chance of true
if utils:randomBool(7) then
    -- DO SOMETHING HERE
end

-- Chooses a random number between min and max values (inclusive)
local num = utils:randomInt(5, 10)

-- Sets the script to invoke when a new game starts. This should be used in init.lua which runs before the loading screen ends.
utils:setNewGameScript("scripts/event/intro.lua"):waitForCompletion()

-- Returns a future to shows a key press tutorial message
-- If a tutorial message is already showing, this will overwrite it
-- Key must be "A", "B", "X", "Y", "SELECT", "PAUSE", "LEFT_SHOULDER", "RIGHT_SHOULDER", "LEFT_TRIGGER", "RIGHT_TRIGGER"
-- The key will be adjusted depending on current input method (keyboard, xbox controller, etc.)
utils:showTutorialMessage("LEFT_TRIGGER", "Flute"):waitForCompletion()

-- Returns a future to show Feed tutorial message. Will show mouse icon on PC if keyboard is used.
utils:showFeedTutorialMessage("Feed Jelly"):waitForCompletion()

-- Returns a future to show finger pointers pointing at the item in hotbar and jelly quick info
utils:showFluteTutorial()

-- Returns a future to hide finger pointers pointing at the item in hotbar and jelly quick info
utils:hideFluteTutorial()

-- Returns a future to show finger pointer pointing at the flute energy notes
utils:showEnergyArrowTutorialMessage()

-- Returns a future to hide finger pointer pointing at the flute energy notes
utils:hideEnergyArrowTutorialMessage()

-- Returns a future where flute charge note animation can be forced. Needs to be manually disabled. Handles quitting to main menu
utils:forceFluteNotesAnimation(true)

-- Returns a future to hide the tutorial message
utils:hideTutorialMessage():waitForCompletion()

-- Returns a future to hide the HUD immediately
utils:hideHud(true)

-- Returns a future to slide out the HUD
utils:hideHud(false)

-- Returns a future to show the HUD immediately
utils:showHud(true)

-- Returns a future to slide in the HUD
utils:showHud(false)

-- Returns a future to immediately show the Quick Info Panel. Quick info is not part of the common HUD and can be shown separately
-- Note: Quick info will NOT be forced to stay visible if outside of the farm
utils:showQuickInfo(true)

-- Returns a future to slide in the Quick Info Panel. Quick info is not part of the common HUD and can be shown separately
-- Note: Quick info will NOT be forced to stay visible if outside of the farm
utils:showQuickInfo(false)

-- Returns a future to disable Jelly singing (usually for tutorial purposes)
utils:disableJellySinging()

-- Returns a future to enable Jelly singing (usually for tutorial purposes)
utils:enableJellySinging()

-- Returns a future that starts a rumble sequence
-- Calling waitForCompletion() will wait until the full rumble sequence completes
-- Note: This will overwrite any currently running rumble
local rumbleStength = {0.5, 0.0, 1.0, 0.0, 1.0}
local rumbleDurationSeconds = {1, 1, 2, 1, 1}
utils:startRumble(rumbleStength, rumbleDurationSeconds)

-- Returns a future that stops any running rumble
utils:stopRumble()

-- Returns true if saving is enabled so the state can be restored
utils:isSavingEnabled()

-- Returns a future that disables save buttons
utils:disableSaving()

-- Returns a future that enables save buttons
utils:enableSaving()

-- Returns a future that disables incrementing of the jelly relic meter
utils:disableRelicMeter()

-- Returns a future that enables incrementing of the jelly relic meter
utils:enableRelicMeter()

-- Returns a future that disables farm limit removing jellies at midnight
utils:disableFarmLimit()

-- Returns a future that enables farm limit removing jellies at midnight
utils:enableFarmLimit()

-- Returns a future that transitions to season summary screen. Fades out and in
-- Note: using waitForCompletion() will wait until the summary screen is closed
utils:showSeasonSummary()

-- Prints the content of a variable to command line
utils:trace(var)

-- Prints the string to command line
utils:trace("Debug trace info")

-- Returns true if a world-level flag is set
utils:isFlagSet("flagName")

-- Returns true if a world-level flag is unset
utils:isFlagUnset("flagName")

-- Returns a future that sets a world-level flag
utils:setFlag("flagName")

-- Returns a future that unsets a world-level flag
utils:unsetFlag("flagName")

-- List of game stats tracked by the game
"temples_completed"
"shrines_completed"
"shortcuts_activated"
"items_harvested"
"codex_entries_revealed"
"hidden_items_found"
"soulstones_found"
"crystal_tablets_found"
"ghost_dispelled"
"stories_finished"
"alchemy_used"
"combos_completed"
"highest_combo_achieved"
"energy_used"
"highest_vogue_medal"
"highest_buffet_medal"
"highest_splash_medal"
"highest_sumo_medal"
"crystals_earned"
"crystals_spent"
"total_profit"
"highest_profit"
"items_sold"
"items_bought"
"shipments_done"
"star_shipments_done"
"jellies_delivered"
"deliveries_completed"
"jellies_caught"
"eggs_hatched"
"relics_created"
"average_age"
"levels_gained"
"avg_total_level"
"items_digested"
"smelly_beans_pooped"
"highest_medal"

-- Returns the int value of a world-level stat (0 by default)
utils:getStat("statName")

-- Returns a future that sets a world-level stat to a value
utils:setStat("statName", 0)

-- Returns a future that increments a world-level stat by 1
-- Note: If stat doesn't exist, it will add it and set it to 1
utils:incrementStat("statName")

-- Returns a future that increments a world-level stat by an amount
-- Note: If stat doesn't exist, it will add it and set it to the amount
utils:incrementStat("statName", 5)

-- Note: A prefix can be passed in to get/set/increment specific stat
-- Some stats track TOTAL, CURRENT and PREVIOUS
-- TOTAL tracks stats for the entire play through
-- CURRENT tracks stats for current season
-- PREVIOUS tracks stats for previous season

-- Returns the int value of a world-level stat for a specific time (0 by default)
utils:getStat("total", "statName")

-- Returns a future that sets a world-level stat to a value
utils:setStat("statName", 0)

-- Returns a future that increments a world-level stat by 1
-- Note: If stat doesn't exist, it will add it and set it to the amount
utils:incrementStat("total", "statName")

-- Returns a future that increments a world-level stat by an amount
-- Note: If stat doesn't exist, it will add it and set it to the amount
utils:incrementStat("total", "statName", 5)

-- Returns the string value of a world-level key/value pair (0 by default)
utils:getValue("key")

-- Returns a future that sets a world-level key/value pair
utils:setValue("key", "value")

-- Returns a future that displays a visual effect at the specified location. Takes in a string for the visual effect.
utils:displayVisualEffect("SMOKE_BIG", mapX, mapY, tileX, tileY)
utils:displayVisualEffect("SMOKE_BIG", mapX, mapY, tileX, tileY, colorId)
utils:displayVisualEffect("SMOKE_BIG", worldX, worldY, colorId)

-- List of Visual Effects that can be shown through scripts
"FIREWORK"
"GLITTER"
"SMOKE_BIG"
"SMOKE_SMALL"
"SMOKE_POOF"
"DIAMOND_BURST"
"DOOR_BURST"
"CHARGE_UP"
"SHORTCUT_POOF"
"ALERT_BAD"
"ALERT_GOOD"
"GHOST_A"
"GHOST_B"
"GHOST_C"
"STINKER_POOF"

-- Returns a future that converts a Jelly to a code, opens the Jelly code window and completes when the player has closed the window
-- Note: Jelly will be deleted after Window closes
local jelly = player:getJellyInBackpack()
utils:registerAndDisplayJellyCode(jelly)

-- Returns a future that opens the Jelly code window and completes when the player has input a code
local prompt = utils:promptForJellyCode()
prompt:waitForCompletion()
if prompt:isValidCode() then
    -- Player entered valid jelly code
    if prompt:isPreviouslyReceived() then
        -- Player already used this code
        prompt:discardJelly():waitForCompletion()
    elseif prompt:isPreviouslySent() then
        -- Player sent this Jelly so can't get it back
        prompt:discardJelly():waitForCompletion()
    else
        if player:isJellyInBackpack() then
            -- Spawn the jelly on the farm
            prompt:spawnJellyOnFarm():waitForCompletion()
        else
            -- Spawn the jelly in the backpack
            prompt:spawnJellyInBackpack():waitForCompletion()
        end
    end
else
    -- Player entered invalid jelly code
    chat:say(player, "Invalid code"):waitForCompletion()
    prompt:discardJelly():waitForCompletion()
end

-- Pauses the script for a specified amount of milliseconds
utils:sleep(1000)

-- Pauses the script for one game frame
utils:sleepOneFrame()

-- Locks a lock by the given name. Used for mutual exclusion in scripts.
utils:lock("lockId")

-- Unlocks a lock
utils:unlock("lockId")

Script Wrappers

The following methods are available when working with variables that represent one of the sections listed below. For example player:getEggInBackpack, will return a variable which has access to the methods outlined in the Common and Egg sections below.

Common

The following methods are available to all Jellies, Eggs, Relics, and Ghosts. Note: Not all effects work on Wild Jellies. Those that do have a note.

-- Returns a future to apply an Age Effect. Takes in an int for the modifier, and a boolean for if the change is relative.
-- Note: works on Wild Jellies
common:applyAgeEffect(valueModifier, relative)

-- Returns a future to apply a Dim Effect.
-- Note: works on Wild Jellies
common:applyDimEffect()

-- Returns a future to apply a Dye Effect. Takes in a string for the colour pallet name.
common:applyDyeEffect(colorPaletteName)

-- Returns a future to apply a Dye Effect. Takes in an int for the colour pallet id.
common:applyDyeEffect(colorPaletteId)

-- Returns a future to apply a Glow Effect.
-- Note: works on Wild Jellies
common:applyGlowEffect()

-- Returns a future to apply a Love Effect. Takes in an int for the duration of the effect in game minutes.
common:applyLoveEffect(durationGameMinutes)

-- Returns a future to apply a Salt Effect.
-- Note: works on Wild Jellies
common:applySaltEffect()

-- Returns a future to apply a Shape Reset Effect.
-- Note: works on Wild Jellies
common:applyShapeResetEffect()

-- Returns a future to apply a Shape Set Effect. Takes in a string for the name or key of shape.
-- Note: works on Wild Jellies
common:applyShapeSetEffect(shapeNameOrKey)

-- Returns a future to apply a Shape Set Effect. Takes in an int for the id of shape.
-- Note: works on Wild Jellies
common:applyShapeSetEffect(shapeId)

-- Returns a future to apply a Stat Exp Effect. Takes in a string for the stat, an int for the exp, and a boolean on if it's relative.
-- Note: works on Wild Jellies
common:applyStatExpEffect(stat, exp, relative)

-- Returns a future to apply a Stat Gain Multiplier Effect. Takes in a string for the stat, an int for the duration, an int for an onset delay, and a float for the gain multiplier
-- Note: works on Wild Jellies
common:applyStatGainMultiplierEffect(stat, durationGameMinutes, delayOnsetGameMinutes, multiplier)

-- Returns a future to apply a Stat Level Effect. Takes in a string for the stat, an int for the level, and a boolean on if it's relative.
-- Note: works on Wild Jellies
common:applyStatLevelEffect(stat, level, relative)

-- Returns a future to apply a Trait Forget Effect.
-- Note: works on Wild Jellies
common:applyTraitForgetEffect()

-- Returns a future to apply a Trait LEarn Effect. Takes in a string for the trait name.
-- Note: works on Wild Jellies
common:applyTraitLearnEffect(traitName)

-- Returns a future to apply a Trait Mutate Effect.
-- Note: works on Wild Jellies
common:applyTraitMutateEffect()

-- Returns a future to apply a Unlove Effect.
common:applyUnloveEffect()

-- Returns a future to apply a Wash Effect.
common:applyWashEffect()

-- Returns a boolean if the entity has the trait. Takes in a String for the trait name.
common:hasTrait(trait)

-- Returns a future to remove a trait from a entity. Takes in a String for the trait name.
common:removeTrait(trait)

-- Returns a future to spawn a specific number of items. Takes in a String for the item name or key, and an int for the amount.
common:spawnExactItemAmount(itemNameOrKey, amount)

-- Returns a future to spawn a random number of items, starting at 0 inclusive. Takes in a String for the item name or key, and an int for the maximum amount.
common:spawnRandomItemAmount(itemNameOrKey, max)

-- Returns a future to spawn a random number of items. Takes in a String for the item name or key, an int for the minimum amount, and an int for the maximum amount.
common:spawnRandomItemAmount(itemNameOrKey, min, max)

-- Returns a future to spawn a specific number of crystals. Takes in an int for the amount.
common:spawnExactCrystalAmount(amount)

-- Returns a future to spawn a random number of crystals, starting at 0 inclusive. Takes in an int for the maximum amount.
common:spawnRandomItemAmount(itemNameOrKey, max)

-- Returns a future to spawn a random number of crystals. Takes in a String for the item name or key, an int for the minimum amount, and an int for the maximum amount.
common:spawnRandomItemAmount(itemNameOrKey, min, max)

-- Returns a future that destroys the entity
common:destroy()

-- Returns a boolean if the entity has a light source.
common:hasLightSource()

-- Returns the color palette id, as an int.
common:getgetColorPaletteId()

-- Returns the shape id, as an int
common:getShapeId()

-- Returns the internal color palette name, as a string.
common:getColorPaletteInternalName()

-- Returns the internal shape name, as a string.
common:getShapeInternalName()

-- Returns the localised color palette name, as a string.
common:getColorPaletteName()

-- Returns the localised shape name, as a string.
common:getShapeName()

-- Returns the stat level, as an int. Takes in a string for the stat.
common:getStatLevel(stat)

-- Returns the stat exp, as an int. Takes in a string for the stat.
common:getStatExp(stat)

-- Returns the required exp for level, as an int. Takes in an int for the level.
common:getRequiredExpForLevel(level)

-- Returns the entityId, as an int.
common:getEntityId()

-- Returns the X coordinate of the map the entity is on, as an int.
common:getMapX()

-- Returns the Y coordinate of the map the entity is on, as an int.
common:getMapY()

-- Returns the X coordinate of the tile the entity is on, as an int.
common:getTileX()

-- Returns the Y coordinate of the tile the entity is on, as an int.
common:getTileY()

-- Returns the raw stats.
common:getStatsRaw()

-- Returns the raw nature data.
common:getNatureDataRaw()

-- Returns the localised nature name
common:getNatureName()

-- Returns the internal nature name
common:getNatureInternalName()

-- Returns trait name from the specified slot. Takes in an int for the slot number, should be 0 - 2 inclusive.
-- Note: Will return null if the slot specified is out of range or if the slot doesn't have a trait
local traitName = common:getTraitInSlot(slotIndex)

-- Returns the amount of traits.
local amountOfTraits = common:getTraitsCount()

Eggs

The following methods are available to Eggs in addition to the base methods.

-- Returns the age in days, as an int
egg:getAgeInDays()

-- Returns a future that sets the age of the egg in days. Takes in an int.
egg:setAgeInDays(ageInDays)

-- Returns the time required to hatch the egg in game minutes, as an int
egg:getHatchTimeInGameMinutes()

-- Returns the current hatch time in game minutes, as an int
egg:getCurrentHatchTimeInGameMinutes()

-- Returns the remaining time to hatch in game minutes, as an int
egg:getTimeRemainingToHatchInGameMinutes()

-- Immediately hatches the egg
egg:hatch()

-- Set egg's timer in game minutes. Can pass in true for `relative` param to add/subtract from the current time
egg:setCurrentHatchTime(10, false)

-- Set egg's timer X in game minutes from hatching
egg:setRemainingHatchTime(10)

-- Set egg's required time to hatch in game minutes. Can pass in true for `relative` param to add/subtract from the time
egg:setTotalTimeToHatch(120, false)

Jellies

The following methods are available to a Jelly in addition to the base methods. Note: Not all effects work on Wild Jellies. Those that do have a note.

local jelly = jellySelection:getSelectedJelly()

-- Get the level of a stat (TUMMY, BLOB or SOCIAL)
local tummyLevel = jelly:getStatLevel("TUMMY")

-- Get the color id
local colorId = jelly:getColorPalette()

-- Get the shape id
local shapeId = jelly:getShape()

-- Get the number of buffet competition medals
local buffetMedals = jelly:getBuffetMedals()

-- Get the number of splash competition medals
local splashMedals = jelly:getSplashMedals()

-- Get the number of sumo competition medals
local sumoMedals = jelly:getSumoMedals()

-- Get the number of vogue competition medals
local vogueMedals = jelly:getVogueMedals()

-- Get the total number of competition medals
local totalMedals = jelly:getTotalMedals()

-- Get the number of Champion medals from competitions
local championMedals = jelly:getTotalChampionMedals()

-- Check if a Jelly has a certain trait
if jelly:hasTrait("boring") then
    -- DO SOMETHING HERE
end

-- Check if a Jelly has an empty trait slot
if jelly:hasEmptyTraitSlot() then
    -- DO SOMETHING HERE
end

-- Check if a Jelly trait slot (0 - 2) is empty
if jelly:isEmptyTraitSlot(1) then
    -- DO SOMETHING HERE
end

-- Returns a future that removes a specific trait from the Jelly.
jelly:removeTrait("boring")

-- Returns a future that removes a trait from a specific slot on the Jelly. Slots are 0-2
jelly:removeTraitBySlot(0)

-- Returns a future that replaces a trait in a specific slot on the Jelly. Slots are 0-2
jelly:replaceTraitInSlot(2, "boring")

-- Returns a future that replaces a specific slot on the Jelly.
jelly:replaceTraitByName("boring", "explorer")

-- Returns a future that applies the Trait Forget item effect
-- The Jelly will forget a random trait
jelly:applyTraitForgetEffect()

-- Returns a future that applies the Trait Learn item effect
-- The Jelly will learn a specific trait
jelly:applyTraitLearnEffect("cuddly")

-- Returns a future that applies the Trait Mutate item effect
-- The Jelly will forget a random trait and learn a random trait
jelly:applyTraitMutateEffect()

-- Returns a future to set the Happiness Value. Takes in an int for the modifier, and a boolean for if the change is relative.
jelly:setHappinessValue(valueModifier, relative)

-- Returns a future to apply a Sleep Effect. Takes in an int for the duration of the effect in game minutes, an int for an onset delay and a boolean if it's relative.
-- Note: works on Wild Jellies
jelly:applySleepEffect(durationGameMinutes, delayOnsetGameMinutes, relative)

-- Returns a future to apply a Sleep Effect. Takes in an int for the duration of the effect in game minutes, with no onset delay and is relative.
-- Note: works on Wild Jellies
jelly:applySleepEffect(durationGameMinutes)

-- Returns a future to apply a Awake Effect. Takes in an int for the duration of the effect in game minutes, an int for an onset delay and a boolean if it's relative.
jelly:applyAwakeEffect(durationGameMinutes, delayOnsetGameMinutes, relative)

-- Returns a future to apply a Relic Meter Effect. Takes in an int for the modifier and a boolean for if the change is relative.
-- Note: works on Wild Jellies
jelly:applyRelicMeterEffect(valueModifier, relative)

-- Returns a future to apply a Max Relic Meter Effect. Takes in an int for the modifier and a boolean for if the change is relative.
-- Note: works on Wild Jellies
jelly:applyMaxRelicMeterEffect(valueModifier, relative)

-- Returns the current relic meter value. Implementation Note: Value starts at max relic meter value and turns to relic at 0
local currentRelicMeterValue = jelly:getRelicMeter()

-- Returns the max relic meter value
local maxRelicMeterValue = jelly:getMaxRelicMeter()

-- Increments the current relic meter value by the amount in parameter. Implementation Note: Not the same as the relic meter on display in game. Value starts at max relic meter and turns to relic at 0.
jelly:incrementRelicMeterCounter(AMOUNT)

-- Decrements the current relic meter value by the amount in parameter. Implementation Note: Not the same as the relic meter on display in game. Value starts at max relic meter and turns to relic at 0.
jelly:decrementRelicMeterCounter(AMOUNT)

-- Increments the current relic meter on display in game by the amount in parameter. Implementation Note: Value starts at 0 and turns to relic at max relic meter.
jelly:incrementDisplayRelicMeterCounter(AMOUNT)

-- Decrements the current relic meter on display in game by the amount in parameter. Implementation Note: Value starts at 0 and turns to relic at max relic meter.
jelly:decrementDisplayRelicMeterCounter(AMOUNT)

-- Check if the Jelly is hungry
-- Note: This always returns false for wild jellies
if jelly:isHungry() then
    -- DO SOMETHING HERE
end

-- Check if the Jelly is tired
-- Note: This always returns false for wild jellies
if jelly:isTired() then
    -- DO SOMETHING HERE
end

-- Check if the Jelly is happy
-- Note: This always returns false for wild jellies
if jelly:isHappy() then
    -- DO SOMETHING HERE
end

-- Check if the Jelly is sad
-- Note: This always returns false for wild jellies
if jelly:isSad() then
    -- DO SOMETHING HERE
end

-- Check if an item is in the Jelly's stomach
-- Note: This always returns false for wild jellies
if jelly:isItemInStomach("Actina Tuber") then
    -- DO SOMETHING HERE
end

-- Check if an item is in the Jelly's specific stomach slot
-- Note: This always returns false for wild jellies. Stomach slot needs to be 0, 1 or 2
if jelly:isItemInStomachSlot("Actina Tuber", 0) then
    -- DO SOMETHING HERE
end

-- Check if specific stomach slot is empty
-- Note: Slot number needs to be 0, 1 or 2
jelly:isStomachSlotEmpty(1)

-- Check if the jelly is a wild jelly or captured jelly
if jelly:isWildJelly() then
    -- DO SOMETHING HERE
end
if jelly:isCapturedJelly() then
    -- DO SOMETHING HERE
end
if jelly:isJellyInLove() then
    -- DO SOMETHING HERE
end

-- Returns a future that removes all accessories and spawns them beside the jelly
jelly:dropAllAccessories()

-- Returns a future that forces the Jelly to poop all items in stomach
-- Passing true to the function will wait for poop to spawn in the overworld
jelly:flush(true)
jelly:flush(false)

-- Returns a future that de-highlights the Jelly if it is currently highlighted
jelly:dehighlight()

-- Returns true if jelly is in a competition
jelly:isInCompetition()

Relics

The following methods are available to Relics in addition to the base methods.

-- Check if a Relic has an empty trait slot
if relic:hasEmptyTraitSlot() then
    -- DO SOMETHING HERE
end

-- Check if a Relic trait slot (0 - 2) is empty
if relic:isEmptyTraitSlot(1) then
    -- DO SOMETHING HERE
end

-- Returns the age in days, as an int
relic:getAgeInDays()

-- Returns a future that sets the age of the Relic in days. Takes in an int.
relic:setAgeInDays(ageInDays)

-- Immediately turns the Relic into a Jelly, restoring its stats, colour, shape etc before it turned into a Relic
relic:turnRelicIntoJelly()

Script Scheduler

Scheduled scripts are defined via XML files.

Scheduled scripts allow a mod to execute scripts in background at predefined schedules using a CRON-like syntax.

The data must be placed in config/scheduled/.An example of scheduled scripts XML can be seen below.

<data>
  <entries length="12">
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@daily</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@weekly</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@monday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@tuesday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@wednesday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@thursday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@friday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@saturday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@sunday</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@monthly</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>@yearly</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
    <value class="com.alchemiccutie.api.scheduler.ScriptSchedulerEntry">
      <schedule>10 16 * SPR,SUM * Mon-Fri</schedule>
      <script>scripts/example/example.lua</script>
      <priority>0</priority>
    </value>
  </entries>
</data>

Note that entries.length and value.class attributes are optional.

The field order is: Minute Hour DayOfMonth Season Year DayOfWeek

Valid values for Season are: SPR, SUM, AUT, WIN

Valid values for DayOfWeek are: Mon, Tue, Wed, Thu, Fri, Sat, Sun

Aliases

Alias Extended meaning

@daily

0 0 * * * *

@weekly

0 0 * * * Mon

@monday

0 0 * * * Mon

@tuesday

0 0 * * * Tue

@wednesday

0 0 * * * Wed

@thursday

0 0 * * * Thu

@friday

0 0 * * * Fri

@saturday

0 0 * * * Sat

@sunday

0 0 * * * Sun

@monthly

0 0 1 * * *

@yearly

0 0 1 SPR * *

Multiple values

Symbol Example Meaning

,

0,10,30,55 0 * * * *

Execute the specified script when Minute is 0, 10, 30 or 55

-

0 10-18 * * * *

Execute the specified script when Hour is between 10 and 18 (bounds included)

Note that you can combine the various multiple values symbols, eg: 0-3,10,5 15,18-20,23 * * * *

Internationalization

Mod internationalization is suggested. Alchemic Cutie Modding Toolkit provides facilities for easily translating your mod.

POT (PO Templates) are generated in l10n/templates, along with a file containg word count in l10n/templates/word_count.txt, which will be useful to quote the translation price if you outsource it.

In order to provide a translation for a language you need to translate every .pot file in l10n/templates and put it as a .po file in l10n/xx where xx is the ISO 639-1 code for the language you are providing the translation to (for example Italian translated PO files will be in l10n/it and Spanish ones in l10n/es).