Friday Night Funkin' Cookbook
Friday Night Funkin' CookbookAdvancedScripted Classes

Scripted Classes

Reading time: 3.5 minutes

Funkin's implementation of HScript uses a system of scripted classes. To create a scripted class, create an .hxc file in your mods/mymod/scripts/ folder, and, using Haxe syntax, create a new class which extends the base class for the type of object you are scripting, like so:

// Remember to import each class you want to reference in your script!
import funkin.play.song.Song;

// Choose a name for your scripted class that will be unique
// Also specify the class you are extending, we choose Song here.
// This script's behaviors will extend the default behavior of the song.
class BallisticSong extends Song {
    public function new() {
        // You have to call the super constructor for the class you are extending, which may have different parameters.
        // Check the specific documentation for more info.
        super('ballistic');
    }
}

Extending Scripted Classes

Since update 0.8.2, a scripted class can also extend another scripted class, rather than only a native scriptable class. This is useful for sharing behavior between multiple scripted classes, like a base character that several custom characters all build on.

// MyBaseChar.hxc
// A scripted class that extends a native class, as usual.
import funkin.play.character.SparrowCharacter;

class MyBaseChar extends SparrowCharacter {
  public function new() {
    super();
  }

  // Shared behavior for all characters based on this script.
  function onDance() {
    // ...
  }
}
// MyChar.hxc
// This scripted class extends the scripted class above.
import MyBaseChar;

class MyChar extends MyBaseChar {
  public function new() {
    // The superclass is itself a scripted class; you still call its constructor.
    super();
  }

  override function onDance() {
    // Call the inherited scripted function first.
    super.onDance();
    // Then add custom behavior.
    // ...
  }
}

There are a few rules to keep in mind:

  • If your class defines a new() constructor, you must call super() inside it, just like with a native superclass. If you don't define a constructor at all, the superclass's constructor is called automatically.
  • A scripted class can't have an instance field with the same name as a field in its superclass — Polymod throws an error on that conflict.
  • Scripted functions and fields are inherited through the entire chain of scripted superclasses, so you can extend a scripted class that itself extends another scripted class.
  • Extending a native scriptable class (as shown in the example above) still works exactly as before.

List of Scriptable Classes

There is a predefined list of classes which the game has set up to be scriptable, and will automatically load and execute when relevant. More of these will be added in the future.

  • funkin.play.song.Song for providing unique behavior to custom songs, including playing cutscenes and other stuff. See Scripted Songs.

  • funkin.play.character.BaseCharacter for providing unique behavior to custom characters (such as playing custom animations in certain circumstances). See Scripted Characters.

    • Note that you need to choose the correct subclass of this class for the animation type of your character!
      • funkin.play.character.SparrowCharacter is used for characters that have Sparrow spritesheet animations.
      • funkin.play.character.MultiSparrowCharacter is used for characters that have several Sparrow spritesheet animations to combine into one character.
      • funkin.play.character.PackerCharacter is used for characters that have Packer spritesheet animations.
      • funkin.play.character.AnimateAtlasCharacter is used for characters that have Adobe Animate texture atlases.
      • funkin.play.character.BaseCharacter has empty stubs for all the rendering and animation handlers, and is only useful for people who want to reimplement their character's animation system by hand.
  • funkin.play.stage.Stage for providing unique behavior to custom stages, such as creating custom moving props and defining when props animate or when sound effects play in sync with the stage. See Scripted Stages.

  • funkin.ui.story.Level for providing unique behavior to levels in Story Mode. See Scripted Story Levels.
  • funkin.play.notes.notekind.NoteKind for providing unique visuals and behavior to certain kinds of notes, which can then be placed in the Chart Editor. See Custom Note Kinds.
  • funkin.play.event.SongEvent for creating custom Song Events, which you can place in the Chart Editor and which perform game actions when they are reached. See Custom Song Events
  • funkin.ui.freeplay.charselect.PlayableCharacter for providing unique behavior to custom playable characters. See Scripted Playable Characters
  • funkin.ui.freeplay.FreeplayStyle for defining the sprites and colors used by the Freeplay menu when a given character is selected. See [WIP]
  • funkin.play.notes.notestyle.NoteStyle for modifying the behavior of custom note styles. See [WIP]
  • funkin.play.cutscene.dialogue.Conversation for providing unique behavior to custom dialogue conversations. See Dialogue Cutscenes
  • funkin.play.cutscene.dialogue.DialogueBox for providing unique behavior to custom dialogue boxes used in conversations. See Dialogue Cutscenes
  • funkin.play.cutscene.dialogue.Speaker for providing unique behavior to custom speakers used in conversations. See Dialogue Cutscenes
  • funkin.ui.freeplay.Album for defining custom behavior for Freeplay Albums. See [WIP]

There is also funkin.modding.module.Module for custom scripted Modules, which are scripts which receive events everywhere, rather than only in a specific context. See Scripted Modules for more information on how these work.

There are also scripted classes are also set up to be scriptable, but will only be useful if they're accessed from another script. Expect more of these to be added in the future.

  • funkin.graphics.FunkinSprite for basic static or animated sprites. Allows usage of filters on it. Supports loading various frames types, such as the basic SparrowV2 spritesheets format, packer and Adobe Animate texture atlases.
  • flixel.group.FlxSpriteGroup for groups of sprites which are included inside a state and manipulated together
  • funkin.group.FunkinGroup for groups of sprites which are included inside a state and manipulated together. Similar to FlxSpriteGroup, but adds improved functionality for group modification actions.
  • funkin.ui.MusicBeatState for groups of sprites which represents a given game state. Includes additional utilities for handling script events.
  • funkin.ui.MusicBeatSubState for groups of sprites representing a substate of an existing state
  • flixel.addons.display.FlxRuntimeShader for custom GLSL shaders
  • funkin.play.stage.Bopper for sprites which will play an idle animation to the beat of the music when they are part of a Stage.
  • flixel.FlxSprite for basic static or animated sprites. Use this only if you can't use FunkinSprite.
  • flixel.FlxState for basic groups of sprites which represent a given game state. Use this only if you can't use MusicBeatState.
  • flixel.FlxSubState for groups of sprites representing a substate of an existing state

Contributors:
kiry vajiravuth
Herman Khomich
Cameron Taylor
anysad
kade-github
Last modified:
Created:
Category:  Advanced
Tags: