Phase 7: Windows client export, preset fix, code fixes
- Fix: export_presets.cfg — platform='Windows Desktop' (not 'Windows'), Windows as [preset.0] - Fix: plugin_manager.gd — removed class_name (autoload conflict), fixed multiline % formatting - Fix: Disabled GDExtension temporarily for clean export - Add: Windows PE32+ x86_64 client binary (109MB) at build/tactical-shooter-windows-x86_64/ - Add: tactical-shooter-windows.zip (portable zip package) - Build: Linux server binary (78MB) rebuilt
This commit is contained in:
@@ -12,12 +12,37 @@
|
||||
#include <godot_cpp/variant/packed_byte_array.hpp>
|
||||
#include <godot_cpp/variant/vector3.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace tactical_shooter {
|
||||
|
||||
/**
|
||||
* Position history ring-buffer entry — stores entity positions at a given tick.
|
||||
* Used for lag compensation: we can rewind targets to where they were when a
|
||||
* shot was fired, even if they've since moved.
|
||||
*/
|
||||
struct TickPositionSnapshot {
|
||||
uint32_t tick = 0;
|
||||
struct Entry {
|
||||
uint16_t entity_id;
|
||||
godot::Vector3 position;
|
||||
uint16_t flags;
|
||||
};
|
||||
std::vector<Entry> entries;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pending weapon fire with time-of-fire information for lag compensation.
|
||||
*/
|
||||
struct PendingFire {
|
||||
uint16_t shooter_id = 0xFFFF;
|
||||
uint32_t fire_tick = 0; // Server tick at which the fire was queued
|
||||
uint32_t input_sequence = 0; // Client's input sequence (for reconciliation)
|
||||
};
|
||||
|
||||
/**
|
||||
* SimulationServer — the heart of the tactical shooter simulation.
|
||||
*
|
||||
@@ -37,6 +62,7 @@ namespace tactical_shooter {
|
||||
* - All entity simulation (movement, hit detection) runs in C++
|
||||
* - Serialized state is handed to GDScript for network transport
|
||||
* - Player input arrives from GDScript, gets applied per-entity
|
||||
* - Lag compensation stores a ring buffer of pre-move positions each tick
|
||||
* - Benchmark hooks for the 128Hz load test (t_f671f48a)
|
||||
*/
|
||||
class SimulationServer : public godot::Object {
|
||||
@@ -146,6 +172,43 @@ public:
|
||||
|
||||
void set_movement_config(const godot::Dictionary &config);
|
||||
|
||||
// ---- Weapon Configuration (GDScript API) ----------------------------------
|
||||
|
||||
/**
|
||||
* Set the weapon damage profile for hitscan weapons.
|
||||
* Called from GDScript to define weapon stats.
|
||||
*
|
||||
* Dictionary keys:
|
||||
* base_damage (float) — base damage per shot
|
||||
* head_multiplier (float) — damage multiplier for head hits
|
||||
* body_multiplier (float) — damage multiplier for body hits
|
||||
* arm_multiplier (float) — damage multiplier for arm hits
|
||||
* leg_multiplier (float) — damage multiplier for leg hits
|
||||
* max_range (float) — maximum shot distance in units
|
||||
* spread_degrees (float) — random spread per shot (degrees)
|
||||
* fire_rate_hz (float) — max shots per second
|
||||
*/
|
||||
void set_weapon_config(const godot::Dictionary &config);
|
||||
|
||||
// ---- Lag Compensation Configuration (GDScript API) -------------------------
|
||||
|
||||
/**
|
||||
* Set the depth of the position history ring buffer (in ticks).
|
||||
* More ticks = can compensate for higher latency but uses more memory.
|
||||
* Default: 64 ticks (~500ms at 128Hz, enough for any reasonable ping).
|
||||
*/
|
||||
void set_history_depth(uint32_t ticks);
|
||||
|
||||
// ---- Damaged / Death Signal (GDScript API via Dictionary return) -----------
|
||||
|
||||
/**
|
||||
* Get the most recent hit result from processing combat.
|
||||
* Returns Dictionary with: hit (bool), entity_id (int), damage (float),
|
||||
* distance (float), hitbox_id (int), killed (bool).
|
||||
* Empty if no shot was processed this tick.
|
||||
*/
|
||||
godot::Dictionary get_last_hit_result() const;
|
||||
|
||||
// ---- Benchmark / Stats (GDScript API) ------------------------------------
|
||||
|
||||
/**
|
||||
@@ -199,6 +262,29 @@ private:
|
||||
*/
|
||||
uint16_t allocate_entity_id();
|
||||
|
||||
// ---- Lag Compensation (Position History) ----------------------------------
|
||||
|
||||
/**
|
||||
* Record pre-move positions of all living entities for the given tick.
|
||||
* Called at the start of process_tick(), BEFORE update_movement().
|
||||
*/
|
||||
void record_position_history(uint32_t tick);
|
||||
|
||||
/**
|
||||
* Rewind target entities to positions stored at a given tick for hit
|
||||
* detection, then restore them back.
|
||||
*/
|
||||
struct RewindState {
|
||||
std::vector<TickPositionSnapshot::Entry> saved;
|
||||
};
|
||||
RewindState begin_rewind(uint32_t target_tick);
|
||||
void end_rewind(const RewindState &state);
|
||||
|
||||
/**
|
||||
* Process a single compensated fire: rewind, check hit, restore.
|
||||
*/
|
||||
void process_compensated_fire(const PendingFire &fire);
|
||||
|
||||
// ---- State --------------------------------------------------------------
|
||||
|
||||
bool running_ = false;
|
||||
@@ -225,8 +311,26 @@ private:
|
||||
};
|
||||
std::vector<QueuedInput> queued_inputs_;
|
||||
|
||||
// Queued weapon fires (entity IDs)
|
||||
std::vector<uint16_t> pending_fires_;
|
||||
// Queued weapon fires with lag-compensation info
|
||||
std::vector<PendingFire> pending_fires_;
|
||||
WeaponDamage weapon_config_;
|
||||
float weapon_fire_rate_hz_ = 10.0f;
|
||||
|
||||
// Last hit result (queried by GDScript for feedback)
|
||||
struct LastHitResult {
|
||||
bool hit = false;
|
||||
uint16_t entity_id = 0xFFFF;
|
||||
float damage = 0.0f;
|
||||
float distance = 0.0f;
|
||||
uint8_t hitbox_id = 0;
|
||||
bool killed = false;
|
||||
};
|
||||
LastHitResult last_hit_result_;
|
||||
|
||||
// Position history ring buffer (for lag compensation)
|
||||
std::vector<TickPositionSnapshot> position_history_;
|
||||
uint32_t history_depth_ = 64;
|
||||
uint32_t history_write_index_ = 0;
|
||||
|
||||
// Last serialized snapshot per entity (for delta compression)
|
||||
std::unordered_map<uint16_t, EntitySnapshot> last_snapshots_;
|
||||
|
||||
Reference in New Issue
Block a user