dayz-proxy-align
Skill20 starsChanged 41 days agoMITView on GitHub
Use when: align proxy, clothing shows at the floor, dressable mannequin, proxy orientation, ropa al suelo, worn vs ground (_m vs _g). Proxy triangles on a host. Not general LOD/memory edit: dayz-p3d-inspector; not clothing mesh/weights: dayz-clothing.
- Installs packages
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- 3d-generation-harnessSkill
- ai-3d-to-dayzSkill
- ardy-motion-generationSkill
- blender-animationSkill
- blender-assemblySkill
- blender-visual-reviewSkill
- dayz-3d-viewerSkill
- dayz-ai-patternsSkill
- dayz-animation-pipelineSkill
- dayz-aviationSkill
- dayz-basebuildingSkill
- dayz-charactersSkill
- dayz-clothingSkill
- dayz-doorsSkill
- dayz-environment-hazardsSkill
- dayz-feature-specSkill
- dayz-mcp-verifySkill
- dayz-model-pipelineSkill
- dayz-mod-workflowSkill
- dayz-motorbikesSkill
- dayz-p3d-auditSkill
- dayz-p3d-inspectorSkill
- dayz-particlesSkill
- dayz-pbo-buildSkill
- dayz-pbo-reverse-engineeringSkill
- dayz-persistenceSkill
- dayz-physics-engineSkill
- dayz-preflightSkill
- dayz-realistic-animation-directorSkill
- dayz-sound-systemSkill
- dayz-test-ingameSkill
- dayz-texture-pipelineSkill
- dayz-ui-developmentSkill
- dayz-undergroundSkill
- dayz-vehiclesSkill
- dayz-weaponsSkill
- enforce-script-referenceSkill
- mixamo-retargetSkill
- ovh-cloudSkill
- rigorous-data-auditSkill
- rip-vehicle-importSkill
- systematic-debuggingSkill
- task-observerSkill
- uv-clean-atlasSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
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
- Very specific: line 89
Use space="engine" when the matrix describes the pose expected in DayZ.
- Very specific: line 91
All mutators are fail-closed: path, index, anchor, rotation, scale, canonical proxy anatomy and exclusive ownership are validated before …
≈ “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.
Files
DayZ Proxy Align — visual proxy positioning + lossless write-back
A DayZ proxy is a named selection proxy:\path\to\model.NNN over ONE tiny triangle in
a Visual LOD. That triangle encodes the attachment frame, but the engine derives it by
angle-sort, not by vertex order (see "The proxy frame convention" below): the widest-angle
corner is the anchor/position and the other two corners give the orientation. When the
triangle is degenerate or mis-oriented, the attached clothing/item renders at the floor,
floating, or rotated.
This skill is the visual, fast alternative to blind FORWARD/UP-knob iteration: it loads the host model + every proxy, lets you drag/rotate each anchor with a TransformControls gizmo against the real worn clothing, and writes the edited triangles straight back into the MLOD with py3d — losslessly.
When to reach for it
Misplaced/mis-oriented proxies on any host model — most often a dressable static
object (mannequin, Armor-Rack pattern: Inventory_Base/Container_Base that embeds
vanilla \dz\characters\proxies\*_dz proxies and declares clothing attachments[]).
Symptoms: equipped clothing shows at the floor, floats, clips, or is rotated.
Pipeline
.p3d --extract--> recipe.json --worn_overlay(optional)--> recipe+worn
--viewer--> drag/rotate gizmo --export--> edits.json --apply--> aligned .p3dDependencies
# py3d DayZ fork >= 1.6.0. Pick ONE route; both end in the same assert below.
# NEVER `pip install py3d` (PyPI = point-cloud lib) NOR git+upstream (without guards).
#
# Route A - this pack is checked out:
pip install -e tools/py3d
# Route B - a vendored wheel is present in this skill's wheels/ directory. That wheel
# is placed by the local py3d rollout and is NOT shipped in this pack; the installer
# fails closed when it is missing, and refuses to guess when legacy wheels sit beside it.
# python3 scripts/install_py3d.py
python3 -c "import py3d; assert getattr(py3d,'IS_DAYZ_FORK',False) and tuple(map(int,py3d.__version__.split('.')))>=(1,6,0), (py3d.__version__, py3d.__file__)"
pip install numpy --break-system-packagesWorn-mesh preview of vanilla clothing also needs an external ODOL→MLOD backend
(vanilla *_m.p3d are ODOL); pass its scripts dir to worn_overlay.py --odol-backend
or set DAYZ_ODOL_BACKEND_ROOT. The host model itself must be MLOD (binarized hosts:
convert them externally first).
py3d lifecycle (pack fork >= 1.6.0, batch / non-visual)
For deterministic automation, the pack py3d fork (>= 1.6.0) owns the complete add/inspect/align/remove lifecycle:
import py3d
with open("host.p3d", "rb") as handle:
model = py3d.P3D(handle)
lod = model.lods[0]
name = lod.add_proxy(
r"\dz\characters\proxies\vests", 1,
origin=(0.0, 1.1, 0.0),
rotation=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
space="engine",
)
descriptor = {
item["name"]: item for item in lod.get_proxies(strict=True)
}[name]
lod.align_proxy(
name,
origin=(0.0, 1.15, 0.02),
rotation=descriptor["engine_frame"],
space="engine",
)
# lod.remove_proxy(name)
model.save("host_aligned.p3d")The legacy default remains space="raw". In 1.4.0 the explicit conversion is
engine_frame = P' × raw_frame, with
P' = ((-1,0,0),(0,0,1),(0,1,0)); the same involutive matrix converts back.
Use space="engine" when the matrix describes the pose expected in DayZ.
All mutators are fail-closed: path, index, anchor, rotation, scale, canonical
proxy anatomy and exclusive ownership are validated before mutation.
get_proxies(strict=True) rejects malformed proxy selections. align_proxy
preserves point/face/selection identities; remove_proxy deletes exactly its
selection, face and three points, remaps surviving point indices and sharp
edges, and intentionally leaves the normal pool unchanged.
py3d 1.4.0 lifecycle (plugin projection, historical)
The Cowork plugin projection vendored py3d 1.4.0 as a wheel and documented the
same add/inspect/align/remove API under this heading. This pack uses the fork
>= 1.6.0 via pip install -e tools/py3d — see the lifecycle section above.
The 1.4.0 conversion engine_frame = P' × raw_frame with
P' = ((-1,0,0),(0,0,1),(0,1,0)) is unchanged.
Scripts
| Script | Purpose |
scripts/proxy_frame.py | the source-verified proxy-frame convention (angle-sort -> anchor + orientation matrix; canonical-triangle builder). shared by extract/canon |
scripts/proxy_extract.py | host .p3d -> recipe.json (body mesh + every proxy's triangle, derived frame + ambiguous flag, ref model path) |
scripts/worn_overlay.py | resolve the worn-on-male model per slot (a default item is seeded for every slot; override any with --map), debinarize ODOL, inject LOD0 geometry as proxies[i].worn |
scripts/proxy_canon.py | rewrite every proxy as a canonical unambiguous triangle -> edits.json (identity by default = worn upright, or per-slot --rot) |
scripts/proxy_viewer.py | recipe.json -> standalone HTML editor (move/rotate gizmo, worn ref + assembled "final result" overlays; export bakes canonical triangles) |
scripts/proxy_apply.py | edits.json + src .p3d -> aligned .p3d (edits the MLOD in place; lossless) |
Quick start
python3 scripts/proxy_extract.py maniqui.p3d recipe.json
# worn reference: every slot gets a sensible default _m item out of the box.
python3 scripts/worn_overlay.py recipe.json recipe.json --dz "/path/DZ" \
--odol-backend "/path/to/odol-backend/scripts"
# --map Vest=vests/press_vez Legs=pants/cargopants # test specific items per slot
# --dry-run # just print the resolved mapping
# --no-defaults # start empty, map only what you pass
# FAST PATH — fix the common "worn but rotated" case in one shot (no GUI):
python3 scripts/proxy_canon.py recipe.json edits.json # identity frame for every slot
# --rot Headgear=Y:90 Mask=Y:90 # per-slot rotation only where needed
python3 scripts/proxy_apply.py maniqui.p3d edits.json maniqui_aligned.p3d --verify
# INTERACTIVE PATH — dial orientation in by eye:
python3 scripts/proxy_viewer.py recipe.json proxy_align_viewer.html
# open the HTML, align each proxy, click "Exportar edits", save as edits.json
python3 scripts/proxy_apply.py maniqui.p3d edits.json maniqui_aligned.p3d --verifyUsing the editor
Click a proxy (sidebar or its sphere) to attach the gizmo. W = move, E = rotate; drag the arrows/rings. Two clothing overlays help you align:
- Resultado final — every slot's worn mesh attached to its proxy, rigidly following your edits. This is the assembled "dressed mannequin" preview: align the proxies, toggle it on, and see the whole result at the current alignment.
- Worn ref — the selected proxy's worn mesh in its native character-space position, as a fixed target to align the anchor against.
"Reset proxy" restores a proxy to its loaded position. "Exportar edits" opens a modal;
Select-All + Ctrl+C (clipboard is blocked on file://) and save as edits.json.
The gizmo sets the anchor position and the frame rotation; on export the skill writes a canonical (unambiguous) triangle encoding exactly that, so the engine re-derives the frame you set. Scale is fixed (proxies are a tiny triangle); only position + rotation matter.
The model-variant rule (clothing has MORE THAN ONE model)
DayZ clothing ships as variants distinguished by suffix:
<item>_m— worn on the male player. Use this for a male host.<item>_f— worn on the female player.<item>_g— ground/dropped model (the "default"/floor one). Not this.
worn_overlay.py seeds one default _m item per slot and always prefers _m when
resolving. If a slot has several plausible candidates (e.g. plate_carrier_m,
plate_carrier_holster_g), it reports them and you should pick one explicitly with --map
— do not silently guess; surface the choice to the user. Picking the _g/ground model
is the classic cause of "it shows the floor model".
Note the scope boundary: the engine swap that replaces a slot's default *_dz proxy
with the equipped item's worn model is config/skeleton behaviour (e.g. the F2.3 problem on
a static Inventory_Base), separate from anchor position. This skill aligns the anchor and
previews the correct worn variant; it does not by itself force the engine swap.
Why write-back is safe (the viability gate)
The dayz-p3d-inspector Recipe->build path does NOT write proxies and can drop Memory
selections, so this skill never uses it. Instead proxy_apply.py loads the MLOD with py3d,
mutates ONLY the listed proxy points, and re-writes. py3d round-trips a real DayZ MLOD
byte-for-byte, so the host geometry, the host's own selections (e.g. woodup1/zbytek),
the Geometry/Memory LODs and #UVSet# are preserved. Before trusting an edit, re-extract
the output and confirm the proxy count and non-proxy selections are unchanged
(proxy_apply.py --verify).
The proxy frame convention (orientation is deterministic)
Coords are raw MLOD (Y-up), rendered directly (matches dayz-p3d-inspector). The engine reads a
proxy triangle by angle-sort, verified against Arma3ObjectBuilder (utilities/proxy.py
find_axis_vertices / get_transform_rotation / create_proxy; doc
https://mrcmodding.gitbook.io/home/documents/proxy-coordinates):
- sort the three corners by interior angle, descending;
- widest-angle corner = anchor (position);
- middle-angle corner direction = local +Y; smallest-angle corner direction = local +Z;
- +X = Y x Z, then Z re-orthogonalized.
It is pure geometry, so orientation is fully reproducible offline — proxy_frame.py computes
the same matrix the engine does. The old "confirm rotation in-game by trial" caveat came from not
knowing this rule (tests/test_proxy_frame.py checks it offline: canonical -> identity, the 90/45/45 tie -> ambiguous, rotation round-trips).
The degenerate-triangle gotcha (the usual cause of "worn but rotated"). If the two edges from
the anchor are equal length — the 90/45/45 isosceles triangle hand-rolled proxy builders tend to
emit — the middle and smallest angles tie, so +Y/+Z get assigned by raw vertex order and the
engine picks a rotated, unintended frame. proxy_extract.py reports this as ambiguous. Fix it
with a canonical triangle that has three distinct angles (90/63.4/26.6): proxy_canon.py
rewrites every proxy to a canonical frame (identity by default, or per-slot --rot), and the
viewer's export bakes canonical triangles too. Any rotation of a canonical triangle stays canonical
(rotation preserves angles), so an exact orientation survives the lossless write-back.
Worn-mesh overlays are shown in native character-space coords (a robust positional reference); with canonical frames the "Resultado final" preview matches the engine's orientation rather than only approximating it. Engine-exactness for DayZ vs Arma3 MLOD is [verify in-game] but high-confidence — same MLOD format.
Sibling skills
- dayz-p3d-inspector — general MLOD viewer/editor + Recipe round-trip (this skill is the proxy-specialized, write-safe counterpart).
- External ODOL→MLOD backend — required for vanilla worn meshes and binarized hosts; not distributed with this pack (
--odol-backend/DAYZ_ODOL_BACKEND_ROOT). - dayz-p3d-audit / dayz-pbo-build — audit the aligned .p3d and validate before packing.
Vehicle crew proxies (added 2026-06-05)
The angle-sort frame convention above (widest-angle corner = anchor; middle = +Y;
smallest = +Z) and the 90/45/45 isosceles gotcha are NOT clothing/mannequin-only. They
apply identically to vehicle crew proxies — crewdriver / crewcodriver, i.e.
proxy:\dz\vehicles\wheeled\proxies\crew_driver. A crew proxy is the same tiny triangle
in a LOD and is read by the same angle-sort.
Real case — LFQuad 2026-06-05. crewdriver / crewcodriver were 1 mm 90/45/45
triangles → ambiguous frame → driver and co-driver sat sideways and the player
rotated on get-in. The tie resolved differently per seat (one had +Y mapping to "up",
wrong; the other +Y to "forward", correct), so the same bug looked different on each
seat. Fix: canonical triangles (three distinct angles) with +Y → vehicle forward,
+Z → up (use proxy_canon.py / canonical_triangle).
The crew proxy ANCHOR sets the seated player's POSITION/HEIGHT. The config proxyPos
resolves the seat from the proxy in the ViewGeo LOD — NOT from a memory point or a bone.
An anchor placed too high seats the player in the air. LFQuad evidence: anchors at
Y=1.46 / 1.70 left the rider elevated; corrected down to actual seat height.
A crew proxy positions and yaws; the engine keeps the rider upright (added 2026-09-23, LFDucati T94). [EXACT] Measured in game (DayZ 1.30.164014 Exp): CrewTransform returns exactly the ODOL proxy rows conjugated by R = diag(-1,1,-1) (origins through the same R) — the engine's crew model space is the ODOL reader's space rotated 180 deg about Y — but a proxy pitched 20 deg forward still seated the player vertical with a fixed ~17 deg yaw and the hips 35 cm back, and a 20 deg roll left the player standing ~30 cm beside the bike. Proxy pitch and roll never reach the rider: leaning or crouching needs animation, and what the engine does must be measured from the player frame and bones in vehicle space, not by eye.
Do not copy a frame raw from another sub-model's proxy. Croco bus_* proxies are
not vanilla crew_*; the correct frame depends on the sub-model. For vanilla crew
proxies the rule is +Y → forward.
Crew-proxy frames beyond identity: gate the ODOL, set the convention first (added 2026-09-23, LFDucati T90/T93). [EXACT] A crew proxy triangle authored as RAW-space identity came out of binarize with rows aside -X, up +Z, dir +Y in the ODOL, while the vanilla Motorbike_02 proxies read identity in the same reader — and in game the driver stood sideways and spun on get-in (measured in game, DayZ 1.30.164014 Exp). Write crew proxies with space="engine" and the frame the vanilla model carries after binarize (identity for crew and wheels). [DESIGN] The gate is the FILE THE ENGINE READS, compared with a model that works, with the same ODOL reader: diff every proxy of the export against the vanilla equivalents, fail on the known-broken build (negative control) and pass vanilla-vs-itself (positive control). A checker that re-derives the frame with the exporter's own convention goes green on its own error; a gate that compares the ODOL with what was requested only proves the file carries what was written, not what the engine does with it. Before building rotated variants, fix the convention with a working reference: how a vanilla ODOL writes a known rotation, or a small per-axis rotation verified in game.
Pure-geometry proxies: MODEL-SPACE geometry + the engine-identity frame P' (added 2026-06-24; in-game VERIFIED 2026-06-24)
For a pure-geometry proxy (a body region split off to beat the 65535 vertex ceiling —
proxy:\<mod>\proxy\chassis.NNN, 1 visual LOD, no config class), TWO things must be right:
- Geometry authored in MODEL-SPACE (its real position on the car, NOT centered at its own origin).
Measured by debinarizing vanilla proxies (
prox_intY[0.36,1.56] cabin,sedan_engineZ[-2.30,-1.12] front) + Star_Audi_R8 + kt_roadkill_body. Centering each chunk at its own origin piles them all at the host origin. - Triangle FRAME = the engine-identity
P' = [[-1,0,0],[0,0,1],[0,1,0]], NOT this skill'sderive_frameidentity. SameP'as the weapon-proxy section below: the skill/py3d "identity" renders the geometry LAID ~90 deg to the side;canonical_triangle(anchor, P')(i.e.add_proxy(path, rotation=P')) renders it as authored. VALIDATED IN-GAME on MercedesAMGLF body-proxys 2026-06-24 (AC1.4 PASS), independently of the A6_SR2M weapon-proxy validation. This SUPERSEDES the earlier note here ("origin anchor + skill-identity is mandatory") — that was offline-only and rendered the MercedesAMGLF body rotated ~90 deg in-game (the offline frame/render gave green-in-false twice).
Path carries NO .p3d extension (engine appends it; a doubled .p3d.p3d = proxy silently absent in-game).
Attachment proxies (wheel/crew/door) are NOT a placement reference — physics/config place them (proxyPos,
axles); their non-zero pos misleads. Gate: for proxies the offline frame/render is NOT valid — the gate is
the in-game spawn+render. Vehicle case + the three rules (path / frame P' / model-space): skill dayz-vehicles
(body-proxy convention, CONFIRMED in-game).
Weapon attachment proxies + the engine-vs-skill convention map (added 2026-06-24, A6_SR2M)
A weapon's proxy: selections (suppressor_45acp, optic_*, *_mag, a custom rail mount) orient the
ATTACHED item exactly like clothing proxies. Hard-won lessons from the A6_SR2M comp/rail/optic:
- The engine reads the triangle as
h(R) = P'·R, withP' = [[-1,0,0],[0,0,1],[0,1,0]](a 180° rotation about the Y+Z diagonal) relative to this skill'sderive_frame. Soderive_frameis the skill frame, the rendered frame isP'·derive_frame. Validated in-game: a rail baked with the skill-IDENTITY frame rendered "laid 90° to the side"; a frame ofP'renders upright. Thereforecanonical_triangle(anchor, P')makes the engine render IDENTITY. (Resolves the old WARNING inproxy_frame.py: the skillderive_frame≠ engine; they differ byP'.) - Matching a vanilla item's frame value works only if your model is authored like the vanilla one. optic_reflex (vanilla model) + mag worked by copying the vanilla frame bit-for-bit. A CUSTOM muzzle/comp model authored on different local axes does NOT — it renders rotated even at the "correct" vanilla frame.
- Find the bore by the HOLE, not by bbox/hollow heuristics. A custom comp had a circular bore hole
AND an oval vent hole, plus a perpendicular tab longer than the bore.
bbox-longest and central-void/hollow detection both pointed at the wrong axis. The reliable method: render the MUZZLE VIEW (orthographic projection looking down world X = the barrel, at the current proxy frame) and locate the round (circular = bore) vs elongated (oval) holes. The barrel must pass through the CIRCULAR hole. - Fix = shift + roll, verified against the user's in-game photo. Detect the circular hole's Y-Z
center; translate the proxy triangle so that center lands on the barrel line (anchor Y/Z); apply the
needed roll about world X (e.g. 180°:
p -> (p.x, 2*Yb - p.y, -p.z)). Re-render the muzzle view to confirm the barrel+is centered in the circular hole before building. - The inventory PREVIEW does NOT use the proxy — it renders the raw MODEL. Fixing the proxy fixes
in-game but the icon still shows the model's authored (wrong) orientation. To make the preview match
in-game, bake the proxy's orientation
M = engM(proxy)into the MODEL (rotate every LOD's points + the normal pool + memory points byM) and reset the proxy tocanonical_triangle(anchor, P')(engine-identity). In-game is unchanged (anchor + I·(M·v) == anchor + M·v); the preview now shows the in-game orientation.
Session tooling not preserved (the muzzle-view render, hole detection, shift+roll bake and weapon+attachment overlay scripts lived in a session TEMP dir); the method described above is sufficient to re-derive them.
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
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.

