The strategic layer does not search for a route: the player or the AI picks the destinations and the engine classifies each consecutive pair, deciding the waypoint kind and whether the order is legal. This models that classifier as pure functions. The waypoint kind of any leg that is neither a gate transit nor a node route is a pure function of the owning species -- which is the whole answer to why kind 2 has never been observed. Kind 2 is the Liir drive; the two node-drive races are Human and Zuul, both of which map to kind 3, and every observation so far was taken on one of those two. Also modelled: the three refusal bits versus the nine advisory ones, the gate transit that waives the grounded-fleet refusal, the projection radius that splits gate-to-gate from gate-to-gateless, the single-hop node line lookup and bore, and the fuel check whose range is squared at full precision while the distance is narrowed -- the one floating-point asymmetry here that flips a decision. The leading-destination drop is reproduced with its original off-by-one behind an explicit flag rather than silently fixed. 120 hand-computed checks. Host ctest 43/43; clean-room check OK.
129 lines
7.5 KiB
CMake
129 lines
7.5 KiB
CMake
cmake_minimum_required(VERSION 3.25)
|
|
project(sots-engine LANGUAGES C CXX)
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
|
|
# Build id stamped into the shim log banner (tools/build-shim.sh passes git describe + UTC time).
|
|
set(SHIM_BUILD_ID "dev" CACHE STRING "Build identifier logged by the shim")
|
|
|
|
# Provenance of the binary facts: the generated header's own "Source:" line, forwarded verbatim
|
|
# so every shim.log records which RE snapshot the RVAs came from.
|
|
file(STRINGS include/generated/sots_addresses.h _addr_provenance REGEX "^// Source:")
|
|
list(GET _addr_provenance 0 _addr_provenance)
|
|
string(REGEX REPLACE "^// " "" SOTS_ADDR_PROVENANCE "${_addr_provenance}")
|
|
|
|
add_library(sots_addresses INTERFACE)
|
|
target_include_directories(sots_addresses INTERFACE ${CMAKE_SOURCE_DIR}/include)
|
|
|
|
# ---- engine modules (host + cross): pure, oracle-verified code accrues here ----
|
|
add_subdirectory(src/mars/parse) # brace-block + .effect readers (lib mars_parse)
|
|
add_subdirectory(src/mars/text) # flat-kv, id-manifest, csv (lib mars_text)
|
|
add_subdirectory(src/game/sim) # strategic formulas, pure (lib sots_game_sim)
|
|
add_subdirectory(src/mars/vfs) # .gob ZIP reader + native override (lib mars_vfs, miniz)
|
|
add_subdirectory(src/mars/stream) # Streamable save format + gzip (lib mars_stream)
|
|
add_subdirectory(src/mars/rng) # MT19937 (lib mars_rng)
|
|
add_subdirectory(src/game/config) # flat KEY/value constants loader (lib sots_game_config)
|
|
add_subdirectory(src/game/data) # typed catalogs on mars/parse+text (lib game_data)
|
|
add_subdirectory(src/game/effects) # tech effects (TechId table + apply) (lib game_effects)
|
|
add_subdirectory(src/game/design) # ship-design rules + derived stats (lib game_design)
|
|
add_subdirectory(src/game/events) # player event log + research events (lib sots_game_events)
|
|
add_subdirectory(src/game/combat) # post-battle strategic consequences (lib sots_game_combat)
|
|
add_subdirectory(src/game/nav) # fleet path planning, pure (lib sots_game_nav)
|
|
add_subdirectory(src/app) # the standalone turn driver (lib sots_app, sots_turn)
|
|
|
|
# ---- shim trace/compare infrastructure (host-testable; linked into binkw32) ----
|
|
add_library(shim_trace STATIC
|
|
src/shim/trace/sha256.cpp
|
|
src/shim/trace/emitter.cpp
|
|
src/shim/trace/tracer.cpp
|
|
src/shim/trace/selftest.cpp)
|
|
target_include_directories(shim_trace PUBLIC ${CMAKE_SOURCE_DIR}/src)
|
|
target_compile_options(shim_trace PRIVATE -Wall -Wextra -Werror)
|
|
if(MINGW)
|
|
target_compile_definitions(shim_trace PUBLIC __USE_MINGW_ANSI_STDIO=1) # C99 %lld/%.17g
|
|
endif()
|
|
|
|
# ---- B1 budget adapter: ServerPlayer snapshot <-> game::sim economy (pure, host-tested) ----
|
|
add_library(shim_budget STATIC src/shim/hooks/budget_inputs.cpp)
|
|
target_link_libraries(shim_budget PUBLIC shim_trace sots_game_sim)
|
|
target_compile_options(shim_budget PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- B2 tech-effect adapter: ServerPlayer fields <-> game::effects state (pure, host-tested) ----
|
|
add_library(shim_techfx STATIC src/shim/hooks/tech_effect_fields.cpp)
|
|
target_link_libraries(shim_techfx PUBLIC shim_trace sots_addresses sots_game_effects)
|
|
target_compile_options(shim_techfx PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- B4 colony adapter: ServerSystem snapshot <-> game::sim colony turn (pure, host-tested) ----
|
|
add_library(shim_colony STATIC src/shim/hooks/colony_inputs.cpp)
|
|
target_link_libraries(shim_colony PUBLIC shim_trace sots_game_sim)
|
|
target_compile_options(shim_colony PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- B4 movement adapter: StarFleet snapshot <-> game::sim movement (pure, host-tested) ----
|
|
add_library(shim_movement STATIC src/shim/hooks/movement_inputs.cpp)
|
|
target_link_libraries(shim_movement PUBLIC shim_trace sots_game_sim)
|
|
target_compile_options(shim_movement PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- T turn-driver adapter: ServerPlayer snapshot <-> the driver's own writes (pure, host-tested) ----
|
|
add_library(shim_player_turn STATIC src/shim/hooks/player_turn_inputs.cpp)
|
|
target_link_libraries(shim_player_turn PUBLIC shim_trace)
|
|
target_compile_options(shim_player_turn PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- P events adapter: live Game::EventStorage <-> sots::events model (pure, host-tested) ----
|
|
add_library(shim_events STATIC src/shim/hooks/event_inputs.cpp)
|
|
target_link_libraries(shim_events PUBLIC shim_trace sots_addresses sots_game_events)
|
|
target_compile_options(shim_events PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- shim: the strategic RNG word ledger (lane Z) -- absolute generator position recovered
|
|
# from (mt[624], left) alone, so a turn's RNG cost can be attributed to a phase without
|
|
# hooking a single RNG primitive. Host-testable; linked into the hook descriptors below.
|
|
add_library(shim_rng_ledger STATIC src/shim/hooks/rng_ledger.cpp)
|
|
target_link_libraries(shim_rng_ledger PUBLIC shim_trace sots_addresses mars_rng)
|
|
target_compile_options(shim_rng_ledger PRIVATE -Wall -Wextra -Werror)
|
|
|
|
if(WIN32)
|
|
# ---- shim: proxy binkw32.dll that the original game loads (Phase 2 frontend) ----
|
|
add_library(minhook STATIC
|
|
third_party/minhook/src/buffer.c
|
|
third_party/minhook/src/hook.c
|
|
third_party/minhook/src/trampoline.c
|
|
third_party/minhook/src/hde/hde32.c)
|
|
target_include_directories(minhook PUBLIC third_party/minhook/include)
|
|
|
|
# ---- hooks: one descriptor per hooked game function (src/shim/hooks/*) ----
|
|
add_library(shim_hooks STATIC src/shim/hooks/global_consts.cpp src/shim/hooks/dictionaries.cpp
|
|
src/shim/hooks/research.cpp
|
|
src/shim/hooks/tech_effects.cpp
|
|
src/shim/hooks/compute_budget.cpp
|
|
src/shim/hooks/colony_turn.cpp
|
|
src/shim/hooks/system_output.cpp
|
|
src/shim/hooks/fleet_movement.cpp
|
|
src/shim/hooks/player_turn.cpp
|
|
src/shim/hooks/tail_rng.cpp
|
|
src/shim/hooks/draw_sites.cpp)
|
|
target_link_libraries(shim_hooks PUBLIC shim_trace sots_addresses sots_game_config sots_game_sim
|
|
sots_game_effects mars_rng shim_budget shim_techfx
|
|
shim_colony shim_movement shim_events
|
|
shim_player_turn shim_rng_ledger)
|
|
target_compile_options(shim_hooks PRIVATE -Wall -Wextra -Werror)
|
|
|
|
add_library(binkw32 SHARED src/shim/main.cpp src/shim/fpu_force.cpp src/shim/binkw32.def)
|
|
target_link_libraries(binkw32 PRIVATE minhook sots_addresses shim_trace shim_hooks)
|
|
target_compile_definitions(binkw32 PRIVATE
|
|
SHIM_BUILD_ID="${SHIM_BUILD_ID}"
|
|
SOTS_ADDR_PROVENANCE="${SOTS_ADDR_PROVENANCE}")
|
|
# Must be exactly binkw32.dll (no "lib" prefix); export names come solely from the .def.
|
|
set_target_properties(binkw32 PROPERTIES PREFIX "" OUTPUT_NAME "binkw32")
|
|
else()
|
|
# ---- host: engine module tests (ctest) + a header smoke test ----
|
|
enable_testing()
|
|
add_executable(addr_smoke tests/addr_smoke.cpp)
|
|
target_link_libraries(addr_smoke PRIVATE sots_addresses)
|
|
add_test(NAME addr_smoke COMMAND addr_smoke)
|
|
foreach(_t mars_parse game_config game_data game_design game_sim mars_stream mars_text mars_vfs shim_trace game_effects game_events game_combat game_nav shim_budget shim_techfx shim_colony shim_movement shim_events shim_player_turn shim_rng_ledger app)
|
|
if(EXISTS ${CMAKE_SOURCE_DIR}/tests/${_t}/CMakeLists.txt)
|
|
add_subdirectory(tests/${_t})
|
|
endif()
|
|
endforeach()
|
|
endif()
|