diff --git a/networking/network_synchronizer/.gitignore b/networking/network_synchronizer/.gitignore new file mode 100644 index 0000000..7256bf4 --- /dev/null +++ b/networking/network_synchronizer/.gitignore @@ -0,0 +1,5 @@ +# Editor cache +.godot +.import +/logs/* + diff --git a/networking/network_synchronizer/Character.gd b/networking/network_synchronizer/Character.gd new file mode 100644 index 0000000..3522fce --- /dev/null +++ b/networking/network_synchronizer/Character.gd @@ -0,0 +1,70 @@ +extends KinematicBody + +# ----------------------------------------------------------------------------------------- Settings +const MOVE_SPEED: int = 10 +const MOTION_INTERPOLATE_SPEED: int = 20 +const VELOCITY_INTERPOLATE_SPEED: int = 2 +const GRAVITY: int = 10 +const JUMP_IMPULSE: float = 6.0 + + +# --------------------------------------------------------------------------------------------- Vars +onready var avatar_container: Spatial = $AvatarContainer +onready var _mesh: MeshInstance = $AvatarContainer/Mesh +var linear_velocity := Vector3() +onready var camera: Camera = $Camera +var on_floor: bool = false + + +# ---------------------------------------------------------------------------------------------- API +func set_color(color): + var mat = _mesh.get_surface_material(0) + if mat == null: + mat = SpatialMaterial.new() + else: + mat = mat.duplicate() + mat.set_albedo(Color(color)) + _mesh.set_surface_material(0, mat) + + +func update_safe_body_transform(): + $KinematicBody.transform = transform + + +# ------------------------------------------------------------------------------------ Notifications +func _ready(): + ## Avoid colliding with parent + $KinematicBody.add_collision_exception_with(self) + + if "player_0" == name: + $KinematicBody.collision_layer = 0 + $KinematicBody.collision_mask = 0 + + $AvatarContainer.physics_interpolation_mode = PHYSICS_INTERPOLATION_MODE_ON + + +# ------------------------------------------------------------------------------ Processing internal +## Computes one motion step. +func step_body(delta: float, input_direction: Vector3, is_jumping: bool): + _set_player_orientation(input_direction) + + var motion: Vector3 = input_direction * MOVE_SPEED + var new_velocity: Vector3 + + if on_floor and linear_velocity.length() < MOVE_SPEED: + new_velocity = linear_velocity.linear_interpolate(motion, MOTION_INTERPOLATE_SPEED * delta) + if is_jumping: + new_velocity.y = new_velocity.y + JUMP_IMPULSE + else: + new_velocity = linear_velocity.linear_interpolate(motion, VELOCITY_INTERPOLATE_SPEED * delta) + new_velocity.y = new_velocity.y - GRAVITY * delta + + if new_velocity.length() > 0.01: + linear_velocity = move_and_slide(new_velocity, Vector3(0, 1, 0)) + on_floor = is_on_floor() + + +func _set_player_orientation(input_direction): + if input_direction.length_squared() < 0.01: + return + avatar_container.transform = avatar_container.transform.looking_at(input_direction, Vector3(0, 1, 0)) diff --git a/networking/network_synchronizer/Character.tscn b/networking/network_synchronizer/Character.tscn new file mode 100644 index 0000000..63cb331 --- /dev/null +++ b/networking/network_synchronizer/Character.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=8 format=2] + +[ext_resource path="res://NetworkedController.gd" type="Script" id=1] +[ext_resource path="res://PlayerCamera.gd" type="Script" id=2] +[ext_resource path="res://Character.gd" type="Script" id=3] + +[sub_resource type="CapsuleShape" id=4] +radius = 0.249783 +height = 1.50094 + +[sub_resource type="CapsuleMesh" id=2] +radius = 0.25 +mid_height = 1.5 + +[sub_resource type="SpatialMaterial" id=3] + +[sub_resource type="CapsuleShape" id=5] +radius = 0.343218 +height = 1.47735 + +[node name="Character" type="KinematicBody"] +script = ExtResource( 3 ) + +[node name="CollisionShape" type="CollisionShape" parent="."] +transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 ) +shape = SubResource( 4 ) + +[node name="AvatarContainer" type="Spatial" parent="."] + +[node name="Mesh" type="MeshInstance" parent="AvatarContainer"] +transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 ) +mesh = SubResource( 2 ) +skeleton = NodePath("../..") +material/0 = SubResource( 3 ) + +[node name="Camera" type="Camera" parent="."] +transform = Transform( -0.707107, 0.454519, -0.541675, 0, 0.766044, 0.642787, 0.707107, 0.454519, -0.541675, -4.12047, 6.30383, -4.13525 ) +projection = 1 +size = 15.0 +near = 0.01 +far = 2000.0 +script = ExtResource( 2 ) + +[node name="NetworkedController" type="NetworkedController" parent="."] +doll_connection_stats_frame_span = 180 +script = ExtResource( 1 ) + +[node name="KinematicBody" type="KinematicBody" parent="."] + +[node name="CollisionShape" type="CollisionShape" parent="KinematicBody"] +transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 ) +shape = SubResource( 5 ) diff --git a/networking/network_synchronizer/LICENSE b/networking/network_synchronizer/LICENSE new file mode 100644 index 0000000..1f5be36 --- /dev/null +++ b/networking/network_synchronizer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 GodotNetworking + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/networking/network_synchronizer/MainScene.gd b/networking/network_synchronizer/MainScene.gd new file mode 100644 index 0000000..1114853 --- /dev/null +++ b/networking/network_synchronizer/MainScene.gd @@ -0,0 +1,106 @@ +extends Node + +# ----------------------------------------------------------------------------------------- Settings +const SERVER_PORT = 2000 +const MAX_PLAYERS = 5 +const SERVER_IP = "127.0.0.1" +const COLORS_LIST = [ + "#0ad609", + "#f0bf58", + "#1120d3", + "#704c28", + "#2af4ce" +] + + +# --------------------------------------------------------------------------------------------- Vars +onready var _menu: Control = $Menu +onready var _session_type_lbl: Label = $SessionTypeLbl + +var _player_id_counter = 0 +var _players = {} + + +# ------------------------------------------------------------------------------------- UI functions +func _start_server(): + _menu.hide() + _session_type_lbl.text = "Server" + + var peer = NetworkedMultiplayerENet.new() + peer.create_server(SERVER_PORT, MAX_PLAYERS) + get_tree().network_peer = peer + get_tree().connect("network_peer_connected", self, "_on_client_connected") + get_tree().connect("network_peer_disconnected", self, "_on_client_disconnected") + print("Server IP: ", IP.get_local_addresses()) + + +func _start_client(): + _menu.hide() + _session_type_lbl.text = "Client" + + var peer = NetworkedMultiplayerENet.new() + peer.create_client(SERVER_IP, SERVER_PORT) + get_tree().network_peer = peer + + +# ------------------------------------------------------------------- Server only internal functions +func _on_client_connected(peer_id): + print("Connected: ", peer_id) + var new_player_id = _player_id_counter + _player_id_counter += 1 + _players[new_player_id] = {"peer_id": peer_id, "player_id": new_player_id} + + # Spawn player on server, for server any player is puppet (even if it's + # autoritative) + _spawn_new_player(new_player_id, peer_id) + + # Spawn the player on the client + rpc_id(peer_id, "_spawn_new_player", new_player_id, peer_id) + + # Tell anyone new player appeared + for player_id in _players.keys(): + if _players[player_id]["peer_id"] != peer_id: + rpc_id(_players[player_id]["peer_id"], "_spawn_new_player", new_player_id, 1) + + # Spawn the actual _players on this client + for player_id in _players.keys(): + if player_id != new_player_id: + rpc_id(peer_id, "_spawn_new_player", player_id, 1) + + +func _on_client_disconnected(peer_id): + print("Disconnected: ", peer_id) + + var disconnected_player_id = -1 + for player_id in _players.keys(): + if _players[player_id]["peer_id"] == peer_id: + disconnected_player_id = player_id + break + + if disconnected_player_id == -1: + return + + _players.erase(disconnected_player_id) + _remove_player(disconnected_player_id) + + # Tell anyone player disappeared + for player_id in _players.keys(): + rpc_id(_players[player_id]["peer_id"], "_remove_player", disconnected_player_id) + + +# --------------------------------------------------------------------------------- Remote functions +remote func _spawn_new_player(player_id, peer_id): + print("Spawn player id: ", player_id, ", Peer_id: ", peer_id) + print("While my peer id is: ", get_tree().multiplayer.network_peer.get_unique_id()) + + var character = load("res://Character.tscn").instance() + character.set_network_master(peer_id) + character.set_name("player_" + str(player_id)) + get_tree().get_current_scene().add_child(character) + character.set_color(COLORS_LIST[player_id]) + + +remote func _remove_player(player_id): + var player_node = get_tree().get_current_scene().get_node("player_" + str(player_id)) + if player_node != null: + player_node.queue_free() diff --git a/networking/network_synchronizer/MainScene.tscn b/networking/network_synchronizer/MainScene.tscn new file mode 100644 index 0000000..c52aeb6 --- /dev/null +++ b/networking/network_synchronizer/MainScene.tscn @@ -0,0 +1,107 @@ +[gd_scene load_steps=10 format=2] + +[ext_resource path="res://MainScene.gd" type="Script" id=1] +[ext_resource path="res://aerial_rocks_02_diff_4k.jpg" type="Texture" id=2] + +[sub_resource type="ProceduralSky" id=1] + +[sub_resource type="Environment" id=2] +background_mode = 2 +background_sky = SubResource( 1 ) + +[sub_resource type="BoxShape" id=3] +extents = Vector3( 50, 0.25, 50 ) + +[sub_resource type="PlaneMesh" id=4] +size = Vector2( 100, 100 ) + +[sub_resource type="SpatialMaterial" id=5] +albedo_texture = ExtResource( 2 ) + +[sub_resource type="CapsuleShape" id=6] +radius = 0.25 + +[sub_resource type="CapsuleMesh" id=7] +radius = 0.25 + +[node name="Node" type="Node"] +script = ExtResource( 1 ) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource( 2 ) + +[node name="DirectionalLight" type="DirectionalLight" parent="."] +transform = Transform( 0.942496, -0.163932, -0.291253, 0.331754, 0.35325, 0.874731, -0.0405109, -0.921054, 0.387322, 0, 29.9334, 0 ) +shadow_enabled = true + +[node name="Floor" type="StaticBody" parent="."] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.03388, 0 ) + +[node name="CollisionShape" type="CollisionShape" parent="Floor"] +shape = SubResource( 3 ) + +[node name="MeshInstance" type="MeshInstance" parent="Floor"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.235271, 0 ) +mesh = SubResource( 4 ) +material/0 = SubResource( 5 ) + +[node name="SessionTypeLbl" type="Label" parent="."] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -20.0 +margin_right = 20.0 +margin_bottom = 14.0 +custom_colors/font_color = Color( 0, 0, 0, 1 ) +text = "None" +align = 1 + +[node name="Menu" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 + +[node name="HBoxContainer" type="HBoxContainer" parent="Menu"] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -103.0 +margin_top = -7.0 +margin_right = 112.0 +margin_bottom = 13.0 +rect_pivot_offset = Vector2( 0.5, 0.5 ) + +[node name="ServerButton" type="Button" parent="Menu/HBoxContainer"] +margin_right = 103.0 +margin_bottom = 20.0 +custom_colors/font_color = Color( 0, 1, 0.262745, 1 ) +text = "Start as Server" + +[node name="VSeparator" type="VSeparator" parent="Menu/HBoxContainer"] +margin_left = 107.0 +margin_right = 111.0 +margin_bottom = 20.0 + +[node name="ClientButton" type="Button" parent="Menu/HBoxContainer"] +margin_left = 115.0 +margin_right = 215.0 +margin_bottom = 20.0 +custom_colors/font_color = Color( 0, 0.988235, 1, 1 ) +text = "Start as Client" + +[node name="Camera" type="Camera" parent="."] +transform = Transform( -0.707107, 0.353553, -0.612372, 0, 0.866025, 0.5, 0.707107, 0.353553, -0.612372, -71.053, 66.4778, -71.053 ) +projection = 1 +size = 50.0 +far = 2000.0 + +[node name="StaticBody" type="StaticBody" parent="."] +transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.772334, 2.46257 ) + +[node name="CollisionShape" type="CollisionShape" parent="StaticBody"] +shape = SubResource( 6 ) + +[node name="MeshInstance" type="MeshInstance" parent="StaticBody"] +mesh = SubResource( 7 ) + +[connection signal="pressed" from="Menu/HBoxContainer/ServerButton" to="." method="_start_server"] +[connection signal="pressed" from="Menu/HBoxContainer/ClientButton" to="." method="_start_client"] diff --git a/networking/network_synchronizer/NetworkSync.gd b/networking/network_synchronizer/NetworkSync.gd new file mode 100644 index 0000000..d3ae7f1 --- /dev/null +++ b/networking/network_synchronizer/NetworkSync.gd @@ -0,0 +1 @@ +extends SceneSynchronizer diff --git a/networking/network_synchronizer/NetworkedController.gd b/networking/network_synchronizer/NetworkedController.gd new file mode 100644 index 0000000..471e299 --- /dev/null +++ b/networking/network_synchronizer/NetworkedController.gd @@ -0,0 +1,133 @@ +extends NetworkedController +# Take cares to control the player and propagate the motion on the other peers + + +const MAX_PLAYER_DISTANCE: float = 20.0 + +var _position_id := -1 +var _rotation_id := -1 + + +func _ready(): + # Notify the NetworkSync who is controlling parent nodes. + NetworkSync.set_node_as_controlled_by(get_parent(), self) + NetworkSync.register_variable(get_parent(), "translation") + NetworkSync.register_variable(get_parent(), "linear_velocity") + NetworkSync.register_variable(get_parent(), "on_floor") + if not get_tree().multiplayer.is_network_server(): + set_physics_process(false) + + +func _physics_process(_delta): + """ + # Changes the character relevancy to scale the net traffic depending on the character + importance. + for character in get_tree().get_nodes_in_group("characters"): + if character != get_parent(): + var delta_distance = character.get_global_transform().origin - get_parent().get_global_transform().origin + + var is_far_away = delta_distance.length_squared() > (MAX_PLAYER_DISTANCE * MAX_PLAYER_DISTANCE) + set_doll_peer_active(character.get_network_master(), !is_far_away); + """ + + +func _collect_inputs(_delta: float, db: DataBuffer): + # Collects the player inputs. + + var input_direction := Vector3() + var is_jumping: bool = false + + if Input.is_action_pressed("forward"): + input_direction -= get_parent().camera.global_transform.basis.z + if Input.is_action_pressed("backward"): + input_direction += get_parent().camera.global_transform.basis.z + if Input.is_action_pressed("left"): + input_direction -= get_parent().camera.global_transform.basis.x + if Input.is_action_pressed("right"): + input_direction += get_parent().camera.global_transform.basis.x + if Input.is_action_pressed("jump"): + is_jumping = true + input_direction.y = 0 + input_direction = input_direction.normalized() + + db.add_bool(is_jumping) + + var has_input: bool = input_direction.length_squared() > 0.0 + db.add_bool(has_input) + if has_input: + db.add_normalized_vector2(Vector2(input_direction.x, input_direction.z), DataBuffer.COMPRESSION_LEVEL_3) + + +func _controller_process(delta: float, db: DataBuffer): + # Process the controller. + + # Take the inputs + var is_jumping = db.read_bool() + var input_direction := Vector2() + + var has_input = db.read_bool() + if has_input: + input_direction = db.read_normalized_vector2(DataBuffer.COMPRESSION_LEVEL_3) + + var initial_transform: Vector3 = get_parent().transform.origin + + # Process the character + get_parent().step_body(delta, Vector3(input_direction.x, 0.0, input_direction.y), is_jumping) + + var after_transform: Vector3 = get_parent().transform.origin + + var mode = "Client" + if is_server_controller(): + mode = "Server" + + mode = "" + + #if "player_0" == get_parent().name: + # print(get_parent().name, " ", mode, ", Input: ", get_current_input_id(), " Delta: ", delta, " Dir: ", Vector3(input_direction.x, 0.0, input_direction.y), " Jump: ", is_jumping, " - Initial t ", initial_transform, " result t", after_transform) + + +func _count_input_size(inputs: DataBuffer) -> int: + # Count the input buffer size. + var size: int = 0 + size += inputs.get_bool_size() + inputs.skip_bool() + size += inputs.get_bool_size() + if inputs.read_bool(): + size += inputs.get_normalized_vector2_size(DataBuffer.COMPRESSION_LEVEL_3) + + return size + + +func _are_inputs_different(inputs_A: DataBuffer, inputs_B: DataBuffer) -> bool: + # Compare two inputs, returns true when those are different or false when are close enough. + if inputs_A.read_bool() != inputs_B.read_bool(): + return true + + var inp_A_has_i = inputs_A.read_bool() + var inp_B_has_i = inputs_B.read_bool() + if inp_A_has_i != inp_B_has_i: + return true + + if inp_A_has_i: + var inp_A_dir = inputs_A.read_normalized_vector2(DataBuffer.COMPRESSION_LEVEL_3) + var inp_B_dir = inputs_B.read_normalized_vector2(DataBuffer.COMPRESSION_LEVEL_3) + if (inp_A_dir - inp_B_dir).length_squared() > 0.0001: + return true + + return false + + +func _collect_epoch_data(buffer: DataBuffer): + buffer.add_vector3(get_parent().global_transform.origin, DataBuffer.COMPRESSION_LEVEL_0) + buffer.add_vector3(get_parent().avatar_container.rotation, DataBuffer.COMPRESSION_LEVEL_2) + + +func _apply_epoch(_delta: float, alpha: float, past_buffer: DataBuffer, future_buffer: DataBuffer): + var past_position := past_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_0) + var past_rotation := past_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_2) + + var future_position := future_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_0) + var future_rotation := future_buffer.read_vector3(DataBuffer.COMPRESSION_LEVEL_2) + + get_parent().global_transform.origin = lerp(past_position, future_position, alpha) + get_parent().avatar_container.rotation = lerp(past_rotation, future_rotation, alpha) diff --git a/networking/network_synchronizer/PlayerCamera.gd b/networking/network_synchronizer/PlayerCamera.gd new file mode 100644 index 0000000..4bac34c --- /dev/null +++ b/networking/network_synchronizer/PlayerCamera.gd @@ -0,0 +1,8 @@ +extends Camera + + +func _ready() -> void: + if is_network_master(): + current = true + else: + set_process_input(false) diff --git a/networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg b/networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg new file mode 100644 index 0000000..d2ff457 Binary files /dev/null and b/networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg differ diff --git a/networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg.import b/networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg.import new file mode 100644 index 0000000..1938c14 --- /dev/null +++ b/networking/network_synchronizer/aerial_rocks_02_diff_4k.jpg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="StreamTexture" +path.s3tc="res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.s3tc.stex" +path.etc2="res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.etc2.stex" +metadata={ +"imported_formats": [ "s3tc", "etc2" ], +"vram_texture": true +} + +[deps] + +source_file="res://aerial_rocks_02_diff_4k.jpg" +dest_files=[ "res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.s3tc.stex", "res://.import/aerial_rocks_02_diff_4k.jpg-8512df93af913ad07cc794706f989328.etc2.stex" ] + +[params] + +compress/mode=2 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=true +flags/filter=true +flags/mipmaps=true +flags/anisotropic=false +flags/srgb=1 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/networking/network_synchronizer/default_env.tres b/networking/network_synchronizer/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/networking/network_synchronizer/default_env.tres @@ -0,0 +1,7 @@ +[gd_resource type="Environment" load_steps=2 format=2] + +[sub_resource type="ProceduralSky" id=1] + +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/networking/network_synchronizer/icon.png b/networking/network_synchronizer/icon.png new file mode 100644 index 0000000..c98fbb6 Binary files /dev/null and b/networking/network_synchronizer/icon.png differ diff --git a/networking/network_synchronizer/icon.png.import b/networking/network_synchronizer/icon.png.import new file mode 100644 index 0000000..a4c02e6 --- /dev/null +++ b/networking/network_synchronizer/icon.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/networking/network_synchronizer/project.pandemonium b/networking/network_synchronizer/project.pandemonium new file mode 100644 index 0000000..2b10b99 --- /dev/null +++ b/networking/network_synchronizer/project.pandemonium @@ -0,0 +1,92 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +_global_script_classes=[ { +"base": "SpringArm3D", +"class": @"PlayerCamera", +"language": @"GDScript", +"path": "res://player_camera.gd" +} ] +_global_script_class_icons={ +@"PlayerCamera": "" +} + +[NetworkSynchronizer] + +debug_doll_speedup=true + +[application] + +config/name="NetSyncTest3.x" +run/main_scene="res://MainScene.tscn" +config/icon="res://icon.png" + +[autoload] + +NetworkSync="*res://NetworkSync.gd" + +[display] + +window/size/width=640 +window/size/height=400 +window/dpi/allow_hidpi=true +window/stretch/mode="2d" +window/stretch/aspect="expand" +stretch_2d=true + +[editor] + +main_run_args="--server" + +[gdnative] + +singletons=[ ] + +[input] + +forward={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":87,"unicode":0,"echo":false,"script":null) + ] +} +backward={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":83,"unicode":0,"echo":false,"script":null) + ] +} +left={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":65,"unicode":0,"echo":false,"script":null) + ] +} +right={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":68,"unicode":0,"echo":false,"script":null) + ] +} +jump={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":32,"unicode":0,"echo":false,"script":null) + ] +} + +[layer_names] + +3d_physics/layer_1="Common" +3d_physics/layer_2="Player" + +[physics] + +common/physics_jitter_fix=0.0 +common/enable_pause_aware_picking=true + +[rendering] + +environment/default_environment="res://default_env.tres"