Mag-fed
Mags that work like a real weapon. Each model below is rendered on its own, with its version history underneath.
Modelled in Blender after a real mag-fed marker (Tippmann TMC style), traced at real scale from a photo: AR lower with the grip and trigger guard, M-LOK handguard, short barrel with a flash hider, flat-top upper with a red dot and flip-up rear sight, PMAG-style mag, skeleton stock with the carbon air tank through it and a gauge on the regulator. ~0.86 m long, 62k triangles in your hands, an 8k version on other players. The mag drops out down the magwell, the charging handle pulls back on a full reload and the trigger moves on every shot. Body and accent colours still come from POE. Script: tools/blender/marker.py.
01Bolt-action sniper

The built-in marker's sniper frame, modelled in Blender after a real bolt-action DMR (the 468 PTR "Black King"): the magfed lower and upper with a long quad-rail handguard, a thin barrel into a ported suppressor-style shroud, a long scope on two rings, a precision stock with an adjustable cheek riser, a folded bipod and a short 5-round mag. The bolt handle on the right goes back and forward after every shot. The Sniper marker in POE uses it in olive with brass accents; any built-in marker can pick the frame.
Scoped
Bolt02P17 pistol (sidearm)

The built-in sidearm, modelled in Blender after a .43 cal mag-fed paintball pistol in the shape of a Glock 17 Gen 5 (the T4E G17), traced at real scale (202 mm) from a side photo: slide with serrations front and back and white-dot iron sights, polymer frame with the accessory rail, stippled grip with the beavertail, ambidextrous slide stops, an 8-round magazine with the CO2 inside. Its grip sits on the rifle's grip point, so other players hold it in the right hand. The slide blows back on every shot and locks back on an empty mag; the magazine drops out on a reload. Script: tools/blender/pistol.py.
Hip
Aimed03First-person rig

Marker + arms
New in v2 build · 2026-10-12- Drawn in its own pass with its own camera: never clips into bunkers, doesn't stretch when ADS zooms.
- Lit by the same sun and sky as the world.
- Animated in code: walk bob, mouse lag, recoil kick, sprint pose, mag-drop reload.
- The arms are the player character's own (
tools/blender/character_game.py): posed on the marker as the first-person camera sees it, fingers curled onto its surface, cut off at the shoulder. The pistol has its own two-handed pose. - Hands are posable: the arm and finger bones are in the rigs (
character_game.blend: Rig, ViewArms, ViewArmsPistol); pose them in Blender and run Export to game.py. Poses persist intools/blender/hand_poses.json.tools/blender/hand_fit.pyfits every finger onto the marker's surface (and puts the character's hands where the first-person ones are).
04Player

Magfed player
- Kitted for magfed (a MakeHuman/MPFB body dressed in Blender,
tools/blender/character_mpfb.py, made game-ready bytools/blender/character_game.py): an i5-style paintball mask over a balaclava, camo field jacket and cargo pants with pockets, flaps, elbow and knee pads, gloves with knuckle pads, laced boots. The folds, pockets, vents and fingers are baked from the 400k-triangle study into one 2048 texture set. - Right-handed: right hand on the grip, finger along the trigger guard; left hand under the handguard.
- Teams wear coloured armbands and the mask strap in the team colour; the player number is a patch high on the back.
- One skinned mesh (37k triangles) on the same joints as before: hips and knees for walking and crouching, the upper body tilts to aim. Each shot kicks the marker back. Open
blender-out/character-game/character_game.blendto see it in Blender. - The hand-up "I'm out" signal is modelled (a blend shape posed through the whole arm), so the shoulder folds instead of stretching. Paint sticks to the exact part that was hit.
- Aiming down sights: the marker and arms come up to the face and the head dips onto the sight. Bots do it when lined up on someone at range or watching an angle; online you see everyone's.





Ranger and Urban
- Same body, different kit:
tools/blender/character_mpfb.py --variant ranger|urbandresses the same MPFB body on the same rig, so every character is the same size and is hit the same way.character_game.pybakes each into its own file with its own first-person sleeves and gloves. - Ranger: arid camo shirt, ranger-green pants, a coyote plate carrier (three mag pouches, admin pouch, MOLLE and drag handle on the back; the number patch sits on the carrier), a cap worn backwards, tan mask.
- Urban: charcoal top, urban camo pants, a black chest rig with four pouches and an H harness, a beanie, white mask.
- Team colour on the armbands and mask strap, like the Woodland player.


Number + pod pack
Part of player v2Jersey number across the back; a harness holds four translucent paint pods with team-color lids.

Paintball mask
Part of player v2Goggle frame, mirrored lens that reflects the sky, top visor, ear guards, vented jaw and strap over a team-color headwrap. It's what makes the silhouette read as paintball, not military.
05Paint

Paintball + splat
- Blue fires orange, Red fires green, so you always know whose shot it was.
- Glossy shell drawn ~2× real size (17 mm), stretched along its path in flight.
- Splats: lumpy core, thrown streaks, droplets; five variants; wrap onto curved surfaces; fade after 20 s.
06Field

Inflatable bunkers
- Can 1.8 m and Pin 2.7 m: stand-behind cover. The Can is now modelled in Blender (below).
- Cake 0.95 m and Snake 8 m: crouch cover you can also jump on.
- Brick, Temple, the center X, and the three-sided Dorito.
- Collision matches each real outline. Due to be replaced by wooden woodsball barricades.
- Placed with the map editor: each bunker’s colors can be changed there, and the temple’s size and the snake’s length are adjustable. Team flags, canopy tents and spawn zones are placed the same way.
07Modelled in Blender

Can
- Built by a script:
tools/blender/can.pyruns Blender headless, so the model can be rebuilt or tweaked any time (blender -b --python tools/blender/can.py -- public/builtin --previews). - Eight sewn panels bulge between the seams; the top seam pinches in with gathered wrinkles; stitching puckers along every seam; the stripe is a raised band. Fill valve and four stake tabs with D-rings.
- A 2.6M-triangle sculpt baked onto a 7.8k-triangle game mesh: 2048 px normal, occlusion and roughness maps, 0.7 MB in all (
public/builtin/can.glb). - The color map is a mask (stripe, shading, dirt), painted in the game, so editor colors still work; PLASTER is printed on the stripe. Paint and sight hit the nylon body only.

Oil drum
- A real 200 L steel drum: rolled chimes, rolling hoops and swedges, a recessed lid with a stiffening ring, embossed UN markings, two bungs, a welded seam, dents.
- Worn: paint chipped to rust where drums get knocked (chimes, hoops, base), scratched to bright steel, rust streaks bleeding down, grime, a stencilled FUEL / DIESEL 200 L.
- 1M-triangle sculpt baked onto a 6.2k-triangle game mesh (
public/builtin/barrel.glb, 0.8 MB). The colour texture is a mask, so the editor's Paint option (blue, rust, olive, red) still works. - Open it in Blender:
tools/blender/barrel.pyalso savesblender-out/barrel/barrel.blend, packed and lit with three painted drums.

Plank wood
- Textures, not a model: plank walls are built from the editor's numbers (any length, window or door), so the detail lives in tileable PBR maps that every plank wall, deck, crate, stair, bridge and post shares.
- Real grain: growth rings traced from a pith behind each board, cathedral arches or straight rift grain, latewood standing proud of the weathered earlywood, knots with the grain swirling round them.
- Weathered: butt joints, wandering gaps, rounded edges, cupping, drying checks, saw marks, nails with iron stains and rust runs, silvering, water stain, lichen, grime.
- Colour, normal and AO/roughness maps: a 2 m sheet of 12 boards at 2048 px and a 1 m beam at 1024 px, 4.4 MB of WebP (
public/builtin/textures/).tools/blender/planks.pyalso savesblender-out/planks/planks.blend, a lit wall with a window.

Field grass
- Scanned forest floor: PolyHaven's forrest_ground_01 (CC0), real grass with twigs, dead leaves and bare patches, 2 m to a repeat. The grass tufts stand on it as before.
- Fitted to the field: the scan is pale khaki in Woodland's light, so the shader raises its contrast (a 1.5 power) and tints it green to the old grass's brightness, keeping its browns. Its normal map and roughness fade out under leaf litter, dirt and mud.
- Colour, normal and AO/roughness maps at 2048 px, 5 MB of WebP (
public/builtin/textures/grass_*). Size, contrast and tint per set live inPBRinsrc/woodland.js.

Trail dirt
- Photo-scanned, not painted: the first texture from PolyHaven (CC0, free to use with no credit needed),
forest_ground_04: a real forest trail of packed earth, gravel and small stones. - On every trail and dirt patch: the ground shader blends it in where the map paints dirt, with the normal map lighting the stones and the scan's roughness, both fading out where the trail meets the grass. A warm tint keeps it with the leaf litter.
- Colour, normal and AO/roughness maps at 2048 px, 4.6 MB of WebP (
public/builtin/textures/dirt_*), loaded with the Blender wood. Grass, leaf litter and mud are PolyHaven scans too (below and above).

Leaf litter
- Under every forest patch: PolyHaven's forest_leaves_04 (CC0), broadleaf leaves, twigs and needles on forest soil, 1.5 m to a repeat.
- Fitted to the field: a second rotated sample breaks up the small scan's tiling, more contrast keeps it darker than the trails, and its roughness is held at 0.92 or more so dry leaves don't glare grey in the sun.
- Colour, normal and AO/roughness maps at 2048 px, 5.5 MB of WebP (
public/builtin/textures/leaves_*).

Mud
- Trampled, not painted: PolyHaven's brown_mud_02 (CC0), soil churned by boots with clods and prints, 1.3 m to a repeat, on the mud patches at the outpost and in the creek.
- Wet: tinted darker than the scan, and the shader still makes mud glossy on top.
- Colour, normal and AO/roughness maps at 2048 px, 3.8 MB of WebP (
public/builtin/textures/mud_*). Size, contrast, tint and roughness per set live inPBRinsrc/woodland.js.

Trees
- Grown, not sculpted:
tools/blender/trees.pygrows six trees from seeds, three Norway spruces (whorls of branches that droop and turn up at the tips, dead stubs below the crown) and three oak-like broadleaves (limbs forking three levels deep to fill a rounded crown). - The way game trees are made: bark tubes swept along the skeleton with tileable bark, and foliage on alpha cards (textured needle sprays and leaf twigs, both painted by the script) whose normals point out of the crown, so it shades like one soft volume.
- Three levels of detail from each skeleton: about 12k triangles a spruce for the trees near you, 2k further off and past the net, 0.8k in the deep woods. Shadows come from the next level down. Trees are scaled and turned per placement, with a little colour variation.
- Every trunk collides at the size of its bark (the stem radius at 1.3 m drives the collision circle). 5.5 MB GLB (
public/builtin/trees.glb);blender-out/trees/trees.blendopens all six, lit, with their lower LODs alongside.

Rocks, logs, stumps, bushes and grass
- Sculpted and baked (
tools/blender/nature.py): four granite boulders, two fallen logs and two stumps, each sculpted at high detail (100-200k faces) and baked onto a light game mesh: a 1024 px colour map with the occlusion in it, and a normal map. - Rocks: fracture faces where they split, cracks, flecked grain, lichen rosettes, moss on top and in the hollows, dirt at the foot. Logs: bark ridges and furrows, patches peeled to grey deadwood, a sawn end with growth rings and checks or a snapped, splintered end, branch stubs, moss along the top. Stumps: roots flaring into the ground, a sawn top with the hinge splinters left standing.
- Bushes: three hazel-like shrubs grown like the trees (stems from the ground, twigs, leaf twigs on cards) in two levels of detail, wearing the trees' own leaf and bark textures. Grass: two painted tufts, green and dry blades with a few seed heads, on bent crossed cards.
- Sized from the editor's numbers as before (rock size and height, log length and radius, stump radius and height), so collision is unchanged. 2.1 MB GLB (
public/builtin/nature.glb);blender-out/nature/nature.blendopens them all, lit, on a lawn of the grass.
08Imported models
Everything else above is built in code. Models made in Blender can be added from the editor too: export a .glb, import it in the map editor, and place it like any bunker. Imported models live in public/models/ and get box collision in the game. None ship with the game yet.