Editor Tooling

This page covers how to extend the Spark Editor with custom tabs, views, and property drawers for your plugin.

The Spark Editor Window

The Spark Editor Window (SparkEditorWindow) is the central hub for managing game data. It uses a tabbed interface where each plugin adds its own tabs.

The window architecture:

  1. Sidebar: Lists all plugin categories and their tabs.

  2. Content Area: Displays the currently selected tab's content.

  3. Inspector Panel: Shows the selected entry's fields for editing.

Tabs are loaded dynamically from plugin manifests.

Creating Custom Editor Tabs

When you create a plugin manifest, you define tabs that appear in the Spark Editor. There are two tab types:

Database Tabs

These show a list of database entries with CRUD (create, read, update, delete) operations. Most plugins use database tabs.

In your plugin manifest, configure a tab with:

  • Tab Type: Database

  • Asset Type: Your entry class (e.g., FactionEntry)

  • Path: The Resources path where entries are stored

The Spark Editor automatically generates the list view, search, filtering, and inspector for database entries. Your entry's fields (with Spark attributes) render automatically.

Plugin Settings Tabs

These show a single settings asset for plugin configuration. Used for plugins that need global settings rather than a list of entries.

In your plugin manifest, configure a tab with:

  • Tab Type: PluginSettings

  • Asset Type: Your settings class (inheriting PluginSettingsBase)

Custom Editor Views

For more control over how your plugin appears in the Spark Editor, implement ISparkPluginViewProvider:

SparkPluginViewProviderBase provides the scaffolding. Override CreateEditorView() to build your custom UI using Unity's UI Toolkit (VisualElements, UXML, USS).

Plugin View Loader

The SparkPluginViewLoader handles dynamic loading of editor views. It finds the correct view provider for each tab based on assembly and type scanning.

Custom Property Drawers

Spark includes several custom property drawers for its attributes. If you need custom rendering for a specific field type in your plugin, create a property drawer:

Built-in Drawers

Spark provides drawers for all its custom attributes:

  • ConditionalFieldDrawer: Shows/hides fields based on conditions.

  • DatabaseEntryDropdownDrawer: Renders entry selection dropdowns.

  • ReadOnlyDrawer: Makes fields non-editable.

  • SectionDrawer: Renders collapsible section headers.

  • SwitchDrawer: Switches field layouts based on another field.

Entry Selector Windows

The SparkDatabaseEntrySelectorWindow is a popup window for selecting database entries. It provides:

  • Search by name

  • Filtering by type

  • Preview of entry details

  • Quick creation of new entries

You can open this window from your custom editor code:

Editor Field Creation

The EditorFields.CreateField() utility creates appropriate editor fields based on the property type. It handles:

  • Primitive types (int, float, string, bool)

  • Unity types (Vector3, Color, Sprite, GameObject)

  • Enum dropdowns

  • Object references

  • Collections (lists, arrays)

  • Custom types with Spark attributes

Use this when building custom editor views to get consistent field rendering.

UI Toolkit Patterns

Spark's editor UI uses Unity's UI Toolkit. Key patterns:

  • UXML templates: Define layout structure.

  • USS stylesheets: Define visual styling.

  • Element querying: root.Q<Label>("my-label") to find elements.

  • Value change callbacks: Bind to field changes for auto-saving.

Extension Data Cleanup

The ExtensionDataCleanupUtility handles orphaned extension data. When a database entry is deleted, its extension data should be cleaned up. This utility scans for extension data whose target entries no longer exist.

Best Practices

  • Use database tabs for entry management. They come with free CRUD, search, and inspector.

  • Only create custom views when you need non-standard UI (graphs, visualizations, drag-and-drop editors).

  • Follow Spark's USS class naming for consistent styling.

  • Use EditorFields.CreateField() for field rendering instead of building fields manually.

  • Always mark assets dirty (EditorUtility.SetDirty()) when modifying them through custom editor code.

  • Test your editor extensions with domain reload enabled to catch static state issues.

Last updated

Was this helpful?