Build & Runtime
- config.h.in — compile-time feature flags template; configured by CMake into
config.h - src/neolith.conf — runtime configuration template
- examples/m3_mudlib/ — test mudlib
- examples/m3_testbots/ — integration test scenarios simulating user interactions
- examples/apps/ — example applications using Neolith as a LPC shell
Core Source (frequently modified)
- src/backend.c — main event loop; src/interpret.c — LPC VM; src/simulate.c — object management
- src/comm.c — network I/O; src/apply.cpp — LPC apply dispatch
- lib/lpc/ — LPC compiler pipeline and runtime types
- lib/lpc/func_spec.c.in — efun definitions source template; edited directly, configured by CMake into
func_spec.cthen preprocessed intofunc_spec.i - lib/lpc/grammar.y — LPC parser grammar
- lib/port/ — platform abstraction layer (file I/O, sockets, etc.)
- lib/misc/ — utilities (string, time, host filepath, etc.)
Reference Docs (ground truth for LPC behavior)
- docs/efuns/ — efun signatures and behavior
- docs/applies/ — driver-to-LPC apply callback reference
Planning & History (active work context)
- docs/plan/ — active design and implementation plans (short-term, may be deleted or archived)
- docs/history/ — recently completed plans and experimental features.
- docs/ChangeLog.md — release-level change summaries
- Layering model:
- Driver layer: the foundation libraries (compiled with
NO_OPCODESguard) and subsystems insrc. - LPC layer: built on top of Driver layer, using specifications defined in
options.h(LPC predefines) andfunc_spec.c(LPC operators and efuns) - Efuns layer: built on top of Driver and LPC.
- stem: connects all layers and subsystems, maintains
mud_state(), and provides the runtime environment consumed by LPC and efuns. Unit-testing programs also setup/teardown their minimal runtime stem in fixtures.
- Driver layer: the foundation libraries (compiled with
- Object/apply safety:
- After applies, re-check
ob->flags & O_DESTRUCTEDbecause targets may self-destruct. - Keep apply paths stack-balanced on both success and failure.
- After applies, re-check
- Generated-file policy:
config.his generated at CMake configure step which is available for all source files.options.h,lpc/grammar.handefuns_*.hare generated when building LPC layer (lib/lpc). Never include these headers ifNO_OPCODESis defined.func_spec.cis NOT a C source file, but a LPC efun specification generated byedit_source.- Do not edit generated artifacts directly; edit the source templates and regenerate.
- Run from repository root (where
CMakePresets.jsonlives). - List presets:
cmake --list-presets
- Configure + build pattern:
cmake --preset <configure-preset> cmake --build --preset <build-preset>
- Preset prefixes:
dev-: incremental Debug buildsci-: clean RelWithDebInfo rebuilds
- Common clean build commands:
cmake --build --preset ci-linux cmake --build --preset ci-vs16-x64 cmake --build --preset ci-clang-x64 cmake --build --preset ci-macos
- Basic run:
/path/to/neolith -f /path/to/neolith.conf -p
- Use examples/m3.conf as a quick minimal runnable smoke-testing config.
- Mudlib directory path is resolved as related path to
m3.conf.
- Mudlib directory path is resolved as related path to
-penables pedantic mode (memory leak checks); see docs/manual/dev.md.-tenables trace logging; see docs/manual/trace.md.
- Use
-cfor stdin/stdout-driven testing (no telnet client required). - Reference: docs/manual/console-mode.md.
- Example:
/path/to/neolith -f /path/to/neolith.conf -c < /path/to/console_commands.txt > /path/to/console_output.log- Unit tests use GoogleTest in tests/; test files follow
test_*.cppand useTEST()/TEST_F(). - Run
ctestfrom repository root.
ctest --preset ut-linux
ctest --preset ut-vs16-x64
ctest --preset ut-clang-x64- For targeted runs using
--test-dir, include--build-and-testafter code changes. - Verify before running:
--test-dirmatches the intended build output/platform-Rmatches the intended configuration (for example,RelWithDebInfo)
Example:
ctest --test-dir out/build/clang-x64 -R RelWithDebInfo --build-and-test- Use
examples/m3_testbotsfor integration testing involving simulation of user interactions. - Update
examples/m3_testbots/src/smoke_test.pywith test scenarios as needed. - Run:
hatch run smoke_test- Use inline Doxygen function comments:
/** * @brief Brief description. * @param arg Description of parameter. * @returns What the function returns. */
- Add block comments for complex logic or important invariants, especially in critical paths like memory management, applies, and async handling.
- Write docs in Markdown under docs/ (GitHub Flavored Markdown). Follow file-organization.md for naming and structure.
- Name documentation files with lowercase letters and dashes (
-) as separators (no underscores or camelCase), and prefix filenames with the library, feature, or subsystem (for example,async-dns-integration.md). - Updating existing docs can proceed silently. Creation of new documents requires user approval.
- Start feature work with a plan document in docs/plan/ to track design decisions, implementation status, and handoff instructions, and keep it updated as work progresses.
- Search docs/history for recently completed plans when debugging regressions; they may contain bugs or experimental changes.
- Keep permanent-state docs in docs/manual/ and docs/internals/ accurate as code evolves:
- Manuals are for operators and mudlib developers (coding in LPC); internals are for driver developers (coding in C/C++).
- Avoid implementation details; focus on behavior, contracts, and design decisions.
- Permanent-state docs can only link to other permanent-state docs (no links to plan docs or source code).
- When adding content to audience-specific docs (manuals vs internals), ensure the content matches the intended audience.
- Use docs/manual/internals.md as a cross-reference for linking between manuals and internals when needed.
- Keep docs concise and structured for retrieval (clear headings, tables, and short bullet lists).
- Don't mix driver-facing and mudlib-facing details in the same doc.
- Document decisions and interfaces, not full implementations.
- Keep implementation status focused on deltas.
- When updating docs, remove outdated or redundant text and keep plan/current-state docs aligned.
- Identfy which layer the code belongs to before making changes.
- Keep LPC and efun layer code platform-agnostic.
- Keep driver layer libraries and stem subsystems interface minimal and well-documented.
- Prioritize impact-first changes: fix code and tests first, then update only docs directly affected by the change.
- Run the smallest relevant test scope for touched behavior (targeted test files first; expand scope only when risk is broader).
- Apply doc updates conditionally:
- Update docs/efuns/ only when efun behavior/signature is added or changed.
- Update docs/manual/ or docs/internals/ only when architecture, contracts, or operational behavior changes.
- Update docs/ChangeLog.md for release-relevant user-visible or developer-facing changes.
- Keep doc edits concise and source-linked; avoid restating implementation that is already clear in code.
- Use docs/CONTRIBUTING.md as the policy source of truth when guidance conflicts.