Commit Graph
62 Commits
Author SHA1 Message Date
Samuel Lison a9bbedd9cd Merge pull request #47 from TemujinCalidius/feat/landing-page
docs: SurvivorCore landing page + README refresh
2026-07-01 09:19:34 +10:00
Samuel LisonandClaude Opus 4.8 e674772a45 docs: add SurvivorCore landing page + refresh README
A static landing page (site/) deployed to GitHub Pages via Actions:
- AI-generated brand: the survival-shield logo (favicon → 1024 + .ico) and an
  atmospheric campfire hero, on the docs/design-language palette.
- Sections: hero, value props, feature grid (stats, inventory/crafting, gathering,
  combat, mobs & AI, no-code admin), an "in action" showcase with the demo videos,
  and a get-started/install panel. Dark translucent theme, responsive, self-contained.
- README refreshed to v0.5.0 with the full feature set, badges, and the site link.

The "See it in action" screenshot (site/assets/img/ui-showcase.png) drops in next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:18:20 +10:00
Samuel Lison 16608201bf Merge pull request #45 from TemujinCalidius/dev
release: v0.5.0 → main
v0.5.0
2026-06-25 20:22:52 +10:00
Samuel Lison 7c89683e4e Merge pull request #44 from TemujinCalidius/release/v0.5.0
chore(release): v0.5.0
2026-06-25 20:21:54 +10:00
Samuel LisonandClaude Opus 4.8 4d910a3b89 chore(release): v0.5.0
Promote CHANGELOG Unreleased → 0.5.0 and bump wally.toml. (SurvivorCore.VERSION
is already 0.5.0 in src/init.luau.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:21:08 +10:00
Samuel Lison 9a09d997a9 Merge pull request #43 from TemujinCalidius/feat/mob-combat
feat: mob & AI engine + combat (melee + ranged)
2026-06-25 20:20:02 +10:00
Samuel LisonandClaude Opus 4.8 2c68bcc6b0 feat: mob & AI engine + combat (melee + ranged) (#17, #12, #14)
Mob & AI engine (#17): a `Mob` component + a `Mobs` FSM runtime
(idle/wander/chase/attack/flee/leash/death), faction-driven profiles
(hostile/passive/neutral), Humanoid-based mobs so combat/health/death share one
path, per-mob-type reactions, and a `Mobs` Config section.

Combat (#12, #14): server-authoritative melee + ranged reusing the v0.4.0 swing
pipeline; the `combat:hit`/`combat:kill` kill-event schema designed once. Bows use
a TCE-style aim (hold RMB to aim with an over-the-shoulder camera + crosshair and
charge ring, hold LMB to draw, release to fire); the server simulates the gravity
arc and sends the path so the client flies a cosmetic arrow along the real curve.
Arrows are their own configurable ammo item (weight/damage/curve/range/speed).

No-code: admin plugin gains Mob, Weapon and Arrow editors (+ "Add to World" /
"Tool model" drops); the engine loads Weapons/Arrows/Mobs from SurvivorCoreContent.

Fix: scope the orphan hotbar-pin sweep to the removed/consumed item, so consuming
one item never clears an unrelated hotbar-pinned weapon.

Docs: combat.md + mobs.md (with demo video); CHANGELOG Unreleased entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:18:51 +10:00
Samuel Lison 92dbf956da Merge pull request #42 from TemujinCalidius/main
chore: sync docs (v0.4.0 videos) main → dev
2026-06-24 16:13:40 +10:00
Samuel Lison 3e97b4f502 Merge pull request #41 from TemujinCalidius/docs/v0.4.0-videos
docs: link v0.4.0 demo videos
2026-06-24 16:13:03 +10:00
Samuel LisonandClaude Opus 4.8 8606564b83 docs: link v0.4.0 demo videos (gathering/crafting + no-code content)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 16:12:21 +10:00
Samuel Lison ddaacb96bf Merge pull request #38 from TemujinCalidius/dev
release: v0.4.0 → main
v0.4.0
2026-06-24 15:46:58 +10:00
Samuel Lison aa84746520 Merge pull request #37 from TemujinCalidius/release/v0.4.0
chore(release): v0.4.0
2026-06-24 15:46:24 +10:00
Samuel LisonandClaude Opus 4.8 76cdd17b97 chore(release): v0.4.0 — promote CHANGELOG (gather/craft + no-code content), bump version
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 15:45:48 +10:00
Samuel Lison afad44c204 Merge pull request #36 from TemujinCalidius/feat/gather-craft
feat: tool-swing harvesting, hand crafting & no-code content (#1, #4, #11)
2026-06-24 15:44:38 +10:00
Samuel LisonandClaude Opus 4.8 d679850f90 feat: tool-swing harvesting, hand crafting & no-code content (#1, #4, #11)
Closes the gather → craft loop and lays the no-code content layer.

- Tool-swing harvesting (#1): equip a hotbar tool (a real Tool via the new
  ToolEquip bridge), click a node, server-validated hit (range / line-of-sight
  / equipped tool / cooldown) granting a per-hit random yield, blocking the hit
  when the inventory is full. Bare-hand hold-E kept. The engine's first
  client-input → RemoteEvent → server-validation pipeline (combat reuses it).
  A floating HP bar shows a node's remaining hits.
- Hand crafting (#4): server-authoritative consume → produce with a
  complexity-scaled craft channel + a progress bar above the crafter; a
  Crafting tab lists hand recipes and gates each on what you carry.
- No-code content (#11, Builder first slice): a Resources registry + a
  content-from-instances loader (Registry.loadFromFolder reads a
  SurvivorCoreContent folder at start), Gatherable binds to a named Resource,
  and a per-resource-type reaction API (reed sways, tree fells + leaves a
  stump). The admin plugin becomes one widget with Stats + Content tabs to
  create/edit items + gatherables, including "Add to World".

New hooks: gather:blocked, craft:start / craft:end / craft:blocked. Docs +
CHANGELOG. Engine stays content-free; the demo supplies the sample content.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 15:43:34 +10:00
Samuel Lison c9bf78300e Merge pull request #34 from TemujinCalidius/dev
release: v0.3.0 → main
v0.3.0
2026-06-23 18:05:29 +10:00
Samuel Lison 2b705487e5 Merge pull request #33 from TemujinCalidius/release/v0.3.0
chore(release): v0.3.0
2026-06-23 18:04:36 +10:00
Samuel LisonandClaude Opus 4.8 f6f4fa8ebf chore(release): v0.3.0 — promote CHANGELOG (inventory/hotbar/menu UI), bump version
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 18:03:59 +10:00
Samuel Lison f70bb5b4da Merge pull request #31 from TemujinCalidius/feat/inventory-hotbar-ui
feat(ui): inventory, hotbar & tabbed menu UI (#7, #9, #3)
2026-06-23 17:57:20 +10:00
Samuel LisonandClaude Opus 4.8 1b5ef088b3 fix(hud): keep a single HUD, preferring the authored one over the fallback
Both the authored template and the built-in fallback name their ScreenGui
"SurvivalHud", and the fallback fires on a 1s timer if no bars have bound
yet. The dedupe ran only once at startup, so a fallback that raced the
template (more likely now startClient does more before the template copies
in) left two HUDs on screen — a restart usually shuffled the timing enough
to hide it, until it didn't.

Tag the fallback, make the dedupe continuous (re-runs whenever another HUD
appears) and always prefer the authored HUD, and don't build the fallback
when a HUD ScreenGui already exists. Also link the inventory/hotbar demo
video in docs/inventory.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 17:23:17 +10:00
Samuel LisonandClaude Opus 4.8 5ab855fa1b feat(ui): inventory, hotbar & tabbed menu UI (#7, #9, #3)
Server-authoritative slots+weight inventory, a 9-slot hotbar (keys 1-9),
equipment slots, and a restyleable tabbed menu (functional Inventory +
Character Sheet; Codex/Achievements/Quests scaffolded), built the engine's
way: authored ScreenGui templates + attribute-discovering binders, with a
zero-setup fallback.

- Drag-and-drop is driven by a per-frame cursor poll (immune to the grid
  ScrollingFrame that swallows InputChanged) with GUI-inset-corrected drop
  hit-testing so releases land on the actual slot.
- Menu key defaults to Tab; the engine frees it by disabling the CoreGui
  player roster (ReclaimCoreKeys) and moves the chat to bottom-left so it
  clears the top-left HUD (Chat config). Toggle ignores focused TextBoxes.
- Consumables apply onConsume via the stat-effects layer + fire item:use;
  gather yields flow into the inventory; pickups auto-pin to the hotbar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 17:06:54 +10:00
Samuel Lison 3132c8d214 Merge pull request #30 from TemujinCalidius/main
chore: forward-merge main → dev (SECURITY.md + CONTRIBUTING)
2026-06-22 10:28:10 +10:00
Samuel Lison 60f8e436a4 Merge pull request #28 from TemujinCalidius/dev
Release v0.2.1
v0.2.1
2026-06-22 10:26:49 +10:00
Samuel Lison 6547611c78 Merge pull request #27 from TemujinCalidius/release/v0.2.1
chore(release): v0.2.1
2026-06-22 10:26:09 +10:00
Samuel LisonandClaude Opus 4.8 9a10523965 chore(release): v0.2.1 — promote CHANGELOG (#20 fix), bump version
Promote the Unreleased #20 fix to 0.2.1 and bump SurvivorCore.VERSION + wally.toml.
Promotes WITHOUT re-adding an empty `## Unreleased` section, so the released
changelog on `main` doesn't carry a confusing dangling heading (a fresh
`## Unreleased` reappears when the next change adds an entry).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 10:25:46 +10:00
Samuel Lison cff8ae61fa Merge pull request #26 from TemujinCalidius/fix/hud-attribute-binding
fix(hud): custom stat `attribute` overrides now work (#20)
2026-06-22 10:06:09 +10:00
Samuel LisonandClaude Opus 4.8 2cb39109e9 fix(hud): read stats by their backing attribute, not the stat name (#20)
A stat's value lives on the player under its `attribute` (which defaults to the
name but a game can override via Config.override("SurvivalStats", {Stat={attribute=...}})).
The client read the stat NAME instead, so any custom attribute override silently
froze the bar. Fixed in all three spots that hardcoded the name:

- src/client/Hud.luau — the bar binder now resolves def.attribute and reads +
  listens on it (was GetAttribute(statName) / GetAttributeChangedSignal(statName)).
- src/systems/SurvivalConsequences.luau — the Health<->Humanoid sync writes the
  resolved Health attribute (was hardcoded "Health").
- src/client/MovementFeedback.luau — the energy vignette/breathing reads the
  resolved Energy attribute (was hardcoded "Energy").

Default behaviour (attribute = name) is unchanged. Verified in Studio: with
Health.attribute="HP" / Energy.attribute="EP", resolve() yields HP/EP and the
fixed code reads/writes there; un-overridden stats still default to the name.
Gate green.

Closes #20

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 10:05:31 +10:00
Samuel Lison 2161420033 Merge pull request #24 from TemujinCalidius/dev
Release v0.2.0 — survival stats + HUD
v0.2.0
2026-06-20 20:11:58 +10:00
Samuel Lison d37e8f2620 Merge pull request #23 from TemujinCalidius/release/v0.2.0
chore(release): v0.2.0
2026-06-20 20:11:11 +10:00
Samuel LisonandClaude Opus 4.8 586afc6b50 chore(release): v0.2.0 — promote CHANGELOG, bump version
Promote the Unreleased survival-stats + HUD milestone to 0.2.0 (start a fresh
Unreleased section) and bump SurvivorCore.VERSION + wally.toml to 0.2.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 20:10:17 +10:00
Samuel Lison a1b6f25481 Merge pull request #22 from TemujinCalidius/feat/survival-stats
Survival stats + HUD: engine, sprint/energy, consequences, admin plugin
2026-06-20 20:03:10 +10:00
Samuel LisonandClaude Opus 4.8 95d5d0b819 feat(survival): bleeding out = instant death; attach demo video to docs
- Blood reaching 0 now kills INSTANTLY (humanoid.Health = 0), not a per-second
  drain. Removed the BledOut drain rate from the Consequences config.
- Add the HUD/stats/plugin demo video to the survival-stats + admin-plugin docs.

Gate green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:57:11 +10:00
Samuel LisonandClaude Opus 4.8 3d8fd24cd9 feat(survival): realistic default rates; poison hurts only at 100%; hide Roblox health GUI
Tuning + fixes from playtest feedback:
- Poison drains health ONLY at 100% (was scaled from any level) — no more health
  ticking down from leftover/partial poison.
- Hide Roblox's built-in top-right health GUI (CoreGuiType.Health); the engine ships
  its own Health bar. (Retries a few frames since CoreGui can refuse it at session start.)
- Realistic default drift (all in config): Hunger/Thirst ~8h to max, Fatigue ~24h.
  Starving/dehydrated each take ~8h to kill (stack → ~4h when both). Default bleed/poison
  SOURCE rates ~1h (Consequences.Affliction) for real gameplay.
- Poison-at-max health drain 1.0/s and bled-out 3.0/s kept as sensible defaults (tunable).

Demo test station uses EXAGGERATED bleed/poison rates (visible in seconds) and gains
STARVE/DEHYDRATE cubes (jump the need to max) so the slow real-world consequences are
testable without waiting hours.

Gate green (stylua/selene/luau-lsp/build).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:42:40 +10:00
Samuel LisonandClaude Opus 4.8 5cafb1bf6d refactor(survival): track + disconnect SurvivalConsequences character connections
Mirrors Movement's per-character connection hygiene (store HealthChanged/Died and
disconnect on re-setup + player leave). Defensive/consistency only — Roblox already
auto-disconnects on character destroy, so no behaviour change. Follow-up from the
consequence-system adversarial review (which confirmed no real bugs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:31:58 +10:00
Samuel LisonandClaude Opus 4.8 aaac7a12af feat(survival): consequences — stats drain health, bleed-out/starvation kill
Make the survival stats matter, end to end (server-authoritative, tunable via the
new "Consequences" Config section):

- Starving (Hunger maxed) and dehydrated (Thirst maxed) drain health.
- Poison drains health scaled by its level (full rate at 100%).
- Blood at 0 → bleed out → death (fast health drain).
- Drains STACK and reduce the character's real Humanoid health, so death + Roblox
  respawn happen for free.
- Energy stops regenerating while starving, dehydrated, or fully fatigued — overriding
  the post-sprint regen, so a depleted player stays depleted until they fix the cause.

Supporting engine work:
- SurvivalConsequences system: the drain tick + keeps the "Health" stat attribute in
  lockstep with the Humanoid (HUD Health bar now reflects real damage) + resets all
  stats and clears modifiers on every (re)spawn — a fresh body, no death-loop.
- SurvivalStats: getDefinition() (read a stat's max) + resetPlayer().
- Movement: energy-regen gate reads Hunger/Thirst/Fatigue.
- Demo test station drops its hand-rolled health mirror (the engine does it now).

Verified: gate green (stylua/selene/luau-lsp/build); drain math checked (stacked = 6.5/s,
poison scales, regen gates). Tuning + behaviour ported from TheCounterEarth's StatsConfig.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:23:06 +10:00
Samuel LisonandClaude Opus 4.8 2714821697 feat(demo): survival test station (damage/feed/drink/poison/bleed + cures)
A row of ProximityPrompt parts in the demo to exercise the survival systems by
hand: DAMAGE (real Humanoid damage → death/respawn), FEED/DRINK (Hunger/Thirst
down), POISON/ANTIDOTE and BLEED/BANDAGE (start/stop rate modifiers) — each a live
call into the SurvivorCore stat-effects API, so it doubles as usage documentation.

Also mirrors the character Humanoid health into the "Health" stat attribute so the
HUD Health bar tracks damage + resets on respawn (demo scaffolding; the engine-level
Health<->Humanoid sync is tracked in the respawn/loot issue).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:59:51 +10:00
Samuel LisonandClaude Opus 4.8 b72350757f feat(movement): sprint/jump/energy + low-stat feedback (ported from TheCounterEarth)
Sprinting did nothing because Energy shipped display-only. This ports TCE's
proven movement system into the engine, server-authoritative:

- Hold Shift → sprint: drains Energy while moving, raises WalkSpeed to SprintSpeed,
  forces ExhaustedSpeed at 0 energy; Energy regenerates after an idle delay.
- Jumps cost energy and are gated below MinToJump (JumpPower → 0), with the same
  0.15s multi-signal throttle TCE uses.
- Energy is written through the stat-effects layer (Stats.adjust), so it stays a
  replicated Player Attribute the HUD already shows — no extra remotes for state.

Adds the engine's FIRST RemoteEvent plumbing (shared/Remotes.luau → SprintIntent,
created server-side, awaited client-side) and a tunable "Movement" Config section
(shared/MovementConfig.luau) carrying TCE's exact numbers + the free vignette/
breathing/heartbeat asset IDs.

Client (MovementFeedback, booted by startClient): Shift input → SprintIntent, plus
the low-stat feedback — a screen vignette + breathing loop that intensify as Energy
drops and a heartbeat loop below 40% health, all smoothed per frame.

New files: src/shared/{Remotes,MovementConfig}.luau, src/systems/Movement.luau,
src/client/MovementFeedback.luau. Wired into start()/startClient().

Gate green (stylua/selene/luau-lsp/build x3). Needs an in-Play test after a Studio
restart (Play-Solo stale-bytecode cache). Thirst/fatigue/campfire regen gating is a
follow-on with the full consequence-system port (StatsConfig is the blueprint).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:49:41 +10:00
Samuel LisonandClaude Opus 4.8 bbcbdff5fd chore(assets): vendor vignette + breathing/heartbeat sources from TheCounterEarth
Source-of-truth art for the upcoming low-stat feedback (a vignette overlay +
breathing/heartbeat loop when energy/health run low). Mirrors the icon pipeline:
sources live in demo/assets/, the engine will reference uploaded asset IDs.

- demo/assets/textures/vignette.png (4096²)
- demo/assets/audio/breathing.wav, heartbeat.wav

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:18:25 +10:00
Samuel LisonandClaude Opus 4.8 619052a790 feat(stats): dynamic per-player stat effects (adjust + rate modifiers)
The base ratePerSecond is a constant drift per stat — fine for hunger creeping
up, but it can't express event-driven, per-player behaviour: poison ticking
until cured, bleeding until clotted, sprint draining energy until you stop.
(That's why Poison/Blood ship at rate 0 and Energy is display-only.)

Adds a server-side modifier layer on top of the baseline, surfaced on
SurvivorCore.Stats once start() has run:

  - adjust(player, name, delta)       one-time signed delta, clamped to 0..max
  - addModifier(player, name, spec)   named rate modifier {ratePerSecond, source, duration?}
  - removeModifier(player, name, src) remove by source key
  - getValue(player, name)            read current value

The tick now applies base + Σ(active modifiers) per player; timed modifiers
expire on their own; a leaver's modifiers are dropped (no leak). Same-source
re-add replaces (no implicit stacking). Server-only / authoritative.

Verified: gate green (stylua/selene/luau-lsp/build); algorithm exercised in
Studio (adjust→clamp, poison modifier ticks up, cure stops it, timed expiry,
negative bleed). Foundation for sprint/jump energy + poison/bleed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:18:25 +10:00
Samuel Lison 187c272077 Merge pull request #18 from TemujinCalidius/docs/security-and-disclosure
docs: add security policy + coordinated disclosure (SECURITY.md)
2026-06-20 17:44:05 +10:00
Samuel LisonandClaude Opus 4.8 47bda58afc docs: add security policy + coordinated disclosure (SECURITY.md)
Bring SurvivorCore's coordinated-disclosure setup in line with the sibling
public repo: a public engine consumed by other games has the same
"public issue = public exploit" risk.

- SECURITY.md: private "Report a vulnerability" channel (GitHub Security
  Advisories), coordinated disclosure (ack → fix privately → release →
  publish advisory + CVE + credit), supported-versions = latest release,
  scope = engine code in this repo (games' own code/content out of scope),
  and the Roblox-specific "never trust the client / validate RemoteEvents"
  guidance. Notes selene + luau-lsp as the code-scanning equivalent since
  Luau isn't CodeQL-supported.
- CONTRIBUTING: point would-be reporters to the private channel, and
  document the multi-issue-close convention (separate `Closes #N` each).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 12:58:17 +10:00
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
Samuel LisonandClaude Opus 4.8 69bbf12be9 feat(hud): ship free default stat icons (visible in Studio Edit)
Owner relaxed the asset side of the content-free rule — assets in this repo are
free to use — so the engine now ships its generated HUD icons as defaults instead
of leaving blank slots. Two wins: the HUD is iconed out of the box, and the icons
render in Studio's EDIT view (no Play needed), so you can author/tune the HUD and
see the real thing — or edit it straight from the Explorer.

- StatDefs.luau: each of the 7 stats carries an `icon` default. Putting it here
  (not as a per-bar HUD attribute) keeps the admin-panel/config override working —
  a per-bar attribute would shadow it. resolveIcon: per-bar attr > config/def.icon
  (now the shipped id) > Assets > "".
- assets/hud/SurvivalHud.model.json: bake each bar's child `Icon` ImageLabel
  (Image + Visible=true) so it shows in edit mode; the Credits counter (no StatDefs
  entry) also gets a per-bar `Icon` attribute to drive its runtime resolution.
- Retire demo/client/HudIcons.client.luau (+ its demo.project.json mount): the
  runtime icon-assigning script is now redundant.
- Relax the docs/PR-template "content-free" wording to "design-free": free default
  ART may ship (overridable per stat); game-specific DESIGN (items/recipes/lore)
  still never ships. Updated design-language, survival-stats, CONTRIBUTING.
- CHANGELOG: record default icons + add the missing admin-plugin entry; note CI
  now builds all three Rojo targets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 19:02:39 +10:00
Samuel LisonandClaude Opus 4.8 2e7bd69c2c docs: make admin-plugin install explicit + discoverable
Owner feedback: synced the engine into a fresh place, couldn't find the admin
plugin. Root cause is a docs gap — nothing told the reader that a plugin is
installed separately from a place sync.

- admin-plugin.md: lead the Install section with the key distinction (it's a
  Studio editor tool, not place content, so an engine sync does NOT install it);
  add per-OS plugins-folder paths (macOS / Windows); spell out the restart-once /
  hot-reload-after behaviour; and note the form needs a place with the engine
  synced (else the empty state), incl. the restart-drops-unsaved-sync caveat.
- getting-started.md: link Survival Stats + the admin plugin from Next steps,
  flagging that the plugin installs separately from the engine.
- README: add a "Tuning, no code" pointer to the admin plugin from the front page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 18:33:43 +10:00
Samuel LisonandClaude Opus 4.8 4256edfd87 feat(plugin): add Survival Stats admin Studio plugin (deltas-only, locked tuning)
A Studio dock widget that lets the experience owner tune the survival stats
through a validated form instead of hand-editing Attributes on the
SurvivalStatsConfig instance — the first slice of the Builder/Admin plugin (#11).

The point is compatibility: edits are LOCKED against engine updates. StatAdmin
(the pure, headlessly-testable logic layer) writes deltas only — it sets an
attribute solely when the owner changes a field from the live engine default,
and removes it on reset / edit-back-to-default. So unset fields keep following
the (improvable) engine defaults across a SurvivorCore release, while explicit
overrides live on the owner's instance, which the engine only ever seeds and
never overwrites. Nothing tuned is lost; nothing left alone is frozen.

Hard guardrail: the plugin can read/write only the seven owner-tunable fields
(STUDIO_ATTR_MAP). A write() assert makes it impossible to ever set the
engine-owned semantics Invert / DangerHigh — re-freezing the affliction
fill-direction bug is structurally unreachable. Runtime-verified in Studio:
every write path exercised (including rejected Invert/DangerHigh attempts) left
zero banned attributes on the instance.

- plugin/StatAdmin.luau     — logic: roster, effective values, deltas-only writes
- plugin/StatAdminUi.luau   — the dock-widget form (per-field reset, override dots)
- plugin/init.server.luau   — toolbar/widget wiring + ChangeHistory undo steps
- plugin.project.json       — separate Rojo tree; build with --plugin to install
- CI: stylua + a plugin-sourcemap luau-lsp pass + a plugin build
- docs/admin-plugin.md + cross-links; fix stale Invert row in the no-code table

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 18:22:57 +10:00
Samuel LisonandClaude Opus 4.8 63b1bbd6fb docs: 'providing your own HUD art' + the Studio/Rojo stale-Play-cache gotcha
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 16:28:42 +10:00
Samuel LisonandClaude Opus 4.8 c3c676fd13 Wire generated flat icons into the demo HUD (stats + credits)
The binder now re-renders a bar/counter the moment its `Icon` attribute is set, so
a game can assign art at runtime — the engine still ships zero asset ids. The demo
ships an example flat icon set (8 game-agnostic glyphs generated via 3D AI Studio /
Gemini 3 Pro, background keyed to transparent, trimmed): a client script assigns
them to the HUD bars + the credits coin. Source PNGs archived under demo/assets/icons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 16:13:44 +10:00
Samuel LisonandClaude Opus 4.8 30ee904840 Make stat fill-direction engine-owned (fix afflictions still filling wrong)
`invert` and `dangerHigh` are stat semantics, not owner tuning — but they were in
the SurvivalStatsConfig instance's override map, so a stale/place-saved instance
(carrying the old Invert=true) overrode the corrected engine default and kept
Poison/Hunger/Thirst filling the wrong way. Removed both from STUDIO_ATTR_MAP and
stopped shipping them on the config template, so the engine always owns them and a
stale instance can never freeze a bug across an update. Per-bar `Invert` attribute
remains for a deliberate one-off display flip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:15:46 +10:00
Samuel LisonandClaude Opus 4.8 0d6ff2e064 docs: add the project design language (UI style, palette, icon pipeline)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:03:38 +10:00
Samuel LisonandClaude Opus 4.8 5ec10553b6 Fix affliction bars (empty when safe) + add a HUD credits readout
The bar fill now shows the RAW stat value by default, so afflictions
(Hunger/Thirst/Fatigue/Poison) read empty when you're fine and fill UP as they
worsen — fixing Poison showing a full green bar at 0/100. A new `dangerHigh`
flag (true for those four) drives the warning color toward the correct end, so
warnings still fire near danger; `invert` remains an optional depleting-bar look.
Threaded dangerHigh through StatDefs/StatConfig + the SurvivalStatsConfig template.

Adds a bar-less "counter" to the binder (a GuiObject with a `Counter` attribute +
a `Value` label) and a Credits readout in the HUD header bound to a `Credits`
Player attribute (grouped like "1,234"); the demo seeds a sample value.

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