Commit Graph
160 Commits
Author SHA1 Message Date
西风逍遥游 c65daede2e feat(animation): script-playable skeletal animation via AnimSkin writeback
AnimSkin can now write CPU-skinning results back to the render mesh so skeletal animation actually plays from scripts:
- capture bind normals at fromModel and skin them per pose (updateSkinnedNormals / getSkinnedNormals, cofactor inverse-transpose + normalize)
- packed getSkinnedPositions() array getter, matching AnimLattice's script pattern
- one-call applyToMesh(gfx, mesh, pose): skin positions+normals then in-place gpu.updateMeshVertices
- Renderable3D.getMesh() script binding so createRenderable meshes are reachable
- Mesh::gpuVertexCount so getVertexCount() is correct for non-morph meshes (both backends)
- tests: packed positions == skinPositionsTo, normals follow pose and stay unit length, applyToMesh render test with in-place updates
- docs: animation/graphics user guides + design spec
2026-08-23 14:24:11 +08:00
西风逍遥游 ffff64588c feat(decal): P1 full PBR channel blending with instanced decal layer
Completes the PBR surface-parameter layer: mesh3d.frag now blends normal / roughness / metallic / emissive (in addition to albedo) from the DecalLayer before lighting; decals are drawn as grouped instanced draws (112B per-instance SSBO, alpha-over non-premultiplied layer, per-decal uvRect/atlas + channel strengths + blend mode API); DecalManager gains frustum + distance culling and setUvRect/setTextures/setBlend; new headless readback readDecalLayerToImageData validates the pass without a swapchain. Fixes two Vulkan validation violations found by the layer (missing vertex/index binds on instanced draws, blend attachmentCount).
2026-08-23 00:52:26 +08:00
西风逍遥游 5c1ba73994 docs(decal): add decal system design spec 2026-08-22 23:28:58 +08:00
西风逍遥游 a6e9db4086 test(docs): expand map/rpg/building coverage matrix + accessor round-trips
Add §17b–§17d API detail tables to docs/dev/测试覆盖.md for map, rpg and
building (all rows now '已展开'), backed by a fresh audit of the existing
70+ map cases, 28 rpg cases and 15 building cases.

Fill the audit gaps with two compact accessor tests:
- map.path.accessorRoundTrips: diagonal, blockEmpty, cellCost getter,
  unblockGid/clearBlockedGids, invalidateCache, setBlocked/isWalkable.
- map.fov.accessorRoundTrips: cornerPeek, eyeOffset, cliffBlock,
  verticalRange, perceptionRadiusScale, revealerPosition3/perception,
  revealer count and unknown-id behavior.

Local win32-debug: map/map_fov/map_path bundles pass.
2026-08-22 17:13:22 +08:00
西风逍遥游 5624388f1c test(event): cover Event::wait with a pre-queued message
The blocking-wake path was already covered by event.workerPushWakesWait;
add the queued-message fast path (wait returns immediately). Update
docs/dev/测试覆盖.md §9: wait marked 已覆盖.
2026-08-22 14:05:43 +08:00
西风逍遥游 d995497842 Merge remote-tracking branch 'origin/dev' into codex/headless-tests-ci 2026-08-22 12:57:15 +08:00
西风逍遥游 ff77852fcd Merge pull request #176 from EVEngine/codex/thread-test-gaps
test(thread): close last API gaps + fix JobSystem use-after-free found by ASan
2026-08-22 12:56:46 +08:00
西风逍遥游 3e9d2814fa Merge pull request #171 from EVEngine/codex/cmdline-fixes
feat(cmdline): eve get/build 基于官方 release SDK,release CI 增加消费侧全链路验证
2026-08-22 12:38:40 +08:00
西风逍遥游 c47e061181 test(thread): cover Channel::demand and Thread::postMain
Fill the last thread-module API gaps: blocking demand() and cross-thread
postMain() into the Event queue (same-thread, empty-name throw, worker
thread). 46/46 thread bundle cases pass locally on win32-debug. Update
docs/dev/测试覆盖.md: thread row to '已展开' with a full API detail table.
2026-08-22 12:22:31 +08:00
西风逍遥游 2d079b39ef ci(linux): verify headless GPU tests run without Xvfb
Add a dedicated Linux step that runs the six headless GPU bundles
(graphics_font, TextureSampler, gpgpu, tensor, virtualgeometry_gpu,
graphics_headless) with no display server — proving the headless-vs-window
policy in docs/dev/测试覆盖.md §0. The regular xvfb run keeps covering the
full suite including windowed demo tests.
2026-08-22 11:54:15 +08:00
西风逍遥游 a7ec3938b7 test: adopt headless graphics for functional GPU tests, keep windowed demos
Introduce the headless-vs-window test policy (docs/dev/测试覆盖.md §0):
functional GPU tests run via Graphics::initHeadless + offscreen canvas
readback; visual/demo tests (ClassicScenes, RenderImageAudit, animation,
voxel, particles, UI, swapchain-readback cases) keep real windows.

Mechanics:
- Graphics::initHeadless is now re-entrant: the process-wide singleton
  updates the logical viewport on repeat calls instead of throwing, so
  multiple cases in a bundle can share one headless device.
- test/Fixtures.h adds openHeadlessGfx() and a useHeadless mode for
  GfxFixture; EVENGINE_TEST_VIEW_W/H overrides apply to both paths.

Migrated (window-free, no behavior change to assertions):
- test/graphics_font.cpp: atlas + print-to-canvas pixel readback; the
  interactive debug-preview loop is guarded by isHeadless().
- test/TextureSampler.cpp: sampler parameter round-trips.

graphics_headless.cpp now asserts the re-entrant resize semantics.
2026-08-22 11:12:43 +08:00
西风逍遥游 80aca00f67 Merge remote-tracking branch 'origin/dev' into codex/cmdline-fixes
# Conflicts:
#	src/engine/cmdline/Doc.cpp
2026-08-22 10:45:21 +08:00
西风逍遥游 55184c7e4a docs(release): document the consumer-side validation gates in the release flow 2026-08-22 10:38:12 +08:00
西风逍遥游 7437224c90 api(graphics): align C++/script names, validate sampler strings, document error contracts
- Add RGBA-float drawSolidRect/drawTexturedRect overloads so the C++ names
  match the script-facing API (script already bound those names).
- Add string-based setTextureSampler(Texture*, filter, mipmap, aniso, lodBias)
  overload with strict magic-string validation (unknown filter/mipmap now
  throws instead of silently falling back to linear); keep
  setTextureSamplerParams as a deprecated alias. Script binding now targets
  the overload with an explicit cast.
- Document error contracts: DataModule encode/decode (new[] ownership +
  throws), Filesystem setSource/mount/unmount (false on recoverable failure,
  no throw), ModelData getMesh vs numeric getters (nullptr vs throw), plus a
  two-state error-semantics section in API-CONVENTIONS.md.
- Tests: TextureSampler string validation (valid + deprecated alias + typo
  throws), headless test now exercises the RGBA-float overloads.
2026-08-22 02:30:12 +08:00
西风逍遥游 9b5d6f654d feat(common): expose Runtime reflection API to scripts as eve.reflect
Runtime::initialize() now adds an eve.reflect sub-table binding the reflection layer (classes/classInfo/scan/scripts, createInstance, inspect/read/write/readObject, array*/table* editing) so Squirrel tools and editors can introspect and edit script classes and instances with the same semantics as the C++ Runtime API.

Scalar reads/writes keep the slot's own type; container/instance slots are read as live script objects; mutators return false instead of throwing on missing or method members. Adds test/ReflectScript.cpp covering the full surface.
2026-08-21 23:26:47 +08:00
西风逍遥游 4fc5277ff1 Merge pull request #161 from EVEngine/codex/gpu-driven-rendering
GPU-driven rendering: bindless + indirect draw + GPU cull + visibility buffer/resolve + VirtualGeometry integration
2026-08-21 21:40:20 +08:00
西风逍遥游 453d33387f Merge remote-tracking branch 'origin/dev' into codex/gpu-driven-rendering
# Conflicts:
#	AGENTS.md
#	external/VKBuilder
#	src/modules/graphics/Graphics.h
#	src/modules/graphics/RenderControl.cpp
#	src/modules/graphics/RenderSystem3D.cpp
#	src/modules/graphics/vulkan/Graphics.cpp
#	src/modules/graphics/vulkan/Graphics.h
2026-08-21 20:45:42 +08:00
西风逍遥游 4c6f27d0f5 Merge pull request #158 from EVEngine/codex/runtime-inspector-mvvm
feat(ui): reflection-driven property inspector (MVVM DevTools)
2026-08-21 20:19:48 +08:00
西风逍遥游 11c6444853 Merge pull request #160 from EVEngine/codex/state-hot-reload
feat: state hot reload for scripts and state machines
2026-08-21 20:19:38 +08:00
西风逍遥游 54dea0d561 feat: state hot reload for scripts and state machines
Adds a capture -> reload -> restore pipeline so code/asset changes can be hot-applied without resetting running state:

- common: StateValue (JSON-compatible state tree) + IStateProvider capability interface.
- devtools: Snapshot v2 (script roots + native provider section, v1 compatible, strict rejection of non-data roots), ReloadSession (begin/commit/abort), eve.dev script API (stateRoots / beginStateReload / commitStateReload / abortStateReload).
- load.nut: three-phase soft reload (capture -> dofile -> restore) with migrate_instance / remap_instances helpers and eve_before_reload / eve_after_reload hooks.
- dialogue + AnimStateMachine: IStateProvider for phase/vars/rng and params/current state.
- animation: AnimClip::adopt + AnimClipRegistry + 'animclip' IAssetReloader so .eva content reloads keep clip identity.
- rpg + card: IStateProvider for casting/cooldowns and card phases.
- Tests: stateValue, snapshot v2/strict, reload script protocol, dialogue, animation state machine + reload, rpg/card state roundtrips.
2026-08-21 19:46:25 +08:00
西风逍遥游 4f527476fa Merge pull request #157 from EVEngine/codex/docs-user-docs-and-doxygen-sidebar
docs: rework user docs and rebuild the Doxygen sidebar
2026-08-21 18:47:15 +08:00
西风逍遥游 96dae32c38 feat(ui): DevTools panel suite - database grid, nested editing, scene tree, editor shell 2026-08-21 18:15:59 +08:00
西风逍遥游 06061d9d99 feat(ui): reflection-driven property inspector (MVVM DevTools) 2026-08-21 17:34:26 +08:00
西风逍遥游 d86f9eceec docs: rework user docs and rebuild the Doxygen sidebar
- Readme (zh/en): make "download prebuilt SDK, no build" the primary path for
  game developers; move build-from-source content under an engine-developers
  section.
- Rewrite docs/usr/README.md: download/run, capabilities, debugging,
  packaging, and a "things to keep in mind" section.
- Unify wording in MODULES/TRIMMING/dev docs and the SDK README.
- Replace the JS treeview with a plain-HTML static sidebar (home, user guide,
  module handbook grouped into 5 categories, API indexes) so docs navigate
  without JavaScript.
- Add a Doxygen landing page and page-hierarchy wrappers generated by
  docs/CMakeLists.txt; tune Doxyfile for the static layout.
2026-08-21 17:05:51 +08:00
西风逍遥游 5065d0a91b merge: integrate origin/dev (PR #134 JobSystem, #151-#154) into codex/framegraph-mt-render
dev is the repo's feature branch (main is release-gated to promote/docs PRs).
Resolved JobSystemThreadPool.cpp to our completeJob ordering (decrement
outstanding counters after fireCompletion/releaseDependents) — dev's merged
PR #134 version kept the pre-fix order that can reset the frame arena under a
still-running worker.
2026-08-21 12:57:16 +08:00
西风逍遥游 95b869cbbd merge: integrate origin/main (TU split, #129 perf, module decoupling) into codex/framegraph-mt-render
Port the deferred FrameGraph integration onto main's split Vulkan backend:
- Graphics3D.cpp owns buildDeferredFrameGraphs / recordDeferredFrameGraph /
  recordShadowCascadePass / recordGBufferPassDraws (parallel JobSystem
  recording, one command pool per frame-slot per pass).
- begin3DFrame / beginSwapchainRenderPass / flushToSwapchain 2D-only path
  call recordDeferredFrameGraph() instead of the serial pending passes.
- Drop the superseded serial recordPendingShadowPasses/GBufferPass and the
  duplicate culling implementation (main's RenderSystem3D already carries
  the per-camera / per-cascade frustum culling).
- VKBuilder submodule -> 51514d9 (master; our spec-safe pool/lifecycle PR
  was merged upstream as sunxfancy/VKBuilder#2).
2026-08-21 12:48:49 +08:00
西风逍遥游 0ca17b9a57 feat(render): enforce spec-safe parallel recording via per-pass command pools and RecordCycle lifecycle 2026-08-21 09:35:25 +08:00
西风逍遥游 d786e18fa9 feat(animation): add 3D lattice scale-deformer (AnimLattice)
CPU trilinear lattice deformation for procedural 3D scale/squash-stretch
animation: per-control-point scale + offset, model/array binding, deformed
position/normal cache, script API (anim.newLattice + AnimLattice class) and
gfx.newMeshFromArrays / gfx.updateMeshVertices script wrappers so scripts can
upload deformed meshes per frame. Includes unit tests and the
examples/lattice-deform demo.
2026-08-21 01:08:35 +08:00
西风逍遥游 d4936d12dc docs(framegraph): record parallel-recording verdict (driver-level AMDVLK crash)
TSan (WSL) proves the JobSystem + executor + framegraph planning are
data-race-free; on Windows the parallel record path AVs inside
amdvlk64.dll from vkb::FrameGraph::record's recordOne on two workers, and
still crashes after device->waitIdle() — an AMDVLK concurrent-recording
defect, not a pending-CB reuse issue. Engine keeps serial recording; the
executor stays available for drivers/CI builds that support it.
2026-08-21 00:35:47 +08:00
西风逍遥游 b684bf713d feat(render): move the 3 CSM shadow cascades into the deferred FrameGraph
Stage D (shadow part): each in-flight slot's FrameGraph now owns both the
shadow and G-buffer passes as declarative, dependency-free passes in one
layer. The CSM array is imported per cascade via its layer view with
arrayLayers=3 so barriers cover the whole array; every cascade ends in
DepthStencilReadOnlyOptimal for the engine-side forward pass to sample.

- recordPendingShadowPasses / recordPendingGBufferPass are gone, merged
  into recordDeferredFrameGraph(): graph record + submit before the
  swapchain pass, with a once-per-slot-per-frame guard so repeated
  render3D() calls in one script frame never re-record the same command
  buffers (resetting in-flight CBs hung the driver).
- buildDeferredFrameGraphs() rebuilds one graph per slot from the current
  shadow array + G-buffer targets; shadows can be enabled without a
  G-buffer pass and vice versa (graphs are built on demand).
- JobSystem fix (PR #134 scheduler bug): completeJob now decrements
  outstanding/outstandingFrame only after fireCompletion +
  releaseDependents have finished using the job. Previously a waiter
  (beginFrame/endFrame) could observe outstandingFrame == 0 and reset the
  per-frame arena while a worker still touched the job (use-after-free:
  lost forked job -> hang, or crash). Two stress tests
  (render_graph.jobSystemGroupStress, render_graph.jobSystemEngineFramePattern)
  cover the engine's exact beginFrame/parallel_for/task-group frame
  pattern.
- Recording stays serial (graph->record()) for now: the JobSystem
  help-execution path still has a residual timing-sensitive race that can
  leave a worker stuck in a pass callback. The parallel executor
  (jobSystemPassExecutor) is ready and CPU-tested; enable it once that
  race is root-caused upstream (documented in FrameGraphJobs.h).

Verified locally (win32-debug, full clean rebuild): render_graph.*,
thread.*, Shadow3D.*, RenderSystem3D.*, Lighting3D.*, Mesh.* and
AO/AA/Outline/GI — 77 cases pass.
2026-08-20 23:11:38 +08:00
西风逍遥游 674643c2da feat(graphics): GPU-driven phase 0 - bindless set, GPU tables, per-frame arena
- GpuDrivenCaps: probe + enable Vulkan 1.2 core features (drawIndirectCount,
  descriptor indexing, non-uniform indexing, update-after-bind) at device
  creation; the toolchain's Vulkan headers omit the core drawIndirect bit so
  it is assumed supported and left untouched.
- Bindless Set1: sampler2D array (4096) + samplerCube array (64) + SSBO table
  array (64) with PARTIALLY_BOUND | UPDATE_AFTER_BIND; textures register on
  creation, placeholder-filled with the 1x1 white texture/cubemap.
- GPU tables: GpuMeshRecord (bounds + index/vertex ranges) filled at mesh
  upload and GpuMaterialRecord built from Material params, uploaded to
  host-visible SSBOs with fixed capacity.
- FrameArena: per-frame-slot host-visible ring allocator, reset each
  begin3DFrame; unused until phase 1 (indirect draw).
- Tests: GpuDriven.capsAvailable / bindlessTextureRegistration /
  meshTableRegistration (GPU runtime verification pending driver recovery).

Rendering is unchanged: nothing consumes the new infrastructure yet.
2026-08-20 21:17:17 +08:00
西风逍遥游 ab1c398b6f feat(render): record the G-buffer pass through vkb::FrameGraph
Stage B of the FrameGraph migration: the G-buffer fill is now a
declarative FrameGraph pass recorded with the JobSystem executor and
submitted before the swapchain pass, replacing the hand-rolled
render-pass + manual begin/end layout tracking in recordPendingGBufferPass.

Design:
- One vkb::FrameGraph per in-flight present slot (framesInFlight=1),
  importing the engine-owned ColorTarget images via importTexture. The
  engine keeps image ownership, so renderEntityIdMask /
  readGBufferToImageData and the AO/outline/AA descriptor wrappers work
  unchanged.
- Each graph declares addPass("gbuffer") with 3 color attachments + 1
  depth attachment (clear ops matching the old path). compilePlan derives
  the dependency/barrier/layout plan; attachment->sampled transitions
  fold into render-pass initial/final layouts (ShaderReadOnly /
  DepthStencilReadOnly after the pass).
- recordPendingGBufferPass now runs recordFrameGraphWithJobSystem() +
  graph->submit() inside a JobSystem frame bracket; the graph's command
  buffer is recorded (serial for one pass today; parallel once shadow
  cascades join in Stage D) and submitted on the graphics queue before
  the swapchain pass. The graph's RP is render-pass compatible with the
  engine's gbuffer pipelines (same formats/samples/subpass layouts).
- Command-buffer safety without a swapchain-driven FrameGraph: each
  graph's CB is only reused two frames later, by which time the present
  slot fence (waited in Present::begin) guarantees the previous graph
  submit completed (same queue, submitted before the present CB).
  An upstream VKBuilder patch (swapchain-less frame advancement + fences)
  would let this collapse back to one graph.

Verified locally (win32-debug, full clean rebuild): render_graph.*,
thread.*, Shadow3D.*, RenderSystem3D.*, Lighting3D.*, Mesh.* and
AO/AA/Outline/GI (75 cases) all pass. Also fixed the test build's
stale-obj layout mismatch that made the new member corrupt ownedTextures
until the graphics module was rebuilt from scratch.
2026-08-20 20:46:16 +08:00
西风逍遥游 5c8046e85f feat(render): FrameGraph parallel-recording foundation on top of JobSystem
PR #134's secondary-command-buffer recording violated the Vulkan state
machine (secondaries began their own render pass instances without
pInheritanceInfo; the spec-compliant fix 1291df8 was reverted). Replace
that path with the groundwork for the vkb::FrameGraph migration:

- Drop the illegal secondary-CB deferred recording and restore the
  branch base's legal inline recording for shadow/GBuffer passes.
- Fix frame-prep culling regressions from PR #134:
  * per-item camera frustum culling (item.culled) instead of always
    testing against the main camera;
  * default-camera culling for the G-buffer pass (item.culledMain);
  * restore per-cascade CSM caster masks (item.cascadeMask).
  Camera view-proj matrices are snapshotted on the main thread before
  the parallel job forks; workers only read immutable data. The light
  job's CSM output is joined before the entity job forks so cascade
  culling never races with the shadow-upload write.
- Add FrameGraphJobs.h: vkb::PassRecordExecutor backed by the JobSystem
  (layer-internal fork/join via frame task groups, layers sequential),
  the exact executor the render backend will hand to FrameGraph::record().
- Add device-free tests (test/render_graph.cpp): the engine's target
  pass topology (3 CSM cascades + GBuffer in one parallel layer ->
  forward -> present) plans with attachment->sampled barrier folding
  (zero explicit barriers on forward/present), and the JobSystem
  executor records every pass exactly once, in parallel per layer.

Verified locally (win32-debug): render_graph.*, thread.*, Shadow3D.*,
RenderSystem3D.*, Lighting3D.* and Mesh.* all pass (58/58). Bundle-mode
SEGFAULTs are the known pre-existing zeroerr single-process issue, not
this change. See docs/dev/superpowers/specs/2026-08-20-framegraph-mt-render.md
for the staged migration plan (GBuffer into the graph next, then the
dedicated render thread).
2026-08-20 19:39:10 +08:00
西风逍遥游 34d1fdb63b refactor(modules): clear remaining back-edges and split the largest TUs (#127)
* chore(ci): add clang-format gate, CODEOWNERS and agent collaboration rules

* refactor(modules): clear remaining back-edges and split the largest TUs

Three known dependency back-edges are gone (module_depgraph.py KNOWN_BACK_EDGES
is now empty; --check passes with 0 violations, 0 cycles):

- window -> graphics: window queries the new IWindowSurfaceHost capability
  (common/WindowSurfaceHost.h) instead of holding a Graphics pointer;
  Window::setGraphics was removed and all call sites updated.
- window -> image: Window::setIcon was replaced by setIconRGBA(const uint8_t*,
  w, h); the window no longer decodes ImageData.
- scene -> graphics: pickScreenAt / collectFrustumIdsAt implementations moved
  to graphics/ScenePicking.cpp (graphics -> scene is a legal downward edge);
  scene now depends only on spatial.

TU splits (pure moves, verified identical method sets and brace balance):

- vulkan/Graphics.cpp (5118 lines) -> Graphics.cpp (lifecycle), GraphicsPipeline,
  Graphics2D, Graphics3D, GraphicsMesh + shared GraphicsInternal.h.
- scene/Scene.cpp -> Scene.cpp (script layer / host lifecycle / serialization)
  + SceneNodes.cpp + shared SceneInternal.h.

Verified with a real build (MSVC 19.51, prebuilt third-party): full build green;
window.* and Scene.* suites pass, including scene picking/culling and GPU cases.

* refactor(graphics): narrow Graphics interfaces and clear public-header leaks

Step 4 — interface segregation:
- New lean interfaces: IGraphics2D, IGraphics3D, IResourceFactory, IPostFX
  (pure virtuals, forward-declared types only; graphics/Color.h extracted from
  Canvas.h so modules that only need the color type stop pulling Canvas.h).
- Graphics now implements all four facets; consumers can depend on the narrow
  interface they use instead of the 129-method god class.
- Migrated voxel (VoxelWorld::drawVisible -> IGraphics3D*) and model3d
  (ModelRenderer::buildRenderable(s) -> IResourceFactory&).
- Graphics.h slims from 24 sub-header includes to a handful of small type
  headers + forward declarations; the destructor moved out-of-line so
  unique_ptr effect members are destroyed where types are complete.

Step 5 — header leaks (module_depgraph.py '*' marks: 14 -> 7):
- map/TileLayer.h, particles/ParticleEmitter.h, avatar/AvatarInstance.h,
  animation/SpineAnim.h, map/TileSystem.h, model3d/ModelData.h,
  model3d/ModelRenderer.h, audio/Audio.h + Source.h, image/ImageData.h +
  Image.h, dialogue/Dialogue.h, procgen Palette/OutputSpec/TextureRecipe/
  PbrMaterial -> forward declarations, includes moved to .cpp.
- voxel/VoxelWorld.h: terrain sampler Pimpl'd (unique_ptr + out-of-line
  destructor), removing the procgen header dependency.
- gpgpu/vulkan backend headers stop pulling graphics/vulkan/Graphics.h.
- Remaining '*' marks are deliberate: tiny POD/enum headers (GridConfig,
  MapObject, BlendMode, Color), an internal backend header
  (GraphicsInternal.h -> filesystem), and lean interface references.

Verified with a full clean build (MSVC) and tests: window/Scene/voxel/
RenderSystem/Quad/shader/TextureSampler/resourceLifetime pass; broad suite
only shows the pre-existing PHYSFS-init filesystem-environment failures.

* feat(resources): revive ResourceManager as unified IAssetReloader-backed cache

* fix(resources): leak ResourceManager singleton to avoid exit-time teardown crashes

Cached CPU resources may own third-party handles (FreeType faces, Assimp
scenes, image decode handlers) whose libraries are torn down at process
exit in an unspecified TU order; destroying cached entries from the
singleton destructor can segfault at exit (seen on CI Windows in
model3d.materialApi.objMtl). Keep the singleton alive until OS reclaim;
explicit unload()/clear() still release entries during the run.

* refactor(devtools): consume business modules through capability interfaces

DevTools / cmdline no longer include business-module headers, so trimming
scene / physics / procgen / particles / audio / ui / graphics no longer
requires disabling devtools, and devtools can be switched off with
-DEVENGINE_MODULE_DEVTOOLS=OFF.

New capability interfaces in common/:
- ISceneQuery (scene) - host/node inspection + mutation + transform sync
- IRenderCapture (graphics) - render status, PNG capture, camera control,
  visible-entity snapshot, entity-ID mask, G-buffer PNGs
- IPhysicsQuery (physics) - 2D world lifecycle + ray casts
- IProcgenQuery (procgen) - recipe listing, map/mesh generation
- IParticlesQuery (particles) - emitter status + one-shot emit
- IAudioQuery (audio) - volume / stop-all
- IEditorHost (ui) - declarative editor host (used by cmdline too)

Providers register in their module constructors. DevTools rewires McpServer
(render/scene/procgen/physics/particles/audio/host tools), SceneInspect
(now delegates to ISceneQuery + IRenderCapture) and RenderVision (uses
IRenderCapture::capturePngDataUrl); cmdline/Mcp.cpp uses IEditorHost.

manifest: devtools DEPS graphics scene physics procgen particles audio ui
image event filesystem -> event; cmdline DEPS filesystem ui -> filesystem.

Verified: full build green; devtools.mcp.* tests pass; broad suite shows
only the pre-existing PHYSFS-init filesystem-environment failures.

* style: apply clang-format to changed lines after dev merge

* fix(webgpu): include RenderControl/TextureSampler explicitly after Graphics.h slimming

* fix(webgpu): provide newFont/print stubs to satisfy IGraphics2D/IResourceFactory vtables

* fix(common): make ProcgenQuery.h self-sufficient (cstdint/utility for GCC)
2026-08-20 05:53:33 +08:00
西风逍遥游 a195d4781f Merge branch 'dev' into codex/release-flow-sdk 2026-08-19 23:40:12 +08:00
西风逍遥游 da3e103ba9 Merge pull request #124 from EVEngine/feat/card-ecs
refactor(card): 用 ECS 持有卡牌运行时对象
2026-08-19 23:38:05 +08:00
西风逍遥游 38b70171fb fix(release): make sync-docs PR-based and release-aware
- compute main's changes since the merge-base with dev instead of per-commit
  cherry-picks, so merge/squash/rebase doc merges all work and dev-only work
  is never touched;
- allow release version touchpoints (RELEASE_PATHS) in the non-doc gate, fixing
  the spurious failure every sync-docs run after a non-ff release merge;
- sync by copying doc paths from main onto sync-docs/from-main and opening a
  PR to dev (no direct push), matching the PR-only branch model;
- docs updated in 发布流程.md and the release-branch-model spec.
2026-08-19 22:07:42 +08:00
西风逍遥游 b08657ab67 feat(sdk): package licenses, auto-export module headers, add plugin/APK smoke tests, checksums and branch cleanup
- install_sdk.cmake: export headers for exactly the modules the build enabled
  (EVE_ENABLED_MODULES from cmake/module_manifest.cmake) instead of a stale
  whitelist; package engine + vendored third-party licenses under
  share/eve/licenses/.
- test-sdk.sh: hard-gate native C++ plugin compile (find_package(EVEngine) +
  add_eve_plugin) on win32/linux/macosx; android now assembles an APK from the
  SDK template (gradlew assembleDebug) instead of skipping.
- sdk-release.yml: run the android APK smoke; publish generates SHA256SUMS,
  verifies every zip's share/eve/VERSION against the tag, uploads SHA256SUMS
  with the SDKs, and (best-effort) attests build provenance.
- release.py: new cleanup-branches subcommand deletes merged vX.Y.Z /
  promote/* / rebase/* branches (tags and main/dev are never touched);
  new cleanup-branches.yml runs it weekly + on demand.
- docs: SDK packaging and branch cleanup sections in 发布流程.md and the
  release-branch-model spec.
2026-08-19 21:57:52 +08:00
西风逍遥游 703f1fb7a5 ci(release): fix ambiguous refspecs, add version consistency and SDK hardening
- release.py: use explicit refs/heads + refs/tags refspecs everywhere (short
  refspecs are ambiguous when the release branch and tag share a name, and git
  refuses to push them); rebase dev onto the branch's -dev write-back instead
  of the official tag; add a real-git integration test suite.
- version single-sourcing: fix config.h.in PATCH macro bug and include -dev;
  derive Android versionCode; sync required version touchpoints in start and
  enforce them via check-versions in CI.
- SDK: exact version assertions in test-sdk.sh, publish-time VERSION cross-check.
- workflows: converge toolchain versions to repo vars, SHA-pin actions, add
  Dependabot config.
2026-08-19 21:50:02 +08:00
西风逍遥游 138072f513 feat(release): open PRs instead of pushing main and dest
finish no longer updates main or force-pushes dest. It opens promote/vX.X.X to main and rebase/vX.X.X to dest for a human merge, and posts the main-gate check so GITHUB_TOKEN PRs stay mergeable.
2026-08-19 20:53:05 +08:00
西风逍遥游 81f51eccc8 refactor(card): hold runtime objects as ECS entities
Factory-created cards, hands, decks, and zones live in the ECS table
so ecs::View and eve.view can enumerate them without changing the
Squirrel API or ordered membership.
2026-08-19 20:15:33 +08:00
西风逍遥游 ede37ca479 refactor: update documentation generation process and remove obsolete files
- Updated `.gitignore` to reflect changes in documentation generation commands.
- Modified `CMakeLists.txt` to set a new version format and streamline documentation handling by adding a subdirectory for docs.
- Removed the outdated `Doxyfile` and replaced it with a new configuration in `docs/Doxyfile.in`.
- Updated README files to reference the new documentation structure and generation process.
- Deleted unused `imgui.ini` and API conventions documentation file to clean up the repository.
2026-08-19 18:00:07 +08:00
西风逍遥游 23324e2216 Merge branch 'main' of https://github.com/EVEngine/EVEngine 2026-08-19 11:34:06 +08:00
西风逍遥游 c63725e5df Merge remote-tracking branch 'origin/main' into codex/ui-viewport-terrain-editor
# Conflicts:
#	src/modules/graphics/RenderSystem3D.h
#	src/modules/ui/UI.h
#	src/modules/ui/UISystem.h
#	src/modules/ui/Widget.h
2026-08-19 09:59:41 +08:00
西风逍遥游 4f46060765 Merge pull request #119 from EVEngine/codex/asserts-and-api-docs
feat: zeroerr parameter validation + Doxygen API documentation
2026-08-19 09:43:21 +08:00
西风逍遥游 1bce65f794 Merge pull request #114 from EVEngine/codex/test-suite-optimization
test: prune redundant cases, bundle CTest discovery, fast headless defaults
2026-08-19 09:40:38 +08:00
西风逍遥游 90b49cb63b Merge branch 'main' of https://github.com/EVEngine/EVEngine 2026-08-19 09:15:37 +08:00
西风逍遥游 34f9d0045e feat(rpg): add RPG Quest Tracker design document and implementation plan
- Introduced a new document detailing the design of a universal quest tracker for the RPG module, covering objectives, policies, and event handling.
- Updated existing RPG framework documentation to reference the new quest tracking system.
- Created an implementation plan outlining the architecture, file structure, and initial tasks for developing the quest tracker.
2026-08-19 09:15:26 +08:00
西风逍遥游 c7de064bf4 Merge remote-tracking branch 'origin/main' into codex/ui-viewport-terrain-editor
# Conflicts:
#	src/modules/sceneloader/SceneLoader.cpp
#	test/sceneloader.cpp
2026-08-19 09:11:05 +08:00
西风逍遥游 4ac980118e test: default back to per-case CTest runs; bundles stay opt-in
CI showed GPU/window tests are ~70x slower when several share one
process (bundle/animation_sprite_spine.cpp: 373s vs 5s per-case under
Lavapipe), so the default make test/* now runs per-case (fast, process
isolated) and excludes bundle/* entries. Bundle runs remain available
via FILTER=bundle/<file>.cpp or ctest -L bundle for CPU-focused local
runs. ClassicScenes fast headless defaults (VIEW_SECONDS, PERF_FRAMES)
stay enabled.
2026-08-19 09:11:05 +08:00