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, withelapsedbeing 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.curBeatto get the current beat.stepHit()is run on every step. You can usegame.curStepto get the current step.startCountdown()is run when the countdown is started.countdownTick()is run on every tick of the countdown. You can usegame.countdownProgressto 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, withnewNotebeing the note in question.onSustainSpawned(newSustain, newNote)is run every time a sustain note is spawned, withnewSustainbeing the note in question andnewNotebeing 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.noteis 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.noteis the note in question.noteMissed(note)is run when a note was missed.noteis the note in question.sustainMissed(note)is run when a sustain note was missed.noteis the note in question.noNoteHit(hitNote)is run when a note key was pressed, but no note was hit.hitNoteis the column associated with the key that was pressed.noteSplash(note, newSplash)is run when a note splash is spawned.noteis the note that was hit, andnewSplashis the spawned note splash.onEvent(event)is run when an event is triggered, ONLY on the script connected to that event.eventis the event in question.onAnyEvent(event)is run when an event is triggered, on every script.eventis the event in question.onCustomEvent(type, event)is run when the "custom" event is triggered, on every script.typeis the type of the event, andeventis the event in question.
Common variables and functions
PlayStateis used to access anything in the PlayState class, whilegameis used to access the current instance of that class.game.player1is the player character (boyfriend,)game.player2is the opponent (dad,) andgame.gfis the girlfriend.game.allCharactersis 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.stageis the current stage and all it's associated data, withgame.stage.piecesbeing a map of the sprites that make up the stage. Note that in a stage script, you can usestageandstage.piecesinstead. For example, to access the floor of the default stage, you would usegame.stage.pieces["stagefront"]game.songNameis the current song name as it's displayed in all UI elements.PlayState.songIdis the filename of the current song.PlayState.songIdShortis the filename of the current song, without any preceding folders if there are any.PlayState.inStoryModeis whether or not the player is in story mode.PlayState.storyProgressis which song of the week the player is on.PlayState.firstPlayis 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.canStartCountdownis used to control whether the countdown can start.game.canEndSongis used to control whether the post-song events can happen. Both of these are used for cutscenes, and neither of them will prevent thestartCountdownandendSongfunctions from triggering in scripts.game.startCountdown()andgame.endSong()can be used to manually start the countdown or end the song after a cutscene.game.endingSongsays whether the song has attempted to end at least once, even ifgame.canEndSongwas 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.