level editor - Poobslag/turbofat GitHub Wiki

Level editor

The level editor can be accessed through the GodotEditor by launching the LevelEditor scene directly. This editor is still very unstable and omits some very basic UI features. Bad things will happen if you type invalid json. You can lose all of your data if you forget to save; it will not prompt you. It would be nice to improve it some day, but it is a low priority next to making the game more fun.

Level editor screenshot

Left panel: Palette

The left panel provides a palette of pieces which can be dragged to the playfield to the right. The 🔄 button rotates the pieces, while the ⬅️ ➡️ buttons change the snack/vegetable blocks into other varieties.

Center panel: Playfield

The playfield can be edited by dragging pieces from the palette on the left.

Pieces can be erased from the playfield with the right mouse button.

Right panel: Save and load

The top text field is the scenario name. This should be snake_case and should match the scenario filename. It's never displayed to the user, but is used when storing save data.

The Open File button loads a scenario from the file system. The Open Resource button loads a scenario from the game's resource files. The Save button saves a scenario to the file system.

The Test button will let you try out the scenario. When you're in test mode, clicking "Back" will bring you back to the level editor.

Bottom panel: Json file

All scenario data is stored in json. This text area shows you what will be written to disk. You can manually edit this.

Exit

The exit button is in the bottom-right corner. Make sure to save your changes first.

File format

Scenarios are stored in json files which define things how you win, how you lose, what types of pieces you're given, special scoring criteria and other obstacles.

Current implementation

  • blocks_during: Blocks/boxes which appear or disappear while the game is going on.
    • blocks_during.no_clear_filled_lines: Lines will not be cleared when the player fills them. They can still be cleared with a level trigger effect. (Default: clear_filled_lines)
    • blocks_during.clear_on_top_out: The entire playfield is cleared when the player tops out. (Default: false)
    • blocks_during.filled_line_clear_delay: How many pieces or trigger effects a line waits before being cleared; 0 = immediate. (Default: 0)
    • blocks_during.filled_line_clear_max: The maximum number of lines which can be cleared simultaneously. (Default: 999999)
    • blocks_during.filled_line_clear_min: The minimum number of lines which must be filled to trigger line clears. (Default: 0)
    • blocks_during.filled_line_clear_order: The order in which filled lines are cleared. oldest, lowest, random, default. (Default: default)
    • blocks_during.fill_lines: Tiles key for 'filled' lines -- lines which fill from the top for levels with narrow playfields. (Default = ''; no lines will be inserted)
    • blocks_during.line_clear_type: Whether lines drop when the player clears a line. default, float, float_fall (Default: default)
    • blocks_during.pickup_type: Whether pickups move with blocks. default, float, float_regen (Default: default)
    • blocks_during.refresh_on_top_out: If true, the playfield is restored to its initial state when the player tops out. (Default: false)
    • blocks_during.shuffle_filled_lines: bag, none, slice (Default: bag)
    • blocks_during.shuffle_inserted_lines: bag, none, slice (Default: bag)
    • fill_lines: If assigned, blank lines will be filled from the specified tile set. 0, 1. (Default: '')
  • color_string: Level button color. This is usually random, but for rank mode we use specific colors. red, blue. (Default: '')
  • combo_break: Things that disrupt the player's combo. veg_row (Default: [])
    • pieces 0, pieces 1, pieces 999999: Combo breaks if you drop this many pieces without continuing your combo. A value of '0' means you can't build combos. (Default: pieces 2)
    • veg_row: Clearing a vegetable row breaks the player's combo.
  • finish_condition: How the player finishes. When the player finishes, they can't play anymore, and the level just ends. It should be used for limits such as serving 5 customers or clearing 10 lines.
    • finish_condition.type: customers, lines, none, pieces, score, time_over, time_under. (Default: none)
    • finish_condition.value: 5, 60, 1000. (Default: 0)
  • icons: Icons shown when selecting a level which warn the player about gimmicks. carrot, mole, shark, onion, spear, piece_j, piece_l, piece_o, piece_p, piece_q, piece_t, piece_u, piece_v, piece_s, piece_z, piece_c, piece_k, snack_box, cake_box, veggie, basic, slow, fast, dig, surprising, annoying, confusing, sneaky, narrow, blind, stop, turn
  • input_replay: A set of computer-controlled piece inputs. This is used to steer pieces around during tutorials, and will prevent the player from controlling the piece. (Default: [])
  • lose_condition: How the player loses. For some levels, the player might lose in the middle of a level if they don't make enough blocks, or don't play quickly enough.
    • top_out: Player loses if they top out too many times. 1, 999999. (Default: top_out 3)
    • finish_on_lose: If the player loses, the 'finish' screen is shown and it is not recorded as a loss. Used for sandbox modes. (Default: false)
  • other: Rules which are unique enough that it doesn't make sense to put them in their own groups.
    • other.after_tutorial: For levels which follow tutorial levels. Affects UI behavior. (Default: false)
    • other.no_clear_on_finish: When finishing the level, all lines are not automatically cleared. (Default: clear_on_finish)
    • other.enhance_combo_fx: Makes the combo visuals more noticable. Used in combo-centric tutorials so that the player can more easily tell when they need to maintain a combo. (Default: false)
    • other.food_speed: Food speed factor. Higher speeds make foods disappear faster so the player can see. (Default: 1.0)
    • other.non_interactive: For non-interactive tutorial levels which don't let the player do anything. (Default: false)
    • other.suppress_piece_rotation: Prevents the player from rotating pieces. none, rotation, rotation_and_signals. `(Default: rotation)
    • other.suppress_piece_initial_rotation: Prevents the player from rotating pieces, or from performing initial rotation. none, rotation, rotation_and_signals. (Default: rotation)
    • other.start_level: When the level is restarted, a different level is swapped in instead. Used for tutorials. career/ultra_normal, tutorial/squish_0. (Default: '')
    • other.tile_set: Affects the blocks' appearance (and sometimes behavior). default, veggie, diagram. (Default: default)
    • other.tutorial: For tutorial levels. Affects UI behavior. (Default: false)
    • other.vertical_line_pieces: Makes line pieces vertical, for levels where horizontal line pieces will cause a top out. (Default: false)
  • piece_types: The selection of pieces provided to the player.
    • ordered_start: If true, the start pieces always appear in the same order instead of being shuffled. (Default: false)
    • piece_j: Pieces which show up during a level. piece_c, piece_d, piece_i, piece_j, piece_k, piece_l, piece_o, piece_p, piece_q, piece_s, piece_t, piece_u, piece_v, piece_z. (Default: [])
    • start_piece_j: Pieces provided at the start of a level. If multiple pieces are specified, they're shuffled. start_piece_c, start_piece_d, start_piece_i, start_piece_j, start_piece_k, start_piece_l, start_piece_o, start_piece_p, start_piece_q, start_piece_s, start_piece_t, start_piece_u, start_piece_v, start_piece_z. (Default: [])
    • no_suppress_o_piece: Disables the behavior where the bag algorithm rerolls the extra piece once if it comes up as an O-Block. (Default: suppress_o_piece)
    • no_suppress_repeat_piece: Disables the behavior where the bag algorithm avoids repeat pieces. (Default: suppress_repeat_piece)
  • rank: Tweaks to rank calculation.
    • rank.box_factor: Multiplier for the expected box_score_per_line. '3.0' means the player needs 3x the usual box points per line to get a good rank. (Default: 1.0)
    • rank.rank_criteria: Thresholds for getting different grades: rank_criteria m=3350 s-=580. Criteria can be specified for all grades: M, SSS, SS+. However for consistency, it's recommended to only specify an M grade in which case the rest are extrapolated.
    • rank.skip_results: Skip the results screen. Used for tutorials. (Default: false)
    • rank.success_bonus: Bonus rank given if the player achieves the level's success condition. Useful when designing levels where achieving a score of 1,000 is an A grade, but failing with a score of 999 is also an A grade. This property gives the player a little bump in rank so achieving the target score will always result in a higher grade. (Default: 0)
    • rank.unranked: Player is not given a rank for this level. (Default: false)
  • score: Rules for scoring points.
    • score.veg_points: Bonus points awarded for clearing a row with no boxes. 0, 10. (Default: 0)
    • score.snack_all: Bonus points awarded for each snack box in a line clear. 0, 10. (Default: 5)
    • score.cake_all: Bonus points awarded for each cake box in a line clear. 0, 40. (Default: 10)
  • speed_ups: Requirements to speed up and make the game harder.
    • speed_ups.type: customers, lines, none, pieces, score, time_over, time_under. (Default: none)
    • speed_ups.value: 5, 60, 1000. (Default: 0)
    • speed_ups.speed: T, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, AA, AB, AC, AD, AE, AF, F0, F1, FA, FB, FC, FD, FE, FF, FFF. (Default: 0)
  • start_speed: The speed the player starts on. T, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, AA, AB, AC, AD, AE, AF, F0, F1, FA, FB, FC, FD, FE, FF, FFF. (Default: 0)
  • success_condition: How the player succeeds. When the player succeeds, there's a big fanfare and celebration, it should be used for accomplishments such as surviving 10 minutes or getting 1,000 points.
    • success_condition.type: customers, lines, none, pieces, score, time_over, time_under. (Default: none)
    • success_condition.value: 5, 60, 1000. (Default: 0)
    • success_condition.lenient_value: A marathon mode might end when the player clears 1,000 lines, but we only grade the player with the expectation of them getting 150 lines. That '150 lines' is the lenient value. 100, 200, 500. (Default: <null>)
  • tiles: Sets of blocks which are shown initially, or appear during the game.
    • tiles.start: A set of blocks which is shown initially.
    • tiles.0 tiles.1: Alternate set of blocks appear during the game.
  • timers: Timers which cause strange things to happen during a level.
    • timers.interval: How frequently the timer should fire, measured in seconds. (Default: 1.0)
    • timers.start: How long the timer should wait to fire the first time, measured in seconds. (Default: <interval>)
  • triggers: Triggers which cause strange things to happen during a level.
    • triggers.phase: Event which makes the the trigger fire. line_cleared, box_built cake
    • triggers.phase.after_piece_written: Fires after the piece is written, and all boxes are made, and all lines are cleared.
    • triggers.phase.before_start: Fires when the game will start soon, including when the puzzle is first shown.
    • triggers.phase.box_built: Fires when a snack/cake box is built. any, snack, cake, brown, pink, bread, white, cheese, cake_jjo, cake_jlo, cake_jtt, cake_llo, cake_ltt, cake_pqv, cake_puv, cake_quv, cake_cju, cake_clu, cake_ctu. (Default: any)
    • triggers.phase.combo_ended: Fires when the player breaks their combo. The optional integer expression allows the trigger to be conditional based on the player's combo. 7..., 3,6,9..., 10-15 (Default: <all>)
    • triggers.phase.initial_rotated_180: Fires when the piece is flipped using initial DAS.
    • triggers.phase.initial_rotated_ccw: Fires when the piece is rotated counterclockwise using initial DAS.
    • triggers.phase.initial_rotated_cw: Fires when the piece is rotated clockwise using initial DAS.
    • triggers.phase.line_cleared: Fires after the line is erased for a line clear, but before the lines above are shifted. Optional parameters allow the trigger to be conditional based on different conditions, such as the player's score or how many lines were cleared simultaneously. line_cleared score=260, line_cleared combo=7...
    • triggers.phase.line_cleared.combo: Expression defining how many combos will fire this trigger. 7..., 3,6,9..., 10-15. (Default: <any>)
    • triggers.phase.line_cleared.n: Expression defining how many line clears will fire this trigger. 7..., 3,6,9..., 10-15. (Default: <any>)
    • triggers.phase.line_cleared.score: Expression defining which score milestones will fire this trigger. 7..., 3,6,9..., 10-15. (Default: <any>)
    • triggers.phase.line_cleared.y: Expression defining which rows will fire this trigger. 7..., 3,6,9..., 10-15. (Default: <any>)
    • triggers.phase.pickup_collected: Fires when a pickup is collected. any, snack, cake
    • triggers.phase.piece_written: Fires when the piece is written, but before any boxes are made or lines are cleared. Optional parameters allow the trigger to be conditional based on different conditions, such as the current combo or how many pieces have been placed. piece_written combo=0,1,2, piece_written n=4,11,18...
    • triggers.phase.piece_written.combo: Expression defining which combo values will fire the trigger. 7..., 3,6,9..., 10-15. (Default: <any>)
    • triggers.phase.piece_written.n: Expression defining which pieces will fire the trigger. 7..., 3,6,9..., 10-15. (Default: <any>)
    • triggers.phase.rotated_180: Fires when the piece is flipped.
    • triggers.phase.rotated_ccw: Fires when the piece is rotated counterclockwise.
    • triggers.phase.rotated_cw: Fires when the piece is rotated clockwise.
    • triggers.phase.start: Fires after the initial coundown finishes, when the player can start playing.
    • triggers.phase.timer_0: Fires when timer 0 times out. Also available are timer_1, timer_2, timer_3, timer_4, timer_5, timer_6, timer_7, timer_8, timer_9,
    • triggers.effect: Effect caused by the trigger. advance_spears, insert_line tiles_key=0
    • triggers.effect.add_carrots: Adds one or more carrots to the playfield. add_carrots count=2 size=large
    • triggers.effect.add_carrots.count: How many carrots appear during a single 'add carrots' effect. (Default: 1)
    • triggers.effect.add_carrots.duration: Duration in seconds that the carrot remains onscreen. (Default: 8)
    • triggers.effect.add_carrots.size: Carrot size. small, medium, large, xl. (Default: medium)
    • triggers.effect.add_carrots.smoke: Size of the smoke cloud. none, small, medium, large. (Default: small)
    • triggers.effect.add_carrots.x: Restricts which columns the carrots appear on, where '0' is the leftmost column of the playfield. For large carrots, this corresponds to the leftmost column of the carrot. 3, 2,4,6, 3-5 (Default: <all>)
    • triggers.effect.add_moles: Adds one or more moles to the playfield. add_moles count=2 reward=seed
    • triggers.effect.add_moles.count: How many moles appear during a single 'add moles' effect. (Default: 1)
    • triggers.effect.add_moles.home: Restricts which types of tiles moles can appear: any, veg, box, surface, cake or hole. (Default: any)
    • triggers.effect.add_moles.y: Restricts which rows the moles appear on, where '0' is the bottom row of the playfield and '16' is the top. (Default: <any>)
    • triggers.effect.add_moles.x: Restricts which columns the moles appear on, where '0' is the leftmost column of the playfield. (Default: <any>)
    • triggers.effect.add_moles.dig_duration: How many turns/seconds/cycles the moles dig for. (Default: 3)
    • triggers.effect.add_moles.reward: Reward the moles dig up. seed, star. (Default: star)
    • triggers.effect.add_onion: Adds an onion to the playfield. add_onion dddennn.
    • triggers.effect.add_onion[0]: String representing states the onion goes through, such as ..dddddennnn. .: 'None' state. The onion is underground. d: 'Day' state. The onion is dancing ominously. e: 'Day End' state. The onion raises their arms in warning. n: 'Night' state. The onion is in the sky, and the puzzle is cast in darkness.
    • triggers.effect.add_sharks: Adds one or more sharks to the playfield. add_sharks size=small count=3 patience=5
    • triggers.effect.add_sharks.count: How many sharks appear during a single 'add sharks' effect. (Default: 1)
    • triggers.effect.add_sharks.home: Restricts which types of tiles sharks can appear: any, veg, box, surface, cake or hole. (Default: any)
    • triggers.effect.add_sharks.y: Restricts which rows the sharks appear on, where '0' is the bottom row of the playfield and '16' is the top. (Default: <any>)
    • triggers.effect.add_sharks.x: Restricts which columns the sharks appear on, where '0' is the leftmost column of the playfield. (Default: <any>)
    • triggers.effect.add_sharks.patience: How many turns/seconds/cycles the shark waits before disappearing. (Default: <forever>)
    • triggers.effect.add_sharks.size: Size (and appetite) of the shark. small, medium, large. (Default: medium)
    • triggers.effect.add_spears: Adds one or more spears to the playfield. add_spears sizes=X6,l4r4 y=12-16
    • triggers.effect.add_spears.sizes: List of String sizes, like 'x5', 'l3', 'l2r4' or 'R8'. The letters 'l' and 'r' refer to spears emerging from the left or right sides. Capital letters are used for wide spears. The number corresponds to the spear's length in cells. x5, l3, l2r4, R8`. (Default: x4)
    • triggers.effect.add_spears.count: How many spears appear during a single 'add spears' effect. (Default: 1)
    • triggers.effect.add_spears.duration: How long the spears wait before disappearing. (Default: <forever>)
    • triggers.effect.add_spears.y: Restricts which rows the spears appear on, where '0' is the bottom row of the playfield and '16' is the top. (Default: <any>)
    • triggers.effect.advance_moles: Advances all moles on the playfield, allowing them to dig up pickups.
    • triggers.effect.advance_onion: Advances the day/night cycle of any onions on the playfield.
    • triggers.effect.advance_sharks: Advances all sharks on the playfield, making them appear/disappear.
    • triggers.effect.advance_spears: Advances all spears on the playfield, making them appear/disappear.
    • triggers.effect.clear_filled_lines: Clears any filled lines on the playfield. This normally has no effect, as filled lines on the playfield are automatically cleared. But it can result in interesting behavior when combined with effects which prevent or delay these automatic line clears.
    • triggers.effect.clear_filled_lines.force: Line clears will ignore any 'blocks during' conditions such as 'filled_line_clear_delay' or 'filled_line_clear_max'. (Default: false)
    • triggers.effect.insert_line: Inserts a new line. insert_line count=2 tiles_keys=0,1
    • triggers.effect.insert_line.count: Number of lines to insert. (Default: 1)
    • triggers.effect.insert_line.tiles_keys: Keys corresponding to sets of tiles in LevelTiles for the tiles to insert. 0, 1,2,3. (Default: [])
    • triggers.effect.remove_carrots: Removes one or more carrots from the playfield. remove_carrots 3
    • triggers.effect.remove_carrots[0]: Number of carrots to remove. (Default: 1)
    • triggers.effect.remove_onion: Removes the onion from the playfield.
    • triggers.effect.remove_spears: Removes one or more spears from the playfield. remove_spears 3
    • triggers.effect.remove_spears[0]: The number of spears to remove. (Default: 1)
    • triggers.effect.rotate_next_pieces: Rotates one or more pieces in the piece queue. rotate_next_pieces ccw 0 0
    • triggers.effect.rotate_next_pieces[0]: Direction to rotate. cw, ccw, 180, none. (Default: none)
    • triggers.effect.rotate_next_pieces[1]: First piece index in the queue to rotate. (Default: 0)
    • triggers.effect.rotate_next_pieces[2]: Last piece index in the queue to rotate. (Default: 999999)

Ideas

  • blocks_start: preset
  • lose_condition: block_grade 50, combo_grade 70, speed_grade 80
  • next_queue: Behavior of the next queue. untrust 10, untrust 50, double_l, nice_pair 80
  • piece_types:
    • Vegetable pieces, veg_j, veg_o, veg_p
    • Trominos, c, k
⚠️ **GitHub.com Fallback** ⚠️