Files
tactical-shooter/addons/netfox/network-performance.gd
T
shawn e7299b17e9 Phase 7: netfox + godot-jolt stack upgrade
Stack installed:
- netfox v1.35.3 (core + extras + noray + internals)
- godot-jolt v0.16.0-stable

Architecture:
- Server: ENet transport (works headless, no netfox deps)
- Client/Editor: netfox rollback (RollbackSynchronizer, TickInterpolator)

New/modified:
- docs/migration-netfox-plan.md — migration architecture
- scripts/network/network_manager.gd — netfox-aware ENet fallback
- scripts/network/player.gd — clean base player
- client/characters/player_netfox.gd — rollback player w/ WeaponManager
- client/characters/input/player_net_input.gd — BaseNetInput subclass
- client/characters/character/fps_character_controller.gd — netfox input feed
- client/weapons/ — weapon data, registry, TacticalWeaponHitscan, WeaponManager
- client/scripts/round_replicator.gd — client-side round state bridge
- server/scripts/round_manager.gd — improved state machine
- server/scripts/plugin_api/plugin_manager.gd — refined plugin system
- config: enemy_tag, ally_tag for meatball targeting

Removed: old C++ SimulationServer GDExtension (replaced by netfox rollback)
2026-07-02 17:39:22 -04:00

176 lines
6.5 KiB
GDScript

extends Node
class_name _NetworkPerformance
const NETWORK_LOOP_DURATION_MONITOR: StringName = &"netfox/Network loop duration (ms)"
const ROLLBACK_LOOP_DURATION_MONITOR: StringName = &"netfox/Rollback loop duration (ms)"
const NETWORK_TICKS_MONITOR: StringName = &"netfox/Network ticks simulated"
const ROLLBACK_TICKS_MONITOR: StringName = &"netfox/Rollback ticks simulated"
const ROLLBACK_TICK_DURATION_MONITOR: StringName = &"netfox/Rollback tick duration (ms)"
const ROLLBACK_NODES_SIMULATED_MONITOR: StringName = &"netfox/Rollback nodes simulated"
const ROLLBACK_NODES_SIMULATED_PER_TICK_MONITOR: StringName = &"netfox/Rollback nodes simulated per tick (avg)"
const FULL_STATE_PROPERTIES_COUNT: StringName = &"netfox/Full state properties count"
const SENT_STATE_PROPERTIES_COUNT: StringName = &"netfox/Sent state properties count"
const SENT_STATE_PROPERTIES_RATIO: StringName = &"netfox/Sent state properties ratio"
var _network_loop_start: float = 0
var _network_loop_duration: float = 0
var _network_ticks: int = 0
var _network_ticks_accum: int = 0
var _rollback_loop_start: float = 0
var _rollback_loop_duration: float = 0
var _rollback_ticks: int = 0
var _rollback_ticks_accum: int = 0
var _rollback_nodes_simulated: int = 0
var _rollback_nodes_simulated_accum: int = 0
var _full_state_props: int = 0
var _full_state_props_accum: int = 0
var _sent_state_props: int = 0
var _sent_state_props_accum: int = 0
static var _logger: NetfoxLogger = NetfoxLogger._for_netfox("NetworkPerformance")
## Check if performance monitoring is enabled.
## [br][br]
## By default, monitoring is only enabled in debug builds
## ( see [method OS.is_debug_build] ). [br]
## Can be forced on with the [code]netfox_perf[/code] feature tag. [br]
## Can be forced off with the [code]netfox_noperf[/code] feature tag.
func is_enabled() -> bool:
if OS.has_feature("netfox_noperf"):
return false
if OS.has_feature("netfox_perf"):
return true
# This returns true in the editor too
return OS.is_debug_build()
## Get time spent in the last network tick loop, in millisec.
## [br]
## Note that this also includes time spent in the rollback tick loop.
func get_network_loop_duration_ms() -> float:
return _network_loop_duration * 1000
## Get the number of ticks simulated in the last network tick loop.
func get_network_ticks() -> int:
return _network_ticks
## Get time spent in the last rollback tick loop, in millisec.
func get_rollback_loop_duration_ms() -> float:
return _rollback_loop_duration * 1000
## Get the number of ticks resimulated in the last rollback tick loop.
func get_rollback_ticks() -> int:
return _rollback_ticks
## Get the average amount of time spent in a rollback tick during the last
## rollback loop, in millisec.
func get_rollback_tick_duration_ms() -> float:
return _rollback_loop_duration * 1000 / maxi(_rollback_ticks, 1)
## Get the number of nodes simulated during the last rollback loop.
func get_rollback_nodes_simulated() -> int:
return _rollback_nodes_simulated
## Get the number of nodes simulated per tick on average during the last
## rollback loop.
func get_rollback_nodes_simulated_per_tick() -> float:
return _rollback_nodes_simulated / maxf(1., _rollback_ticks)
func push_rollback_nodes_simulated(count: int):
_rollback_nodes_simulated_accum += count
## Get the number of properties in the full state recorded during the last tick
## loop.
func get_full_state_props_count() -> int:
return _full_state_props
## Get the number of properties actually sent during the last tick loop.
func get_sent_state_props_count() -> int:
return _sent_state_props
## Get the ratio of sent properties count to full state properties count.
##
## See [member get_full_state_props_count][br]
## See [member get_sent_state_props_count]
func get_sent_state_props_ratio() -> float:
return _sent_state_props / maxf(1., _full_state_props)
func push_full_state(state: Dictionary) -> void:
_full_state_props_accum += state.size()
func push_full_state_broadcast(state: Dictionary) -> void:
_full_state_props_accum += state.size() * (multiplayer.get_peers().size() - 1)
func push_sent_state(state: Dictionary) -> void:
_sent_state_props_accum += state.size()
func push_sent_state_broadcast(state: Dictionary) -> void:
_sent_state_props_accum += state.size() * (multiplayer.get_peers().size() - 1)
func _ready() -> void:
if not is_enabled():
_logger.debug("Network performance disabled")
return
_logger.debug("Network performance enabled, registering performance monitors")
Performance.add_custom_monitor(NETWORK_LOOP_DURATION_MONITOR, get_network_loop_duration_ms)
Performance.add_custom_monitor(ROLLBACK_LOOP_DURATION_MONITOR, get_rollback_loop_duration_ms)
Performance.add_custom_monitor(NETWORK_TICKS_MONITOR, get_network_ticks)
Performance.add_custom_monitor(ROLLBACK_TICKS_MONITOR, get_rollback_ticks)
Performance.add_custom_monitor(ROLLBACK_TICK_DURATION_MONITOR, get_rollback_tick_duration_ms)
Performance.add_custom_monitor(ROLLBACK_NODES_SIMULATED_MONITOR, get_rollback_nodes_simulated)
Performance.add_custom_monitor(ROLLBACK_NODES_SIMULATED_PER_TICK_MONITOR, get_rollback_nodes_simulated_per_tick)
Performance.add_custom_monitor(FULL_STATE_PROPERTIES_COUNT, get_full_state_props_count)
Performance.add_custom_monitor(SENT_STATE_PROPERTIES_COUNT, get_sent_state_props_count)
Performance.add_custom_monitor(SENT_STATE_PROPERTIES_RATIO, get_sent_state_props_ratio)
NetworkTime.before_tick_loop.connect(_before_tick_loop)
NetworkTime.on_tick.connect(_on_network_tick)
NetworkTime.after_tick_loop.connect(_after_tick_loop)
NetworkRollback.before_loop.connect(_before_rollback_loop)
NetworkRollback.on_process_tick.connect(_on_rollback_tick)
NetworkRollback.after_loop.connect(_after_rollback_loop)
func _before_tick_loop() -> void:
_network_loop_start = _time()
_network_ticks_accum = 0
func _on_network_tick(_dt, _t) -> void:
_network_ticks_accum += 1
func _after_tick_loop() -> void:
_network_loop_duration = _time() - _network_loop_start
_network_ticks = _network_ticks_accum
_full_state_props = _full_state_props_accum
_full_state_props_accum = 0
_sent_state_props = _sent_state_props_accum
_sent_state_props_accum = 0
func _before_rollback_loop() -> void:
_rollback_loop_start = _time()
_rollback_ticks_accum = 0
_rollback_nodes_simulated_accum = 0
func _on_rollback_tick(_t: int) -> void:
_rollback_ticks_accum += 1
func _after_rollback_loop() -> void:
_rollback_loop_duration = _time() - _rollback_loop_start
_rollback_ticks = _rollback_ticks_accum
_rollback_nodes_simulated = _rollback_nodes_simulated_accum
func _time() -> float:
return Time.get_unix_time_from_system()