Skip to main content
This page covers the internal architecture of the RollingQuest level editor for advanced users and contributors.

EditorController

The EditorController class (EditorController.cs) is the central orchestrator. It:
  • Manages all editor state (blocks, items, enemies, balls, sections)
  • Handles user input (keyboard, mouse)
  • Coordinates between menus, pools, and property panels
  • Implements ILevelReference for gameplay integration
  • Maintains the LuaScriptsCollection and MessagesManager

Key Responsibilities

EditorLevelSection

Each section is an EditorLevelSection instance containing:
  • SectionId — Unique identifier
  • BlocksBlockNet grid of blocks
  • Balls — List of balls in this section
  • Enemies — List of enemies in this section
  • ThemeModel — Visual theme
  • Music — Background music track
  • DarkMode — Dark mode flag
  • SkyboxGrid — Skybox grid flag
  • LavaPool — Lava pool configuration

Pool System

Element pools (EditorBlocksPool, EditorItemsPool, etc.) inherit from EditorElementSelector<T>:
  • Display a grid of templates from the current theme
  • Handle selection and deselection
  • Support keyboard navigation
  • Auto-close after selection
  • Store element property backups for template copying
The editor uses a singleton menu pattern — only one menu can be active at a time:
When a menu opens:
  1. Camera input is disabled
  2. The menu panel is activated
  3. UI elements are focused for keyboard navigation
When a menu closes:
  1. Camera input is restored (unless another menu opens)
  2. The menu panel is deactivated

Event System

Menus communicate through C# events:
  • OnMainMenuSelectChoice — Main menu button clicks
  • OnElementPropertiesOpenTemplateSelector — Template selection requests
  • OnElementPropertiesOnDirectionChange — Direction changes
  • OnBallStyleSelectorAction — Ball style selection
  • Various OnBackButtonPressed events for navigation

Input Handling

Input is processed in two phases:

UIInputs()

Handles menu shortcuts and escape key. Runs every frame but is blocked when a menu is active.

BlocksInputs()

Handles block manipulation (WASD/EQ movement, clicks, space, backspace, tab). Only runs when no menu is active. Both phases check LoadingEnabled and IsAnyMenuActive before processing.

Score Calculation

Score is calculated lazily:
  1. _scoreInfoDeprecated is set to true when elements change
  2. UpdateScoreInfo() runs in Update() when the flag is set
  3. Iterates all sections, blocks, items, and enemies
  4. Updates the ScoreInfoData struct
  5. The HUD reads the struct for display

Section Management

Sections are stored in:
  • _mainSection — The default section (always exists)
  • _sections — Dictionary of additional sections
Switching sections triggers:
  1. SetCurrentSection() updates _currentSection
  2. ReloadEditor() rebuilds the viewport
  3. Theme and music are reloaded for the new section

Persistence Layer

EditorPersistentState is a static class that stores:
  • Camera transform (position, rotation)
  • Block selector position
  • Level data (full level state)
  • Level path
  • Best editor time
Data is saved on quit/test and restored on load.

Creation Modes

Elements are created with a CreationMode flag: This flag affects template callbacks and initialization behavior.