mirror of
https://github.com/TemujinCalidius/SurvivorCore.git
synced 2026-08-14 09:02:29 +00:00
20 KiB
20 KiB
Changelog
All notable changes to SurvivorCore are recorded here. The format follows
Keep a Changelog; this project aims to follow
Semantic Versioning. At release time, ## Unreleased
is promoted to the new version and main is tagged vX.Y.Z.
0.6.0 — 2026-07-03
Added
- Quests (#10) — the goals & progression foundation. A
Questsregistry + server runtime: quests carry objectives (gather/craft/kill/usea target × count; blank target = any) and rewards, withautoStart, arequiresprerequisite (completing a quest auto-starts its chain), and optionalturnInat a quest giver — tag any part/modelQuestGiver+ setQuest = "<id>"and the engine attaches the accept/turn-in prompt. Progress is driven by the events players already generate — no wiring per quest — and rewards are never lost: a full inventory parks the quest as ready and the grant retries until it fits. A Quests menu tab (keyL) renders Active (per-objective progress bars) / Ready / Completed. New hooks + bus events:quest:started/progress/completed/blocked. Session-scoped (persistence is a future system). See docs/quests.md. - Achievements — an always-on runtime for the existing registry, ported architecturally from The
Counter Earth's proven service: the new shared Progression layer translates gameplay events
into auto-derived counters (
gathers_reed,crafts_total,kills_husk,uses_berry,quests_total, …) so an achievement def is just{ key, name, counter, threshold }— the same flat shape in code and no-code. Threshold crossings unlock once, fireachievement:unlocked, and show a toast; an Achievements menu tab (keyJ) tracks progress bars (gold when unlocked). Custom events/counters viaSurvivorCore.Progression.map/Achievements.addCount/Achievements.award. See docs/achievements.md. - Toasts — a small themed top-right notification queue (
Notifyremote +Toasts.show), used by quest completions and achievement unlocks (config-gated per system). - No-code quests & achievements — the admin plugin's Content widget gains Quests
(single-objective: objective type/target/count, reward, auto-start, requires, turn-in; + Quest
giver drops a tagged giver post) and Achievements (counter + threshold) editors; the engine
loads both from
SurvivorCoreContentat start. - EventBridge parity — harvesting, crafting and item-use lifecycle events (
gather:*,craft:*,item:use) now also cross the EventBridge bus (combat/mobs already did), so quests/achievements/analytics can consume every gameplay event uniformly.
Fixed
SurvivorCore.UI.registerPanelnow adopts a menu tab the authored template already scaffolds (hiding its placeholder and running the panel'sbuildinto it) instead of silently doing nothing — this is what lets the Quests/Achievements tabs replace their "coming soon" placeholders.
Changed
- Toolchain: rojo 7.6.1 → 7.7.0 (pin in
rokit.toml; sandbox-verified against the full CI gate).
0.5.0 — 2026-06-25
Added
- Mob & AI engine (#17) — the shared creature substrate combat, animals and monsters all build
on. A mob is a Model tagged
Mobwith a Humanoid + PrimaryPart, so it's damaged, healed and killed exactly like a player. A reusable FSM (idle / wander / chase / attack / flee / return-on-leash / death) drives behavior, with the profile picked by data — aMobsdef'sfaction:"hostile"chases + attacks,"passive"flees,"neutral"wanders. Line-of-sight, leash distance and target selection are built in; movement isHumanoid:MoveTo. NewSurvivorCore.Mobsruntime —spawn/adopt/damage/getActive/isMob(the registry'sregister/loadFromFolderstill author defs in code or no-code) — plus per-mob-type reactionsSurvivorCore.Mobs.onReaction(mobType, "spawned"|"hit"|"attack"|"died", …)for death fades, spawn cries, etc. AMobsConfig section tunes tick rate, default aggro/leash/attack and respawn. New hooks:mob:spawned/mob:hit/mob:attack/mob:died. See docs/mobs.md. - Combat — melee + ranged (#12, #14) — server-authoritative combat reusing the v0.4.0
client-input → server-validated-hit pipeline. A weapon is just an item (
category = "weapon"+ atoolTypeso the hotbar equips it) with flatweapon*stats. Melee: equip + click; the server picks the nearest valid target (a mob, or another player whenFriendlyFireis on) within range + line-of-sight and applies damage. Ranged (bow): a TCE-style aiming flow — hold right-click to aim (over-the-shoulder camera + FOV zoom + a crosshair and a charge ring), hold left-click to draw, release to fire along the crosshair. The server recomputes the shot from the bow's muzzle, times the draw (anti-cheat), consumes one arrow from the inventory, and simulates the gravity arc authoritatively, sending the arc path back so the client flies a cosmetic arrow along the real curve. Arrows are their own configurable ammo item (category = "ammo"): per type a weight, damage ×, drop/curve ×, max range and speed ×, so different arrows fly and hit differently — a shot combines the bow's pullback with the arrow's ballistics. The kill-event schema is designed once here —combat:hit/combat:kill{ attacker, victim, weapon, source }— fired through bothHooksandEventBridge. NewSurvivorCore.Combat+ aCombatConfig section (ranges, cooldowns, friendly fire, bow physics). Because mob/player damage flows throughHumanoid:TakeDamage, it's lethal and drives the survival Health HUD with no extra wiring. See docs/combat.md. - No-code mobs & weapons (#11, Builder slice) — the admin plugin's Content widget gains
Mobs, Weapons and Arrows / Ammo editors (schema-driven, like Items/Gatherables): create
a mob type (faction/health/speed/ranges) — + Add to World drops a tagged placeholder rig; create
a weapon (kind/damage/range/cooldown + bow draw/speed/ammo) — + Tool model drops a starter
Toolto build the held look on; create an arrow type (damage/curve/range/speed/weight). The engine loads all of them fromSurvivorCoreContentat start — what the plugin writes, the runtime registers, no code. A creator also authors a mob by tagging any rigged ModelMoband settingMobType.
Fixed
- Removing or consuming one item no longer clears unrelated hotbar pins — the orphaned-pin sweep is now scoped to the affected item. (Previously, e.g., firing a bow that consumed an arrow could unpin and unequip a hotbar-pinned weapon that had no inventory stack.)
0.4.0 — 2026-06-24
Added
- Tool-swing harvesting & the gather → craft loop (#1, #4) — equip a tool from the hotbar,
click a node to swing, and the server validates the hit (range, line-of-sight, equipped tool,
cooldown) before granting a per-hit random yield straight into your inventory; a full
inventory blocks the hit so nothing is wasted. Bare-hand nodes keep the hold-
Eprompt. This is the engine's first client-input → RemoteEvent → server-validation pipeline, shaped for combat to reuse. Selecting a tool in the hotbar now equips a realTool(the new hotbar→Tool bridge), with a content-free Tool template path. Hand crafting closes the loop: a server-authoritative runtime consumes a recipe's ingredients and produces its output (refunding on no room), surfaced as a Crafting tab that listsRecipes.forStation("hand")and gates each recipe on what you're carrying. New APIs:SurvivorCore.Harvesting,SurvivorCore.Crafting, plusHarvesting/CraftingConfig sections. See docs/harvesting.md and docs/crafting.md. - No-code content layer (#11, Builder first slice) — items and gatherable resources can now
be authored without code. A new
Resourcesregistry defines what a node is (item it yields, HP/gathers, required tool, yield min/max); aGatherablenode binds to one via aResourceattribute (tag a mesh, setResource = "oak_tree"— no per-node attributes). Content can be defined as instances (Registry.loadFromFolderreads aSurvivorCoreContentfolder at start), and the admin plugin gains a "Content" widget to create/edit/delete items + gatherable resources from a form — what it writes, the engine registers, no code. Per-resource-type reaction hooks (SurvivorCore.Gather.onReaction) drive the juice (a reed sways, a tree fells and leaves a stump), withDestroyOnDepleteso a creator can transform the node on depletion. New hooks:gather:blocked,craft:start/craft:end/craft:blocked. See docs/content-authoring.md.
0.3.0 — 2026-06-23
Added
- Inventory, hotbar & tabbed menu UI (#7, #9, #3) — a server-authoritative inventory with a
slots + carry-weight model, a 9-slot quick-use hotbar (keys 1-9), equipment slots
(head/top/pants/shoes/back/quiver), and a restyleable tabbed menu (functional Inventory +
Character Sheet; Codex/Achievements/Quests scaffolded). Built the engine's way — authored
ScreenGui templates (
SurvivalMenu,SurvivalHotbar) driven by attribute-discovering binders, so world creators restyle everything in Studio with zero code (and a zero-setup fallback guarantees the UI always appears). Items stack and have weight; equipping a backpack raises both slot count and weight limit. Consumables apply theironConsumeeffects through the stat-effects layer (e.g. food lowers Hunger) and fire anitem:usehook; every change firesinventory:changed. Full drag-and-drop (move/merge/swap, pin to hotbar), pickups auto-assign to the smallest free hotbar slot, and gathering a node now grants its yield straight into the inventory. New public API:SurvivorCore.Inventory.*(add/remove/move/split/equip/unequip/setHotbar/swapHotbar/useSlot/…) andSurvivorCore.UI.registerPanel/open/close/togglefor code-added tabs. Item display data (name/icon/stack/…) replicates to clients automatically, so games register items once (server-side) and the UI just works; item icons resolve via theItemIconsAssets category or an inlineiconfield. Tunable via the newInventoryandUIConfig sections. The engine still ships zero items — the demo registers a sample set and seeds a starter inventory. Opening the menu defaults to Tab — the engine frees it by disabling Roblox's player roster (which otherwise swallows the key), and moves the chat window to the bottom-left so it clears the top-left HUD; both are opt-out via theUIConfig section (ReclaimCoreKeys,Chat). See docs/inventory.md.
0.2.1 — 2026-06-22
Fixed
- Custom stat
attributeoverrides now work end to end (#20) — the HUD bound stat bars by the stat name, but the engine stores each value under the stat's backingattribute(overridable viaConfig.override("SurvivalStats", { Stat = { attribute = "…" } })), so an override silently froze the bar. The binder now reads + listens on the resolvedattribute; the same hardcoded-name slip in the Health↔Humanoid sync and the energy (vignette/breathing) feedback is fixed too. Default behaviour (attribute defaults to the name) is unchanged.
0.2.0 — 2026-06-20
Added
- Survival consequences — stats now bite back (server-authoritative, all tunable via the
ConsequencesConfig section): starving (Hunger maxed) and dehydrated (Thirst maxed) drain health; poison drains health at 100%; Blood at 0 → bleed out (instant death). Health drains stack and reduce real character health, so death + respawn happen naturally. Energy stops regenerating while starving, dehydrated, or fully fatigued (even after the post-sprint delay). The engine now syncs the Health stat to the character Humanoid (the HUD bar reflects real damage), hides Roblox's built-in health GUI in favour of the HUD bar, and resets all stats + clears modifiers on respawn (no death-loop). Default drift is slow and realistic — Hunger/Thirst ~8 h, Fatigue ~24 h, and ~8 h more to die of starvation/dehydration. - Sprinting, jumping & energy — hold Shift to sprint (server-authoritative): it drains
the Energy stat, speeds you up, and forces an exhausted crawl at 0 energy; energy regenerates
after a short idle delay. Jumps cost energy and are blocked below a threshold. Ships a low-stat
feedback layer too — a screen vignette + breathing loop that intensify as energy drops, and
a heartbeat loop below 40% health. Adds the engine's first RemoteEvent (
SprintIntent) and aMovementConfig section (Config.override("Movement", …)). Logic + tuning + free default art ported from The Counter Earth. See docs/survival-stats.md. - Dynamic stat effects — a per-player, server-side modifier layer over the base rates, so
stats can be driven by events instead of only a constant drift.
SurvivorCore.Stats.adjust(one-time clamped delta),addModifier/removeModifier(named, optionally-timed rate modifiers; effective rate = base + Σ active), andgetValue. This is the foundation for poison ticking until cured, bleeding until clotted, and sprint draining energy. Modifiers are dropped when a player leaves. See docs/survival-stats.md. - Survival-stats engine + built-in HUD (#8, #2) — a server tick simulates per-stat
drain/regen, stored as auto-replicating Player Attributes, and a reactive top-left HUD
renders them (no RemoteEvents). The HUD is a real, designer-editable
SurvivalHudScreenGui in StarterGui — restyle it in Studio with zero code; bars bind by aStatattribute and aFillchild. It's a translucent panel that shows Health + Energy by default and expands to the full roster, with per-bar numeric readouts (99/100/%, configurable) and per-stat icons — the engine ships a free default icon set (baked intoStatDefs+ the HUD template), so the HUD is iconed out of the box and the icons even show in Studio's Edit view, no Play needed. Afflictions (Hunger/Thirst/Fatigue/Poison) read as empty-when-safe and fill up as they worsen (dangerHigh), and the header carries a credits readout (a bar-lessCounterbound to a Player attribute). HUD icons resolve per bar/counter and update live — a game can swap art at runtime by setting theIconattribute, or override the shipped defaults per stat (config / admin plugin /Assets). Ships with seven default stats (health/energy/hunger/thirst/fatigue/blood/ poison), tunable without code via aSurvivalStatsConfigConfiguration instance (or, for developers,Config.override("SurvivalStats", …)/Stats.defineStat). Works out of the box for every distribution — the demo/Rojo source mount it, the drop-in.rbxmauto-installs it onstart(), and a runtime fallback guarantees a HUD always appears. Adds the engine's first client layer (SurvivorCore.startClient()). See docs/survival-stats.md. - Survival Stats admin plugin (#11, first slice) — a Studio dock widget to tune the survival
stats from a validated form instead of hand-editing Attributes. It writes deltas only (an
attribute only when a field differs from the engine default; removed on reset / edit-back), so
owner tuning survives engine updates while untouched fields keep following improvable defaults,
and a hard guardrail makes the engine-owned
Invert/DangerHighsemantics impossible to write. Built as a separateplugin.project.jsonRojo target (install viarojo build plugin.project.json --plugin …); CI lints and builds it too. Includes a reversible edit-mode HUD preview (Preview / Clear) that paints resolved icons + sample fills onto the StarterGui HUD, so owners see play-time styling without pressing Play. See docs/admin-plugin.md. - Continuous integration (
.github/workflows/ci.yml) — every push tomain/devand every PR runsstylua --check,selene,luau-lsp analyze(against a Rojo sourcemap + Roblox type defs), then builds all three Rojo targets —default.project.json(the drop-in engine model),demo.project.json(the runnable demo place), andplugin.project.json(the admin plugin) — to prove they compile. - Changelog enforcement (
.github/workflows/changelog.yml) — PRs must updateCHANGELOG.mdunless they carry theskip-changeloglabel. - Contributor guide (
CONTRIBUTING.md) — prerequisites, local dev setup, code style, thedev/mainbranching model, PR flow, and the engine conventions (no hardcoded asset IDs, content viaregister()/components, content-free core). - Issue & PR templates — bug-report and feature-request issue forms (Studio / Rojo plugin versions, repro), a PR template (changelog, CI, no secrets, no hardcoded asset IDs), and a Discussions link for questions.
- Toolchain pins for
stylua,selene, andluau-lspadded torokit.toml, plusstylua.toml,selene.toml, and.luaurcso local dev and CI lint/format/analyze identically. - Docs — a getting-started/install guide (Rojo + Wally and the drop-in
.rbxm) and an "Extending SurvivorCore" guide (theregister()API, the component/attribute model, Hooks). - README — a "See it live" pointer to The Counter Earth (the engine's closed-Alpha showcase) and a GitHub Sponsors section.
Changed
- The release workflow now cross-posts each tagged release to Discussions → Announcements
(
discussion_category_name+discussions: write).
Fixed
Componentsattribute reading (src/components/init.luau) no longer iterates an optional union; it guards the optional first. Behavior is unchanged — this clears aluau-lsptype-analysis error so CI starts green.
0.1.0 (2026-06-18)
Added
- Foundation scaffold. The core plumbing every layer builds on:
Config— engine-default tuning sections that games override via deep merge.Assets— a typed asset-id registry; the engine never hardcodes IDs.EventBridge— a semantic event bus (fire/onFire) that decouples subscribers from sources.Hooks— lifecycle extension points (Hooks.on("gather:depleted", …)) so game-specific flourish stays out of the engine.Registry— the shared register/validate/index/query lifecycle behind every registry.
- Content registries — empty
Items,Recipes(crafting + cooking, routed bystation),Stats,Achievements,Codex,Appearance, andMobsregistries the game populates at startup. The engine ships zero concrete content. - Component layer — the creator-facing
Gatherablecomponent (tag your own mesh, setItemId/Yield/HPattributes) over a genericComponents.define/scanframework. - Public API —
SurvivorCore.start()and the dot-callable surface (SurvivorCore.Items.register{…},SurvivorCore.Hooks.on(…), …). - Runnable demo (
demo/) and ademo.project.jsonRojo target that mounts the engine underReplicatedStorage.SurvivorCoreand exercises both extension layers. - Release pipeline (
.github/workflows/release.yml) — buildsSurvivorCore.rbxmfrom source and attaches it to eachv*tag's GitHub Release. - Docs & project setup —
README.md,docs/architecture.md, MITLICENSE,rokit.toml(rojo + wally pins), andwally.tomlpackage metadata.