HScript Basics - SlightlySimple/FNF-Restructure-Engine GitHub Wiki
Restructure Engine comes with HScript support, allowing you to run code from outside the game to affect it. All scripts have the file extension ".hscript"
Script Types
In-Game
- Global scripts, which are run on every song, are stored in the "data/autorun" folder.
- Song-specific scripts are stored in the folder where the song's charts are. A song will attempt to load every script in this folder. Note that scripts in subfolders of a song's charts folder will not be loaded, which may be useful if you want to manually load them with other scripts.
- Song group scripts are stored in the folder where the song's charts folder is, if that folder isn't the "data/songs" folder itself. For example, if the charts are in "data/songs/week1/fresh," these scripts would be inside "data/songs/week1"
- Scripts for characters, stages, noteskins, events, and note types are stored in the folder where the respective element's JSON file is, and have the same name as the element.
- Scripts can also manually load other script files.
In menus
Menu scripts are stored in "data/states," except for week-specific scripts which are stored in the folder with the week's JSON file, and have the same name.
Script Functions
create()
is run right after the game and it's scripts are initialized.update(elapsed)
is run at the start of the game's update function, withelapsed
being the time (in seconds) since the function was last run.updatePost(elapsed)
is run at the end of the game's update function.beatHit()
is run on every beat. You can usegame.curBeat
to get the current beat.stepHit()
is run on every step. You can usegame.curStep
to get the current step.startCountdown()
is run when the countdown is started.countdownTick()
is run on every tick of the countdown. You can usegame.countdownProgress
to get the current tick.playSong()
is run when the song starts.endSong()
is run when the song ends.onNoteSpawned(newNote)
is run every time a note is spawned, withnewNote
being the note in question.onSustainSpawned(newSustain, newNote)
is run every time a sustain note is spawned, withnewSustain
being the note in question andnewNote
being the note it's connected to.noteHit(note)
is run when a note was hit, whether it was hit by the player or the opponent.note
is the note in question.sustainHit(note)
is run on every tick a sustain note is being hit, whether it's being hit by the player or the opponent.note
is the note in question.noteMissed(note)
is run when a note was missed.note
is the note in question.sustainMissed(note)
is run when a sustain note was missed.note
is the note in question.noNoteHit(hitNote)
is run when a note key was pressed, but no note was hit.hitNote
is the column associated with the key that was pressed.noteSplash(note, newSplash)
is run when a note splash is spawned.note
is the note that was hit, andnewSplash
is the spawned note splash.onEvent(event)
is run when an event is triggered, ONLY on the script connected to that event.event
is the event in question.onAnyEvent(event)
is run when an event is triggered, on every script.event
is the event in question.onCustomEvent(type, event)
is run when the "custom" event is triggered, on every script.type
is the type of the event, andevent
is the event in question.
Common variables and functions
PlayState
is used to access anything in the PlayState class, whilegame
is used to access the current instance of that class.game.player1
is the player character (boyfriend,)game.player2
is the opponent (dad,) andgame.gf
is the girlfriend.game.allCharacters
is an array that stores all characters, and can be used when there are more than three characters to access the additional ones. For example, if you added a second opponent as a fourth character, you would usegame.allCharacters[3]
game.stage
is the current stage and all it's associated data, withgame.stage.pieces
being a map of the sprites that make up the stage. Note that in a stage script, you can usestage
andstage.pieces
instead. For example, to access the floor of the default stage, you would usegame.stage.pieces["stagefront"]
game.songName
is the current song name as it's displayed in all UI elements.PlayState.songId
is the filename of the current song.PlayState.songIdShort
is the filename of the current song, without any preceding folders if there are any.PlayState.inStoryMode
is whether or not the player is in story mode.PlayState.storyProgress
is which song of the week the player is on.PlayState.firstPlay
is whether or not the song has actually started since initially loading. This is used for cutscenes, to prevent them from playing again when a player dies or restarts the current song.game.canStartCountdown
is used to control whether the countdown can start.game.canEndSong
is used to control whether the post-song events can happen. Both of these are used for cutscenes, and neither of them will prevent thestartCountdown
andendSong
functions from triggering in scripts.game.startCountdown()
andgame.endSong()
can be used to manually start the countdown or end the song after a cutscene.game.endingSong
says whether the song has attempted to end at least once, even ifgame.canEndSong
was false. It can be used in functions that trigger both before the start and at the end of a song, to determine which is currently happening.