DOOM.wad
Commits
Every published commit of this world, on every branch, newest first.
309bbc2517fix(doom HUD): separate gun screen (firing no longer moves bar), smaller gun lifted clear of the bar, face centered + visibleded94faf9dfix(doom HUD): center face in STBAR, fold gun into HUD screen (cross-platform layering), bob off avatar, larger muzzle windowa5f253ff51doom: nearest-neighbor pixel-art textures + co-op facing relay
- All 223 data-bearing doom textures set to filter=nearest so sprites,
walls and the HUD render as crisp pixel art (sampler bit baked into
each data.ztex).
- Co-op marine facing relays through DoomFaceBus: DoomCamera publishes the
local player's look facing over the multiplayer RPC channel keyed by
account userId; DoomPlayerBody resolves its owner and applies it to the
8-direction billboard.
- Authentic STBAR HUD + centered gun, per-frame avatar-resolve perf fix
across pickups/monsters/doors, and co-op damage via the doom_hit RPC.
---
doom: add DoomFaceBus module README + .metadata sidecarsca6f3a846efix(doom): build door-sector floor flats so the player no longer falls through an opening door (takes effect on next E1M1 geometry rebuild)
---
fix(doom): rebuild scene.json (level + 29 monster-AI + HUD/weapon + sky); drop leaked avatar/camera entities; entrypoint adapts to player.avatar entity-ref
---
feat(doom): reintroduce multiplayer co-op on the fixed MP engine â owner-gated monster AI + Sync state + per-peer visual/self-damage, claim-on-shoot damage routing, synced projectiles, replicated fire-pose (engine now instantiates the scene host-authoritatively, so no manual reconcile)
---
feat(doom): host-authoritative co-op hit routing â publish landed shots on the avatar body, monster-owner applies damage+splash (no claimOwnership)
---
fix(doom): build modules use asset.create overwrite, not computed asset.resolve
Replaces the publish-rejected 'if vfs.exists then asset.resolve(name)'
reuse branches in build_level + build_things with asset.create(name,
{ ..., overwrite = true }), which re-authors in place keeping the guid
stable. No computed asset.resolve remains, so the world is publishable.
---
fix(doom): build_things materials via asset.create not Material.Create
Material.Create's typed textures field ({ [string]: string }) flagged the
ref-object texture binding as a publish-blocking type error. Switch the
four doom_billboard material creations to asset.create("material", ...,
{ shader, textures = { base_color_texture = <texName> }, ..., overwrite })
â the canonical path Material.Create wraps anyway â binding the texture by
its name string.0a489da02bfeat(doom): prewarm pass warms doom textures into memory at play start, so first-display GPU uploads come from memory (cuts the white first-load flash)0b8f273729revert(doom): back out multiplayer co-op to clean single-player â engine play-mode only replicates player avatars, not script/scene entities (setSynced/claimOwnership no-op), so shared-enemy co-op isn't possible until the MP entity-sync work lands. Keeps handedness + all single-player fixes.55774c954cfeat(doom): multiplayer co-op â owner-authoritative synced monsters + per-peer visual/self-damage, claim-on-shoot damage routing, host-election monster sync, replicated fire flash
---
fix(doom): co-op reconcile is receive-before-despawn (never empties the map if the host isn't sharing) + self-heals periodicallyec50c4758efeat(doom): authentic Doom-marine player avatar (8-dir PLAY-sprite body, first-person local)
build_player.module authors the marine body assets via asset.create: 8 view-rotation
stand + walk materials (mirror-packed PLAYA-D, rotations 6/7/8 are real h-flipped
textures), a death-frame sequence, and a shared sprq_PLAY quad at Doom scale.
DoomPlayerBody.component renders the body the way Doom multiplayer does: the owner
hides its own body (entity:hide on isLocal -> first-person), every other client
renders + rotates it from the bearing of that client's camera relative to the
player's facing; walk vs stand from movement speed. Selects among the authored
doomspr_PLAY_* materials (no runtime authoring).
doomguy.bundle (tag: playerAvatar) = first-person controller root + marine body
child. World avatar_default_play=doomguy, camera_default_play=@builtin::controller.first_person.
---
feat(doom): 8-directional sprites â aim-based player body + enemy walk rotation
Shared doom.sprite_decode module owns the mirror-pack decode + doom_billboard
material authoring (one source); build_player + build_actors are thin callers.
Player body: DoomPlayerBody now picks its rotation from the camera bearing
relative to the player's AIM/look direction (Doom-authentic) â the owner
publishes its look facing into replicated faceX/faceZ fields, remotes read them.
A player backpedalling while aiming at you shows their front.
Enemies: build_actors authors 8-rotation walk atlases per monster (POSS/SPOS/
TROO/SARG/BOSS); DoomMonster picks the rotation from the camera bearing vs the
monster's movement heading, so a monster moving away shows its back instead of
always facing the camera.
World camera: DoomCamera (world-content cameraBehavior) is the first-person
follow camera (reads Camera.follow); camera_default_play points at it.
---
fix(doom): first-person pitch inversion + ground monsters (floor-snap)
DoomCamera: flip pitch sign so dragging down looks down (was inverted).
DoomMonster: floorSnap() raycasts straight down each active frame and snaps y to
the floor, so monsters stay grounded when crossing sectors of differing height
instead of keeping their spawn-sector height and floating.
---
fix(doom): robust monster floor-snap + reliable player look-facing channel
floorSnap now casts from just above the feet (+1.0) so it only snaps DOWN to the
floor beneath the monster, never up onto a column top / overhang it stands beside
(the earlier +4.0 origin snapped monsters onto columns, which read as floating /
oversized corpses on death).
Player body facing: DoomCamera publishes the horizontal look direction into the
avatar root's (replicated) rotation; DoomPlayerBody reads the root's forward
instead of writing Sync fields from the hidden body (which did not propagate).
Removed the unused faceX/faceZ fields.
---
feat(doom): weapon system (6 weapons, selection, viewmodel) + facing sign fix
doom.weapons: shared roster (Fist/Chainsaw/Pistol/Shotgun/Chaingun/Launcher;
plasma+BFG are registered-only, absent from shareware). build_weapons authors a
ready+fire viewmodel texture per weapon.
DoomGame: currentWeapon state; number keys 1-6 select the owned weapon in a slot
(slot 1 prefers chainsaw over fist); first-person weapon viewmodel anchored
bottom-center, flashing the fire frame on each shot (DoomWeapon bumps firePulse);
HUD shows the current weapon's ammo pool + name. DoomPickup auto-switches to a
newly-picked weapon.
DoomWeapon: fires the current weapon per its stats â hold-to-fire gated by the
weapon's cooldown (auto chaingun), melee weapons need no ammo, the launcher adds
splash damage around the hit. Stats moved out of the component into doom.weapons.
DoomCamera: derive the published look-facing from the camera's own forward (the
-Z basis) so the body's faceX/faceZ matches the actual aim (fixes the 180 flip).
---
fix(doom): lazy-require doom.weapons in components (world module index not ready at scene-apply)
DoomGame + DoomWeapon required doom.weapons at module-load time, which runs
during scene apply before the world module index is built, so the require failed
and the components dropped (no HUD, no weapon). Require it lazily at first use.
---
fix(doom): weapon viewmodel via resident runtime textures (UI image can't load world .texture assets)
The UI image widget shows '[loading]' forever for world .texture assets (they are
not GPU-resident). doom.weapon_textures uploads each viewmodel sprite as a
resident runtime texture (renderer.texture.create) and returns a name->guid map;
DoomGame's viewmodel references those guids. Removed the unused doomgun_*.texture
assets + build_weapons.module. Forces a one-time gun+HUD re-render once the
textures resolve (they load after the first frame).
---
fix(doom): playable combat â inline weapon roster + gun-texture decode (component require collapse), live-public HUD, horizontal auto-aim, corner HUD, respawn ammo
---
feat(doom): composite real muzzle-flash sprite (PISFA0/SHTFA0/CHGFA0/MISFA0) onto the weapon fire frame via picture offsets
---
fix(doom): 8-dir billboard handedness (player+monster), standalone body visibility, despawn-safe DoomPlayerBody
---
chore(doom): delete dead weapons/weapon_textures modules (inlined into components); add README+.metadata sidecars to sprite_decode/build_player/build_actorsb0784bee3ffeat(doom): working pickups (DoomPickup) + extended DoomGame stats (armor, ammo types, weapons, keys) + armor damage absorption
---
feat(doom): wall-aware ranged AI (stand-and-shoot standoff, no wall phasing) + dimmer corpses + baked pickups scene27089db3a4feat(doom): visible combat feedback - attack telegraphs, billboard fireballs+impacts, bullet puffs, monster pain/death frames, player damage flash
---
feat(doom): bake E1M1 with combat-feedback sprites + monster state args (attack/pain/death frames, fireballs, puffs)0d61d53b02refactor(doom): seal-_G compatible module pipeline + clean E1M1 bake
- Pipeline stages (textures/dynamics/level/things/music) are now modules
returning function(ctx); shared WAD/texLib/exclude flows through an explicit
ctx table, statically require()d by build_all -> no frozen-_G writes.
- build_all exposes build{map}/buildMusic{track}; DoomExit/DoomGame require it
instead of loadstring + _G.SCRIPT_ARGS.
- Rebuilt clean E1M1 (91 buckets/3628 tris, 118 things, 4 doors/1 lift/1 exit)
and baked to canonical on the rescued world.
---
chore(doom): remove require-system test fixture modules (reqtest/reqcaller/reqfolder)
---
feat(doom): @root:: module requires + clean E1M1 bake (publishable on require-fix binary)
---
refactor(doom): pipeline stages as .module assets (require-indexable for publish)3e2dfd600aFork of Doom WAD Build (e89aa92e) — full E1M1 scene + spawn379ddfe4bdFork of Doom WAD Build (e89aa92e) — full live content via world.forkLive