Skip to content

Replace build.txt with a publicly extendable manifest file #4170

@Mirsario

Description

@Mirsario

Do you intend to personally contribute/program this feature?

Perhaps

I would like to see this change made to improve my experience with

tModLoader code as Contributor/Maintainer
Mod capability as a Modder

Summary

With obvious plenteous amounts of of inspiration from Minecraft's Fabric mod loader, I would like to propose that, for #2472, instead of moving all build.txt properties to .csproj files and their XML, we upgrade the old concept of a companion metadata/manifest file, using a pleasant popular file format such as TOML.

Reasoning

  • MSBuild's XML is simply clunky and unyielding, and declaring properties there, in global scopes, could easily result in unintended side-effects.
  • There's currently no standardized mechanisms for mods to communicate information between each other without code. Providing one would simplify many interactions, removing the need for many mod-authored APIs, and easing the usage of other ones.

Changes Summary

  • Switch from TXT to TOML. It's a very popular configuration format, of the same INI style. HJSON was considered, but it's not a widely recognized file format, and so it only wins in cases of heavy nesting, which only localization & content files have. I suggest TML.Mod.toml as the new filename, to appear 1% less like the modding API monopoly we happen to be at the time.
  • Allow mods to freely and easily access this manifest, allowing very easy declarative interactions without any need for code.
  • Vastly expand the amount of default fields:
    • author becomes at least two different arrays, Authors and Contributors, under the [People] table. Any other fields, like Supporters, can be added out of people's own volition.
    • homepage is replaced with an entire [Contact] table, containing: Homepage, Sources, Issues, Email, Wiki, and any amount of social links like IRC, Discord, Youtube, Patreon, Kofi, etc. Not every field has to actually have an effect in TML, especially right away.
    • Mods can be made to be able to declare not only their dependencies, but also what they suggest or conflict with, even by version. We don't have to implement effects for Conflicts right away.

Example Uses

  • The old Mod Helpers mod had a feature of allowing users to create bug report issues on mods' issue trackers effortlessly, with the use of a bot. The way that mod authors were expected to communicate the GitHub repositories their mods are hosted on was through declaring inelegant magic properties in their mod class like this:
    public sealed class OverhaulMod : Mod
    {
        public static string GithubUserName { get; } = "Mirsario";
        public static string GithubProjectName { get; } = "TerrariaOverhaul";
        ...
    }
    With the proposal implemented, this would be covered by adding something like this to the mod's manifest file:
    [Contact]
    Sources = "https://github.com/Mirsario/TerrariaOverhaul"
    Issues = "https://github.com/Mirsario/TerrariaOverhaul/issues"
    [Integrations.ModHelpers]
    AllowInGameIssueCreation = true # Opt-in!
    Similarly to this, that same mod introduced insane amounts of tags & categorization to mods. This manifest would be perfect for that too.
  • The manifest file could be used to declare what parts of its mod's codebase implements an API, improving the experience of soft-referencing, as that would allow to skip "registration" or "activation" code that would always involve the boilerplate of checking if the API provider is present & loaded. Examples:
    [Entrypoints]
    CoolConfig.v7 = [ "TerrariaOverhaul.Core.Config.CoolConfigImplementation" ]
    ExampleMod.v1 = [ "TerrariaOverhaul.Core.Integrations.ExampleModIntegration" ]
    (Enforcing major versions in keys seems like a good idea.)
  • Terraria Overhaul currently contains a few data-driven elements to it, utilizing *.prefab.hjson files for ambience track declarations, with *.tags.hjson files planned in the future for set entry declarations. It would be excellent if mods were able to add the following to their manifests to make their assets scanned for such files by Overhaul:
    [Integrations.TerrariaOverhaul]
    TagsFiles = "**/*.tags.hjson"
    PrefabFiles = "Integrations/TerrariaOverhaul/**/*.prefab.hjson"
  • In the future, we can make mod descriptions utilize templates (Mustache?), which would be able to reference values from the manifest, such as contributor lists.
  • In the future, we can use the manifest to allow mods to "provide" libraries to other mods, given that they embed them.

Sketch

What my mod would probably have in its manifest, with a bit of exaggeration for examples' sake:

# Toml has comments!

# Declaring an internal name here would allow us to later remove the src folder name constraint,
# which makes git cloning a bit awkward. Could also be useful for internal renaming.
Id = "TerrariaOverhaul"
Version = "5.0.0.34"
DisplayName = "Terraria Overhaul (Configuration Update!)"
License = "MIT" # Code only!

Environment = "Both"
HideResources = false
IncludeSource = false

[Entrypoints]
CoolConfig.v7 = [ "TerrariaOverhaul.Core.Config.CoolConfigImplementation" ]
ExampleMod.v1 = [ "TerrariaOverhaul.Core.Integrations.ExampleModIntegration" ]

# The values use "semver ranges", which you can read about here:
# https://docs.npmjs.com/cli/v6/using-npm/semver#ranges
[Relations.Depends]
TModLoader = ">=2024"
[Relations.Suggests]
HighFPSSupport = "*" # Asterisk means absolutely any version.
DialoguePanelRework = "*"
TerraVoice = ">=2.0.0"
[Relations.Conflicts]
CoolerItemVisualEffects = "<=1.0.0"

# Not all of these fields will be used by TML.
[Contact]
Homepage = "https://mirsar.io/Projects/TerrariaOverhaul"
Wiki = "https://mirsar.io/TerrariaOverhaul/Wiki"
Sources = "https://github.com/Mirsario/TerrariaOverhaul"
Issues = "https://github.com/Mirsario/TerrariaOverhaul/issues"
Email = "me@mirsar.io"
Discord = "https://discord.gg/RNGq9N8"
Patreon = "https://patreon.com/Mirsario"

# Alternatively Authors and Contributors could be tables, so that
# a description of role/contributions could be provided for every person.
# Is there any need or demand for that?
[People]
Authors = [
	"Mirsario",
	"Kirbyrocket",
]
Contributors = [
	# Code
	"justreq",
	"JaksonD",
	"clownwithnoname",
	"Tenrys",
	"BAMcSH",
	"Hoabs",
	"RighteousRyan1",
	"TimeSignMaid",
	# Assets
	"czfortythree",
	"Photonic0",
	# Localization
	"Cyrillia",
	"J00niper",
	"Wolf-Igmc4",
	"Pixelnando",
	"Snoop1CattZ69",
	"orian34",
	"Foxx-l",
	"ZHAY10086",
	"CriddleZap",
	"Blueberryy",
	"cottonman132",
	"goiabae",
	"CupCat05",
]
Supporters = [
	# Looong list
]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions