Friday Night Funkin' Cookbook
Friday Night Funkin' CookbookIntroductionCustom Characters

Custom Characters

Reading time: 9 minutes

This chapter will walk you through the process of creating a functioning, fully compatible Friday Night Funkin' mod, using the game's official systems for loading custom content and scripts. Once your mod is complete, you will be able to place it in the mods folder in your game install and use its content in-game without overriding the base game content and still maintain compatibility with other mods.

This chapter goes over adding new characters to the game, and using them in a level.

Character Spritesheet Formats

The individual sprites of a character's animations must be combined into a spritesheet for the game to use them. Friday Night Funkin' supports one of several formats:

  • sparrow: Combines the images into a large sheet, then provides an XML file containing the coordinates of each frame with it. Can be exported directly from Adobe Animate or Flash CS6 using the Generate Sprite Sheet option, or can be created from individual frames using Free Texture Packer (note that Free Texture Packer refers to this format as Starling).

  • packer: Combines images into a sheet, then provides a TXT file containing the coordinates of each frame.

  • animateatlas: Created exclusively when using Adobe Animate, this exports individual symbols into a large sheet, then provides a JSON file with data to split up each symbol, then provides a second JSON to arrange those symbols into animations. Great for performance, especially for characters which were made by rearranging smaller parts. We use the flixel-animate Haxelib for this.

  • multisparrow: Allows for different groups of animations to be exported into separate Sparrow spritesheets, then combined together into one character.

  • multianimateatlas: Allows for different groups of animations to be exported into separate Adobe Animate texture atlases, then combined together into one character.

Creating a Character

A custom character requires creating a new JSON file in the data/characters folder. Below is an example of Spooky Kids' character data file, from assets/data/characters/spooky.json1

{
  "version": "1.0.0",
  "name": "Spooky Kids",
  "assetPath": "characters/SpookyKids",
  "startingAnimation": "danceRight",
  "animations": [
    {
      "name": "danceLeft",
      "prefix": "spooky dance idle0",
      "frameIndices": [0, 1, 2, 3, 4, 5, 6, 7]
    },
    {
      "name": "danceRight",
      "prefix": "spooky dance idle0",
      "frameIndices": [8, 9, 10, 11, 12, 13, 14, 15]
    },
    {
      "name": "singLEFT",
      "prefix": "note sing left",
      "offsets": [130, -15]
    },
    {
      "name": "singDOWN",
      "prefix": "spooky DOWN note",
      "offsets": [-50, -140]
    },
    {
      "name": "singUP",
      "prefix": "spooky UP NOTE",
      "offsets": [-20, 26]
    },
    {
      "name": "singRIGHT",
      "prefix": "spooky sing right",
      "offsets": [-130, -15]
    },
    {
      "name": "cheer",
      "prefix": "Spookiez YEAH cheer",
      "offsets": [60, 30]
    }
  ]
}

The available fields are:

  • version: The version number for the Character data file format. Leave this at 1.0.0.
  • name: The readable name for the character, used in places like the Chart Editor.
  • renderType: The render type. One of sparrow, packer, animateatlas, multisparrow.

  • assetPath: The main asset path to use for this character, relative to the images directory in your mod folder.

    • For the sparrow asset type, this must point to the path where the xml and png are located, without the file extension.
    • For the packer asset type, this must point to the path where the txt and png are located, without the file extension.
    • For the animateatlas asset type, this must point to the folder where the Animation.json and any spritemaps are located.
    • For the multisparrow asset type, point to the path where your main Sparrow spritesheet is located. On each animations which uses a different Sparrow spritesheet from the main one, add the assetPath key to that specific animation.
    • For the multianimateatlas asset type, point to the path where your main Adobe Animate texture atlas is located. On each animations which uses a different Adobe Animate texture atlas from the main one, add the assetPath key to that specific animation.
  • scale: Specify the size of the character relative to the original size. For example, 2.0 makes the sprite twice as big. Optional, defaults to 1.0.

  • healthIcon: Data for the health icon to display in-game. For example, Boyfriend will obviously use Boyfriend's health icon. Optional, defaults its ID to character's ID.
  • death: Data for the death screen to use, when the character reaches 0 health. Optional, doesn't default to a specific object.
  • offsets: The global offset to the character's position, in pixels. Optional, defaults to [0, 0].

    • Use an array of two decimal values, the first for horizontal position and the second for vertical position.
  • cameraOffsets: The amount to offset the camera by while focusing on the character. Optional, default value focuses on the character directly.

    • Use an array of two decimal values, the first for horizontal position and the second for vertical position.
  • isPixel: Specify whether to disable texture smoothing for the character. Optional, defaults to false.

  • danceEvery: The frequency at which the character will play its idle animation, in beats. Optional, defaults to 1.

    • Increasing this number will make the character dance less often.
  • flipX: Whether to flip the whole sprite horizontally in-game. Useful for characters that could also be played (Pico). Optional, defaults to false.

  • startingAnimation: The animation for the character to play when they are first loaded in. Optional, defaults to idle.
  • singTime: The amount of time, in steps, for a character to keep singing after they let go of a note. Optional, defaults to 8.

    • Decrease this if the character seems to hold their poses for too long after their section is done.
    • Increase this if the character resets to the idle animation in the middle of their singing animations.
  • atlasSettings: Only available for the animateatlas and multianimateatlas asset types. Specify the settings for the texture atlas.

  • animations: A list of animation data objects for the character.

Health Icon data is structured like so:

  • id: The ID to use for the health icon, defaults to character's ID.
  • scale: Specify the size of the health icon relative to the original size. For example, 2.0 makes the sprite twice as big. Optional, defaults to 1.0.
  • flipX: Whether to flip the whole sprite horizontally in-game. Optional, defaults to false.
  • isPixel: Specify whether to disable texture smoothing for this characters health icon. Optional, defaults to false.
  • offsets: The offset of the health icon, in pixels. Optional, defaults to [0, 0].

    • Use an array of two decimal values, the first for horizontal position and the second for vertical position.

Death data is structured like so:

  • cameraOffsets: The amount to offset the camera by while focusing on this character as they die. Optional, defaults to [0, 0].

    • Default value focuses on the character's graphic midpoint.
    • Use an array of two decimal values, the first for horizontal position and the second for vertical position.
  • cameraZoom: The amount to zoom the camera by while focusing on this character as they die. Optional, defaults to 1.

  • preTransitionDelay: The delay between when the character reaches 0 health and when the death animation plays. Optional, defaults to 0.

Texture atlas configuration data is structured like so:

noteNote

This is only available for the animateatlas and multianimateatlas asset types! Ignore this if you're using another asset type like sparrow or packer.

  • swfMode: If true, the texture atlas will behave as if it was exported as an SWF file. Notably, this allows MovieClip symbols to play.
  • cacheOnLoad: If true, filters and masks will be cached when the atlas is loaded, instead of during runtime.
  • filterQuality: The quality of the filters used in the atlas. It's a number from 0 to 3.

    • 0 is high (the highest quality)
    • 1 is medium
    • 2 is low
    • 3 is rudy (the lowest quality)
  • applyStageMatrix: If true, it applies the stage matrix if it was exported from a symbol instance, positioning the sprite as it would display in Adobe Animate.

    • Turning this on is only recommended if you prepositioned the character in Animate. For other cases, it should be turned off.
  • useRenderTexture: If enabled, the character will render as one texture instead of having each limb render individually. This is useful for things like changing alpha, and shaders that require the whole sprite.

    • Only enable this if your character either:
      • Changes alpha to something other than 1.0
      • Has a shader or blend mode that requires the whole sprite
    • For all other cases, it's recommended to leave this disabled for performance purposes.

Animation data is structured like so:

  • name: The internal animation name for the game to use.
  • prefix: The animation name as specified by your spritesheet.

    • For Sparrow or Packer, check inside the data file to see what each set of frames is named, and use that as the prefix, excluding the frame numbers at the end.
    • For Animate Atlases, use either the frame label or the symbol name of the animation you want to play.
  • offsets: Some animations may need their positions to be corrected relative to the idle animation.

    • Use an array of two decimal values, the first for horizontal position and the second for vertical position.
  • looped: Whether to loop this animation in-game. If false, the animation will pause when it ends, until the game commands the character to do something else.

  • flipX: Whether to flip the sprites of this animation horizontally in-game.
  • flipY: Whether to flip the sprites of this animation vertically in-game.
  • frameRate: A frame rate value, defaulting to 24.
  • frameIndices: Optionally specify an array of frame numbers (starting at frame 0!) to use from a given prefix for this animation.

    • For example, specifying [0, 1, 2, 3] will make this animation only use the first 4 frames of the given prefix.
  • assetPath: For the multisparrow and multianimateatlas asset types specifically. Define a secondary Sparrow or Adobe Animate texture atlas which will be loaded, and which contains the frames for this animation.

  • animType: Only available for the animateatlas and multianimateatlas asset types. Specify the type of animation to use for this animation. If your animation is a frame label animation, set this to "frameLabel". If your animation is a symbol animation, set this to "symbol". Defaults to "frameLabel".

The animation names the game uses by default are:

  • idle: For the idle animation.
  • danceLeft and danceRight: Supersedes the idle animation with one that toggles between two animations.
  • singLEFT, singDOWN, singUP, singRIGHT: The animations for playing notes, when the character is a player or opponent.
  • singLEFTmiss, singDOWNmiss, singUPmiss, singRIGHTmiss: The animations for missing notes, when the character is a player.
  • Adding a new singing animation with the name of an existing animation with -hold at the end will play the animation after the first one ends, while the character is still singing.

    • As a good example, you can copy the singLEFT animation to make a singLEFT-hold animation, which has looped as true and frameIndices as the last few frames of the singing animation.
  • Adding a new singing animation with the name of an existing animation with -end at the end will play an animation before returning to idle.

    • For example, you can define a new singLEFT-end animation to cleanly transition into the idle animation.
  • You can add other animations by name, but you'll have to play them with a script, or a Play Animation song event in the Chart Editor.

When the game starts, it queries the list of possible characters by searching in the data/characters folder for JSON files. This gets used to preload data which is used later when the character is loaded in a stage.

Replacing/Reskinning an Existing Character

As a short aside, you can create a JSON with the same filename as an existing character (from the base game, or from a mod if your mod loads after it) and it will replace it. This can be used to create more elaborate reskins for characters, such as ones that use a different render type.

Using a Character in a Song

There are two ways to use your character in a song once it's implemented.

  1. Create a new chart. Open the Chart Editor, start a chart, and select the character from the Metadata toolbox before charting.
  2. Edit an existing chart in your mod. Open the metadata.json file and check in playData.characters for the player, girlfriend, and opponent keys.

Once the chart which references your character is in your mod folder, simply start the game with your mod installed.

Fixing Character Offsets

Uh Oh! Upon using your character in a song, you might have noticed that with each note hit, the character has weird offsets which makes it wobble back and forth. Let's fix that.

Accessing the Animation Editor

To fix offsets for you character, you first have to access the Animation Editor tool. This can be found in-game by accessing the Debug menu from the main menu (this is bound to ~ by default) and selecting "Animation Editor" option.

Once you have accessed the tool, it might be a little overwhelming at first, but everything is pretty straightforward.

Fixing the Offsets

The first thing you have to do is click 2 on your keyboard to switch to Animation Mode in order to properly fix offsets for each animation. Then, you need to select your character from the Character section in the UI box that is located in the top-left corner.

tipTip

The best thing to do to speed up your process, it to toggle Onion Skin mode by pressing F. This will show the previous animation played being half transparent. This can help speeding up the process, since you will be able to to properly line up the animation with the previous one.

The UI will show you all of the possible controls and shortcuts, to make your process of fixing the character offsets much easier.

Saving Offsets

Once you are happy with your result, simply press ESC on your keyboard to save the Character Data file.

noteNote

In case you want to save the offsets of your character, you are able to do so by pressing CTRL+ESC on your keyboard to save the offsets.

From the beginning of this chapter you will know, that you have to place this character data JSON file in data/characters. Then, you can simply use Hot Reloading to check the offsets without restarting the game.


  1. https://github.com/FunkinCrew/funkin.assets/blob/main/preload/data/characters/spooky.json


Contributors:
MightyTheArmiddilo
AbnormalPoof
Pāvels Rimašs
Cameron Taylor
kade-github
Last modified:
Created:
Category:  Introduction