1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Surface every direct panic site as a warning so they cannot drift in
// unnoticed. `clippy::indexing_slicing` is enabled globally; the renderer
// and physics hot loops carry module-level `#![allow]` with documented
// rationale (see src/render/mod.rs). We deliberately do NOT enable
// `clippy::arithmetic_side_effects` — Doom's fixed-point math uses
// wrapping arithmetic pervasively, and every site would need an
// `#[allow]`, drowning out actionable cases.
//! Deterministic pure-Rust Doom simulator with semantic + depth perception
//! buffers alongside the classic 320x200 indexed framebuffer.
//!
//! The engine is `#![no_std]` (uses `alloc`), headless by default, and
//! generic over a `GameRules` implementation — the built-in
//! [`ClassicDoomRules`] reproduces classic single-player; user code can
//! substitute its own rules for bespoke multiplayer or AI training setups.
//!
//! # Layout
//!
//! - [`DoomEngine`] / [`ClassicEngine`] — top-level orchestrator. Owns the
//! [`World`], [`map::MapData`], [`texture::TextureData`], and a
//! [`render::Renderer`]. See [`DoomEngine::tick`] (single-player) or
//! [`DoomEngine::simulate`] + [`DoomEngine::render_for`] (multi-peer).
//! - [`World`] — entities, controllers, per-player state, sector state.
//! Deterministic, serializable.
//! - [`rules::GameRules`] — the transition function; one `tick` per
//! simulation step.
//! - [`render`] — BSP / wall / plane / sprite rasterizer, HUD overlay,
//! and the `SemanticClass` / depth buffers exposed to AI code.
//! - [`perception::PerceptionFrame`] — a snapshot of `(semantic, depth)`
//! ready for downsampling or feature extraction.
//! - [`combat`] / [`physics`] / [`specials`] — reusable gameplay helpers
//! used by `ClassicDoomRules`; available to custom rule impls.
//!
//! # Quick start
//!
//! ```no_run
//! use neurodoom::{ClassicEngine, PeerId, PlayerAction};
//!
//! # fn demo() -> Result<(), Box<dyn core::error::Error>> {
//! 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(); // one SemanticClass per pixel
//! let _depth = engine.depth_buffer(); // fixed-point distance per pixel
//! # let _ = rgba;
//! # Ok(())
//! # }
//! ```
extern crate alloc;
// --- Public modules: stable, documented API surface ---
// --- Implementation-detail modules: `#[doc(hidden)]` keeps them out of
// rustdoc output and signals "not part of the API contract", but
// they remain accessible so integration tests can reach into the
// static Doom tables (MOBJINFO, STATES, FINESINE) and low-level
// parsers when needed. Prefer the re-exports below in new code. ---
// --- Primary public API (re-exports for convenience) ---
pub use ClassicDoomRules;
pub use ;
pub use ;
pub use PerceptionFrame;
pub use ;
pub use ;
pub use ;
pub use ;