◆Plaster// Armory
Armory

Mag-fed

// every model in the game: built in code from simple shapes (src/models.js), and the Can, the oil drum, the marker, Woodland's wood, trees, rocks, logs, bushes and grass, made in Blender (tools/blender/)

Mags that work like a real weapon. Each model below is rendered on its own, with its version history underneath.

Side view of the mag-fed marker modelled in Blender: flash-hider muzzle, M-LOK handguard, flat-top receiver with a red dot and flip-up rear sight, PMAG-style magazine with an orange pull loop, pistol grip, and a skeleton stock with the carbon air tank running through it.
01 // Magazine
20-rd mag
drops out down the magwell
02 // Optic
Red dot
lines up dead-center in ADS
03 // Barrel
.68 cal
real paint, real arc
04 // Air
Tank in the stock
carbon bottle, gauge on the reg

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

Side view of the bolt-action sniper in olive with brass accents: suppressor-style shroud, thin barrel, quad-rail handguard with a folded bipod, long scope on two rings, short magazine, pistol grip and a precision stock with a cheek riser.

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.

Looking through the 4x scope at a bunker: black surround, fine crosshair with heavy posts.Scoped
Through the scopeAim down sights and the screen becomes the scope: 4× zoom, the marker hidden, look speed slowed by the zoom.
First person with the sniper just after a shot: the marker rolled right, the bolt handle pulled back.Bolt
Working the boltAfter every shot the bolt goes back and forward (1.25 s, with the bolt sound) before the next one.

02P17 pistol (sidearm)

Side view of the P17 pistol: black slide with front and rear serrations and white-dot iron sights, polymer frame with an accessory rail, trigger with its safety blade, stippled grip with a beavertail and the magazine's base plate.

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.

First person with the pistol at the hip, held in the right hand low on the screen.Hip
At the hipHeld out low and right, a little farther from the eye than the rifle so it reads at its real size.
Aiming the pistol: both gloved hands on the grip, thumbs forward, the iron sights centred on a bunker.Aimed
AimedBoth hands on the grip, thumbs forward, the line over the iron sights on the screen centre.

03First-person rig

In game, first person: the character's camo sleeve and grey gloves on the marker's grip and handguard.
In your hands

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 in tools/blender/hand_poses.json. tools/blender/hand_fit.py fits every finger onto the marker's surface (and puts the character's hands where the first-person ones are).

04Player

A Red team magfed player: i5-style paintball mask with a red strap, camo field jacket and cargo pants, red armbands, gloves and boots, holding the marker right-handed.
Operator

Magfed player

  • Kitted for magfed (a MakeHuman/MPFB body dressed in Blender, tools/blender/character_mpfb.py, made game-ready by tools/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.blend to 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.
Blue team player
Crouched
Aiming down sights: marker up at the face, head on the sight
Eliminated, hand up
The Ranger character: arid camo shirt, green pants, a coyote plate carrier with mag pouches, tan mask, a cap worn backwards.
Operator · pick under Operators

Ranger and Urban

  • Same body, different kit: tools/blender/character_mpfb.py --variant ranger|urban dresses the same MPFB body on the same rig, so every character is the same size and is hit the same way. character_game.py bakes 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.
The Urban character: charcoal top, urban camo pants, black chest rig, white mask, beanie.
Back view: jersey number and a four-pod harness.
Rear

Number + pod pack

Part of player v2

Jersey number across the back; a harness holds four translucent paint pods with team-color lids.

Close-up of the paintball mask.
Head

Paintball mask

Part of player v2

Goggle 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

Orange and green paintballs with matching splats.
.68 caliber

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

The inflatable bunker set.
Cover

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

The Can bunker modelled in Blender: yellow nylon panels, black stripe with PLASTER printed on it, valve and stake tabs.
Cover · first Blender model

Can

  • Built by a script: tools/blender/can.py runs 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.
Three oil drums in blue, rust and olive paint: rolling hoops, rolled chimes, chipped and rusted edges, rust streaks, bungs on the lid, and a white FUEL / DIESEL 200 L stencil.
Props · Woodland

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.py also saves blender-out/barrel/barrel.blend, packed and lit with three painted drums.
A Woodland shack in the game, walls of weathered vertical boards: silvered brown wood with visible grain and knots, rows of nails with rust running down, butt joints, dark gaps between boards, and corner posts.
Textures · Woodland

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.py also saves blender-out/planks/planks.blend, a lit wall with a window.
A Woodland trail through the field in the game: green forest-floor grass mottled with brown patches and twigs on both sides of a stony dirt path, grass tufts, sandbags and a fallen log, with forest beyond.
Textures · Woodland · PolyHaven

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 in PBR in src/woodland.js.
A Woodland trail in the game, seen from standing height: packed brown earth scattered with gravel and flat grey stones that catch the light, edged by grass tufts, sandbags and a fallen log, with forest beyond.
Textures · Woodland · PolyHaven

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).
Looking down a Woodland trail between spruces and broadleaves: warm brown leaf litter with twigs under the trees on both sides, the stony trail between, rocks, bushes and a fallen log.
Textures · Woodland · PolyHaven

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_*).
The mud patch at Woodland's outpost: a dark, trampled patch of soil with clods and footprints in the gravel, an old truck, crates, shacks and fuel drums around it.
Textures · Woodland · PolyHaven

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 in PBR in src/woodland.js.
A Woodland spruce stand in the game: tall Norway spruces with grey scaly trunks, whorls of drooping branches clothed in needle sprays, a broadleaf tree at the edge, and the trail and netting behind.
Nature · Woodland

Trees

  • Grown, not sculpted: tools/blender/trees.py grows 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.blend opens all six, lit, with their lower LODs alongside.
A Woodland clearing in the game: a fallen log with bark ridges, moss and branch stubs in the foreground, a stump with roots flaring into the ground, a mossy granite boulder, a leafy bush and clumps of grass with seed heads.
Nature · Woodland

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.blend opens 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.

// renders come from tools/showcase.html in the repo — open it on the dev server to inspect any model from any angle