Files
lingua-engine/.gitignore
T
EmilandClaude Sonnet 5 2d0168104d M4: PhysicsDemo — the "one small game, end to end"
samples/PhysicsDemo ties physics, audio, input, and rendering together
through nothing but the kernel's own vocabulary — no plugin here
references another plugin's implementation, only Contracts. Press Space
to drop a box; engine.physics simulates it falling onto a static ground;
CubeRenderer (new — engine.render's QuadRenderer drew flat cards, no good
for a physics demo where a BoxCollider needs to actually look like a box)
draws it; physics-demo-game watches each spawned box's own Y velocity via
IPhysicsService and plays a bounce sound via IAudioService the moment a
real fall settles. A looping ambient track plays throughout via
AudioSource's own PlayOnAwake. project.json deliberately excludes
engine.editor — this is the shippable configuration M4's "done when"
actually asks for, not the dev one.

"Landed" isn't a Box3D contact event — the native shim never exposed one
(nothing but scalars crosses that boundary, see lingua_physics.c). Watching
velocity every frame is the honest, right-sized alternative for a demo
this size, not a shortcut around missing infrastructure.

Verified two ways. First, real Space-key input isn't simulable here (no
xdotool/ydotool under this Wayland session) — so PhysicsDemoGame.Tests
drives the actual PhysicsDemoGamePlugin.Configure/Tick through the real
Schedule with a controllable fake IEngineInput (and fake IPhysicsService/
IAudioService, since engine.physics/engine.audio's own correctness is
already covered elsewhere): spawn-on-press with edge detection, the
Rigidbody/BoxCollider/CubeRenderer combo the spawned box actually gets,
and — the case most likely to be subtly wrong — a box that never actually
falls doesn't false-positive as "landed," only one that fell past
FallingThreshold and then settled does, exactly once. All 5 passed
immediately. Second, a real windowed run: a box placed in scene.json above
the ground visibly falls and settles onto it on screen after a real
few-second wait — screenshotting by --screenshot-after-frames alone turned
out not to prove this (VSync is off, so frames race by far faster than
real physics time passes; enough elapsed frames isn't enough elapsed
seconds), an interactive run with a real sleep before the screenshot
command is what actually shows it.

Full suite: 92 tests. Remaining for M4: the Linux + Windows build pipeline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N1qPfzq8TDCUMFMV3UwV5N
2026-09-02 17:47:15 +03:00

42 lines
1.1 KiB
Plaintext

## .NET
bin/
obj/
*.user
*.suo
.vs/
## Rider / VS Code
.idea/
.vscode/
*.DotSettings.user
## OS
.DS_Store
Thumbs.db
## Build output
out/
artifacts/
## scripts/stage-plugins.sh's output — regenerated from plugins/, not source.
.stage/
## ImGui's own persisted window layout (position/size/open-state) — a
## per-machine editing session preference, not project source, same
## category as an IDE's own workspace state.
imgui.ini
## CMake build output and FetchContent's cloned dependencies (Box3D) for
## native/*-native/ — regenerated by cmake -S . -B build, not source; only
## the built liblingua_physics.so (checked in under plugins/engine.physics/
## Engine.Physics/native/) is what the engine actually ships.
native/*/build/
native/*/.fetchcontent-cache/
## scripts/run-physics-demo.sh copies the game-specific plugin's built
## output directly into its own folder (that's where its own pluginPaths
## entry in project.json points) — regenerated, not source. plugin.json,
## the .csproj, and the .cs files there stay tracked.
samples/*/GamePlugins/*/*.dll
samples/*/GamePlugins/*/*.pdb