|
| 1 | +[tags]: / "advanced,hscript,events" |
| 2 | + |
| 3 | +# Scripted Song Events |
| 4 | + |
| 5 | +This chapter will walk you through the process of creating a custom song event, which could be used in songs through the chart editor. |
| 6 | + |
| 7 | +Start by creating a scripted class file with the `.hxc` extension (in the `mods/mymod/scripts/events` if you want to keep things organized) |
| 8 | + |
| 9 | +```haxe |
| 10 | +// Remember to import each class you want to reference in your script! |
| 11 | +import funkin.play.event.SongEvent; |
| 12 | +
|
| 13 | +// Choose a name for your scripted class that will be unique, and make sure to specifically extend the SongEvent class. |
| 14 | +class FocusCameraSongEvent extends SongEvent { |
| 15 | + public function new() { |
| 16 | + // The constructor gets called once, when the game loads. |
| 17 | + // The constructor takes one parameter, which is the event ID for your custom event. |
| 18 | + super('FocusCamera'); |
| 19 | + } |
| 20 | +
|
| 21 | + // Add override functions here! |
| 22 | +} |
| 23 | +``` |
| 24 | + |
| 25 | +You can then add override functions to perform custom behavior. |
| 26 | + |
| 27 | +## Performing behavior when getting called |
| 28 | + |
| 29 | +To provide custom behavior to the event that gets called when the song reaches the event's position, you must override the function `handleEvent`. Overriding this function is mandatory, as if your custom event doesn't include it, the game will crash when attempting to activate the event. The function comes with a parameter from which you can retreive some information about the event, such as the property values provided. An example of this can be found in the event Play Animation[^playanim] |
| 30 | + |
| 31 | +```haxe |
| 32 | +// ... |
| 33 | +
|
| 34 | +// Line 18 |
| 35 | +public override function handleEvent(data:SongEventData) |
| 36 | +{ |
| 37 | + // Does nothing if there is no PlayState camera or stage. |
| 38 | + if (PlayState.instance == null || PlayState.instance.currentStage == null) return; |
| 39 | +
|
| 40 | + var targetName = data.getString('target'); |
| 41 | + var anim = data.getString('anim'); |
| 42 | + var force = data.getBool('force'); |
| 43 | + if (force == null) force = false; |
| 44 | +
|
| 45 | + // ... |
| 46 | +} |
| 47 | +
|
| 48 | +// ... |
| 49 | +
|
| 50 | +``` |
| 51 | + |
| 52 | +## Providing song event properties |
| 53 | + |
| 54 | +The game supports providing events some additional properties for more leeway in functionality. For this, you need to override the function `getEventSchema` that returns an array of anonymous objects, each representing a property your event can have. The structure of these anonymous objects is as follows: |
| 55 | + |
| 56 | +- `name`: The internal name of the property, which you can use to get the value of the property when executing the event. |
| 57 | + |
| 58 | +- `title`: The visible name of the property, as displayed in the chart editor events toolbox. |
| 59 | + |
| 60 | +- `type`: The type of the event. Can be either `string` (text properties), `integer`, `float`, `bool` or `enum` (dropdown properties). |
| 61 | + |
| 62 | +- `defaultValue`: An optional default value for the property. |
| 63 | + |
| 64 | +- `keys`: Is an optional map with keys representing the visible name and values representing the internal name of the property values. |
| 65 | + |
| 66 | + - Accessible to the `enum `properties. |
| 67 | + |
| 68 | +- `min`: Represents the optional minimum value that the property could have. |
| 69 | + |
| 70 | + - Available to the `integer` and `float` properties. |
| 71 | + |
| 72 | +- `max`: Represents the optional maximum value that the property could have. |
| 73 | + |
| 74 | + - Available to the `integer` and `float` properties. |
| 75 | + |
| 76 | +- `step`: Represents the amount the value steps by for each change in the toolbox. This field is optional and defaults to `0.1`. |
| 77 | + |
| 78 | + - Available to the `integer` and `float` properties. |
| 79 | + |
| 80 | +- `units`: Represents the unit of measure for the numeric value. (i.e. pixels, steps etc.) |
| 81 | + |
| 82 | + - Available to the `integer` and `float` properties. |
| 83 | + |
| 84 | +## Custom song event chart editor icon |
| 85 | + |
| 86 | +Chart editor supports both static and animated song event icons in the spritesheet format. To provide a custom icon for your event in the chart editor, you need to put two things in the `mods/mymod/images/ui/chart-editor/events` folder: |
| 87 | + |
| 88 | +- An image of your song event icon named after what you put in the event's constructor. |
| 89 | + |
| 90 | +- An XML file for your song event icon, even if it's a single frame. |
| 91 | + |
| 92 | + - The frame names must start with the text you put inside the event's constructor. |
| 93 | + |
| 94 | +Once you made sure both assets are where they should be and have the correct names, your song event should have a custom icon in the chart editor. |
| 95 | + |
| 96 | +## Custom song event title |
| 97 | + |
| 98 | +To give your song event an unique title that will be displayed in the chart editor's event toolbox dropdown, you must override the function `getTitle` with the return of your desired event title. An example of this is found in the event Zoom Camera[^camzoom] |
| 99 | + |
| 100 | +```haxe |
| 101 | +// ... |
| 102 | +
|
| 103 | +// Line 91 |
| 104 | +public override function getTitle():String |
| 105 | +{ |
| 106 | + return 'Zoom Camera'; |
| 107 | +} |
| 108 | +
|
| 109 | +// ... |
| 110 | +``` |
| 111 | + |
| 112 | +[^playanim]: <https://github.com/FunkinCrew/Funkin/blob/main/source/funkin/play/event/PlayAnimationSongEvent.hx> |
| 113 | +[^camzoom]: <https://github.com/FunkinCrew/Funkin/blob/main/source/funkin/play/event/ZoomCameraSongEvent.hx> |
| 114 | + |
| 115 | +> Author: [KoloInDaCrib](https://github.com/KoloInDaCrib) |
0 commit comments