Howto:Creating a simple modding framework
Jump to navigation
Jump to search
This article is a stub. You can help the wiki by expanding it. |
Status
Objective
List of addons
- tanker.nas
- tutorials
- fgcamera
- advanced weather
- bombable
Background
Directory Structure
Mods should be using their own directory structure, resembling $FG_ROOT (the base package), e.g.:
- Aircraft
- GUI
- Textures
- Sounds
- Nasal
etc
Requirements
- register hooks to invoke callbacks for specific simulator/addon events (pause/unpause etc)
- mutual dependencies
Versioning
See FlightGear Version Check for the main article about this subject. |
Prototype
The protoype will be set up like this:
- an optional Nasal submodule stored in $FG_ROOT/Nasal/modding
- mods live under $FG_ROOT/Mods, each in its own folder
- each mod folder's structure will basically resemble the structure of the base package, with its sub-folders for resources like scripts, textures, sounds etc
- each mod will have a top-level
specs.mod
file - each
specs.mod
file is a conventional Nasal file that inherits from an interface class living in the Mod namespace - the
specs.mod
file implements routines for enabling/disabling and configuring the mod
The loader will traverse $FG_ROOT/Mods to obtain a list (vector) of directories.
For each directory found, it will use io.load_nasal() to call the specs.mod
file for that mode
In turn, each specs.mod
file will register itself, e.g. to add menubar items and register GUI dialogs etc
Proof of Concept
The following snippet of code assumes that you put it into $FG_ROOT/Nasal/mod/mod.nas In addition, you need to add a folder to $FG_ROOT named Mods, beneath this folder you can add other folders - with each folder being treated as a separate "mod".
diff --git a/Mods/one/mod.specs b/Mods/one/mod.specs
new file mode 100644
index 0000000..c1b3d8f
--- /dev/null
+++ b/Mods/one/mod.specs
@@ -0,0 +1 @@
+print("Mod 1 registered");
diff --git a/Mods/three/mod.specs b/Mods/three/mod.specs
new file mode 100644
index 0000000..c1b3d8f
--- /dev/null
+++ b/Mods/three/mod.specs
@@ -0,0 +1 @@
+print("Mod 3 registered");
diff --git a/Mods/two/mod.specs b/Mods/two/mod.specs
new file mode 100644
index 0000000..c1b3d8f
--- /dev/null
+++ b/Mods/two/mod.specs
@@ -0,0 +1 @@
+print("Mod 2 registered");
##
# $FG_ROOT/Nasal/mod/loader.nas
var ModdingRegistry = {};
var ModdingInterface = {
new: func() {},
del: func() {},
register: func(name) {
var slotNotEmpty = contains(ModdingRegistry, name);
if (slotNotEmpty) {
print("Warning: Overwriting/re-adding mod:", name);
ModdingRegistry[name].del(); # invoke the destructor of the mod
# ModdingRegistry[name] =
}
},
};
var fgroot = getprop("/sim/fg-root");
var modFolder = fgroot ~ '/'~ 'Mods/';
# http://wiki.flightgear.org/Nasal_library#directory.28.29
var modDirectories = directory( modFolder );
# debug.dump( modDirectories );
foreach(var mod; modDirectories) {
print("Mod directory found:", mod);
var entrypoint = modFolder ~ mod ~ '/mod.specs';
print("Trying to load:", entrypoint,"\n");
io.load_nasal( entrypoint );
}
## invoke:
# init code
# setup code
# loading code
# clean up code