Steam Community :: tModLoader

We’ve done tons of TML work in May, and June’s Stable release is now here to bring that to you.

Changes’ Highlights

The following is a list of the most noteworthy pull requests and commits that have been pushed to 1.4-preview in May, and are now available on the 1.4-stable branch.

tModPorter[] by Chik3r and Chicken-Bones


tModPorter has now been added to tModLoader as an official module on 1.4 preview. It will see more updates over the next while, but it is now at a reasonable release point.

tModPorter itself is a custom software that helps mod developers transition away from 1.3 by automatically handling several of the breaking changes that we’ve introduced.
However, it is not perfect – some work will still be needed, but it is hoped it will carry the brunt of the manual labor.

Associated launcher files are included in the tModPorter folder in the Install Folder for tModLoader, as well as a button in-game to shortcut to that.

Note that this is tModLoader’s first update with it – so if you encounter bugs, please let us know.

Additionally, please note that many more automatic ports will be added to tModPorter in the next few days. You can help Chicken-Bones prioritize by posting things you’d most like to see automatically ported in the tModPorter Discord thread[].

The Grand Sound Playback Reimplementation[] by Mirsario

Porting Notes: #preview-update-log in Discord[]

After 9 years in development, hopefully it will be worth the wait.
ModSound and SoundLoader have both been removed. As well as the Mod.SoundAutoloadingEnabled property.
LegacySoundStyle and CustomSoundStyle were removed. SoundStyle is now a struct (record), which contains everything a sound playing enthusiast would need: AssetRepository-based paths; Volume, pitch and looping control; Numbered suffix variants with even weighted random supported; Sound instance limits and their behavior; And etc., etc.
• All sound playback is now done through one method – SlotId SoundEngine.PlaySound(SoundStyle style, Vector2? position = null).
All legacy (int type, int style) overloads have been removed from the API.
• I went through the pains of entirety converting all SoundID entries to the new SoundStyles, which means that you can now not only replicate vanilla sound playbacks, but also modify their copies with ease. I suggest getting familiar with the x with { A = B } syntax, it’s great here.
• A few improvements may follow later, but they’re unlikely to be breaking changes.

‘Item Use Rework’ – Proper Implementation[] by Chicken-Bones, DarioDaf, ThomasThePencil, einarmo, rjmarzec, and Mirsario

Porting Notes: #preview-update-log in Discord[]

Basically, this cleans up a long standing set of TML bugs resulting from an attempted fix for a vanilla issue (#1437) with unpredictable item usage frames relative to their animations that was preventing modders from implementing their ideas.

Add Mod/GlobalType NewInstance, IsCloneable, Clone and CloneNewInstances[] and Add CloneByReference attribute, improve IsCloneable logic[] by Chicken-Bones


• By demand of mod developers, a design change that was part of the OnSpawn Pull Request has been reverted, and CloneNewInstances from 1.3 is back, again set to false by default, like in 1.3. This revert may be temporary in case the team comes up with superior designs in the later months.
• TML tries to make sure that all ModItem and instanced GlobalItem derivatives return true from IsCloneable, logging warnings otherwise.
• If the default IsCloneable implementation returns false, but your item is cloneable via MemberwiseClone (because you have reference fields which don’t change once the item is spawned/loaded) – you can do ‘override IsCloneable => true‘.
• Added [CloneByReference] attribute for fields that are safe to share between clones (because they’re shared, or not modified after Load/SetDefaults)

Restoration of Mod Trees Part 1: Re-Forestation[] by Solxan

Porting Notes: #preview-update-log in Discord[]

• This re-adds the ModTrees, ModPalmTrees, ModCactus support from 1.3 as they were. Consider this a bug fix PR, not a feature rework/API cleanup
• This does not add 1.4 content unless it was specifically required for these to work
• This is NOT the final PR, and we do expect future breaking changes as outlined in / in support of Issue #1347[].

JIT mods on load and allow extending from types in weak-refs[] by Chicken-Bones and jopojelly

Porting Notes: #preview-update-log in Discord[]

All mods will now be Just-In-Time compiled on load. This will detect mods that silently break as tModLoader changes and disable them instead of allowing them to silently cause errors. A side effect of this is that weak referenced Types will cause the mod to fail to load, so mod developers weakly referencing other mods will need to utilize the [JitWhenModsEnabled] attribute to annotate classes, methods, or properties using those Types to bypass this checking. See the details in the Pull Request for more information on this and more advanced situations.

Additionally, we now support inheriting from base classes in weakly referenced mods. Such classes need to be annotated with the [ExtendsFromMod] attribute to inform tModLoader not to attempt to autoload the class. A side effect of this capability is that mods should no longer call Assembly.GetTypes() on other mod assemblies, as this could fail now. They should now use AssemblyManager.GetLoadableTypes(Assembly) to retrieve all Types that should be considered from other mods.

Re-implemented internal names for AddEquipTexture() and ported the equip methods from Mod to EquipLoader[] by IbanPlay

Porting Notes: #preview-update-log in Discord[]

Mod.AddEquipTexture(…) got turned into EquipLoader.AddEquipTexture(…), and it can now be used to register equipment textures through an internal name instead of being locked into using the name of their associated item as an internal name. This also allows mods to register equip textures without needing an item reference, and most importantly, allows them to register multiple equip textures of the same type for the same item.

Accept dots in HJSON[] by Ishigh1


HJSON localization improvements:
• Periods can now be used in keys;
It’s now possible to write Mods.YourMod: { } in place of Mods: { YourMod: { } }.
• Arrays item paths are now properly handled as well;
Every array item will now have a period-separated key: AnArray.42.SomethingInsideArrayItem.

PickAmmo Rework + better Shoot mechanics[] by ThomasThePencil and Chicken-Bones

Porting Notes: #preview-update-log in Discord[]

• Ammo damage modifiers are selected based on the DamageClass of the ammo
• Added Mod/GlobalItem.CanChooseAmmo hooks.
• PickAmmo hook now has a StatModifier damage parameter.
• Added AmmoID.Sets IsArrow, IsBullet and IsRocket.

Allow Guns to shoot with no ammo[] by DarkLight66


Adds bool Global/ModItem.NeedsAmmo() hook, allowing for weapons which can shoot their default projectile without ammo under certain conditions (like if you had a free ammo buff.)

New NPC hover-with-mouse hooks[] by ThomasThePencil


• Adds NPC.ShowNameOnHover defaulting to true. Can be changed in SetDefaults or AI to hide the hover mouse text
• Adds Mod/GlobalNPC.ModifyHoverBoundingBox(ref Rectangle boundingBox) for custom hover text rect control.

NPC Capture-related hook expansion[] by ThomasThePencil

Porting Notes: #preview-update-log in Discord[]

• Adds CatchingTool and LavaproofCatchingTool Item Sets for creating new bug net type items
• Greatly enhances the hooks for CatchNPC
• A few changes to existing Catch related hooks to be wary of
• Read more in the PR.

Add GlobalProjectile Send/ReceiveExtraAI[] by terrynmuse


void SendExtraAI(Projectile projectile, BitWriter bitWriter, BinaryWriter binaryWriter)
void ReceiveExtraAI(Projectile projectile, BitReader bitReader, BinaryReader binaryReader)

Recipe Ordering[] by Ishigh

Porting Notes: #preview-update-log in Discord[]

• Added methods to allow control of ordering for recipes, for example keeping modded wood with vanilla wood.
• All mods that call Recipe.Register() or RemoveRecipes will need to be updated and/or rebuilt.

Fix Item/NPC/Projectile.CloneDefaults duplicating globals[] by Chicken-Bones


• Does what it says on the can.
CloneDefaults will fully now initialize the item/npc/projectile as another type, and then restore the mod-x and global-x from the original item type.
• You’re only really meant to call this from ModX.SetDefaults.

MonoMod-related Fixes


Fellow code injection abusers and users of mods from them will love to hear this:
We’ve updated to a dev build of MonoMod (the code injection library we use to allow mod developers to more freely modify the game) to get a fix for a process freeze that could super rarely occur during injections, and discovered that specifically that same fix (tied to an unforeseen change the .NET 6 runtime) has also sped up code injections by over ten times.
Thanks and much love to 0x0ade for making MonoMod and collaborating with us!

Show New and Updated mods on launch in an info box[] by direwolf420


We’ve added a notification window when you launch to see which subscribed mods have updated since the last time you played. This will help you track when your favorite mods update so you can check them out for new features. This will also help you if a mod is broken and you want to remember to re-enable it when it updates.

Reload Mods button changes [] by jackbondpreston


Mods will now automatically reload when exiting the Mods menu. This has caused some confusion in the past as users did not know they needed to reload mods. This change will help simplify the new user experience.

As well as these pull requests which didn’t need large descriptions:

Chicken-Bones: Aggregate loading exceptions across content instances.[]
ThomasThePencil: Dynamic Item Scaling Hook[]
Setnour6: The Grand French Localization Update[]
Solxan: Make ModPacks Compatible with 1.4 and Steam Workshop changes[]
Ishigh: TagCompound TryGet[]
Ved-s: Added this[Point] Tilemap indexer[]

And the following self-explanatory fixes:

Solxan: Windows high DPI detection fix – Part 2[]
Solxan: Cleanup Feature for Accidental Uploaded of Mod Source Files[]
Solxan: Fixed a worldgen crash[]
Solxan: Mitigated issues with downloading deleted items in Mod Browser[]
MutanWafflez: Fix AnimationType Bug with ActsLikeTownNPC & ExtraFramesCount[]
ThomasThePencil: Fixed a bug from the damage class rework where ammo knockback was being ignored.[]

Frequently Asked Questions

When will 1.4-stable become the default branch?

In an hour? In a minute? Maybe it already happened?
The announcement post for that will follow shortly after this one, you won’t be able to miss it.

Worry not, 1.3 players – If you wish to stay on TML for Terraria – just select the ‘1.3-legacy’ branch in Steam, using instructions from the answer below.

How do I switch to the preview versions of TML?

To switch to one of the new branches, just do the following:
1. Right click on tModLoader in Steam and select ‘Properties…’, then ‘BETAS’;
2. Select ‘1.4-preview’ in the drop-down menu on top;
3. Close the window. As before, no passwords are required.

When will 1.4 TML be 64-bit???

It’s already 64-bit!
Specifically, it’s what’s called AnyCPU, but we currently only ship x86_64 natives. In addition to TML being made 64-bit-capable, it has been made to run on a ten years newer runtime (.NET 6+), far newer versions of a better game framework (FNA instead of XNA), and we’ve even unified what would’ve been 6 Windows/Linux/Mac Client/Server builds into just one portable release that can be run on every Desktop OS.
Together, all of this yells: performance, consistency, stability, possibilities, and comfort.

I have a 32-bit OS, will it be supported?

We planned to re-add support for 32-bit Windows systems for this update, but didn’t make it in time, so it’ll arrive later in June or July.

Leave a Comment