-
Notifications
You must be signed in to change notification settings - Fork 1
Using The Library — Mod Launcher
This is the most common use case for the library, and the main reason it was built.
All the tutorials on this page assume that your mod has the library loaded, as explained in Getting Started.
A big reason for the library is to help reduce mod size. If you want to add a change a couple of chunks to a L1_TERRA.p3d
, you don't need to include a 1.32MB file, where 99% of it is the base game's file.
If you don't already have one, create a file called CustomFiles.ini
in the root of your mod's folder. This file contains all the path handling for files that Custom Files handles.
In the PathHandlers
header, create a handler for L1_TERRA
.
[PathHandlers]
art\\L1_TERRA.p3d=Resources/HandleL1Terra.lua
Create a file in your Resources
folder, with the same name as you put in CustomFiles.ini
.
This file will be called every time L1_TERRA
is loaded. What we need to do is load the file, modify it, then Output
it back to the game.
-- Get the path - we know this is L1_TERRA, but it's good practice to make a path handler dynamically get the path
local Path = GetPath()
-- Print to console that we're starting the path handler for this file
print("LuaP3DLib path handler started", Path)
-- To read a game file, we need to get the path in the virtual file system. See the docs for more details: https://docs.donutteam.com/docs/lucasmodlauncher/hacks/cf/virtual-file-system
local GamePath = "/GameData/" .. Path
-- Create the P3DFile
local P3DFile = P3D.P3DFile(GamePath)
-- Create the Locator chunk - We'll using a type 14 to create a coin, and we'll place it at 0,0,0
local Locator = P3D.LocatorP3DChunk("Custom Coin", P3D.Vector3(0, 0, 0), 14)
-- Add the locator to the P3DFile
P3DFile:AddChunk(Locator)
-- Output the P3DFile to the game
P3DFile:Output()
Similar to adding a chunk, including an entire Pure3D file to modify a single chunk makes your mod needlessly large.
Doing it dynamically also allows for Pure3D edits based on mod settings.
For this example, we'll allow the end user to dynamically choose a colour for the radar.
As we're allowing the end user to pick the colour, we need to add a mod setting. This is done by adding a [Setting]
block to the Meta.ini
.
To add a colour setting, you can append the below to the end of Meta.ini
. More documentation can be found on the Configuring Mods page on the docs.
[Setting]
Name=RadarColour
Type=Colour
Title=Radar Colour
Default=0xFF00FF00
Alpha=0
As mod settings cannot be changed whilst the game is launched, we only need to read them once. To do this, we can create a global variable in CustomFiles.lua
.
-- Colour settings are provided as a 32bit int. We can use bitshifting to get the individual A, R, G, B values.
local function ColourToARGB(col)
return (col >> 24) & 0xFF, (col >> 16) & 0xFF, (col >> 8) & 0xFF, col & 0xFF
end
-- Create the colour table
RadarColour = {}
-- Assign the values from the setting
RadarColour.A, RadarColour.R, RadarColour.G, RadarColour.B = ColourToARGB(GetSetting("RadarColour"))
If you don't already have one, create a file called CustomFiles.ini
in the root of your mod's folder. This file contains all the path handling for files that Custom Files handles.
In the PathHandlers
header, create a handler for ingame
.
[PathHandlers]
art\\frontend\\scrooby\\ingame.p3d=Resources/HandleIngame.lua
Create a file in your Resources
folder, with the same name as you put in CustomFiles.ini
.
This file will be called every time ingame
is loaded. What we need to do is load the file, modify it, then Output
it back to the game.
Note: For this example, we have a file called radar.p3d
in the Resources
folder that contains a single Sprite
chunk.
-- Get the path - we know this is L1_TERRA, but it's good practice to make a path handler dynamically get the path
local Path = GetPath()
-- Print to console that we're starting the path handler for this file
print("LuaP3DLib path handler started", Path)
-- To read a game file, we need to get the path in the virtual file system. See the docs for more details: https://docs.donutteam.com/docs/lucasmodlauncher/hacks/cf/virtual-file-system
local GamePath = "/GameData/" .. Path
-- Create the P3DFile
local P3DFile = P3D.P3DFile(GamePath)
-- Load the P3D file from Resources
local RadarP3D = P3D.P3DFile(Paths.Resources .. "/radar.p3d")
-- Get the sprite chunk from the file
local RadarSprite = RadarP3D:GetChunk(P3D.Identifiers.Sprite)
-- Loop the P3DFile to find the original `radar.png` sprite, and replace it with the one from Resources
for ChunkIndex, Chunk in P3DFile:GetChunks(P3D.Identifiers.Sprite) do
if Chunk.Name == "radar.png" then
P3DFile.Chunks[ChunkIndex] = RadarSprite
-- Break out of the loop - there's only one `radar.png` Sprite
break
end
end
-- Get the Frontend Project chunk from the original file
local ProjectChunk = P3DFile:GetChunk(P3D.Identifiers.Frontend_Project)
-- Create a variable to store the Hud in
local Hud
-- Loop each Frontend Page in the Frontend Project, looking for `Hud.pag`
for chunk in ProjectChunk:GetChunks(P3D.Identifiers.Frontend_Page) do
if chunk.Name == "Hud.pag" then
-- Assign it to the Hud variable and break from the loop
Hud = chunk
break
end
end
-- Check we actually found the Hud
if Hud then
-- Go down the chunk hierarchy to get the Frontend Multi Sprite that displays the radar
local LayerChunk = Hud:GetChunk(P3D.Identifiers.Frontend_Layer)
local PlayerGroupChunk = LayerChunk:GetChunk(P3D.Identifiers.Frontend_Group)
local HudMapGroupChunk = PlayerGroupChunk:GetChunk(P3D.Identifiers.Frontend_Group)
local RadarGroupChunk = HudMapGroupChunk:GetChunk(P3D.Identifiers.Frontend_Group)
local RadarSprite = RadarGroupChunk:GetChunk(P3D.Identifiers.Frontend_Multi_Sprite)
-- Set the radar colour to be the global variable in `CustomFiles.lua`
RadarSprite.Colour = RadarColour
-- Output the modified file
P3DFile:Output()
end