Skip to content

Data Flow and Persistence

Relevant source files

Purpose: This document explains how TajsMod manages configuration data, runtime state, and persistent storage. It covers the flow of data from disk to memory to UI, the write-through caching strategy, and the signal-based communication patterns used to keep state synchronized across components.

For information about the overall architecture and component initialization, see Core Architecture. For details on individual manager components that consume configuration, see Utility Manager Components.


TajsMod uses a centralized configuration system built around the TajsModConfigManager class, which manages persistent settings stored in a JSON file.

Sources:

The configuration file user://tajs_mod_config.json contains a flat dictionary of key-value pairs. The DEFAULT_CONFIG constant defines all recognized keys with their default values.

CategoryExample KeysDefault ValueType
Node Managementnode_limit400int (-1 for unlimited)
Featurescommand_palette_enabledtruebool
wire_drop_menu_enabledtruebool
goto_group_enabledtruebool
Visualsextra_glowfalsebool
glow_intensity2.0float
ui_opacity100.0float (0-100)
Audiomute_on_focus_losstruebool
background_volume0.0float (0-100)
Debugcustom_boot_screentruebool

Sources:


Key Characteristics:

  1. Three-tier fallback: User config → Defaults → Override parameter
  2. Smart merging: New default keys are automatically added to existing user configs
  3. Permissive loading: Extra keys not in DEFAULT_CONFIG are preserved (e.g., wire_colors_hex)

Sources:

Configuration Writing (Write-Through Pattern)

Section titled “Configuration Writing (Write-Through Pattern)”

Write-Through Guarantee: Every call to set_value() immediately writes to disk. There is no manual save operation or commit phase.

Sources:

Example Code Location: mod_main.gd L467-L470

Example 2: Toggle Feature via Command Palette

Section titled “Example 2: Toggle Feature via Command Palette”

Example Code Location: extensions/scripts/palette/default_commands.gd L293-L308

Sources:


TajsMod maintains state in three primary locations: the configuration dictionary, the Globals singleton, and individual manager instances.

Sources:

The base game provides a Globals autoload singleton that TajsMod extends to add custom properties. These properties provide game-wide access to mod state.

Extended Globals Properties:

PropertyTypePurposeSource
custom_node_limitintOverrides node spawn limit (-1 = unlimited)extensions/scripts/globals.gd
select_all_enabledboolControls Ctrl+A shortcutextensions/scripts/globals.gd
custom_upgrade_multiplierintMultiplier for Ctrl+click upgradesextensions/scripts/globals.gd

Synchronization Example:

Sources:

Each feature manager maintains its own state, initialized from config during setup:

Key Pattern: Managers receive a reference to ConfigManager and read values as needed, rather than storing copies.

Sources:


Merge Logic Details:

  1. Default keys: Always present, loaded value overrides default
  2. Extra keys: Preserved from file (e.g., custom wire colors)
  3. Missing keys: Automatically added from defaults (forward compatibility)

Sources:

Atomic Write: The JSON file is completely rewritten on every save. GDScript’s FileAccess.WRITE mode truncates the file, so partial writes are not possible if the process completes successfully.

Sources:

Usage Locations:

  1. Settings UI “Reset All Settings” button: mod_main.gd L633-L645
  2. Command Palette “Reset All Settings” command: extensions/scripts/palette/default_commands.gd L589-L600

Sources:


TajsMod uses the base game’s Signals autoload to communicate state changes across components without tight coupling.

The Signals.notify signal is used throughout the mod to display user feedback:

Signal Definition: notify(icon: String, text: String)

Common Icons:

  • "check" - Success message
  • "exclamation" - Warning or info
  • "x" - Error message

Example Usage:

Notification Log Integration:

The mod extends this pattern by capturing all notifications for history:

Sources:


When a user changes a setting in the UI, the flow is unidirectional and immediate:

Example: mod_main.gd L513-L516

When a command changes a setting, it must also update the UI to reflect the change:

Key Method: sync_settings_toggle(config_key: String)

Implementation: mod_main.gd L1149-L1155

Registry of Toggles: mod_main.gd L61

The _settings_toggles dictionary maps config keys to UI CheckButton instances for later access.

Sources:


These keys have special handling or affect core functionality:

KeyTypeDefaultSpecial Handling
node_limitint400-1 = unlimited. Synced to Globals.custom_node_limit
six_input_containersbooltrueRequires restart. Changes compiled scene structure
custom_boot_screenbooltrueRequires restart. Patches boot scene
extra_glowboolfalseModifies WorldEnvironment in scene tree
ui_opacityfloat100.0Modifies HUD modulate.a in real-time
wire_colors_hexDictionary(none)Custom key not in DEFAULT_CONFIG, preserved across updates

Restart-Required Settings:

TajsMod tracks original values of restart-required settings to show a banner when they change:

Sources:


MethodPurposeReturnsSide Effects
load_config()Load from disk, merge with defaultsvoidPopulates _config
save_config()Write _config to diskvoidFile I/O
get_value(key, default_override)Read a config valueVariantNone
set_value(key, value)Write a config valuevoidCalls save_config()
get_all()Get copy of entire configDictionaryNone
reset_to_defaults()Delete file, restore defaultsvoidFile deletion, save

Sources:

Some settings are evaluated lazily at the point of use rather than stored redundantly:

This ensures the displayed state is always current without needing explicit synchronization.

Sources:

Reading from Globals for runtime decisions:

Sources:


TajsMod’s data flow architecture follows these principles:

  1. Centralized Configuration: Single ConfigManager instance owns all persistent settings
  2. Write-Through Persistence: Every set_value() immediately writes to disk (no commit phase)
  3. Dual State Locations: Configuration in ConfigManager, runtime state in Globals and managers
  4. Signal-Based Communication: Signals autoload decouples state changes from their effects
  5. Bidirectional Sync: Commands and UI can both modify settings, with explicit sync calls to keep UI updated
  6. Smart Merging: New defaults are automatically added to existing configs on load
  7. Permissive Storage: Extra keys not in defaults are preserved (enables extensibility)

Key Files: