10 Commits
Author SHA1 Message Date
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 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 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 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 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 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 45e2c41a52 docs: document the redesigned HUD (panel, collapse, Value/Icon, StatIcons)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:00:24 +10:00
Samuel LisonandClaude Opus 4.8 772b555578 Document survival stats; lint the HUD loader in CI
Add docs/survival-stats.md (the stat model, no-code SurvivalStatsConfig tuning, the
SurvivorStatBar/Stat contract, the Rojo one-way-sync caveat) and cross-link it.
CHANGELOG Unreleased entry. CI + CONTRIBUTING now run stylua/luau-lsp over assets/
so the HUD loader is checked.

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