Item type stats

From Wiki G1R-MP G1 Remake Multiplayer
Revision as of 13:28, 20 October 2026 by QCherry (talk | contribs) (Release 0.1.9 / BUILD264 / Protocol42: availability and download setup; preserve experimental limits)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Item type stats

Available from G1R:MP 0.1.9. This guide documents the implemented API and explicitly identifies unfinished features and remaining in-game validation. Use matching client/server builds; updating scripts alone is insufficient.

What this changes

Server owners can change supported numeric properties of existing item types: weapon damage, armor protection, equipment bonuses, consumable effects, ammunition, rune settings and common item metadata. One change affects every copy of that item type on that server. It is not a per-player or per-instance enchantment system, and it does not create new item types.

For example, changing the protection of mercenary changes that armor type for everyone wearing it. Two identical swords cannot have different profiles through this API. Profiles are server-wide, including across character dimensions.

Quick examples

Run these examples in a trusted server resource. They alter the server's balance; do not expose unrestricted client-triggered access to them.

Armor protection

local ok, reason = setItemStats("mercenary", {
    resistanceEdge = 80,   -- cutting damage
    resistanceBlunt = 60,  -- blunt damage
    resistancePoint = 50,  -- piercing damage, including arrows
    resistanceFire = 30,   -- fire damage
    bonusHealth = 25
})
assert(ok, reason)

These are protection values, not percentages. The other protection properties are resistanceWind, resistanceIce and resistanceEnergy. Increasing maximum HP does not heal the wearer. Ordinary armor protection and the separate armor-upgrade-slot system are implemented for 0.1.9. Base and selected parts contribute once each; see the guide for current visual qualification.

Weapon, potion and ring

local ok, reason = setItemStatsBatch({
    ["1h_sword_short_02"] = {damage = 60, requiredStrength = 20},
    itfo_potion_mana_03 = {mana = 31},
    itat_ring_life_01 = {bonusHealth = 17}
})
assert(ok, reason)

damage is the weapon's base contribution, not guaranteed final HP loss. Attributes, skill, charge, protection, block and existing minimum-damage rules still matter. The potion restores 31 mana when consumed, subject to the character's maximum. Each owned and equipped copy of the ring contributes its configured bonus.

Inspect support before changing a field

local definitions = getItemStatDefinitions("mercenary")
local field = definitions and definitions.resistanceEdge
if field and field.writable then
    local stats = getItemStats("mercenary")
    outputDebugString("Protection: " .. tostring(stats.effective.resistanceEdge))
else
    outputDebugString("Unavailable: " .. tostring(field and field.reason))
end

Use getItemTypes to discover canonical keys. Friendly equipment aliases and recognized native item-class names resolve to the same profile, but this does not change the key rules of other inventory/equipment APIs. A missing value means unknown or not applicable, not zero.

API reference

Function Purpose
getItemTypes List known canonical item types.
getItemStats Read defaults, observed native defaults, overrides, effective values and revision.
getItemStatDefinitions Read each applicable property's support, range, integer requirement and unavailable reason.
setItemStats Patch selected fields of one type; omitted fields are preserved.
setItemStatsBatch Patch several types in one validated transaction.
resetItemStats Remove one field override or all overrides of one owned type.
getItemStatsProfile Export overrides owned by the calling resource.
replaceItemStatsProfile Replace that resource's complete profile, also removing omitted old overrides.

See Item stat properties for the full property list and ranges, and onPlayerItemStatsReport for client application diagnostics.

Ownership, reset and persistence

An item type with active overrides belongs to the resource that set them. Another resource cannot change even a different field of that owned type. Coordinate balance changes through one resource. Invalid items, unsupported fields, invalid numbers or ownership conflicts reject the submitted transaction rather than applying only its valid parts. Server acceptance is not an acknowledgement that all clients have finished applying native changes.

-- Remove only this protection override; other owned fields stay configured.
assert(resetItemStats("mercenary", "resistanceEdge"))

-- Restore this entire type to its multiplayer baseline.
assert(resetItemStats("mercenary"))

-- Restore every item type owned by THIS resource, not other resources.
assert(replaceItemStatsProfile({}))

Stopping the owning resource removes its overrides. Changes are not automatically written into a database or made permanent across server restarts. Save a profile explicitly if required:

-- Save after an administrator has accepted the balance configuration.
assert(writeResourceData("item_balance", toJSON(getItemStatsProfile())))

-- Restore during your resource's initialization, before normal gameplay.
local saved = readResourceData("item_balance")
if saved then
    local profile = fromJSON(saved)
    assert(type(profile) == "table", "Invalid saved item profile")
    local ok, reason = replaceItemStatsProfile(profile)
    assert(ok, reason)
end

Restoring is subject to current validation; a file is not permission to bypass it. replaceItemStatsProfile is a replacement, whereas setItemStatsBatch is a merge. See Resource data storage for storage behavior.

Equipment and NPC behavior

Armor/player base values stay separate from equipment bonuses, preventing repeated equip operations from repeatedly adding the same bonus. Raising maximum HP/mana does not heal or refill; lowering a maximum clamps the current value if necessary.

Explicit armor bonusHealth, bonusMana, bonusStrength and bonusDexterity also affect scripted NPCs wearing that armor. Unconfigured native bonuses do not silently change legacy NPC balance. NPC maximum setters set base maxima; their getters return effective maxima. Combat-config dexterity remains the base value. getNpcData additionally exposes base/effective values and the four armor contributions; see NPC scripting. NPC toughness is not implemented by this addition.

Ring/amulet numeric overrides use the normal native inventory controls. Two identical rings require two owned copies and occupy two separate slots. After the first numeric jewelry override, server-controlled slot accounting remains active until disconnect/server restart, including after resetting the profile. Reset restores item values; it does not switch back to potentially duplicated native stacking mid-session. Changing only price/weight does not activate this numeric mode. This addition does not implement NPC jewelry equipment.

Damage channels, ammunition and runes

Seven optional damage channels are available: edge, blunt, point, fire, wind, ice and energy. Explicitly setting any channel enables channel-based calculation for that item. Unspecified channels retain their native baseline; they are not automatically zeroed. If scalar damage is also set, the baseline is scaled first, then explicit channels replace their values. Effective damage reports the resulting sum. Matching protection is applied per channel and the existing minimum damage is applied once after summing.

Arrow/bolt damage is added to the bow/crossbow contribution, not substituted for it. For ammunition with an empty native damage map, scalar damage supplies point damage. For example, {damage=17, damageFire=31} supplies point 17 plus fire 31 from the ammunition. Set damagePoint=0 explicitly if only fire damage is wanted. Numeric fire damage does not create a fire visual, burning status or torch-ignition behavior.

Projectile and NPC wind-up calculations retain the accepted attack's snapshot; editing a profile does not rewrite an arrow already in flight. Player melee retains its impact-time calculation. Existing monster combat retains its separate no-armor path.

Implemented runes expose appropriate damage/range/duration/circle fields. manaCost is a fixed cost for one accepted release, including charged spells; 0 means free. Omitting/resetting it preserves original tier, charge and sustained-cast costs. The start checks funds without charging; release checks funds and charges once. A profile edit during an accepted cast affects subsequent casts, not that cast. A free cost does not grant a rune or bypass equipment, circle, timing or target checks. Custom mana-cost behavior still requires final in-game qualification. See Item stat properties.

Compatibility and validation status

Current overrides are replayed to joining/rejoining compatible clients. An unsupported connected client prevents activation; incompatible clients cannot enter a session with active overrides. Both sides need the matching 0.1.9 implementation.

Client reports describe application status, not honest execution or proof of gameplay. Never grant inventory, money, permissions or damage based on a successful report. A new revision, reconnect, reset while equipped, native inventory descriptions and two-client observation should be checked when qualifying a configuration.

The strong mana-potion override/reset and modified life-ring/amulet equip/remove cycles have been confirmed in game. This does not qualify every item or tooltip. Custom rune costs, damage-channel/ammunition presentation, jewelry reset while worn and full multi-client lifecycle coverage remain under validation.

Not implemented by the documented scope: per-instance statistics, criticalMultiplier, superArmorDamage, NPC toughness, and special effects of the three haste potions, orc spore and special joint. Unsupported overrides are rejected. Scroll casting/consumption is not introduced. This is not a promise that every engine field is writable.

Base and part profiles (from 0.1.9)

Armor upgrades selects three compatible pieces separately from the base. All 84 piece keys can be inspected with getItemStats/getItemStatDefinitions and configured by the type-wide item API. The base's profile is not the full-set total: effective protection sums base plus selected parts once. Do not double-count a full-set total in the base. Choosing a part is per character; changing its numeric profile affects all copies of that type on the server. Setters for equipment and item profiles do not grant inventory or heal.