Repository navigation
HScript api documentation (WIP)
HScript (or Haxe Script) is a way to modify the engine using Haxe code. HScript can be a much more powerful tool compared to Lua scripting. While Lua is restricted to only the main gameplay state (PlayState) and restricted by the built in functions, HScript can be run in almost every state; meaning you could modify (or create) every state. While it may seem daunting at first, especally if you have never used Haxe before, its actually quite simple.
// A simple script that sets bf to 1.5X scale and dad's angle to 45.
function createPost(){
bf.scale.set(1.5, 1.5);
dad.angle = 45;
}In the above example the bf and dad varibles are used to modify the player and opponent. These variables are provided to you to quickly access the characters. However not all variables have shortcuts provided. Below modifies the game camera's angle every beat.
function beatHit(beat){
PlayState.instance.camGame.angle += 15; // Adds 15 to the game angle every beat.
}While this does work, it can be tedious to type out PlayState.instance every time you want to access an instance variable in PlayState so it is common to add a shortcut variable in your scripts
Tip
All callback functions available in Lua scripting can also be used in HScript (updatePost() stepHit() onEvent() etc)
var game:PlayState = PlayState.instance;
function beatHit(beat){
game.camGame.angle += 15; // Adds 15 to the game angle every beat.
}Tip
A list of all the variables in PlayState (the main gameplay state) can be found here.
While the PlayState class is used in the above examples, you will likely want to use other classes in your scripts.
var game:PlayState = PlayState.instance;
var mySprite:FlxSprite;
function createPost(){
mySprite = new FlxSprite();
mySprite.loadGraphic(Paths.image("myImage")); // Loads "myImage.png" in the "images" folder in your mod.
mySprite.screenCenter(); // Place mySprite in the center of the screen.
add(mySprite); // Add the sprite to the game.
}Commonly used classes, like FlxSprite, are imported by default however if you want to use another class, you will need to import it yourself.
// Imports should be the first things in your script.
import game.Boyfriend; // import the `Boyfriend` class
var exampleCharacter:Boyfriend;
function createPost(){
exampleCharacter = new Boyfriend(100, 100, "mom"); // Adds a new `Boyfriend` for `mom` at 100, 100.
// All the setup stuff is done within the `Boyfriend` class so you dont need to worry about it in this example!
add(exampleCharacter); // Add to the game.
}Below is a list of all the classes that are imported for you.
| Imported As | Class Package | Notes |
|---|---|---|
| FlxG | flixel.FlxG | |
| FlxSprite | flixel.FlxSprite | |
| FlxSound | flixel.sound.FlxSound | |
| FlxCamera | flixel.FlxCamera | |
| FlxMath | flixel.math.FlxMath | |
| FlxTimer | flixel.util.FlxTimer | |
| FlxTween | flixel.tweens.FlxTween | |
| FlxEase | flixel.tweens.FlxEase | |
| FlxTweenUtil | modding.helpers.FlxTweenUtil | |
| FlxText | flixel.text.FlxText | |
| FlxColor | modding.helpers.FlxColorHelper |
FlxColor is an abstract and cannot be used at runtime.This is a wrapper class with some functions from FlxColor, such as fromRGB().Int should be used when declaring a type. |
| Assets | openfl.utils.Assets | |
| LimeAssets | lime.utils.Assets | |
| Math | Math | |
| Std | Std | |
| StringTools | StringTools | |
| FlxRuntimeShader | flixel.addons.display.FlxRuntimeShader | |
| CustomShader | shaders.custom.CustomShader | |
| ShaderFilter | openfl.filters.ShaderFilter | |
| Json | haxe.Json | |
| FlxSpriteGroup | flixel.group.FlxSpriteGroup | |
| FlxAnimate | flxanimate.FlxAnimate | |
| FlxAtlasSprite | game.FlxAtlasSprite | |
| Map | haxe.ds.StringMap | Alias for StringMap
|
| StringMap | haxe.ds.StringMap | |
| IntMap | haxe.ds.IntMap | |
| EnumValueMap | haxe.ds.EnumValueMap | |
| ObjectMap | haxe.ds.ObjectMap | |
| PlayState | states.PlayState | |
| Conductor | game.Conductor | |
| Paths | Paths | |
| CoolUtil | utilities.CoolUtil | |
| Options | utilities.Options | |
| Character | game.Character | |
| Alphabet | ui.Alpahbet | |
| CustomState | modding.custom.CustomState | Will become deprecated once better custom class support is added |
| CustomSubstate | modding.custom.CustomSubstate | Will become deprecated once better custom class support is added |
| DiscordClient | utilities.DiscordClient | |
| Polymod | polymod.Polymod | |
| PolymodAssets | polymod.PolymodAssets | |
| ModList | modding.ModList | |
| PlayfieldRenderer | modcharting.PlayfieldRenderer | |
| ModchartUtil | modcharting.ModchartUtil | |
| Modifier | modcharting.Modifier | |
| NoteMovement | modcharting.NoteMovement | |
| NotePositionData | modcharting.NotePositionData | |
| ModchartFile | modcharting.ModchartFile |
Note
Any function or type that is auto imported in Haxe is auto imported in HScript (trace() Int String etc.)
A complete list of all the classes can be found here
Note
Note that classes marked as abstract can not be used due to not existing at runtime.
Although support is currently limited, a very powerful tool in hscript is the ability to extend a class. There are many times you would want to add or override functionality to an already existing class that you simply would not easily be able to do with lua.
Below is a simple example of a script that makes a class that extends FlxSprite to make it move in a circle.
class CircleSprite extends FlxSprite{
var iTime:Float = 0;
override function update(elapsed:Float):Void{
super.update(elapsed);
iTime += elapsed;
x = (FlxG.width / 2) + Math.sin(iTime) * 360;
y = (FlxG.height / 2) + Math.cos(iTime) * 360;
}
}
var game:PlayState = PlayState.instance;
var sprite:CircleSprite;
function createPost(){
sprite = new CircleSprite();
sprite.loadGraphic(Paths.image("icons/dad-icons")); // Uses the dad healthicon sheet as a graphic in this example.
sprite.scrollFactor.set(0, 0);
add(sprite);
}Important
Custom classes have the following limitations:
- Can only extend classes in the following packages:
flixelgamemoddingstatessubstatesui
- Functions can only be overwritten if the class you are extending has the function.
For example, say you wanted to override theupdatefunction inFlxText. You would be unable to do so due toFlxTextnot having anupdatefunction and it being located inFlxSpriteinstead; this is due to a limitation of hscript-improved. -
flixel.graphics.frames.FlxFramecan not be extended due to some weird macro issues. - Custom Classes can not extend custom classes.
- Custom classes can only have instance variables/functions, not static.
- The
privatemodifier is not supported.