Files
SurvivorCore/plugin/init.server.luau
T
Samuel LisonandClaude Opus 4.8 c118ced576 feat(plugin): add reversible edit-mode HUD preview (icons + sample fills)
Studio doesn't run the HUD client binder in Edit view, so an authored SurvivalHud
shows its static template there — full bars, blank readouts, and only the shipped
default icons (an icon override isn't visible until Play). The admin plugin now has
a footer with **Preview HUD** / **Clear** that paints, in Edit, what the running
game would render, so owners tune-and-see without pressing Play.

- plugin/HudPreview.luau (new): mirrors the engine binder's resolution — per-bar
  `Icon` attribute › the stat's effective icon (config/admin override else shipped
  default) for icons; FillAxis-aware sample fill; per-stat ValueFormat for the
  readout; a sample counter value. Every property is snapshotted once before the
  first write and clear() restores them exactly (so it's fully reversible);
  apply() takes an optional hud root for testability. Skips the Assets registry
  tier (runtime-only, empty in Edit) and never guesses engine-owned invert/dangerHigh.
- StatAdminUi: a footer bar with Preview / Clear buttons + a status readout.
- init.server: wires both through ChangeHistory (each is one undo step).
- Verified in Studio: synthetic-HUD logic test (icon resolution, sample fill/value,
  exact restore) + a live visual pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 19:26:54 +10:00

94 lines
3.3 KiB
Luau

--!nonstrict
--[[
SurvivorCore Survival Stats admin plugin (main).
A toolbar button toggles a dock widget that edits the survival-stats `SurvivalStatsConfig`
instance through StatAdmin the deltas-only, LOCKED model: it writes only fields the owner
changes from the engine default, removes them on reset, and can NEVER write the engine-owned
semantics (Invert / DangerHigh). Edits are wrapped in ChangeHistoryService recordings so each
is a single undo step. All real logic lives in StatAdmin (testable); the form in StatAdminUi.
First slice of the Builder / Admin plugin (issue #11).
]]
local ChangeHistoryService = game:GetService("ChangeHistoryService")
local StatAdmin = require(script.StatAdmin)
local StatAdminUi = require(script.StatAdminUi)
local HudPreview = require(script.HudPreview)
local toolbar = plugin:CreateToolbar("SurvivorCore")
local button = toolbar:CreateButton("Survival Stats", "Tune survival-stat rates, thresholds and HUD options", "")
button.ClickableWhenViewportHidden = true
-- CreateDockWidgetPluginGui is flagged deprecated by the tooling, but it is still the only
-- API for a dockable plugin widget (there is no replacement) — so allow it here.
-- selene: allow(deprecated)
local widget = plugin:CreateDockWidgetPluginGui(
"SurvivorCoreStatAdmin",
DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Right, false, false, 320, 520, 280, 360)
)
widget.Title = "Survival Stats"
widget.Name = "SurvivorCoreStatAdmin"
local container = Instance.new("Frame")
container.Size = UDim2.fromScale(1, 1)
container.BackgroundColor3 = Color3.fromRGB(18, 21, 28)
container.BorderSizePixel = 0
container.Parent = widget
local ui: { refresh: () -> () }? = nil
-- Wrap a single StatAdmin mutation in one ChangeHistory recording (so it's one undo step),
-- then refresh the form so the override indicators reflect the new state.
local function record(name: string, mutate: () -> any): any
local recording = ChangeHistoryService:TryBeginRecording(name)
local result = mutate()
if recording then
ChangeHistoryService:FinishRecording(recording, Enum.FinishRecordingOperation.Commit)
end
if ui then
ui.refresh()
end
return result
end
local function applyEdit(statName: string, attr: string, raw: any, default: any): any
return record(`Survival Stats: {statName}.{attr}`, function()
return StatAdmin.setOverride(statName, attr, raw, default)
end)
end
local function applyReset(statName: string, attr: string): any
return record(`Survival Stats: reset {statName}.{attr}`, function()
return StatAdmin.resetOverride(statName, attr)
end)
end
-- Edit-mode HUD preview (paints resolved icons + sample fills onto the StarterGui HUD) and its
-- undo-able restore. Each is one ChangeHistory step; both return the HudPreview result so the
-- footer can show a status.
local function applyPreview(): any
return record("Survival Stats: preview HUD", function()
return HudPreview.apply(StatAdmin)
end)
end
local function applyClear(): any
return record("Survival Stats: clear HUD preview", function()
return HudPreview.clear()
end)
end
ui = StatAdminUi.mount(container, StatAdmin, applyEdit, applyReset, applyPreview, applyClear)
button.Click:Connect(function()
widget.Enabled = not widget.Enabled
if widget.Enabled and ui then
ui.refresh()
end
end)
widget:GetPropertyChangedSignal("Enabled"):Connect(function()
button:SetActive(widget.Enabled)
end)