ZiggfreedCommon-1.2.0.jar
What's new
A difficulty-scaling engine primitive, two ref-less spawn-hook helpers, and a dialogue-engine authoring pass (native inheritance + data-driven option styling + reusable option fragments), all additive over 1.1.1. Nothing here is breaking; consumers pick up only what they call.
Dialogue engine
Changed: dialogue reuse is now NATIVE
Parentinheritance, not a hand-rolled template DSL. A body carries a top-level"Parent": "<id>"resolved through the engine's own inheritance (a newInheritMapCodecmerges theNodesmap BY KEY, node fields inherit-on-omit); the oldextends/params/nodeOverrides/extraNodes/prune resolver is gone. State-varied beats collapse onto per-node runtimeConditionsplus newAllOf/AnyOf/Notcombinators and aQuestState-styleStatesOR-shorthand, and a node can self-gate with its ownConditions.New: per-option
Presentation+ fully data-driven default styling. An option can carry aPresentation({Color, Icon:{Item,Glyph}}) that overrides its look, and the per-kind DEFAULTS (accept / turn-in / continue / neutral / farewell colours + glyphs) now live in a pack-authorableDialogueOptionThemeasset (Server/ZiggfreedCommon/DialogueOptionTheme/*.json, foldeddefaults < pack < owner) instead of Java literals. A server owner or content pack retints every dialogue option by dropping a same-id file, no code; the built-in enum is only the fail-closed fallback. (Glyph textures still live in the row.ui- a Java-set texture path renders a red X - so the theme drives the colour and which glyph shows.)New: an option
Stylefield. An option declares its themed look by kind ("Style": "accept"), overriding the action-derived style and resolving through theDialogueOptionTheme- a theme-driven, one-edit-changes-everywhere alternative to hard-coding a per-option colour/glyph.New: shared option fragments (
Fragments+IncludeOptions). A dialogue declares a"Fragments": { "<id>": [ ...options ] }map and a node pulls a fragment in with"IncludeOptions": ["<id>"]; the resolver appends the fragment's options to the node before decode. A shared footer (a common set of menu / navigation options) is authored ONCE and referenced by every node instead of copy-pasted. A no-op for any dialogue that uses neither.New:
scaling/- a generic, domain-free difficulty-scaling engine.ScalingContext(a base difficulty + adouble[]of participant powers + an aggregation mode + an opaque instance handle) is the ONE input abstraction serving both open-world proximity groups and 1-10 player instances, with zero player / party / skill types leaking into the library.AggregationMode(SOLO/AVERAGE/PEAK/WEIGHTED/DISABLED) plusPowerAggregation.foldcombine the array into one effective power;ScalingEngine.resolve(ctx, bandWidth, minCap, maxCap)clamps a band-limited power delta over the authored floor. Pure logic, zero engine coupling, unit-tested. A consumer builds the context (open-world: a cached region power scalar; instanced: a party reduced to adouble[]) and calls the SAME engine for both.New:
HealthUtil.scaleMaxHealth(Holder, factor, key). The ref-less overload of the existing HP-scaler: raise a mob's Health MAX and heal to it reading the stat map straight off a pre-addHolder, so a mob can be scaled INSIDE anonEntityAddspawn hook before it has a valid ref. Idempotent per holder, world-thread, fully try-guarded.New:
EntityIdentifierUtil.roleName/roleIndex. Read an NPC's role identity from itsNPCEntitycomponent:roleName(the restart-stable string to key config on) androleIndex(the restart-unstable integer for hot in-tick lookups only). Both offer a Store/Ref form and a ref-lessHolderform for a pre-add spawn hook.
This mod has no additional files

