Developer
Overview
Integration with ML Smelter Stations is done through client exports, the open/ folder handlers, and server-side OpenServer functions. The open/ folder is not escrowed and can be freely modified to hook into any external system.
Client Exports
openStation
1exports.ml_smelter_stations:openStation(fixedStationId)fixedStationId(string). Theidof a fixed station fromConfig.FixedStations
Opens the station UI for a fixed station without requiring the player to interact with a prop or target zone. Triggers a server-side lock request and opens the UI on success.
1-- Open the main forge from a command or external trigger
2exports.ml_smelter_stations:openStation('main_forge_sandy')Server Handlers
Located in open/server.lua. All OpenServer functions can be modified to customize behavior.
BeforeGiveItem
1function OpenServer.BeforeGiveItem(src, item, amount)
2 return true
3endCalled before giving a crafted item to the player. Return false to block the item from being given.
OnActionComplete
1function OpenServer.OnActionComplete(src, actionType, data)
2 -- actionType: 'start_cooking', 'take_item', 'add_fuel', 'repair'
3endCalled after any station action completes. By default, this awards XP based on Config.XP.Rewards. Override to add custom logic (missions, achievements, analytics).
CanCraftTier
1function OpenServer.CanCraftTier(src, tier)
2 return true -- or false to block
3endChecks if a player meets the level requirement for a recipe tier. Returns true if XP is disabled or the player's level meets the tier threshold.
GetPlayerProgress
1function OpenServer.GetPlayerProgress(src)
2 return progressData -- or nil
3endReturns the player's full XP progress data for the UI. Includes level, totalXp, xpCurrent, xpNeeded, progress fraction, craftsCompleted, tiers, and bonuses.
GetBonuses
1function OpenServer.GetBonuses(src)
2 return { speed = 0.12, antiCarbonize = 0.20 }
3endReturns the player's current tier bonuses (cook time reduction, carbonize time extension). Based on the highest tier the player qualifies for.
AwardXp
1function OpenServer.AwardXp(src, actionType, recipeId)
2endAwards XP to the player for a specific action. Uses Config.XP.Rewards for base values, with optional Config.XP.RecipeXpOverride for per-recipe overrides.
Shared Handlers
Located in open/shared.lua.
OnPlayerAction
1function OpenHandlers.OnPlayerAction(src, data)
2 return true
3endGeneric hook for any player action. Return false to block.
ValidateAction
1function OpenHandlers.ValidateAction(src, actionType)
2 return true
3endCalled before destroy, repair, extinguish, add_fuel, and start_cooking actions. Return false to block the action. Useful for permission checks or conditional access.
Client Handlers
Located in open/client.lua.
Notify
1function OpenClient.Notify(message, type)
2 Bridge.Notify(message, type)
3endOverride to use a custom notification system.
BeforeOpenUI
1function OpenClient.BeforeOpenUI(data)
2 return true
3endCalled before the station UI opens. Return false to block the UI. By default, fetches and sends XP progression data to the UI.
Server Events
ml_smelter_stations:playerCraftingStarted
Fires on the server when a player successfully starts cooking at any station. Listen with AddEventHandler.
1AddEventHandler('ml_smelter_stations:playerCraftingStarted', function(identifier, stationType, recipeName, quantity)
2 -- identifier: player's framework identifier (from Bridge.GetPlayerId)
3 -- stationType: key from Config.Stations (e.g., 'forge', 'campfire')
4 -- recipeName: key from Config.Recipes
5 -- quantity: number of items queued
6end)Server Callbacks
These callbacks are registered via Bridge.OnServerRequest and used internally by the client.
stations:getPlayerProgress: Returns full XP progress data for the requesting playerstations:getRecipeTiers: Returns all recipe tier requirements and lock states for the requesting player
Custom XP Provider
To use a custom XP backend, set Config.XP.Provider = 'custom' and define functions in open/server.lua:
1Config.XP.CustomGetLevel = function(src)
2 return 1 -- return player level
3end
4
5Config.XP.CustomGetXp = function(src)
6 return 0 -- return total XP
7end
8
9Config.XP.CustomAddXp = function(src, amount)
10 return true -- return success
11end
12
13Config.XP.CustomGetProgress = function(src)
14 return {
15 level = 1,
16 maxLevel = 50,
17 totalXp = 0,
18 xpCurrent = 0,
19 xpNeeded = 100,
20 progress = 0,
21 craftsCompleted = 0,
22 tiers = Config.XP.Tiers,
23 }
24endExamples
1function OpenHandlers.ValidateAction(src, actionType)
2 if actionType == 'start_cooking' then
3 local job = Bridge.GetJob(src)
4 if job and job.name == 'police' then
5 Bridge.NotifyPlayer(src, 'error', 'Police cannot use crafting stations on duty.')
6 return false
7 end
8 end
9 return true
10end1local originalOnAction = OpenServer.OnActionComplete
2function OpenServer.OnActionComplete(src, actionType, data)
3 originalOnAction(src, actionType, data)
4
5 if actionType == 'take_item' then
6 PerformHttpRequest('https://api.example.com/crafting', function() end, 'POST', json.encode({
7 player = Bridge.GetPlayerId(src),
8 action = actionType,
9 timestamp = os.time(),
10 }))
11 end
12end1-- In another resource, e.g., an NPC script
2Bridge.AddEntityTarget(npcEntity, { {
3 name = 'open_forge',
4 label = 'Use Forge',
5 icon = 'fas fa-fire',
6 distance = 2.0,
7 onSelect = function()
8 exports.ml_smelter_stations:openStation('main_forge_sandy')
9 end
10} })