Adding a character - Pandemonium14/ExoLoader GitHub Wiki

Getting started

Like any content, characters are added by first adding a folder in the Exocolonist/CustomContent folder. It can be named anything and will also contain any other content that will come with your character, like the sprites or the story file.

Let's pretend we're making a character named Template. To get started, I create a folder called TemplateContent in the CustomContent folder. I create a folder named Characters inside that folder. You can add any number of characters from this folder, by creating their own folder. The folder structure is like this: Exocolonist/CustomContent/TemplateContent/Characters/Template. The next step is to add a data file in it.

Creating the data file

This is the most important step. The data file contains all the information the game needs to know in order to add the character to the list. It contains:

  • An ID entry. This will be used in the backend and in the story files to refer to your character. It cannot contain special characters. Note: if an id starts with another character's id (for example, calimero and cal), it will cause problems. Be careful to not start your id with a vanilla character's id, and avoid making it to short (template is a better choice than temp because temp would make reasonable ids like temporal not work if loaded at the same time)
  • A NAME entry. This is your character's complete name, e.g. Marzipan, Nomination, Recalcitrance.
  • A NICKNAME entry. This is by what your character's is usually refered by, e.g. Marz, Nomi-Nomi, Cal.
  • A GENDER entry. M for male, F for female, X for non-binary.
  • A LOVE entry (TRUE or FALSE). This decides whether or not your character has friendship/love/heart points or not.
  • An AGE10 entry (number). This is your character's age at the very start of the game, when Sol is 10.
  • A BIRTHDAY entry. This should be written like this: [season]-[number] with season being quiet|pollen|dust|wet. For Glow season you can use value glow and it will display "Glow season" in character info.
  • A DIALOGUECOLOR entry. The hexadecimal value of the color your character's dialogue will have during stories. Color picker here.
  • A DEFAULTBG entry. The ID of the background your character's story take place in. Check out Backgrounds.tsv file to look up the IDs.
  • A BASICS entry. This is the beggining of the description, that players will see from the moment they met your character.
  • A MORE entry. The rest of the description, which can be unlocked by the player through events with your character.
  • An ENHANCEMENT entry. How your character's augment is called.
  • A collection of FILLBAR entries. This is the various "stats" your character will have on their page. The text is the name of each end of those slider bars, and the numbers are how far left or right is (0-10 is left-right).

The data files also contains information the game doesn't completely needs, but that the mod uses for its other features.

  • Likes and Dislikes. Lists of collectible IDs that inform what the character likes and dislikes as gifts. Check out the ExocolonistCards - Cards.tsv file to figure out the IDs.
  • An OnMap entry (TRUE or FALSE). This is whether or not the character should get added as a map spot in the colony. If FALSE, you don't need any other entry related to the map spots.
  • An HelioOnly entry (TRUE or FALSE). If TRUE, the character only appears after the Helio lands, and doesn't need a StratoMapSpot or DestroyedMapSpot entry.
  • A SpriteSize entry, which decides how tall your character's sprite will be during stories. This will determine how tall they are compared to the rest of the cast. With 20, they'll be about the size of Sym.
  • An optional OverworldScaleByAge entry containing values that allow you to scale the overworld sprites up or down, the default values for all scales is "4.00", so make this value bigger or smaller if your sprite is too small or too big.
  • An Ages entry. (Subject to change, will update later)
  • A Skeleton entry (more on it in the section "Adding sprites" section)
  • An AnimationFrameRates entry - a list of 3 numbers that affect frame rate for a frame-by-frame animation of the overworld sprite (one of the options for how your character is displayed in the overworld, more on it in the "Adding sprites" section)
  • A Jobs entry. This indicates what jobs will increase friendship with your character. Check out the jobs data file to know what the IDs are.
  • A MainMenu entry that contains information where to display the character on the main menu, if you want to add them there. It has two sub-entries:
    • Template - which character to use as a base template for the positioning in terms of the layer (where sol is closest-most and sym is furthest most)
    • Position - [x, y] coordinates where the character will be displayed, more on it down below.

Overworld Positioning

Currently there are two options on how your characters are positioned on the colony map:

For static position you need to add three MapSpotEntries, deciding XYZ coordinates of the character's map spot in the colony (y isn't really relevant, it is snapped to the floor automatically):

  • StratoMapSpot is for the first part of the game (age 10-14)
  • DestroyedMapSpot is for quiet 15, when the colony is destroyed.
  • HelioMapSpot is for after the Helio lands

If you want your character to move between seasons, or be absent during specific seasons:

  • PreHelioMapSpots as an object with keys quiet|pollen|dust|wet|glow and values of XYZ coordinates for each season. If season key is not present, character will not be on the map during that season - useful if you do not want your character to be around Glow, or maybe if they really hate Dust!
  • PostHelioMapSpots in the same format as PreHelioMapSpots with keys of seasons and values of XYZ coordinates.
  • DestroyedMapSpot - same as with static positioning, since this is only during quiet 15, when the colony is destroyed, just values of XYZ coordinates.

Example

Here is Template's data.json. Use it to fill out your character's info. Be careful to keep all brackets, commas and quotation marks!

The data file can be named anything, but it must be a .json file, in the character's folder. In our example, it'll be in CustomContent/TemplateContent/Characters/Template.

When this is done, launching the game should properly add the character to the characters page, but of course, it won't do anything without also adding content for them, and they won't be visible anywhere, except as an unknown character in the character list. (If OnMap is true, you'll require map sprites to be able to load or start a game, which is covered in the Adding Sprites part)

Note: this example file contains values for both static and dynamic overworld positioning, you do not need both - if dynamic values are found in the file only they would be used - static values are included in the example for reference.

{
	"Data": {
		"ID": "template",
		"NAME": "Custom Template",
		"NICKNAME": "Template",
		"GENDER": "X",
		"LOVE": "TRUE",
		"AGE10": "10",
		"BIRTHDAY": "glow",
		"DIALOGUECOLOR": "000000",
		"DEFAULTBG": "colony",
		"BASICS": "A character template.",
		"MORE": "Made to make adding characters easier.",
		"ENHANCEMENT": "No back pains",
		"FILLBAR1LEFT": "Unfinished",
		"FILLBAR1RIGHT": "Perfect",
		"FILLBAR1CHILD": "0",
		"FILLBAR1TEEN": "3",
		"FILLBAR1ADULT": "6",
		"FILLBAR2LEFT": "Unfinished",
		"FILLBAR2RIGHT": "Perfect",
		"FILLBAR2CHILD": "0",
		"FILLBAR2TEEN": "3",
		"FILLBAR2ADULT": "6",
		"FILLBAR3LEFT": "Unfinished",
		"FILLBAR3RIGHT": "Perfect",
		"FILLBAR3CHILD": "0",
		"FILLBAR3TEEN": "3",
		"FILLBAR3ADULT": "6"
	},
	"Likes": [
		"device",
		"yellowFlower"
	],
	"Dislikes": [
		"egg",
		"cake"
	],
	"Ages": "TRUE",
	"OnMap": "TRUE",
	"HelioOnly": "FALSE",
	"SpriteSize": "18",
	"PreHelioMapSpot": [
		"0.0",
		"0.5",
		"-20.0"
	],
	"PreHelioMapSpots": {
		"quiet": [
			"0.0",
			"0.5",
			"-20.0"
		],
		"pollen": [
			"0.0",
			"0.5",
			"-18.0"
		],
		"dust": [
			"0.0",
			"0.5",
			"-16.0"
		],
		"wet": [
			"0.0",
			"0.5",
			"-14.0"
		],
		"glow": [
			"0.0",
			"0.5",
			"-12.0"
		]
	},
	"PostHelioMapSpot": [
		"38.0",
		"6.9",
		"3.1415"
	],
	"PostHelioMapSpots": {
		"quiet": [
			"38.0",
			"6.9",
			"3.1415"
		],
		"pollen": [
			"39.0",
			"6.9",
			"3.1415"
		],
		"dust": [
			"40.0",
			"6.9",
			"3.1415"
		],
		"wet": [
			"41.0",
			"6.9",
			"3.1415"
		],
		"glow": [
			"42.0",
			"6.9",
			"3.1415"
		]
	},
	"DestroyedMapSpot": [
		"42.0",
		"6.9",
		"3.1415"
	],
	"SpriteSizesByAge": [
		"23",
		"23",
		"23"
	],
	"OverworldScaleByAge": [
		"3.0",
		"4.0",
		"5.0"
	],
	"Skeleton": "tang",
	"Jobs": [
		"relaxLounge"
	],
	"MainMenu": {
		"Template": "sym",
		"Position": ["1.23", "5.35"]
	}
}

Adding Sprites

Then, you can add sprites for your character. This is done by creating a Sprites folder in the same folder as your data file, and putting images in them.

How the mod will use the images is entirely determined by their names.

For story sprites, the kind that get shown during events, the naming scheme is as follows: [characterID][art stage]_[expression].png. The ID is the one you used in the data file. The art stage is a number from one to three:

  • with 1 being for years one to three (early teen)
  • 2 for years four to six (mid-teen)
  • and 3 for seven to nine (late-teen).

Only stages two and three are needed for helio-only characters. The expression can be anything, and you'll be able to use them in stories by using ~set left = [characterID]_[expression]. Important: you MUST include a normal expression to act as the default sprite.

For portraits, the naming scheme is portrait_[characterID]_[art stage].png.

If your character is one the map, you'll need images for their map spot. Overworld map sprites can be either static images, fully animated Spine models (same animation system the game uses for characters) or a frame-by-frame animation created from a series of .png images. The mod automatically detects which to use based on the files you provide. If you provide a Spine animation folder (with .json, .atlas, and .png), the mod will load and display it as an animated character. If you provide a static PNG image, it will be used as-is (also if animated one ever fails to load, static image would be used as a fallback).

Animated overworld sprites (series of .png images)

To add this type of animated character on the map, create a folder inside the Sprites folder with a name like [characterID]_model_[art stage]/ and place your images in this folder, it's better if they're numbered so the order import is correct. The default frame rate for this animation is 12, but you can adjust frame rate for art stage if you include AnimationFrameRates attribute in your .json file for the character. For example, value ["12", "14", "13"] means first art stage (early teen) model will be animated with 12, second (mid teen) with 14, third (late teen) with 13.

Spine-based animaged overworld sprites

To add a Spine-based animated character sprite to the map, create a folder inside the Sprites folder with a name like [characterID]_model_[art stage]/. Inside this folder, you must include:

  • A .json file (Spine skeleton definition)
  • A .atlas file (text format)
  • A .png file (texture used by the atlas)

All three must be present, or the mod will ignore the folder and fall back to a static image. These files come from Spine, a 2D skeletal animation tool. You can find examples here or contact saerielle on Discord if you have troubles setting this up.

Notes:

  • Make sure the .atlas file starts with a blank line and lists the .png filename on the second line
  • The .json should contain a "default" skin.
  • Following animations:
    • idle (used most of the time)
    • look or look1 (most characters you use in Skeleton from character definition like tang have look, but double check it because Dys's early-teen one uses look1 instead)
    • look2

Static images

If you don't want to use animation, or your animated folder is incomplete or misnamed, the mod falls back to using a static image. Place a single .png image in the Sprites folder. The naming scheme is [characterID]_model_[art stage]. Images should be 280x500 PNG files.

Adding character to the main menu

For this, you would need a file named like chara_[characterID].png in your "Sprites" folder. Make sure to size it to how it should appear on the screen.

Note: custom character will only appear on the screen if player has earned their lvl 3 card (named [characterID]3), same as with base game characters.

Here are reference positions of existing game characters, so you can set up the configuration in MainMenu.Position

  • sol ["2.08", "-0.01"]
  • anemone ["2.75", "1.63"]
  • tang ["8.02", "2.36"]
  • marz ["8.28", "2.96"]
  • dys ["4.29", "3.39"]
  • rex ["-0.92", "1.84"]
  • cal ["5.21", "4.49"]
  • tammy ["5.59", "4.75"]
  • nomi ["-0.38", "2.79"]
  • vace ["0.56", "4.06"]
  • sym ["0.73", "5.15"]

Adding stories

Stories are added independently from characters. Just create a Stories folder in you content folder (CustomContent/TemplateContent in our example), and put your .exo files in it. All .exo files in this file will be read, parsed and added automatically.

Important: to work properly if on the map, your character MUST have at least one high priority story, one regular priority story, and one low priority story.