Checkpoint 1: implement native subsystems and begin the gameplay manual

This commit is contained in:
Emil
2026-09-18 03:01:30 +03:00
parent decf49084d
commit 903c97444b
73 changed files with 3932 additions and 6 deletions
+20
View File
@@ -0,0 +1,20 @@
# Keep the manual executable
Document user tasks and actual APIs in English. Explain what each argument means,
which callback it belongs in, and what happens when an object or resource is missing.
Prioritize complete small gameplay examples over isolated declarations. Link examples
to their source files and include them in build or integration checks. When an API
changes, update its examples in the same change.
Mark planned capabilities explicitly. Do not describe a prototype image as a running
editor, a Linux test as Windows validation, or a planned feature as implemented.
Build with strict documentation validation before publishing:
```sh
.cache/docs-venv/bin/python -m mkdocs build --strict
```
Generated output goes to `build/manual`; source Markdown and configuration are tracked
in Git. Research and architecture documents remain separate from this user manual.
+65
View File
@@ -0,0 +1,65 @@
# Build from source
!!! warning "Foundation checkpoint"
These instructions initially cover the build foundation. The integrated editor,
sample projects, and packaging steps are being added and verified during MVP implementation.
## Linux prerequisites
The selected toolchain is C++20, CMake 3.25 or later, Ninja, and Clang.
Graphical builds need Vulkan 1.3 headers/loader and a compatible driver.
SDL3 is built from a pinned source archive.
On Ubuntu, install the native build tools before configuring:
```sh
sudo apt install clang ninja-build cmake python3 python3-venv pkg-config \
libvulkan-dev vulkan-validationlayers libx11-dev libxext-dev libxrandr-dev \
libxcursor-dev libxi-dev libxfixes-dev libxkbcommon-dev libwayland-dev \
libfreetype-dev libharfbuzz-dev xvfb
```
`xvfb` is used for automated window tests. A normal desktop session does not need it.
## Configure, build, test
```sh
python3 tools/fetch_slang.py
cmake --preset linux-debug
cmake --build --preset linux-debug --parallel
ctest --preset linux-debug
```
For an optimized build use `linux-release`. The `linux-sanitize` preset enables
AddressSanitizer and UndefinedBehaviorSanitizer for tests without the graphics backend.
## Dependencies and offline builds
Dependency source URLs, commits, and archive SHA-256 values are stored in
`dependencies.lock.json`. CMake downloads them on the first configuration.
To prefetch them for later offline use:
```sh
python3 tools/fetch_dependencies.py
python3 tools/fetch_dependencies.py --verify-only
```
Cached archives live in `.cache/downloads` and are not committed. Local compilers,
system development libraries, and the Slang compiler must also be available before
disconnecting. Prefetching source archives alone is not a complete offline SDK.
## Windows prerequisites
Use an x64 Visual Studio Developer shell with the Windows SDK, MSVC runtime libraries,
LLVM `clang-cl`, Ninja, CMake, and the Vulkan SDK available. Then use the
`windows-debug` or `windows-release` presets.
```powershell
py tools/fetch_slang.py
cmake --preset windows-debug
cmake --build --preset windows-debug --parallel
ctest --preset windows-debug
```
Windows acceptance is tracked separately from Linux; a successful Linux build does
not verify a Windows build.
+44
View File
@@ -0,0 +1,44 @@
# Faset Engine Manual
Faset is a C++ engine for desktop 2D and 3D games on Linux and Windows.
This manual focuses on writing gameplay: small working examples, the functions they use,
and how those functions interact with scenes, physics, and the editor.
!!! warning "Development status"
MVP implementation is in progress. A planned feature is not a working feature.
Individual guides state their prerequisites and validation status. The current
foundation can be built and tested; a complete editor and game export are not yet available.
Start with [how C++ gameplay works](scripting/index.md), then read
[frame and physics updates](scripting/lifecycle.md). See
[Build from source](getting-started/build.md) for the toolchain and build commands.
The engine, editor, built-in diagnostics, and API identifiers use English.
Your game content and project text can use other languages.
## Learning path
The manual grows alongside tested engine capabilities, in this order:
1. Build and run an example game.
2. Create a C++ behavior and expose a property in the Inspector.
3. Handle input and move a character.
4. Use physics, collision events, and deferred object creation.
5. Work with scene templates, assets, and references.
6. Import from Blender and export a standalone game.
Lua is planned after the C++ foundation. It is not a current scripting option.
## Preview this manual
From the repository root, create a Python virtual environment and install the pinned documentation tools:
```sh
python3 -m venv .cache/docs-venv
.cache/docs-venv/bin/python -m pip install -r docs/requirements.txt
.cache/docs-venv/bin/python -m mkdocs serve
```
On Windows, use `py -m venv .cache/docs-venv` and
`.cache/docs-venv/Scripts/python.exe` in place of the Unix interpreter path.
The manual also remains readable directly as Markdown in the repository.
+41
View File
@@ -0,0 +1,41 @@
# C++ gameplay
In the first version of Faset, a "script" is C++ gameplay code compiled into your game.
It is not an interpreted text file. The gameplay library is statically linked into
a separate Player executable.
The intended iteration cycle is:
1. Stop Play.
2. Edit your C++ behavior or system.
3. Build the changed code and export its property schema.
4. Start a new Player session.
The Editor reads a schema generated by a separate SchemaExporter. It does not load
your gameplay library into its own process. A gameplay crash therefore does not
automatically crash the Editor. Editor native extensions have a different lifecycle
and run inside the Editor process.
!!! note "API examples are added with implementation"
This page describes the accepted execution model. Exact function signatures and
complete examples will be documented alongside compiling runtime examples, rather
than presenting proposed APIs as available functions.
## Behaviors and systems
A behavior gives an individual object lifecycle callbacks. A system operates on a
set of objects with matching components. Both use the same runtime state; the visual
scene and Inspector are the authoring view of that state.
Persistent scene IDs and runtime handles are different. A scene ID survives saving
and reopening. A runtime handle belongs to a particular world/session and can become
invalid after an object is removed. Do not store raw component pointers across
structural changes or treat a runtime handle as a save-file ID.
## Physics ownership
Physics owns the position of a dynamic rigid body. Move it with the supported physics
commands instead of writing its presentation transform. A camera or other visual-only
object can follow the interpolated result without modifying the simulation.
Continue with [Frame and physics updates](lifecycle.md).
+47
View File
@@ -0,0 +1,47 @@
# Frame and physics updates
!!! note "Execution contract"
This page describes the accepted runtime contract. The runnable callback examples
and test results are added as the runtime implementation becomes available.
## Choose the right callback
- `OnStart`: initialize a behavior once its object and components exist.
- `FixedUpdate`: update simulation logic before a physics step.
- `Update`: run frame-based gameplay once per rendered frame.
- `LateUpdate`: update cameras and dependent visual objects after presentation interpolation.
- `OnDestroy`: release subscriptions and other behavior-owned state before its handle is invalidated.
The default simulation interval is 1/60 second. A rendered frame may contain zero,
one, or several fixed ticks. Frame rate and physics rate are not the same quantity.
## Fixed tick order
1. Apply structural commands queued by earlier work.
2. Deliver tick input and call `FixedUpdate`.
3. Apply physics commands and step the 2D and 3D worlds.
4. Read back transforms and queue collision events.
5. Run reactions after physics.
Object creation/removal and component addition/removal are deferred to the beginning
of the next fixed tick. This prevents a callback from invalidating the collection
currently being processed. New objects follow the same initialization rules as objects
loaded from a scene.
After the fixed ticks, the frame runs `Update`, prepares interpolated presentation
transforms, calls `LateUpdate`, and produces the render snapshot.
## Avoid frame-rate-dependent movement
A speed is a distance per second. Multiply it by the callback's elapsed seconds when
calculating a displacement. Do not multiply a velocity by elapsed time before assigning
it to a physics velocity API; the physics step performs that integration.
## Overload and pause
The initial catch-up limit is four fixed ticks per frame. Excess whole intervals are
dropped with a diagnostic rather than making the physics step arbitrarily large.
This is a local-game policy, not a guarantee of deterministic network simulation.
Pausing clears accumulated time. Single-step advances exactly one simulation tick.
Interpolation history is reset for a new session, spawn, or teleport.