| name | SND Artisan Integration |
| description | Use this skill when implementing crafting automation in SND macros using the Artisan plugin. Covers crafting lists, endurance mode, and crafting state management. |
Artisan Integration for SND
This skill covers integration with the Artisan plugin for crafting automation in SND macros.
Prerequisites
-- Always check plugin availability first
if not HasPlugin("Artisan") then
yield("/echo [Script] Artisan plugin not available")
StopFlag = true
return
end
Official IPC API Reference
Source: https://github.com/PunishXIV/Artisan/blob/main/Artisan/IPC/IPC.cs
All APIs below are verified against the official Artisan IPC source code.
Note: In the C# source, CraftItem uses ushort for recipeId and int for amount. In Lua, both are treated as number types.
Endurance Mode
-- Get endurance status (is endurance mode enabled)
IPC.Artisan.GetEnduranceStatus() → boolean
-- Set endurance status (enable/disable endurance mode)
IPC.Artisan.SetEnduranceStatus(boolean enabled) → nil
Crafting List Control
-- Check if a crafting list is currently processing
IPC.Artisan.IsListRunning() → boolean
-- Check if the crafting list is paused
IPC.Artisan.IsListPaused() → boolean
-- Set list pause state (only works if list is already paused)
IPC.Artisan.SetListPause(boolean paused) → nil
Stop/Resume Requests
-- Get the stop request status
IPC.Artisan.GetStopRequest() → boolean
-- Set stop request (true = stop crafting, false = resume)
-- When true: stops crafting
-- When false: resumes crafting (unless in duty finder/bound by duty)
IPC.Artisan.SetStopRequest(boolean stop) → nil
Craft Specific Item
-- Craft a specific item by recipe ID
-- Throws exception if recipe ID not found
IPC.Artisan.CraftItem(number recipeId, number amount) → nil
Busy Check
-- Check if Artisan is busy (endurance running, list processing, or tasks queued)
IPC.Artisan.IsBusy() → boolean
ArtisanMode Enum
local ArtisanMode = {
None = 0,
Endurance = 1,
Lists = 2,
}
Helper Functions
Artisan Status Checking
function IsArtisanRunning()
return IPC.Artisan.IsListRunning() and not IPC.Artisan.IsListPaused()
end
function IsArtisanPaused()
return IPC.Artisan.IsListRunning() and IPC.Artisan.IsListPaused()
end
function GetArtisanStatus()
if not HasPlugin("Artisan") then
return "not_available"
end
if IPC.Artisan.IsListRunning() then
if IPC.Artisan.IsListPaused() then
return "paused"
else
return "running"
end
else
return "idle"
end
end
Wait for Completion
function WaitForArtisanComplete(timeout)
timeout = timeout or 300 -- 5 minutes default for crafting
local startTime = os.clock()
while IsArtisanRunning() and (os.clock() - startTime) < timeout do
yield("/wait 1")
end
if IsArtisanRunning() then
yield("/echo [Script] Artisan timeout, stopping")
IPC.Artisan.SetStopRequest(true)
return false
end
return true
end
Crafting Patterns
Basic Crafting
-- Check if Artisan is running
if IPC.Artisan.IsListRunning() and not IPC.Artisan.IsListPaused() then
yield("/echo [Script] Artisan is already running")
-- Handle already running state
end
-- Start crafting
IPC.Artisan.CraftItem(recipeId, quantity)
-- Wait for crafting to complete
while IPC.Artisan.IsListRunning() and not IPC.Artisan.IsListPaused() do
yield("/wait 1")
end
Complete Crafting Workflow
function CompleteCraftingWorkflow(recipeId, quantity, timeout)
timeout = timeout or 300
-- Check prerequisites
if not HasPlugin("Artisan") then
yield("/echo [Script] ERROR: Artisan plugin not available")
return false
end
if not Player.Available then
yield("/echo [Script] ERROR: Player not available")
return false
end
-- Check if already running
if IsArtisanRunning() then
yield("/echo [Script] Artisan is already running")
return true
end
-- Start crafting
yield("/echo [Script] Starting crafting: Recipe " .. recipeId .. " x" .. quantity)
IPC.Artisan.CraftItem(recipeId, quantity)
-- Wait for completion
if WaitForArtisanComplete(timeout) then
yield("/echo [Script] Crafting completed successfully")
return true
else
yield("/echo [Script] Crafting failed or timed out")
return false
end
end
Crafting with Retry
function CraftWithRetry(recipeId, quantity, maxRetries, timeout)
maxRetries = maxRetries or 3
timeout = timeout or 300
for attempt = 1, maxRetries do
if CompleteCraftingWorkflow(recipeId, quantity, timeout) then
return true
end
if attempt < maxRetries then
yield("/echo [Script] Crafting attempt " .. attempt .. " failed, retrying")
yield("/wait 5")
end
end
yield("/echo [Script] Crafting failed after " .. maxRetries .. " attempts")
return false
end
Pause and Resume
function PauseArtisan()
if not HasPlugin("Artisan") then
return false
end
-- Use SetStopRequest(true) to stop crafting
IPC.Artisan.SetStopRequest(true)
yield("/echo [Script] Artisan stop requested")
return true
end
function ResumeArtisan()
if not HasPlugin("Artisan") then
return false
end
-- Use SetStopRequest(false) to resume crafting
-- Note: Won't resume if in duty finder or bound by duty
IPC.Artisan.SetStopRequest(false)
yield("/echo [Script] Artisan resume requested")
return true
end
function StopArtisan()
if not HasPlugin("Artisan") then
return false
end
IPC.Artisan.SetStopRequest(true)
yield("/echo [Script] Artisan stopped")
return true
end
-- Check if Artisan is busy with anything
function IsArtisanBusy()
if not HasPlugin("Artisan") then
return false
end
return IPC.Artisan.IsBusy()
end
Endurance Mode
Monitor Endurance Status
function CraftingWithEnduranceCheck(recipeId, quantity)
-- Start crafting
IPC.Artisan.CraftItem(recipeId, quantity)
-- Monitor crafting progress
while IsArtisanRunning() do
-- Check endurance status
if IPC.Artisan.GetEnduranceStatus() then
yield("/echo [Script] Endurance is active")
end
yield("/wait 1")
end
yield("/echo [Script] Crafting completed")
end
Error Handling
Safe Artisan Calls
function SafeArtisanCall(functionName, ...)
if not HasPlugin("Artisan") then
return nil, "Artisan plugin not available"
end
local success, result = pcall(function()
return IPC.Artisan[functionName](...)
end)
if success then
return result, nil
else
return nil, "Artisan call failed: " .. tostring(result)
end
end
Timeout Handling
local startTime = os.clock()
while IsArtisanRunning() and (os.clock() - startTime) < 300 do
yield("/wait 1")
end
if IsArtisanRunning() then
yield("/echo [Script] WARNING: Crafting taking too long, stopping...")
IPC.Artisan.SetStopRequest(true)
end
State Machine Integration
CharacterState = {
ready = Ready,
crafting = Crafting,
-- ... other states
}
function Crafting()
if CompleteCraftingWorkflow(recipeId, quantity, 300) then
yield("/echo [Script] Crafting completed")
State = CharacterState.ready
else
yield("/echo [Script] Crafting failed")
State = CharacterState.ready
end
end
Character Condition Integration
-- Character conditions for crafting
local CharacterCondition = {
craftingMode = 5,
executingCraftingSkill = 40,
craftingModeIdle = 41
}
-- Check if character is in crafting mode
if Svc.Condition[CharacterCondition.craftingMode] then
yield("/echo [Script] Character is in crafting mode")
end
-- Check if character is executing crafting skill
if Svc.Condition[CharacterCondition.executingCraftingSkill] then
yield("/echo [Script] Character is executing crafting skill")
end
-- Check if character is busy (including Artisan)
function IsCharacterBusy()
return Svc.Condition[CharacterCondition.casting] or
Svc.Condition[CharacterCondition.betweenAreas] or
Svc.Condition[CharacterCondition.beingMoved] or
Svc.Condition[CharacterCondition.craftingMode] or
Svc.Condition[CharacterCondition.executingCraftingSkill] or
IsArtisanRunning() or
Player.IsBusy
end
Configuration Variables
configs:
EnableArtisan:
default: true
description: Enable Artisan crafting
CraftingTimeout:
default: 300
description: Crafting timeout in seconds
MaxCraftingRetries:
default: 3
description: Maximum crafting retry attempts
CrafterClass:
default: "Carpenter"
description: Select the crafting class to use
is_choice: true
choices: ["Carpenter", "Blacksmith", "Armorer", "Goldsmith", "Leatherworker", "Weaver", "Alchemist", "Culinarian"]
ScripColor:
default: "Orange"
description: Type of scrip to use
is_choice: true
choices: ["Orange", "Purple"]
Best Practices
- Always check plugin availability before using Artisan
- Use longer timeouts for crafting operations (default: 300s / 5 minutes)
- Check crafting state before starting new crafting
- Monitor endurance status for long crafting sessions
- Use appropriate wait times: 1s for crafting monitoring
- Stop crafting on timeout to prevent stuck states
- Check character conditions for crafting mode status