Fresh start: replace with naxIO/netfox-cs-sample foundation

Complete replacement of the tactical-shooter project with the
netfox-cs-sample (MIT) — a CS 1.6 inspired multiplayer FPS built
with Godot 4 and netfox.

## What's new
- Full CS-style gameplay: teams (T/CT), rounds, economy, buy menu
- 6 weapons: Knife, Glock, USP, AK-47, M4A1, AWP
- Bomb plant/defuse with 2 bombsites
- Flashbang & smoke grenades
- Proper netfox rollback netcode at 64 tick
- Network popup UI for host/join
- HUD, crosshair, round timer, scoreboard
- All netfox singletons registered as autoloads (works in exported builds)

## Architecture
- Listen-server (host from client, no dedicated server binary)
- Multiplayer-fps game lives at examples/multiplayer-fps/
- Netfox addons registered as autoloads for exported build compat
- Godot 4.7 with Forward+ renderer

## Removed
- Old headless-server architecture (client_main, server_main, player.gd, etc.)
- Custom netfox bootstrap with ENet fallback
- Old ChaffGames FPS template (2,420 lines, 844 KB)
- SimulationServer GDExtension stub
- Godot-jolt physics (netfox sample uses default Godot physics)
- Duplicate weapon_data.gd, anti_cheat.gd, round_manager.gd, etc.
- Server browser API Python venv (87 MB)
- test_range map and modular assets

## Preserved
- Git history
- Server config at config/default_server_config.cfg
- Windows export preset
- Build directory (gitignored)

Co-authored-by: naxIO <naxIO@users.noreply.github.com>
This commit is contained in:
2026-07-02 20:55:20 -04:00
parent ce39b237c3
commit b0c83af092
4416 changed files with 57418 additions and 902676 deletions
+22 -13
View File
@@ -115,6 +115,11 @@ var _offset: float = 0.
var _rtt: float = 0.
var _rtt_jitter: float = 0.
@onready var _cmd_ping := NetworkCommandServer.register_command(_handle_ping, MultiplayerPeer.TRANSFER_MODE_UNRELIABLE)
@onready var _cmd_pong := NetworkCommandServer.register_command(_handle_pong, MultiplayerPeer.TRANSFER_MODE_UNRELIABLE)
@onready var _cmd_req_time := NetworkCommandServer.register_command(_handle_request_timestamp, MultiplayerPeer.TRANSFER_MODE_RELIABLE)
@onready var _cmd_set_time := NetworkCommandServer.register_command(_handle_set_timestamp, MultiplayerPeer.TRANSFER_MODE_RELIABLE)
## Emitted after the initial time sync.
##
## At the start of the game, clients request an initial timestamp to kickstart
@@ -145,7 +150,7 @@ func start() -> void:
_sample_idx = 0
_sample_buffer = _RingBuffer.new(sync_samples)
_request_timestamp.rpc_id(1)
_cmd_req_time.send(PackedByteArray(), 1)
## Stop the time synchronization loop.
func stop() -> void:
@@ -169,7 +174,7 @@ func _loop() -> void:
_awaiting_samples[_sample_idx] = sample
sample.ping_sent = _clock.get_time()
_send_ping.rpc_id(1, _sample_idx)
_cmd_ping.send(var_to_bytes(_sample_idx), 1)
_sample_idx += 1
@@ -235,15 +240,19 @@ func _discipline_clock() -> void:
_offset = offset - nudge
@rpc("any_peer", "call_remote", "unreliable")
func _send_ping(idx: int) -> void:
func _handle_ping(sender: int, data: PackedByteArray) -> void:
var idx := bytes_to_var(data) as int
var ping_received := _clock.get_time()
var sender := multiplayer.get_remote_sender_id()
_send_pong.rpc_id(sender, idx, ping_received, _clock.get_time())
_cmd_pong.send(var_to_bytes([idx, ping_received, _clock.get_time()]), sender)
func _handle_pong(sender: int, data: PackedByteArray) -> void:
var args := bytes_to_var(data)
var idx := args[0] as int
var ping_received := args[1] as float
var pong_sent := args[2] as float
@rpc("any_peer", "call_remote", "unreliable")
func _send_pong(idx: int, ping_received: float, pong_sent: float) -> void:
var pong_received := _clock.get_time()
if not _awaiting_samples.has(idx):
@@ -264,13 +273,13 @@ func _send_pong(idx: int, ping_received: float, pong_sent: float) -> void:
# Discipline clock based on new sample
_discipline_clock()
@rpc("any_peer", "call_remote", "reliable")
func _request_timestamp() -> void:
func _handle_request_timestamp(sender: int, data: PackedByteArray) -> void:
_logger.debug("Requested initial timestamp @ %.4fs raw time", [_clock.get_raw_time()])
_set_timestamp.rpc_id(multiplayer.get_remote_sender_id(), _clock.get_time())
_cmd_set_time.send(var_to_bytes(_clock.get_time()), sender)
func _handle_set_timestamp(sender: int, data: PackedByteArray) -> void:
var timestamp := bytes_to_var(data) as float
@rpc("any_peer", "call_remote", "reliable")
func _set_timestamp(timestamp: float) -> void:
_logger.debug("Received initial timestamp @ %.4fs raw time", [_clock.get_raw_time()])
_clock.set_time(timestamp)
_loop()