Skip to content

Commit c58d6a4

Browse files
committed
sort functions and add doc comments
1 parent 1529a82 commit c58d6a4

File tree

2 files changed

+64
-25
lines changed

2 files changed

+64
-25
lines changed

addons/mod_loader/mod_data.gd

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,41 @@
11
extends Resource
22
class_name ModData
33

4-
# These 2 files are always required by mods.
5-
# mod_main.gd = The main init file for the mod
6-
# manifest.json = Meta data for the mod, including its dependancies
4+
## Stores and validates all Data required to load a mod successfully
5+
## If some of the data is invalid, [member is_loadable] will be false
6+
77
const LOG_NAME := "ModLoader:ModData"
88

9+
## These 2 files are always required by mods.
10+
## [i]mod_main.gd[/i] = The main init file for the mod
11+
## [i]manifest.json[/i] = Meta data for the mod, including its dependencies
912
enum required_mod_files {
1013
MOD_MAIN,
1114
MANIFEST,
1215
}
1316

14-
var dir_name := "" # technically a duplicate with ModDetails
17+
## Directory of the mod. Has to be identical to [method ModDetails.get_mod_id]
18+
var dir_name := ""
19+
## Path to the Mod's Directory
1520
var dir_path := ""
21+
## False if any data is invalid
1622
var is_loadable := true
23+
## Is increased for every mod depending on this mod. Highest importance is loaded first
1724
var importance := 0
25+
## Contents of the manifest
1826
var details: ModDetails
19-
var config := {} # updated in _load_mod_configs
27+
## Updated in _load_mod_configs
28+
var config := {}
2029

21-
# debug
30+
## only set if DEBUG_ENABLE_STORING_FILEPATHS is enabled
2231
var file_paths := []
2332

2433

2534
func _init(_dir_path: String) -> void:
2635
dir_path = _dir_path
2736

2837

29-
# Load meta data from a mod's manifest.json file
38+
## Load meta data from a mod's manifest.json file
3039
func load_details(modLoader = ModLoader) -> void:
3140
if not has_required_files():
3241
return
@@ -48,9 +57,8 @@ func load_details(modLoader = ModLoader) -> void:
4857
details = mod_details
4958

5059

60+
## Validates if [member dir_name] matches [method ModDetails.get_mod_id]
5161
func is_mod_dir_name_same_as_id() -> bool:
52-
# Check that the mod ID is correct. This will fail if the mod's folder in
53-
# "res://mods-unpacked" does not match its full ID, which is `namespace.name`
5462
var manifest_id = details.get_mod_id()
5563
if dir_name != manifest_id:
5664
ModLoader.mod_log('ERROR - Mod directory name "%s" does not match the data in manifest.json. Expected "%s"' % [ dir_name, manifest_id ], LOG_NAME)
@@ -59,6 +67,7 @@ func is_mod_dir_name_same_as_id() -> bool:
5967
return true
6068

6169

70+
## Confirms that all files from [member required_mod_files] exist
6271
func has_required_files() -> bool:
6372
var file_check = File.new()
6473

@@ -71,10 +80,12 @@ func has_required_files() -> bool:
7180
return is_loadable
7281

7382

83+
## Validates if details are set
7484
func has_details() -> bool:
7585
return not details == null
7686

7787

88+
## Converts enum indices [member required_mod_files] into their respective file paths
7889
func get_required_mod_file_path(required_file: int) -> String:
7990
match required_file:
8091
required_mod_files.MOD_MAIN:

addons/mod_loader/mod_details.gd

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
extends Resource
2+
## Stores and validates contents of the manifest set by the user
23
class_name ModDetails
34

5+
6+
## Mod name.
7+
## Validated by [method is_name_or_namespace_valid]
48
var name := ""
9+
## Mod namespace, most commonly the main author.
10+
## Validated by [method is_name_or_namespace_valid]
511
var namespace := ""
6-
var version_number := "v0.0.0"
12+
## Semantic version. Not a number, but required to be named like this by Thunderstore
13+
## Validated by [method is_semver_valid]
14+
var version_number := "0.0.0"
715
var description := ""
816
var website_url := ""
17+
## Used to determine mod load order
918
var dependencies := [] # Array[String]
1019

1120
var authors := [] # Array[String]
21+
## only used for information
1222
var compatible_game_version := [] # Array[String]
23+
## only used for information
24+
var incompatibilities := [] # Array[String]
1325
var tags := [] # Array[String]
1426
var description_rich := ""
15-
var incompatibilities := [] # Array[String]
1627
var image: StreamTexture
1728

29+
1830
## Required keys in a mod's manifest.json file
1931
const REQUIRED_MANIFEST_KEYS_ROOT = [
2032
"name",
@@ -36,6 +48,8 @@ const REQUIRED_MANIFEST_KEYS_EXTRA = [
3648
]
3749

3850

51+
## Takes the manifest as [Dictionary] and validates everything.
52+
## Will return null if something is invalid.
3953
func _init(manifest: Dictionary) -> void:
4054
if (not dict_has_fields(manifest, REQUIRED_MANIFEST_KEYS_ROOT) or
4155
not dict_has_fields(manifest.extra, ["godot"]) or
@@ -50,7 +64,6 @@ func _init(manifest: Dictionary) -> void:
5064
not is_semver_valid(version_number)):
5165
return
5266

53-
5467
description = manifest.description
5568
website_url = manifest.website_url
5669
dependencies = manifest.dependencies
@@ -66,14 +79,21 @@ func _init(manifest: Dictionary) -> void:
6679
# image StreamTexture
6780

6881

82+
## Mod ID used in the mod loader
83+
## Format: {namespace}-{name}
6984
func get_mod_id() -> String:
7085
return "%s-%s" % [namespace, name]
7186

7287

88+
## Package ID used by Thunderstore
89+
## Format: {namespace}-{name}-{version_number}
7390
func get_package_id() -> String:
7491
return "%s-%s-%s" % [namespace, name, version_number]
7592

7693

94+
## A valid namespace may only use letters (any case), numbers and underscores
95+
## and has to be longer than 3 characters
96+
## /^[a-zA-Z0-9_]{3,}$/
7797
static func is_name_or_namespace_valid(name: String) -> bool:
7898
var re := RegEx.new()
7999
re.compile("^[a-zA-Z0-9_]*$") # alphanumeric and _
@@ -90,29 +110,37 @@ static func is_name_or_namespace_valid(name: String) -> bool:
90110
return true
91111

92112

93-
func _get_string_from_dict(dict: Dictionary, key: String) -> String:
94-
if not dict.has(key):
95-
return ""
96-
return dict[key]
97-
98-
99-
func _get_array_from_dict(dict: Dictionary, key: String) -> Array:
100-
if not dict.has(key):
101-
return []
102-
return dict[key]
103-
104-
113+
## A valid semantic version should follow this format: {mayor}.{minor}.{patch}
114+
## reference https://semver.org/ for details
115+
## /^[0-9]+\\.[0-9]+\\.[0-9]+$/
105116
static func is_semver_valid(version_number: String) -> bool:
106117
var re := RegEx.new()
107118
re.compile("^[0-9]+\\.[0-9]+\\.[0-9]+$")
108119

109120
if re.search(version_number) == null:
110-
printerr('Invalid semantic version: "%s". You may only use numbers and periods in this format {mayor}.{minor}.{patch}' % version_number)
121+
printerr('Invalid semantic version: "%s". ' +
122+
'You may only use numbers and periods in this format {mayor}.{minor}.{patch}' % version_number)
111123
return false
112124

113125
return true
114126

115127

128+
## Returns an empty String if the key does not exist
129+
static func _get_string_from_dict(dict: Dictionary, key: String) -> String:
130+
if not dict.has(key):
131+
return ""
132+
return dict[key]
133+
134+
135+
## Returns an empty Array if the key does not exist
136+
static func _get_array_from_dict(dict: Dictionary, key: String) -> Array:
137+
if not dict.has(key):
138+
return []
139+
return dict[key]
140+
141+
142+
## Works like [method Dictionary.has_all],
143+
## but allows for more specific errors if a field is missing
116144
static func dict_has_fields(dict: Dictionary, required_fields: Array) -> bool:
117145
var missing_fields := required_fields
118146

0 commit comments

Comments
 (0)