agentleFS
willy92winswilly92wins/DayZ-Modding-Knowledge-Pack/skills/dayz-clothing/SKILL.md

dayz-clothing

Skill20 starsChanged 43 days agoMITView on GitHub

Use when: clothing mod, worn model, ClothingTypes, chaleco, armadura, la ropa flota/rígida/girada, slot Vest/Body/Armband, NBCHead/NBCTop/NBCPants/NBCBoots/NBCGloves, NBCBag, Waterskin, gas mask filter, headSelectionsToHide, wet clothing. Worn clothing (_m/_f). Not humanoids/rigging: dayz-characters; not proxy triangles: dayz-proxy-align.

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    The clothing skeleton must be named DayzTemporarySkeleton: ALL vanilla worn clothing compiles with that name (verified via ODOL …

    line 30
  2. Distinctive:

    Verify PBO entries (classname, NO config.bin, ODOL magic) → deploy by hash.

    line 137
  3. Very specific:

    CraftArmbandFlag.CanDo: no longer requires IsEmpty().

    line 248

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

DayZ Worn Clothing — the verified pipeline

Distilled from ArmorHneck (2026-08-03): third-party body armor RAR → fully working worn item, ~6 in-game cycles to isolate three independent SILENT failure modes. Everything below is in-game verified on DayZ 1.29 diag unless labeled otherwise. (until 1.29: the worn pipeline below is the 1.29-diag contract.) (since 1.30 Exp: killers #1–#3 and the worn p3d/model.cfg contract still hold. Config-side NBC layering, mask-filter protection, ItemBaseType wet/hide keys, shoe itemSize, Waterskin rename, and wash/wet actions: dayz-1-30-clothing.md and ## DayZ 1.30 Exp.)

THE THREE SILENT KILLERS (check these FIRST, in this order)

A worn item can fail three independent ways, each with ZERO RPT errors. Any one of them wastes cycles if you chase the others first.

  1. Config must be TEXT in the PBO. A config.bin produced by CfgConvert in this environment does NOT register (class absent: CreateObjectEx → unknown_type, invisible to VPP). Pack config.cpp as text (packonly); every working local mod ships text. Gate: live spawn of the classname — never trust static PBO inspection for "it registered".
  2. Worn mesh must be in the canonical clothing frame (see next section). A mesh built facing +Z renders as EXPLODED rigid pieces floating ~1 m above the player (each 0/1-weighted plate is transformed by its bone from a flipped frame). Fix: rotate 180° about +Y (det=+1 — do NOT touch winding) AND swap left*/right* selection pairs in every LOD. That fix keeps a mirror (CANONICAL WORN FRAME → handedness); with the Blender source, re-export it with (x, z, y) (Rule 12) instead.
  3. The clothing skeleton must be named DayzTemporarySkeleton. ALL vanilla worn clothing compiles with that name (verified via ODOL model_info.skeleton.name on armbend_dynamic_m + chainmail_m): same 159 bones and hierarchy as OFP2_ManSkeleton, ONLY the name differs — it is the placeholder the engine swaps for the wearer's skeleton at bind time. With skeletonName="OFP2_ManSkeleton" the engine treats the p3d as having its OWN skeleton and never re-binds: the item renders as a rigid block anchored above the player, not animating. The community 114-bone OFP2 template fails clothing TWICE (bone count and name). Template: references/model.cfg.template.

CANONICAL WORN FRAME (measured on chainmail_m / hoodie_m)

  • -Z = chest/front · +X = anatomical LEFT · +Y = up · origin at feet (ground Y=0); mesh authored over the vanilla A-pose body.
  • Measure orientation with ANATOMICAL COMPONENTS, never a global Z histogram (both ±Z masses are ~55/45 on real clothing — the histogram false-negatives a 180° flip). Reliable signals: front detail components (hoodie drawstrings at Z −0.14..−0.07), pelvis/spine weighted centroids (vanilla ≈ Z −0.04..−0.08), left* selection centroids on +X.
  • Torso clothing spans Y ≈ 0.61..1.66 m. Reference garment for overlay checks: dz\characters\tops\chainmail_m.p3d (body armor, full-body bone set).
  • Handedness (added 2026-10-01). This frame holds a non-mirrored body in DayZ's left-handed space. A Blender garment (right-handed; front −Y and left +X, like the official rig) lands on it with (x, y, z) → (x, z, y): det −1, faces in Blender order, normals negated (dayz-model-pipeline Rule 12). A det +1 map mirrors it: (x, z, −y) faces +Z (killer #2), and (−x, z, y) faces −Z with left* on −X. A mesh that needs "rotate 180° + swap L/R" was exported with such a map. ArmorHneck's received p3d was the (x, z, −y) of the artist's Blender file (ArmorHneck_dev\CLAUDE.md, 2026-08-04). Rotation
    • swap fixes the binding but keeps the mirror: text, logos, buckles and one-sided straps read reversed. The properly handed fix is a re-export of the Blender source with Rule 12, with no swap. With only the p3d, reflect it on the axis its state calls for: a p3d as received from (x, z, −y) (facing +Z, never rotated or swapped) takes z → −z; one that already had "rotate 180° + swap L/R", i.e. (−x, z, y) like the shipped ArmorHneck, takes x → −x AND the L/R swap undone (z → −z on it would face +Z again). Either reflection moves every point (memory points included), reverses every face and reflects the normals the same way; P3D.transform() with that diagonal matrix (det −1) does all three.
  • Chiral in-game check [run 2026-10-02, DayZDiag 1.29.163709]. The anatomical test above rules out a det +1 export only while the L/R selections were never swapped by hand; a swapped build needs an asymmetric feature. Put an "F" in relief on the left chest of a test garment (weighted 100 % to spine3). Export it once with Rule 12 and once with the old (x, z, −y) + rotate + swap as the control, wear each with an item in hands and set the camera in front. Pass: the "F" reads correctly and sits on the side opposite the item hand (items sit on RightHand_Dummy). Expected on the control: the "F" mirrored, on the item side. On ArmorHneck itself, compare one asymmetric detail against the artist's Blender file. Result, on a vest-like test garment worn in the Armband slot (binarized, ODOL skeleton DayzTemporarySkeleton, driven by dayz-mcp): the Rule 12 build (py3d.blender_to_dayz()), worn by the player with a crowbar in the right hand, shows the "F" reading correctly on the wearer's left chest, opposite the crowbar. The control (ROT_X_NEG90, every face reversed and every normal negated, then 180° about +Y) shows the "F" mirrored on the wearer's right chest. The garment carries only spine3, so the control's L/R swap renamed nothing. dayz-mcp cannot take a worn item off the player, so the control was worn by a SurvivorM_Francis spawned beside the player, facing the camera with empty hands; its right side was read from its facing. (claim: CLAIM-CLOTHING-CHIRAL-INGAME) Not covered: ArmorHneck itself, a garment with left/right-weighted parts, a female body.

THE CLOTHING CONTRACT (structure of a working wearable)

config.cpp (text!):

  • Class inherits a vanilla clothing base for the slot (Armband_ColorBase, Chainmail, vest/top bases...). model= the GROUND p3d (*_g.p3d).
  • class ClothingTypes { male="..._m.p3d"; female="..._f.p3d"; };
  • inventorySlot[] names the worn slots. (until 1.29: NBC pieces listed only the primary slot — "Headgear", "Body", "Legs", "Feet", "Gloves".) (since 1.30 Exp: those NBC bases also list secondary slots "NBCHead", "NBCTop", "NBCPants", "NBCBoots", "NBCGloves" so they can coexist with regular clothing.)
  • hiddenSelections[] per model section; textures/materials arrays aligned.
  • (since 1.30 Exp) Type metadata lives on ItemBaseType: headSelectionsToHide[], hideSelectionsByinventorySlot, varWetMax, temperaturePerQuantityWeight, EnvironmentWetnessIncrements. The config keys existed in 1.29 (parsed on ItemBase); 1.30 centralizes them on the type. Dual-slot headgear (bandana/shemag) still uses hideSelectionsByinventorySlot = 1 plus simpleHiddenSelections[].
  • Damage rvmats referenced only from healthLevels must be re-added at pack time (AddonBuilder whitelist gap — see dayz-pbo-build SP-155).

Worn p3d (_m/_f):

  • Visual LODs skinned by NAMED SELECTIONS in lowercase = bone names (leftarm, rightarm, leftforearm, rightforearm, leftupleg, rightupleg, neck, pelvis, spine, spine3 — more is better: vanilla also weights shoulder/roll/extra transition bones for smooth joints).
  • Per-vertex weight sums MUST be 1.0 (vanilla ODOL encodes raw bytes summing 255). 0/1 plate-rigid weights WORK but articulate coarsely.
  • Camo sections: tops/vests use camoMale / camoFemale alone; ONLY armbands carry the 4 complexion variants (camoMale_big_a/b + small_a/b). + zbytek.
  • Empty Geometry LOD with autocenter=0 = the vanilla worn pattern (keep it).
  • Ground _g: normal item p3d (Geometry+mass+Component01, memory points, ViewGeo, FireGeo with a penetration rvmat).

model.cfg:

  • Copy references/model.cfg.template VERBATIM (CfgSkeletons DayzTemporarySkeleton, 159 exact pairs, isDiscrete=0) and add one CfgModels class per p3d (class name == p3d filename) with skeletonName="DayzTemporarySkeleton" and its sections.

BUILD (staged — see ArmorHneck_dev\tools\build.ps1 as template)

  1. Stage the mod to %TEMP% (binarize with -addon=P:\ dies on any broken third-party config in the tree — "Error 3", names the wrong culprit). Stage beside it every file the p3d cite outside the mod's prefix, the vanilla penetration rvmat of the Fire Geometry included, or binarize embeds those materials EMPTY (dayz-pbo-build SP-155 rules 1 and 5, corrected 2026-10-03: ArmorHneck's ODOL of 2026-08-04 carries dz\data\data\penetration\armor_5mm_plate.rvmat empty).
  2. Full AddonBuilder pass to binarize the p3d (model.cfg NEXT TO the p3d in the staging; ODOL must come out with skeleton name DayzTemporarySkeleton — verify with the external ODOL parser, model_info.skeleton.name).
  3. Assemble pack tree: config.cpp TEXT + model.cfg + ODOL p3d + ALL paa/rvmat (including damage/destruct) → AddonBuilder -packonly (separate -temp!).
  4. Verify PBO entries (classname, NO config.bin, ODOL magic) → deploy by hash.
  5. Gate = in-game: spawn (registers?) → equip (worn renders on body?) → move (follows animations?). A worn item CANNOT be validated offline-only.

DIAGNOSIS LADDER (when a worn item misbehaves)

SymptomCauseVerify with
Item unknown/unspawnable, no RPT errorconfig.bin in PBO (killer #1)spawn gate; PBO entry list
Worn = rigid block floating ~1 m, rotated, no animskeleton name != DayzTemporarySkeleton (killer #3)ODOL model_info.skeleton.name vs vanilla
Worn = EXPLODED separate pieces above headmesh frame flipped 180° (killer #2)anatomical component Z-signs vs chainmail
Fits but plates misaligned (arms/legs)rip proportions vs canonical bindalignment viewer (below) or artist pass
Body/arms invisible when equippedexpected: torso-slot hide (Body/Vest classes hide skin)wear it with the intended slot class
Coarse joints while moving0/1 plate weights, no transition bonesoptional weight-smoothing pass
Gas mask worn, still takes bio/gas damage(since 1.30 Exp) GP5/Airborne Protection no longer carries biological/dust_particle_breath; those come from attached GasMask_Filterconfig class Protection vs slot GasMaskFilter
Custom backpack cannot attach NBC pack(since 1.30 Exp) backpack attachments[] missing "NBCBag" (not every vanilla bag has it)compare TaloonBag_ColorBase vs SmershBag / ChildBag_ColorBase

Config-vs-p3d bisection (one config-only rebuild, answers "which side is broken"): add two test classes — {your slot class + a VANILLA worn p3d (chainmail)} and {a vanilla clothing class + YOUR p3d}. Vanilla-p3d-OK + custom-p3d-broken in both classes = the p3d. Both OK = your main class fields. Both broken = pipeline.

ODOL parity check vs a debinarized vanilla worn (external ODOL parser): skeleton name + 159 bones, per-vertex weight sums, sub_skeleton palette (unused palette entries with 0 weight are normal in vanilla), sections, ModelInfo flags. SP-034 caveat: vanilla CHARACTER BODY vertex positions decode corrupt, but clothing worn p3ds decoded fine (armband, chainmail, hoodie all plausible).

ALIGNMENT VIEWER (fit plates to the body interactively)

references/alignment_viewer_extract.py → JSON of mesh + per-region bone weights + pivots (+ vanilla chainmail ghost as the placement reference); references/alignment_viewer_build.py → self-contained HTML (embedded three.js UMD): per-region rotation/offset sliders (weight-masked, around the region pivot), L/R mirroring, front/back/side views, exports an adjustments JSON. references/apply_alignment_json.py applies that JSON to the MLOD sources with the EXACT same math (three.js Euler XYZ replicated; cross-check a sample vertex against the live viewer before batch-applying — err ~1e-8). Works for arbitrary region sets (arm/leg/abdomen masks, combined selections).

ARTIST HANDOFF (when a human does the fitting — the usual best route)

references/export_clothing_fbx.py (Blender headless + py3d): MLOD worn → FBX with geometry, UVs (V flipped for Blender), the diffuse as PNG (ImageToPAA paa→png), and the bone weights carried by a 10-bone WEIGHT-CARRIER armature (FBX drops loose vertex groups — verified: without an armature deformer the groups vanish on reimport; with it, round-trip keeps all 10 groups at exact weight sums). Axis map DayZ→Blender: (x, z, y), det −1 and its own inverse, so the return trip is the same map with faces in the order they come back and normals negated (dayz-model-pipeline Rule 12); with py3d ≥ 1.8.0 that is py3d.blender_to_dayz() on the model rebuilt from the FBX in Blender coordinates. The artist sees the garment like the official rig: Z up, front −Y, left +X, faces outward. [OFFLINE MEASURED 2026-10-01, ArmorHneck _m, Blender 5.1.1 + py3d 1.7.0] FBX round trip back to DayZ exact to 2.7e-7 m with the same face order; leftarm centroid x = +0.34, pelvis/spine centroid y = −0.045; signed volume +0.026 in Blender, i.e. faces outward. Until 2026-10-01 the script used (x, −z, y) (det +1) with py3d.BLENDER_TO_DAYZ for the return. The artist then saw a mirror image (front +Y, left +X) with inward faces (signed volume −0.026), and only that exact inverse brought it back. A package made by the old script returns through (x, z, −y), i.e. transform(py3d.ROT_X_NEG90) (the name py3d 1.8.0 gives that matrix; the old py3d.BLENDER_TO_DAYZ still works but is deprecated and warns), never through Rule 12 or py3d.blender_to_dayz(), which would land it facing +Z, mirrored and inside-out. ALWAYS verify by reimporting the FBX in a clean scene (counts + vgroups + weight sums) before shipping. Package: FBX m/f + PNG + the MLOD p3ds + model.cfg + README from references/LEEME-ARTISTA.template.md (states the three do-not-undo fixes, the group-preservation rule, and the return flow). Scripts carry the ArmorHneck paths — adapt per garment.

PROVENANCE

ArmorHneck case (full trail): ArmorHneck_dev\CLAUDE.md, research workspace %TEMP%\armorhneck_research_ws\REPORT.md (Codex dual research: canonical frame measurement + transform prescription). Cross-refs: dayz-characters §2026-08-03 (same finding, humanoid context), dayz-pbo-build SP-155 (staged build + rvmat gap), dayz-test-ingame (launch/lifecycle), external ODOL parsing (converter not distributed).

DayZ 1.30 Exp (build 1.30.164014)

Worn-mesh killers #1–#3, the canonical frame, DayzTemporarySkeleton, and the staged packonly build are unchanged. What 1.30 adds is config/script contract around slots, protection, wetness, and one classname rename. Details and [EXACT] blocks: dayz-1-30-clothing.md.

What changes

  • NBC secondary slots. Vanilla NBC hood/jacket/pants/boots/gloves list both the primary clothing slot and NBCHead / NBCTop / NBCPants / NBCBoots / NBCGloves (CfgSlots in exp\scripts\scripts\config.cpp:3124-3159).
  • NBCBag on some backpacks, not all. TaloonBag_ColorBase, TortillaBag, DryBag_ColorBase, HuntingBag, MountainBag_ColorBase, AssaultBag_ColorBase, Attack2Bag_ColorBase, CoyoteBag_ColorBase, AliceBag_ColorBase append "NBCBag" next to "Chemlight", "WalkieTalkie", "Backpack_1". SmershBag and ChildBag_ColorBase do not. The pack item is scripted as NBCPack_ColorBase (Container_Base); its CfgVehicles entry is not in this extract ([UNVERIFIED]).
  • GP5 / Airborne protection moved to the filter. (until 1.29: class Protection on both masks included biological = 1 and dust_particle_breath = 1.) (since 1.30 Exp: those two keys are omitted; only dust_particle_eyes = 1 remains. GetProtectionLevel reads the attached GasMask_Filter. The sealed GasMask class still has full passive Protection. There is no class named FilterBase.)
  • ItemBaseType parses headSelectionsToHide, hideSelectionsByinventorySlot, varWetMax, temperaturePerQuantityWeight, EnvironmentWetnessIncrements. ItemBase.GetHeadHidingSelection / HidesSelectionBySlot / GetWetMax read the type. Defaults for soaking/drying live on Inventory_Base.
  • Shoe itemSize width. Most footwear bases went from width 4 to width 3 (height also shrank on several boots). LeatherShoes_ColorBase stays {4,2}.
  • WaterPouch_* → Waterskin_* in CfgVehicles. Script stub WaterPouch_ColorBase: Bottle_Base{} remains. Craft: 2 TannedLeather + LeatherSewingKit (−10) → Waterskin_Natural. De-craft: empty Waterskin_ColorBase + blade (−12 HP) → 1 TannedLeather.
  • CraftArmbandFlag.CanDo no longer requires IsEmpty(); it only rejects a flag that is already an attachment. Extra knives (Jambiya, Scimitar, DonerKnife, Akinaka) are valid tools.
  • Wash head / wet clothing. New ActionWashHead* / ActionWetClothing* apply per-slot wetness and GetThermalBiasHandler().Add(-THERMAL_BIAS_WASH_HEAD_DECREMENT). [CHANGELOG] known issue: bottles can still Wash Head while frozen; ActionWashHeadItemContinuous.ActionCondition does not call GetIsFrozen().
  • Nasdara/Badlands garments (Kameez, Shalwar, Pakol, DustGoggles, …) have scripts under ItemBase\Clothing\ but no characters_* config in this public extract ([UNVERIFIED] heatIsolation / cargo).

What breaks for a 1.29 clothing/gear mod

  1. NBC clothing that lists only the primary slot cannot layer with regular Headgear/Body/Legs/Feet/Gloves.
  2. Custom backpacks without "NBCBag" cannot take the NBC pack attachment.
  3. GP5/Airborne clones with hardcoded biological on the mask, or that skip attachments[] = {"GasMaskFilter"}, will not match 1.30 filter-gated protection.
  4. CreateObject("WaterPouch_Natural") / recipes naming WaterPouch_* fail: the config class is Waterskin_Natural.
  5. Shoe mods still at width 4 occupy more grid than vanilla 1.30 footwear.
  6. Dual-slot headgear that omits headSelectionsToHide[] / hideSelectionsByinventorySlot will clip or hide the wrong head selections.

Migration checklist

  • NBC pieces: inventorySlot[] includes the matching NBC* slot.
  • Backpacks that should carry the NBC pack: attachments[] includes "NBCBag".
  • Filter masks: attachments[] = {"GasMaskFilter"}; biological protection lives on GasMask_Filter, not on the mask Protection block.
  • Declare headSelectionsToHide[] / varWetMax / optional EnvironmentWetnessIncrements on the clothing class (read via ItemBaseType).
  • Replace WaterPouch_* with Waterskin_* (optional 1.29 alias: empty WaterPouch_Natural: Waterskin_Natural { scope = 1; } [DESIGN]).
  • Recheck shoe itemSize[] if you balanced against vanilla width 4.
  • Armband-from-flag: CanDo must not assume IsEmpty().
  • Gate remains in-game: spawn → equip → move (killers #1–#3 unchanged).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.