DEV Community

John
John

Posted on

Dev Log 17 - .cs > .json

Dev Log – Conditional Narrative & Node System Upgrade
Tags: #unity #gamedev #storysystem #devtools #conditionaltext

  1. Extended Story Branch Added node_0004 as the continuation of the “Follow the shoreline to the right” choice from node_0001.

Preserved existing JSON node format, but matched the style, spacing, and metadata of the earlier entries tested.

Defined three new choices from node_0004:

Climb up the sand dune to get a better view → node_0005

Follow the shoreline to the right → node_0006

Approach the rocks on the shoreline → node_0007

Environment profile cloned from node_0001 for consistency.

  1. Conditional Narrative Text System Introduced textVariants to StoryNode JSON format:

Each variant contains its own text plus optional location, items, conditions, and knowledge requirements.

Loader picks the first variant whose requirements match the player’s current state.

Falls back to node.text if no variants match (backwards‑compatible).

This allows narrative lines to adapt dynamically based on:

Equipped gear (e.g., waterproof boots)

Physical state (injured, exhausted, well‑rested)

Health conditions (bleeding, fever, poisoned)

Stamina thresholds

Illness/disease flags - (ready hopefully for using full disease system, I'm sure many issues await)

Story flags from previous choices

  1. Code Changes StoryNodeLoader Added GetNodeTextForPlayer() (public) to resolve the correct text for the player.

Added VariantMatchesPlayer() to check variant requirements against PlayerStats.

Kept IsChoiceVisible() logic intact for choice filtering.

Maintained full backwards compatibility with existing nodes.

StoryUIManager
Updated DisplayNode() to call nodeLoader.GetNodeTextForPlayer(node) instead of using node.text directly.

Preserved all original UI behaviour (button hiding, shuffling, compass direction display *depending on item).

No duplicated logic — all variant resolution happens in the loader.

StoryNode Class
Added List textVariants to support conditional text.

Created TextVariant class with the same requirement fields as Choice.requires.

  1. Workflow & Testing Benefits No runtime JSON editing — all variants live in static data, chosen at runtime.

One source of truth — variant matching logic is centralised in the loader.

Future‑proof — adding new condition types only requires updating VariantMatchesPlayer().

Debug‑friendly — can later add logging to show which variant was picked and why.

Playtest synergy — can run this side‑by‑side with your simulated runtime gear script to instantly see narrative changes when toggling gear/conditions.

.. added a lightweight debug code into the script to show - When enabled,:

Which variant was selected

Which variants were skipped

The exact requirements for each

When disabled, the loader runs silently.


📜 Dev Log — 5 Sept 2025
Project: Weapon Systems Overhaul Theme: “Goodbye Database, Hello JSON” Mood: Triumphant, slightly caffeinated, and maybe a little smug.

  1. The Great Data Migration Old World: A monolithic RangedWeaponItemDatabase scriptable object holding all weapons like a medieval scroll — long, unwieldy, and prone to papercuts (compile errors).

New World:

Exported all weapon data to a clean, human‑readable JSON file.

Built a RangedWeaponImporter that reads the JSON and generates individual RangedWeaponItem assets. Adjusted the Gear Validator (copied most of it, and adjusted it for use with ranged items).

Now each weapon is its own neat .asset file — easy to edit, version control friendly, and no more “one typo nukes the whole database” disasters.

  1. Type Safety Crusade Before: compatibleAmmoTypes was a List. Strings are fine for poetry, not for ammo types — typos like "ShotgnShell_12Gage" could sneak in and ruin your day.

After:

Converted compatibleAmmoTypes to List (enum).

Updated importer to parse JSON strings into enums, with warnings for unknown values.

Attachments now also store compatibleAmmoType as an enum.

Compatibility checks are now direct enum comparisons — no .ToString() gymnastics.

  1. Attachment System Tune‑Up Fixed the IsAttachmentCompatible method to work with enums.

Cleaned up GetCombinedModifiers to initialise with a proper WeaponStatModifier.FromFloats() helper.

Now combining modifiers is clean, safe, and doesn’t require manually setting every field to zero.

  1. Debugger Rehab Program Retired all scripts that depended on the old database into a Archived Script folder - Retired Scripts, changed extension to .txt so no sneaky reading of .cs will appear.

Converted them to the Inspector‑assigned list pattern:

AmmoTypeDebugger — now works directly with List without parsing strings.

AttachmentCompatibilityDebugger — checks each weapon’s attachments for compatibility.

WeaponDebugger — finds a weapon by name and prints final stats with modifiers applied.

WeaponStatSheetDebugger — prints a full stat sheet for all assigned weapons.

WeaponNullCheckDebugger — hunts down missing names, null attachments, and empty stat modifiers.

All null‑safe, all compile‑happy.

  1. Fire Mode Evolution Added fireMode and semiAutoRate to RangedWeaponItem.

Upgraded FireModeController to:

Start in Semi or Auto depending on weapon settings.

Toggle modes for Selective weapons.

Apply attachment modifiers to fire rates.

Clamp rates to safe minimums.

Ready for integration with projectile, ammo, and effects systems.

  1. WeaponStatModifier Resurrection Defined WeaponStatModifier as a [System.Serializable] struct with all the right fields.

Added FromFloats() helper for clean default creation.

Now used consistently across importer, attachment system, and debuggers.

  1. The Big Payoff Errors at start of day: ~200+

Errors now: 0 🎯

Side effects:

Codebase is cleaner and more modular.

Data pipeline is future‑proof.

Debugging tools are flexible and reusable.

Enum safety means no more silent data corruption from typos.

  1. Lessons Learned Strings are for love letters, not ammo types.

If you can’t delete a legacy system without breaking everything, replace it piece by piece until it begs to be deleted.

Always initialise your structs — uninitialized zoom multipliers are the silent killer of balance.

A good importer is like a bouncer: it lets the right data in and throws the bad data out with a warning.


Dev Log — 06 Sept 2025 Title: The Melee Manifesto: JSON, Jabs, and Just Enough Sanity

Today was a full-blown melee migration ritual. We took the entire hardcoded MeleeWeaponItemDatabase and transformed it into a clean, modular JSON format. Every weapon, from butter knives to steel-tipped spears, was preserved with full stat fidelity. The data was split into seven paste-ready blocks, formatted for Notepad, because apparently JSON throws a tantrum if you give it more than one root object.

35 unique melee items added so far.

Lesson learned: don’t surprise JSON with extra {} after it’s already closed the party.

Built a fresh block extractor script that reads from MeleeWeapons.json and outputs individual JSON files for each weapon. It skips duplicates, sanitizes filenames, and avoids overwriting ranged data. Each weapon now lives in its own file under StreamingAssets/Data/WeaponExtracted — because even cleavers deserve personal space.

Merged the validator into a unified WeaponJSONValidator that handles both ranged and melee formats. It dynamically detects whether an entry uses "weaponName" or "itemName" and applies appropriate checks. It flags missing fields, invalid ranges, and null attachments. Basically, it’s a QA intern who never sleeps and always judges your accuracy stat.

Rebuilt the importer from scratch. The MeleeWeaponImporter now parses enums properly, handles nullable fields, and creates .asset files in Assets/ItemAssets/MeleeWeapons. It registers in the Tools menu and actually shows up this time. The Enum.TryParse errors were caused by forgetting to include using System; — because apparently Unity needs a formal invitation to remember what C# is.

Fixes applied today:

JSON parse error: “Additional text encountered after finished reading JSON content.”
Cause: multiple root objects from stacked blocks.
Fix: removed duplicate { "items": [...] } wrappers and merged weapon entries into a single array.
Outcome: validator stopped screaming.

Compiler error: CS0103: The name 'Enum' does not exist in the current context.
Cause: missing using System; in the importer script. (Overlooked basics)
Fix: added the missing namespace.
Outcome: Unity remembered how to parse enums.

Importer not showing in Tools menu.
Cause: script wasn’t wrapped in an EditorWindow or registered with MenuItem.
Fix: wrapped it properly and added [MenuItem("Tools/Import MeleeWeapons from JSON")].
Outcome: importer now appears proudly in the Tools menu.

Enum compatibility issues.
Cause: mismatch between JSON strings and enum types.
Fix: verified MeleeWeaponItem structure and ensured all fields matched the JSON schema.
Outcome: assets imported cleanly with no nulls or mismatches.

Notes to self: Don’t trust Unity to remember Enum.TryParse unless you explicitly invite System to the party. JSON doesn’t tolerate optimism — it wants one root object and zero surprises. Every weapon deserves its own .asset, even if it’s just a butter knife with dreams.

We’re forging a legacy, one blade at a time.

Total unique weapons so far 85

Next up - Tools (mixed use , weapons and tools), misc items (mixed use) , liquids(&Containers), foods(tinned,meat,fruit,vegetables,misc/seeds), cooking items (mixed use), mechanical items, environmental items, and then whatever else i have forgotten to add yet.

Progress is slow. Progress is progress.

Top comments (0)