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
This commit is contained in:
@@ -73,6 +73,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Audio", "plugins\eng
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Audio.Tests", "tests\Engine.Audio.Tests\Engine.Audio.Tests.csproj", "{E610BD6A-A732-4863-8D19-555B75134E13}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{5D20AA90-6969-D8BD-9DCD-8634F4692FDA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PhysicsDemo", "PhysicsDemo", "{51874E45-60A1-E43B-395E-A3BE4050752F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GamePlugins", "GamePlugins", "{9760813E-A577-3C56-DE20-0218A108BABD}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "physics-demo-game", "physics-demo-game", "{83FF5113-4091-0AE3-A9AD-50B7BB917258}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhysicsDemoGame", "samples\PhysicsDemo\GamePlugins\physics-demo-game\PhysicsDemoGame.csproj", "{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhysicsDemoGame.Tests", "tests\PhysicsDemoGame.Tests\PhysicsDemoGame.Tests.csproj", "{0201686F-0E2A-400F-8166-CBD11B65D724}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -371,6 +383,30 @@ Global
|
||||
{E610BD6A-A732-4863-8D19-555B75134E13}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E610BD6A-A732-4863-8D19-555B75134E13}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E610BD6A-A732-4863-8D19-555B75134E13}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -408,5 +444,10 @@ Global
|
||||
{2C2E545D-6937-476D-AC62-F96CEA6403F9} = {2D4F0C3C-7532-0E50-D9FD-7209344A42BE}
|
||||
{C9AA2FF3-EB6C-4849-AD9F-9E99EFF30AEB} = {2D4F0C3C-7532-0E50-D9FD-7209344A42BE}
|
||||
{E610BD6A-A732-4863-8D19-555B75134E13} = {2D4F0C3C-7532-0E50-D9FD-7209344A42BE}
|
||||
{51874E45-60A1-E43B-395E-A3BE4050752F} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
|
||||
{9760813E-A577-3C56-DE20-0218A108BABD} = {51874E45-60A1-E43B-395E-A3BE4050752F}
|
||||
{83FF5113-4091-0AE3-A9AD-50B7BB917258} = {9760813E-A577-3C56-DE20-0218A108BABD}
|
||||
{1AFDA567-D86A-43C8-91B9-34CC13F48FEF} = {83FF5113-4091-0AE3-A9AD-50B7BB917258}
|
||||
{0201686F-0E2A-400F-8166-CBD11B65D724} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Reference in New Issue
Block a user