mirror of
https://github.com/TemujinCalidius/SurvivorCore.git
synced 2026-08-14 00:58:01 +00:00
Select a Part or Model in Studio, answer "what is this object?", fill a form — it becomes a gatherable node, a mob or a quest giver. Closes the gap between authoring a def and setting up a world object, which until now meant knowing to tag a part and hand-typing PascalCase attributes in the property panel. Engine — components can declare an attribute SCHEMA: - src/components/Schema.luau (new): AttributeSpec/Display/ComponentSchema types, normalize/defaults/get/list, and the schemas for Gatherable, Mob, QuestGiver. Dependency-free ON PURPOSE: the plugin requires it live at edit time, and the component modules themselves can't be required there (Harvesting asserts IsServer; Remotes creates instances in ReplicatedStorage). - Components.define now accepts EITHER the legacy `attr = default` map or a schema array, normalizing both to one ordered spec list; bind() reads the derived default map, so binding is byte-identical. Legacy maps are sorted, as `pairs` order is arbitrary and would make a UI jitter. New getSchema/ listSchemas. The three shipped components pull name/tag/display/attributes from the schema; their onSetup bodies are untouched (defaults verified identical, all 23 attributes). Plugin — the Build page: - Field.luau (new): coerce/format/equalsDefault, lifted from ConfigAdmin (which now delegates), shared by every schema-driven editor. - FieldRow.luau (new): the shared [○/●] label … control + help row, including a ⌄ picker that cycles authored ids for fields declaring `ref`. - BuildAdmin.luau (new): live schema read with three distinct empty states, selection/eligibility/identify, deltas-only attribute writes, applyType (tag + clear any other component) and clear. - BuildAdminUi.luau (new): chooser cards, grouped form, multi-select apply, stale-bind-marker warning, SelectionChanged-driven refresh. - init.server.luau: record()-wrapped buildActions + the page. Docs: docs/admin-plugin.md Build section + a 60-second walkthrough, docs/extending.md schema guide, a CONTRIBUTING rule that new creator components declare one, CHANGELOG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
37 lines
1.7 KiB
Luau
37 lines
1.7 KiB
Luau
--[[
|
||
Mob — the creature component. A creator builds (or imports) any rigged Model with a Humanoid +
|
||
PrimaryPart, tags it "Mob", and sets `MobType = "<id>"` to inherit health/speed/ranges/faction
|
||
from a `SurvivorCore.Mobs` def (authored in code or no-code via the admin plugin). Per-instance
|
||
attributes (Faction, Health, AggroRange, …) override the def for that one mob.
|
||
|
||
On setup the node is handed to the server `Mobs` runtime (`Mobs.adopt`), which resolves its
|
||
effective stats, sets the Humanoid health, and starts the AI FSM (idle/wander/chase/attack/flee).
|
||
Combat damages it like any Humanoid; per-type juice (death fade, spawn cry) attaches via
|
||
`SurvivorCore.Mobs.onReaction` — no core edits. This is the Builder-UI-drivable creature path
|
||
(#11/#14): the attribute set below is the schema the admin plugin's Mobs editor writes.
|
||
]]
|
||
|
||
local Components = require(script.Parent)
|
||
local Schema = require(script.Parent.Schema)
|
||
local Mobs = require(script.Parent.Parent.systems.Mobs)
|
||
|
||
-- Attributes + their creator-facing help text live in the schema (the Studio plugin renders this
|
||
-- component's setup form from it).
|
||
local SCHEMA = Schema.COMPONENTS.Mob
|
||
|
||
return Components.define({
|
||
name = SCHEMA.name,
|
||
tag = SCHEMA.tag,
|
||
display = SCHEMA.display,
|
||
attributes = SCHEMA.attributes,
|
||
onSetup = function(instance, _values)
|
||
-- The server Mobs runtime reads the instance attributes directly (one merge path:
|
||
-- override attr › registry def › "Mobs" Config), so nothing to stash here — just adopt it.
|
||
if instance:IsA("Model") then
|
||
Mobs.adopt(instance)
|
||
else
|
||
warn(`[Mob] '{instance:GetFullName()}' must be a Model (Humanoid + PrimaryPart) to be a mob`)
|
||
end
|
||
end,
|
||
})
|