Digging through and reorganizing code

By cyberpuffin, 9 July, 2023

Over the past week or so I've been digging through and reorganizing how the Config and Database are structured.

As an example, the Config.gd autoload script had grown to be over 2,000 lines.  While there are arguably more lines in the code-base for splitting it out and defining classes, the base config file is much cleaner and functions now have a dedicated script to live in.

"""
Configuration singleton
"""
"""
Configuration singleton

autoload: 4

Store and manage configuration data.
"""
extends Node

const AudioConfig = preload("res://Scripts/Data/ConfigAudio.gd")
const FontConfig = preload("res://Scripts/Data/ConfigFont.gd")
const PreferenceConfig = preload("res://Scripts/Data/ConfigPreference.gd")
const ThemeConfig = preload("res://Scripts/Data/ConfigTheme.gd")
const UserDataConfig = preload("res://Scripts/Data/ConfigUserData.gd")
const WindowConfig = preload("res://Scripts/Data/ConfigWindow.gd")

var audio: AudioConfig
var font: FontConfig
var preference: PreferenceConfig
var theme: ThemeConfig
var user_data: UserDataConfig
var window: WindowConfig

func _init() -> void:
	audio = AudioConfig.new()
	font = FontConfig.new()
	preference = PreferenceConfig.new()
	theme = ThemeConfig.new()
	user_data = UserDataConfig.new()
	window = WindowConfig.new()

	add_child(audio)
	add_child(font)
	add_child(preference)
	add_child(theme)
	add_child(user_data)
	add_child(window)

	return

func _ready() -> void:
	Config.check_valid()

func check_valid() -> void:
	"""Validate the read-in values from the config and override as necessary"""
	if !(Config.preference.difficulty in range(
		1, (Config.preference.MAX_DIFFICULTY + 1)
	)):
		Log.error("%s: Config difficulty '%d' is out of supported range." % [
			"Config: check_valid", Config.preference.difficulty
		])
		Config.preference.difficulty = 1
	# TODO: Add further validity checks

Db.gd got a similar treatment and further work is being done to consolidate the theme functions into the new structure.

Change tracking and tracing

So there's a big mess of code, functions spread out across multiple classes, commented out code to deal with the framework upgrade, and the original theme functional sprawl to contend with.

How to track it all?

Git

Revision control is, to me, the first step in any project.  Get an initial state loaded and commited and track from there.  Certain files used in a Godot project don't lend themselves to being tracked in git directly.  A SQLite database or video files, for example.  For these files we have to setup git-lfs.

Git Large File Storage (LFS) replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server like GitHub.com or GitHub Enterprise.

eh? why?

Git, or whatever Revision Control System (RCS) you want to use, tracks changes to files in its repository allowing, among other things, the ability to roll back mistakes or failed experiments.

All this time spent on converting Accessible Sudoku to Godot 4 there has been a branch for the 3.x release.  At any time the 3.x branch can be loaded into a 3.x Godot editor to crank out another build or check how things used to work.

When Godot announced the release of 4.1 the first step, after the new release was installed, was to create a branch from my current commit git checkout -b 4.1.  Which worked out well, as the SQLite addon Accessible Sudoku uses had not released its update yet (https://github.com/2shady4u/godot-sqlite/issues/148).

Close the editor, reset incidental changes, git checkout 4.0, git branch -d 4.1, and load up the 4.0.3 editor.  Carry on with the code tracing and rearrangements and the issue is resolved by 2shady4u a few days later.

Retry 4.1 with the updated addon and all is well.

Code tracing

Now that the engine is stable and code is being tracked we can start walking the code to make sure things are pointing to the correct / new locations and old / deprecated components can be either updated or removed.

Breakpoints

Through each scripts that's autoloaded and the Options scene's main script I've added breakpoints to the start of every function.  At the start of the program, and as each breakpoint is hit, the code in the function can be verified to the latest configuration and the breakpoint can be removed.

Once full functionality is validated breakpoints can be used to identify the functions that are no longer used.

Versions

Godot 4.1

Technology

Comments