Skip to main content

What's New in Dalamud v9

Dalamud v9 was a prior version of Dalamud, released together with Patch 6.5. This is a high-level overview of changes. You can see a code diff of all of these changes here.

Key Information

  • Branch: v9 (view on GitHub)
  • Release Date: Targeted to release alongside Patch 6.5 (estimated September/October 2023).
  • API Level: 9
  • .NET Version: .NET 7.0 / .NET 8.0

New Features

  • The console (/xllog) has been redone, and now lets you create filters that can filter to specific plugins.
  • Added a new plugin-specific logging class that you can receive as a service instance via the IPluginLog type.
    • Static functions in PluginLog have been deprecated, and we recommend that you move to the new service. They were slow and unreliable, due to having to look up the calling plugin via reflection, and won’t support new filtering features in the improved console.
    • We are planning to remove the static functions in a future API cycle.
  • Extended DtrBarEntry to now allow for a tooltip, and an OnClick event, to add even more functionality to your DTR bar entries.
  • Added IAddonLifecycle and IAddonEventManager services which simplify access to addons greatly.
  • Added comprehensive new service to acquire ImGui textures from game icons/textures via ITextureProvider, detailed below.
  • Added various new functions to manipulate colors for UI work in Dalamud.Interface.ColorHelpers.

Major Changes

General

  • All services must be used via interfaces, their implementations are now private.
    • This allows us to create per-plugin implementations of services, which will be able to safely dispose of plugin-specific resources - something we have never been able to do before reliably - and opens up the possibility of creating mocks that allow for testing outside of the game.
    • We can also now build features that rely on detecting what plugin is using a service, like plugin-scoped logs and reliable command lists.
    • To migrate, you only have to change the type used to the interface equivalent in the Dalamud.Plugin.Services namespace (e.g. DataManager => IDataManager)
  • IDataManager.ClientOpcodes and IDataManager.ServerOpcodes have been removed. Dalamud systems that use opcodes directly will now use hooks instead. We recommend any plugin that has been using these opcodes to switch to hooks.

UI and ImGui

  • The UiBuilder.OpenMainUi event has been added, which you should subscribe to to open your plugin's "main interface", if applicable
    • This is shown as a separate, highlighted button in the plugin installer, in addition to the already existing OpenConfigUi button
  • Texture- and Icon-related functions on DataManager have been removed and are now available in a new service, ITextureProvider.
    • API has been simplified in a major way and now properly supports high-resolution textures
    • Icons and textures are now only loaded once globally when requesting them using this service, reducing memory usage
    • Icons and textures are now automatically unloaded if not drawn for more than 2 seconds, and will be reloaded transparently if they are accessed again by your plugin
    • An API that allows plugins to replace paths to tex files has been added. This means that you no longer manually have to implement this functionality to make your plugin compatible with e.g. UI mods.
    • ITextureProvider is designed for ImGui specific use cases. Plugins that need to work with raw tex files should implement their own logic.
  • All Dalamud APIs that interact with textures now return IDalamudTextureWrap, and IDalamudTextureWrap no longer inherits from the TextureWrap type in ImGuiScene. This has been done to decouple the public API from ImGuiScene, and to remove the need for plugins to reference it.
    • To migrate, you merely need to switch the types used. The exposed API is exactly the same.
    • IDalamudTextureWrap.Size (Vector2) has been added, finally.
  • IDisposable ImGui-helpers have been moved to the main Dalamud assembly and are now accessible via the Dalamud.Interface.Utility namespace
    • We recommend using these for any new UI, as they are much safer and reduce the chance of crashes caused by misbehaving UI code

Hooking

  • Obsolete constructors for Hook<T> and the static Hook<T>.FromX() functions have been removed.
    • Please use the equivalent functions in the IGameInteropProvider service
    • IGameInteropProvider.HookFromSignature() has been added
  • SignatureHelper.Initialize() has been removed. Please use IGameInteropProvider.InitializeFromAttributes().

Minor Changes

  • Util.HttpClient has been removed in favor of allowing plugins to manage their own HTTP lifecycles.
    • You can use Dalamud.Networking.Http.HappyEyeballsCallback as your SocketsHttpHandler.ConnectCallback to enable improved IPv6 connection handling to dual-stack servers.
  • SeStringManager has been removed. Please use SeStringBuilder instead.
  • ChatHandlers has been removed.
    • ChatHandlers.IsAutoUpdateComplete is now available as DalamudPluginInterface.IsAutoUpdateComplete
    • ChatHandlers.MakeItalics() can be accessed via SeStringBuilder
  • Util.CopyTo() has been removed, as it has been added to the standard library as Stream.CopyTo().
  • DalamudPluginInterface.PluginNames and PluginInternalNames have been replaced in favor of InstalledPlugins, which provides more context.
  • Obsolete/non-functional icons in FontAwesomeIcon have been removed.
  • DataManager.IsDataReady has been removed, as it is always true when plugins are loaded.
  • SeStringBuilder.AddItemLink() now correctly adds a full item link, instead of only adding an ItemPayload.
  • Util.IsLinux() has been changed to Util.IsWine(). Util.GetHostPlatform() has been added to get the actual platform the game is running on - this relies on a special env var that may not be present on all environments Dalamud can run under yet.
  • The Serilog property SourceContext is no longer used for Dalamud systems. Plugins implementing their own logging systems should write their plugin internal name to the Dalamud.PluginName property instead, otherwise, filtering in the new console will not work.
  • UIBuilder.GposeActive has been moved to IClientState.IsGPosing, and is now more reliable/will only be true if the user is actually in GPose.
  • IDalamudPlugin.Name has been removed. This has not been shown anywhere in more than 2 years.
  • Dev-Plugins without a manifest are no longer supported. Please have a manifest or use DalamudPackager!
  • Most FlyTextKind enum members have been renamed, see commit here.

Errata

These changes have been made after the official stabilization.

  • SigScanner was mistakenly made internal, making it impossible for plugins to create their own scanners
    • SigScanner was made public with the same API, and the internal service implementation was decoupled

Contributors

We want to thank the following people for their contributions to Dalamud during this patch cycle:

  • MidoriKami
  • Haselnussbomber
  • kalilistic
  • Soreepeong
  • nebel
  • Caraxi
  • Ottermandias
  • Aireil

FFXIVClientStructs changes

These are relevant changes made to FFXIVClientStructs, listed here for reference. We want to thank aers, Pohky, WildWolf and the other FFXIVClientStructs contributors for their work.

From a593cb163e1c5d33b27d34df4d1ccc57d1e67643, as of commit 0af185ef155cf03f24c2dee8f50f3973a7d417aa:

Client/Game/ActionManager.cs:

  • Changed UseAction to take a ulong instead of long for targetID
  • Changed UseActionLocation to take a ulong instead of long for targetID
  • Changed GetActionStatus to take a ulong instead of long for targetID

Client/Game/ActionTimelineManager.cs:

  • Added Parent character pointer
  • Added GetHeightAdjustActionTimelineRowId

Client/Game/Character/Character.cs:

  • Changed ActionRecipientsObjectIdArray to be ulong instead of long
  • Added EmoteController
  • Added CalculateHeight

Client/Game/Character/CharacterManager.cs:

  • Changed LookupBattleCharaByObjectId to take a uint instead of int

Client/Game/Control/TargetSystem.cs:

  • Changed GetCurrentTargetID to return ulong instead of uint
  • Changed GameObjectArray.Objects to be ulong instead of long

Client/Game/InstanceContent/PublicContentDirector.cs:

  • Added HandleEnterContentInfoPacket

Client/Game/InventoryManager.cs:

  • Changed MoveItemSlot to use ushort instead of uint for slot

Client/Game/Object/GameObject.cs:

  • Removed long operators

Client/Game/QuestManager.cs:

  • Removed Obsolete fields and structs

Client/Game/RetainerManager.cs:

  • Removed Obsolete fields and structs
  • Changed RetainerList.Retainer to Retainer
  • Changed functions from RetainerList.Retainer to Retainer

Client/Game/UI/Map.cs:

  • Added MarkerInfo.ShouldRender field
  • Removed obsolete fields and structs

Client/Graphics/Kernel/Notifier.cs:

  • Changed namespace to match file location

Client/Graphics/Kernel/Texture.cs:

  • Changed namespace to match file location

Client/Graphics/Scene/CharacterBase.cs:

  • Changed ColorSetTextures to ColorTableTextures
  • Changed ColorSetTexturesSpan to ColorTableTexturesSpan

Client/System/Framework/Framework.cs:

  • Added TaskManager field

Client/System/Resource/Handle/ResourceHandle.cs:

  • Added Unknown0A field
  • Added Expansion field
  • Added UserData field
  • Added LoadState field
  • Added LoadIntoKernel method
  • Added Load method
  • Added GetUserData method

Client/System/Resource/ResourceGraph.cs:

  • Changed ResourceCategory to be a ushort

Client/UI/AddonLookingForGroupDetail.cs:

  • Added RelayPartyFinderInfoButton field
  • Added CategoryImageNode field

Client/UI/AddonRecipeNote.cs:

  • Changed many Unk fields to AtkTextNode*

Client/UI/AddonSalvageItemSelector.cs:

  • Changed ItemsData to Items with a fixed size array

Client/UI/Agent/AgentContext.cs:

  • Changed ContextMenu.EventParams to be a fixed array

Client/UI/Agent/AgentFriendList.cs:

  • Added SelectedPlayerName, SelectedContentId and SelectedIndex fields

Client/UI/Agent/AgentHudLayout.cs:

  • Changed namespace to FFXIVClientStructs.FFXIV.Client.UI.Agent

Client/UI/Agent/AgentReadyCheck.cs:

  • Changed ReadyCheckEntries from FixedArray to FixedSizeArray

Client/UI/Agent/AgentRetainerList.cs:

  • Changed Retainers to fixed array

Client/UI/Agent/AgentSalvage.cs:

  • Changed DesynthResult to DesynthResults and changed FixedArray to FixedSizeArray

Client/UI/Info/InfoProxyCommonList.cs:

  • Changed Data to CharData
  • Changed ContentID to ulong
  • Changed GetContentIDForEntry to return ulong
  • Removed CharIndex field from InfoProxyCommonList
  • Removed CharacterDict and CharacterArray from InfoProxyCommonList
  • Moved OnlineStatus, MentorState, PartyStatus, DutyStatus to single OnlineStatus enum linked to bitflag of OnlineStatus.exd
  • Added Sort field
  • Added ExtraFlags field

Client/UI/Info/InfoProxyCatalogSearch.cs:

  • Was InfoProxyItemSearch

Client/UI/Info/InfoProxyItemSearch.cs:

  • Was InfoProxy11
  • Changed SelectedItemId to SearchItemId
  • Changed GlobalItemId to ListingId
  • Added RetainerListings
  • Added RetainerListingsCount
  • Added PlayerRetainers

Client/UI/Misc/CharaViewPortrait.cs:

  • Changed DirectionalLightingVerticalAngle and DirectionalLightingHorizontalAngle to be signed

Client/UI/Misc/ItemOrderModule.cs:

  • Changed RetainerSorter to be a StdMap<ulong, Pointer<ItemOrderModuleSorter>>
  • Removed RetainerSorterCount

Client/UI/Misc/RaptureGearsetModule.cs:

  • Changed Gearset to be a fixed array named Entries
  • Changed IsValidGearset to return bool instead of byte
  • Changed CreateGearset to return sbyte instead of uint
  • Changed HasLinkedGlamourPlate to return bool instead of byte
  • Changed IsGearsetLinkedWithBanner to HasLinkedBanner
  • Changed GetBannerIndexByGearsetIndex to GetBannerIndex
  • Changed SetBannerIndexForGearsetIndex to SetBannerIndex
  • Added FindGearsetIDByName
  • Added GearsetItem.Flags field
  • Changed GearsetEntry.RightLeft to be named RingLeft

Client/UI/Misc/RaptureMacroModule.cs:

  • Changed Instance to be a method instead of a property
  • Changed Individual and Shared to be fixed arrays
  • Added RaptureTextModule and TextChecker fields

Client/UI/Misc/RetainerCommentModule.cs:

  • Changed Retainers to fixed array
  • Changed SetComment to return void instead of void*

Client/UI/Shell/RaptureShellModule.cs:

  • Changed Instance to be a method instead of a property

Client/UI/UIModule.cs:

  • Changed GetUIInputData to return UIInputData*

Component/GUI/AtkComponentDragDrop.cs:

  • Added AtkDragDropInterface field

Component/GUI/AtkComponentListItemRenderer.cs:

  • Added AtkDragDropInterface field

Component/GUI/AtkDragDropManager.cs:

  • Added DragDrop1, DragDrop2 and DragDropS pointer fields
  • Added IsDragging, ReclickToDrop, MouseMoved and IsNotDiscarding bool fields

Component/GUI/AtkLinkedList.cs:

  • Obsoleted AtkLinkedList in favor of StdLinkedList

Component/GUI/AtkModule.cs:

  • Added AtkTextureResourceManager field
  • Changed DefaultTextureVersion to AtkTextureResourceManager.DefaultTextureVersion
  • Changed ExdModule to AtkTextureResourceManager.ExdModule

Component/GUI/AtkStage.cs:

  • Added AtkTextureResourceManager field

Component/GUI/AtkTextureResource.cs:

  • Changed Count_1 to Count
  • Changed Count_2 to Version
  • Added ShareCount field

Component/GUI/AtkUnitBase.cs:

  • Added ShowHideFlags field
  • Changed Show and Hide paramenters to match the game

Component/GUI/AtkUnitList.cs:

  • Changed AtkUnitEntries to fixed array named Entries;
  • Changed Count to ushort

STD/Pair.cs:

  • Added Deconstruct method to StdPair

New Files Added:

  • Component/GUI/AtkDragDropInterface.cs
  • Component/GUI/AtkTextureResourceManager.cs
  • Client/UI/UIInputData.cs
  • Client/UI/Agent/AgentScenarioTree.cs
  • Client/UI/Agent/AgentMycBattleAreaInfo.cs
  • Client/UI/Agent/AgentMiragePrismPrismItemDetail.cs
  • Client/UI/Agent/AgentItemDetail.cs
  • Client/System/Framework/TaskManager.cs
  • Client/System/Framework/Task.cs
  • Client/System/Framework/RootTask.cs
  • Application/Network/WorkDefinitions/EnterContentInfo.cs
  • Client/Game/Control/EmoteController.cs
  • Client/Game/Conditions.cs

Changed All Agents to use the new AgentGettersGenerator

Changed All VTable to vtbl