Skip to content

[1.4.4] Boss Log Entry Mod Call

Sheepish Shepherd edited this page Dec 22, 2024 · 26 revisions

What is this?

If you develop a mod with bosses, consider adding support via Mod Calls. We offer a mod call that you can use in Mod.PostSetupContent to automatically add your boss to the boss checklist and boss log. Users will be able to view all bosses and information about them at a glance. We also will provide support for other features in this mod such as the Boss Radar and Boss Records. Even if you only play with mods, consider asking any mod developers to add support if they haven't already and possibly redirect them to this page!

If you are unfamiliar with Mod.Call, first read the Mod.Call guide on the tModLoader wiki to get an idea about how it works.

Recent Additions or Changes

[v2.0.0] Limb Messages

Examples

Here are some examples of mods integrating with Boss Checklist. If the instructions on this page confuse you, it might be helpful to read some real examples:

  • ExampleMod - Shows adding one boss. This example is highly commented.

Porting Notes

If you are in the process of porting your mod to 1.4.4, BossChecklist provides a feature to auto-generate localization keys for necessary parameters using the old mod call parameters as the value. If you do not want to use this feature or no longer need to, you are able to disable the feature in the configs under 'Disable Auto-Localization'. For boss or mini-boss entries, localization keys will be registered under the first listed NPC's localization keys. For events, the paths will be registered under 'Mods.ModName.BossChecklistIntegration'.

Porting Steps

  1. To port, first make sure your mod loads on 1.4.4. Next, make sure make sure your game is in English, then load BossChecklist and your mod together before adjusting any Mod.Calls.
  2. This process should have added localization keys to your .hjson files. Verify that your English .hjson file has new entries for keys ending in SpawnInfo with the text for spawning a boss.
  3. Next, decide on an InternalName for each of your bosses. The InternalName should not change once you publish your mod, so make sure it is representative of the boss. The InternalName should be alphanumeric characters only and have no spaces or special characters.
    • For bosses consisting of a single NPC, using nameof(BossNPCClassName) is convenient.
  4. Adjust your existing Mod.Calls to the new layout.
    • Change "AddBoss" to "LogBoss". Same for Event and MiniBoss.
    • The display name, spawn info, and despawn info entries are all automatic now, so they won't make it to the new Mod.Call. They can still be passed in, if needed. For example, if you already have a localization entry for an event display name, you can pass in ["displayName"] = Language.GetText("Mods.MyMod.Events.MyEvent.DisplayName"), as part of the "Additional Entry Data" dictionary. This will allow you to remove the localization entry Boss Checklist generated for that event in your mod's .hjson files.
  5. Rebuild your mod and verify that they show up in the logs. Consult client.log for error messages if anything is not working. You should be able to adjust .hjson files while the game is running to see text changes immediately without rebuilding the mod, if needed.
    • If you previously used item chat tags, like $"Use a [i:{ModContent.ItemType<MyBossSpawner>()}].", do note that this is still possible to do via .hjson files. Simply type Use a [i:MyModInternalName/MyBossSpawner]. as the localization entry. Also note that if you were using Terraria items, [i:SuspiciousLookingEye] can replace [i:43] to be more readable.
  6. If you run into any issues or feedback, come by the boss-checklist channel in our Discord and we'll be happy to help.

The final Mod.Call might look something like this:

bossChecklistMod.Call(
	"LogBoss",
	Mod,
	nameof(MyBoss),
	5.5f,
	() => DownedBossSystem.downedMyBoss,
	ModContent.NPCType<MyBoss>(),
	new Dictionary<string, object>() {
		["spawnItems"] = ModContent.ItemType<MyBossSpawner>(),
		// Other optional arguments as needed...
	}
);

Arguments

[0] Entry Type

string - The first argument needed is the message type, which determines what type of entry you are submitting. For bosses use LogBoss, for mini-bosses use LogMiniBoss, and for events use LogEvent.

[1] Mod Instance

Mod - A mod instance will be necessary for logging and native support. Mods calls are expected to be within ModSystem.PostSetupContent, so Mod should be used.

[2] Internal Name

string - For this argument, you are free to choose what internal name is assigned to your entry. For most cases, you will just use nameOf(MyNPCClassName) but for special cases and events you may decide to use the entry's name. The internal name you submit for your entry with solely be for your entry key. Your entry key can be used by other developers to submit mod-collaborative data to your entry. Vanilla entries have entry keys too!. Please note that internal names cannot contain spaces and must consist entirely of letter characters.

[3] Progression

float - Determine what part of the game you boss should be fought at and how difficult is it to fight compared to other bosses. Is it a pre-hardmode boss? Should it be fought after Plantera? Use the Progression Reference Guide for vanilla entry progression values and to learn how to access modded entry values.

[4] Downed Boolean

Func<bool> - Your entries should have a downed boolean assigned to them within a ModSystem class.* Your downed boolean must then be cast as a Func<bool> before being submitted as this would need to be checked at multiple points during gameplay, not just during the entry submission. An example of this is shown on ExampleMod.

[5] Boss ID / List of IDs

int or List<int> - Submit all necessary NPC ID numbers that is apart of you entry. Use ModContent.NPCType<>() to submit your ID(s). Most boss and mini-boss entries only require a single int to be passed, but for special cases or events where multiple NPCs must be added, please use a List<int>. NPCs that consist of multiple parts, such as Skeletron's head and arms or how the Twins consist of Retinazer and Spazmatism. However, this should NOT include any minion-like NPCs such as Eye of Cthulhu servants. For event entries, the Boss Log will list off the NPCs by their banner item. Be sure to apply a banner to all your NPCs to have them be displayed.

*Note: It is up to the mod developer to properly set up saving and syncing for their downed booleans. ExampleMod has a good example of this.

[6] Additional Entry Data

Dictionary<string, object> (optional) - A dictionary of objects with string keys can be passed to add any additional data that isn't required to make an entry. BossChecklist will look through your dictionary for specific string keys to apply your data where needed. The keys can be applied in any order and do not all need to be present. The current keys that are checked for are the following:

  • "displayName"

LocalizedText - The names that are displayed on the Boss Log will be automatically fetched by BossChecklist. In most instances, your NPC's display name will be fetched, but when submitting a Multi-NPC entry or event a localization key will be generated for you to use. If you do NOT need to use the key generated for you and would rather used an already defined localization, use this argument to pass it through.

If you are in the process of porting your mod calls, you can have your localization keys automatically registered.

  • "spawnInfo"

LocalizedText or Func<LocalizedText> - Your entries must provide a localized text of any and all ways to encounter your entry. A localized text can be provided to display ways to encounter or spawn your entry with information such as spawn items in the form of Chat Tags or any conditions that need to be met. If you need to submit spawn info with conditional text, such as determining what info should be presented based on what world evil is preset, use Func<LocalizedText> instead. Don't forget to take advantage of .WithFormatArgs with your LocalizedText.

If you are in the process of porting your mod calls, you can have your localization keys automatically registered.

  • "spawnItems"

int or List<int> - Not all entries have spawn items, but if your entry happens to, use this key. This can include any items that are needed to spawn your entry. You may need to add multiple items such as how Golem requires both the Lihzahrd Altar and a Lihzahrd Power Cell to be summoned. The Boss Log will also automatically search for any crafting recipes you items may have and display them on the spawn info page, so you may want to submit this for you players to reference to.

  • "collectibles"

int or List<int> - If your entry has collectible items include the item IDs in a list. Collectible items are NOT your entry's loot. Entry loot is automatically fetched using the bestiary. Avoid including items such as weapons, armor, and other non-aesthetic items. However, if you feel that they can be considered a collectible because of their extreme rarity (such as the Terraprisma from the Empress of Light) feel free to do so. The following are fully recognized as collectible items:

  • Relics and Trophies

  • Masks

  • Music Boxes

  • Pet Items

  • "availability"

Func<bool> - If you need to hide your boss for whatever reason, make a Func<bool> of the conditions that need to be met for this entry to be available. This can be useful for that are dependent on a condition, such as the Brain of Cthulhu only being available in crimson worlds. Be aware that users expect to be able to see all bosses in the checklist, and have the option to circumvent the availability check within their configs.

  • "overrideHeadTextures"

string or List<string> or Func<List<Asset<Texture2D>>> - Head textures are searched for by looking through the NPC IDs provided and attempting to find any corresponding head types. There may be a case where you may not want this to automatically occur, such as when submitting an event or having an NPC with multiple head textures but you only want one to display. To remedy this, use this key and submit a list of texture paths and those textures will completely override the auto-generated ones. If you decide to use the more dynamic option using Func<List<Asset<Texture2D>>>, it is up to you to ensure that all textures are displayed properly, and that no missing textures exceptions occur.

  • "limbs"

Dictionary<int, LocalizedText> - You can submit boss NPC parts to take advantage of BossChecklist's 'Non-Boss Defeated Annoucements' config. A good example of this is Golem, where his fists and head are crucial components to defeat before defeating the main boss. Another use could be a multi-boss, such as the Twins. Defeating one will notify all players, signaling them to focus the other seamlessly. To utilize this feature, make sure you have the NPC type as the dictionary key and a LocalizedText of the message you want displayed when it's killed.

Note: Your Boss ID / List of IDs, should only contain the main NPCs that trigger its defeation. If you have the limbs within that list, move it here instead.

  • "despawnMessage"

LocalizedText or Func<NPC, LocalizedText> (advanced) - Despawn messages are NOT supported for event entries. BossChecklist has despawn message feature to signal players via chat when a boss has despawned and is no longer active. Mod developers can submit their own despawn messages using this key! Despawn messages are full customizable in terms of conditions, allowing unique messages to be displayed under multiple different circumstances. Here is an example of how this feature can be utilized:

Note: Your localization should use {0} in place of the NPC name to make use of the WithFormatArgs. This will show the NPC's actual in-game name.

// In this example, the despawn message will be "The boss laughs as it leaves the world" if all players are dead and the boss's health was above half.
// The despawn message will be "The boss has left" if all players are dead and the boss was below half health.
// Finally, if no conditions have been met, default to the generic despawn message.

Func<NPC, LocalizedText> ExampleDespawnMessage = delegate (NPC npc)
{
	if (Main.player.All(plr => !plr.active || plr.dead)) {
		if (npc.life > npc.lifeMax / 2) {
			// A despawn message if the boss despawns with more than half health when all players are dead
			return Language.GetText("Mods.ModName.Path.To.DespawnMessage.ExtraExample").WithFormatArgs(npc.FullName);
		}
		else {
			// A despawn message when all players are dead
			return Language.GetText("Mods.ModName.Path.To.DespawnMessage.PlayerDeath").WithFormatArgs(npc.FullName);
		}
	}

	// return your generic despawn message if no conditions are met
	return Language.GetText("Mods.ModName.Path.To.DespawnMessage.Generic").WithFormatArgs(npc.FullName);
};
  • "customPortrait"

Action<SpriteBatch, Rectangle, Color> (advanced) - A portrait is auto-generated for you, but if it looks funky or you want to customize it to how you think it should look, your entry can include a custom drawing action. You will have free reign over the area within the rectangle provided. The color input is for detecting the mask status of progression mode for players who want to go through the game without knowing what's to come, which will render the texture completely black. For developers who don't know how to take advantage of this can use the following to submit an image for the portrait:

(This may not be exactly how you'll want it, but close enough to make adjustments for)

(SpriteBatch spriteBatch, Rectangle rect, Color color) => {
	Texture2D texture = ModContent.Request<Texture2D>("Texture/File/Path/Here").Value;
	Vector2 centered = new Vector2((rect.X + (rect.Width / 2) - (texture.Width / 2), rect.Y + (rect.Height / 2) - (texture.Height / 2));
	spriteBatch.Draw(texture, centered, color);
}