Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c1cf2fecc | ||
|
|
331815d458 | ||
|
|
54d1bae962 | ||
|
|
798aa0e550 | ||
|
|
822b44f1d7 | ||
|
|
d7a7a7c3a4 | ||
|
|
abd8c21273 | ||
|
|
4ac02ee44a | ||
|
|
6c2e8fa800 | ||
|
|
1ea0ce6ba9 | ||
|
|
62059e154d | ||
|
|
a68fb8e7fd | ||
|
|
93946c1d24 | ||
|
|
7c777eba7c | ||
|
|
af836785d3 | ||
|
|
ba8bf45dbc | ||
|
|
9e921a5b3b | ||
|
|
6446f8917e | ||
|
|
45c5d2d188 | ||
|
|
77c145fa02 | ||
|
|
4a434f7855 | ||
|
|
d3217838cb | ||
|
|
cf5b702233 | ||
|
|
6459d69cc7 | ||
|
|
d4c1f0e86b | ||
|
|
abbb71d0c1 | ||
|
|
4ec5a3cd8a | ||
|
|
4a59ca1629 | ||
|
|
deb37c308b |
@@ -96,3 +96,4 @@ jobs:
|
||||
python-version: '3.12'
|
||||
- run: python -m pip install -r docs/requirements.txt
|
||||
- run: python -m mkdocs build --strict
|
||||
- run: python tests/verify_playable_exports_test.py
|
||||
|
||||
@@ -71,9 +71,9 @@ jobs:
|
||||
VK_LOADER_DEBUG: error,warn,driver
|
||||
run: ctest --preset windows-debug --timeout 180
|
||||
- name: Real Release exports, 2D and 3D execution, incremental Debug rebuild
|
||||
run: build/windows-debug/faset_build_service_tests.exe --integration .cache/windows-export-e2e
|
||||
- name: Export and relocate both checked-in playable games
|
||||
run: python tools/verify_playable_exports.py --editor build/windows-debug/faset_editor.exe --output .cache/windows-playable-exports
|
||||
run: build/windows-debug/faset_build_service_tests.exe --integration "${{ runner.temp }}/faset-windows-export-e2e"
|
||||
- name: Export and relocate C++ and Lua playable games
|
||||
run: python tools/verify_playable_exports.py --editor build/windows-debug/faset_editor.exe --output .cache/windows-playable-exports --include-lua
|
||||
- name: Preserve graphics and export evidence
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
||||
@@ -89,8 +89,8 @@ jobs:
|
||||
.cache/windows-graphics/sdk/source-identity.json
|
||||
build/windows-debug/Testing/Temporary/LastTest.log
|
||||
build/windows-debug/*test.ppm
|
||||
.cache/windows-export-e2e/result-*.json
|
||||
.cache/windows-export-e2e/export-*/generations/*/manifest.json
|
||||
.cache/windows-export-e2e/export-*/generations/*/verification.ppm
|
||||
${{ runner.temp }}/faset-windows-export-e2e/result-*.json
|
||||
${{ runner.temp }}/faset-windows-export-e2e/export-*/generations/*/manifest.json
|
||||
${{ runner.temp }}/faset-windows-export-e2e/export-*/generations/*/verification.ppm
|
||||
.cache/windows-playable-exports/report.json
|
||||
.cache/windows-playable-exports/evidence/*
|
||||
|
||||
+4
-1
@@ -74,13 +74,16 @@ if(TARGET faset_assets AND TARGET faset_authoring AND EXISTS "${PROJECT_SOURCE_D
|
||||
endif()
|
||||
if(TARGET faset_editor_commands AND TARGET faset_build_service)
|
||||
include(cmake/Plugins.cmake)
|
||||
add_library(faset_editor_session STATIC src/editor/session.cpp)
|
||||
add_library(faset_editor_session STATIC src/editor/session.cpp src/editor/autosave.cpp)
|
||||
target_link_libraries(faset_editor_session PUBLIC faset_editor_commands faset_build_service faset_assets faset_editor_plugins)
|
||||
if(BUILD_TESTING)
|
||||
add_executable(faset_editor_session_tests tests/editor_session_tests.cpp)
|
||||
target_link_libraries(faset_editor_session_tests PRIVATE faset_editor_session)
|
||||
target_compile_definitions(faset_editor_session_tests PRIVATE FASET_TEST_ENGINE="${PROJECT_SOURCE_DIR}")
|
||||
add_test(NAME editor_session_settings COMMAND faset_editor_session_tests)
|
||||
add_executable(faset_editor_autosave_tests tests/editor_autosave_tests.cpp)
|
||||
target_link_libraries(faset_editor_autosave_tests PRIVATE faset_editor_session)
|
||||
add_test(NAME editor_autosave COMMAND faset_editor_autosave_tests)
|
||||
endif()
|
||||
endif()
|
||||
foreach(module UI EditorUI Editor Applications)
|
||||
|
||||
@@ -179,9 +179,22 @@ Lua, C++ hot reload, Blender live link, встроенное изображен
|
||||
|
||||
Начальные бюджеты отслеживания для конкретных демо и Linux reference host: frame p95 ≤ 4 мс, GPU/readback p95 ≤ 1 мс, simulation/snapshot p95 ≤ 0,5 мс, явные Vulkan allocations ≤ 20 MiB, startup от `main()` ≤ 500 мс. [Методика и исходные измерения](docs/validation/linux-release-2026-09-18/README.md) ограничивают область этих чисел; для других сцен/ОС нужны отдельные baselines. Это бюджеты P1, а не обещание такой производительности любой игры.
|
||||
|
||||
Lua runtime/editor пакет реализован как необязательный модуль поверх публичного API, проверяемых handles и схем. Доступны Inspector, диагностика и явный lifecycle development reload; сохранение состояния при reload проектируется отдельно. [Проверка Lua-модуля](docs/validation/lua-module.md) подтверждает Linux CPU-контракты и отключение модуля для C++-only проекта; Windows и независимый graphical/release профиль модуля остаются отдельными проверками. Таким образом, Lua-часть P1 появилась после MVP, но это не закрывает весь этап скорости итераций.
|
||||
|
||||
Улучшать schema/build cache, сообщения компилятора, шаблоны проектов, переход к коду, autosave и измеренное время «изменение → результат». Dynamic gameplay loading рассматривать при подтверждённой проблеме линковки.
|
||||
Реализованы необязательный Lua runtime/editor модуль, development reload без
|
||||
сохранения runtime-состояния, проверяемые schema/package cache и snapshots C++
|
||||
исходников, структурированная диагностика, переход к исходнику, четыре C++/Lua
|
||||
2D/3D starter-проекта и безопасный autosave именованных сцен. [Датированный
|
||||
отчёт P1](docs/validation/p1-iteration-2026-09-24/README.md) содержит raw
|
||||
повторные измерения Debug-итераций, 3000 кадров без роста явных GPU allocations,
|
||||
синтетическую расширенную сцену и реальные найденные ограничения. [Lua Release
|
||||
пакет](docs/validation/lua-release-2026-09-24/README.md) на Linux проверен после
|
||||
переноса и скрытия исходного проекта. Windows native/manual, 61 SwiftShader
|
||||
CTest и перенос всех трёх Release-игр, включая Lua-only, прошли на
|
||||
[чистой ревизии `4ac02ee`](https://github.com/emil28092005/Faset_Engine/actions/runs/35937433040).
|
||||
Это функциональная проверка software Vulkan без активного validation layer.
|
||||
Исторический Release benchmark точных демо нельзя
|
||||
подменять новым Debug workflow; свежий Release reference и физический Windows GPU
|
||||
остаются отдельным покрытием. Dynamic gameplay loading рассматривать при
|
||||
подтверждённой проблеме линковки, без обещания C++ hot reload в P1.
|
||||
|
||||
### P2. GPU-driven visibility и LOD
|
||||
|
||||
@@ -199,16 +212,7 @@ GPU instance record содержит стабильные slot/generation; пл
|
||||
|
||||
### P3. Освещение, тени и temporal reconstruction
|
||||
|
||||
**Освещение и тени реализованы до измеренного выбора пути; приёмка этапа ещё
|
||||
открыта.** Есть authored directional/point/spot lights, общий shader ABI для
|
||||
Direct и P2, четыре каскада солнца, отдельный 16-face atlas для point/spot,
|
||||
видимость каскадеров из shadow views и общий бюджет 4096 caster draws.
|
||||
Ранжирование 128 local lights, атомарный отказ от шести point faces и
|
||||
unshadowed fallback доступны с диагностикой. На Linux reference GPU Release
|
||||
1920×1080 измеренный рост стоимости main raster уже превысил порог для
|
||||
Forward+, поэтому depth-free tiled путь 16×16 и повторные измерения входят в
|
||||
оставшуюся работу. [Протокол проверки](docs/validation/p3-lighting-2026-09-24/README.md)
|
||||
отделяет текущий checkpoint от финальной Linux/Windows приёмки.
|
||||
Расширить local lights, добавить clustered/Forward+ при измеренной необходимости, cascaded sun shadows и ограниченный local shadow atlas. Shadow views имеют собственную видимость и бюджеты.
|
||||
|
||||
Затем: previous transforms, motion vectors, jitter, history rejection и TAA; temporal upscaling — после устойчивого TAA. Проверять тонкую геометрию, движение, disocclusion, camera cut и смену разрешения, сравнивать с режимом без temporal. У cache/pass видны затраты и причины обновления.
|
||||
|
||||
|
||||
+50
-7
@@ -4,6 +4,7 @@
|
||||
#include <faset/editor/mcp.hpp>
|
||||
#include <faset/editor/session.hpp>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#ifdef FASET_HAS_EDITOR_UI
|
||||
#include <faset/editor/editor_ui.hpp>
|
||||
@@ -40,7 +41,7 @@ void help() {
|
||||
std::cout
|
||||
<< "Faset Editor\n"
|
||||
" faset_editor Open the project launcher\n"
|
||||
" faset_editor --project PATH [--new NAME --dimension 2|3] [--scene RELATIVE_PATH]\n"
|
||||
" faset_editor --project PATH [--new NAME --dimension 2|3 [--language cpp|lua]] [--scene RELATIVE_PATH]\n"
|
||||
" faset_editor --project PATH --mcp [--gui]\n"
|
||||
" faset_editor --project PATH --command JSON [--wait]\n"
|
||||
"Options: --engine SDK_SOURCE, --headless, --frames N, --capture PATH.ppm\n"
|
||||
@@ -52,9 +53,10 @@ int editor_main(int argc, char** argv) {
|
||||
using namespace faset::editor;
|
||||
try {
|
||||
std::filesystem::path project, engine = path_from_utf8(FASET_ENGINE_SOURCE), scene, capture;
|
||||
std::string new_name, command;
|
||||
std::string new_name, command, language = "cpp";
|
||||
int dimension = 3;
|
||||
bool mcp = false, gui = true, explicit_gui = false, wait = false;
|
||||
bool explicit_language = false;
|
||||
std::uint64_t frames = 0;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
const std::string arg = argv[i];
|
||||
@@ -74,6 +76,10 @@ int editor_main(int argc, char** argv) {
|
||||
new_name = value();
|
||||
else if (arg == "--dimension")
|
||||
dimension = std::stoi(value());
|
||||
else if (arg == "--language") {
|
||||
language = value();
|
||||
explicit_language = true;
|
||||
}
|
||||
else if (arg == "--scene")
|
||||
scene = path_from_utf8(value());
|
||||
else if (arg == "--mcp")
|
||||
@@ -100,30 +106,65 @@ int editor_main(int argc, char** argv) {
|
||||
throw Error("cli.option", "Unknown option: " + arg);
|
||||
}
|
||||
require(!(mcp && !command.empty()), "cli.mode", "Choose MCP or a single command");
|
||||
require(!explicit_language || !new_name.empty(), "cli.language",
|
||||
"--language requires --new NAME");
|
||||
require(language == "cpp" || language == "lua", "cli.language",
|
||||
"Language must be cpp or lua");
|
||||
if (mcp && !explicit_gui)
|
||||
gui = false;
|
||||
require(!project.empty() || (gui && !mcp && new_name.empty()), "cli.project",
|
||||
"Use --project PATH for command, MCP, or --new modes");
|
||||
auto previous_project = project;
|
||||
#ifdef FASET_HAS_EDITOR_UI
|
||||
std::optional<ProjectSelection> retry_create;
|
||||
std::string creation_error;
|
||||
#endif
|
||||
for (;;) {
|
||||
if (project.empty()) {
|
||||
#ifdef FASET_HAS_EDITOR_UI
|
||||
const auto selection =
|
||||
run_project_launcher(engine, previous_project, frames, capture);
|
||||
run_project_launcher(engine, previous_project, frames, capture,
|
||||
retry_create, creation_error);
|
||||
retry_create.reset();
|
||||
creation_error.clear();
|
||||
if (!selection)
|
||||
return 0;
|
||||
project = selection->path;
|
||||
new_name = selection->create ? selection->name : std::string();
|
||||
dimension = selection->dimension;
|
||||
language = selection->language;
|
||||
explicit_language = selection->create;
|
||||
#else
|
||||
throw Error("editor.gui_unavailable",
|
||||
"This build has no graphical project launcher; use --project PATH");
|
||||
#endif
|
||||
}
|
||||
Session session({std::filesystem::absolute(project), std::filesystem::absolute(engine),
|
||||
executable_directory(argv[0])});
|
||||
if (!new_name.empty())
|
||||
session.scaffold(new_name, dimension);
|
||||
std::unique_ptr<Session> session_holder;
|
||||
try {
|
||||
session_holder = std::make_unique<Session>(SessionConfig{
|
||||
std::filesystem::absolute(project), std::filesystem::absolute(engine),
|
||||
executable_directory(argv[0])});
|
||||
if (!new_name.empty()) {
|
||||
if (explicit_language)
|
||||
session_holder->scaffold(new_name, dimension, language);
|
||||
else
|
||||
session_holder->scaffold(new_name, dimension);
|
||||
}
|
||||
} catch (const std::exception& error) {
|
||||
#ifdef FASET_HAS_EDITOR_UI
|
||||
if (gui && !new_name.empty()) {
|
||||
retry_create = ProjectSelection{std::filesystem::absolute(project),
|
||||
new_name, dimension, true, language};
|
||||
creation_error = error.what();
|
||||
project.clear();
|
||||
new_name.clear();
|
||||
scene.clear();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
throw;
|
||||
}
|
||||
Session& session = *session_holder;
|
||||
const auto settings = session.project();
|
||||
#ifdef FASET_HAS_EDITOR_UI
|
||||
if (gui && std::filesystem::exists(project / "project.faset.json"))
|
||||
@@ -167,6 +208,8 @@ int editor_main(int argc, char** argv) {
|
||||
project.clear();
|
||||
scene.clear();
|
||||
new_name.clear();
|
||||
explicit_language = false;
|
||||
language = "cpp";
|
||||
continue;
|
||||
#else
|
||||
throw Error(
|
||||
|
||||
+3
-147
@@ -39,54 +39,6 @@ const char* visibility_mode_name(faset::render::VisibilityMode mode) {
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
const char* temporal_mode_name(faset::render::TemporalMode mode) {
|
||||
switch (mode) {
|
||||
case faset::render::TemporalMode::Off: return "off";
|
||||
case faset::render::TemporalMode::TAA: return "taa";
|
||||
case faset::render::TemporalMode::Upscale: return "upscale";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
const char* temporal_fallback_name(faset::render::TemporalFallbackReason reason) {
|
||||
using Reason = faset::render::TemporalFallbackReason;
|
||||
switch (reason) {
|
||||
case Reason::None: return "none";
|
||||
case Reason::ComputeUnavailable: return "compute-unavailable";
|
||||
case Reason::FormatUnavailable: return "format-unavailable";
|
||||
case Reason::ExtentUnsupported: return "extent-unsupported";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
const char* temporal_reset_name(faset::render::TemporalResetReason reason) {
|
||||
using Reason = faset::render::TemporalResetReason;
|
||||
switch (reason) {
|
||||
case Reason::None: return "none";
|
||||
case Reason::FirstFrame: return "first-frame";
|
||||
case Reason::CameraCut: return "camera-cut";
|
||||
case Reason::CameraDiscontinuity: return "camera-discontinuity";
|
||||
case Reason::ViewChanged: return "view-changed";
|
||||
case Reason::ViewportChanged: return "viewport-changed";
|
||||
case Reason::ProjectionChanged: return "projection-changed";
|
||||
case Reason::Resize: return "resize";
|
||||
case Reason::ModeChanged: return "mode-changed";
|
||||
case Reason::ScaleChanged: return "scale-changed";
|
||||
case Reason::ShaderReload: return "shader-reload";
|
||||
case Reason::Unsupported: return "unsupported";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
float render_scale_value(const std::string& value) {
|
||||
std::size_t consumed{};
|
||||
float scale{};
|
||||
try {
|
||||
scale = std::stof(value, &consumed);
|
||||
} catch (const std::exception&) {
|
||||
throw std::invalid_argument("--render-scale must be a finite number");
|
||||
}
|
||||
if (consumed != value.size() || !std::isfinite(scale))
|
||||
throw std::invalid_argument("--render-scale must be a finite number");
|
||||
return scale;
|
||||
}
|
||||
struct ProfileSample {
|
||||
double wall{}, simulation{}, snapshot{}, render{}, rendererCpu{}, gpu{}, readbackCpu{};
|
||||
faset::runtime::FrameStats runtime;
|
||||
@@ -96,7 +48,6 @@ struct ProfileSample {
|
||||
bool physicsDebug{};
|
||||
bool gpuVisibilityActive{};
|
||||
faset::render::VisibilityMode effectiveVisibilityMode{faset::render::VisibilityMode::Direct};
|
||||
faset::render::FrameStats lighting;
|
||||
};
|
||||
Json distribution(std::vector<double> values) {
|
||||
if (values.empty())
|
||||
@@ -145,63 +96,7 @@ Json profileFrames(const std::vector<ProfileSample>& samples) {
|
||||
{"physics_debug", sample.physicsDebug},
|
||||
{"gpu_visibility_active", sample.gpuVisibilityActive},
|
||||
{"effective_visibility_mode",
|
||||
visibility_mode_name(sample.effectiveVisibilityMode)},
|
||||
{"effective_lighting_path", sample.lighting.effective_lighting_path},
|
||||
{"submitted_local_lights", sample.lighting.submitted_local_lights},
|
||||
{"omitted_local_lights", sample.lighting.omitted_local_lights},
|
||||
{"requested_sun_cascades", sample.lighting.requested_sun_cascades},
|
||||
{"effective_sun_cascades", sample.lighting.effective_sun_cascades},
|
||||
{"requested_local_shadow_faces",
|
||||
sample.lighting.requested_local_shadow_faces},
|
||||
{"local_shadow_faces", sample.lighting.local_shadow_faces},
|
||||
{"local_shadow_tiles", sample.lighting.local_shadow_tiles},
|
||||
{"dropped_shadow_faces", sample.lighting.dropped_shadow_faces},
|
||||
{"dropped_point_shadow_faces",
|
||||
sample.lighting.dropped_point_shadow_faces},
|
||||
{"shadow_atlas_full_drops", sample.lighting.shadow_atlas_full_drops},
|
||||
{"shadow_caster_budget_drops",
|
||||
sample.lighting.shadow_caster_budget_drops},
|
||||
{"shadow_unavailable_drops",
|
||||
sample.lighting.shadow_unavailable_drops},
|
||||
{"shadow_caster_draws", sample.lighting.shadow_caster_draws},
|
||||
{"sun_shadow_atlas_bytes",
|
||||
sample.lighting.sun_shadow_atlas_bytes},
|
||||
{"local_shadow_atlas_bytes",
|
||||
sample.lighting.local_shadow_atlas_bytes},
|
||||
{"gpu_main_raster_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_main_raster_ms) : Json(nullptr)},
|
||||
{"gpu_sun_shadow_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_sun_shadow_ms) : Json(nullptr)},
|
||||
{"gpu_local_shadow_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_local_shadow_ms) : Json(nullptr)},
|
||||
{"requested_temporal_mode",
|
||||
temporal_mode_name(sample.lighting.requested_temporal_mode)},
|
||||
{"effective_temporal_mode",
|
||||
temporal_mode_name(sample.lighting.effective_temporal_mode)},
|
||||
{"temporal_fallback_reason",
|
||||
temporal_fallback_name(sample.lighting.temporal_fallback_reason)},
|
||||
{"temporal_reset_reason",
|
||||
temporal_reset_name(sample.lighting.temporal_reset_reason)},
|
||||
{"temporal_history_valid", sample.lighting.temporal_history_valid},
|
||||
{"temporal_valid_motion_instances",
|
||||
sample.lighting.temporal_valid_motion_instances},
|
||||
{"temporal_internal_width", sample.lighting.temporal_internal_width},
|
||||
{"temporal_internal_height", sample.lighting.temporal_internal_height},
|
||||
{"temporal_jitter", sample.lighting.temporal_jitter},
|
||||
{"gpu_temporal_resolve_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_temporal_resolve_ms) : Json(nullptr)},
|
||||
{"gpu_temporal_composite_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_temporal_composite_ms) : Json(nullptr)},
|
||||
{"gpu_ui_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_ui_ms) : Json(nullptr)},
|
||||
{"gpu_light_tiles_ms",
|
||||
gpuMeasured ? Json(sample.lighting.gpu_light_tiles_ms) : Json(nullptr)},
|
||||
{"light_tile_count", sample.lighting.light_tile_count},
|
||||
{"light_tile_counts_valid", sample.lighting.light_tile_counts_valid},
|
||||
{"light_tile_candidate_count", sample.lighting.light_tile_counts_valid
|
||||
? Json(sample.lighting.light_tile_candidate_count) : Json(nullptr)},
|
||||
{"light_tile_overflow_count", sample.lighting.light_tile_counts_valid
|
||||
? Json(sample.lighting.light_tile_overflow_count) : Json(nullptr)}});
|
||||
visibility_mode_name(sample.effectiveVisibilityMode)}});
|
||||
}
|
||||
return {{"samples", std::move(frames)},
|
||||
{"summary_ms",
|
||||
@@ -310,8 +205,6 @@ int player_main(int argc, char** argv) {
|
||||
projectRoot;
|
||||
bool headless = false, validateOnly = false, debugPhysics = false, watchLua = false;
|
||||
auto visibilityMode = faset::render::VisibilityMode::Direct;
|
||||
auto temporalMode = faset::render::TemporalMode::Off;
|
||||
float renderScale = 1.f;
|
||||
std::string visibilityName = "direct";
|
||||
std::uint64_t maximumFrames = 0;
|
||||
std::set<std::string> options;
|
||||
@@ -322,8 +215,7 @@ int player_main(int argc, char** argv) {
|
||||
<< "faset_player [--scene PATH] [--assets CACHE] [--frames N] "
|
||||
"[--headless] [--capture PATH.ppm] [--validate] [--control PATH] "
|
||||
"[--profile PATH.json] [--debug-physics] [--project ROOT] "
|
||||
"[--watch-lua] [--visibility direct|gpu-frustum|gpu-occlusion] "
|
||||
"[--temporal off|taa|upscale] [--render-scale 0.5..1]\n"
|
||||
"[--watch-lua] [--visibility direct|gpu-frustum|gpu-occlusion]\n"
|
||||
"No --scene: open scene.fscene beside the executable. CACHE contains "
|
||||
"assets/<id>/.\n"
|
||||
"Headless uses offscreen Vulkan; --frames uses the configured fixed "
|
||||
@@ -341,9 +233,6 @@ int player_main(int argc, char** argv) {
|
||||
"--visibility selects the renderer for this Player run; Direct is "
|
||||
"the default. GPU modes require their packaged shader bundle and "
|
||||
"device capabilities.\n"
|
||||
"--temporal selects scene TAA or temporal upscaling; Off is the default. "
|
||||
"--render-scale applies only to upscale and must be at least 0.5 "
|
||||
"and less than 1. UI remains at output resolution.\n"
|
||||
"Keys: A/D horizontal, W/S vertical, Space jump, E interact, P pause, "
|
||||
"N single-step, F3 physics boxes, Escape quit.\n";
|
||||
return 0;
|
||||
@@ -380,18 +269,6 @@ int player_main(int argc, char** argv) {
|
||||
"or gpu-occlusion");
|
||||
} else if (arg == "--frames")
|
||||
maximumFrames = count(value());
|
||||
else if (arg == "--temporal") {
|
||||
const auto selected = value();
|
||||
if (selected == "off")
|
||||
temporalMode = faset::render::TemporalMode::Off;
|
||||
else if (selected == "taa")
|
||||
temporalMode = faset::render::TemporalMode::TAA;
|
||||
else if (selected == "upscale")
|
||||
temporalMode = faset::render::TemporalMode::Upscale;
|
||||
else
|
||||
throw std::invalid_argument("--temporal must be off, taa or upscale");
|
||||
} else if (arg == "--render-scale")
|
||||
renderScale = render_scale_value(value());
|
||||
else if (arg == "--headless")
|
||||
headless = true;
|
||||
else if (arg == "--validate")
|
||||
@@ -403,7 +280,6 @@ int player_main(int argc, char** argv) {
|
||||
else
|
||||
throw std::invalid_argument("Unknown option: " + arg);
|
||||
}
|
||||
(void)faset::render::temporal_internal_extent(1280, 720, temporalMode, renderScale);
|
||||
if (options.contains("--profile") &&
|
||||
(profilePath.empty() || !options.contains("--frames") || maximumFrames > 100000 ||
|
||||
validateOnly))
|
||||
@@ -508,8 +384,6 @@ int player_main(int argc, char** argv) {
|
||||
renderConfig.headless = headless;
|
||||
renderConfig.validation = true;
|
||||
renderConfig.visibility_mode = visibilityMode;
|
||||
renderConfig.temporal_mode = temporalMode;
|
||||
renderConfig.render_scale = renderScale;
|
||||
faset::render::Renderer renderer(renderConfig);
|
||||
const auto rendererReady = Clock::now();
|
||||
std::vector<ProfileSample> profile;
|
||||
@@ -701,13 +575,6 @@ int player_main(int argc, char** argv) {
|
||||
<< "using "
|
||||
<< visibility_mode_name(renderer.stats().effective_visibility_mode)
|
||||
<< " rendering.\n";
|
||||
if (frames == 0 && temporalMode != renderer.stats().effective_temporal_mode)
|
||||
std::cerr << "Requested " << temporal_mode_name(temporalMode)
|
||||
<< " temporal rendering is unavailable ("
|
||||
<< temporal_fallback_name(renderer.stats().temporal_fallback_reason)
|
||||
<< "); using "
|
||||
<< temporal_mode_name(renderer.stats().effective_temporal_mode)
|
||||
<< ".\n";
|
||||
const auto frameFinished = Clock::now();
|
||||
if (frames == 0)
|
||||
firstFrameMs = milliseconds(started, frameFinished);
|
||||
@@ -720,8 +587,7 @@ int player_main(int argc, char** argv) {
|
||||
milliseconds(renderStarted, frameFinished), measured.cpu_ms, measured.gpu_ms,
|
||||
measured.readback_cpu_ms, runtimeStats, measured.draw_calls, measured.vertices,
|
||||
measured.gpu_allocated_bytes, measured.texture_count, debugPhysics,
|
||||
measured.gpu_visibility_active, measured.effective_visibility_mode,
|
||||
measured});
|
||||
measured.gpu_visibility_active, measured.effective_visibility_mode});
|
||||
}
|
||||
++frames;
|
||||
}
|
||||
@@ -753,13 +619,6 @@ int player_main(int argc, char** argv) {
|
||||
{"visibility_mode", visibilityName},
|
||||
{"effective_visibility_mode",
|
||||
visibility_mode_name(stats.effective_visibility_mode)},
|
||||
{"temporal_mode", temporal_mode_name(temporalMode)},
|
||||
{"render_scale", renderScale},
|
||||
{"effective_temporal_mode",
|
||||
temporal_mode_name(stats.effective_temporal_mode)},
|
||||
{"temporal_fallback_reason",
|
||||
temporal_fallback_name(stats.temporal_fallback_reason)},
|
||||
{"effective_lighting_path", stats.effective_lighting_path},
|
||||
{"simulation_mode", "synthetic_fixed_timestep"},
|
||||
{"fixed_delta_seconds", config.fixedDelta},
|
||||
{"percentile_method", "nearest_rank_all_completed_frames_no_warmup_exclusion"},
|
||||
@@ -788,9 +647,6 @@ int player_main(int argc, char** argv) {
|
||||
{"visibility_mode", visibilityName},
|
||||
{"effective_visibility_mode",
|
||||
visibility_mode_name(stats.effective_visibility_mode)},
|
||||
{"temporal_mode", temporal_mode_name(temporalMode)},
|
||||
{"effective_temporal_mode",
|
||||
temporal_mode_name(stats.effective_temporal_mode)},
|
||||
{"gpu_visibility_active", stats.gpu_visibility_active},
|
||||
{"validation_errors", stats.validation_errors}}
|
||||
.dump()
|
||||
|
||||
+52
-10
@@ -75,6 +75,22 @@ ProjectSelection open_project(const fs::path& path) {
|
||||
throw std::runtime_error("Project name or scene type is invalid.");
|
||||
return {path, std::move(name), dimension, false};
|
||||
}
|
||||
bool fresh_destination(const fs::path& path) {
|
||||
if (!fs::exists(path))
|
||||
return true;
|
||||
if (!fs::is_directory(path) || fs::is_symlink(path))
|
||||
return false;
|
||||
for (const auto& entry : fs::directory_iterator(path)) {
|
||||
if (entry.path().filename() != ".faset" || !entry.is_directory() ||
|
||||
entry.is_symlink())
|
||||
return false;
|
||||
for (const auto& internal : fs::directory_iterator(entry.path()))
|
||||
if (internal.path().filename() != "cache" || !internal.is_directory() ||
|
||||
internal.is_symlink() || !fs::is_empty(internal.path()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Json recent_records(const fs::path& file) {
|
||||
try {
|
||||
auto j = read_json(file);
|
||||
@@ -124,9 +140,11 @@ struct ProjectLauncher::Impl {
|
||||
std::optional<ProjectSelection> selected;
|
||||
bool create = false, cancelled = false, browsing = false, browser_valid = false;
|
||||
int dimension = 3;
|
||||
std::string language = "cpp";
|
||||
std::string error;
|
||||
Impl(render::Renderer& r, const fs::path& engine, const fs::path& initial,
|
||||
const fs::path& recents)
|
||||
const fs::path& recents, const std::optional<ProjectSelection>& retry,
|
||||
std::string creation_error)
|
||||
: renderer(r), ui(engine / "assets/fonts/NotoSans.ttf"),
|
||||
recents_file(recents.empty() ? recent_path() : recents) {
|
||||
auto theme = ui::Theme::load(engine / "assets/ui/dark.json");
|
||||
@@ -147,13 +165,22 @@ struct ProjectLauncher::Impl {
|
||||
ui.set_ime(
|
||||
[this](bool enabled) { renderer.set_text_input(enabled); },
|
||||
[this](ui::Rect r) { renderer.set_text_input_area(r.x, r.y, r.width, r.height); });
|
||||
const auto start = initial.empty() ? user_home() / "FasetProjects/MyGame" : initial;
|
||||
const auto start = retry ? retry->path
|
||||
: initial.empty() ? user_home() / "FasetProjects/MyGame" : initial;
|
||||
ui.update_text("launcher-path", path_to_utf8(start));
|
||||
create = initial.empty();
|
||||
create = retry ? retry->create : initial.empty();
|
||||
if (retry) {
|
||||
ui.update_text("launcher-name", retry->name);
|
||||
dimension = retry->dimension;
|
||||
language = retry->language;
|
||||
error = std::move(creation_error);
|
||||
}
|
||||
ui.find("launcher-open")->on_click = [this](Widget&) { set_mode(false); };
|
||||
ui.find("launcher-create")->on_click = [this](Widget&) { set_mode(true); };
|
||||
ui.find("launcher-2d")->on_click = [this](Widget&) { dimension = 2; };
|
||||
ui.find("launcher-3d")->on_click = [this](Widget&) { dimension = 3; };
|
||||
ui.find("launcher-cpp")->on_click = [this](Widget&) { language = "cpp"; };
|
||||
ui.find("launcher-lua")->on_click = [this](Widget&) { language = "lua"; };
|
||||
ui.find("launcher-submit")->on_click = [this](Widget&) { submit(); };
|
||||
ui.find("launcher-cancel")->on_click = [this](Widget&) { cancelled = true; };
|
||||
ui.find("launcher-name")->on_preview = [this](Widget&) { error.clear(); };
|
||||
@@ -209,14 +236,14 @@ struct ProjectLauncher::Impl {
|
||||
throw std::runtime_error("Enter a project name.");
|
||||
if (name.size() > 256 || name.find_first_of("\r\n\t") != std::string::npos)
|
||||
throw std::runtime_error("Use a short project name on one line.");
|
||||
if (fs::exists(path) && (!fs::is_directory(path) || !fs::is_empty(path)))
|
||||
if (!fresh_destination(path))
|
||||
throw std::runtime_error("Create requires a new or empty directory.");
|
||||
auto parent = path.parent_path();
|
||||
while (!parent.empty() && !fs::exists(parent))
|
||||
parent = parent.parent_path();
|
||||
if (parent.empty() || !fs::is_directory(parent))
|
||||
throw std::runtime_error("Project parent directory is unavailable.");
|
||||
selected = ProjectSelection{path, name, dimension, true};
|
||||
selected = ProjectSelection{path, name, dimension, true, language};
|
||||
} else
|
||||
selected = open_project(path);
|
||||
error.clear();
|
||||
@@ -351,14 +378,24 @@ struct ProjectLauncher::Impl {
|
||||
ui.find("launcher-create")->selected = create;
|
||||
ui.find("launcher-2d")->selected = dimension == 2;
|
||||
ui.find("launcher-3d")->selected = dimension == 3;
|
||||
ui.find("launcher-cpp")->selected = language == "cpp";
|
||||
ui.find("launcher-lua")->selected = language == "lua";
|
||||
ui.find("launcher-2d")->appearance =
|
||||
dimension == 2 ? Appearance::Quiet : Appearance::Default;
|
||||
ui.find("launcher-3d")->appearance =
|
||||
dimension == 3 ? Appearance::Quiet : Appearance::Default;
|
||||
ui.find("launcher-cpp")->appearance =
|
||||
language == "cpp" ? Appearance::Quiet : Appearance::Default;
|
||||
ui.find("launcher-lua")->appearance =
|
||||
language == "lua" ? Appearance::Quiet : Appearance::Default;
|
||||
ui.find("launcher-language-hint")->text =
|
||||
language == "cpp" ? "Compiled gameplay. Add Lua later if you need quick reloads."
|
||||
: "Lua gameplay reloads during development without a C++ rebuild.";
|
||||
for (const auto* id : {"launcher-name-label", "launcher-name", "launcher-dimension-label",
|
||||
"launcher-dimensions", "launcher-name-group",
|
||||
"launcher-name-space", "launcher-path-space",
|
||||
"launcher-dimension-group"})
|
||||
"launcher-dimension-group", "launcher-language-group",
|
||||
"launcher-language-space"})
|
||||
ui.find(id)->visible = create;
|
||||
ui.find("launcher-heading")->text = create ? "Create project" : "Open project";
|
||||
ui.find("launcher-submit")->text = create ? "Create project" : "Open project";
|
||||
@@ -424,8 +461,11 @@ struct ProjectLauncher::Impl {
|
||||
}
|
||||
};
|
||||
ProjectLauncher::ProjectLauncher(render::Renderer& r, const fs::path& engine,
|
||||
const fs::path& initial, const fs::path& recents)
|
||||
: impl_(std::make_unique<Impl>(r, engine, initial, recents)) {}
|
||||
const fs::path& initial, const fs::path& recents,
|
||||
const std::optional<ProjectSelection>& retry,
|
||||
std::string creation_error)
|
||||
: impl_(std::make_unique<Impl>(r, engine, initial, recents, retry,
|
||||
std::move(creation_error))) {}
|
||||
ProjectLauncher::~ProjectLauncher() = default;
|
||||
void ProjectLauncher::frame(const std::vector<render::Event>& events) {
|
||||
impl_->frame(events);
|
||||
@@ -445,9 +485,11 @@ bool ProjectLauncher::cancelled() const {
|
||||
std::optional<ProjectSelection> run_project_launcher(const fs::path& engine,
|
||||
const fs::path& initial,
|
||||
std::uint64_t max_frames,
|
||||
const fs::path& capture) {
|
||||
const fs::path& capture,
|
||||
const std::optional<ProjectSelection>& retry,
|
||||
std::string creation_error) {
|
||||
render::Renderer renderer({1100, 720, "Faset Engine — Projects", false, true});
|
||||
ProjectLauncher launcher(renderer, engine, initial);
|
||||
ProjectLauncher launcher(renderer, engine, initial, {}, retry, std::move(creation_error));
|
||||
std::uint64_t frames = 0;
|
||||
while (!renderer.should_close() && !launcher.cancelled() && !launcher.selection() &&
|
||||
(max_frames == 0 || frames < max_frames)) {
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
{"id": "launcher-3d", "kind": "button", "text": "3D", "layout": {"width": 116}}
|
||||
]}
|
||||
]},
|
||||
{"id": "launcher-language-space", "kind": "row", "layout": {"height": 18}},
|
||||
{"id": "launcher-language-group", "kind": "column", "layout": {"gap": 6}, "children": [
|
||||
{"id": "launcher-language-label", "kind": "label", "text": "Gameplay language", "layout": {"height": 24}},
|
||||
{"id": "launcher-languages", "kind": "row", "layout": {"height": 42, "gap": 4}, "children": [
|
||||
{"id": "launcher-cpp", "kind": "button", "text": "C++", "layout": {"width": 116}},
|
||||
{"id": "launcher-lua", "kind": "button", "text": "Lua", "layout": {"width": 116}}
|
||||
]},
|
||||
{"id": "launcher-language-hint", "kind": "label", "text": "Compiled gameplay. Add Lua later if you need quick reloads.", "font_size": 12, "layout": {"height": 30}}
|
||||
]},
|
||||
{"id": "launcher-hint", "kind": "label", "text": "Open a directory containing project.faset.json.", "font_size": 13, "layout": {"height": 36}},
|
||||
{"id": "launcher-actions-space", "kind": "row", "layout": {"height": 22}},
|
||||
{"id": "launcher-actions-rule", "kind": "row", "layout": {"height": 1}},
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
add_library(faset_build_service STATIC ${PROJECT_SOURCE_DIR}/src/editor/build_service.cpp)
|
||||
add_library(faset_build_service STATIC
|
||||
${PROJECT_SOURCE_DIR}/src/editor/build_service.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/editor/build_cache.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/editor/build_diagnostics.cpp)
|
||||
target_include_directories(faset_build_service PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||
target_compile_features(faset_build_service PUBLIC cxx_std_20)
|
||||
target_link_libraries(faset_build_service PUBLIC faset_core faset_scripting_project PRIVATE faset_assets faset_authoring Threads::Threads)
|
||||
if(BUILD_TESTING)
|
||||
add_executable(faset_build_diagnostics_tests ${PROJECT_SOURCE_DIR}/tests/build_diagnostics_tests.cpp)
|
||||
target_link_libraries(faset_build_diagnostics_tests PRIVATE faset_build_service)
|
||||
add_test(NAME build_diagnostics COMMAND faset_build_diagnostics_tests)
|
||||
add_executable(faset_build_cache_tests ${PROJECT_SOURCE_DIR}/tests/build_cache_tests.cpp)
|
||||
target_link_libraries(faset_build_cache_tests PRIVATE faset_build_service)
|
||||
target_compile_definitions(faset_build_cache_tests PRIVATE FASET_ENGINE_SOURCE="${PROJECT_SOURCE_DIR}")
|
||||
add_test(NAME build_cache COMMAND faset_build_cache_tests)
|
||||
add_executable(faset_build_service_tests ${PROJECT_SOURCE_DIR}/tests/build_service_tests.cpp)
|
||||
target_link_libraries(faset_build_service_tests PRIVATE faset_build_service faset_assets)
|
||||
target_compile_definitions(faset_build_service_tests PRIVATE FASET_ENGINE_SOURCE="${PROJECT_SOURCE_DIR}")
|
||||
@@ -13,5 +23,12 @@ if(BUILD_TESTING)
|
||||
target_link_libraries(faset_build_schema_tests PRIVATE faset_build_service faset_authoring faset_editor_commands)
|
||||
add_dependencies(faset_build_schema_tests faset_build_schema_tool)
|
||||
add_test(NAME build_schema_publication COMMAND faset_build_schema_tests $<TARGET_FILE:faset_build_schema_tool> ${PROJECT_SOURCE_DIR})
|
||||
set_tests_properties(build_schema_publication PROPERTIES TIMEOUT 60)
|
||||
# This fixture performs many full cache invalidations and process launches.
|
||||
# Windows runner startup and antivirus overhead exceed 60 seconds even when
|
||||
# individual native fixture commands finish normally.
|
||||
if(WIN32)
|
||||
set_tests_properties(build_schema_publication PROPERTIES TIMEOUT 240)
|
||||
else()
|
||||
set_tests_properties(build_schema_publication PROPERTIES TIMEOUT 60)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -47,5 +47,8 @@ if(TARGET faset_ui AND TARGET faset_editor_session AND TARGET faset_scene_view)
|
||||
set_tests_properties(editor_ui_gizmos PROPERTIES LABELS "gpu")
|
||||
add_test(NAME editor_ui_authoring COMMAND faset_editor_ui_tests)
|
||||
set_tests_properties(editor_ui_authoring PROPERTIES LABELS "gpu")
|
||||
add_executable(faset_editor_ui_latency ${PROJECT_SOURCE_DIR}/tests/editor_ui_latency.cpp)
|
||||
target_link_libraries(faset_editor_ui_latency PRIVATE faset_editor_ui)
|
||||
target_compile_definitions(faset_editor_ui_latency PRIVATE FASET_TEST_ENGINE="${PROJECT_SOURCE_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+1
-96
@@ -17,32 +17,6 @@ foreach(FASET_ENTRY vertexMain fragmentMain shadowMain)
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/baseline.slang" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py" VERBATIM)
|
||||
list(APPEND FASET_SHADER_OUTPUTS "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.reflection.json")
|
||||
endforeach()
|
||||
foreach(FASET_ENTRY temporalVertexMain temporalFragmentMain)
|
||||
set(FASET_SHADER_OUTPUT "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.spv")
|
||||
add_custom_command(OUTPUT "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.reflection.json"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py"
|
||||
--compiler "${SLANGC_EXECUTABLE}" --source "${PROJECT_SOURCE_DIR}/shaders/baseline.slang"
|
||||
--entry "${FASET_ENTRY}" --output "${FASET_SHADER_DIRECTORY}"
|
||||
BYPRODUCTS "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.slang-reflection.json"
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/baseline.slang" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py" VERBATIM)
|
||||
list(APPEND FASET_SHADER_OUTPUTS "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.reflection.json")
|
||||
endforeach()
|
||||
set(FASET_SHADER_OUTPUT "${FASET_SHADER_DIRECTORY}/gpuTemporalVertexMain.spv")
|
||||
add_custom_command(OUTPUT "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/gpuTemporalVertexMain.reflection.json"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py"
|
||||
--compiler "${SLANGC_EXECUTABLE}" --source "${PROJECT_SOURCE_DIR}/shaders/gpu_scene.slang"
|
||||
--entry gpuTemporalVertexMain --define FASET_GPU_GRAPHICS=1 --output "${FASET_SHADER_DIRECTORY}"
|
||||
BYPRODUCTS "${FASET_SHADER_DIRECTORY}/gpuTemporalVertexMain.slang-reflection.json"
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/gpu_scene.slang" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py" VERBATIM)
|
||||
list(APPEND FASET_SHADER_OUTPUTS "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/gpuTemporalVertexMain.reflection.json")
|
||||
set(FASET_SHADER_OUTPUT "${FASET_SHADER_DIRECTORY}/lightTileMain.spv")
|
||||
add_custom_command(OUTPUT "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/lightTileMain.reflection.json"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py"
|
||||
--compiler "${SLANGC_EXECUTABLE}" --source "${PROJECT_SOURCE_DIR}/shaders/light_tiles.slang"
|
||||
--entry lightTileMain --output "${FASET_SHADER_DIRECTORY}"
|
||||
BYPRODUCTS "${FASET_SHADER_DIRECTORY}/lightTileMain.slang-reflection.json"
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/light_tiles.slang" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py" VERBATIM)
|
||||
list(APPEND FASET_SHADER_OUTPUTS "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/lightTileMain.reflection.json")
|
||||
foreach(FASET_ENTRY gpuVertexMain gpuShadowMain gpuCullMain gpuHzbMain gpuPostCullMain)
|
||||
if(FASET_ENTRY STREQUAL "gpuVertexMain" OR FASET_ENTRY STREQUAL "gpuShadowMain")
|
||||
set(FASET_GPU_DEFINE FASET_GPU_GRAPHICS=1)
|
||||
@@ -60,76 +34,19 @@ foreach(FASET_ENTRY gpuVertexMain gpuShadowMain gpuCullMain gpuHzbMain gpuPostCu
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/gpu_scene.slang" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py" VERBATIM)
|
||||
list(APPEND FASET_SHADER_OUTPUTS "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.reflection.json")
|
||||
endforeach()
|
||||
foreach(FASET_ENTRY temporalResolveMain temporalCompositeVertexMain temporalCompositeFragmentMain)
|
||||
if(FASET_ENTRY STREQUAL "temporalResolveMain")
|
||||
set(FASET_TEMPORAL_DEFINE FASET_TEMPORAL_RESOLVE=1)
|
||||
else()
|
||||
set(FASET_TEMPORAL_DEFINE FASET_TEMPORAL_COMPOSITE=1)
|
||||
endif()
|
||||
set(FASET_SHADER_OUTPUT "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.spv")
|
||||
add_custom_command(OUTPUT "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.reflection.json"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py"
|
||||
--compiler "${SLANGC_EXECUTABLE}" --source "${PROJECT_SOURCE_DIR}/shaders/temporal.slang"
|
||||
--entry "${FASET_ENTRY}" --define "${FASET_TEMPORAL_DEFINE}" --output "${FASET_SHADER_DIRECTORY}"
|
||||
BYPRODUCTS "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.slang-reflection.json"
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/temporal.slang" "${PROJECT_SOURCE_DIR}/tools/compile_shader.py" VERBATIM)
|
||||
list(APPEND FASET_SHADER_OUTPUTS "${FASET_SHADER_OUTPUT}" "${FASET_SHADER_DIRECTORY}/${FASET_ENTRY}.reflection.json")
|
||||
endforeach()
|
||||
add_custom_command(OUTPUT "${FASET_SHADER_DIRECTORY}/compatibility.spv"
|
||||
COMMAND "${SLANGC_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/shaders/compatibility.hlsl"
|
||||
-entry compatibilityMain -stage compute -target spirv -profile spirv_1_6
|
||||
-o "${FASET_SHADER_DIRECTORY}/compatibility.spv"
|
||||
DEPENDS "${PROJECT_SOURCE_DIR}/shaders/compatibility.hlsl" VERBATIM)
|
||||
add_custom_target(faset_shaders DEPENDS ${FASET_SHADER_OUTPUTS} "${FASET_SHADER_DIRECTORY}/compatibility.spv")
|
||||
add_library(faset_render "${PROJECT_SOURCE_DIR}/src/render/renderer.cpp" "${PROJECT_SOURCE_DIR}/src/render/math.cpp" "${PROJECT_SOURCE_DIR}/src/render/render_graph.cpp" "${PROJECT_SOURCE_DIR}/src/render/shader_contract.cpp" "${PROJECT_SOURCE_DIR}/src/render/lighting.cpp" "${PROJECT_SOURCE_DIR}/src/render/temporal.cpp" "${PROJECT_SOURCE_DIR}/src/render/temporal_reference.cpp")
|
||||
add_library(faset_render "${PROJECT_SOURCE_DIR}/src/render/renderer.cpp" "${PROJECT_SOURCE_DIR}/src/render/math.cpp" "${PROJECT_SOURCE_DIR}/src/render/render_graph.cpp" "${PROJECT_SOURCE_DIR}/src/render/shader_contract.cpp")
|
||||
target_include_directories(faset_render PUBLIC "${PROJECT_SOURCE_DIR}/include")
|
||||
target_compile_features(faset_render PUBLIC cxx_std_20)
|
||||
target_link_libraries(faset_render PRIVATE Vulkan::Vulkan SDL3::SDL3 faset_core)
|
||||
target_compile_definitions(faset_render PRIVATE FASET_SHADER_DIRECTORY="${FASET_SHADER_DIRECTORY}")
|
||||
add_dependencies(faset_render faset_shaders)
|
||||
if(BUILD_TESTING)
|
||||
add_executable(faset_render_lighting_gpu_tests "${PROJECT_SOURCE_DIR}/tests/render_lighting_gpu_tests.cpp")
|
||||
target_link_libraries(faset_render_lighting_gpu_tests PRIVATE faset_render)
|
||||
add_test(NAME render_lighting_sun COMMAND faset_render_lighting_gpu_tests --sun)
|
||||
set_tests_properties(render_lighting_sun PROPERTIES LABELS "gpu;p3")
|
||||
add_test(NAME render_lighting_local COMMAND faset_render_lighting_gpu_tests --local)
|
||||
set_tests_properties(render_lighting_local PROPERTIES LABELS "gpu;p3")
|
||||
add_test(NAME render_lighting_tiled COMMAND faset_render_lighting_gpu_tests --tiled)
|
||||
set_tests_properties(render_lighting_tiled PROPERTIES LABELS "gpu;p3")
|
||||
add_executable(faset_render_lighting_policy_tests "${PROJECT_SOURCE_DIR}/tests/render_lighting_policy_tests.cpp")
|
||||
target_link_libraries(faset_render_lighting_policy_tests PRIVATE faset_render)
|
||||
add_test(NAME render_lighting_policy COMMAND faset_render_lighting_policy_tests)
|
||||
set_tests_properties(render_lighting_policy PROPERTIES LABELS "p3")
|
||||
add_executable(faset_render_temporal_graph_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_graph_tests.cpp")
|
||||
target_link_libraries(faset_render_temporal_graph_tests PRIVATE faset_render)
|
||||
add_test(NAME render_temporal_graph COMMAND faset_render_temporal_graph_tests)
|
||||
set_tests_properties(render_temporal_graph PROPERTIES LABELS "gpu")
|
||||
add_executable(faset_render_temporal_acceptance_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_acceptance_tests.cpp")
|
||||
target_link_libraries(faset_render_temporal_acceptance_tests PRIVATE faset_render)
|
||||
add_test(NAME render_temporal_acceptance COMMAND faset_render_temporal_acceptance_tests)
|
||||
set_tests_properties(render_temporal_acceptance PROPERTIES LABELS "gpu")
|
||||
add_test(NAME render_temporal_quality_matrix COMMAND
|
||||
"${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tests/test_temporal_quality_matrix.py"
|
||||
"$<TARGET_FILE:faset_render_temporal_acceptance_tests>")
|
||||
set_tests_properties(render_temporal_quality_matrix PROPERTIES LABELS "p3")
|
||||
add_executable(faset_render_temporal_shader_contract_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_shader_contract_tests.cpp")
|
||||
target_include_directories(faset_render_temporal_shader_contract_tests PRIVATE "${PROJECT_SOURCE_DIR}/src/render")
|
||||
target_link_libraries(faset_render_temporal_shader_contract_tests PRIVATE faset_render faset_core)
|
||||
target_compile_definitions(faset_render_temporal_shader_contract_tests PRIVATE FASET_TEST_SHADER_DIRECTORY="${FASET_SHADER_DIRECTORY}")
|
||||
add_test(NAME render_temporal_shader_contract COMMAND faset_render_temporal_shader_contract_tests)
|
||||
add_executable(faset_render_temporal_reference_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_reference_tests.cpp")
|
||||
target_link_libraries(faset_render_temporal_reference_tests PRIVATE faset_render)
|
||||
add_test(NAME render_temporal_reference COMMAND faset_render_temporal_reference_tests)
|
||||
add_executable(faset_render_temporal_lifecycle_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_lifecycle_tests.cpp")
|
||||
target_link_libraries(faset_render_temporal_lifecycle_tests PRIVATE faset_render)
|
||||
add_test(NAME render_temporal_lifecycle COMMAND faset_render_temporal_lifecycle_tests)
|
||||
set_tests_properties(render_temporal_lifecycle PROPERTIES LABELS "gpu")
|
||||
add_executable(faset_render_temporal_motion_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_motion_tests.cpp")
|
||||
target_link_libraries(faset_render_temporal_motion_tests PRIVATE faset_render)
|
||||
add_test(NAME render_temporal_motion COMMAND faset_render_temporal_motion_tests)
|
||||
add_executable(faset_render_temporal_policy_tests "${PROJECT_SOURCE_DIR}/tests/render_temporal_policy_tests.cpp")
|
||||
target_link_libraries(faset_render_temporal_policy_tests PRIVATE faset_render)
|
||||
add_test(NAME render_temporal_policy COMMAND faset_render_temporal_policy_tests)
|
||||
add_executable(faset_render_tests "${PROJECT_SOURCE_DIR}/tests/render_tests.cpp")
|
||||
target_link_libraries(faset_render_tests PRIVATE faset_render SDL3::SDL3)
|
||||
add_test(NAME render_graph COMMAND faset_render_tests --unit)
|
||||
@@ -161,17 +78,5 @@ if(BUILD_TESTING)
|
||||
target_link_libraries(faset_render_window_tests PRIVATE faset_render SDL3::SDL3)
|
||||
add_test(NAME render_window_lifecycle COMMAND faset_render_window_tests "${CMAKE_BINARY_DIR}/window-test")
|
||||
set_tests_properties(render_window_lifecycle PROPERTIES LABELS "gpu;window" TIMEOUT 40 SKIP_RETURN_CODE 77)
|
||||
add_executable(faset_p3_lighting_benchmark
|
||||
"${PROJECT_SOURCE_DIR}/examples/renderer/p3_lighting_benchmark.cpp")
|
||||
target_link_libraries(faset_p3_lighting_benchmark PRIVATE faset_render faset_core)
|
||||
target_compile_definitions(faset_p3_lighting_benchmark PRIVATE
|
||||
FASET_BENCHMARK_CONFIGURATION="$<CONFIG>")
|
||||
add_test(NAME render_lighting_benchmark_schema COMMAND
|
||||
"${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tests/test_p3_lighting_benchmark.py")
|
||||
set_tests_properties(render_lighting_benchmark_schema PROPERTIES LABELS "p3" TIMEOUT 90)
|
||||
add_test(NAME render_lighting_benchmark_smoke COMMAND
|
||||
"${Python3_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tests/test_p3_lighting_benchmark.py"
|
||||
--real-executable "$<TARGET_FILE:faset_p3_lighting_benchmark>")
|
||||
set_tests_properties(render_lighting_benchmark_smoke PROPERTIES LABELS "gpu;p3" TIMEOUT 90)
|
||||
endif()
|
||||
install(FILES ${FASET_SHADER_OUTPUTS} DESTINATION shaders)
|
||||
|
||||
+37
-1
@@ -1,6 +1,6 @@
|
||||
# Faset Engine — архитектура
|
||||
|
||||
Редакция 1.2 · 23 сентября 2026 · **MVP принят; реализация P2 описана отдельно от исходных решений**.
|
||||
Редакция 1.3 · 24 сентября 2026 · **MVP принят; реализация P1/P2 описана отдельно от исходных решений**.
|
||||
|
||||
Этот файл фиксирует решения пользователя. **Принято** означает выбранное направление реализации, а не автоматически завершённую возможность движка. Работающий код, выполненные проверки и текущие ограничения перечислены в [журнале реализации](IMPLEMENTATION.md). Этапы до MVP и после него, зависимости работ и критерии готовности находятся в [PLAN.md](../PLAN.md).
|
||||
|
||||
@@ -111,6 +111,41 @@ Development и release Player содержат runtime, выбранные иг
|
||||
|
||||
Критерии [плана](../PLAN.md) включают цикл сцена → Inspector → MCP authoring edit → Undo → save → build → отдельный Player, повторный импорт GLB с сохранением overrides, lifecycle/handle tests и запуск на обеих ОС без Editor/Blender/MCP/SDK. Выполненные проверки и незакрытые условия перечислены в [журнале реализации](IMPLEMENTATION.md); наличие теста само по себе не означает прохождения на обеих ОС.
|
||||
|
||||
## 10. P1 — проверяемая итерация gameplay
|
||||
|
||||
Для native-сборки источником истины остаются CMake/Ninja и их dependency graph.
|
||||
BuildService сохраняет проверяемую копию `Scripts` по хешу содержимого,
|
||||
отделяет Debug от Release и
|
||||
запоминает версионированный fingerprint рецепта, исходников, Lua-деклараций,
|
||||
toolchain, шейдерных и runtime-входов. Повторное использование schema/package
|
||||
разрешено лишь после проверки полного manifest и схемы; испорченная или устаревшая
|
||||
генерация не выдаётся за cache hit. Переключение указателя на успешную генерацию
|
||||
атомарно; сбой сборки оставляет предыдущую доступной, но Inspector помечает
|
||||
метаданные устаревшими. Исходный каталог и копия повторно хешируются после native
|
||||
build и перед повторным использованием кэша или публикацией. Это обнаруживает сохранившееся изменение;
|
||||
запись и восстановление прежних байтов другим процессом того же пользователя во
|
||||
время чтения компилятором не исключены. Экспорт отдельно проверяет asset generations.
|
||||
|
||||
Структурированные сообщения компилятора/Lua дополняют сырой лог. Для исходников
|
||||
проекта Editor и MCP вызывают один `faset_source_open` с относительным путём и
|
||||
позициями; внешний редактор запускается аргументами без shell. Четыре стартовых
|
||||
проекта комбинируют C++/Lua и 2D/3D. C++ остаётся rebuild-and-restart, а Lua
|
||||
development reload проверяет candidate и перезапускает script/world state, не
|
||||
сохраняя произвольное runtime-состояние.
|
||||
|
||||
Autosave относится только к именованным dirty сценам Editor после двух секунд
|
||||
покоя. Он использует ревизию документа и прежний disk-hash conflict check, не
|
||||
перезаписывает внешний файл и не создаёт Undo-операцию. Неназванная сцена требует
|
||||
Save As; recovery journal работает независимо от autosave. Статусы видны в UI и
|
||||
через Editor MCP. Player и экспортная игра по-прежнему не имеют MCP.
|
||||
|
||||
Измерения P1 разделяют Debug-время итераций, offscreen первый кадр и старый
|
||||
Release reference baseline точных демо. Исходный отчёт, raw-профили и отдельное
|
||||
дополнение о версиях/хешах исполняемых инструментов находятся в
|
||||
[датированном dossier](validation/p1-iteration-2026-09-24/README.md). Большая
|
||||
синтетическая сцена выявляет стоимость CPU simulation/snapshot; её время нельзя
|
||||
переносить на 2D/3D демо или выдавать за обещание кадровой частоты.
|
||||
|
||||
## История решений
|
||||
|
||||
- **17.09.2026:** выбраны имя Faset Engine, Linux/Windows desktop 2D/3D, ручная работа и MCP, интеграция с Blender, Box2D и Box3D; подготовлены исследования.
|
||||
@@ -118,5 +153,6 @@ Development и release Player содержат runtime, выбранные иг
|
||||
- **18.09.2026:** утверждены процессы и linkage, явная metadata registration/schema export, JSON/binary formats, вложенные шаблоны/sparse overrides, lifecycle, фиксированный tick и последовательный scheduler; граница MCP ограничена Editor/headless authoring services.
|
||||
- **18.09.2026:** английский принят основным языком интерфейса, диагностик и публичного API; уточнена граница прямых Vulkan-вызовов внутри собственного backend.
|
||||
- **23.09.2026:** после принятого MVP выполнен P2 GPU visibility/LOD на Linux reference GPU; direct renderer сохранён как начальный режим и эталон, ограничения и измерения вынесены в отдельный [протокол](studies/19-p2-gpu-visibility-acceptance.md).
|
||||
- **24.09.2026:** P1 итерация фиксирует проверяемое повторное использование schema/package, структурированную диагностику, стартовые C++/Lua проекты, безопасный autosave и измерительный протокол без C++ hot reload.
|
||||
|
||||
Реализация идёт по [PLAN.md](../PLAN.md). Последующие изменения принятых контрактов фиксируются здесь с причиной и способом проверки.
|
||||
|
||||
+48
-40
@@ -467,47 +467,55 @@ rendered 120 frames in Direct mode. The corresponding
|
||||
passed on Linux and Windows. Unsupported-HZB integration and physical Windows
|
||||
GPU coverage remain untested.
|
||||
|
||||
## P3 lighting checkpoint — authored lights and bounded shadow views
|
||||
## Post-MVP checkpoint — P1 gameplay iteration
|
||||
|
||||
At source revision `b191ae0`, the versioned `faset.light` schema and SceneView
|
||||
extract directional, point, and spot lights. Any authored Light, even disabled,
|
||||
suppresses the compatibility sun; scenes without a Light keep their previous
|
||||
appearance. The renderer validates all local records, then selects at most 128
|
||||
by priority, projected influence, and stable ID. A single typed lighting
|
||||
descriptor ABI serves Direct and P2 GPU graphics: materials remain set 0,
|
||||
lighting is set 1, GPU scene graphics data moves to set 2, and existing push
|
||||
constant sizes remain unchanged. Both paths shade the same sun/local PBR lights
|
||||
before tone mapping.
|
||||
P1 adds a complete-input native build stamp and a content-addressed `Scripts` copy.
|
||||
The package key binds configuration, recipe, source, Lua declaration, toolchain,
|
||||
shader and runtime artifacts. A second unchanged build reuses a verified schema
|
||||
and package generation without invoking SchemaExporter; CMake/Ninja still verify
|
||||
the native graph. Malformed/corrupt generations, modified headers/tools and
|
||||
detected source mismatches cannot publish a false hit. The live tree and staged
|
||||
copy are rehashed after native build and before reuse/publication; a same-user
|
||||
write-and-restore during compiler reads remains outside this check. Failed jobs
|
||||
preserve the previous successful pointer, while Inspector metadata becomes stale.
|
||||
|
||||
A pure CPU shadow planner builds up to four texel-snapped sun cascades from an
|
||||
explicit camera frustum, ending at at most 80 world units; a low-level Snapshot
|
||||
without the frustum keeps one shadow view. Shadow caster bounds come from the
|
||||
source LOD-0 draw and are tested against the light view, independently of
|
||||
camera/P2 culling. The Vulkan backend renders the sun to its own D32 atlas and
|
||||
point/spot shadows to a separate 4×4 D32 atlas. A point light claims six faces
|
||||
atomically, a spot one. Both atlases try 2048² and then 1024² if required by
|
||||
capabilities or allocation. The combined frame budget is 4096 caster draws;
|
||||
scheduled tiles are cleared and redrawn each frame. Overflow, disabled shadow,
|
||||
or unavailable atlas leaves a submitted light illuminating without shadow.
|
||||
There is no hidden sun raster when the sun is absent, its shadow is disabled, or
|
||||
the scene only has sprites. Atlas ownership, dropout, submitted light counts,
|
||||
actual raster work and GPU timings are exposed in `FrameStats`, Player profiles
|
||||
and the optional Editor diagnostics overlay.
|
||||
Compiler and Lua output now produce bounded structured Console diagnostics with
|
||||
raw logs retained. Source opening accepts only project `Scripts` files and passes
|
||||
literal file/line/column arguments to the configured external editor. A real
|
||||
compile failure revealed that compiler paths pointed to the staged copy;
|
||||
`d7a7a7c` maps only the verified snapshot subtree back to project-relative
|
||||
source. The same correction retains a later actionable error after 250 unrelated
|
||||
warnings. Four runnable C++/Lua × 2D/3D starters are available in launcher and
|
||||
CLI; the existing scaffold default remains compatible. Named dirty scenes
|
||||
autosave after two idle seconds by default; unnamed scenes require Save As, and
|
||||
disk/revision conflicts retain the journal and never overwrite external edits.
|
||||
|
||||
The implementation's Linux Debug checkpoint at `a5fb216` built all targets and
|
||||
ran 60 CTests with no failures; the existing native window lifecycle test
|
||||
skipped under the compositor. The optional ImGui overlay passed its dedicated
|
||||
test in an enabled build. After benchmark integration at `b191ae0`, six focused
|
||||
tests passed, including the real Vulkan benchmark smoke. These are bounded
|
||||
checks, not a final P3 acceptance run. The [lighting validation record](validation/p3-lighting-2026-09-24/README.md)
|
||||
lists cases, exact revision, and remaining Windows/Release evidence.
|
||||
The [P1 dated dossier](validation/p1-iteration-2026-09-24/README.md) retains a
|
||||
clean-revision `6c2e8fa` Debug workflow with every raw command/profile. On the
|
||||
Ryzen 7 1700/RTX 2080 Ti Linux host, five unchanged builds had median 11.53 s,
|
||||
five changed-C++ builds 28.16 s, five changed-header builds 23.89 s, and five
|
||||
watched Lua reloads 0.502 s. All five unchanged builds reported a verified
|
||||
generation reuse. The 3,000-frame profile showed no growth in the explicit
|
||||
Vulkan allocation counter (15,787,008 bytes). A seeded 527-object synthetic
|
||||
scene reached 149.39 ms p95 wall time, dominated by CPU simulation/snapshot;
|
||||
this is a visible scalability issue, not a tiny-demo Release budget comparison.
|
||||
The historical exact-scene Release budgets were met in the earlier 2026-09-18
|
||||
record, but that evolving working-tree baseline does not certify the current
|
||||
revision. A quiet-host current Release rerun is pending.
|
||||
|
||||
The fixed-scene Release reference-GPU sweep uses 1920×1080, 0/4/16/32/64/128
|
||||
lights, Direct/GPU frustum/GPU occlusion, shadows on/off, three independent
|
||||
repeats, ten warm-up and thirty measured frames per configuration. It reached
|
||||
the agreed Forward+ gate: main-raster overhead at 32 lights was about 0.50 ms
|
||||
relative to the matching zero-light case, roughly 30% of that GPU frame;
|
||||
64 and 128 lights added about 1.02 and 2.03 ms. Its raw CSV/report are being
|
||||
published separately with the exact benchmark revision and driver. A 16×16
|
||||
tiled Forward+ path, image parity and before/after build+raster measurement are
|
||||
therefore pending. Temporal reconstruction is developed and accepted separately.
|
||||
Linux focused cache, diagnostics, schema and workflow-math tests pass; a real
|
||||
failed-build replay now reports navigable `Scripts/Gameplay.cpp:73:2`. The
|
||||
[Lua-only Release result](validation/lua-release-2026-09-24/README.md) validated
|
||||
and rendered after source-hidden relocation on the physical Linux GPU. At
|
||||
`6c2e8fa`, [native/manual CI](https://github.com/emil28092005/Faset_Engine/actions/runs/35936310287)
|
||||
passed on Linux and Windows. Its Windows graphics job passed all 61 CTests on
|
||||
SwiftShader, then hit an invalid integration fixture under the engine checkout;
|
||||
`4ac02ee` moved the fixture to runner temporary storage. The subsequent
|
||||
[Windows graphics run](https://github.com/emil28092005/Faset_Engine/actions/runs/35937433040)
|
||||
passed all 61 CTests and the real export integration. Two C++ and one Lua-only
|
||||
Release package validated and rendered 120 frames each after relocation with
|
||||
source paths unavailable; the [raw Windows report](validation/p1-iteration-2026-09-24/windows-4ac02ee/playable-report.json)
|
||||
records hashes and software Vulkan device identity. The later `d7a7a7c`
|
||||
real-diagnostic-navigation assertion still awaits its Windows CI result.
|
||||
Windows had no active Khronos validation layer, and no physical Windows GPU
|
||||
performance result is claimed.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB |
@@ -1,5 +1,28 @@
|
||||
# Developer diagnostics
|
||||
|
||||
## Build errors and source navigation
|
||||
|
||||
Build and export jobs report compiler, clang-cl/MSVC, and Lua errors as structured
|
||||
Console rows. Each row shows severity, message, and a one-based source location.
|
||||
Choose **Open source** to open a file under the current project's `Scripts/`
|
||||
directory at that line and column. Diagnostics from engine or external files remain
|
||||
visible but have no source action. The **Jobs** tab shows whether a verified build
|
||||
generation was reused, the elapsed phases, and an expandable raw process log;
|
||||
**Copy full log** retains the complete available output for troubleshooting.
|
||||
|
||||
The same action is available over Editor MCP:
|
||||
|
||||
```json
|
||||
{"command":"faset_source_open","arguments":{"path":"Scripts/Gameplay.cpp","line":17,"column":4}}
|
||||
```
|
||||
|
||||
`faset_script_open` remains Lua-only. Both commands use the project's optional
|
||||
`editor.script_editor` argv array, or Zed by default. The tokens `{file}`,
|
||||
`{line}`, `{column}`, and `{project}` may appear within one argument, for
|
||||
example `["zed", "{file}:{line}:{column}"]`. Faset passes each argument
|
||||
literally to the editor process without shell expansion. An invalid editor
|
||||
command produces a source-editor error without changing the build result.
|
||||
|
||||
The optional Dear ImGui overlay shows renderer counters inside the Editor. The Editor's normal interface remains the retained Faset UI. Enable the diagnostic build explicitly:
|
||||
|
||||
```sh
|
||||
@@ -12,37 +35,11 @@ On Windows, use `windows-debug` for both presets and `build/windows-debug/faset_
|
||||
|
||||
Use the **Visibility** selector to compare **Direct**, **GPU frustum**, and **GPU occlusion** on the same open scene. This is a live renderer setting for the Editor viewport; it does not change the scene or exported game. The selected mode is independent of **Freeze counters**. The counters describe the previous completed frame, so render one more frame after changing modes before reading them. **Effective path** names the algorithm that actually ran. A **Fallback from** line appears when device or target capabilities prevent the selected mode; for example, GPU occlusion may use GPU frustum if HZB is unavailable.
|
||||
|
||||
Use the **Temporal** selector for **Off**, **TAA**, or **Upscale**. Upscale shows a
|
||||
50–99% render-scale slider; output UI remains sharp. The requested/effective
|
||||
mode, fallback reason, internal extent, history reset reason and temporal GPU
|
||||
pass times are shown separately from visibility and HZB history. This selector
|
||||
only changes the live Editor viewport. See [Temporal rendering](temporal.md).
|
||||
|
||||
The panel reports the previous completed frame: renderer wall time, GPU timestamp time where available, synchronous readback time, draw calls, packed vertices, culled meshes, textures, explicit Vulkan allocation sizes, actual validation availability/errors, and GPU pass-label count. It also shows whether GPU visibility ran, submitted indirect bins, visible instances, frustum rejects, deferred and post-pass visible instances, HZB history validity, counts per prepared LOD level, and GPU pass timings where available. GPU counts are explicitly marked unavailable until the first frame rendered with diagnostics open; only a displayed zero is a measured zero. **Previous HZB history: invalid** is expected after a camera cut or resize until compatible depth history is available. A current HZB preview can still exist after that first frame because it was built from the current depth. Renderer wall time includes waiting for GPU work; it is not thread CPU usage. Memory excludes driver-internal allocations. The overlay itself adds drawing work, so hide it for a baseline performance measurement.
|
||||
|
||||
In **GPU occlusion** mode, enable **Show HZB** to inspect the current grayscale depth pyramid. The **Mip** slider selects a pyramid level; the preview starts at mip 3 to keep its readback small. A larger mip number shows coarser depth. The preview reads the HZB only while the panel and toggle are open, and only once per completed frame or mip change. Switching it off or closing the panel releases the preview; its GPU texture retires when the next frame begins. Opening diagnostics also enables readback of GPU visibility counters, which is disabled again when the panel closes. Disable the HZB preview for performance comparisons: its diagnostic copy and texture upload add GPU and CPU work. **Freeze counters** does not freeze the HZB image.
|
||||
|
||||
The **Lighting and shadows** section reports the actual local lights submitted
|
||||
and omitted, requested/effective sun cascades, requested/rasterized local faces,
|
||||
allocated local tiles, and shadow caster draws against the 4096-draw limit.
|
||||
Dropped-face counters distinguish a full atlas, caster budget, and unavailable
|
||||
atlas; `point` counts faces dropped as a complete six-face group. A light whose
|
||||
shadow faces are dropped still illuminates without a shadow. Atlas memory is the
|
||||
live explicit Vulkan allocation size for the separate sun and local atlases.
|
||||
When GPU timestamps are available, the panel shows sun and local shadow pass
|
||||
durations. A zero duration after a disabled sun or sprite-only frame confirms
|
||||
that no sun shadow raster ran. The lighting path names the algorithm actually
|
||||
used, so compare it with a benchmark's requested mode before interpreting costs.
|
||||
See [Lighting](lighting.md) for the 128-light and 16-tile limits.
|
||||
|
||||
The Vulkan backend emits `VK_EXT_debug_utils` labels for `SunShadowAtlas`,
|
||||
`LocalShadowAtlas`, `ForwardAndUI`, `Readback`, and, when presenting,
|
||||
`Presentation`. A fallback frame can have no shadow-raster label. A graphics
|
||||
capture tool that supports this extension can identify the command-buffer
|
||||
regions. Labels remain available without the Khronos validation layer when
|
||||
the extension is exposed; unsupported systems continue rendering and report
|
||||
labels unavailable. A submitted-label count confirms calls were emitted, not
|
||||
that an external capture tool was tested.
|
||||
The Vulkan backend emits `VK_EXT_debug_utils` labels for `ShadowMap`, `ForwardAndUI`, `Readback`, and, when presenting, `Presentation`. A graphics capture tool that supports this extension can identify those command-buffer regions. Labels remain available without the Khronos validation layer when the extension is exposed; unsupported systems continue rendering and report labels unavailable. A submitted-label count confirms calls were emitted, not that an external capture tool was tested.
|
||||
|
||||
This module is disabled by default and is linked only to the graphical Editor and its dedicated test when enabled. Player and exported games do not link ImGui. No overlay control changes authoring documents, gameplay state or export settings.
|
||||
|
||||
|
||||
@@ -9,8 +9,10 @@ Player process. **Stop** leaves the authoring document unchanged.
|
||||
|
||||
1. Edit `Scripts/Gameplay.cpp` and its explicit schema declarations.
|
||||
2. Stop the running Player.
|
||||
3. Choose **Build C++**. The compiler and SchemaExporter run outside the Editor.
|
||||
4. Read compiler errors in the Console. A failed build retains the previous schema
|
||||
3. Choose **Build**. CMake/Ninja build native gameplay and the separate
|
||||
SchemaExporter refreshes the Inspector schema when inputs changed.
|
||||
4. Read compiler errors in the Console. Select a project-source diagnostic to open
|
||||
its line in your external editor. A failed build retains the previous schema
|
||||
and binary; the schema status reports that it is stale.
|
||||
5. After a successful build, edit the behavior's exposed fields in the Inspector.
|
||||
6. Choose **Play**. It builds if necessary and launches the captured scene.
|
||||
@@ -23,6 +25,22 @@ The Player supports pause and single-step. Editor controls use a private session
|
||||
control file; they do not expose runtime entity queries through MCP. Closing the
|
||||
Player is observed by the Editor, which keeps its logs and authoring state.
|
||||
|
||||
An unchanged second build still asks CMake/Ninja to verify their dependency graph.
|
||||
When the native outputs, gameplay sources, toolchain, shaders and runtime inputs
|
||||
match the validated package, **Jobs** reports `schema_cache_hit` and
|
||||
`generation_reused` as true and returns the same verified generation without a
|
||||
second SchemaExporter run or package copy. A changed `.cpp`, header, Lua declaration,
|
||||
build recipe or relevant tool invalidates that reuse. A damaged cached package is
|
||||
not treated as a hit. The job also exposes elapsed phases and a build fingerprint;
|
||||
see [Developer diagnostics](diagnostics.md) for structured errors and raw logs.
|
||||
|
||||
If a build fails, correct the listed source and build again. The prior playable
|
||||
generation remains available, but stale Inspector metadata is not evidence that
|
||||
the failed edit built successfully. Save the scene separately: named dirty scenes
|
||||
autosave after two idle seconds by default, while an unnamed scene needs **Save As**.
|
||||
External file changes produce a visible conflict instead of an overwrite; the
|
||||
[workspace guide](workspace.md#create-and-save-a-scene) explains recovery.
|
||||
|
||||
## Export a standalone game
|
||||
|
||||
Use **Export** in the Editor for the current scene. Resolve template conflicts and
|
||||
@@ -46,9 +64,10 @@ Development builds use **Debug**. Exports default to **Release** and use a separ
|
||||
CMake cache. The BuildService API also accepts `RelWithDebInfo` for exports. Exporting
|
||||
does not change the configuration of your development Player.
|
||||
|
||||
Each successful export creates an immutable directory under
|
||||
Each successful export creates a versioned directory under
|
||||
`Exports/MyGame/generations/<generation>`. `current.json` points to the active
|
||||
generation. Distribute the **whole generation directory**, not just the executable.
|
||||
generation. The Editor leaves published generations untouched. Distribute the
|
||||
**whole generation directory**, not just the executable.
|
||||
If building, cooking or verification fails, the previous pointer and package remain
|
||||
available. Cancelling a job does not delete earlier exports.
|
||||
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
# Light a 3D scene
|
||||
|
||||
Select an entity in the **Scene** tree, choose **+ Add Component** in the
|
||||
**Inspector**, and add **Light**. Its Transform places a point or spot light. A
|
||||
spot light points along the entity's local negative Z axis; a directional light
|
||||
uses the entity's orientation. Lights affect 3D meshes in linear PBR shading
|
||||
before tone mapping. Sprites and Editor UI remain unlit.
|
||||
|
||||
| Light kind | Coverage | Shadow cost |
|
||||
| --- | --- | --- |
|
||||
| `directional` | A sun-like direction, independent of position | Up to four cascade tiles |
|
||||
| `point` | All directions within `range` | Six local-atlas tiles, assigned together |
|
||||
| `spot` | A cone within `range` | One local-atlas tile |
|
||||
|
||||
The Light component's fields are:
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `kind` | `directional` | `directional`, `point`, or `spot` |
|
||||
| `enabled` | `true` | A disabled light contributes no illumination |
|
||||
| `color` | `[1, 1, 1, 1]` | RGB illumination color; alpha is part of the schema color value |
|
||||
| `intensity` | `1` | Nonnegative brightness |
|
||||
| `range` | `10` | Positive reach of point and spot lights |
|
||||
| `inner_angle` | `0.35` | Full-strength spot cone half-angle, in radians |
|
||||
| `outer_angle` | `0.7` | Outer spot cone half-angle, in radians; must be at least `inner_angle` |
|
||||
| `casts_shadow` | `true` | Allow this light to use its shadow atlas |
|
||||
| `shadow_priority` | `0` | Higher local-light selection and shadow priority; does not change brightness |
|
||||
|
||||
The Inspector validates the spot angles together. Their allowed outer limit is
|
||||
below π/2 radians. A point light does not depend on the entity's rotation.
|
||||
After editing the light or Transform, save the scene as usual. [Editor
|
||||
workspace](workspace.md) explains Inspector editing, Undo, and save conflicts.
|
||||
|
||||
## Sun shadows and compatibility
|
||||
|
||||
With a 3D scene camera, a shadow-casting directional light uses four cascades
|
||||
covering the camera near plane through at most **80 world units**, or the camera
|
||||
far plane if it is closer. Faset blends samples near cascade splits and snaps
|
||||
each shadow projection to texels to reduce shimmer during small camera moves.
|
||||
Objects outside the camera view can still cast into a visible receiver: shadow
|
||||
visibility uses each light's view and the source mesh's LOD 0, separately from
|
||||
the main camera's Direct or GPU visibility result. A low-level renderer Snapshot
|
||||
without an explicit camera frustum uses one compatibility sun view.
|
||||
|
||||
Only one enabled directional light is used. If there are several, Faset chooses
|
||||
the one with the smallest stable entity ID and reports the ignored lights. A
|
||||
scene with **no Light component** retains the older white sun. Adding any Light
|
||||
component, including a disabled one, suppresses that compatibility sun. Thus a
|
||||
local-only scene does not receive an unexpected directional light.
|
||||
|
||||
## Local shadow capacity and fallbacks
|
||||
|
||||
The renderer accepts at most **128** local lights per frame. It sorts candidates
|
||||
by `shadow_priority` (highest first), then projected influence, then stable ID.
|
||||
The `omitted_local_lights` counter reports lights beyond this limit; an omitted
|
||||
light contributes no illumination. All authored light records are validated,
|
||||
including candidates past the limit.
|
||||
|
||||
The separate local shadow atlas has **16 tiles**. A spot consumes one; a point
|
||||
consumes six or none. Sun cascades and local shadows share a maximum of **4096
|
||||
caster draws** per frame. A light whose shadow group does not fit the remaining
|
||||
tiles or draw budget still illuminates, **without a shadow**. Disabling
|
||||
`casts_shadow` also keeps illumination while skipping that light's shadow work.
|
||||
The renderer reports requested faces, rendered faces, tiles, and drops by cause
|
||||
in [Diagnostics](diagnostics.md) and the [Player profile](profiling.md).
|
||||
|
||||
Faset uses separate sampled D32 sun and local atlases, normally 2048×2048 pixels
|
||||
each. If a device cannot use that size, the renderer tries 1024×1024; if a
|
||||
sampled depth atlas cannot be created, the affected lights fall back to unshadowed
|
||||
illumination and report unavailable shadow views. Scheduled atlas tiles are
|
||||
cleared and redrawn each frame; there is no persistent shadow cache yet.
|
||||
Sprite-only scenes, a missing sun, and a sun with `casts_shadow: false` skip sun
|
||||
shadow raster work.
|
||||
|
||||
## Add a point light through MCP
|
||||
|
||||
MCP edits the **Editor document**, not entities in a running game. Use
|
||||
`faset_schema` to inspect the current field IDs, then send a `faset_scene_edit`
|
||||
batch with the document ID, its current revision, and a target entity ID:
|
||||
|
||||
```json
|
||||
{
|
||||
"document": "REPLACE_WITH_DOCUMENT_ID",
|
||||
"revision": 4,
|
||||
"idempotency_key": "add-red-point-light",
|
||||
"operations": [{
|
||||
"op": "component.add",
|
||||
"entity": "REPLACE_WITH_ENTITY_ID",
|
||||
"type": "faset.light",
|
||||
"fields": {
|
||||
"kind": "point",
|
||||
"color": [1, 0.15, 0.1, 1],
|
||||
"intensity": 8,
|
||||
"range": 6,
|
||||
"shadow_priority": 2
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
Move the entity with its Transform component. `component.add` fills omitted
|
||||
fields from the schema; `component.set` changes an existing field. Save the
|
||||
document with `faset_document_save`. [MCP and command line](mcp.md) covers
|
||||
revisions, retries, and transactions.
|
||||
|
||||
## Supply lights directly from C++
|
||||
|
||||
Code that constructs a renderer `faset::render::Snapshot` can supply lights
|
||||
directly. Set `authored_lights_present` even when the only authored Light is
|
||||
disabled, so the renderer does not synthesize the compatibility sun. Use stable,
|
||||
unique IDs for deterministic capacity decisions:
|
||||
|
||||
```cpp
|
||||
faset::render::Snapshot snapshot;
|
||||
snapshot.authored_lights_present = true;
|
||||
|
||||
faset::render::LocalLight point;
|
||||
point.kind = faset::render::LocalLight::Kind::Point;
|
||||
point.stable_id = "level/torch";
|
||||
point.position = {-2, 1.5f, 0};
|
||||
point.color = {1, 0.3f, 0.1f, 1};
|
||||
point.intensity = 8;
|
||||
point.range = 6;
|
||||
point.shadow_priority = 2;
|
||||
snapshot.local_lights.push_back(point);
|
||||
|
||||
faset::render::LocalLight spot;
|
||||
spot.kind = faset::render::LocalLight::Kind::Spot;
|
||||
spot.stable_id = "level/lamp";
|
||||
spot.position = {2, 3, 0};
|
||||
spot.direction = {0, -1, 0};
|
||||
spot.inner_angle = 0.25f;
|
||||
spot.outer_angle = 0.55f;
|
||||
spot.intensity = 5;
|
||||
spot.range = 9;
|
||||
snapshot.local_lights.push_back(spot);
|
||||
```
|
||||
|
||||
This is the **renderer Snapshot API**, not a gameplay `Update()` method. The
|
||||
current gameplay scripting API does not expose live Light-component creation or
|
||||
modification; author lights in the Inspector or through Editor MCP. See
|
||||
[Gameplay scripting](../scripting/index.md) for the APIs available to game code.
|
||||
@@ -67,6 +67,20 @@ resume and single-step process controls; it cannot read or modify game entities.
|
||||
scenes that have never been saved. Restoring an already open document requires its
|
||||
current revision. Recovery refuses to overwrite an externally changed scene file.
|
||||
|
||||
Long-lived headless and graphical Editor sessions also poll the same autosave
|
||||
controller. With `editor.autosave` enabled (the default), a named dirty scene is
|
||||
saved after two seconds idle. `faset_autosave_status {}` reports `enabled` and each
|
||||
open document's `state`, `revision`, `path`, and `error`. States include `saved`,
|
||||
`pending`, `saving`, `conflict`, `failed`, `save_as_required`, and `disabled`.
|
||||
An unnamed scene remains in recovery until you give it an explicit path. An
|
||||
external disk edit produces `conflict` without overwriting that edit. For scripted
|
||||
workflows, use `faset_document_save` with `expected_revision` when you need a
|
||||
definite save boundary instead of waiting for idle autosave. If a conflict occurs,
|
||||
save to a new project-relative path and compare the two files. Change the
|
||||
preference through `faset_project_settings_get` and `faset_project_settings_set`
|
||||
with the returned project revision and `{"editor":{"autosave":false}}`; the
|
||||
new value applies to the current session and persists for the next Editor launch.
|
||||
|
||||
## Single-command CLI
|
||||
|
||||
The CLI is useful for scripts that do not need an MCP session:
|
||||
|
||||
@@ -39,29 +39,58 @@ Use `--debug-physics` or press **F3** to show current physics box colliders. Deb
|
||||
geometry increases draw count, so record whether it was enabled. The collider view
|
||||
uses simulation poses; normal visuals can use interpolated poses.
|
||||
|
||||
## Measure Editor and C++ workflows
|
||||
## Measure Editor, C++ and Lua iteration
|
||||
|
||||
From the engine repository:
|
||||
|
||||
```sh
|
||||
cmake --build --preset linux-debug --target faset_editor faset_editor_ui_latency --parallel 2
|
||||
python3 tools/measure_workflows.py \
|
||||
--editor build/linux-debug/faset_editor \
|
||||
--project examples/projects/collect-3d \
|
||||
--output .cache/my-workflow-measurement
|
||||
--output /tmp/faset-workflow-measurement
|
||||
```
|
||||
|
||||
Use a new output directory. The tool copies the project, preserving your original,
|
||||
and records command startup, two-frame GUI startup/shutdown, first/cached Blender
|
||||
bundle import, initial/no-change/changed Debug builds and a subsequent Player frame.
|
||||
It checks that editing gameplay makes the schema stale and successful building
|
||||
clears that state. The initial build uses available dependency archives and OS
|
||||
caches; it is not a measurement of internet download speed.
|
||||
The UI probe must be built beside the Editor first. The default Lua input is
|
||||
`examples/lua`; use `--lua-project` to select another declared Lua project and
|
||||
`--ui-latency-binary` when the probe is elsewhere. Use a **new** output directory;
|
||||
the tool refuses to overwrite evidence. It copies both projects and never edits
|
||||
the checked-in examples.
|
||||
|
||||
`report.json` version 2 separates the initial cold project configure/build,
|
||||
unchanged builds, changed `.cpp` builds, changed-header builds, deliberate compile
|
||||
failure/recovery, Lua edit-to-reload, first offscreen Player frame and synthetic
|
||||
Editor input-to-visible-state. Each warm/changed case has one warm-up and five
|
||||
measured repetitions. Each sample remains in `raw/` with command, stdout/stderr,
|
||||
duration and, on Linux, peak RSS; the report includes median and nearest-rank p95.
|
||||
The file hashes identify every changed source variant. Five unchanged builds must
|
||||
return a verified schema/package cache hit. The cold case begins with empty project
|
||||
`.faset` caches, **not** a cold OS file cache, newly downloaded dependencies or a
|
||||
fresh engine toolchain. It is a development `Debug` workflow.
|
||||
|
||||
The first-frame value comes from the Player's `main_to_first_frame` profile after
|
||||
five one-frame offscreen runs. It excludes OS process loading and says nothing about
|
||||
window presentation latency. The separate UI probe applies keyboard input through
|
||||
the retained Editor UI, then measures 100 post-warm-up offscreen frames; it is not
|
||||
native desktop input-to-photon latency. A watched Lua Player records five
|
||||
edit-to-successful-reload times, including its polling and log notification. A
|
||||
3,000-frame Player profile compares explicit Vulkan allocation and texture maxima
|
||||
in frames 101–200 with frames 2901–3000. Zero growth over that interval is useful
|
||||
but does not prove the absence of all leaks. The tool also adds 512 deterministic
|
||||
objects to a disposable scene and profiles 240 frames; this stresses scene
|
||||
simulation/snapshot work, not representative game content.
|
||||
|
||||
On Linux, GNU `time` records peak RSS for each command and its waited-for children.
|
||||
This is a maximum, not the sum of simultaneous compiler processes. Other platforms
|
||||
report this field as null unless equivalent measurement support is added. The tool
|
||||
keeps raw stdout/stderr, durations, hardware and revision information alongside its
|
||||
report. A dirty source checkout is explicitly identified.
|
||||
report this field as null unless equivalent measurement support is added. The report
|
||||
keeps raw stdout/stderr, profiles, hardware, driver, build setting, source hashes,
|
||||
Git revision and dirty-tree state. New runs also hash the exact CMake, Ninja, C/C++
|
||||
compiler, Slang, Editor and UI-probe binaries selected by the disposable project's
|
||||
`CMakeCache.txt`. Compare profiles only with the same scene, configuration,
|
||||
resolution, validation/readback settings and hardware class. The
|
||||
[dated P1 workflow record](https://github.com/emil28092005/Faset_Engine/blob/main/docs/validation/p1-iteration-2026-09-24/README.md)
|
||||
retains a successful Debug run and its exact raw files. Its post-run binary
|
||||
provenance supplement is explicitly separate from the original report.
|
||||
|
||||
`tools/verify_playable_exports.py` separately verifies the two sample games in
|
||||
relocated Release packages and records their Player profiles. Its assertions test
|
||||
@@ -118,85 +147,13 @@ and reads back the full image, so `cpu_ms` is wall time including waits, not CPU
|
||||
utilization. An open scene can run slower with HZB; visibility correctness and
|
||||
full-frame speed are separate findings.
|
||||
|
||||
## Compare temporal modes
|
||||
|
||||
Use one scene, output resolution, camera sequence, visibility path, binary and GPU
|
||||
for Off, TAA and Upscale. Run enough frames to include both the first-frame reset
|
||||
and steady-state accumulation. Keep the raw captures as well as timing samples:
|
||||
|
||||
```sh
|
||||
./faset_player --headless --frames 240 --profile off.json --temporal off
|
||||
./faset_player --headless --frames 240 --profile taa.json --temporal taa
|
||||
./faset_player --headless --frames 240 --profile upscale.json \
|
||||
--temporal upscale --render-scale 0.67
|
||||
```
|
||||
|
||||
The profile records requested and effective temporal modes, fallback and history
|
||||
reset reason, internal/output extent, jitter, and valid previous-transform count
|
||||
per completed frame. `gpu_temporal_resolve_ms`, `gpu_temporal_composite_ms`, and
|
||||
`gpu_ui_ms` are separate submitted GPU pass times when timestamp queries work;
|
||||
otherwise they are `null`. `gpu_allocated_bytes` includes live temporal targets
|
||||
and histories, subject to the allocation limits described above. Compare full
|
||||
frame GPU and renderer wall time too: scene raster savings can be offset by
|
||||
resolve, memory and synchronous readback. A valid frame-level history flag says
|
||||
the previous frame may be sampled, not that every pixel accepted it. For image
|
||||
quality, inspect a still thin edge, a slow pan and a newly uncovered surface, and
|
||||
compare the same frame against Off. See [Temporal rendering](temporal.md) for
|
||||
mode controls and native C++ configuration.
|
||||
|
||||
## Measure P3 lighting and shadows
|
||||
|
||||
A Player `--profile` sample includes `effective_lighting_path`, local lights
|
||||
submitted/omitted, requested/effective sun cascades, requested/rasterized local
|
||||
shadow faces, tile use, shadow drop reasons, caster draws, and explicit atlas
|
||||
allocation bytes. `gpu_main_raster_ms`, `gpu_sun_shadow_ms`, and
|
||||
`gpu_local_shadow_ms` are GPU timestamps or `null` when timestamps are
|
||||
unavailable. A light can illuminate while its shadow faces are dropped. A
|
||||
submitted-light count of zero is a different workload from 128 lights whose
|
||||
shadows are disabled. See [Lighting](lighting.md) for the capacity policy and
|
||||
[Diagnostics](diagnostics.md) for the Editor counters.
|
||||
|
||||
The fixed-scene benchmark compares 0, 4, 16, 32, 64, and 128 local lights under
|
||||
Direct, GPU frustum, and GPU occlusion visibility, with shadows on and off. Its
|
||||
wrapper runs three independent 1920×1080 repetitions per configuration, each
|
||||
with ten warm-up and thirty recorded frames. First inspect the planned matrix:
|
||||
|
||||
```sh
|
||||
python3 tools/benchmark_p3_lighting.py --list-runs
|
||||
```
|
||||
|
||||
From the repository, after a Linux Release renderer build, run one shadow setting
|
||||
into a new output directory. Supply the actual device driver identity:
|
||||
|
||||
```sh
|
||||
python3 tools/benchmark_p3_lighting.py --sweep \
|
||||
--executable build/linux-release/faset_p3_lighting_benchmark \
|
||||
--output .cache/p3-lighting-off \
|
||||
--shadows off --driver 'REPLACE_WITH_ACTUAL_DRIVER' --validation off
|
||||
```
|
||||
|
||||
The wrapper writes one raw CSV per run, `merged.csv`, and `summary.json`. Keep
|
||||
all three with the exact source revision and device. It checks that every run
|
||||
used its requested visibility mode and submitted every requested light. GPU
|
||||
timestamps for the main raster isolate fragment-heavy lighting better than
|
||||
renderer wall time, which includes GPU waits and synchronous readback. Shadow
|
||||
time is split into sun and local GPU durations. The Forward+ decision compares
|
||||
the median of three run medians against the matching zero-light configuration;
|
||||
the threshold is **1.0 ms extra main raster time or 15% of the zero-light GPU
|
||||
frame** at 32, 64, or 128 lights on the Linux physical reference GPU. The
|
||||
[P3 lighting validation record](https://github.com/emil28092005/Faset_Engine/blob/main/docs/validation/p3-lighting-2026-09-24/README.md)
|
||||
states the measured decision and scope. A software Vulkan run checks
|
||||
functionality, not physical GPU performance.
|
||||
|
||||
## Current performance scope
|
||||
|
||||
The accepted MVP path uses direct draws and CPU culling; P2 adds optional GPU
|
||||
visibility for opaque static meshes, with prepared LODs supplied by the project.
|
||||
P3 adds local lights and bounded sun/local shadow atlases. The benchmark's
|
||||
`lighting_path` and a Player profile's `effective_lighting_path` identify the
|
||||
algorithm actually used. Both paths currently use one graphics queue and
|
||||
synchronous full-image capture/readback. Use measurements to find the next
|
||||
bottleneck before introducing parallel jobs or expanding GPU-driven rendering.
|
||||
Neither an offscreen capture benchmark nor a tiny demo is a promise of a
|
||||
production frame budget. Observed measurements and follow-up targets belong in
|
||||
the implementation acceptance report with their source revision and method.
|
||||
Both paths currently use one graphics queue and synchronous full-image
|
||||
capture/readback. Use measurements to find the next bottleneck before introducing
|
||||
parallel jobs or expanding GPU-driven rendering. Neither an offscreen capture
|
||||
benchmark nor a tiny demo is a promise of a production frame budget. Observed
|
||||
measurements and follow-up targets belong in the implementation acceptance report
|
||||
with their source revision and method.
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Temporal rendering
|
||||
|
||||
Faset renders the scene with **Off** by default. In the optional Editor diagnostics
|
||||
panel (**F12**), choose **TAA** to accumulate a full-resolution scene over successive
|
||||
frames, or **Upscale** to render the scene at a lower resolution and reconstruct it
|
||||
at the output resolution. The Upscale slider accepts 50–99%; 67% is a useful
|
||||
starting point for visual comparison. UI text and controls always render at output
|
||||
resolution after the scene resolve. Shadow maps keep their own unjittered views.
|
||||
|
||||
The diagnostic selector affects only the current Editor viewport. It does not edit
|
||||
the scene, gameplay code, or an exported Player. The panel's **Requested** and
|
||||
**Effective** fields identify a device fallback. It also shows internal and output
|
||||
extent, whether the previous completed frame's color history was eligible, the
|
||||
reason it reset, and separate GPU times for resolve, composite and UI where
|
||||
timestamp queries are available. A reset on the first frame, camera cut, changed
|
||||
view, resize, scale switch or compatible shader reload is expected. A valid history
|
||||
does not imply every pixel reused it: newly visible surfaces can still reject
|
||||
their individual history samples.
|
||||
|
||||
For a Player or exported game, select the mode at launch:
|
||||
|
||||
```sh
|
||||
./faset_player --headless --frames 120 --temporal taa --profile taa.json
|
||||
./faset_player --headless --frames 120 --temporal upscale \
|
||||
--render-scale 0.67 --profile upscale.json
|
||||
```
|
||||
|
||||
`--temporal` accepts `off`, `taa`, or `upscale`. Off and TAA use scale `1`; Upscale
|
||||
requires a scale from `0.5` inclusive to `1` exclusive. An invalid mode or scale
|
||||
stops startup with an error. If Vulkan compute or the required image formats are
|
||||
unavailable, the renderer falls back to Off and records its effective mode and
|
||||
reason in the profile. Direct, GPU frustum and GPU occlusion visibility can be
|
||||
combined with either temporal mode. See [Profiling](profiling.md) for how to compare
|
||||
their timings fairly.
|
||||
|
||||
Native renderer users can make the same choice without modifying gameplay scripts:
|
||||
|
||||
```cpp
|
||||
faset::render::RendererConfig config;
|
||||
config.temporal_mode = faset::render::TemporalMode::Upscale;
|
||||
config.render_scale = 0.67f;
|
||||
faset::render::Renderer renderer(config);
|
||||
|
||||
// A live viewport switch recreates scene targets and resets color history.
|
||||
renderer.set_temporal_mode(faset::render::TemporalMode::TAA);
|
||||
```
|
||||
|
||||
Provide a stable `DrawItem::instance_key` for moving opaque objects so the renderer
|
||||
can find their previous model transform. Camera cuts must be marked in the
|
||||
`Snapshot`; cuts, teleports and incompatible projection changes reject old history.
|
||||
World transparency and sprites use the scene depth/order and reject stale color on
|
||||
their reactive pixels. TAA and Upscale are optional image-quality paths; compare
|
||||
them against Off on the actual game scene, especially thin geometry, slow pans,
|
||||
newly revealed surfaces and moving transparent content.
|
||||
|
||||
These are first-generation, opt-in reconstruction modes. They can reduce shimmer
|
||||
on a stationary edge while lowering the peak brightness of a subpixel line, and
|
||||
a newly revealed edge can differ by one pixel from its settled appearance. The
|
||||
amount depends on scene content, resolution and motion. Upscale also trades
|
||||
internal render resolution for resolve cost and extra images; it is not always
|
||||
faster. Compare Off, TAA and Upscale at the target output resolution with both
|
||||
still and moving cameras, and inspect thin objects and opening doors before
|
||||
choosing a mode for a game. The [P3 temporal validation record](https://github.com/emil28092005/Faset_Engine/blob/main/docs/validation/p3-temporal-2026-09-24/README.md)
|
||||
contains source captures, paired image measurements and a bounded 720p cost
|
||||
profile.
|
||||
@@ -14,7 +14,8 @@ process; stopping it leaves the authoring scene unchanged.
|
||||
Launch `faset_editor` without arguments to open the project launcher.
|
||||
|
||||
1. Choose **Create project**, enter a name and a new or empty project directory,
|
||||
then select **2D** or **3D** for the initial scene.
|
||||
then select **C++** or **Lua** and **2D** or **3D**. Each combination creates a
|
||||
runnable start scene and a small behavior for that language.
|
||||
2. Choose **Create project** to create the project files and open the Editor.
|
||||
3. To return later, choose **Open project**, select its directory with **Browse**,
|
||||
and confirm **Open project**. The directory must contain `project.faset.json`.
|
||||
@@ -33,6 +34,12 @@ was launched in MCP mode so the connection keeps a single project context.
|
||||
|
||||
For a direct launch, use `faset_editor --project /path/to/MyGame` on Linux or
|
||||
`faset_editor.exe --project C:\Projects\MyGame` on Windows.
|
||||
For scripted project creation, pass `--new MyGame --dimension 2|3
|
||||
--language cpp|lua` with `--project` pointing to the new directory. Omitting
|
||||
`--language` retains the earlier C++ scaffold without a runnable start scene;
|
||||
select a language explicitly for a complete starter.
|
||||
The [C++ first behavior](../scripting/first-behavior.md) and
|
||||
[Lua gameplay](../scripting/lua.md) guides show the first editing steps.
|
||||
|
||||
## Create and save a scene
|
||||
|
||||
@@ -50,6 +57,19 @@ outside the Editor, ordinary Save reports a conflict instead of overwriting it.
|
||||
Save your in-memory work to a new path and compare the two versions before replacing
|
||||
anything.
|
||||
|
||||
Autosave is enabled by default. After a named scene has been idle for two seconds,
|
||||
the Editor saves its current revision to that scene file. The status bar shows
|
||||
**Pending autosave**, **Saving**, or **Saved**. An unnamed scene shows **Save As
|
||||
required** until you choose its path. The status bar's **Save As...** action opens
|
||||
an editable, new project-relative path; it never overwrites the conflicting file.
|
||||
|
||||
If the disk file changes outside Faset, autosave stops for that revision and shows
|
||||
**Save conflict**. Use **Save As...** to keep both versions, then compare or reload
|
||||
the original. **Save failed** preserves the unsaved scene in the recovery journal;
|
||||
correct the write error or use Save As. Autosave does not clear Undo history or
|
||||
replace the [recovery journal](#recover-unsaved-work). Recovery still protects
|
||||
unnamed scenes and edits before the idle deadline.
|
||||
|
||||
## Navigate and transform
|
||||
|
||||
- **Right drag:** orbit the 3D view; pan in a 2D scene.
|
||||
@@ -119,13 +139,16 @@ for the C++ iteration loop.
|
||||
## Project settings
|
||||
|
||||
Open **File → Project settings** to change the project name, initial **2D / 3D** type,
|
||||
and start-scene path. Save a scene first, then choose it from the saved-scene list or
|
||||
enter its project-relative path. Choose **Save project** to update
|
||||
`project.faset.json` explicitly. A missing start scene is rejected and the dialog
|
||||
stays open.
|
||||
start-scene path, or **Autosave named scenes** preference. Save a scene first, then
|
||||
choose it from the saved-scene list or enter its project-relative path. Choose
|
||||
**Save project** to update `project.faset.json` explicitly. A missing start scene is
|
||||
rejected and the dialog stays open. The Autosave preference applies immediately;
|
||||
when disabled, the status bar says **Autosave off** and you can still use Ctrl+S or
|
||||
Save As. The project file stores it as `editor.autosave`; omitting it means enabled.
|
||||
|
||||
These settings are used when the project opens again; they do not convert the active
|
||||
scene, switch its dimension, restart the Player, or add a scene Undo entry.
|
||||
The project name, default dimension, and start scene are used when the project opens
|
||||
again; they do not convert the active scene, switch its dimension, restart the Player,
|
||||
or add a scene Undo entry.
|
||||
**Cancel** or **Escape** discards this form's draft. If another writer changes the
|
||||
project settings while the dialog is open, Save reports a revision conflict and
|
||||
keeps your draft. **Reload saved** deliberately discards it and reloads the latest
|
||||
|
||||
@@ -31,17 +31,27 @@ cmake --build --preset linux-debug --parallel
|
||||
ctest --preset linux-debug
|
||||
```
|
||||
|
||||
Create a project and open the native Editor:
|
||||
Create a runnable C++ or Lua starter and open the native Editor:
|
||||
|
||||
```sh
|
||||
build/linux-debug/faset_editor --project "$PWD/MyGame" --new MyGame --dimension 3
|
||||
build/linux-debug/faset_editor --project "$PWD/MyGame" --new MyGame --dimension 3 --language cpp
|
||||
build/linux-debug/faset_editor --project "$PWD/LuaGame" --new LuaGame --dimension 2 --language lua
|
||||
```
|
||||
|
||||
You can also run `build/linux-debug/faset_editor` without arguments to open the
|
||||
project launcher and create or select a project using the native interface.
|
||||
project launcher. Its Create view offers C++ 2D, C++ 3D, Lua 2D, and Lua 3D.
|
||||
Each explicit starter includes `Scenes/main.scene.json` with a player, ground,
|
||||
and a behavior bound to `Scripts/Gameplay.cpp` or `Scripts/main.lua`. 3D starters
|
||||
also include a camera and light. Existing files in a destination directory are
|
||||
never replaced by starter creation. The older `--new NAME --dimension 2|3`
|
||||
command without `--language` retains its original scene-free C++ scaffold.
|
||||
|
||||
Use **Build** after changing `MyGame/Scripts/Gameplay.cpp`, then **Play**.
|
||||
The Player runs separately. Stop it before changing and rebuilding C++ gameplay.
|
||||
Lua starters declare their entry script in `project.faset.json`, install LuaLS
|
||||
annotations/configuration, and need no `Gameplay.cpp`. Use **Refresh Lua** after
|
||||
editing a Lua behavior declaration; development **Reload Lua** can apply a valid
|
||||
script edit to a running Player without recompiling C++.
|
||||
See [MCP and CLI](../editor/mcp.md) for headless authoring and automation.
|
||||
|
||||
For an optimized build use `linux-release`. The `linux-sanitize` preset enables
|
||||
|
||||
@@ -56,14 +56,26 @@ The example scene is a complete, loadable document:
|
||||
|
||||
The sprite is visible because it has `faset.sprite`. It moves because it also has `tutorial.move_x`. The configuration field is `speed`; the type string must match the registration exactly. `rotation` uses radians, and the default coordinate system is Y-up.
|
||||
|
||||
After **Build C++** succeeds in the Editor, choose **Add component** in the Inspector
|
||||
After **Build** succeeds in the Editor, choose **Add component** in the Inspector
|
||||
and select the registered type. Its schema supplies editable fields, defaults and
|
||||
constraints. The direct Player command above is useful for testing the same behavior
|
||||
independently of an editor session.
|
||||
|
||||
## Make a change and verify it
|
||||
|
||||
Change the scene's `speed` to `-2`: the object moves left. Change the C++ callback or schema: stop the Player, rebuild, regenerate the schema, then launch a new session. There is no automatic C++ hot reload.
|
||||
Change the scene's `speed` to `-2`: the object moves left. Change the C++ callback
|
||||
or schema: stop the Player, choose **Build**, then launch a new Play session. The
|
||||
Build job regenerates metadata when its inputs changed; an unchanged second build
|
||||
can reuse the verified schema/package generation. It still asks CMake/Ninja to check
|
||||
the native dependency graph. There is no automatic C++ hot reload.
|
||||
|
||||
To try compiler navigation in a project opened by the Editor, add
|
||||
`#error Check navigation` to its `Scripts/Gameplay.cpp`, choose **Build**, and
|
||||
select the resulting Console diagnostic. **Open source** passes the file and
|
||||
one-based location to the configured external editor. Remove the line and build
|
||||
again; the failed attempt keeps the previous valid generation. See
|
||||
[Developer diagnostics](../editor/diagnostics.md) for editor command setup and
|
||||
[Build, Play, and export](../editor/export.md) for the full iteration loop.
|
||||
|
||||
The `tutorial_moving` CTest checks that both 30 Hz and 60 Hz frame sequences move the object two metres in one second. It checks the resulting pose, rather than only checking that the program starts.
|
||||
|
||||
|
||||
@@ -5,6 +5,23 @@ behaviors share the same runtime lifecycle, typed entity operations, scene compo
|
||||
and Inspector metadata. The Editor does not run gameplay code in its own process.
|
||||
There is no built-in script editor: edit `.lua` files in Zed or another external editor.
|
||||
|
||||
## Start with a runnable Lua project
|
||||
|
||||
Choose **Create project → Lua → 2D or 3D** in the native launcher, or run:
|
||||
|
||||
```sh
|
||||
build/linux-debug/faset_editor --project "$PWD/LuaGame" --new LuaGame --dimension 2 --language lua
|
||||
```
|
||||
|
||||
The starter creates `Scripts/main.lua`, a scene with a player and ground, and a
|
||||
manifest entry for that script. The player moves horizontally and jumps with the
|
||||
default input actions. The 3D choice also provides a camera and directional light.
|
||||
Open `Scripts/main.lua` in your external editor and change `speed` or
|
||||
`fixed_update`. **Refresh Lua** updates declared Inspector fields; **Reload Lua**
|
||||
updates a development Player after a valid edit without rebuilding native gameplay.
|
||||
The starter installs LuaLS declarations and `.luarc.json`; reopening it in Zed or
|
||||
another LuaLS-enabled editor provides completions for the Faset API.
|
||||
|
||||
## Enable Lua in a project
|
||||
|
||||
Add explicit entry scripts to `project.faset.json`:
|
||||
@@ -19,7 +36,7 @@ Add explicit entry scripts to `project.faset.json`:
|
||||
|
||||
This is a manifest fragment, not a complete project file. Each entry must return one
|
||||
`faset.behavior` table with a unique custom TypeId. All sources live beneath `Scripts`
|
||||
and are captured as an immutable build/export snapshot. Paths must be project-relative;
|
||||
and are copied into a content-verified build/export snapshot. Paths must be project-relative;
|
||||
symlinks and paths outside `Scripts` are rejected. Auxiliary modules do not need to
|
||||
appear in the entry list.
|
||||
|
||||
@@ -193,14 +210,18 @@ The Editor command palette exposes:
|
||||
| `faset_lua_refresh` | Build if needed, extract schemas, refresh Inspector metadata |
|
||||
| `faset_lua_reload` | Request a Lua reload in a development Player |
|
||||
| `faset_lua_setup` | Install Faset LuaLS declarations/configuration |
|
||||
| `faset_script_open` | Open a script in an external editor |
|
||||
| `faset_source_open` | Open a C++, header or Lua source at a one-based line/column |
|
||||
| `faset_script_open` | Lua-only compatibility alias for source opening |
|
||||
|
||||
The external-editor default is `zed`. Set `editor.script_editor` in
|
||||
`project.faset.json` to an argument array such as `["code", "--goto", "{file}"]`,
|
||||
or pass an `editor` argument array to `faset_script_open`. Exact `{file}` and
|
||||
`{project}` arguments are substituted; a missing file argument is appended. The
|
||||
command launches the executable directly, without a shell. The Assets panel lists
|
||||
Lua sources under `Scripts` and provides **Open Script**.
|
||||
`project.faset.json` to an argument array such as
|
||||
`["zed", "{file}:{line}:{column}"]`, or pass an `editor` argument array to
|
||||
`faset_source_open`. `{file}`, `{line}`, `{column}` and `{project}` are substituted
|
||||
inside arguments; a missing file argument is appended. The command launches the
|
||||
executable directly, without a shell. Only regular source files under this
|
||||
project's `Scripts` can be opened. The Assets panel lists those files and the
|
||||
Console's structured Lua error can open its source location. A missing external
|
||||
editor is an actionable navigation error, not a failed gameplay build.
|
||||
|
||||
Development Play watches Lua changes. The Player's `--watch-lua` option enables this
|
||||
for direct development runs. A candidate source generation is loaded and validated
|
||||
@@ -209,6 +230,18 @@ Successful reload **restarts the scene**, invalidates old handles, and resets al
|
||||
script state. This is not state-preserving hot swapping. C++ source changes still
|
||||
require a rebuild and a new Player process.
|
||||
|
||||
For a short iteration, change `speed` in `Scripts/main.lua`, save it, and watch the
|
||||
Console for **Lua reloaded**. The running development Player picks up a valid
|
||||
snapshot without native recompilation. Change a field declaration or TypeId, then
|
||||
choose **Refresh Lua** to validate metadata and update Inspector choices. If the
|
||||
candidate has a syntax/schema error, the previous running generation remains in
|
||||
place; use the structured diagnostic to return to the source, correct it and retry.
|
||||
Lua module declaration, gameplay source, compiler/toolchain or shader changes can
|
||||
invalidate a later build's verified schema/package cache. The **Jobs** result
|
||||
distinguishes `schema_cache_hit` and `generation_reused`; those flags do not imply
|
||||
that the native build graph was skipped. See the [build loop](../editor/export.md)
|
||||
and [profiling guide](../editor/profiling.md).
|
||||
|
||||
Export captures the declared entry list and Lua modules with the game. The exported
|
||||
Player runs without the Editor or a separate Lua installation; development watching
|
||||
is not enabled by ordinary exported-game launch. Exported Lua remains readable source,
|
||||
|
||||
@@ -42,9 +42,9 @@ Tasks 1–3 define the shared interfaces. Integrate Task 2's descriptor ABI befo
|
||||
|
||||
**Files:** Modify `include/faset/render/renderer.hpp`, `src/authoring/schema.cpp`, `src/player/SceneView.cpp`, `tests/authoring_tests.cpp`, `tests/runtime_player_tests.cpp`, and relevant Manual authoring examples.
|
||||
|
||||
**Interfaces:** Introduce `SunLight { stable_id, direction, color, intensity, casts_shadow }`, `LocalLight { Kind::Point|Spot, stable_id, position, direction, color, intensity, range, inner_angle, outer_angle, casts_shadow, shadow_priority }`, and `CameraFrustum { view, projection, near_plane, far_plane, perspective }`. Add `std::optional<SunLight> Snapshot::sun`, `std::vector<LocalLight> Snapshot::local_lights`, `bool Snapshot::authored_lights_present` (default false), and `std::optional<CameraFrustum> Snapshot::camera_frustum` after existing aggregate fields; retain `Snapshot::light_direction`. `SceneView::build` fills camera data for 3D scenes, sets authored-light presence even for disabled/future-version light components, and picks the first enabled directional by stable ID. A legacy sun is synthesized only when both sun and authored-light presence are absent.
|
||||
**Interfaces:** Introduce `SunLight { stable_id, direction, color, intensity, casts_shadow }`, `LocalLight { Kind::Point|Spot, stable_id, position, direction, color, intensity, range, inner_angle, outer_angle, casts_shadow, shadow_priority }`, and `CameraFrustum { view, projection, near_plane, far_plane, perspective }`. Add `std::optional<SunLight> Snapshot::sun`, `std::vector<LocalLight> Snapshot::local_lights`, and `std::optional<CameraFrustum> Snapshot::camera_frustum` after existing aggregate fields; retain `Snapshot::light_direction`. `SceneView::build` fills camera data for 3D scenes and picks the first enabled directional by stable ID.
|
||||
|
||||
- [ ] **Step 1: Write failing schema/extraction tests.** Construct a version-1 scene with directional, point, and spot entities in one order and reversed order. Assert all local IDs/properties agree; authored sun color/intensity are preserved; a no-light scene has `authored_lights_present == false` and retains the default legacy sun, while a local-only or explicitly disabled-sun scene has the flag true and no sun. Extra directionals emit a diagnostic; invalid `range <= 0`, `inner_angle > outer_angle`, nonfinite color/transform, and unknown kind identify the entity/field. An essential assertion is:
|
||||
- [ ] **Step 1: Write failing schema/extraction tests.** Construct a version-1 scene with directional, point, and spot entities in one order and reversed order. Assert all local IDs/properties agree; authored sun color/intensity are preserved; no-light scene retains the default legacy sun; extra directionals emit a diagnostic; invalid `range <= 0`, `inner_angle > outer_angle`, nonfinite color/transform, and unknown kind identify the entity/field. An essential assertion is:
|
||||
```cpp
|
||||
auto a = view.build(scene_with_three_lights(), 16.f / 9.f);
|
||||
auto b = view.build(reordered_scene_with_three_lights(), 16.f / 9.f);
|
||||
@@ -54,14 +54,14 @@ Tasks 1–3 define the shared interfaces. Integrate Task 2's descriptor ABI befo
|
||||
"Light ordering follows stable IDs, not entity array order");
|
||||
```
|
||||
- [ ] **Step 2: Run the focused tests red.** Run `cmake --preset linux-debug` and `cmake --build --preset linux-debug --target faset_authoring_tests faset_player_tests --parallel 4`; missing typed fields should fail compilation. If compilation succeeds, `ctest --test-dir build/linux-debug --output-on-failure --no-tests=error -R '^(authoring|player_scene_contracts)$'` must fail on a new behavioral assertion. Record the expected failure rather than assuming the build itself must be red.
|
||||
- [ ] **Step 3: Add schema defaults and extraction.** Keep builtin version 1; use `fields.value` for additive fields, normalize directions after the world transform, validate finite/color/range/cone values, sort by stable ID, and preserve the legacy fallback only when no authored light component exists. Set `camera_frustum` from the same unjittered view/projection used to form `view_projection`. Update direct C++ API examples to construct one point and one spot light.
|
||||
- [ ] **Step 3: Add schema defaults and extraction.** Keep builtin version 1; use `fields.value` for additive fields, normalize directions after the world transform, validate finite/color/range/cone values, sort by stable ID, and preserve the legacy fallback. Set `camera_frustum` from the same unjittered view/projection used to form `view_projection`. Update direct C++ API examples to construct one point and one spot light.
|
||||
```cpp
|
||||
struct CameraFrustum {
|
||||
Mat4 view{identity}, projection{identity};
|
||||
float near_plane{0.1f}, far_plane{1000.f};
|
||||
bool perspective{true};
|
||||
};
|
||||
// Snapshot::light_direction remains a fallback only if authored_lights_present is false.
|
||||
// Snapshot::light_direction remains available to callers without Snapshot::sun.
|
||||
```
|
||||
- [ ] **Step 4: Run focused tests green.** `ctest --test-dir build/linux-debug --output-on-failure -R '^(authoring|player_scene_contracts)$'` passes, including old version-1 scenes and exported-scene decoding.
|
||||
- [ ] **Step 5: Commit** `Expose authored sun, point, and spot lights in render snapshots`.
|
||||
|
||||
@@ -12,7 +12,7 @@ P3 supplies one sun plus point and spot lights, camera-fitted cascaded sun shado
|
||||
|
||||
Keep `faset.light` at builtin schema version 1 and add optional fields with defaults: `kind` (`directional`, `point`, `spot`, default `directional`), `enabled` (true), `color` (white), `intensity` (1, nonnegative), `range` (10, positive, for local lights), `inner_angle` (0.35 radians), `outer_angle` (0.70 radians, strictly below π/2), `casts_shadow` (true), and `shadow_priority` (integer 0). Existing fields and component IDs remain valid. Cross-field validation requires `0 <= inner_angle <= outer_angle`; local range, color channels, intensity, transforms, and cone directions must be finite. Invalid authored values return a diagnostic with entity and field rather than nonfinite GPU data. Missing new fields use the schema defaults.
|
||||
|
||||
`Snapshot` retains `light_direction` for existing direct-render clients. Add an optional `SunLight`, a vector of `LocalLight`, an `authored_lights_present` flag (default false), and an optional explicit `CameraFrustum` containing unjittered view/projection matrices, near/far distances, and projection kind. `SceneView` populates these from the authoring scene and sets the flag if any authored light component exists, including a disabled or future-version component. Each light carries the stable entity/component identity, transformed position or normalized direction, color, intensity, range, cone angles, and shadow options. The first enabled directional light by stable ID is the sun; extra directionals produce a visible diagnostic until a later multi-sun design exists. The renderer synthesizes the legacy sun from `Snapshot::light_direction` only when `sun` is absent **and** `authored_lights_present` is false. Thus an old scene without light components keeps its previous appearance, while a local-only scene or explicitly disabled sun does not receive an unintended directional light. Low-level callers may set the flag to request a dark scene without authoring metadata. Local lights are ordered by stable ID to prevent reordering from changing atlas allocation or results. Point attenuation tends smoothly to zero at `range`; a spot multiplies it by a smooth inner-to-outer cone factor. The shader handles zero distance and invalid normals without NaN output.
|
||||
`Snapshot` retains `light_direction` for existing direct-render clients. Add an optional `SunLight`, a vector of `LocalLight`, and an optional explicit `CameraFrustum` containing unjittered view/projection matrices, near/far distances, and projection kind. `SceneView` populates these from the authoring scene. Each light carries the stable entity/component identity, transformed position or normalized direction, color, intensity, range, cone angles, and shadow options. The first enabled directional light by stable ID is the sun; extra directionals produce a visible diagnostic until a later multi-sun design exists. If there is no authored directional light, the renderer synthesizes the legacy sun from `Snapshot::light_direction`. Local lights are ordered by stable ID to prevent reordering from changing atlas allocation or results. Point attenuation tends smoothly to zero at `range`; a spot multiplies it by a smooth inner-to-outer cone factor. The shader handles zero distance and invalid normals without NaN output.
|
||||
|
||||
Explicit camera frustum data is required for four cascades. If a low-level caller supplies only the legacy `view_projection`, the renderer uses one bounded legacy-compatible sun shadow view and reports `effective_sun_cascades = 1`; it never silently claims CSM. 2D sprite-only snapshots do not incur shadow work. The future temporal stage may jitter the main raster projection, but the shadow planner consumes the unjittered `CameraFrustum` exclusively.
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
These files preserve bounded checks and their inputs. Each record states its source revision or working-tree limitation; a passing record does not certify later commits or every supported platform.
|
||||
|
||||
- [MVP acceptance dossier](mvp-acceptance.md): criterion-by-criterion closure, tested revisions and remaining compatibility coverage.
|
||||
- [P1 gameplay iteration](p1-iteration-2026-09-24/README.md): repeatable Debug C++/Lua workflow, raw samples, toolchain provenance, real compiler navigation and coverage limits.
|
||||
- [P2 GPU visibility Linux evidence](p2-gpu-visibility-2026-09-23/README.md): Debug/Release GPU acceptance, lavapipe functional checks, relocated Player exports, and explicit platform/performance limits.
|
||||
- [P2 pinned SwiftShader compatibility](p2-swiftshader-2026-09-23/README.md): the Windows CI regression, shader capability fix, independent review closure, final native CI and relocated Player evidence.
|
||||
- [P3 lighting and shadows](p3-lighting-2026-09-24/README.md): implementation, acceptance matrix, bounded evidence, and remaining Forward+/platform checks; temporal reconstruction is tracked separately.
|
||||
- [P3 temporal reconstruction](p3-temporal-2026-09-24/README.md): Off/TAA/Upscale source captures, three-path image-quality matrix, edge and reveal measurements, and bounded 720p costs.
|
||||
- [Windows software Vulkan](windows-software-vulkan-2026-09-18/README.md): fresh native build, 35 tests, launcher/window/MCP workflows and both relocated Release games on SwiftShader.
|
||||
- [Checkpoint 5 Linux acceptance](checkpoint5-linux-2026-09-18/README.md): clean offline source build, first Editor launch, exact-candidate standalone games and live Blender checks.
|
||||
- [Final Linux source checks](final-linux-2026-09-18/README.md): `4cb8255` integrated test results and both Release games after the asset-relocation correction, including package manifests and standalone captures.
|
||||
|
||||
@@ -40,7 +40,7 @@ check. For sanitizers, configure with `-DFASET_SANITIZERS=ON`, build the
|
||||
`faset_lua_tests`, `faset_lua_safety_tests`, and `faset_schema_exporter` targets, then
|
||||
run `ctest --test-dir <build> --output-on-failure -R '^lua_'`.
|
||||
|
||||
## Not verified here
|
||||
## Not verified in the September 18 run
|
||||
|
||||
- Windows compilation or execution of the new module.
|
||||
- Graphical/window interaction and real-time Lua reload in a running rendered game.
|
||||
@@ -53,3 +53,20 @@ run `ctest --test-dir <build> --output-on-failure -R '^lua_'`.
|
||||
The renderer-linked CPU checks used the existing Vulkan loader, repo-pinned Vulkan
|
||||
headers and cached Slang, with SDL X11/Wayland disabled. No system graphics packages
|
||||
were installed. This proves linkage and CPU validation, not graphics compatibility.
|
||||
|
||||
## September 24 Release follow-up
|
||||
|
||||
The [Release execution record](lua-release-2026-09-24/README.md) closes the
|
||||
Linux offscreen export gap above. At source commit `4331857`, a Release Editor
|
||||
exported the checked-in Lua-only sample into a disposable Unicode-path project.
|
||||
The package was relocated, the source project path was hidden, and its Player
|
||||
validated and rendered 120 frames on an NVIDIA GeForce RTX 2080 Ti with driver
|
||||
595.84 and Khronos validation enabled; zero validation errors were reported.
|
||||
The package manifest has `lua_enabled: true`, declared Lua source and its license,
|
||||
and no project C++ gameplay source. The five focused Release Lua/schema tests
|
||||
passed. This verifies an offscreen run on Linux; a separate physical Windows GPU
|
||||
and manual window interaction have not been tested by this record. Windows
|
||||
SwiftShader execution is configured in CI and needs a passing run before it is
|
||||
claimed as covered.
|
||||
|
||||

|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Lua-only Release game: relocated execution
|
||||
|
||||
This is a local Linux result for source revision
|
||||
`433185717e1f324acb6eaf186818589d11697453` on 2026-09-24. The
|
||||
[machine-readable report](report.json) records the exact source input hashes,
|
||||
Release package, Editor binary hash, command arguments and elapsed times. The
|
||||
Editor itself was built with the `linux-release` preset. The exported Player
|
||||
and package also identify their configuration as Release.
|
||||
|
||||
| Check | Observed result |
|
||||
|---|---|
|
||||
| Disposable source | `examples/lua` copied to a Unicode-path temporary project outside the engine tree |
|
||||
| Package | `lua_enabled: true`; 32 hash-checked files, including Lua gameplay source and `Notices/lua/LICENSE.txt`; no project `Gameplay.cpp` or `.hpp` |
|
||||
| Relocation | Generation copied outside the project/engine; original project path hidden before Player launch |
|
||||
| CPU validation | Packaged Player `--validate` succeeded from an unrelated empty working directory |
|
||||
| GPU execution | 120/120 headless 1280×720 frames, 0 validation errors |
|
||||
| Device | NVIDIA GeForce RTX 2080 Ti; proprietary driver 595.84, Vulkan 1.4.329; selected-device details in the report and [Vulkan probe](vulkaninfo-summary.txt) |
|
||||
| Image | Four expected scene colors, including cyan player and gold collectible; raw [PPM](lua.ppm) SHA-256 `e2f4c3b84de75dadd2e31d388d0ba51abc1861f1ec76eb7ba51a4a2dcac720a7` |
|
||||
| Focused Release CTest | 5/5: `lua_contracts`, `lua_safety_contracts`, `lua_cli_contracts`, `lua_player_reload`, `build_schema_publication` |
|
||||
|
||||
The [manifest](lua-manifest.json) binds the package file checksums. The
|
||||
[Player profile](lua-profile.json) contains all 120 per-frame samples and
|
||||
resource/timing definitions; the [validate](lua-validate.json),
|
||||
[render](lua-run.json) and [export](lua-export.json) logs retain raw process
|
||||
results. The [PNG preview](lua.png) is a lossless conversion of the checked
|
||||
PPM.
|
||||
|
||||
The verifier also confirmed a clean Git source tree, rejected undeclared
|
||||
package files and unexpected C++ script files, classified the selected device
|
||||
as physical, and found the sample Lua `on_start` log in the relocated run.
|
||||
|
||||
To repeat this check from a built checkout, choose a **new, empty** output
|
||||
directory:
|
||||
|
||||
```sh
|
||||
cmake --preset linux-release
|
||||
cmake --build --preset linux-release --target faset_editor --parallel 4
|
||||
python3 tools/verify_playable_exports.py --editor build/linux-release/faset_editor \
|
||||
--output .cache/lua-release-check --only-lua
|
||||
cmake --build --preset linux-release --target faset_player faset_schema_exporter \
|
||||
faset_lua_tests faset_lua_safety_tests faset_build_schema_tests --parallel 4
|
||||
ctest --test-dir build/linux-release --no-tests=error --output-on-failure \
|
||||
-R '^(lua_contracts|lua_safety_contracts|lua_cli_contracts|lua_player_reload|build_schema_publication)$'
|
||||
```
|
||||
|
||||
The render used the Player's synthetic fixed timestep and offscreen Vulkan
|
||||
presentation. It does not establish manual window interaction or physical
|
||||
Windows GPU compatibility. The separate
|
||||
[Windows graphics run at `4ac02ee`](https://github.com/emil28092005/Faset_Engine/actions/runs/35937433040)
|
||||
passed 61/61 CTests and relocated all three Release games under pinned SwiftShader.
|
||||
The Lua-only package validated and completed 120 offscreen frames with its source
|
||||
project paths hidden. Its device is a **software** Vulkan implementation; the
|
||||
Khronos validation layer was not active on that Windows worker. The
|
||||
[P1 dossier's Windows report](../p1-iteration-2026-09-24/windows-4ac02ee/playable-report.json)
|
||||
retains the source/package identities and result. This does not establish
|
||||
physical Windows GPU compatibility.
|
||||
|
||||

|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,220 @@
|
||||
{
|
||||
"asset_generations": {},
|
||||
"build_fingerprint": "b745490f85f05987d849f6bb6f4d06953883f4b8e10c5551fadf164c7eec5857",
|
||||
"configuration": "Release",
|
||||
"executable": "faset_player",
|
||||
"files": [
|
||||
{
|
||||
"path": "README.txt",
|
||||
"sha256": "82bf72bc542643f6c4090e0a5de69b0014ca3fa17c6f9dfb12cc41e44c8b8db6",
|
||||
"size": 262
|
||||
},
|
||||
{
|
||||
"path": "Notices/Faset-NOTICE.txt",
|
||||
"sha256": "30c2e7e80f5153b31ab57675e07246aef9165965d64e36022b426a26449ece3f",
|
||||
"size": 204
|
||||
},
|
||||
{
|
||||
"path": "Notices/dependencies.json",
|
||||
"sha256": "262e8f63cf21c516829b1fedb0900ac90e76d62aa8f78d9ad02d8f24e0359e74",
|
||||
"size": 2468
|
||||
},
|
||||
{
|
||||
"path": "Notices/lua/LICENSE.txt",
|
||||
"sha256": "e42d195c77d3ad7255ee9c874772d3c53998e7f60f9acf453d4630fa161e0bfe",
|
||||
"size": 1126
|
||||
},
|
||||
{
|
||||
"path": "Notices/stb/LICENSE",
|
||||
"sha256": "bebfe904b14301657e4e5d655c811d51fd31b97c455b9cc2d8600d6bac6cff63",
|
||||
"size": 2510
|
||||
},
|
||||
{
|
||||
"path": "Notices/json/LICENSE.MIT",
|
||||
"sha256": "46a65cffd1ea955132d95a8dd921640714a8d6b537d2e4e482d31145ae95b603",
|
||||
"size": 1076
|
||||
},
|
||||
{
|
||||
"path": "Notices/box3d/LICENSE",
|
||||
"sha256": "da5e31a26bf3cfd5ba5c96d6823e480128c81e76c107ef9d3ee5d94789184b90",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/box2d/LICENSE",
|
||||
"sha256": "68a3e676d7e94093b102d5cba0d4e04af812040d6f230c3db67a6664574e43d2",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/entt/LICENSE",
|
||||
"sha256": "0785027ce472d7c61f05fba664a1d3ba6639c1593ced351ad9e4bed868765d99",
|
||||
"size": 1097
|
||||
},
|
||||
{
|
||||
"path": "Notices/sdl3/LICENSE.txt",
|
||||
"sha256": "97f35b302b361680ec1e891e95d2d52097bb95abff361434916d99dc1305f127",
|
||||
"size": 884
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.reflection.json",
|
||||
"sha256": "eed140bbe09c7d14935b688c770261ac0e81677c0974aa811c88ed67ea779b95",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.reflection.json",
|
||||
"sha256": "589818f670881c64f3aba726ee3bc82fe4b9d835a347f99134e0e157dc4a112e",
|
||||
"size": 2050
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.reflection.json",
|
||||
"sha256": "996fe5c7e31c6b8f316d8f290b3be0ae7063eb46c500a661e8715e9b822a2598",
|
||||
"size": 3587
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.reflection.json",
|
||||
"sha256": "9a03a2b692d2b0c758f63fb27760352cfef20a068372ebc137f1ca1797dcd3c2",
|
||||
"size": 2755
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.reflection.json",
|
||||
"sha256": "9f43472c267dbb6a2ddc69e252f7f00c5ca46f376d3c7c27165c8d12a175179d",
|
||||
"size": 3098
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.spv",
|
||||
"sha256": "62cb72e356346e1511c6d640a3cecb4a6e5283795338299b357edae5f7f52be4",
|
||||
"size": 12460
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.spv",
|
||||
"sha256": "08682362ee2120ed19d260e613285071747c3e436bb09bb6238e46f9cedc2308",
|
||||
"size": 4140
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.spv",
|
||||
"sha256": "7691360ec55f41d40d43652f506b051cef8b3a3ddcdcc7db61a7d4d97f9e87d8",
|
||||
"size": 16180
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.spv",
|
||||
"sha256": "ffcdb91e70c41ce9452094865546a009b9203140cf8eeb3ad1b4e5868d82b815",
|
||||
"size": 2404
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.spv",
|
||||
"sha256": "4647ef4fe1a68ab623ee9c19dac56631907f825cba0becd30869c5221c2a0385",
|
||||
"size": 4928
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.reflection.json",
|
||||
"sha256": "e3fd0889cd2f569d410f5d7558a4091d9f57f247a1dcf1788462f67525340819",
|
||||
"size": 2645
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.reflection.json",
|
||||
"sha256": "72ebf8d32452830650416dc4717d89a4324e97ece7028dfb97c66803c8dce71f",
|
||||
"size": 2649
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.reflection.json",
|
||||
"sha256": "c584f3b957ebf194a292451362a98590f85ff3cfbfd8f917b1c1265039381777",
|
||||
"size": 2639
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.spv",
|
||||
"sha256": "7643b4d688492b5ee923b9606f0b0e70343ca05fa67673838206119a6f86d8d8",
|
||||
"size": 784
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.spv",
|
||||
"sha256": "f5c4f289917ecab5d00d543c053aac1d10e6cca311fd172daf06d315160a3505",
|
||||
"size": 7436
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.spv",
|
||||
"sha256": "1ad2631c35d654f48166321ae43d4165043e1b919b14f1dc61caf97b1ada0898",
|
||||
"size": 1224
|
||||
},
|
||||
{
|
||||
"path": "faset_player",
|
||||
"sha256": "99d7b8286a9151ec4eff9a9899e862d987048b031e1e40ca1938646afbde37bd",
|
||||
"size": 6329192
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "e07b12047f8141c3c4cc8f0e7d0905a5c635375e4494755e34191db0859ab86f",
|
||||
"size": 175
|
||||
},
|
||||
{
|
||||
"path": "Scripts/util/motion.lua",
|
||||
"sha256": "bad3dcdc1081fd1dec589c12dad8dc175b739d77ea52b957ead9ecb4b7cb88a3",
|
||||
"size": 150
|
||||
},
|
||||
{
|
||||
"path": "Scripts/player.lua",
|
||||
"sha256": "1c51810574a3413c46a7cbd0ea2e84a9b802da1206a2b72bb78f6cc951367a11",
|
||||
"size": 1376
|
||||
},
|
||||
{
|
||||
"path": "Scripts/beacon.lua",
|
||||
"sha256": "44d932ebedf66cadb9620f2d926177be2f8d43d71d56aa83611de686af026231",
|
||||
"size": 820
|
||||
},
|
||||
{
|
||||
"path": "scene.fscene",
|
||||
"sha256": "641ba14a1f9c3966b9ec797814fdfa54f954dc5e0d53ab00c645598edef61baf",
|
||||
"size": 1681
|
||||
}
|
||||
],
|
||||
"format": "faset.export",
|
||||
"generation": "aa31bf16-984e-4854-b46f-15655bd6cc67",
|
||||
"lua_enabled": true,
|
||||
"lua_fingerprint": "a9261789bb1e0ca38bd40b08b0454165cd51454cba3ad4725dd357812ced6e35",
|
||||
"platform": "linux",
|
||||
"prerequisites": [
|
||||
"Linux x86_64",
|
||||
"Vulkan 1.3 driver",
|
||||
"Compatible glibc and libstdc++ runtime"
|
||||
],
|
||||
"renderer_profile": {
|
||||
"api": "Vulkan 1.3",
|
||||
"materials": [
|
||||
"base-color factor and texture",
|
||||
"metallic and roughness factors"
|
||||
],
|
||||
"required_features": [
|
||||
"dynamicRendering",
|
||||
"synchronization2"
|
||||
],
|
||||
"shadow_map": {
|
||||
"resolution": 1024,
|
||||
"world_extent": 40
|
||||
},
|
||||
"texture_sampling": "linear clamp, one mip level",
|
||||
"unsupported_material_features": [
|
||||
"normal maps",
|
||||
"metallic-roughness maps",
|
||||
"emissive and occlusion maps",
|
||||
"alpha mode selection",
|
||||
"unlit mode",
|
||||
"per-material face culling"
|
||||
]
|
||||
},
|
||||
"scene_hash": "143724a468d711cbdf9a9700310d7b0acef003ce1b21422ca5204e0e565fa02c",
|
||||
"simulation": {
|
||||
"fixed_delta": 0.016666666666666666,
|
||||
"gravity": [
|
||||
0,
|
||||
-9.81,
|
||||
0
|
||||
],
|
||||
"max_catch_up_ticks": 4,
|
||||
"physics_substeps": 4
|
||||
},
|
||||
"units": {
|
||||
"angle": "radian",
|
||||
"coordinates": "right-handed Y-up",
|
||||
"distance": "metre"
|
||||
},
|
||||
"validation_log": "{\"dimension\":2,\"validated\":true}\n",
|
||||
"version": 1
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-playable-exports-8wzkrc_u/Faset Café 世界/lua/faset_player",
|
||||
"--headless",
|
||||
"--frames",
|
||||
"120",
|
||||
"--capture",
|
||||
"/tmp/faset-playable-exports-8wzkrc_u/Faset Café 世界/lua/verification.ppm",
|
||||
"--profile",
|
||||
"/tmp/faset-playable-exports-8wzkrc_u/Faset Café 世界/lua/profile.json"
|
||||
],
|
||||
"cwd": "/tmp/faset-playable-exports-8wzkrc_u/empty-working-directory",
|
||||
"seconds": 0.6288121230027173,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "{\"device\":\"NVIDIA GeForce RTX 2080 Ti\",\"dimension\":2,\"effective_visibility_mode\":\"direct\",\"frames\":120,\"gpu_visibility_active\":false,\"ticks\":120,\"validation_errors\":0,\"visibility_mode\":\"direct\"}\n",
|
||||
"stderr": "Lua player ready: A/D move, Space jump, E reset\n"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-playable-exports-8wzkrc_u/Faset Café 世界/lua/faset_player",
|
||||
"--validate"
|
||||
],
|
||||
"cwd": "/tmp/faset-playable-exports-8wzkrc_u/empty-working-directory",
|
||||
"seconds": 0.007359832990914583,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "{\"dimension\":2,\"validated\":true}\n",
|
||||
"stderr": ""
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
File diff suppressed because one or more lines are too long
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"format": "faset.playable-export-verification",
|
||||
"version": 1,
|
||||
"started_utc": "2026-09-23T23:30:12.719805+00:00",
|
||||
"platform": "linux",
|
||||
"engine": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-lua-export",
|
||||
"editor": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-lua-export/build/linux-release/faset_editor",
|
||||
"standalone_root": "/tmp/faset-playable-exports-8wzkrc_u",
|
||||
"engine_revision": "433185717e1f324acb6eaf186818589d11697453",
|
||||
"engine_dirty": false,
|
||||
"engine_git_status": [],
|
||||
"engine_diff_sha256": null,
|
||||
"editor_sha256": "03ac75942f5f1d29e9d6fedb21ecffc6c74f4299401dbe84f01ab1b4e9c176a0",
|
||||
"project_workspace": "/tmp/faset-playable-projects-cuhq4iwr",
|
||||
"vulkaninfo_available": true,
|
||||
"driver_override": null,
|
||||
"frames_per_game": 120,
|
||||
"status": "passed",
|
||||
"projects": [
|
||||
{
|
||||
"name": "lua",
|
||||
"dimension": 2,
|
||||
"language": "lua",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "8392da3c18916400ea628daed094c77c390c553cbdcf822da227bdcd3d86380c"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "f1ab54150a58b289c47bcc34566ad7ee3025ad931db81e7f5dce70d9fbcac8ab"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/beacon.lua",
|
||||
"sha256": "44d932ebedf66cadb9620f2d926177be2f8d43d71d56aa83611de686af026231"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/player.lua",
|
||||
"sha256": "1c51810574a3413c46a7cbd0ea2e84a9b802da1206a2b72bb78f6cc951367a11"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/util/motion.lua",
|
||||
"sha256": "bad3dcdc1081fd1dec589c12dad8dc175b739d77ea52b957ead9ecb4b7cb88a3"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "7e4c0781c1837208b4499a9991ffb702143edf1f933ae9c7e3d2543fd2577747"
|
||||
}
|
||||
],
|
||||
"generation": "aa31bf16-984e-4854-b46f-15655bd6cc67",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-playable-exports-8wzkrc_u/Faset Café 世界/lua",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 32,
|
||||
"asset_generations": {},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.584992,
|
||||
"min": 0.551712,
|
||||
"p50": 0.5608,
|
||||
"p95": 0.574592,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 4.928888,
|
||||
"min": 1.544123,
|
||||
"p50": 1.919881,
|
||||
"p95": 2.423702,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 4.923196,
|
||||
"min": 1.540666,
|
||||
"p50": 1.915753,
|
||||
"p95": 2.420426,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.837363,
|
||||
"min": 0.395756,
|
||||
"p50": 0.504853,
|
||||
"p95": 0.641169,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.210056,
|
||||
"min": 0.084289,
|
||||
"p50": 0.122261,
|
||||
"p95": 0.171062,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.254931,
|
||||
"min": 0.046518,
|
||||
"p50": 0.065754,
|
||||
"p95": 0.087906,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 5.322149,
|
||||
"min": 1.702973,
|
||||
"p50": 2.142903,
|
||||
"p95": 2.634219,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 4,
|
||||
"sha256": "e2f4c3b84de75dadd2e31d388d0ba51abc1861f1ec76eb7ba51a4a2dcac720a7"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
}
|
||||
],
|
||||
"requested_projects": [
|
||||
"lua"
|
||||
],
|
||||
"finished_utc": "2026-09-23T23:32:18.151669+00:00"
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
==========
|
||||
VULKANINFO
|
||||
==========
|
||||
|
||||
Vulkan Instance Version: 1.4.341
|
||||
|
||||
|
||||
Instance Extensions: count = 27
|
||||
-------------------------------
|
||||
VK_EXT_acquire_drm_display : extension revision 1
|
||||
VK_EXT_acquire_xlib_display : extension revision 1
|
||||
VK_EXT_debug_report : extension revision 10
|
||||
VK_EXT_debug_utils : extension revision 2
|
||||
VK_EXT_direct_mode_display : extension revision 1
|
||||
VK_EXT_display_surface_counter : extension revision 1
|
||||
VK_EXT_headless_surface : extension revision 1
|
||||
VK_EXT_layer_settings : extension revision 2
|
||||
VK_EXT_surface_maintenance1 : extension revision 1
|
||||
VK_EXT_swapchain_colorspace : extension revision 5
|
||||
VK_KHR_device_group_creation : extension revision 1
|
||||
VK_KHR_display : extension revision 23
|
||||
VK_KHR_external_fence_capabilities : extension revision 1
|
||||
VK_KHR_external_memory_capabilities : extension revision 1
|
||||
VK_KHR_external_semaphore_capabilities : extension revision 1
|
||||
VK_KHR_get_display_properties2 : extension revision 1
|
||||
VK_KHR_get_physical_device_properties2 : extension revision 2
|
||||
VK_KHR_get_surface_capabilities2 : extension revision 1
|
||||
VK_KHR_portability_enumeration : extension revision 1
|
||||
VK_KHR_surface : extension revision 25
|
||||
VK_KHR_surface_maintenance1 : extension revision 1
|
||||
VK_KHR_surface_protected_capabilities : extension revision 1
|
||||
VK_KHR_wayland_surface : extension revision 6
|
||||
VK_KHR_xcb_surface : extension revision 6
|
||||
VK_KHR_xlib_surface : extension revision 6
|
||||
VK_LUNARG_direct_driver_loading : extension revision 1
|
||||
VK_NV_display_stereo : extension revision 1
|
||||
|
||||
Instance Layers: count = 12
|
||||
---------------------------
|
||||
VK_LAYER_INTEL_nullhw INTEL NULL HW 1.1.73 version 1
|
||||
VK_LAYER_KHRONOS_validation Khronos Validation Layer 1.4.341 version 1
|
||||
VK_LAYER_MESA_anti_lag Open-source implementation of the VK_AMD_anti_lag extension. 1.4.303 version 1
|
||||
VK_LAYER_MESA_device_select Linux device selection layer 1.4.303 version 1
|
||||
VK_LAYER_MESA_overlay Mesa Overlay layer 1.4.303 version 1
|
||||
VK_LAYER_MESA_screenshot Mesa Screenshot layer 1.4.303 version 1
|
||||
VK_LAYER_NV_optimus NVIDIA Optimus layer 1.4.329 version 1
|
||||
VK_LAYER_NV_present NVIDIA Presentation Layer 1.4.329 version 1
|
||||
VK_LAYER_VALVE_steam_fossilize_32 Steam Pipeline Caching Layer 1.3.207 version 1
|
||||
VK_LAYER_VALVE_steam_fossilize_64 Steam Pipeline Caching Layer 1.3.207 version 1
|
||||
VK_LAYER_VALVE_steam_overlay_32 Steam Overlay Layer 1.3.207 version 1
|
||||
VK_LAYER_VALVE_steam_overlay_64 Steam Overlay Layer 1.3.207 version 1
|
||||
|
||||
Devices:
|
||||
========
|
||||
GPU0:
|
||||
apiVersion = 1.4.329
|
||||
driverVersion = 595.84.0.0
|
||||
vendorID = 0x10de
|
||||
deviceID = 0x1e04
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||
deviceName = NVIDIA GeForce RTX 2080 Ti
|
||||
driverID = DRIVER_ID_NVIDIA_PROPRIETARY
|
||||
driverName = NVIDIA
|
||||
driverInfo = 595.84
|
||||
conformanceVersion = 1.4.3.3
|
||||
deviceUUID = 2c71c7ba-97ac-c78e-2c06-af362631f3fe
|
||||
driverUUID = 027cbdd1-c478-513e-af69-ebc9eaa7de87
|
||||
GPU1:
|
||||
apiVersion = 1.4.335
|
||||
driverVersion = 26.0.8
|
||||
vendorID = 0x10005
|
||||
deviceID = 0x0000
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_CPU
|
||||
deviceName = llvmpipe (LLVM 21.1.8, 256 bits)
|
||||
driverID = DRIVER_ID_MESA_LLVMPIPE
|
||||
driverName = llvmpipe
|
||||
driverInfo = Mesa 26.0.8-1ubuntu0.3 (LLVM 21.1.8)
|
||||
conformanceVersion = 1.3.1.1
|
||||
deviceUUID = 6d657361-3236-2e30-2e38-2d3175627500
|
||||
driverUUID = 6c6c766d-7069-7065-5555-494400000000
|
||||
WARNING: [Loader Message] Code 0 : ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPlanePropertiesKHR!
|
||||
WARNING: [Loader Message] Code 0 : ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPropertiesKHR!
|
||||
Binary file not shown.
@@ -0,0 +1,138 @@
|
||||
# P1 gameplay iteration: measured Linux workflow
|
||||
|
||||
The [unaltered version 2 workflow report](report.json) was produced by a clean
|
||||
`6c2e8fa80036315a695f67f3c53524165fb4b10a` checkout on 2026-09-24.
|
||||
It used disposable copies of the checked-in `collect-3d` and `examples/lua`
|
||||
projects. Every sample, process log and Player profile is retained under `raw/`;
|
||||
[the run log](workflow.log) shows the order and completion. The report identifies
|
||||
each input revision by SHA-256, and records all command arguments, phase labels,
|
||||
configuration and dirty-tree state. Its SHA-256 is
|
||||
`fd463c0cd12eed0a22143aa68bd732386804b0df4ecb2a3d9caa26f59dcfe6e2`.
|
||||
|
||||
The original report's `toolchain.slang` is `null` because that version looked
|
||||
for `slangc` on `PATH`, while CMake used a configured executable. A **separate**
|
||||
[post-run provenance supplement](provenance.json), generated after commit
|
||||
`abd8c21` from the surviving disposable [compressed CMake cache](CMakeCache.txt.gz), hashes
|
||||
the selected CMake, Ninja, C/C++ compiler, Slang, Editor and UI-probe binaries.
|
||||
It binds to the original report hash and records both script revisions. The
|
||||
measured report was not rewritten. Subsequent workflow runs include these
|
||||
identities in their report directly. `4ac02ee` changed only the Windows CI export
|
||||
fixture location; neither follow-up is presented as the measured code revision.
|
||||
|
||||
## Measurement conditions and results
|
||||
|
||||
The host ran Linux 7.0, Ryzen 7 1700, 32 GiB RAM, RTX 2080 Ti and NVIDIA 595.84.
|
||||
The disposable project used Debug, Clang 21.1.8, CMake 4.2.3, Ninja 1.13.2 and
|
||||
Slang 2026.18. The Player rendered offscreen Vulkan at 1280×720 with validation
|
||||
active and full-frame readback. The run did not overlap the separate P3 GPU sweep.
|
||||
Build times still depend on ambient CPU load, filesystem cache and prepared
|
||||
dependencies. The `cold` row means an empty project `.faset` cache, **not** a cold
|
||||
OS page cache or a first dependency download.
|
||||
|
||||
| Observation | Samples | Median | Nearest-rank p95 | Scope |
|
||||
| --- | ---: | ---: | ---: | --- |
|
||||
| Initial configure and native build | 1 | 106.01 s | — | Disposable Debug project |
|
||||
| Unchanged build | 5 | 11.53 s | 13.12 s | All five reused the verified schema/package generation |
|
||||
| Changed `Gameplay.cpp` build | 5 | 28.16 s | 30.33 s | One warm-up edit excluded |
|
||||
| Changed `Gameplay.hpp` build | 5 | 23.89 s | 25.51 s | One warm-up edit excluded |
|
||||
| Watched Lua edit to reload log | 5 | 0.502 s | 0.504 s | Persistent Player; includes watcher polling |
|
||||
| First completed offscreen Player frame | 5 | 0.284 s | 0.333 s | From `main()`; excludes OS loader and window presentation |
|
||||
| Synthetic Editor input to rendered state | 100 | 13.97 ms | 18.03 ms | Ten warm-ups; offscreen retained-UI frame, not input-to-photon |
|
||||
|
||||
The intentional C++ compile failure took 10.00 s and the corrected recovery
|
||||
build 19.93 s. The failed job preserved its prior successful build pointer.
|
||||
The run also imported the small Blender bundle cold and cached in 49 and 52 ms,
|
||||
respectively; Editor process startup dominates that tiny asset sample, so those
|
||||
two values do not establish import-cache speedup. The raw
|
||||
[failed-build job](raw/build_failure-01-stdout.txt) exposed a navigation defect:
|
||||
the compiler named the staged source copy, and the original structured
|
||||
diagnostic omitted `file`. A later fix maps only the verified staged `Scripts`
|
||||
subtree to project-relative source. A [real failed-build replay](diagnostic-replay.json)
|
||||
with the corrected Editor returns `Scripts/Gameplay.cpp`, line 73, column 2.
|
||||
The `build_diagnostics` test also covers project-contained snapshot paths and
|
||||
Windows drives; `build_schema_publication` verifies that an error after 250
|
||||
third-party warnings survives the 200-row diagnostic limit. These are separate
|
||||
from this unmodified measurement.
|
||||
|
||||
Follow-up `54d1bae` rehashes both the live source and the staged copy after
|
||||
native build and before reuse/publication. A fixture changes the staged C++
|
||||
header during schema export; the build fails and retains the last-good pointer.
|
||||
The copy is content-verified at those boundaries, not sealed against a same-user
|
||||
write-and-restore during compiler reads.
|
||||
|
||||
The [3,000-frame lifecycle profile](raw/cpp-3000-frame-lifecycle.json) completed
|
||||
with zero Vulkan validation errors. Maximum explicit Vulkan allocation was
|
||||
15,787,008 bytes in both frames 101–200 and 2901–3000, a measured growth of zero;
|
||||
the live texture count remained one. These counters exclude driver-internal
|
||||
memory and do not prove absence of all resource leaks.
|
||||
|
||||
The generated [527-entity scene](raw/generated-512.scene.json) adds 512 seeded
|
||||
copies to the 15-entity source and ran for 240 offscreen frames with zero Vulkan
|
||||
validation errors. Its [raw profile](raw/generated-512-profile.json) reports p95
|
||||
frame wall 149.39 ms, simulation 48.19 ms, scene snapshot 68.12 ms, renderer call
|
||||
36.51 ms and GPU timestamp 0.911 ms. It exposes a significant CPU scaling cost
|
||||
in this synthetic content; it is not a typical-game benchmark or a Release budget
|
||||
failure for the tiny checked-in sample.
|
||||
|
||||
## Reference budgets and coverage
|
||||
|
||||
The [2026-09-18 Release reference baseline](../linux-release-2026-09-18/README.md)
|
||||
measured the **exact** `collect-2d` and `collect-3d` packaged scenes on this host,
|
||||
at 1280×720 with validation/readback. Its 240-frame p95s met the initial tracking
|
||||
budgets: frame 2.684/2.732 ms versus ≤4; GPU 0.579/0.600 ms versus ≤1; readback
|
||||
0.633/0.608 ms versus ≤1; simulation 0.258/0.300 ms and snapshot 0.215/0.257 ms
|
||||
versus ≤0.5 each. Explicit allocations were about 15.02/15.06 MiB versus
|
||||
≤20 MiB; first-frame startup from `main()` was 265.5/260.8 ms versus ≤500 ms.
|
||||
That baseline was an evolving earlier working tree. Its values are **historical**
|
||||
and are not compared with this Debug workflow's timing.
|
||||
|
||||
The [fresh clean combined P1/P3 Release reference](final-release/README.md) at
|
||||
`4a3453e` repeats these exact scenes on the same physical RTX 2080 Ti, now with
|
||||
120-frame source-hidden relocation checks for C++ 2D/3D and Lua-only, plus
|
||||
sequential 240-frame C++ 2D/3D profiles. The frame, GPU, readback, simulation,
|
||||
snapshot and startup tracking budgets all pass. Explicit allocations instead
|
||||
reach **43.022/43.118 MiB**, above the former ≤20 MiB budget because the new
|
||||
renderer eagerly retains a 16 MiB sun atlas and a 16 MiB local atlas in both
|
||||
scenes. The 2D sample casts no sun shadows and neither sample uses local shadow
|
||||
faces. This is a measured tracking-budget miss, not a failed export or a reason
|
||||
to redefine the counter silently. The linked dossier retains exact values,
|
||||
atlas breakdown, raw profiles and source/toolchain provenance.
|
||||
|
||||
The [Lua-only Linux Release dossier](../lua-release-2026-09-24/README.md) separately
|
||||
records a relocated package that validated and rendered 120 frames after hiding
|
||||
its source project, with 0 validation errors. The final fixture placement was
|
||||
checked in clean-revision [`4ac02ee` Windows graphics CI](https://github.com/emil28092005/Faset_Engine/actions/runs/35937433040):
|
||||
61/61 CTests passed on pinned SwiftShader, the real 2D/3D Release export
|
||||
integration passed, and **all three** relocated Release games (`collect-2d`,
|
||||
`collect-3d`, Lua-only) validated and rendered 120/120 frames with source paths
|
||||
unavailable. The [Windows playable report](windows-4ac02ee/playable-report.json)
|
||||
contains package and source hashes, device identity, result details and capture
|
||||
checksums; [integration results](windows-4ac02ee/integration-result-2.json),
|
||||
[integration manifests](windows-4ac02ee/integration-manifest-2.json),
|
||||
[Vulkan probe](windows-4ac02ee/vulkan-probe.json) and
|
||||
[toolchain record](windows-4ac02ee/toolchain.json) preserve representative raw
|
||||
evidence. The parallel [native/manual CI](https://github.com/emil28092005/Faset_Engine/actions/runs/35937433211)
|
||||
passed on Linux and Windows. This is **software** Vulkan; Windows did not have an
|
||||
active Khronos validation layer (`validation_enabled: false`), and no physical
|
||||
Windows GPU/driver performance claim follows. The later [combined P1/P3 Windows
|
||||
graphics CI](https://github.com/emil28092005/Faset_Engine/actions/runs/35942307579)
|
||||
at `87230f3` passed 74/74 CTests, including real diagnostic navigation, real
|
||||
Release export integration and all three relocated games. The physical-GPU
|
||||
Linux reference above had active validation.
|
||||
|
||||
## P1 acceptance record
|
||||
|
||||
| Area | Evidence and current limit |
|
||||
| --- | --- |
|
||||
| Lua | Linux native and Release [relocated Lua result](../lua-release-2026-09-24/README.md), repeated in the [clean combined three-game Release reference](final-release/README.md); Windows CPU/SwiftShader [combined 74-test suite](https://github.com/emil28092005/Faset_Engine/actions/runs/35942307579) and [relocated Lua-only Release report](windows-4ac02ee/playable-report.json), 120 completed frames. |
|
||||
| Cache and rollback | [Five verified hits](report.json), `build_cache` and `build_schema_publication` contracts for headers, toolchain, schema/shader corruption and source races; the raw failed/recovered build retains the previous pointer. |
|
||||
| Diagnostics | `build_diagnostics` fixtures cover Clang, clang-cl, Lua, Unicode and unparseable output. The raw real failure above found a staged-source mapping gap; [the replay](diagnostic-replay.json), parser case, warning-flood case and real BuildService integration assertion cover the correction. |
|
||||
| Starters/navigation | [Four runnable C++/Lua × 2D/3D starters](../p1-starters-linux-2026-09-24.md) plus launcher/CLI and source-open tests. |
|
||||
| Autosave | `editor_session_settings`, UI tests and [workspace behavior](../../manual/editor/workspace.md#create-and-save-a-scene): idle coalescing, unnamed Save As, external/revision conflicts, Undo and recovery. |
|
||||
| Iteration | This Debug report, 179 raw files, 3,000-frame and seeded larger-scene profiles, plus the [clean combined Release reference](final-release/README.md) with three relocated games and exact 2D/3D budgets. The allocation budget miss is recorded; no CI timing gates. |
|
||||
| Documentation | The English Manual describes build/reload, templates, navigation, autosave and profile interpretation; strict MkDocs and full platform test totals are recorded in the implementation journal. |
|
||||
|
||||
The [profiling guide](../../manual/editor/profiling.md#measure-editor-c-and-lua-iteration)
|
||||
documents how to repeat the run and interpret its deliberately distinct timing
|
||||
labels. C++ hot reload, state-preserving Lua reload and Player-world MCP are not
|
||||
part of this P1 contract.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,111 @@
|
||||
# Final combined P1/P3 Release reference — 2026-09-24
|
||||
|
||||
This is the clean-source, physical-GPU reference for the checked-in playable
|
||||
`collect-2d`, `collect-3d`, and Lua-only games at
|
||||
`4a3453e2b1868555d833f578d43f48b8bc47d41a`. The real Release Editor
|
||||
exported each project to a self-contained package. The packages were copied to
|
||||
Unicode-named paths outside their disposable source projects, and those source
|
||||
paths were hidden while each Player ran from an unrelated empty working
|
||||
directory. The 3D export imported and packaged the Blender exit arch. All three
|
||||
games passed standalone CPU validation and rendered **120/120** offscreen Vulkan
|
||||
frames on the physical NVIDIA GeForce RTX 2080 Ti with the Khronos validation
|
||||
layer active and **zero validation errors**. The [verifier report](report.json),
|
||||
[2D manifest](evidence/collect-2d-manifest.json),
|
||||
[3D manifest](evidence/collect-3d-manifest.json), and
|
||||
[Lua manifest](evidence/lua-manifest.json) retain input, package and binary
|
||||
hashes. The [toolchain supplement](provenance.json) binds the unmodified report
|
||||
and 240-frame summary to the exact Editor, CMake, Ninja, Clang and Slang
|
||||
binaries. The verifier recorded a clean checkout at its start, and the second
|
||||
profiles used the same relocated Player binaries.
|
||||
|
||||
| Relocated package | Runtime | Frames | GPU validation | Source paths hidden |
|
||||
| --- | --- | ---: | --- | --- |
|
||||
| `collect-2d` | C++ | 120/120 | active, 0 errors | yes |
|
||||
| `collect-3d` | C++ with Blender asset | 120/120 | active, 0 errors | yes |
|
||||
| `lua` | Lua-only | 120/120 | active, 0 errors | yes |
|
||||
|
||||
The two **same relocated C++ executables** then ran a second, sequential
|
||||
240-frame profile. For each run, the disposable source-project paths were again
|
||||
hidden and restored afterward. These exact 2D/3D samples used default Direct
|
||||
visibility and temporal Off, 1280×720 offscreen Vulkan, synchronous readback,
|
||||
the active Khronos validation layer and synthetic fixed-step simulation. No
|
||||
frame was discarded as a warm-up: the table uses nearest-rank p95 over all 240
|
||||
completed frames, including the first. Both profiles report zero validation
|
||||
errors. Raw [2D](reference-240/collect-2d-profile-240.json) and
|
||||
[3D](reference-240/collect-3d-profile-240.json) profiles, exact
|
||||
[2D invocation](reference-240/collect-2d-run-240.json) and
|
||||
[3D invocation](reference-240/collect-3d-run-240.json), and the
|
||||
[machine-readable budget comparison](reference-240/reference-summary.json)
|
||||
support every value below.
|
||||
|
||||
| Exact-scene observation | Initial P1 tracking budget | 2D | 3D |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| Frame wall p95 | ≤4 ms | 2.694 ms | 3.036 ms |
|
||||
| GPU timestamp p95 | ≤1 ms | 0.573 ms | 0.617 ms |
|
||||
| Readback CPU p95 | ≤1 ms | 0.559 ms | 0.561 ms |
|
||||
| Simulation p95 | ≤0.5 ms | 0.242 ms | 0.300 ms |
|
||||
| Scene snapshot p95 | ≤0.5 ms | 0.197 ms | 0.288 ms |
|
||||
| `main()` to first frame | ≤500 ms | 295.4 ms | 248.3 ms |
|
||||
| Maximum explicit Vulkan allocation | ≤20 MiB | **43.022 MiB — miss** | **43.118 MiB — miss** |
|
||||
|
||||
The memory miss is real, not a profile rounding artifact: 2D used 45,112,032
|
||||
bytes and 3D used 45,212,272 bytes, while the earlier threshold was 20,971,520
|
||||
bytes. Each run counted a **16 MiB sun atlas and a 16 MiB local-light atlas**
|
||||
inside the live Vulkan allocation total. The 2D sprites produced no sun-shadow
|
||||
raster work; the 3D meshes rendered four sun cascades. Neither sample used a
|
||||
local shadow face. Both 2048² D32 atlases are currently allocated when the
|
||||
Renderer is created, even when the scene never uses them. The remaining explicit
|
||||
allocations were 11.022 MiB (2D) and 11.118 MiB (3D). Lazy local-atlas
|
||||
allocation is a sensible follow-up, but alone it would still leave the 3D
|
||||
scene above 20 MiB with its current 2048² sun atlas. We have kept the physical
|
||||
counter and shadow resolution intact and recorded the miss rather than silently
|
||||
changing either to satisfy an older threshold. The 20 MiB value is an initial
|
||||
**tracking budget** for tiny pre-P3 scenes, not a functional export gate; any
|
||||
revised shadow-memory budget needs its own measured baseline.
|
||||
|
||||
The Lua run establishes relocated Release execution, not a 2D/3D latency
|
||||
budget. The [2026-09-18 Release reference](../../linux-release-2026-09-18/README.md)
|
||||
used these scenes on the same GPU but an evolving earlier working tree; its
|
||||
numbers are historical context, not this clean combined revision. This run
|
||||
measures small scenes on one active Linux desktop and one driver (NVIDIA
|
||||
595.84). GPU timestamps exclude CPU work, `renderer_readback_cpu` is a
|
||||
map/copy/unmap duration inside the renderer call, and the explicit allocation
|
||||
counter excludes driver-internal memory. It does not establish production-game
|
||||
scaling, whole-process VRAM usage, display-paced FPS, physical Windows GPU
|
||||
performance or absence of all leaks.
|
||||
|
||||
## Reproduce and inspect
|
||||
|
||||
From this repository with the dependencies configured:
|
||||
|
||||
```sh
|
||||
cmake --preset linux-release
|
||||
cmake --build --preset linux-release --target faset_editor --parallel 2
|
||||
python3 tools/verify_playable_exports.py \
|
||||
--editor build/linux-release/faset_editor \
|
||||
--output /tmp/faset-p1-release-new \
|
||||
--standalone-root /tmp/faset-p1-packages-new \
|
||||
--include-lua
|
||||
python3 docs/validation/p1-iteration-2026-09-24/final-release/profile_exact_scenes.py \
|
||||
--verification /tmp/faset-p1-release-new/report.json \
|
||||
--output /tmp/faset-p1-release-new/reference-240
|
||||
```
|
||||
|
||||
Use **new, empty** output and standalone directories. The second helper
|
||||
refuses an incomplete or dirty-tree verifier report, hides the disposable
|
||||
source projects during each 240-frame run, checks exact settings and validation,
|
||||
then restores them. The original [verifier log](verifier.log),
|
||||
[240-frame log](reference-240.log), raw 120-frame profiles for
|
||||
[2D](evidence/collect-2d-profile.json),
|
||||
[3D](evidence/collect-3d-profile.json) and
|
||||
[Lua](evidence/lua-profile.json), PPM captures, and the
|
||||
[SHA-256 file list](SHA256SUMS.txt) are retained here. The
|
||||
large disposable native build directories and relocated executable packages
|
||||
remain under `/tmp`; their input, manifest and executable hashes are in the
|
||||
reports.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
@@ -0,0 +1,35 @@
|
||||
d5dca233d7ddbb7c32998ec920fda6cf67e6515c965372985c807ccd4ff54075 README.md
|
||||
d23e8614c133938974d1c1a865100d24175242ab818573cb1416ba82d1e62260 collect-2d.png
|
||||
f83799304917c2e0250605e83f69cbee4865818078ba3f9aed590c010f2b19b3 collect-3d.png
|
||||
3ca7066843c2875c86a4917782a07f93358a44ebd220d25a3f2457ae542ec415 evidence/collect-2d-export.json
|
||||
5f8de3eb000dc7207b256265f0fa20a29efe194dd1347ab4c3bf670cfdcfb2b0 evidence/collect-2d-manifest.json
|
||||
c45dc33981db0c2038d22cda2be4151de46445a4f368259d6b0002c35e402633 evidence/collect-2d-profile.json
|
||||
591329c7cb85c9fc0220deec7e76ca24e139037481d949c91882858c76c2621a evidence/collect-2d-run.json
|
||||
af24b1c312e67b0e0cbe2b5871888db17b9bb47e95eca5028c9e07d72b2f1bea evidence/collect-2d-validate.json
|
||||
f9d74067d87c1ebf30c6db372a26d93b7285791c8cb0307a24af5adb23bf201a evidence/collect-2d.ppm
|
||||
a00c55bbda0242e924781b4ca9d73910741506dce4df93dafde8d729389511a8 evidence/collect-3d-export.json
|
||||
7e09c5ae35c8f998510b83af51ded67bba0bc7483f8cfdb17a785368a8f9b2ca evidence/collect-3d-import.json
|
||||
484eda90411c48277385a2f679561cfa6304965a7a7be6ec065bfbd9dace1722 evidence/collect-3d-manifest.json
|
||||
96193de60cf7fa139fc110c99628e065779a378151e816ce947129ed4217f9a0 evidence/collect-3d-profile.json
|
||||
17e2ea46f9811432018704fa2468850f015b113f3407525bf795c21cf44b4fcb evidence/collect-3d-run.json
|
||||
f102446ff954cf1e9062726772a868ff1a30783da5ff77e2c3486227e8acc867 evidence/collect-3d-validate.json
|
||||
2905891c9766b2f1f65d5b4284056cb3839f1faae195f9fea39a56e3ebf44363 evidence/collect-3d.ppm
|
||||
737db5241ea2caba9393e18dbcf1e48ef6c106ae6f4fdc6ac3bfe0e2fc43325c evidence/lua-export.json
|
||||
3caecdb756b289c2bd1f61ec4e5a8c5194b35166f34f332a1651a5a846e7f631 evidence/lua-manifest.json
|
||||
eb985bd647266529ab98d0535150e20e7c54692a2546e0df935bbcfb71cbca66 evidence/lua-profile.json
|
||||
acce29b23725fba6a54e2e70827b0bd92137408eacaec4f58f5dee37666a8d0c evidence/lua-run.json
|
||||
f44cbe6db9ac6170c4db7f6f502fe09d62cc5da1e2535fe93cc474f6a28293ca evidence/lua-validate.json
|
||||
e2f4c3b84de75dadd2e31d388d0ba51abc1861f1ec76eb7ba51a4a2dcac720a7 evidence/lua.ppm
|
||||
5e395b08f275eadc6066697204abf2287e9a1ea124cba6cf6f5deca3924282aa evidence/vulkaninfo-summary.txt
|
||||
19c9b2c5a401af52980604fa074f89fe9452cfa728a606ad937c509a1c4164eb lua.png
|
||||
5d69428a1202c1e144779074c0ab88360c459e2dd99b22c1fcf8929dbeab2618 profile_exact_scenes.py
|
||||
fa49dae530785e24fe028ee5d0ade949fab61d540b118d8bf96d787267e6f87b provenance.json
|
||||
65858b1de2334d304ad3a0907180aaf4f79ead3da63762500e50b7298d922bfa reference-240/collect-2d-profile-240.json
|
||||
0d117fc6571fc497271921e818c97c729aeb58da6613bb2b1f24c815ae171319 reference-240/collect-2d-run-240.json
|
||||
b0c4c6b4020b1ded792917fff1f36510b76bb30864d89bd4e6e250b5693c5fe8 reference-240/collect-3d-profile-240.json
|
||||
ebbc376e8788b11b31f1eb7a767142348bcc6a6986e0593e20b44cb0e2d1e65d reference-240/collect-3d-run-240.json
|
||||
63da692b605621acc1cace00d4a3c9cf35de13abfd4351aea6653a88c870e03f reference-240/playable-report.json
|
||||
f8297f3cb0578addee56c0b3cb9439b37ae37707b02d433d662b534620f329e9 reference-240/reference-summary.json
|
||||
d97939ba5cee29ae237568c00714b68ab6849c4c506987cff05392750da5e0ca reference-240.log
|
||||
63da692b605621acc1cace00d4a3c9cf35de13abfd4351aea6653a88c870e03f report.json
|
||||
f4a0f3a487a5d7180caa08c8c254d2e39bad5d6cf5c4877d131af3dbd98fa777 verifier.log
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
File diff suppressed because one or more lines are too long
+269
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"asset_generations": {},
|
||||
"build_fingerprint": "b2559255996b7990919d5aa15cbfa53c225a0ee299e6a43ffbf04cd8bbb606db",
|
||||
"configuration": "Release",
|
||||
"executable": "faset_player",
|
||||
"files": [
|
||||
{
|
||||
"path": "README.txt",
|
||||
"sha256": "82bf72bc542643f6c4090e0a5de69b0014ca3fa17c6f9dfb12cc41e44c8b8db6",
|
||||
"size": 262
|
||||
},
|
||||
{
|
||||
"path": "Notices/Faset-NOTICE.txt",
|
||||
"sha256": "30c2e7e80f5153b31ab57675e07246aef9165965d64e36022b426a26449ece3f",
|
||||
"size": 204
|
||||
},
|
||||
{
|
||||
"path": "Notices/dependencies.json",
|
||||
"sha256": "a54639ad2d9ad13c2e5f1ec90d6775f5dfc493656789b78c7e44debe2a378fdc",
|
||||
"size": 2206
|
||||
},
|
||||
{
|
||||
"path": "Notices/stb/LICENSE",
|
||||
"sha256": "bebfe904b14301657e4e5d655c811d51fd31b97c455b9cc2d8600d6bac6cff63",
|
||||
"size": 2510
|
||||
},
|
||||
{
|
||||
"path": "Notices/json/LICENSE.MIT",
|
||||
"sha256": "46a65cffd1ea955132d95a8dd921640714a8d6b537d2e4e482d31145ae95b603",
|
||||
"size": 1076
|
||||
},
|
||||
{
|
||||
"path": "Notices/box3d/LICENSE",
|
||||
"sha256": "da5e31a26bf3cfd5ba5c96d6823e480128c81e76c107ef9d3ee5d94789184b90",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/box2d/LICENSE",
|
||||
"sha256": "68a3e676d7e94093b102d5cba0d4e04af812040d6f230c3db67a6664574e43d2",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/entt/LICENSE",
|
||||
"sha256": "0785027ce472d7c61f05fba664a1d3ba6639c1593ced351ad9e4bed868765d99",
|
||||
"size": 1097
|
||||
},
|
||||
{
|
||||
"path": "Notices/sdl3/LICENSE.txt",
|
||||
"sha256": "97f35b302b361680ec1e891e95d2d52097bb95abff361434916d99dc1305f127",
|
||||
"size": 884
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuTemporalVertexMain.reflection.json",
|
||||
"sha256": "7a8efe2645e7ce465ca44d19f8cfb2eb6c767abd1c3ce12ed69a149a50be8a8c",
|
||||
"size": 3308
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuTemporalVertexMain.spv",
|
||||
"sha256": "dfe7309aafbd41974668b295e179354965db440e4156b9f12d6a67db16b357f9",
|
||||
"size": 5996
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalFragmentMain.reflection.json",
|
||||
"sha256": "e36452227788f3703d7342b6d9a7a0efef74ce4da3aa96bb176a26e169ec3628",
|
||||
"size": 3874
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalFragmentMain.spv",
|
||||
"sha256": "03adc6673276979b3ea46becf3a36940d3061af77cb8c965c7471feff8dbf89a",
|
||||
"size": 30976
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalVertexMain.reflection.json",
|
||||
"sha256": "6f7812ce88b14bca62a6d2ad82a8657e2ee48c252558f34677c6a2bd980a7edb",
|
||||
"size": 3935
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalVertexMain.spv",
|
||||
"sha256": "6cc3535c952a33ee46fd417fbec7fcad8f24357508b2119256b3077be3d60955",
|
||||
"size": 1784
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeFragmentMain.reflection.json",
|
||||
"sha256": "44765a41fc362c9a97b1a19834f285e2e7facb24d8715e3d8559b8e9633a7a0e",
|
||||
"size": 959
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeFragmentMain.spv",
|
||||
"sha256": "9e21c8534c0e70a58ae018fb2d143bf9cfb70112e71b67585f525eef0aecad1b",
|
||||
"size": 768
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeVertexMain.reflection.json",
|
||||
"sha256": "a3a2ea858bd038423896043b0703704f707addceb5bd56721cd897f6bd092065",
|
||||
"size": 956
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeVertexMain.spv",
|
||||
"sha256": "6b19f65b64f40d0a249660fdfba9dd5d95831ffab7314a307bf1f5cf39c6a248",
|
||||
"size": 340
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalResolveMain.reflection.json",
|
||||
"sha256": "9407ee1522f32df231d996ea691224863c023c1ca42cc02ccd7e16de1d873082",
|
||||
"size": 3179
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalResolveMain.spv",
|
||||
"sha256": "4c5fc0da7a4c424e5426694c2c2d9f3cd17d1a64066712f5defe882ad8776662",
|
||||
"size": 22192
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.reflection.json",
|
||||
"sha256": "19ce128388c7f88e0c517fb58a25e46f1382e35ae5f376b10eebe155a2811c4c",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.reflection.json",
|
||||
"sha256": "589818f670881c64f3aba726ee3bc82fe4b9d835a347f99134e0e157dc4a112e",
|
||||
"size": 2050
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.reflection.json",
|
||||
"sha256": "8986a45a8d29743d16f0caece9181b18c85d6490d93b4a56cdb4f53052890f3f",
|
||||
"size": 3587
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.reflection.json",
|
||||
"sha256": "96b3620b163dadf214933cfba6600b1b6a835c4d98b75b1f83e6ccd3dedb2425",
|
||||
"size": 2755
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.reflection.json",
|
||||
"sha256": "01a6cc1bbf3c11c558560d6f8557fd4582d392906ed20a8c729673d0ebf640ed",
|
||||
"size": 3098
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.spv",
|
||||
"sha256": "1f8edd3be1f99f9433494a6f7be68f1317d6e7099e19354a7b8130d5d932224d",
|
||||
"size": 12548
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.spv",
|
||||
"sha256": "08682362ee2120ed19d260e613285071747c3e436bb09bb6238e46f9cedc2308",
|
||||
"size": 4140
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.spv",
|
||||
"sha256": "e5ea6589ddb3613b59f8e58420be95a534cf4149816bc65bae26b1395c638955",
|
||||
"size": 16288
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.spv",
|
||||
"sha256": "f56e0ae3e9b31cb1e3f24e379c81e11c853f8a7102648aaaebc92a17c7e8e53c",
|
||||
"size": 2492
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.spv",
|
||||
"sha256": "32421d4a91f3a88d5210fee7af34b48bcad83072f14e2ccb9ef2ff983e45f78f",
|
||||
"size": 5016
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.reflection.json",
|
||||
"sha256": "d39e2f83c797589296eac9dce139b9ad836a895d6685bc40f79dd2609d687fee",
|
||||
"size": 3597
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.reflection.json",
|
||||
"sha256": "2b07af2aae7578bdb6c2aa22658538821608b1dd5aeddd7b06e42b2e78cedf12",
|
||||
"size": 3596
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.reflection.json",
|
||||
"sha256": "b3bdff863d53a0b385e06a36701a83a6ecafe9a93e97281a732cce8ff862c0db",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/lightTileMain.reflection.json",
|
||||
"sha256": "bf6a9256aaa6d6edacfa1e1c265d7c8ce2c1e4ea4036e0bea078c22fd4b536ca",
|
||||
"size": 1978
|
||||
},
|
||||
{
|
||||
"path": "shaders/lightTileMain.spv",
|
||||
"sha256": "92850edcc5ee5b586a90ce84ee69a98075a6fff3c13db4a57528d9431afe8b68",
|
||||
"size": 6800
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.spv",
|
||||
"sha256": "7643b4d688492b5ee923b9606f0b0e70343ca05fa67673838206119a6f86d8d8",
|
||||
"size": 784
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.spv",
|
||||
"sha256": "fea4dd48664a510bad12b5e8582f2db798d4dbea62ce0de35dc2acfe32372733",
|
||||
"size": 28960
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.spv",
|
||||
"sha256": "1ad2631c35d654f48166321ae43d4165043e1b919b14f1dc61caf97b1ada0898",
|
||||
"size": 1224
|
||||
},
|
||||
{
|
||||
"path": "faset_player",
|
||||
"sha256": "5936d8a1ceae9250c69f1b8ebccbadebc40b13e812bebeb9752da3d14d202a4a",
|
||||
"size": 6154704
|
||||
},
|
||||
{
|
||||
"path": "scene.fscene",
|
||||
"sha256": "0d7b221abc1cae5e9f1d04357c684ac6993f5878d634b4b950eec66dd8e55b2a",
|
||||
"size": 6214
|
||||
}
|
||||
],
|
||||
"format": "faset.export",
|
||||
"generation": "ca306aa8-a094-42bc-833f-a24a05cab73d",
|
||||
"lua_enabled": false,
|
||||
"lua_fingerprint": "",
|
||||
"platform": "linux",
|
||||
"prerequisites": [
|
||||
"Linux x86_64",
|
||||
"Vulkan 1.3 driver",
|
||||
"Compatible glibc and libstdc++ runtime"
|
||||
],
|
||||
"renderer_profile": {
|
||||
"api": "Vulkan 1.3",
|
||||
"materials": [
|
||||
"base-color factor and texture",
|
||||
"metallic and roughness factors"
|
||||
],
|
||||
"required_features": [
|
||||
"dynamicRendering",
|
||||
"synchronization2"
|
||||
],
|
||||
"shadow_atlases": {
|
||||
"caster_draw_limit": 4096,
|
||||
"fallback_resolution": 1024,
|
||||
"local_face_limit": 16,
|
||||
"preferred_resolution": 2048,
|
||||
"sampled_d32_required": true,
|
||||
"sun_cascade_limit": 4
|
||||
},
|
||||
"texture_sampling": "linear clamp, one mip level",
|
||||
"unsupported_material_features": [
|
||||
"normal maps",
|
||||
"metallic-roughness maps",
|
||||
"emissive and occlusion maps",
|
||||
"alpha mode selection",
|
||||
"unlit mode",
|
||||
"per-material face culling"
|
||||
]
|
||||
},
|
||||
"scene_hash": "fdfa1c49cf78a1cf52cd41b201c35bb0b5f852c90b7626b2a7f17da3e2e3e24c",
|
||||
"simulation": {
|
||||
"fixed_delta": 0.016666666666666666,
|
||||
"gravity": [
|
||||
0,
|
||||
-9.81,
|
||||
0
|
||||
],
|
||||
"max_catch_up_ticks": 4,
|
||||
"physics_substeps": 4
|
||||
},
|
||||
"units": {
|
||||
"angle": "radian",
|
||||
"coordinates": "right-handed Y-up",
|
||||
"distance": "metre"
|
||||
},
|
||||
"validation_log": "{\"dimension\":2,\"validated\":true}\n",
|
||||
"version": 1
|
||||
}
|
||||
+7284
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/faset_player",
|
||||
"--headless",
|
||||
"--frames",
|
||||
"120",
|
||||
"--capture",
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/verification.ppm",
|
||||
"--profile",
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/profile.json"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"seconds": 0.6589637870201841,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "New round: collect the three gold cubes, then reach the green exit. E resets.\n{\"device\":\"NVIDIA GeForce RTX 2080 Ti\",\"dimension\":2,\"effective_temporal_mode\":\"off\",\"effective_visibility_mode\":\"direct\",\"frames\":120,\"gpu_visibility_active\":false,\"temporal_mode\":\"off\",\"ticks\":120,\"validation_errors\":0,\"visibility_mode\":\"direct\"}\n",
|
||||
"stderr": ""
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/faset_player",
|
||||
"--validate"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"seconds": 0.008382081025047228,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "{\"dimension\":2,\"validated\":true}\n",
|
||||
"stderr": ""
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+296
@@ -0,0 +1,296 @@
|
||||
{
|
||||
"asset_generations": {
|
||||
"5832763b-3ed0-44d6-9088-0b524f196a91": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2"
|
||||
},
|
||||
"build_fingerprint": "bd02f95edc719dfab9193177d2839502f3322cd85b8fc8f6dcb4f9a2560362b1",
|
||||
"configuration": "Release",
|
||||
"executable": "faset_player",
|
||||
"files": [
|
||||
{
|
||||
"path": "README.txt",
|
||||
"sha256": "82bf72bc542643f6c4090e0a5de69b0014ca3fa17c6f9dfb12cc41e44c8b8db6",
|
||||
"size": 262
|
||||
},
|
||||
{
|
||||
"path": "Notices/Faset-NOTICE.txt",
|
||||
"sha256": "30c2e7e80f5153b31ab57675e07246aef9165965d64e36022b426a26449ece3f",
|
||||
"size": 204
|
||||
},
|
||||
{
|
||||
"path": "Notices/dependencies.json",
|
||||
"sha256": "a54639ad2d9ad13c2e5f1ec90d6775f5dfc493656789b78c7e44debe2a378fdc",
|
||||
"size": 2206
|
||||
},
|
||||
{
|
||||
"path": "Notices/stb/LICENSE",
|
||||
"sha256": "bebfe904b14301657e4e5d655c811d51fd31b97c455b9cc2d8600d6bac6cff63",
|
||||
"size": 2510
|
||||
},
|
||||
{
|
||||
"path": "Notices/json/LICENSE.MIT",
|
||||
"sha256": "46a65cffd1ea955132d95a8dd921640714a8d6b537d2e4e482d31145ae95b603",
|
||||
"size": 1076
|
||||
},
|
||||
{
|
||||
"path": "Notices/box3d/LICENSE",
|
||||
"sha256": "da5e31a26bf3cfd5ba5c96d6823e480128c81e76c107ef9d3ee5d94789184b90",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/box2d/LICENSE",
|
||||
"sha256": "68a3e676d7e94093b102d5cba0d4e04af812040d6f230c3db67a6664574e43d2",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/entt/LICENSE",
|
||||
"sha256": "0785027ce472d7c61f05fba664a1d3ba6639c1593ced351ad9e4bed868765d99",
|
||||
"size": 1097
|
||||
},
|
||||
{
|
||||
"path": "Notices/sdl3/LICENSE.txt",
|
||||
"sha256": "97f35b302b361680ec1e891e95d2d52097bb95abff361434916d99dc1305f127",
|
||||
"size": 884
|
||||
},
|
||||
{
|
||||
"path": "assets/5832763b-3ed0-44d6-9088-0b524f196a91/current.json",
|
||||
"sha256": "b0732959808ce61ef5a3223fba2d9ad8c17a3ea7873d4a81c00aadee6c51032e",
|
||||
"size": 134
|
||||
},
|
||||
{
|
||||
"path": "assets/5832763b-3ed0-44d6-9088-0b524f196a91/generations/4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2/manifest.json",
|
||||
"sha256": "ee3f68794c6dc44ab492b1ba4640aa74e4de79a5ec10aed8dcdd45a03afc508e",
|
||||
"size": 4532
|
||||
},
|
||||
{
|
||||
"path": "assets/5832763b-3ed0-44d6-9088-0b524f196a91/generations/4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2/meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh",
|
||||
"sha256": "3875c16ea628d4126373ebfe07816621fbad3961596a2fcd112f1eec0e378071",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "assets/5832763b-3ed0-44d6-9088-0b524f196a91/generations/4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2/meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "assets/5832763b-3ed0-44d6-9088-0b524f196a91/generations/4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2/meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuTemporalVertexMain.reflection.json",
|
||||
"sha256": "7a8efe2645e7ce465ca44d19f8cfb2eb6c767abd1c3ce12ed69a149a50be8a8c",
|
||||
"size": 3308
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuTemporalVertexMain.spv",
|
||||
"sha256": "dfe7309aafbd41974668b295e179354965db440e4156b9f12d6a67db16b357f9",
|
||||
"size": 5996
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalFragmentMain.reflection.json",
|
||||
"sha256": "e36452227788f3703d7342b6d9a7a0efef74ce4da3aa96bb176a26e169ec3628",
|
||||
"size": 3874
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalFragmentMain.spv",
|
||||
"sha256": "03adc6673276979b3ea46becf3a36940d3061af77cb8c965c7471feff8dbf89a",
|
||||
"size": 30976
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalVertexMain.reflection.json",
|
||||
"sha256": "6f7812ce88b14bca62a6d2ad82a8657e2ee48c252558f34677c6a2bd980a7edb",
|
||||
"size": 3935
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalVertexMain.spv",
|
||||
"sha256": "6cc3535c952a33ee46fd417fbec7fcad8f24357508b2119256b3077be3d60955",
|
||||
"size": 1784
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeFragmentMain.reflection.json",
|
||||
"sha256": "44765a41fc362c9a97b1a19834f285e2e7facb24d8715e3d8559b8e9633a7a0e",
|
||||
"size": 959
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeFragmentMain.spv",
|
||||
"sha256": "9e21c8534c0e70a58ae018fb2d143bf9cfb70112e71b67585f525eef0aecad1b",
|
||||
"size": 768
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeVertexMain.reflection.json",
|
||||
"sha256": "a3a2ea858bd038423896043b0703704f707addceb5bd56721cd897f6bd092065",
|
||||
"size": 956
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeVertexMain.spv",
|
||||
"sha256": "6b19f65b64f40d0a249660fdfba9dd5d95831ffab7314a307bf1f5cf39c6a248",
|
||||
"size": 340
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalResolveMain.reflection.json",
|
||||
"sha256": "9407ee1522f32df231d996ea691224863c023c1ca42cc02ccd7e16de1d873082",
|
||||
"size": 3179
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalResolveMain.spv",
|
||||
"sha256": "4c5fc0da7a4c424e5426694c2c2d9f3cd17d1a64066712f5defe882ad8776662",
|
||||
"size": 22192
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.reflection.json",
|
||||
"sha256": "19ce128388c7f88e0c517fb58a25e46f1382e35ae5f376b10eebe155a2811c4c",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.reflection.json",
|
||||
"sha256": "589818f670881c64f3aba726ee3bc82fe4b9d835a347f99134e0e157dc4a112e",
|
||||
"size": 2050
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.reflection.json",
|
||||
"sha256": "8986a45a8d29743d16f0caece9181b18c85d6490d93b4a56cdb4f53052890f3f",
|
||||
"size": 3587
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.reflection.json",
|
||||
"sha256": "96b3620b163dadf214933cfba6600b1b6a835c4d98b75b1f83e6ccd3dedb2425",
|
||||
"size": 2755
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.reflection.json",
|
||||
"sha256": "01a6cc1bbf3c11c558560d6f8557fd4582d392906ed20a8c729673d0ebf640ed",
|
||||
"size": 3098
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.spv",
|
||||
"sha256": "1f8edd3be1f99f9433494a6f7be68f1317d6e7099e19354a7b8130d5d932224d",
|
||||
"size": 12548
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.spv",
|
||||
"sha256": "08682362ee2120ed19d260e613285071747c3e436bb09bb6238e46f9cedc2308",
|
||||
"size": 4140
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.spv",
|
||||
"sha256": "e5ea6589ddb3613b59f8e58420be95a534cf4149816bc65bae26b1395c638955",
|
||||
"size": 16288
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.spv",
|
||||
"sha256": "f56e0ae3e9b31cb1e3f24e379c81e11c853f8a7102648aaaebc92a17c7e8e53c",
|
||||
"size": 2492
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.spv",
|
||||
"sha256": "32421d4a91f3a88d5210fee7af34b48bcad83072f14e2ccb9ef2ff983e45f78f",
|
||||
"size": 5016
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.reflection.json",
|
||||
"sha256": "d39e2f83c797589296eac9dce139b9ad836a895d6685bc40f79dd2609d687fee",
|
||||
"size": 3597
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.reflection.json",
|
||||
"sha256": "2b07af2aae7578bdb6c2aa22658538821608b1dd5aeddd7b06e42b2e78cedf12",
|
||||
"size": 3596
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.reflection.json",
|
||||
"sha256": "b3bdff863d53a0b385e06a36701a83a6ecafe9a93e97281a732cce8ff862c0db",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/lightTileMain.reflection.json",
|
||||
"sha256": "bf6a9256aaa6d6edacfa1e1c265d7c8ce2c1e4ea4036e0bea078c22fd4b536ca",
|
||||
"size": 1978
|
||||
},
|
||||
{
|
||||
"path": "shaders/lightTileMain.spv",
|
||||
"sha256": "92850edcc5ee5b586a90ce84ee69a98075a6fff3c13db4a57528d9431afe8b68",
|
||||
"size": 6800
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.spv",
|
||||
"sha256": "7643b4d688492b5ee923b9606f0b0e70343ca05fa67673838206119a6f86d8d8",
|
||||
"size": 784
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.spv",
|
||||
"sha256": "fea4dd48664a510bad12b5e8582f2db798d4dbea62ce0de35dc2acfe32372733",
|
||||
"size": 28960
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.spv",
|
||||
"sha256": "1ad2631c35d654f48166321ae43d4165043e1b919b14f1dc61caf97b1ada0898",
|
||||
"size": 1224
|
||||
},
|
||||
{
|
||||
"path": "faset_player",
|
||||
"sha256": "52fbe0067fc2be3807e60ffa5a77e819838dc50a4b723af51f16379b4a487e7c",
|
||||
"size": 6163816
|
||||
},
|
||||
{
|
||||
"path": "scene.fscene",
|
||||
"sha256": "21c364140669ec82c6886102667b255df5ccdf0ec77e0ca64060f84dd7b86632",
|
||||
"size": 8639
|
||||
}
|
||||
],
|
||||
"format": "faset.export",
|
||||
"generation": "004c6e18-969b-4ef5-95bb-5d7742f96564",
|
||||
"lua_enabled": false,
|
||||
"lua_fingerprint": "",
|
||||
"platform": "linux",
|
||||
"prerequisites": [
|
||||
"Linux x86_64",
|
||||
"Vulkan 1.3 driver",
|
||||
"Compatible glibc and libstdc++ runtime"
|
||||
],
|
||||
"renderer_profile": {
|
||||
"api": "Vulkan 1.3",
|
||||
"materials": [
|
||||
"base-color factor and texture",
|
||||
"metallic and roughness factors"
|
||||
],
|
||||
"required_features": [
|
||||
"dynamicRendering",
|
||||
"synchronization2"
|
||||
],
|
||||
"shadow_atlases": {
|
||||
"caster_draw_limit": 4096,
|
||||
"fallback_resolution": 1024,
|
||||
"local_face_limit": 16,
|
||||
"preferred_resolution": 2048,
|
||||
"sampled_d32_required": true,
|
||||
"sun_cascade_limit": 4
|
||||
},
|
||||
"texture_sampling": "linear clamp, one mip level",
|
||||
"unsupported_material_features": [
|
||||
"normal maps",
|
||||
"metallic-roughness maps",
|
||||
"emissive and occlusion maps",
|
||||
"alpha mode selection",
|
||||
"unlit mode",
|
||||
"per-material face culling"
|
||||
]
|
||||
},
|
||||
"scene_hash": "ee12794145c14ba5b599c5d9ae21648cccdfa91c47ee7742549f60d5fe7bc3e0",
|
||||
"simulation": {
|
||||
"fixed_delta": 0.016666666666666666,
|
||||
"gravity": [
|
||||
0,
|
||||
-9.81,
|
||||
0
|
||||
],
|
||||
"max_catch_up_ticks": 4,
|
||||
"physics_substeps": 4
|
||||
},
|
||||
"units": {
|
||||
"angle": "radian",
|
||||
"coordinates": "right-handed Y-up",
|
||||
"distance": "metre"
|
||||
},
|
||||
"validation_log": "warning: material material-bb63b094febbf90bb7049c9bcf7587bc has features beyond the initial base-color/PBR renderer\n{\"dimension\":3,\"validated\":true}\n",
|
||||
"version": 1
|
||||
}
|
||||
+7284
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/faset_player",
|
||||
"--headless",
|
||||
"--frames",
|
||||
"120",
|
||||
"--capture",
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/verification.ppm",
|
||||
"--profile",
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/profile.json"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"seconds": 0.6575766110036056,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "New round: collect the three gold cubes, then reach the green exit. E resets.\n{\"device\":\"NVIDIA GeForce RTX 2080 Ti\",\"dimension\":3,\"effective_temporal_mode\":\"off\",\"effective_visibility_mode\":\"direct\",\"frames\":120,\"gpu_visibility_active\":false,\"temporal_mode\":\"off\",\"ticks\":120,\"validation_errors\":0,\"visibility_mode\":\"direct\"}\n",
|
||||
"stderr": "warning: material material-bb63b094febbf90bb7049c9bcf7587bc has features beyond the initial base-color/PBR renderer\n"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/faset_player",
|
||||
"--validate"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"seconds": 0.00796160800382495,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "{\"dimension\":3,\"validated\":true}\n",
|
||||
"stderr": "warning: material material-bb63b094febbf90bb7049c9bcf7587bc has features beyond the initial base-color/PBR renderer\n"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,294 @@
|
||||
{
|
||||
"asset_generations": {},
|
||||
"build_fingerprint": "0bfae1f2850e06540c91a793a50673f53e9768434c02b5625dbe4839e27f23f0",
|
||||
"configuration": "Release",
|
||||
"executable": "faset_player",
|
||||
"files": [
|
||||
{
|
||||
"path": "README.txt",
|
||||
"sha256": "82bf72bc542643f6c4090e0a5de69b0014ca3fa17c6f9dfb12cc41e44c8b8db6",
|
||||
"size": 262
|
||||
},
|
||||
{
|
||||
"path": "Notices/Faset-NOTICE.txt",
|
||||
"sha256": "30c2e7e80f5153b31ab57675e07246aef9165965d64e36022b426a26449ece3f",
|
||||
"size": 204
|
||||
},
|
||||
{
|
||||
"path": "Notices/dependencies.json",
|
||||
"sha256": "262e8f63cf21c516829b1fedb0900ac90e76d62aa8f78d9ad02d8f24e0359e74",
|
||||
"size": 2468
|
||||
},
|
||||
{
|
||||
"path": "Notices/lua/LICENSE.txt",
|
||||
"sha256": "e42d195c77d3ad7255ee9c874772d3c53998e7f60f9acf453d4630fa161e0bfe",
|
||||
"size": 1126
|
||||
},
|
||||
{
|
||||
"path": "Notices/stb/LICENSE",
|
||||
"sha256": "bebfe904b14301657e4e5d655c811d51fd31b97c455b9cc2d8600d6bac6cff63",
|
||||
"size": 2510
|
||||
},
|
||||
{
|
||||
"path": "Notices/json/LICENSE.MIT",
|
||||
"sha256": "46a65cffd1ea955132d95a8dd921640714a8d6b537d2e4e482d31145ae95b603",
|
||||
"size": 1076
|
||||
},
|
||||
{
|
||||
"path": "Notices/box3d/LICENSE",
|
||||
"sha256": "da5e31a26bf3cfd5ba5c96d6823e480128c81e76c107ef9d3ee5d94789184b90",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/box2d/LICENSE",
|
||||
"sha256": "68a3e676d7e94093b102d5cba0d4e04af812040d6f230c3db67a6664574e43d2",
|
||||
"size": 1067
|
||||
},
|
||||
{
|
||||
"path": "Notices/entt/LICENSE",
|
||||
"sha256": "0785027ce472d7c61f05fba664a1d3ba6639c1593ced351ad9e4bed868765d99",
|
||||
"size": 1097
|
||||
},
|
||||
{
|
||||
"path": "Notices/sdl3/LICENSE.txt",
|
||||
"sha256": "97f35b302b361680ec1e891e95d2d52097bb95abff361434916d99dc1305f127",
|
||||
"size": 884
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuTemporalVertexMain.reflection.json",
|
||||
"sha256": "7a8efe2645e7ce465ca44d19f8cfb2eb6c767abd1c3ce12ed69a149a50be8a8c",
|
||||
"size": 3308
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuTemporalVertexMain.spv",
|
||||
"sha256": "dfe7309aafbd41974668b295e179354965db440e4156b9f12d6a67db16b357f9",
|
||||
"size": 5996
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalFragmentMain.reflection.json",
|
||||
"sha256": "e36452227788f3703d7342b6d9a7a0efef74ce4da3aa96bb176a26e169ec3628",
|
||||
"size": 3874
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalFragmentMain.spv",
|
||||
"sha256": "03adc6673276979b3ea46becf3a36940d3061af77cb8c965c7471feff8dbf89a",
|
||||
"size": 30976
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalVertexMain.reflection.json",
|
||||
"sha256": "6f7812ce88b14bca62a6d2ad82a8657e2ee48c252558f34677c6a2bd980a7edb",
|
||||
"size": 3935
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalVertexMain.spv",
|
||||
"sha256": "6cc3535c952a33ee46fd417fbec7fcad8f24357508b2119256b3077be3d60955",
|
||||
"size": 1784
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeFragmentMain.reflection.json",
|
||||
"sha256": "44765a41fc362c9a97b1a19834f285e2e7facb24d8715e3d8559b8e9633a7a0e",
|
||||
"size": 959
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeFragmentMain.spv",
|
||||
"sha256": "9e21c8534c0e70a58ae018fb2d143bf9cfb70112e71b67585f525eef0aecad1b",
|
||||
"size": 768
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeVertexMain.reflection.json",
|
||||
"sha256": "a3a2ea858bd038423896043b0703704f707addceb5bd56721cd897f6bd092065",
|
||||
"size": 956
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalCompositeVertexMain.spv",
|
||||
"sha256": "6b19f65b64f40d0a249660fdfba9dd5d95831ffab7314a307bf1f5cf39c6a248",
|
||||
"size": 340
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalResolveMain.reflection.json",
|
||||
"sha256": "9407ee1522f32df231d996ea691224863c023c1ca42cc02ccd7e16de1d873082",
|
||||
"size": 3179
|
||||
},
|
||||
{
|
||||
"path": "shaders/temporalResolveMain.spv",
|
||||
"sha256": "4c5fc0da7a4c424e5426694c2c2d9f3cd17d1a64066712f5defe882ad8776662",
|
||||
"size": 22192
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.reflection.json",
|
||||
"sha256": "19ce128388c7f88e0c517fb58a25e46f1382e35ae5f376b10eebe155a2811c4c",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.reflection.json",
|
||||
"sha256": "589818f670881c64f3aba726ee3bc82fe4b9d835a347f99134e0e157dc4a112e",
|
||||
"size": 2050
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.reflection.json",
|
||||
"sha256": "8986a45a8d29743d16f0caece9181b18c85d6490d93b4a56cdb4f53052890f3f",
|
||||
"size": 3587
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.reflection.json",
|
||||
"sha256": "96b3620b163dadf214933cfba6600b1b6a835c4d98b75b1f83e6ccd3dedb2425",
|
||||
"size": 2755
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.reflection.json",
|
||||
"sha256": "01a6cc1bbf3c11c558560d6f8557fd4582d392906ed20a8c729673d0ebf640ed",
|
||||
"size": 3098
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuPostCullMain.spv",
|
||||
"sha256": "1f8edd3be1f99f9433494a6f7be68f1317d6e7099e19354a7b8130d5d932224d",
|
||||
"size": 12548
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuHzbMain.spv",
|
||||
"sha256": "08682362ee2120ed19d260e613285071747c3e436bb09bb6238e46f9cedc2308",
|
||||
"size": 4140
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuCullMain.spv",
|
||||
"sha256": "e5ea6589ddb3613b59f8e58420be95a534cf4149816bc65bae26b1395c638955",
|
||||
"size": 16288
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuShadowMain.spv",
|
||||
"sha256": "f56e0ae3e9b31cb1e3f24e379c81e11c853f8a7102648aaaebc92a17c7e8e53c",
|
||||
"size": 2492
|
||||
},
|
||||
{
|
||||
"path": "shaders/gpuVertexMain.spv",
|
||||
"sha256": "32421d4a91f3a88d5210fee7af34b48bcad83072f14e2ccb9ef2ff983e45f78f",
|
||||
"size": 5016
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.reflection.json",
|
||||
"sha256": "d39e2f83c797589296eac9dce139b9ad836a895d6685bc40f79dd2609d687fee",
|
||||
"size": 3597
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.reflection.json",
|
||||
"sha256": "2b07af2aae7578bdb6c2aa22658538821608b1dd5aeddd7b06e42b2e78cedf12",
|
||||
"size": 3596
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.reflection.json",
|
||||
"sha256": "b3bdff863d53a0b385e06a36701a83a6ecafe9a93e97281a732cce8ff862c0db",
|
||||
"size": 3591
|
||||
},
|
||||
{
|
||||
"path": "shaders/lightTileMain.reflection.json",
|
||||
"sha256": "bf6a9256aaa6d6edacfa1e1c265d7c8ce2c1e4ea4036e0bea078c22fd4b536ca",
|
||||
"size": 1978
|
||||
},
|
||||
{
|
||||
"path": "shaders/lightTileMain.spv",
|
||||
"sha256": "92850edcc5ee5b586a90ce84ee69a98075a6fff3c13db4a57528d9431afe8b68",
|
||||
"size": 6800
|
||||
},
|
||||
{
|
||||
"path": "shaders/shadowMain.spv",
|
||||
"sha256": "7643b4d688492b5ee923b9606f0b0e70343ca05fa67673838206119a6f86d8d8",
|
||||
"size": 784
|
||||
},
|
||||
{
|
||||
"path": "shaders/fragmentMain.spv",
|
||||
"sha256": "fea4dd48664a510bad12b5e8582f2db798d4dbea62ce0de35dc2acfe32372733",
|
||||
"size": 28960
|
||||
},
|
||||
{
|
||||
"path": "shaders/vertexMain.spv",
|
||||
"sha256": "1ad2631c35d654f48166321ae43d4165043e1b919b14f1dc61caf97b1ada0898",
|
||||
"size": 1224
|
||||
},
|
||||
{
|
||||
"path": "faset_player",
|
||||
"sha256": "6df88e53e4fff9376341fd3d049b4e047a268d0bf344184d903b6c17ff20bd0e",
|
||||
"size": 6509384
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "e07b12047f8141c3c4cc8f0e7d0905a5c635375e4494755e34191db0859ab86f",
|
||||
"size": 175
|
||||
},
|
||||
{
|
||||
"path": "Scripts/util/motion.lua",
|
||||
"sha256": "bad3dcdc1081fd1dec589c12dad8dc175b739d77ea52b957ead9ecb4b7cb88a3",
|
||||
"size": 150
|
||||
},
|
||||
{
|
||||
"path": "Scripts/player.lua",
|
||||
"sha256": "1c51810574a3413c46a7cbd0ea2e84a9b802da1206a2b72bb78f6cc951367a11",
|
||||
"size": 1376
|
||||
},
|
||||
{
|
||||
"path": "Scripts/beacon.lua",
|
||||
"sha256": "44d932ebedf66cadb9620f2d926177be2f8d43d71d56aa83611de686af026231",
|
||||
"size": 820
|
||||
},
|
||||
{
|
||||
"path": "scene.fscene",
|
||||
"sha256": "641ba14a1f9c3966b9ec797814fdfa54f954dc5e0d53ab00c645598edef61baf",
|
||||
"size": 1681
|
||||
}
|
||||
],
|
||||
"format": "faset.export",
|
||||
"generation": "92846e8b-d199-4679-8f6a-fb0686acba75",
|
||||
"lua_enabled": true,
|
||||
"lua_fingerprint": "a9261789bb1e0ca38bd40b08b0454165cd51454cba3ad4725dd357812ced6e35",
|
||||
"platform": "linux",
|
||||
"prerequisites": [
|
||||
"Linux x86_64",
|
||||
"Vulkan 1.3 driver",
|
||||
"Compatible glibc and libstdc++ runtime"
|
||||
],
|
||||
"renderer_profile": {
|
||||
"api": "Vulkan 1.3",
|
||||
"materials": [
|
||||
"base-color factor and texture",
|
||||
"metallic and roughness factors"
|
||||
],
|
||||
"required_features": [
|
||||
"dynamicRendering",
|
||||
"synchronization2"
|
||||
],
|
||||
"shadow_atlases": {
|
||||
"caster_draw_limit": 4096,
|
||||
"fallback_resolution": 1024,
|
||||
"local_face_limit": 16,
|
||||
"preferred_resolution": 2048,
|
||||
"sampled_d32_required": true,
|
||||
"sun_cascade_limit": 4
|
||||
},
|
||||
"texture_sampling": "linear clamp, one mip level",
|
||||
"unsupported_material_features": [
|
||||
"normal maps",
|
||||
"metallic-roughness maps",
|
||||
"emissive and occlusion maps",
|
||||
"alpha mode selection",
|
||||
"unlit mode",
|
||||
"per-material face culling"
|
||||
]
|
||||
},
|
||||
"scene_hash": "143724a468d711cbdf9a9700310d7b0acef003ce1b21422ca5204e0e565fa02c",
|
||||
"simulation": {
|
||||
"fixed_delta": 0.016666666666666666,
|
||||
"gravity": [
|
||||
0,
|
||||
-9.81,
|
||||
0
|
||||
],
|
||||
"max_catch_up_ticks": 4,
|
||||
"physics_substeps": 4
|
||||
},
|
||||
"units": {
|
||||
"angle": "radian",
|
||||
"coordinates": "right-handed Y-up",
|
||||
"distance": "metre"
|
||||
},
|
||||
"validation_log": "{\"dimension\":2,\"validated\":true}\n",
|
||||
"version": 1
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/faset_player",
|
||||
"--headless",
|
||||
"--frames",
|
||||
"120",
|
||||
"--capture",
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/verification.ppm",
|
||||
"--profile",
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/profile.json"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"seconds": 0.6108254339778796,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "{\"device\":\"NVIDIA GeForce RTX 2080 Ti\",\"dimension\":2,\"effective_temporal_mode\":\"off\",\"effective_visibility_mode\":\"direct\",\"frames\":120,\"gpu_visibility_active\":false,\"temporal_mode\":\"off\",\"ticks\":120,\"validation_errors\":0,\"visibility_mode\":\"direct\"}\n",
|
||||
"stderr": "Lua player ready: A/D move, Space jump, E reset\n"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/faset_player",
|
||||
"--validate"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"seconds": 0.009439726010896266,
|
||||
"exit_code": 0,
|
||||
"timed_out": false,
|
||||
"stdout": "{\"dimension\":2,\"validated\":true}\n",
|
||||
"stderr": ""
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,82 @@
|
||||
==========
|
||||
VULKANINFO
|
||||
==========
|
||||
|
||||
Vulkan Instance Version: 1.4.341
|
||||
|
||||
|
||||
Instance Extensions: count = 27
|
||||
-------------------------------
|
||||
VK_EXT_acquire_drm_display : extension revision 1
|
||||
VK_EXT_acquire_xlib_display : extension revision 1
|
||||
VK_EXT_debug_report : extension revision 10
|
||||
VK_EXT_debug_utils : extension revision 2
|
||||
VK_EXT_direct_mode_display : extension revision 1
|
||||
VK_EXT_display_surface_counter : extension revision 1
|
||||
VK_EXT_headless_surface : extension revision 1
|
||||
VK_EXT_layer_settings : extension revision 2
|
||||
VK_EXT_surface_maintenance1 : extension revision 1
|
||||
VK_EXT_swapchain_colorspace : extension revision 5
|
||||
VK_KHR_device_group_creation : extension revision 1
|
||||
VK_KHR_display : extension revision 23
|
||||
VK_KHR_external_fence_capabilities : extension revision 1
|
||||
VK_KHR_external_memory_capabilities : extension revision 1
|
||||
VK_KHR_external_semaphore_capabilities : extension revision 1
|
||||
VK_KHR_get_display_properties2 : extension revision 1
|
||||
VK_KHR_get_physical_device_properties2 : extension revision 2
|
||||
VK_KHR_get_surface_capabilities2 : extension revision 1
|
||||
VK_KHR_portability_enumeration : extension revision 1
|
||||
VK_KHR_surface : extension revision 25
|
||||
VK_KHR_surface_maintenance1 : extension revision 1
|
||||
VK_KHR_surface_protected_capabilities : extension revision 1
|
||||
VK_KHR_wayland_surface : extension revision 6
|
||||
VK_KHR_xcb_surface : extension revision 6
|
||||
VK_KHR_xlib_surface : extension revision 6
|
||||
VK_LUNARG_direct_driver_loading : extension revision 1
|
||||
VK_NV_display_stereo : extension revision 1
|
||||
|
||||
Instance Layers: count = 12
|
||||
---------------------------
|
||||
VK_LAYER_INTEL_nullhw INTEL NULL HW 1.1.73 version 1
|
||||
VK_LAYER_KHRONOS_validation Khronos Validation Layer 1.4.341 version 1
|
||||
VK_LAYER_MESA_anti_lag Open-source implementation of the VK_AMD_anti_lag extension. 1.4.303 version 1
|
||||
VK_LAYER_MESA_device_select Linux device selection layer 1.4.303 version 1
|
||||
VK_LAYER_MESA_overlay Mesa Overlay layer 1.4.303 version 1
|
||||
VK_LAYER_MESA_screenshot Mesa Screenshot layer 1.4.303 version 1
|
||||
VK_LAYER_NV_optimus NVIDIA Optimus layer 1.4.329 version 1
|
||||
VK_LAYER_NV_present NVIDIA Presentation Layer 1.4.329 version 1
|
||||
VK_LAYER_VALVE_steam_fossilize_32 Steam Pipeline Caching Layer 1.3.207 version 1
|
||||
VK_LAYER_VALVE_steam_fossilize_64 Steam Pipeline Caching Layer 1.3.207 version 1
|
||||
VK_LAYER_VALVE_steam_overlay_32 Steam Overlay Layer 1.3.207 version 1
|
||||
VK_LAYER_VALVE_steam_overlay_64 Steam Overlay Layer 1.3.207 version 1
|
||||
|
||||
Devices:
|
||||
========
|
||||
GPU0:
|
||||
apiVersion = 1.4.329
|
||||
driverVersion = 595.84.0.0
|
||||
vendorID = 0x10de
|
||||
deviceID = 0x1e04
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||
deviceName = NVIDIA GeForce RTX 2080 Ti
|
||||
driverID = DRIVER_ID_NVIDIA_PROPRIETARY
|
||||
driverName = NVIDIA
|
||||
driverInfo = 595.84
|
||||
conformanceVersion = 1.4.3.3
|
||||
deviceUUID = 2c71c7ba-97ac-c78e-2c06-af362631f3fe
|
||||
driverUUID = 027cbdd1-c478-513e-af69-ebc9eaa7de87
|
||||
GPU1:
|
||||
apiVersion = 1.4.335
|
||||
driverVersion = 26.0.8
|
||||
vendorID = 0x10005
|
||||
deviceID = 0x0000
|
||||
deviceType = PHYSICAL_DEVICE_TYPE_CPU
|
||||
deviceName = llvmpipe (LLVM 21.1.8, 256 bits)
|
||||
driverID = DRIVER_ID_MESA_LLVMPIPE
|
||||
driverName = llvmpipe
|
||||
driverInfo = Mesa 26.0.8-1ubuntu0.3 (LLVM 21.1.8)
|
||||
conformanceVersion = 1.3.1.1
|
||||
deviceUUID = 6d657361-3236-2e30-2e38-2d3175627500
|
||||
driverUUID = 6c6c766d-7069-7065-5555-494400000000
|
||||
WARNING: [Loader Message] Code 0 : ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPlanePropertiesKHR!
|
||||
WARNING: [Loader Message] Code 0 : ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPropertiesKHR!
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Profile the two relocated Release samples retained by verify_playable_exports.py."""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
|
||||
def digest(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def read(path: Path) -> dict:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def write(path: Path, value: object) -> None:
|
||||
path.write_text(json.dumps(value, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def require(condition: bool, message: str) -> None:
|
||||
if not condition:
|
||||
raise RuntimeError(message)
|
||||
|
||||
|
||||
def run_source_hidden(source: dict, command: list[str], cwd: Path) -> subprocess.CompletedProcess:
|
||||
projects = Path(source["project_workspace"]) / "Faset Café 世界"
|
||||
disabled = projects.parent / "projects-offline-reference"
|
||||
require(projects.is_dir() and not disabled.exists(),
|
||||
"Disposable source projects must be available to hide")
|
||||
projects.rename(disabled)
|
||||
try:
|
||||
require(not projects.exists(), "Source project paths remain available")
|
||||
return subprocess.run(command, cwd=cwd, capture_output=True, text=True,
|
||||
encoding="utf-8", errors="replace", timeout=300)
|
||||
finally:
|
||||
if disabled.exists() and not projects.exists():
|
||||
disabled.rename(projects)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--verification", type=Path, required=True,
|
||||
help="Passed report.json from tools/verify_playable_exports.py")
|
||||
parser.add_argument("--output", type=Path, required=True,
|
||||
help="New/empty directory for raw 240-frame evidence")
|
||||
args = parser.parse_args()
|
||||
verification = args.verification.resolve()
|
||||
output = args.output.resolve()
|
||||
source = read(verification)
|
||||
require(source.get("status") == "passed" and not source.get("engine_dirty"),
|
||||
"A clean, passed export verification is required")
|
||||
require(source.get("frames_per_game") == 120, "Expected a 120-frame verifier")
|
||||
require(set(source.get("requested_projects", [])) ==
|
||||
{"collect-2d", "collect-3d", "lua"} and
|
||||
{item.get("name") for item in source.get("projects", [])} ==
|
||||
{"collect-2d", "collect-3d", "lua"} and
|
||||
all(item.get("status") == "passed" and
|
||||
item.get("completed_frames") == 120 and
|
||||
item.get("source_project_paths_unavailable") is True
|
||||
for item in source["projects"]),
|
||||
"Expected three source-hidden 120-frame Release games")
|
||||
require(not output.exists() or not any(output.iterdir()),
|
||||
"Output directory must be new or empty")
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(verification, output / "playable-report.json")
|
||||
cwd = Path(source["standalone_root"]) / "empty-working-directory"
|
||||
require(cwd.is_dir(), "Verifier's unrelated working directory is missing")
|
||||
limits = {"wall": 4.0, "gpu": 1.0, "renderer_readback_cpu": 1.0,
|
||||
"simulation": 0.5, "snapshot": 0.5}
|
||||
report = {"format": "faset.p1-release-reference", "version": 1,
|
||||
"source_revision": source["engine_revision"],
|
||||
"editor_sha256": source["editor_sha256"],
|
||||
"verification_sha256": digest(verification),
|
||||
"host": {"platform": platform.platform(), "machine": platform.machine(),
|
||||
"processor": platform.processor()},
|
||||
"method": "sequential relocated Release Player, default direct/temporal-off, "
|
||||
"offscreen 1280x720, 240 completed frames including first; "
|
||||
"nearest-rank p95, validation/readback enabled",
|
||||
"projects": []}
|
||||
for item in source["projects"]:
|
||||
if item["name"] not in ("collect-2d", "collect-3d"):
|
||||
continue
|
||||
require(item.get("status") == "passed" and item.get("configuration") == "Release" and
|
||||
item.get("source_project_paths_unavailable") is True,
|
||||
f"Incomplete relocated export: {item['name']}")
|
||||
name = item["name"]
|
||||
package = Path(item["standalone_directory"])
|
||||
player = package / item["executable"]
|
||||
require(player.is_file() and not player.is_symlink(), f"Missing Player: {player}")
|
||||
profile_path = output / f"{name}-profile-240.json"
|
||||
command = [str(player), "--headless", "--frames", "240", "--profile",
|
||||
str(profile_path)]
|
||||
started = time.monotonic()
|
||||
process = run_source_hidden(source, command, cwd)
|
||||
invocation = {"arguments": command, "cwd": str(cwd),
|
||||
"source_project_paths_unavailable": True,
|
||||
"seconds": time.monotonic() - started,
|
||||
"exit_code": process.returncode,
|
||||
"stdout": process.stdout, "stderr": process.stderr}
|
||||
write(output / f"{name}-run-240.json", invocation)
|
||||
require(process.returncode == 0 and profile_path.is_file(),
|
||||
f"240-frame Player failed; inspect {name}-run-240.json")
|
||||
profile = read(profile_path)
|
||||
require(profile.get("format") == "faset.player-profile" and
|
||||
profile.get("completed_frames") == 240 and
|
||||
len(profile.get("samples", [])) == 240 and
|
||||
profile.get("dimension") == item["dimension"] and
|
||||
profile.get("presentation_mode") == "offscreen" and
|
||||
profile.get("width") == 1280 and profile.get("height") == 720 and
|
||||
profile.get("visibility_mode") == "direct" and
|
||||
profile.get("effective_visibility_mode") == "direct" and
|
||||
profile.get("temporal_mode") == "off" and
|
||||
profile.get("effective_temporal_mode") == "off" and
|
||||
profile.get("percentile_method") ==
|
||||
"nearest_rank_all_completed_frames_no_warmup_exclusion" and
|
||||
profile.get("validation_enabled") is True and
|
||||
profile.get("validation_errors") == 0,
|
||||
f"Invalid reference profile: {profile_path}")
|
||||
p95 = {key: profile["summary_ms"][key]["p95"] for key in limits}
|
||||
allocated = max(sample["gpu_allocated_bytes"] for sample in profile["samples"])
|
||||
sun_atlas = max(sample["sun_shadow_atlas_bytes"] for sample in profile["samples"])
|
||||
local_atlas = max(sample["local_shadow_atlas_bytes"] for sample in profile["samples"])
|
||||
startup = profile["startup_ms"]["main_to_first_frame"]
|
||||
checks = {key: {"observed_ms": value, "limit_ms": limits[key],
|
||||
"met": value is not None and value <= limits[key]}
|
||||
for key, value in p95.items()}
|
||||
checks["explicit_allocation"] = {"observed_bytes": allocated,
|
||||
"limit_bytes": 20 * 1024 * 1024,
|
||||
"met": allocated <= 20 * 1024 * 1024}
|
||||
checks["startup"] = {"observed_ms": startup, "limit_ms": 500.0,
|
||||
"met": startup <= 500.0}
|
||||
result = {"name": name, "dimension": item["dimension"],
|
||||
"device": profile["device"], "player_sha256": digest(player),
|
||||
"manifest_sha256": digest(package / "manifest.json"),
|
||||
"profile_sha256": digest(profile_path),
|
||||
"requested_frames": profile["requested_frames"],
|
||||
"completed_frames": profile["completed_frames"],
|
||||
"summary_ms": profile["summary_ms"], "startup_ms": profile["startup_ms"],
|
||||
"effective_lighting_path": profile.get("effective_lighting_path"),
|
||||
"gpu_allocated_bytes_max": allocated,
|
||||
"sun_shadow_atlas_bytes_max": sun_atlas,
|
||||
"local_shadow_atlas_bytes_max": local_atlas,
|
||||
"gpu_allocated_excluding_shadow_atlases_bytes_max": max(
|
||||
sample["gpu_allocated_bytes"] -
|
||||
sample["sun_shadow_atlas_bytes"] -
|
||||
sample["local_shadow_atlas_bytes"]
|
||||
for sample in profile["samples"]),
|
||||
"effective_sun_cascades_max": max(
|
||||
sample["effective_sun_cascades"] for sample in profile["samples"]),
|
||||
"local_shadow_faces_max": max(
|
||||
sample["local_shadow_faces"] for sample in profile["samples"]),
|
||||
"budget_checks": checks}
|
||||
report["projects"].append(result)
|
||||
write(output / "reference-summary.json", report)
|
||||
require({item["name"] for item in report["projects"]} == {"collect-2d", "collect-3d"},
|
||||
"Both exact sample scenes are required")
|
||||
print(output / "reference-summary.json")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"format": "faset.p1-release-toolchain-provenance",
|
||||
"version": 1,
|
||||
"source_revision": "4a3453e2b1868555d833f578d43f48b8bc47d41a",
|
||||
"source_clean_at_verifier_start": true,
|
||||
"build_preset": "linux-release",
|
||||
"configuration": "Release",
|
||||
"host": {
|
||||
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
|
||||
"machine": "x86_64",
|
||||
"processor": "",
|
||||
"logical_cpus": 16,
|
||||
"cpu_model": "AMD Ryzen 7 1700 Eight-Core Processor",
|
||||
"mem_total": "32784216 kB"
|
||||
},
|
||||
"report_sha256": "63da692b605621acc1cace00d4a3c9cf35de13abfd4351aea6653a88c870e03f",
|
||||
"reference_summary_sha256": "f8297f3cb0578addee56c0b3cb9439b37ae37707b02d433d662b534620f329e9",
|
||||
"editor_sha256": "73702e9f0fe015ef932db694400a0501048be2d602ab521ecc48c51767275d23",
|
||||
"verifier_tool_sha256": "21485df78b81c22bce1f6dfc810997f3ac0505cacd8bc647786ce9d90a7c67e1",
|
||||
"profile_helper_sha256": "5d69428a1202c1e144779074c0ab88360c459e2dd99b22c1fcf8929dbeab2618",
|
||||
"selected_tools": {
|
||||
"cmake": {
|
||||
"selected": "/usr/bin/cmake",
|
||||
"resolved": "/usr/bin/cmake",
|
||||
"sha256": "6e1dccda39845415d68eabb934c598998949c99ec4668625d571aee1827b05c7",
|
||||
"version_exit_code": 0,
|
||||
"version_output": "cmake version 4.2.3\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).",
|
||||
"version_flag": "--version"
|
||||
},
|
||||
"ninja": {
|
||||
"selected": "/usr/bin/ninja",
|
||||
"resolved": "/usr/bin/ninja",
|
||||
"sha256": "91e9548850cda2799facfdaa7abe33f9e978832f85e98212255708a7bbe437f2",
|
||||
"version_exit_code": 0,
|
||||
"version_output": "1.13.2",
|
||||
"version_flag": "--version"
|
||||
},
|
||||
"c_compiler": {
|
||||
"selected": "clang",
|
||||
"resolved": "/usr/lib/llvm-21/bin/clang",
|
||||
"sha256": "412bbe8c60571a1eb06f48fde89635033621caeb01a9b4ee76d46711bae8e932",
|
||||
"version_exit_code": 0,
|
||||
"version_output": "Ubuntu clang version 21.1.8 (6ubuntu1)\nTarget: x86_64-pc-linux-gnu\nThread model: posix\nInstalledDir: /usr/lib/llvm-21/bin",
|
||||
"version_flag": "--version"
|
||||
},
|
||||
"cxx_compiler": {
|
||||
"selected": "clang++",
|
||||
"resolved": "/usr/lib/llvm-21/bin/clang",
|
||||
"sha256": "412bbe8c60571a1eb06f48fde89635033621caeb01a9b4ee76d46711bae8e932",
|
||||
"version_exit_code": 0,
|
||||
"version_output": "Ubuntu clang version 21.1.8 (6ubuntu1)\nTarget: x86_64-pc-linux-gnu\nThread model: posix\nInstalledDir: /usr/lib/llvm-21/bin",
|
||||
"version_flag": "--version"
|
||||
},
|
||||
"slangc": {
|
||||
"selected": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/.cache/slang/bin/slangc",
|
||||
"resolved": "/home/emil/Desktop/Faset_Engine/.cache/slang/bin/slangc",
|
||||
"sha256": "ff47ad16a3110e43f96a45e90720e6f894371d27f5e47715b298159e395b75e8",
|
||||
"version_exit_code": 0,
|
||||
"version_output": "2026.18",
|
||||
"version_flag": "-version"
|
||||
}
|
||||
},
|
||||
"gpu": [
|
||||
{
|
||||
"project": "collect-2d",
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0
|
||||
},
|
||||
{
|
||||
"project": "collect-3d",
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0
|
||||
},
|
||||
{
|
||||
"project": "lua",
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0
|
||||
}
|
||||
],
|
||||
"supplement_created_utc": "2026-09-24T02:15:34.021841+00:00"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/tmp/faset-p1-final-release-4a3453e/reference-240/reference-summary.json
|
||||
+14484
File diff suppressed because it is too large
Load Diff
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/faset_player",
|
||||
"--headless",
|
||||
"--frames",
|
||||
"240",
|
||||
"--profile",
|
||||
"/tmp/faset-p1-final-release-4a3453e/reference-240/collect-2d-profile-240.json"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"source_project_paths_unavailable": true,
|
||||
"seconds": 0.9077925750170834,
|
||||
"exit_code": 0,
|
||||
"stdout": "New round: collect the three gold cubes, then reach the green exit. E resets.\n{\"device\":\"NVIDIA GeForce RTX 2080 Ti\",\"dimension\":2,\"effective_temporal_mode\":\"off\",\"effective_visibility_mode\":\"direct\",\"frames\":240,\"gpu_visibility_active\":false,\"temporal_mode\":\"off\",\"ticks\":240,\"validation_errors\":0,\"visibility_mode\":\"direct\"}\n",
|
||||
"stderr": ""
|
||||
}
|
||||
+14484
File diff suppressed because it is too large
Load Diff
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"arguments": [
|
||||
"/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/faset_player",
|
||||
"--headless",
|
||||
"--frames",
|
||||
"240",
|
||||
"--profile",
|
||||
"/tmp/faset-p1-final-release-4a3453e/reference-240/collect-3d-profile-240.json"
|
||||
],
|
||||
"cwd": "/tmp/faset-p1-final-packages-4a3453e/empty-working-directory",
|
||||
"source_project_paths_unavailable": true,
|
||||
"seconds": 0.969158330000937,
|
||||
"exit_code": 0,
|
||||
"stdout": "New round: collect the three gold cubes, then reach the green exit. E resets.\n{\"device\":\"NVIDIA GeForce RTX 2080 Ti\",\"dimension\":3,\"effective_temporal_mode\":\"off\",\"effective_visibility_mode\":\"direct\",\"frames\":240,\"gpu_visibility_active\":false,\"temporal_mode\":\"off\",\"ticks\":240,\"validation_errors\":0,\"visibility_mode\":\"direct\"}\n",
|
||||
"stderr": "warning: material material-bb63b094febbf90bb7049c9bcf7587bc has features beyond the initial base-color/PBR renderer\n"
|
||||
}
|
||||
+577
@@ -0,0 +1,577 @@
|
||||
{
|
||||
"format": "faset.playable-export-verification",
|
||||
"version": 1,
|
||||
"started_utc": "2026-09-24T02:01:24.205054+00:00",
|
||||
"platform": "linux",
|
||||
"engine": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration",
|
||||
"editor": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/build/linux-release/faset_editor",
|
||||
"standalone_root": "/tmp/faset-p1-final-packages-4a3453e",
|
||||
"engine_revision": "4a3453e2b1868555d833f578d43f48b8bc47d41a",
|
||||
"engine_dirty": false,
|
||||
"engine_git_status": [],
|
||||
"engine_diff_sha256": null,
|
||||
"editor_sha256": "73702e9f0fe015ef932db694400a0501048be2d602ab521ecc48c51767275d23",
|
||||
"project_workspace": "/tmp/faset-p1-final-release-4a3453e",
|
||||
"vulkaninfo_available": true,
|
||||
"driver_override": null,
|
||||
"frames_per_game": 120,
|
||||
"status": "passed",
|
||||
"projects": [
|
||||
{
|
||||
"name": "collect-2d",
|
||||
"dimension": 2,
|
||||
"language": "cpp",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": ".gitignore",
|
||||
"sha256": "53aa4d7124d4c8d93b8d7c4cb470b6c82b844e019a660d6243ffeadc50602de1"
|
||||
},
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "8cf5a2d6de849eb090b9ea6d5e27841f551bd06947e5054f0d2f59639a90edd0"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "be48a6d21385e717b6c8ebf9a3b4322eebbeff6bb067428e089ab5214be79854"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.cpp",
|
||||
"sha256": "6b581b24da613e1915819de0a0f0ea820dd3333efa62c4b479a9ea7ffdbc6bcc"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.hpp",
|
||||
"sha256": "4121587182ed4f74901b1c0757c53daadbf309af1d6bb5dd87fef142130ccbbe"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "36e2acd32210f5489372a2331346a3294ead2395f0713e3e5fd2da4e83263689"
|
||||
}
|
||||
],
|
||||
"generation": "ca306aa8-a094-42bc-833f-a24a05cab73d",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 41,
|
||||
"asset_generations": {},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.581984,
|
||||
"min": 0.555552,
|
||||
"p50": 0.5592,
|
||||
"p95": 0.568896,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 6.021328,
|
||||
"min": 1.627681,
|
||||
"p50": 1.892219,
|
||||
"p95": 2.165605,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 6.013313,
|
||||
"min": 1.621609,
|
||||
"p50": 1.883223,
|
||||
"p95": 2.15763,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.645991,
|
||||
"min": 0.386439,
|
||||
"p50": 0.478583,
|
||||
"p95": 0.582889,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.332657,
|
||||
"min": 0.135175,
|
||||
"p50": 0.166364,
|
||||
"p95": 0.244932,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.250653,
|
||||
"min": 0.130637,
|
||||
"p50": 0.153339,
|
||||
"p95": 0.221498,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.632972,
|
||||
"min": 1.913981,
|
||||
"p50": 2.233333,
|
||||
"p95": 2.59779,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 7,
|
||||
"sha256": "f9d74067d87c1ebf30c6db372a26d93b7285791c8cb0307a24af5adb23bf201a"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
},
|
||||
{
|
||||
"name": "collect-3d",
|
||||
"dimension": 3,
|
||||
"language": "cpp",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": ".gitignore",
|
||||
"sha256": "53aa4d7124d4c8d93b8d7c4cb470b6c82b844e019a660d6243ffeadc50602de1"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/create.py",
|
||||
"sha256": "9c7291124fb1498a3f992ef74afc39cd98f9cc3e2ff4687c633bece85d580905"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/manifest.json",
|
||||
"sha256": "7a13347adc89761fb02ebeab3c58ba87f319cd62f53ec87a3bb61bcd066ffa55"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/manifest.json.faset-import.json",
|
||||
"sha256": "ef4eef28a18a0cc40a40df75db34c97faa5d783b891265f862633f3aec514afc"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
|
||||
"sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/source.blend",
|
||||
"sha256": "ff2676bec97ab778e531e87a185ad716049ea3b05b4a4f0027a6345737735035"
|
||||
},
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "2df5ca4df47ab5d3d05d41508201296d4ad5ec876245f19f061767ade6a30e8f"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "61b65baf79e52f07ac386a7f98acf985a1b09e88770cdde37ef461dc94b9dcd7"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Extensions/Beacon.hpp",
|
||||
"sha256": "c60d56161eead16f541835053ad32ac3333383d83015709c060b7d45e0af5a97"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.cpp",
|
||||
"sha256": "5d419786a6861d7f14ed4eca54634694d8cd43be5dbbd60a2c6790db665c3a6a"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.hpp",
|
||||
"sha256": "4121587182ed4f74901b1c0757c53daadbf309af1d6bb5dd87fef142130ccbbe"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "43d273b1054ec9069369073f54cc1fc7efb3d6b699dcd342c552a2dc2ef852ef"
|
||||
}
|
||||
],
|
||||
"import": {
|
||||
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
|
||||
"cache_hit": false,
|
||||
"diagnostics": [],
|
||||
"generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"manifest": {
|
||||
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
|
||||
"files": [
|
||||
{
|
||||
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh",
|
||||
"sha256": "3875c16ea628d4126373ebfe07816621fbad3961596a2fcd112f1eec0e378071",
|
||||
"size": 928
|
||||
}
|
||||
],
|
||||
"generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"importer": "faset-gltf-1/cgltf-1.15",
|
||||
"input_key": {
|
||||
"bundle_sha256": "7a13347adc89761fb02ebeab3c58ba87f319cd62f53ec87a3bb61bcd066ffa55",
|
||||
"dependencies": {},
|
||||
"importer": "faset-gltf-1/cgltf-1.15",
|
||||
"settings": {},
|
||||
"source": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
|
||||
"target_profile": "desktop-static-pbr-v1",
|
||||
"toolchain": {
|
||||
"cgltf": "360db1a95480fe102ae9c69b27c5d101167ff5ba",
|
||||
"stb": "2c980bb59875b0d32144a71867fbdebb2f77cd20"
|
||||
}
|
||||
},
|
||||
"kind": "scene",
|
||||
"materials": [
|
||||
{
|
||||
"alpha_cutoff": 0.5,
|
||||
"alpha_mode": "OPAQUE",
|
||||
"base_color": [
|
||||
0.2199999988079071,
|
||||
0.28999999165534973,
|
||||
0.3400000035762787,
|
||||
1.0
|
||||
],
|
||||
"base_color_texture": -1,
|
||||
"double_sided": true,
|
||||
"emissive": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"emissive_texture": -1,
|
||||
"format": "faset.material",
|
||||
"id": "material-bb63b094febbf90bb7049c9bcf7587bc",
|
||||
"metallic": 0.07999999821186066,
|
||||
"metallic_roughness_texture": -1,
|
||||
"name": "Weathered stone",
|
||||
"normal_texture": -1,
|
||||
"occlusion_texture": -1,
|
||||
"roughness": 0.800000011920929,
|
||||
"unlit": false,
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"id": "mesh-fc069a07a87e0f831fd92efdbc4efa1f",
|
||||
"name": "Cube.001",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mesh-0961e2a3f92977836a3aa80cab09277e",
|
||||
"name": "Cube.002",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
|
||||
"name": "Cube.003",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "node-cec6e8cea80cf5a98ba3263a0156bee4",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.4500000476837158,
|
||||
1.2999999523162842,
|
||||
1.0
|
||||
],
|
||||
"mesh": 0,
|
||||
"name": "Left post",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
},
|
||||
{
|
||||
"id": "node-5f8a90a6c4d27020d20bd4fa81d1d958",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.4500000476837158,
|
||||
-1.2999999523162842,
|
||||
1.0
|
||||
],
|
||||
"mesh": 1,
|
||||
"name": "Right post",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
},
|
||||
{
|
||||
"id": "node-482463e486a8d1fd741340c653cd128f",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"mesh": 2,
|
||||
"name": "Lintel",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
"node-cec6e8cea80cf5a98ba3263a0156bee4",
|
||||
"node-5f8a90a6c4d27020d20bd4fa81d1d958",
|
||||
"node-482463e486a8d1fd741340c653cd128f",
|
||||
"mesh-fc069a07a87e0f831fd92efdbc4efa1f",
|
||||
"mesh-0961e2a3f92977836a3aa80cab09277e",
|
||||
"mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
|
||||
"material-bb63b094febbf90bb7049c9bcf7587bc"
|
||||
],
|
||||
"payload_source": "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-3d/Assets/exit-arch/payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
|
||||
"schema_version": 1,
|
||||
"settings": {},
|
||||
"source": "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-3d/Assets/exit-arch/manifest.json",
|
||||
"source_sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
|
||||
"textures": []
|
||||
},
|
||||
"previous_generation": "",
|
||||
"removed_output_ids": []
|
||||
},
|
||||
"generation": "004c6e18-969b-4ef5-95bb-5d7742f96564",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 46,
|
||||
"asset_generations": {
|
||||
"5832763b-3ed0-44d6-9088-0b524f196a91": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2"
|
||||
},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.62432,
|
||||
"min": 0.592032,
|
||||
"p50": 0.593792,
|
||||
"p95": 0.61008,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 5.917472,
|
||||
"min": 1.873163,
|
||||
"p50": 2.209838,
|
||||
"p95": 2.552535,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 5.909758,
|
||||
"min": 1.867162,
|
||||
"p50": 2.201673,
|
||||
"p95": 2.53905,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.530744,
|
||||
"min": 0.388893,
|
||||
"p50": 0.499071,
|
||||
"p95": 0.636931,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.608728,
|
||||
"min": 0.172335,
|
||||
"p50": 0.203934,
|
||||
"p95": 0.284217,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.714438,
|
||||
"min": 0.170371,
|
||||
"p50": 0.191832,
|
||||
"p95": 0.280138,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.969116,
|
||||
"min": 2.24785,
|
||||
"p50": 2.627506,
|
||||
"p95": 3.081914,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 65,
|
||||
"sha256": "2905891c9766b2f1f65d5b4284056cb3839f1faae195f9fea39a56e3ebf44363"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
},
|
||||
{
|
||||
"name": "lua",
|
||||
"dimension": 2,
|
||||
"language": "lua",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "8392da3c18916400ea628daed094c77c390c553cbdcf822da227bdcd3d86380c"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "f1ab54150a58b289c47bcc34566ad7ee3025ad931db81e7f5dce70d9fbcac8ab"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/beacon.lua",
|
||||
"sha256": "44d932ebedf66cadb9620f2d926177be2f8d43d71d56aa83611de686af026231"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/player.lua",
|
||||
"sha256": "1c51810574a3413c46a7cbd0ea2e84a9b802da1206a2b72bb78f6cc951367a11"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/util/motion.lua",
|
||||
"sha256": "bad3dcdc1081fd1dec589c12dad8dc175b739d77ea52b957ead9ecb4b7cb88a3"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "7e4c0781c1837208b4499a9991ffb702143edf1f933ae9c7e3d2543fd2577747"
|
||||
}
|
||||
],
|
||||
"generation": "92846e8b-d199-4679-8f6a-fb0686acba75",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 46,
|
||||
"asset_generations": {},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.589568,
|
||||
"min": 0.551712,
|
||||
"p50": 0.552416,
|
||||
"p95": 0.570016,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 6.280958,
|
||||
"min": 1.607562,
|
||||
"p50": 1.83424,
|
||||
"p95": 2.180794,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 6.273714,
|
||||
"min": 1.602192,
|
||||
"p50": 1.828289,
|
||||
"p95": 2.169262,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 3.40345,
|
||||
"min": 0.412939,
|
||||
"p50": 0.503159,
|
||||
"p95": 0.622655,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.231888,
|
||||
"min": 0.080883,
|
||||
"p50": 0.103485,
|
||||
"p95": 0.166965,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.136677,
|
||||
"min": 0.046938,
|
||||
"p50": 0.056226,
|
||||
"p95": 0.083728,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.601142,
|
||||
"min": 1.775219,
|
||||
"p50": 2.019429,
|
||||
"p95": 2.450732,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 4,
|
||||
"sha256": "e2f4c3b84de75dadd2e31d388d0ba51abc1861f1ec76eb7ba51a4a2dcac720a7"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
}
|
||||
],
|
||||
"requested_projects": [
|
||||
"collect-2d",
|
||||
"collect-3d",
|
||||
"lua"
|
||||
],
|
||||
"finished_utc": "2026-09-24T02:07:41.244688+00:00"
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"format": "faset.p1-release-reference",
|
||||
"version": 1,
|
||||
"source_revision": "4a3453e2b1868555d833f578d43f48b8bc47d41a",
|
||||
"editor_sha256": "73702e9f0fe015ef932db694400a0501048be2d602ab521ecc48c51767275d23",
|
||||
"verification_sha256": "63da692b605621acc1cace00d4a3c9cf35de13abfd4351aea6653a88c870e03f",
|
||||
"host": {
|
||||
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
|
||||
"machine": "x86_64",
|
||||
"processor": ""
|
||||
},
|
||||
"method": "sequential relocated Release Player, default direct/temporal-off, offscreen 1280x720, 240 completed frames including first; nearest-rank p95, validation/readback enabled",
|
||||
"projects": [
|
||||
{
|
||||
"name": "collect-2d",
|
||||
"dimension": 2,
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"player_sha256": "5936d8a1ceae9250c69f1b8ebccbadebc40b13e812bebeb9752da3d14d202a4a",
|
||||
"manifest_sha256": "5f8de3eb000dc7207b256265f0fa20a29efe194dd1347ab4c3bf670cfdcfb2b0",
|
||||
"profile_sha256": "65858b1de2334d304ad3a0907180aaf4f79ead3da63762500e50b7298d922bfa",
|
||||
"requested_frames": 240,
|
||||
"completed_frames": 240,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.585248,
|
||||
"min": 0.552064,
|
||||
"p50": 0.557184,
|
||||
"p95": 0.573056,
|
||||
"samples": 240
|
||||
},
|
||||
"render_call": {
|
||||
"max": 6.04885,
|
||||
"min": 1.470684,
|
||||
"p50": 1.795998,
|
||||
"p95": 2.305238,
|
||||
"samples": 240
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 6.043249,
|
||||
"min": 1.466045,
|
||||
"p50": 1.79204,
|
||||
"p95": 2.300209,
|
||||
"samples": 240
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.620153,
|
||||
"min": 0.398713,
|
||||
"p50": 0.462312,
|
||||
"p95": 0.559205,
|
||||
"samples": 240
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.357284,
|
||||
"min": 0.130406,
|
||||
"p50": 0.168848,
|
||||
"p95": 0.242057,
|
||||
"samples": 240
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.338358,
|
||||
"min": 0.124996,
|
||||
"p50": 0.157076,
|
||||
"p95": 0.197363,
|
||||
"samples": 240
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.47329,
|
||||
"min": 1.746054,
|
||||
"p50": 2.137342,
|
||||
"p95": 2.693952,
|
||||
"samples": 240
|
||||
}
|
||||
},
|
||||
"startup_ms": {
|
||||
"main_to_first_frame": 295.436243,
|
||||
"renderer_initialization": 284.655357,
|
||||
"scene_read": 0.410555,
|
||||
"world_initialization": 0.64129
|
||||
},
|
||||
"effective_lighting_path": "forward",
|
||||
"gpu_allocated_bytes_max": 45112032,
|
||||
"sun_shadow_atlas_bytes_max": 16777216,
|
||||
"local_shadow_atlas_bytes_max": 16777216,
|
||||
"gpu_allocated_excluding_shadow_atlases_bytes_max": 11557600,
|
||||
"effective_sun_cascades_max": 0,
|
||||
"local_shadow_faces_max": 0,
|
||||
"budget_checks": {
|
||||
"wall": {
|
||||
"observed_ms": 2.693952,
|
||||
"limit_ms": 4.0,
|
||||
"met": true
|
||||
},
|
||||
"gpu": {
|
||||
"observed_ms": 0.573056,
|
||||
"limit_ms": 1.0,
|
||||
"met": true
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"observed_ms": 0.559205,
|
||||
"limit_ms": 1.0,
|
||||
"met": true
|
||||
},
|
||||
"simulation": {
|
||||
"observed_ms": 0.242057,
|
||||
"limit_ms": 0.5,
|
||||
"met": true
|
||||
},
|
||||
"snapshot": {
|
||||
"observed_ms": 0.197363,
|
||||
"limit_ms": 0.5,
|
||||
"met": true
|
||||
},
|
||||
"explicit_allocation": {
|
||||
"observed_bytes": 45112032,
|
||||
"limit_bytes": 20971520,
|
||||
"met": false
|
||||
},
|
||||
"startup": {
|
||||
"observed_ms": 295.436243,
|
||||
"limit_ms": 500.0,
|
||||
"met": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "collect-3d",
|
||||
"dimension": 3,
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"player_sha256": "52fbe0067fc2be3807e60ffa5a77e819838dc50a4b723af51f16379b4a487e7c",
|
||||
"manifest_sha256": "484eda90411c48277385a2f679561cfa6304965a7a7be6ec065bfbd9dace1722",
|
||||
"profile_sha256": "b0c4c6b4020b1ded792917fff1f36510b76bb30864d89bd4e6e250b5693c5fe8",
|
||||
"requested_frames": 240,
|
||||
"completed_frames": 240,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.628288,
|
||||
"min": 0.590144,
|
||||
"p50": 0.592224,
|
||||
"p95": 0.616512,
|
||||
"samples": 240
|
||||
},
|
||||
"render_call": {
|
||||
"max": 5.902553,
|
||||
"min": 1.958014,
|
||||
"p50": 2.192415,
|
||||
"p95": 2.551243,
|
||||
"samples": 240
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 5.89525,
|
||||
"min": 1.949527,
|
||||
"p50": 2.184501,
|
||||
"p95": 2.543007,
|
||||
"samples": 240
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.581069,
|
||||
"min": 0.350231,
|
||||
"p50": 0.454097,
|
||||
"p95": 0.560908,
|
||||
"samples": 240
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.432225,
|
||||
"min": 0.170772,
|
||||
"p50": 0.191732,
|
||||
"p95": 0.299776,
|
||||
"samples": 240
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.745236,
|
||||
"min": 0.171273,
|
||||
"p50": 0.188084,
|
||||
"p95": 0.287632,
|
||||
"samples": 240
|
||||
},
|
||||
"wall": {
|
||||
"max": 7.001186,
|
||||
"min": 2.330556,
|
||||
"p50": 2.605595,
|
||||
"p95": 3.036327,
|
||||
"samples": 240
|
||||
}
|
||||
},
|
||||
"startup_ms": {
|
||||
"main_to_first_frame": 248.272928,
|
||||
"renderer_initialization": 237.578356,
|
||||
"scene_read": 0.506575,
|
||||
"world_initialization": 0.62037
|
||||
},
|
||||
"effective_lighting_path": "forward",
|
||||
"gpu_allocated_bytes_max": 45212272,
|
||||
"sun_shadow_atlas_bytes_max": 16777216,
|
||||
"local_shadow_atlas_bytes_max": 16777216,
|
||||
"gpu_allocated_excluding_shadow_atlases_bytes_max": 11657840,
|
||||
"effective_sun_cascades_max": 4,
|
||||
"local_shadow_faces_max": 0,
|
||||
"budget_checks": {
|
||||
"wall": {
|
||||
"observed_ms": 3.036327,
|
||||
"limit_ms": 4.0,
|
||||
"met": true
|
||||
},
|
||||
"gpu": {
|
||||
"observed_ms": 0.616512,
|
||||
"limit_ms": 1.0,
|
||||
"met": true
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"observed_ms": 0.560908,
|
||||
"limit_ms": 1.0,
|
||||
"met": true
|
||||
},
|
||||
"simulation": {
|
||||
"observed_ms": 0.299776,
|
||||
"limit_ms": 0.5,
|
||||
"met": true
|
||||
},
|
||||
"snapshot": {
|
||||
"observed_ms": 0.287632,
|
||||
"limit_ms": 0.5,
|
||||
"met": true
|
||||
},
|
||||
"explicit_allocation": {
|
||||
"observed_bytes": 45212272,
|
||||
"limit_bytes": 20971520,
|
||||
"met": false
|
||||
},
|
||||
"startup": {
|
||||
"observed_ms": 248.272928,
|
||||
"limit_ms": 500.0,
|
||||
"met": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
{
|
||||
"format": "faset.playable-export-verification",
|
||||
"version": 1,
|
||||
"started_utc": "2026-09-24T02:01:24.205054+00:00",
|
||||
"platform": "linux",
|
||||
"engine": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration",
|
||||
"editor": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/build/linux-release/faset_editor",
|
||||
"standalone_root": "/tmp/faset-p1-final-packages-4a3453e",
|
||||
"engine_revision": "4a3453e2b1868555d833f578d43f48b8bc47d41a",
|
||||
"engine_dirty": false,
|
||||
"engine_git_status": [],
|
||||
"engine_diff_sha256": null,
|
||||
"editor_sha256": "73702e9f0fe015ef932db694400a0501048be2d602ab521ecc48c51767275d23",
|
||||
"project_workspace": "/tmp/faset-p1-final-release-4a3453e",
|
||||
"vulkaninfo_available": true,
|
||||
"driver_override": null,
|
||||
"frames_per_game": 120,
|
||||
"status": "passed",
|
||||
"projects": [
|
||||
{
|
||||
"name": "collect-2d",
|
||||
"dimension": 2,
|
||||
"language": "cpp",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": ".gitignore",
|
||||
"sha256": "53aa4d7124d4c8d93b8d7c4cb470b6c82b844e019a660d6243ffeadc50602de1"
|
||||
},
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "8cf5a2d6de849eb090b9ea6d5e27841f551bd06947e5054f0d2f59639a90edd0"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "be48a6d21385e717b6c8ebf9a3b4322eebbeff6bb067428e089ab5214be79854"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.cpp",
|
||||
"sha256": "6b581b24da613e1915819de0a0f0ea820dd3333efa62c4b479a9ea7ffdbc6bcc"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.hpp",
|
||||
"sha256": "4121587182ed4f74901b1c0757c53daadbf309af1d6bb5dd87fef142130ccbbe"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "36e2acd32210f5489372a2331346a3294ead2395f0713e3e5fd2da4e83263689"
|
||||
}
|
||||
],
|
||||
"generation": "ca306aa8-a094-42bc-833f-a24a05cab73d",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 41,
|
||||
"asset_generations": {},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.581984,
|
||||
"min": 0.555552,
|
||||
"p50": 0.5592,
|
||||
"p95": 0.568896,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 6.021328,
|
||||
"min": 1.627681,
|
||||
"p50": 1.892219,
|
||||
"p95": 2.165605,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 6.013313,
|
||||
"min": 1.621609,
|
||||
"p50": 1.883223,
|
||||
"p95": 2.15763,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.645991,
|
||||
"min": 0.386439,
|
||||
"p50": 0.478583,
|
||||
"p95": 0.582889,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.332657,
|
||||
"min": 0.135175,
|
||||
"p50": 0.166364,
|
||||
"p95": 0.244932,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.250653,
|
||||
"min": 0.130637,
|
||||
"p50": 0.153339,
|
||||
"p95": 0.221498,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.632972,
|
||||
"min": 1.913981,
|
||||
"p50": 2.233333,
|
||||
"p95": 2.59779,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 7,
|
||||
"sha256": "f9d74067d87c1ebf30c6db372a26d93b7285791c8cb0307a24af5adb23bf201a"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
},
|
||||
{
|
||||
"name": "collect-3d",
|
||||
"dimension": 3,
|
||||
"language": "cpp",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": ".gitignore",
|
||||
"sha256": "53aa4d7124d4c8d93b8d7c4cb470b6c82b844e019a660d6243ffeadc50602de1"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/create.py",
|
||||
"sha256": "9c7291124fb1498a3f992ef74afc39cd98f9cc3e2ff4687c633bece85d580905"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/manifest.json",
|
||||
"sha256": "7a13347adc89761fb02ebeab3c58ba87f319cd62f53ec87a3bb61bcd066ffa55"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/manifest.json.faset-import.json",
|
||||
"sha256": "ef4eef28a18a0cc40a40df75db34c97faa5d783b891265f862633f3aec514afc"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
|
||||
"sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3"
|
||||
},
|
||||
{
|
||||
"path": "Assets/exit-arch/source.blend",
|
||||
"sha256": "ff2676bec97ab778e531e87a185ad716049ea3b05b4a4f0027a6345737735035"
|
||||
},
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "2df5ca4df47ab5d3d05d41508201296d4ad5ec876245f19f061767ade6a30e8f"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "61b65baf79e52f07ac386a7f98acf985a1b09e88770cdde37ef461dc94b9dcd7"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Extensions/Beacon.hpp",
|
||||
"sha256": "c60d56161eead16f541835053ad32ac3333383d83015709c060b7d45e0af5a97"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.cpp",
|
||||
"sha256": "5d419786a6861d7f14ed4eca54634694d8cd43be5dbbd60a2c6790db665c3a6a"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/Gameplay.hpp",
|
||||
"sha256": "4121587182ed4f74901b1c0757c53daadbf309af1d6bb5dd87fef142130ccbbe"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "43d273b1054ec9069369073f54cc1fc7efb3d6b699dcd342c552a2dc2ef852ef"
|
||||
}
|
||||
],
|
||||
"import": {
|
||||
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
|
||||
"cache_hit": false,
|
||||
"diagnostics": [],
|
||||
"generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"manifest": {
|
||||
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
|
||||
"files": [
|
||||
{
|
||||
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh",
|
||||
"sha256": "3875c16ea628d4126373ebfe07816621fbad3961596a2fcd112f1eec0e378071",
|
||||
"size": 928
|
||||
}
|
||||
],
|
||||
"generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"importer": "faset-gltf-1/cgltf-1.15",
|
||||
"input_key": {
|
||||
"bundle_sha256": "7a13347adc89761fb02ebeab3c58ba87f319cd62f53ec87a3bb61bcd066ffa55",
|
||||
"dependencies": {},
|
||||
"importer": "faset-gltf-1/cgltf-1.15",
|
||||
"settings": {},
|
||||
"source": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
|
||||
"target_profile": "desktop-static-pbr-v1",
|
||||
"toolchain": {
|
||||
"cgltf": "360db1a95480fe102ae9c69b27c5d101167ff5ba",
|
||||
"stb": "2c980bb59875b0d32144a71867fbdebb2f77cd20"
|
||||
}
|
||||
},
|
||||
"kind": "scene",
|
||||
"materials": [
|
||||
{
|
||||
"alpha_cutoff": 0.5,
|
||||
"alpha_mode": "OPAQUE",
|
||||
"base_color": [
|
||||
0.2199999988079071,
|
||||
0.28999999165534973,
|
||||
0.3400000035762787,
|
||||
1.0
|
||||
],
|
||||
"base_color_texture": -1,
|
||||
"double_sided": true,
|
||||
"emissive": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"emissive_texture": -1,
|
||||
"format": "faset.material",
|
||||
"id": "material-bb63b094febbf90bb7049c9bcf7587bc",
|
||||
"metallic": 0.07999999821186066,
|
||||
"metallic_roughness_texture": -1,
|
||||
"name": "Weathered stone",
|
||||
"normal_texture": -1,
|
||||
"occlusion_texture": -1,
|
||||
"roughness": 0.800000011920929,
|
||||
"unlit": false,
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"id": "mesh-fc069a07a87e0f831fd92efdbc4efa1f",
|
||||
"name": "Cube.001",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mesh-0961e2a3f92977836a3aa80cab09277e",
|
||||
"name": "Cube.002",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
|
||||
"name": "Cube.003",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "node-cec6e8cea80cf5a98ba3263a0156bee4",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.4500000476837158,
|
||||
1.2999999523162842,
|
||||
1.0
|
||||
],
|
||||
"mesh": 0,
|
||||
"name": "Left post",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
},
|
||||
{
|
||||
"id": "node-5f8a90a6c4d27020d20bd4fa81d1d958",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.4500000476837158,
|
||||
-1.2999999523162842,
|
||||
1.0
|
||||
],
|
||||
"mesh": 1,
|
||||
"name": "Right post",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
},
|
||||
{
|
||||
"id": "node-482463e486a8d1fd741340c653cd128f",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"mesh": 2,
|
||||
"name": "Lintel",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
"node-cec6e8cea80cf5a98ba3263a0156bee4",
|
||||
"node-5f8a90a6c4d27020d20bd4fa81d1d958",
|
||||
"node-482463e486a8d1fd741340c653cd128f",
|
||||
"mesh-fc069a07a87e0f831fd92efdbc4efa1f",
|
||||
"mesh-0961e2a3f92977836a3aa80cab09277e",
|
||||
"mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
|
||||
"material-bb63b094febbf90bb7049c9bcf7587bc"
|
||||
],
|
||||
"payload_source": "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-3d/Assets/exit-arch/payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
|
||||
"schema_version": 1,
|
||||
"settings": {},
|
||||
"source": "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-3d/Assets/exit-arch/manifest.json",
|
||||
"source_sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
|
||||
"textures": []
|
||||
},
|
||||
"previous_generation": "",
|
||||
"removed_output_ids": []
|
||||
},
|
||||
"generation": "004c6e18-969b-4ef5-95bb-5d7742f96564",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 46,
|
||||
"asset_generations": {
|
||||
"5832763b-3ed0-44d6-9088-0b524f196a91": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2"
|
||||
},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.62432,
|
||||
"min": 0.592032,
|
||||
"p50": 0.593792,
|
||||
"p95": 0.61008,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 5.917472,
|
||||
"min": 1.873163,
|
||||
"p50": 2.209838,
|
||||
"p95": 2.552535,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 5.909758,
|
||||
"min": 1.867162,
|
||||
"p50": 2.201673,
|
||||
"p95": 2.53905,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 2.530744,
|
||||
"min": 0.388893,
|
||||
"p50": 0.499071,
|
||||
"p95": 0.636931,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.608728,
|
||||
"min": 0.172335,
|
||||
"p50": 0.203934,
|
||||
"p95": 0.284217,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.714438,
|
||||
"min": 0.170371,
|
||||
"p50": 0.191832,
|
||||
"p95": 0.280138,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.969116,
|
||||
"min": 2.24785,
|
||||
"p50": 2.627506,
|
||||
"p95": 3.081914,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 65,
|
||||
"sha256": "2905891c9766b2f1f65d5b4284056cb3839f1faae195f9fea39a56e3ebf44363"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
},
|
||||
{
|
||||
"name": "lua",
|
||||
"dimension": 2,
|
||||
"language": "lua",
|
||||
"source_inputs": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "8392da3c18916400ea628daed094c77c390c553cbdcf822da227bdcd3d86380c"
|
||||
},
|
||||
{
|
||||
"path": "Scenes/main.scene.json",
|
||||
"sha256": "f1ab54150a58b289c47bcc34566ad7ee3025ad931db81e7f5dce70d9fbcac8ab"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/beacon.lua",
|
||||
"sha256": "44d932ebedf66cadb9620f2d926177be2f8d43d71d56aa83611de686af026231"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/player.lua",
|
||||
"sha256": "1c51810574a3413c46a7cbd0ea2e84a9b802da1206a2b72bb78f6cc951367a11"
|
||||
},
|
||||
{
|
||||
"path": "Scripts/util/motion.lua",
|
||||
"sha256": "bad3dcdc1081fd1dec589c12dad8dc175b739d77ea52b957ead9ecb4b7cb88a3"
|
||||
},
|
||||
{
|
||||
"path": "project.faset.json",
|
||||
"sha256": "7e4c0781c1837208b4499a9991ffb702143edf1f933ae9c7e3d2543fd2577747"
|
||||
}
|
||||
],
|
||||
"generation": "92846e8b-d199-4679-8f6a-fb0686acba75",
|
||||
"configuration": "Release",
|
||||
"standalone_directory": "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua",
|
||||
"executable": "faset_player",
|
||||
"package_file_count": 46,
|
||||
"asset_generations": {},
|
||||
"device": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"device_class": "physical",
|
||||
"driver": {
|
||||
"apiVersion": "1.4.329",
|
||||
"driverVersion": "595.84.0.0",
|
||||
"deviceName": "NVIDIA GeForce RTX 2080 Ti",
|
||||
"driverID": "DRIVER_ID_NVIDIA_PROPRIETARY",
|
||||
"driverName": "NVIDIA",
|
||||
"driverInfo": "595.84"
|
||||
},
|
||||
"validation_enabled": true,
|
||||
"validation_errors": 0,
|
||||
"completed_frames": 120,
|
||||
"summary_ms": {
|
||||
"gpu": {
|
||||
"max": 0.589568,
|
||||
"min": 0.551712,
|
||||
"p50": 0.552416,
|
||||
"p95": 0.570016,
|
||||
"samples": 120
|
||||
},
|
||||
"render_call": {
|
||||
"max": 6.280958,
|
||||
"min": 1.607562,
|
||||
"p50": 1.83424,
|
||||
"p95": 2.180794,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_cpu": {
|
||||
"max": 6.273714,
|
||||
"min": 1.602192,
|
||||
"p50": 1.828289,
|
||||
"p95": 2.169262,
|
||||
"samples": 120
|
||||
},
|
||||
"renderer_readback_cpu": {
|
||||
"max": 3.40345,
|
||||
"min": 0.412939,
|
||||
"p50": 0.503159,
|
||||
"p95": 0.622655,
|
||||
"samples": 120
|
||||
},
|
||||
"simulation": {
|
||||
"max": 0.231888,
|
||||
"min": 0.080883,
|
||||
"p50": 0.103485,
|
||||
"p95": 0.166965,
|
||||
"samples": 120
|
||||
},
|
||||
"snapshot": {
|
||||
"max": 0.136677,
|
||||
"min": 0.046938,
|
||||
"p50": 0.056226,
|
||||
"p95": 0.083728,
|
||||
"samples": 120
|
||||
},
|
||||
"wall": {
|
||||
"max": 6.601142,
|
||||
"min": 1.775219,
|
||||
"p50": 2.019429,
|
||||
"p95": 2.450732,
|
||||
"samples": 120
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
"width": 1280,
|
||||
"height": 720,
|
||||
"sampled_colors": 4,
|
||||
"sha256": "e2f4c3b84de75dadd2e31d388d0ba51abc1861f1ec76eb7ba51a4a2dcac720a7"
|
||||
},
|
||||
"source_project_paths_unavailable": true,
|
||||
"status": "passed"
|
||||
}
|
||||
],
|
||||
"requested_projects": [
|
||||
"collect-2d",
|
||||
"collect-3d",
|
||||
"lua"
|
||||
],
|
||||
"finished_utc": "2026-09-24T02:07:41.244688+00:00"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
collect-2d-export: /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/build/linux-release/faset_editor --engine /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration --project "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-2d" --command "{\"name\": \"faset_export\", \"arguments\": {\"document\": \"example-collect-2d-scene\", \"output\": \"Exports\"}}" --wait
|
||||
collect-3d-import: /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/build/linux-release/faset_editor --engine /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration --project "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-3d" --command "{\"name\": \"faset_import\", \"arguments\": {\"path\": \"Assets/exit-arch/manifest.json\"}}" --wait
|
||||
collect-3d-export: /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/build/linux-release/faset_editor --engine /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration --project "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/collect-3d" --command "{\"name\": \"faset_export\", \"arguments\": {\"document\": \"example-collect-3d-scene\", \"output\": \"Exports\"}}" --wait
|
||||
lua-export: /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration/build/linux-release/faset_editor --engine /home/emil/Desktop/.worktrees/Faset_Engine-p1-p3-integration --project "/tmp/faset-p1-final-release-4a3453e/Faset Café 世界/lua" --command "{\"name\": \"faset_export\", \"arguments\": {\"document\": \"example-lua-scene\", \"output\": \"Exports\"}}" --wait
|
||||
collect-2d-validate: "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/faset_player" --validate
|
||||
collect-2d-run: "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/faset_player" --headless --frames 120 --capture "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/verification.ppm" --profile "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-2d/profile.json"
|
||||
collect-3d-validate: "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/faset_player" --validate
|
||||
collect-3d-run: "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/faset_player" --headless --frames 120 --capture "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/verification.ppm" --profile "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/collect-3d/profile.json"
|
||||
lua-validate: "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/faset_player" --validate
|
||||
lua-run: "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/faset_player" --headless --frames 120 --capture "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/verification.ppm" --profile "/tmp/faset-p1-final-packages-4a3453e/Faset Café 世界/lua/profile.json"
|
||||
3 relocated Release game(s) passed: /tmp/faset-p1-final-release-4a3453e/report.json
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"format": "faset.workflow-provenance-supplement",
|
||||
"version": 1,
|
||||
"captured_at_utc": "2026-09-24T00:17:12.501486+00:00",
|
||||
"measurement_revision": "6c2e8fa80036315a695f67f3c53524165fb4b10a",
|
||||
"collector_revision": "abd8c21273ac886f6afe30e728a27a65b882f11f",
|
||||
"report_sha256": "fd463c0cd12eed0a22143aa68bd732386804b0df4ecb2a3d9caa26f59dcfe6e2",
|
||||
"measurement_script_sha256": "dc13c1b253b8093ac4a528b7194a1e54e0cb00fdfe0881021e6740de40717ee3",
|
||||
"collector_script_sha256": "8fd8098c11e01ef6e0b2c0681f26d62b1dedf0e25840222642ec5d77df248868",
|
||||
"archived_cmake_cache": "CMakeCache.txt.gz",
|
||||
"binary_provenance": {
|
||||
"cmake_cache_sha256": "d82a2b2ed39430f9ebba82b87b182a1a8822e2419a69778eb4dadcb074064c73",
|
||||
"binaries": {
|
||||
"cmake": {
|
||||
"path": "/usr/bin/cmake",
|
||||
"sha256": "6e1dccda39845415d68eabb934c598998949c99ec4668625d571aee1827b05c7",
|
||||
"version": "cmake version 4.2.3"
|
||||
},
|
||||
"ninja": {
|
||||
"path": "/usr/bin/ninja",
|
||||
"sha256": "91e9548850cda2799facfdaa7abe33f9e978832f85e98212255708a7bbe437f2",
|
||||
"version": "1.13.2"
|
||||
},
|
||||
"c": {
|
||||
"path": "/usr/lib/llvm-21/bin/clang",
|
||||
"sha256": "412bbe8c60571a1eb06f48fde89635033621caeb01a9b4ee76d46711bae8e932",
|
||||
"version": "Ubuntu clang version 21.1.8 (6ubuntu1)"
|
||||
},
|
||||
"cxx": {
|
||||
"path": "/usr/lib/llvm-21/bin/clang",
|
||||
"sha256": "412bbe8c60571a1eb06f48fde89635033621caeb01a9b4ee76d46711bae8e932",
|
||||
"version": "Ubuntu clang version 21.1.8 (6ubuntu1)"
|
||||
},
|
||||
"slang": {
|
||||
"path": "/home/emil/Desktop/Faset_Engine/.cache/slang/bin/slangc",
|
||||
"sha256": "ff47ad16a3110e43f96a45e90720e6f894371d27f5e47715b298159e395b75e8",
|
||||
"version": "2026.18"
|
||||
},
|
||||
"editor": {
|
||||
"path": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor",
|
||||
"sha256": "e0cd1a3e7dec54e6960723b1a9068602a17e84e14e490289ea6de6ebf3964657",
|
||||
"version": null
|
||||
},
|
||||
"ui_latency_binary": {
|
||||
"path": "/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor_ui_latency",
|
||||
"sha256": "c1b7f68c0e68d5c38d458330d22cbaa7dd6ed2d2962df520fd99cf7eb71ea1ed",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"note": "Captured after the completed run from its surviving disposable CMake cache and unchanged measured binaries; report.json is the unmodified original run output.",
|
||||
"cmake_cache_archive_sha256": "da52ab111b3b1a14a73f322e4ad7594ac55e72512074ec92c1889f03ae98a38b"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Command exited with non-zero status 1
|
||||
{"peak_rss_kib":303308}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"seconds": 9.99945926599321,
|
||||
"returncode": 1,
|
||||
"build_configuration": "Debug",
|
||||
"source_hash": "9cf76ceab03f32fc0baf1eebf6db150fe386fe685ee3a9137271a806f97bdff9",
|
||||
"command": [
|
||||
"/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor",
|
||||
"--project",
|
||||
"/tmp/faset-p1-workflows-20260924-3/project",
|
||||
"--command",
|
||||
"{\"name\": \"faset_build\", \"arguments\": {}}",
|
||||
"--wait"
|
||||
],
|
||||
"stdout": "raw/build_failure-01-stdout.txt",
|
||||
"stderr": "raw/build_failure-01-stderr.txt",
|
||||
"peak_rss_kib": 303308
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"peak_rss_kib":351984}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"seconds": 19.928895885997918,
|
||||
"returncode": 0,
|
||||
"build_configuration": "Debug",
|
||||
"source_hash": "801fb7ba8f67c774ab1d7ec6350c8f099bf37aa6cd34afc952f7e81954df971e",
|
||||
"command": [
|
||||
"/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor",
|
||||
"--project",
|
||||
"/tmp/faset-p1-workflows-20260924-3/project",
|
||||
"--command",
|
||||
"{\"name\": \"faset_build\", \"arguments\": {}}",
|
||||
"--wait"
|
||||
],
|
||||
"stdout": "raw/build_recovery-01-stdout.txt",
|
||||
"stderr": "raw/build_recovery-01-stderr.txt",
|
||||
"peak_rss_kib": 351984
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"peak_rss_kib":9248}
|
||||
@@ -0,0 +1,210 @@
|
||||
{
|
||||
"error": "",
|
||||
"id": "import-ae79d218-16e3-4275-a83b-1c3ac2aa99f3",
|
||||
"kind": "import",
|
||||
"progress": 1.0,
|
||||
"request": {
|
||||
"allow_removed_outputs": false,
|
||||
"path": "Assets/exit-arch/manifest.json",
|
||||
"settings": null
|
||||
},
|
||||
"result": {
|
||||
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
|
||||
"cache_hit": true,
|
||||
"diagnostics": [],
|
||||
"generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"manifest": {
|
||||
"asset_id": "5832763b-3ed0-44d6-9088-0b524f196a91",
|
||||
"files": [
|
||||
{
|
||||
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh",
|
||||
"sha256": "98b38aca7d2786c58a2265ba4d1f2255123f03d31d947e239232cf55bfdc2c97",
|
||||
"size": 928
|
||||
},
|
||||
{
|
||||
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh",
|
||||
"sha256": "3875c16ea628d4126373ebfe07816621fbad3961596a2fcd112f1eec0e378071",
|
||||
"size": 928
|
||||
}
|
||||
],
|
||||
"generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"importer": "faset-gltf-1/cgltf-1.15",
|
||||
"input_key": {
|
||||
"bundle_sha256": "7a13347adc89761fb02ebeab3c58ba87f319cd62f53ec87a3bb61bcd066ffa55",
|
||||
"dependencies": {},
|
||||
"importer": "faset-gltf-1/cgltf-1.15",
|
||||
"settings": {},
|
||||
"source": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
|
||||
"target_profile": "desktop-static-pbr-v1",
|
||||
"toolchain": {
|
||||
"cgltf": "360db1a95480fe102ae9c69b27c5d101167ff5ba",
|
||||
"stb": "2c980bb59875b0d32144a71867fbdebb2f77cd20"
|
||||
}
|
||||
},
|
||||
"kind": "scene",
|
||||
"materials": [
|
||||
{
|
||||
"alpha_cutoff": 0.5,
|
||||
"alpha_mode": "OPAQUE",
|
||||
"base_color": [
|
||||
0.2199999988079071,
|
||||
0.28999999165534973,
|
||||
0.3400000035762787,
|
||||
1.0
|
||||
],
|
||||
"base_color_texture": -1,
|
||||
"double_sided": true,
|
||||
"emissive": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"emissive_texture": -1,
|
||||
"format": "faset.material",
|
||||
"id": "material-bb63b094febbf90bb7049c9bcf7587bc",
|
||||
"metallic": 0.07999999821186066,
|
||||
"metallic_roughness_texture": -1,
|
||||
"name": "Weathered stone",
|
||||
"normal_texture": -1,
|
||||
"occlusion_texture": -1,
|
||||
"roughness": 0.800000011920929,
|
||||
"unlit": false,
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"id": "mesh-fc069a07a87e0f831fd92efdbc4efa1f",
|
||||
"name": "Cube.001",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-fc069a07a87e0f831fd92efdbc4efa1f-0.fmesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mesh-0961e2a3f92977836a3aa80cab09277e",
|
||||
"name": "Cube.002",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-0961e2a3f92977836a3aa80cab09277e-0.fmesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
|
||||
"name": "Cube.003",
|
||||
"primitives": [
|
||||
{
|
||||
"material": 0,
|
||||
"path": "meshes/mesh-93b5b3e52cb6bb120fefb80e2d8e222b-0.fmesh"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "node-cec6e8cea80cf5a98ba3263a0156bee4",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.4500000476837158,
|
||||
1.2999999523162842,
|
||||
1.0
|
||||
],
|
||||
"mesh": 0,
|
||||
"name": "Left post",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
},
|
||||
{
|
||||
"id": "node-5f8a90a6c4d27020d20bd4fa81d1d958",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.4500000476837158,
|
||||
-1.2999999523162842,
|
||||
1.0
|
||||
],
|
||||
"mesh": 1,
|
||||
"name": "Right post",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
},
|
||||
{
|
||||
"id": "node-482463e486a8d1fd741340c653cd128f",
|
||||
"local_transform": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
3.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"mesh": 2,
|
||||
"name": "Lintel",
|
||||
"parent_id": "",
|
||||
"stable_source_id": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
"node-cec6e8cea80cf5a98ba3263a0156bee4",
|
||||
"node-5f8a90a6c4d27020d20bd4fa81d1d958",
|
||||
"node-482463e486a8d1fd741340c653cd128f",
|
||||
"mesh-fc069a07a87e0f831fd92efdbc4efa1f",
|
||||
"mesh-0961e2a3f92977836a3aa80cab09277e",
|
||||
"mesh-93b5b3e52cb6bb120fefb80e2d8e222b",
|
||||
"material-bb63b094febbf90bb7049c9bcf7587bc"
|
||||
],
|
||||
"payload_source": "/tmp/faset-p1-workflows-20260924-3/project/Assets/exit-arch/payload/ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3.glb",
|
||||
"schema_version": 1,
|
||||
"settings": {},
|
||||
"source": "/tmp/faset-p1-workflows-20260924-3/project/Assets/exit-arch/manifest.json",
|
||||
"source_sha256": "ee6c748a212905fc9c465cbe95c033e94b80be643624f4f240ad5353761205b3",
|
||||
"textures": []
|
||||
},
|
||||
"previous_generation": "4a5bfcc1437a7b4d65c388da2beace0308cceda8e16503d08ce676260f21d5c2",
|
||||
"removed_output_ids": []
|
||||
},
|
||||
"stage": "complete",
|
||||
"state": "succeeded"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"seconds": 0.05242176400497556,
|
||||
"returncode": 0,
|
||||
"build_configuration": "Debug",
|
||||
"source_hash": "5d419786a6861d7f14ed4eca54634694d8cd43be5dbbd60a2c6790db665c3a6a",
|
||||
"command": [
|
||||
"/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor",
|
||||
"--project",
|
||||
"/tmp/faset-p1-workflows-20260924-3/project",
|
||||
"--command",
|
||||
"{\"name\": \"faset_import\", \"arguments\": {\"path\": \"Assets/exit-arch/manifest.json\"}}",
|
||||
"--wait"
|
||||
],
|
||||
"stdout": "raw/cached_asset_import-01-stdout.txt",
|
||||
"stderr": "raw/cached_asset_import-01-stderr.txt",
|
||||
"peak_rss_kib": 9248
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"peak_rss_kib":353052}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"seconds": 29.83193460397888,
|
||||
"returncode": 0,
|
||||
"build_configuration": "Debug",
|
||||
"source_hash": "f94e26cbed75fee4b6f565adb64f525eb702221116ecb4fb3034b08bb2f5647a",
|
||||
"command": [
|
||||
"/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor",
|
||||
"--project",
|
||||
"/tmp/faset-p1-workflows-20260924-3/project",
|
||||
"--command",
|
||||
"{\"name\": \"faset_build\", \"arguments\": {}}",
|
||||
"--wait"
|
||||
],
|
||||
"stdout": "raw/changed_cpp_build-01-stdout.txt",
|
||||
"stderr": "raw/changed_cpp_build-01-stderr.txt",
|
||||
"peak_rss_kib": 353052
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"peak_rss_kib":353088}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"seconds": 30.331249505019514,
|
||||
"returncode": 0,
|
||||
"build_configuration": "Debug",
|
||||
"source_hash": "34bb0f6974f75e16bd13b79ea568c79b6d3baddb4387a461e7d4e4fc2d08e439",
|
||||
"command": [
|
||||
"/home/emil/Desktop/.worktrees/Faset_Engine-p1-p3/build/linux-debug/faset_editor",
|
||||
"--project",
|
||||
"/tmp/faset-p1-workflows-20260924-3/project",
|
||||
"--command",
|
||||
"{\"name\": \"faset_build\", \"arguments\": {}}",
|
||||
"--wait"
|
||||
],
|
||||
"stdout": "raw/changed_cpp_build-02-stdout.txt",
|
||||
"stderr": "raw/changed_cpp_build-02-stderr.txt",
|
||||
"peak_rss_kib": 353088
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"peak_rss_kib":352196}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user