### Control Synchronization Start and Stop Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Methods to control the overall synchronization process. `start` initiates synchronization and should be called by the host, while `stop` halts synchronization, also initiated by the host. ```GDScript func start() -> void: # Starts synchronizing! This should only be called on the "host" (the peer with id 1), # which will tell all the other clients to start as well. # It's after calling this that the "Virtual methods" described below will start getting called. pass func stop() -> void: # Stops synchronizing. If called on the "host" (the peer with id 1) # it will tell all the clients to stop as well. pass ``` -------------------------------- ### Start Synchronization (Godot GDScript) Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Initiates the synchronization process. This method should only be called on the host peer (ID 1), which then signals all other clients to begin synchronizing. Virtual methods described in the documentation start being called after this method is invoked. ```gdscript func start() -> void: # Starts synchronizing! This should only be called on the # "host" (the peer with id 1), which will tell all the other clients to start # as well. It's after calling this that the "Virtual methods" described below # will start getting called. ``` -------------------------------- ### Start and Stop Match Logging Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Functions for enabling and disabling detailed logging of match information. `start_logging` initiates the log file with optional match data, while `stop_logging` concludes the logging session. ```GDScript func start_logging(log_file_path: String, match_info: Dictionary = {}) -> void: # Starts logging detailed information about the current match to the given log file. # The common convention is to put the log files under "user://detailed_logs/". # The `match_info` is stored at the start of the log, and is used when loading a replay of the match. # This method should be called before SyncManager.start() or in response to the "sync_started" signal. pass func stop_logging() -> void: # Stops logging. This method should be called after SyncManager.stop() # or in response to the "sync_stopped" signal. pass ``` -------------------------------- ### Logging Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Methods for starting and stopping detailed logging of synchronization information. ```APIDOC ## Logging ### Description Methods for starting and stopping detailed logging of synchronization information. ### Methods - **start_logging(log_file_path: String, match_info: Dictionary = {}) -> void** Starts logging detailed information about the current match to the given log file. The common convention is to put the log files under "user://detailed_logs/". The `match_info` is stored at the start of the log, and is used when loading a replay of the match. This method should be called before `SyncManager.start()` or in response to the "sync_started" signal. - **stop_logging() -> void** Stops logging. This method should be called after `SyncManager.stop()` or in response to the "sync_stopped" signal. ``` -------------------------------- ### Start Logging Match Data (Godot GDScript) Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Begins logging detailed match information to a specified file. The `match_info` dictionary is stored at the log's beginning and is used for loading replays. This should be called before `SyncManager.start()` or in response to the "sync_started" signal. ```gdscript func start_logging(log_file_path: String, match_info: Dictionary = {}) -> void: # Starts logging detailed information about the current match to the given # log file. The common convention is to put the log files under # "user://detailed_logs/". The `match_info` is stored at the start of the # log, and is used when loading a replay of the match. This method should # be called before `SyncManager.start()` or in response to the "sync_started" # signal. ``` -------------------------------- ### Start and Stop Logging Match Data - GDScript Source: https://context7.com/bimdav/delta-rollback/llms.txt This GDScript code demonstrates how to start and stop logging match data for Delta Rollback. It creates a log directory if it doesn't exist, generates a unique log filename based on the current date and time, and starts logging with initial match information. It also handles stopping the logging process. This functionality is crucial for debugging and replay. ```gdscript extends Node2D const LOG_FILE_DIRECTORY = 'user://detailed_logs' func _ready() -> void: SyncManager.sync_started.connect(_on_sync_started) SyncManager.sync_stopped.connect(_on_sync_stopped) func _on_sync_started() -> void: # Don't log during replay if SyncReplay.active: return # Create log directory if needed if not DirAccess.dir_exists_absolute(LOG_FILE_DIRECTORY): DirAccess.make_dir_absolute(LOG_FILE_DIRECTORY) # Generate unique log filename var datetime := Time.get_datetime_dict_from_system(true) var log_file_name = "%04d%02d%02d-%02d%02d%02d-peer-%d.log" % [ datetime['year'], datetime['month'], datetime['day'], datetime['hour'], datetime['minute'], datetime['second'], multiplayer.get_unique_id() ] # Start logging with match info for replay setup SyncManager.start_logging( LOG_FILE_DIRECTORY + '/' + log_file_name, { "map": current_map, "players": player_list, "game_mode": game_mode } ) func _on_sync_stopped() -> void: SyncManager.stop_logging() # This method is called by Log Inspector to setup replay func setup_match_for_replay(my_peer_id: int, peer_ids: Array, match_info: Dictionary) -> void: # Load map and configure match based on logged match_info load_map(match_info["map"]) # Setup players based on peer IDs from the log for peer_id in [my_peer_id] + peer_ids: setup_player(peer_id) ``` -------------------------------- ### Setup Match for Replay Method Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md This GDScript function is used to set up the match scene for replaying a game. It receives the current peer ID, an array of all peer IDs, and a dictionary containing match information. Implementations should use the 'match_info' to configure the game state and disable unnecessary features for replay. ```gdscript func setup_match_for_replay(my_peer_id: int, peer_ids: Array, match_info: Dictionary) -> void: # Setup the match using 'match_info' and disable anything we don't # want or need during replay. pass ``` -------------------------------- ### Install Godot Rollback Netcode Addon Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Instructions for installing the Godot Rollback Netcode addon as an editor plugin. This involves copying the addon directory into the Godot project and enabling it via Project Settings. ```gdscript Project -> Project settings... -> Plugins tab -> Enable 'Godot Rollback Netcode' ``` -------------------------------- ### Spawn Networked Scene (Godot GDScript) Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Spawns a scene and creates a "spawn record" for rollback purposes. It returns the top-level node of the spawned scene. It's recommended to perform setup in response to the "scene_spawned" signal, as the scene might be re-spawned due to rollbacks. ```gdscript func spawn(name: String, parent: Node, scene: PackedScene, data: Dictionary = {}, rename: bool = true, signal_name: String = '') -> Node: # Spawns a scene and makes a "spawn record" in state so that it can be # de-spawned or re-spawned as the result of a rollback. # # It returns the top-level node that was spawned, however, rather than doing # most setup on the returned node, you should do it in response to the # "scene_spawned" signal. This is because the scene could be re-spawned due # to a rollback, and you probably want all the same setup to happen then as # when it was originally spawned. (Note: there are rare cases when you do want # to do setup *only* when spawned initially, and not when re-spawned.) # # * `name`: The base name to use for the top-level node that is spawned. # * `parent`: The parent node the spawned scene will be added to. # * `scene`: The scene to spawn. # * `data`: Data that will be passed to `_network_spawn_preprocess()` and # `_network_spawn()` on the top-level node. See the "Virtual methods" # described below for more information. # * `rename`: If true, the actual name of the top-level node that is spawned # will have an incrementing integer appended to it. If false, it'll try to # use the `name` but this could lead to conflicts. Only set to false if you # know for sure that no other sibling node will use that name. # * `signal_name`: If provided, this is the name that'll be passed to the # "scene_spawned" signal; otherwise the `name` will be used. pass ``` -------------------------------- ### Custom NetworkAdaptor Implementation in GDScript Source: https://context7.com/bimdav/delta-rollback/llms.txt This GDScript code provides a template for creating a custom network adaptor by extending the base `NetworkAdaptor.gd` class. It outlines methods for attaching, detaching, starting, and stopping the adaptor, as well as sending different types of network messages (ping, start, stop, input ticks) using reliable or unreliable transports. It also includes functions to check if the network is a host and to get the unique network ID. ```gdscript extends "res://addons/delta_rollback/NetworkAdaptor.gd" # Example: Custom adaptor for Steam P2P networking func attach_network_adaptor(sync_manager) -> void: # Setup when adaptor is attached pass func detach_network_adaptor(sync_manager) -> void: # Cleanup when adaptor is detached pass func start_network_adaptor(sync_manager) -> void: # Called when synchronization starts pass func stop_network_adaptor(sync_manager) -> void: # Called when synchronization stops pass func send_ping(peer_id: int, msg: Dictionary) -> void: # Send ping to measure RTT _send_reliable(peer_id, "ping", msg) func send_ping_back(peer_id: int, msg: Dictionary) -> void: _send_reliable(peer_id, "ping_back", msg) func send_remote_start(peer_id: int) -> void: _send_reliable(peer_id, "start", {}) func send_remote_stop(peer_id: int) -> void: _send_reliable(peer_id, "stop", {}) func send_input_tick(peer_id: int, msg: PackedByteArray) -> void: # Use unreliable for input (more frequent, can tolerate loss) _send_unreliable(peer_id, msg) func is_network_host() -> bool: return multiplayer.is_server() func get_network_unique_id() -> int: return multiplayer.get_unique_id() func poll() -> void: # Process incoming messages pass ``` -------------------------------- ### Initialize and Manage SyncManager Singleton in GDScript Source: https://context7.com/bimdav/delta-rollback/llms.txt This snippet demonstrates how to connect to SyncManager signals, add remote peers, start and stop the synchronization process, and handle logging. It's essential for setting up multiplayer and managing the game's network state. ```gdscript extends Node2D func _ready() -> void: # Connect to SyncManager signals SyncManager.sync_started.connect(_on_sync_started) SyncManager.sync_stopped.connect(_on_sync_stopped) SyncManager.sync_lost.connect(_on_sync_lost) SyncManager.sync_regained.connect(_on_sync_regained) SyncManager.sync_error.connect(_on_sync_error) func setup_multiplayer(peer_id: int) -> void: # Add remote peer for synchronization SyncManager.add_peer(peer_id) func start_match() -> void: # Only call start() on the host (peer id 1) if multiplayer.is_server(): # Optionally start logging for debugging SyncManager.start_logging("user://logs/match.log", { "map": "arena_1", "players": 2 }) SyncManager.start() func end_match() -> void: SyncManager.stop() SyncManager.stop_logging() SyncManager.clear_peers() func _on_sync_started() -> void: print("Synchronization started! Current tick: ", SyncManager.current_tick) func _on_sync_stopped() -> void: print("Synchronization stopped") func _on_sync_lost() -> void: # Show "reconnecting" UI to player $SyncLostLabel.visible = true func _on_sync_regained() -> void: $SyncLostLabel.visible = false func _on_sync_error(msg: String) -> void: print("Fatal sync error: ", msg) ``` -------------------------------- ### DummyNetworkAdaptor for Local Play in GDScript Source: https://context7.com/bimdav/delta-rollback/llms.txt This GDScript code demonstrates how to use the `DummyNetworkAdaptor` for local play or testing scenarios where real networking is not required. It shows how to replace the default network adaptor with the dummy version, configure player input prefixes, and start the synchronization process without any network peers. It also includes a function to set up online play using the default RPC adaptor. ```gdscript extends Node2D const DummyNetworkAdaptor = preload("res://addons/delta_rollback/DummyNetworkAdaptor.gd") func start_local_game() -> void: # Replace network adaptor with dummy for local play SyncManager.network_adaptor = DummyNetworkAdaptor.new() # Configure local input (both players on same machine) $Player1.input_prefix = "player1_" $Player2.input_prefix = "player2_" # Start synchronization without peers SyncManager.start() func start_online_game(peer_id: int) -> void: # Use default RPC adaptor for online play SyncManager.reset_network_adaptor() SyncManager.add_peer(peer_id) if multiplayer.is_server(): await get_tree().create_timer(2.0).timeout # Wait for ping data SyncManager.start() ``` -------------------------------- ### Manage Peers with Godot High-Level Multiplayer API Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Methods to manage network peers for synchronization. `add_peer` connects a new peer, `clear_peers` removes all connected peers. These operations are crucial before starting the synchronization process. ```GDScript func add_peer(peer_id: int) -> void: # Adds a peer using its ID within Godot's High-Level Multiplayer API. # Once a peer is added, the SyncManager will start pinging it right away. # All peers should be added before calling SyncManager.start(). pass func clear_peers() -> void: # Clears the list of peers. pass ``` -------------------------------- ### Logging Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Methods for starting and stopping detailed match logging. ```APIDOC ## Logging ### Description Methods for managing detailed logging of match information. ### Methods - `start_logging(log_file_path: String, match_info: Dictionary = {}) -> void` Starts logging detailed match information to the specified file path. `match_info` is stored at the beginning of the log and used for replay loading. Call this before `SyncManager.start()` or in response to the `"sync_started"` signal. - `stop_logging() -> void` Stops logging. Call this after `SyncManager.stop()` or in response to the `"sync_stopped"` signal. ``` -------------------------------- ### Synchronization Control Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Methods for starting and stopping the synchronization process. ```APIDOC ## Synchronization Control ### Description Methods to control the start and stop of the synchronization process. ### Methods - `start() -> void` Starts synchronizing. This should only be called on the host (peer ID 1). It signals all clients to start synchronizing as well. Virtual methods will be called after this. - `stop() -> void` Stops synchronization. If called on the host (peer ID 1), it signals all clients to stop as well. ``` -------------------------------- ### Scene Management Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Methods for spawning and despawning scenes with rollback support. ```APIDOC ## Scene Management ### Description Methods for spawning and despawning scenes with rollback support. ### Methods - **spawn(name: String, parent: Node, scene: PackedScene, data: Dictionary = {}, rename: bool = true, signal_name: String = '') -> Node** Spawns a scene and makes a "spawn record" in state so that it can be de-spawned or re-spawned as the result of a rollback. It returns the top-level node that was spawned, however, rather than doing most setup on the returned node, you should do it in response to the "scene_spawned" signal. This is because the scene could be re-spawned due to a rollback, and you probably want all the same setup to happen then as when it was originally spawned. (Note: there are rare cases when you do want to do setup *only* when spawned initially, and not when re-spawned.) * `name`: The base name to use for the top-level node that is spawned. * `parent`: The parent node the spawned scene will be added to. * `scene`: The scene to spawn. * `data`: Data that will be passed to `_network_spawn_preprocess()` and `_network_spawn()` on the top-level node. See the "Virtual methods" described below for more information. * `rename`: If true, the actual name of the top-level node that is spawned will have an incrementing integer appended to it. If false, it'll try to use the `name` but this could lead to conflicts. Only set to false if you know for sure that no other sibling node will use that name. * `signal_name`: If provided, this is the name that'll be passed to the "scene_spawned" signal; otherwise the `name` will be used. - **despawn(node: Node) -> void** De-spawns a node that was previously spawned via `SyncManager.spawn()`. It calls `_network_despawn()` and removes the "spawn record" in state. By default, this will also remove the node from its parent and call `node.queue_free()`. However, if you have enabled "Reuse despawned nodes" in Project Settings, then the node will be saved and reused when the same scene needs to be spawned later. This makes it especially important to clean-up the nodes internal state in `_network_despawn()` so that the node is "like new" when reused. ``` -------------------------------- ### NetworkRandomNumberGenerator for Deterministic Randomness Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md The NetworkRandomNumberGenerator provides deterministic random number generation that is compatible with rollback. Clients must initialize the node with the same seed at the start of a match to ensure consistent random sequences across all peers. ```GDScript class NetworkRandomNumberGenerator extends RandomNumberGenerator: pass ``` -------------------------------- ### Spawn and Despawn Networked Scenes Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Manages the lifecycle of scenes that need to be synchronized across the network. `spawn` creates a scene and records it for rollback, while `despawn` removes it and handles potential node reuse. ```GDScript func spawn(name: String, parent: Node, scene: PackedScene, data: Dictionary = {}, rename: bool = true) -> Node: # Spawns a scene and makes a "spawn record" in state so that it can be # de-spawned or re-spawned as the result of a rollback. # It returns the top-level node that was spawned. # `name`: The base name to use for the top-level node that is spawned. # `parent`: The parent node the spawned scene will be added to. # `scene`: The scene to spawn. # `data`: Data that will be passed to `_network_spawn_preprocess()` and `_network_spawn()` on the top-level node. # `rename`: If true, the actual name of the top-level node that is spawned will have an incrementing integer appended to it. pass func despawn(node: Node) -> void: # De-spawns a node that was previously spawned via `SyncManager.spawn()`. # It calls `_network_despawn()` and removes the "spawn record" in state. # By default, this will also remove the node from its parent and call `node.queue_free()`. # However, if you have enabled "Reuse despawned nodes" in Project Settings, then the node will be saved and reused. pass ``` -------------------------------- ### Sound Playback Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Method for playing sounds with rollback-aware identification. ```APIDOC ## Sound Playback ### Description Method for playing sounds with rollback-aware identification. ### Method - **play_sound(identifier: String, sound: AudioStream, info: Dictionary = {}) -> void** Plays a sound and records that we played this specific sound on the current tick, so that we won't play it again if we re-execute the same tick again due to a rollback. * `identifier`: A unique identifier for the sound. Only one sound with this identifier will be played on the current tick. The common convention is to use the node path of the node playing the sound, with some sort of "tag" appended, for example: ``` SyncManager.play_sound(str(get_path()) + ':shoot', shoot_sound) ``` * `sound`: The sound resource to play. * `info`: A set of optional parameters, including: - `position`: A `Vector2` giving the position the sound should originate from. If omitted, positional audio won't be used. - `volume_db`: A `float` giving the volume in decibels. - `pitch_scale`: A `float` to scale the pitch. - `bus`: The name of the bus to play the sound to. If none is given, the default bus configured in Project Settings will be used. ``` -------------------------------- ### Logging Match Data (GDScript) Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Functions for enabling and disabling detailed logging of match information. This is useful for debugging and analyzing gameplay, especially for replays. Logging should be initiated before starting synchronization. ```GDScript SyncManager.start_logging(log_file_path: String, match_info: Dictionary = {}) -> void SyncManager.stop_logging() -> void ``` -------------------------------- ### Network Spawn Data Preprocessing Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Prepares data before a scene is spawned via SyncManager. _network_spawn_preprocess() modifies the data passed to SyncManager.spawn(), converting developer-friendly data into a state-safe format. The returned data is saved in state. ```gdscript func _network_spawn_preprocess(data: Dictionary) -> Dictionary: # Pre-process spawn data to make it state-safe return data ``` -------------------------------- ### Manage Peers and Synchronization - Godot GDScript Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Methods for managing network peers and controlling the synchronization process. This includes adding/clearing peers, starting/stopping the sync manager, and ensuring all peers are added before starting. ```gdscript func add_peer(peer_id: int) -> void: # Adds a peer using its ID within Godot's High-Level Multiplayer API. # The SyncManager will start pinging the peer immediately. # All peers must be added before calling SyncManager.start(). pass func start() -> void: # Starts synchronizing. This should only be called on the host (peer id 1). # The host will then notify all clients to start as well. # Virtual methods will be called after this. pass func stop() -> void: # Stops synchronizing. If called on the host (peer id 1), it notifies clients to stop. pass func clear_peers() -> void: # Clears the list of connected peers. pass ``` -------------------------------- ### SyncManager Singleton Properties Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Key properties of the SyncManager singleton, which is central to the rollback netcode functionality. These properties provide information about the current synchronization state, including ticks and whether synchronization has started. ```gdscript var current_tick: int var input_tick: int var started: bool ``` -------------------------------- ### Connecting Signals for State Persistence in Godot Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Demonstrates how to use `SyncManager.connect_signal()` to connect signals in a way that is written into the game state. This is useful for features like replaying the game, as the signal connections will be preserved across rollbacks and saves. ```GDScript func _ready(): var button = $Button SyncManager.connect_signal(button, "pressed", self, "_on_Button_pressed") func _on_Button_pressed(): print("Button pressed!") ``` -------------------------------- ### Manage SyncManager Peers and State (GDScript) Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Methods to manage network peers and the overall synchronization state. This includes adding and clearing peers, starting and stopping the synchronization process, and managing the list of active peers. ```GDScript SyncManager.add_peer(peer_id: int) -> void SyncManager.start() -> void SyncManager.stop() -> void SyncManager.clear_peers() -> void ``` -------------------------------- ### Network Pre/Post-Processing Hooks Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Provides hooks for actions before and after network processing. _network_preprocess() runs before _network_process(), and _network_postprocess() runs after, allowing for ordered execution of network-related logic. ```gdscript func _network_preprocess(input: Dictionary) -> void: # Pre-process network input pass func _network_postprocess(input: Dictionary) -> void: # Post-process network input pass ``` -------------------------------- ### Logging Match Data - Godot GDScript Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Functions to enable and disable detailed logging of match information. Logs are stored in a specified file path and can include custom match data for replay analysis. Logging should be configured before starting synchronization. ```gdscript func start_logging(log_file_path: String, match_info: Dictionary = {}) -> void: # Starts logging detailed match information to the specified log file. # The 'match_info' dictionary is stored at the beginning of the log. # Common convention places logs in 'user://detailed_logs/'. # Call before SyncManager.start() or in response to 'sync_started' signal. pass func stop_logging() -> void: # Stops the detailed logging process. # Should be called after SyncManager.stop() or in response to 'sync_stopped' signal. pass ``` -------------------------------- ### Scene Spawning and Despawning Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Methods related to the spawning and despawning of scenes managed by SyncManager, including rollback scenarios. ```APIDOC ## Scene Spawning and Despawning ### Description These methods are invoked when scenes are spawned or despawned using `SyncManager.spawn()` and `SyncManager.despawn()`, and also during rollback operations that involve re-spawning or de-spawning. ### Methods - `_network_spawn_preprocess(data: Dictionary) -> Dictionary` - **Description**: Pre-processes data intended for `SyncManager.spawn()` before it's passed to `_network_spawn()`. The returned data is what gets saved in state, allowing conversion of developer-friendly data (like `Node` objects) into state-safe formats (like node paths). - `_network_spawn(data: Dictionary) -> void` - **Description**: Called when a scene is spawned by `SyncManager.spawn()` or re-spawned during rollback. - `_network_despawn() -> void` - **Description**: Called when a node is de-spawned by `SyncManager.despawn()` or de-spawned during rollback. ``` -------------------------------- ### Peer Management Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Methods for managing network peers and the synchronization process. ```APIDOC ## Peer Management ### Description Methods for managing network peers and the synchronization process. ### Methods - **add_peer(peer_id: int) -> void** Adds a peer using its ID within Godot's High-Level Multiplayer API. Once a peer is added, the SyncManager will start pinging it right away. All peers should be added before calling `SyncManager.start()`. - **start() -> void** Starts synchronizing! This should only be called on the "host" (the peer with id 1), which will tell all the other clients to start as well. It's after calling this that the "Virtual methods" described below will start getting called. - **stop() -> void** Stops synchronizing. If called on the "host" (the peer with id 1) it will tell all the clients to stop as well. - **clear_peers() -> void** Clears the list of peers. ``` -------------------------------- ### Play Synchronized Sound (Godot GDScript) Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README.md Plays a sound and records its playback for the current tick to prevent replaying it after a rollback. A unique identifier ensures only one sound with that ID plays per tick. Optional parameters include position, volume, pitch, and audio bus. ```gdscript func play_sound(identifier: String, sound: AudioStream, info: Dictionary = {}) -> void: # Plays a sound and records that we played this specific sound on the # current tick, so that we won't play it again if we re-execute the same # tick again due to a rollback. # * `identifier`: A unique identifier for the sound. Only one sound with this # identifier will be played on the current tick. The common convention is # to use the node path of the node playing the sound, with some sort of # "tag" appended, for example: # ``` # SyncManager.play_sound(str(get_path()) + ':shoot', shoot_sound) # ``` # * `sound`: The sound resource to play. # * `info`: A set of optional parameters, including: # - `position`: A `Vector2` giving the position the sound should originate # from. If omitted, positional audio won't be used. # - `volume_db`: A `float` giving the volume in decibels. # - `pitch_scale`: A `float` to scale the pitch. # - `bus`: The name of the bus to play the sound to. If none is given, the # default bus configured in Project Settings will be used. ``` -------------------------------- ### Manage Scenes with spawn() and despawn() in GDScript Source: https://context7.com/bimdav/delta-rollback/llms.txt The `spawn()` and `despawn()` methods provide network-aware scene management within Delta Rollback. They create 'spawn records' that ensure scenes are correctly de-spawned or re-spawned during rollbacks. This is essential for maintaining consistent game state across network instances. ```gdscript extends Node2D const Bullet = preload("res://scenes/Bullet.tscn") const Explosion = preload("res://scenes/Explosion.tscn") @onready var spawn_parent = $SpawnParent func _network_process(input: Dictionary) -> void: if input.get("fire", false): # Spawn a bullet with custom data var bullet = SyncManager.spawn( "Bullet", # Base name for the node spawn_parent, # Parent node Bullet, # PackedScene to instantiate { # Data passed to _network_spawn position = global_position, direction = facing_direction, owner_id = get_multiplayer_authority() }, true # rename: append incrementing integer ) # In Bullet.gd func _network_spawn(data: Dictionary) -> void: global_position = data['position'] direction = data['direction'] owner_id = data['owner_id'] # Called when despawned via SyncManager.despawn() func _network_despawn() -> void: pass # Clean up if needed # Called when node is reused (if reuse_despawned_nodes is enabled) func _network_prepare_for_reuse() -> void: direction = Vector2.ZERO owner_id = 0 func _network_process(_input: Dictionary) -> void: position += direction * speed func explode() -> void: SyncManager.spawn("Explosion", get_parent(), Explosion, { position = global_position }) SyncManager.despawn(self) ``` -------------------------------- ### Implement Network Synchronization Virtual Methods in GDScript Source: https://context7.com/bimdav/delta-rollback/llms.txt This snippet shows how to implement virtual methods required for nodes participating in rollback synchronization. It covers adding nodes to the 'network_sync' group and defining functions for input gathering, state saving/loading, and network processing. ```gdscript extends Node2D func _ready() -> void: # Add to network_sync group to participate in rollback add_to_group('network_sync') # Called only on nodes owned by the local player (network master) func _get_local_input() -> Dictionary: var input := {} var input_vector = Input.get_vector("move_left", "move_right", "move_up", "move_down") if input_vector != Vector2.ZERO: input["input_vector"] = input_vector if Input.is_action_just_pressed("fire"): input["fire"] = true return input # Called for remote players to predict their input func _predict_remote_input(previous_input: Dictionary, ticks_since_real_input: int) -> Dictionary: var input = previous_input.duplicate() # Don't predict one-shot actions like firing input.erase("fire") return input # Main game logic - runs every tick (including during rollback) func _network_process(input: Dictionary) -> void: var input_vector = input.get("input_vector", Vector2.ZERO) position += input_vector * speed if input.get("fire", false): _fire_projectile() # Save current state for potential rollback func _save_state() -> Dictionary: return { position = position, speed = speed, health = health, } # Restore state during rollback func _load_state(state: Dictionary) -> void: position = state['position'] speed = state['speed'] health = state['health'] # Interpolate between states for smooth rendering (optional) func _interpolate_state(old_state: Dictionary, new_state: Dictionary, weight: float) -> void: position = lerp(old_state['position'], new_state['position'], weight) ``` -------------------------------- ### Node State Management for Rollback Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Methods for saving and loading a node's state to enable rollback functionality. _save_state() returns the current state, and _load_state() applies a previously saved state. Caution is advised against storing references, objects, arrays, or dictionaries directly in the state; node paths are preferred. ```gdscript func _save_state() -> Dictionary: # Return the current node state pass func _load_state(state: Dictionary) -> void: # Load the node back to a previous state pass ``` -------------------------------- ### Network Scene Spawning and Despawning Source: https://gitlab.com/bimdav/delta-rollback/-/blob/master/README 2.md Methods for handling the lifecycle of network-spawned scenes. _network_spawn_preprocess modifies spawn data, _network_spawn is called on spawn, and _network_despawn on despawn. ```gdscript func _network_spawn_preprocess(data: Dictionary) -> Dictionary: # Preprocess data before spawning a network scene return data func _network_spawn(data: Dictionary) -> void: # Called when a network scene is spawned pass func _network_despawn() -> void: # Called when a network scene is despawned pass ```