neurodoom 0.6.7

Deterministic no_std Doom engine with semantic and depth perception buffers for AI
Documentation
# neurodoom

Deterministic pure-Rust Doom engine with per-pixel semantic and depth
perception buffers for AI and multi-agent work.

- `#![no_std]` core (uses `alloc`), headless by default, 320x200 output.
- Classic single-player reproduction in `ClassicDoomRules`.
- Generic over any `GameRules` implementation for custom multiplayer or
  training setups.

### History

Started as a thin wrapper around [PureDOOM](https://github.com/Daivuk/PureDOOM)
(a single-header, dependency-free C port of Doom). The plan was to bind
the C engine and hang perception buffers off it. In practice, almost
every subsystem — WAD parser, map loader, BSP + column rasterizer,
visplanes, sprite system, physics, state machine, sector specials, game
loop — got rewritten in pure Rust so the engine could be `#![no_std]`,
panic-averse, and deterministic.

## At a glance

```rust
use neurodoom::{ClassicEngine, PeerId, PlayerAction};

let wad = std::fs::read("doom1.wad")?;
let mut engine = ClassicEngine::new(&wad, "E1M1")?;

engine.tick_single(PeerId(0), PlayerAction::default());

let rgba     = engine.framebuffer();       // 320 * 200 * 4 bytes
let semantic = engine.semantic_buffer();   // 1 SemanticClass per pixel
let depth    = engine.depth_buffer();      // fixed-point distance per pixel
```

## Examples

All three examples need a Doom WAD. Point `DOOM_WAD` at one, or place
`doom1.wad` in the project root.

```sh
# Playable single-player with level progression across the episode.
cargo run --release --example classic

# 24 reactive bots in a 6x4 grid, fighting in E1M1 with no monsters.
# Each cell shows the bot's POV with HUD + animated weapon. Dead cells
# switch to depth view.
cargo run --release --example ai_multiplayer

# Play back the recorded DEMO1 / DEMO2 / DEMO3 lumps from the WAD —
# no user input, just feeds the stored tic-commands to the engine.
cargo run --release --example demo
```

Controls are documented in each example's file header.

## Multi-peer rendering

`DoomEngine::tick(...)` is the single-player convenience — it runs
simulation for one tick *and* renders `PeerId(0)`'s view. For multi-peer
work (several AI bots sharing one world, each needing its own view),
split the two:

```rust
engine.simulate(&actions, &[]);      // advance sim, no render
for peer in peers {
    engine.render_for(peer);          // re-render from that peer's eye
    // read engine.{framebuffer,semantic_buffer,depth_buffer}()
}
```

See `examples/ai_multiplayer.rs` for the full pattern (including
staggered rendering to amortize the per-peer cost).

## Further reading

Module-level docs (`cargo doc --open`) cover each subsystem. The crate
is panic-averse by design: direct panic sites are surfaced as clippy
warnings and `Cargo.toml` sets `panic = "abort"` on both `dev` and
`release`. See `src/render/mod.rs` for the policy details.

## License

BSD-3-Clause. See [LICENSE](LICENSE).