Diora Level Editing

1. Getting Started

The Construct is your hub for creating your own levels for Diora!

Enter the construct and interact with the blueprint table to get started.

Entering the editor
The editor can spoil the story and mechanics in Diora. Please consider finishing the story before using the editor.

1.1. Editor

The editor was designed to make level editing as easy as possible. All campaign levels were made using the level editor!

Selected block Cursor position

UI Layout

D-Pad hint

Crank hint

1.2. Controls

Standard Controls

a - Place currently selected block

dpad - Move cursor horizontally

crank - Rotate level

Controls While Holding b

a - Erase hovered block

updown - Move cursor vertically

leftright - Rotate cursor

crank - Change selected block

2. Editor Menu

Use these menus to manage your level and project.

Editor Menu List

2.1. Menus

Test Level

Used to test your level!

Press b to get back to the editor quickly.

Use menu and select render icon to render a project icon instead of making one from scratch.

Save / Quit

The save/quit menu contains multiple menus and commands, but is mainly used to save the level and exit back to the project menu.

savequit

Editor Settings

Used to change settings such as the movement and rotation snap.

Movement Snap

needed for correct placement of certain blocks like fences.

editorsettings
Rotation Snap

Can be used to make more organic placements.

Block Overlap

Behavior can be changed to place blocks inside of each other, or replace blocks.

Save On Test

Can be enabled if you are paranoid about my error checking abilities.

Use Block As Cursor

Can be turned off to help with visibility near your cursor.

Level Settings

Used to change settings such as the music, background, and weather of the level.

levelsettings

Block Library

Browse and load blocks to use in the level.

Filters can be applied using leftright to sort by all, interactable, rendering fx, connectable, and decorative.

blocklibrary

Block Inspector

Hover the cursor over a block and inspect its values.

Numerical values can be edited using the leftright.

String values can be edited using the a button.

blockinspector
Figure 1. Using the block inspector to change a spinning block’s speed s value.
The movement snap setting is used for most numerical values except for r and tr values which use the rotation snap setting.

Edit Connections

The connections menu is used to link blocks together. Hover the cursor over a block and edit its connections. Connections are linked 'opposite to flow'.

Connection UI
Figure 2. The display is 'listening' for the button’s state to change.

3. Console Commands

While levels can be made entirely on the Playdate, advanced tools are available using a computer! The Commands System is used to handle complex logic behind dialogue, triggers, and editor tools.

console
consoleresult

3.1. Demos

Unsure of how to use a certain block? Check to see if the block has a demo level.

  • Use !msg demos to print the list of valid demos.

  • Use !msg demo NAME to load the level.

4. Custom Assets

Diora projects support many types of custom assets.

Some custom assets require knowledge of Blender 3.6 and the Playdate SDK.

4.1. Example Project

Download this example project to understand the structure for custom assets.

Example Project

4.2. Dialogue

Dialogue files are used to control interactions with NPCs.

Write the dialogue .txt and place it in the project’s dialogue folder.

To attach a dialogue file to an npc, set the convo value on the npc object to the name of the dialogue file using the block inspector.

Example

This is an example of a standard dialogue file

#character zuriya
#evil true
Hey, have you seen any 'Network Technicians'?
Cause |w They || told me to apprehend any I find.
So let me know if you see any, okay?
Dialogue
Figure 3. Dialogue from the above example.

Dialogue Commands

Dialogue commands are used in dialogue files to run simple commands, usually used to change what character is speaking.

#character zuriya

Dialogue Effects

Add tags between word to apply effects to the text in dialogue.

Effect tags are formatted with a vertical bar and a character |c with the character changing for each type of effect.

A double vertical bar || is used to stop the effect.

Only one effect can be used at a time.

Always put spaces between words and the effect tags.

#character npc1
|w Heyyyyyyy || hows it going?
I'm |s soooo scared.
Hey, |m ugh not again.
dialogueeffects

4.3. Blocks

Example Block
  • Render frames from Blender.

  • Use the Dither Tool to convert to a single image.

  • Build the image table to a .pdt using the Playdate SDK and place in the blocks folder.

  • Replace existing blocks by using the same name, or use !msg loadblock NAME.

To create blocks with special abilities like stairs or spinning blocks, you must supply a blockdata file.

  • Find the block you want to duplicate the functionality of.

  • Create a .json file with the name of the block.

  • Use the blockdata console command and copy the block data into the json file.

blockdata
  • Place the file in the project’s blockdata folder.

Block Design Tips

palette

In the example block template, the palette block shows materials commonly used in Diora. Custom shaders can be used to make special effects!

materials

Consider how a block’s full rotation is 180 frames, with one every 2 degrees. If a block is rotationally symmetrical every 180 or 90 degrees, you only need to supply 45 or 90 frames. (0-44 or 0-89 in blender). This is also true for custom backgrounds.

4.4. NPCs

Example NPC
  • Render frames from Blender.

  • Use the Dither Tool to convert to a single image.

  • Build the image table to a .pdt using the Playdate SDK and place in the blocks folder.

  • Replace existing blocks by using the same name, or use !msg loadblock NAME.

  • Make a blockdata file for the npc using this data, refer to the instructions for blockdata above.

{
	[dontstand] = true,
	[drawfunc] = npc,
	[newfunc] = npc,
	[npc] = true,
}

4.5. NPCs in Dialogue

To make a custom NPC speak in dialogue, you will need to make a character file and render an icon table.

  • In the NPC blend file, Switch to the icon camera and render.

  • Use the Dither Tool to render the last 16 frames, they should be arranged in a 4x4 square.

  • Build the image to a .pdt named the NPC’s id and place it in the charactericons folder.

  • Make a .txt named the NPC’s id. The file will contain the NPC’s display name, icon id, and bebe id.

Paul
paul
box

Built in bebe sounds are auto, box, breath, granular, heh, hu, lama, moai, phase, pop, and type.

  • Place the file in the project’s characters folder.

  • Dialogue should now be able to accept the npc id name in the character command.

4.6. Bebe

Custom voice bebe sound effects are possible.

  • Convert the bebe to ADPCM WAV using Audacity.

  • Build the bebe to .pda using Playdate SDK or an external converter.

  • Place .pda in the project’s audio/bebe folder.

4.7. Backgrounds

Example Background
  • Render frames and use the Dither Tool.

  • Build to .pdt and place in the backgrounds folder.

  • Load with !msg background NAME.

4.8. Music

  • Convert the track to ADPCM WAV using Audacity.

  • Build the track to .pda using Playdate SDK or an external converter.

  • Place .pda in the project’s audio/music folder.

  • Define loops using a .txt with the same name as the track. (Display name, loop start)

Concrete Jungle
20.2
  • Place .txt in the project’s musicdata folder.

4.9. Project Icon

  • Create custom icons at (200x240).

  • Build to .pdi using Playdate SDK.

  • Replace project.pdi in the project’s icons folder.

    A project icon can be rendered while in test mode instead of making one from scratch. Open the menu with menu and select render icon.

4.10. Metadata

Metadata files can be placed in the project folder.

  • 'desc.txt': Simple message about your project.

desc
  • 'lock.txt': Will remove the edit option in the UI. The file can contain anything.

This does not actually prevent anyone from editing your project, but can be used to deter editing and make the project feel more complete.

5. Commands

Commands are used by the Console and Dialogue system.

These commands are interchangeable! Use # for a dialogue command or !msg (and a space) for the console. This can be used to achieve very complex effects!

!msg music theme in the console vs #music theme in a dialogue file or cmd.

Command Args Example Description

Hello World!

No command, dialogue.

 — 

#-- this is bad

Comment, self explanatory.

background

name

#background construct

Changes level background, required for custom backgrounds.

bebe

name

#bebe diora

Changes Bebe sound. (Use character first.)

blockdata

name

#blockdata ladder

Prints block data .json to console.

branch

dialogue

#branch tip1 tip2 tip3

Branches into the new dialogue file, will pick randomly if more are given.

branchlore

lore dialogue

#branchlore spoketodave reward

Branches if the lore is true.

branchlorenot

lore dialogue

#branchlorenot beenscared scare

Branches if the lore is not true.

call

function

#call fpsu

Calls the global scope function with no arguments. Can be unstable!

cam

angle zpos time

#cam 90 5 2

Starts a camera animation. Use end to return angle control to the user.

changeself

name

#changeself npcpaul

Changes the dialogue owner into the block with the given name. Useful to make an npc put on a hat.

character

name

#character paul

Changes Bebe, name, and Icon with one command based on a character file.

clear

time

#clear

Clears the screen for the specified time, useful for hiding cutscene transitions.

convoat

convo x y z

#convoat warning 1 2 3

Starts the convo with the owner that is at the position.

crankindicator

x y z

#crankindicator

Set the position to where the player spawns, will show indicator when there is no input for a bit.

debug

#debug

Toggles debug mode.

deletewhere

exp

#deletewhere x==3

Deletes blocks that satisfy the expression.

demo

name

#demo kick

Start a demo level.

demos

#demos

Print the demo list.

destroy

#destroy

Destroys the block that owns the dialogue.

destroyat

x y z

#destroyat 1 2 3

Destroys the block at xyz.

endcmdlore

lore

#endcmdlore spoketodave

Will stop executing the cmd if the dialogue is true. Useful to run a command on a first time entry.

endcmdlorenot

lore

#endcmdlorenot spoketodave

Will stop executing the cmd if the dialogue is not true.

evil

active

#evil true

Sets the dialogue display to be possessed.

explode

x y z r

#explode

Explodes the position and radius like a bomb block.

export

#export

Prints the level .json in the console.

fade

value

#fade 1

Sets the current fade value, (0-1).

fadetarget

value

#fadetarget

Sets the fade transition target, (0-1), useful to hide a level transition during a cutscene.

fistcrush

x y z

#fistcrush 1 2 3

Will spawn a fist and crush the position given.

gointo

name

#gointo room

Level transition, keeps player in the same spot. (like a door)

icon

name

#icon diora

Changes dialogue Icon. (Use character first.)

image

path

#image

Displays the image in the dialogue window, use none to hide. (This doesn’t support custom assets yet, sorry.)

interactat

x y z

#interactat 1 2 3

Interacts with block at the xyz.

jumpself

state

#jumpself

Makes the dialogue owner jump up and down. Must be start or stop.

kill

delay

#kill

Diora is kil. (delay is optional and rarely used.)

lb

#lb

Loads the block. Required for custom blocks.

loadblock

name

#loadblock

Loads the block by name. Required for custom blocks.

lockinput

bool

#lockinput true

Locks/Unlocks player input.

moveplayer

x y

#moveplayer 0 1

Moves the player during dialogue or cmd with the delta.

moveself

#moveself -1 0

Moves the dialogue owner during dialogue with the delta.

music

name

#music construct

Changes level music. Required for custom music.

musicclimb

bottom top music1 music2

#musicclimb 4 55 theme none

Starts the music climb effect.

musicloop

time

#musicloop 0.1 15.73

Set music loop point, use reset to use the default.

offsetblocks

x y z

#offsetblocks

Offsets all blocks in the scene.

offsetwhere

exp x y z

#offsetwhere z>1 0 0 1

Offsets blocks satisfying the expression.

placeprefab

name

#placeprefab tree

Places the prefab at the editor cursor. Prefab placement can be messy, save first!

placeprefabat

name x y z r

#placeprefabat tree 3 2 1

Places the prefab at the position.

placeprefabatself

name

#placeprefabatself idk

Places the prefab at the dialogue owner’s position. IDK why this is in the game.

playerlookat

x y

#playerlookat 1 2

Makes the player look twoards the position specified.

print

message

#print Hello World!

Prints the message.

risefinish

x1 y1 z1 x2 y2 z2

#risefinish -1 -1 9.5 1 1 25

Used for the drone port level exit animation.

rsnap

angle

#rsnap 22.5

Sets rotation snap value.

runcmd

string

#runcmd

runs the string as a command, use #. String together commands or make pasting easier.

selflookat

#selflookat 3 3

Makes the dialogue owner look twoards the position specified.

selflookatplayer

#selflookatplayer

Makes the dialogue owner look at the player.

set

type name value

#set number playermovespeed 0.9

Sets the global variable. Can be unstable!

setat

type name value x y z

#setat boolean active false 1 2 3

Sets the variable of the block at the xyz.

setlore

name value

#setlore spoketodave true

Sets lore value for story progression.

setplayer

type name value

#setplayer number tr 180

Sets a value on the player object.

setself

type name value

#setself string msg hello!

Sets the variable of the block that owns the dialogue.

shake

#shake

Shakes the screen.

sle

name

#sle house

Starts the level in the editor by name.

sli

name

#sli house

Starts the level immedietly by name.

slowfadeout

seconds

#slowfadeout 8

Does a slow fadeout animation like in the credits.

snap

value

#snap 0.5

Sets the movement snap value.

sound

name

#sound explosion

Plays the sound effect.

startlevel

name

#startlevel house

Starts the level by name.

stopvideo

#stopvideo

Stops the video thread if it exists.

text

string

#text Calling paulj

Displays the text as an image like #image, use none to hide.

unlock

name

#unlock

Unlocks the current level hovered over on the map, or by name.

video

name

#video intro

Plays a video.

videohold

#videohold

Plays a video, will hold on the last frame.

wait

seconds

#wait 4.5

Delays the command or dialogue.

waitforvideo

#waitforvideo

Waits the command until the video ends.

win

delay

#win

Diora is win! (delay is optional and rarely used.)

6. Conclusion

If you have questions or want to share your project, please feel free to join the Diora Discord Server!

Thank you!

-Zack