Friday Night Funkin' Cookbook
Friday Night Funkin' CookbookExpertMod Packages

Mod Packages

Reading time: 1.5 minute

As your mods complexity increases, with many different scripts (modules, custom objects/states, etc) it is vital to eventually organize this code. You can do this in the same way as regular haxe: Package names.

package kade.hex.modules;

import funkin.modding.module.Module;

// ...

class Hex_Hud extends Module
{
    // ... some code here ...
}

As seen in the code snippet, the module 'Hex_Hud' has the package of 'kade.hex.modules' which will allow for better organization of your code, and to keep stack traces nice and clean.

Referencing modules/scripted classes

Referencing other modules (and also scripts), can be done by using the ModuleHandler, or by creating a scripted version of that object.


import funkin.modding.module.ModuleHandler;

// ...

public override function onStateCreate(event:ScriptEvent):Void
{
    // The first argument is the 'id' of the module (the one used in the constructor *OF* that module)
    var hexHud = ModuleHandler.getModule("Hex_Hud");

    // ... some code using it, the variable acts like a singleton of that module.
}

// ...

Instantiating your own custom scripted class

Since modules are created (instantiated) by the game, they are already accessible via the game itself. But if you want to create your own scripted classes, you can do a couple of things.

Game provided class

If the game already provides it, and your script extends it. It is very simple:

// The FlxTypeSpriteGroup class (base game provided)

import funkin.modding.base.ScriptedFlxSpriteGroup;

// ...

class HEXDialogueBox extends FlxTypedSpriteGroup
{
    // ... dialogue code
}

Then you can simply create this class in a song like so:

import funkin.play.song.Song;
import funkin.play.PlayState;
import funkin.modding.base.ScriptedFlxSpriteGroup;
import funkin.play.PlayStatePlaylist;

class RamSong extends Song {
    var cutscenePlayed = false;

    public override function onCountdownStart(event:CountdownScriptEvent):Void {
        if (!PlayStatePlaylist.isStoryMode)
            cutscenePlayed = true;
        
        if (!cutscenePlayed) {
            event.cancel();

            PlayState.instance.camHUD.visible = false;
            playDialogue();
        }
        super.onCountdownStart(event);
    }


    public function playDialogue() {
        var hexDiag:HEXDialogueBox = ScriptedFlxSpriteGroup.init("HEXDialogueBox"); // this line with instantiate this class (based on its name, or name and package)
        
        // ... setup dialogue code
    }
}

Custom classes

If you created the class yourself, you can simply instance itself with the 'new' operator.

package kade.hex.states;

import funkin.ui.MusicBeatState;

class HexMainMenu extends MusicBeatState {

    // ... surely there is code here
}
import kade.hex.states.HexMainMenu;
import flixel.FlxG;

// ...

public function someFunction() {
    var mm:HexMainMenu = new HexMainMenu();
    FlxG.switchState(mm);
}

// ...

With this knowledge you are now able to reference modules dynamically, and create custom objects.


Contributors:
Kade-gtihub
Last modified:
Created:
Category:  Expert
Tags: