From 1f73d22cd6733ebc28156fef627fd818d6ce2c85 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 20 Jan 2024 22:18:58 +0100 Subject: [PATCH] Added Godot based server --- character/CharacterController.gd | 2 - enemy/EnemyController.gd | 18 +-- enemy/Slime.tscn | 6 +- network/Network.gd | 26 ---- network/NetworkNode.gd | 23 ++++ network/Packet.gd | 1 + network/PacketHandler.gd | 5 + network/client/Client.gd | 15 +++ network/{ => client}/Login.gd | 16 +-- network/{ => client}/Ping.gd | 10 +- network/server/Login.gd | 35 +++++ network/server/Ping.gd | 20 +++ network/server/Server.gd | 29 +++++ player/Player.tscn | 10 +- player/PlayerController.gd | 4 +- {world/shader => shader}/Outline.gdshader | 0 {world/shader => shader}/OutlineMaterial.tres | 2 +- {server => tools/server}/core/Client.go | 0 {server => tools/server}/core/Server.go | 8 +- {server => tools/server}/go.mod | 0 {server => tools/server}/login.go | 0 {server => tools/server}/main.go | 0 {server => tools/server}/packet/types.go | 0 {server => tools/server}/ping.go | 0 tools/stresstest/go.mod | 3 + tools/stresstest/main.go | 61 +++++++++ world/Arena.blend.import | 56 ++++++++ world/Game.tscn | 123 +++++++++--------- 28 files changed, 338 insertions(+), 135 deletions(-) delete mode 100644 character/CharacterController.gd delete mode 100644 network/Network.gd create mode 100644 network/NetworkNode.gd create mode 100644 network/PacketHandler.gd create mode 100644 network/client/Client.gd rename network/{ => client}/Login.gd (53%) rename network/{ => client}/Ping.gd (70%) create mode 100644 network/server/Login.gd create mode 100644 network/server/Ping.gd create mode 100644 network/server/Server.gd rename {world/shader => shader}/Outline.gdshader (100%) rename {world/shader => shader}/OutlineMaterial.tres (85%) rename {server => tools/server}/core/Client.go (100%) rename {server => tools/server}/core/Server.go (94%) rename {server => tools/server}/go.mod (100%) rename {server => tools/server}/login.go (100%) rename {server => tools/server}/main.go (100%) rename {server => tools/server}/packet/types.go (100%) rename {server => tools/server}/ping.go (100%) create mode 100644 tools/stresstest/go.mod create mode 100644 tools/stresstest/main.go create mode 100644 world/Arena.blend.import diff --git a/character/CharacterController.gd b/character/CharacterController.gd deleted file mode 100644 index ddca3d2..0000000 --- a/character/CharacterController.gd +++ /dev/null @@ -1,2 +0,0 @@ -class_name CharacterController -extends Node diff --git a/enemy/EnemyController.gd b/enemy/EnemyController.gd index d33184e..896eea6 100644 --- a/enemy/EnemyController.gd +++ b/enemy/EnemyController.gd @@ -1,18 +1,2 @@ class_name EnemyController -extends CharacterController - -@export var character: Character -var move: Vector2 - -func _input(_event): - move = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") - character.direction = (Global.camera.transform.basis * Vector3(move.x, 0, move.y)).normalized() - - if Input.is_action_pressed("jump"): - character.jump() - - if Input.is_action_pressed("attack"): - print("Attack") - - if Input.is_action_pressed("aim"): - print("Aim") +extends Node diff --git a/enemy/Slime.tscn b/enemy/Slime.tscn index 50ea509..40cfb94 100644 --- a/enemy/Slime.tscn +++ b/enemy/Slime.tscn @@ -41,15 +41,15 @@ model = NodePath("Model") [node name="Model" parent="." instance=ExtResource("1_1h1hj")] -[node name="CollisionShape" type="CollisionShape3D" parent="."] +[node name="Collision" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0452515, 0.3, 0) shape = SubResource("BoxShape3D_x1ppt") -[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +[node name="Animation" type="AnimationPlayer" parent="."] root_node = NodePath("../Model") libraries = { "": SubResource("AnimationLibrary_1bw8m") } autoplay = "slime_idle" -[node name="HealthComponent" parent="." instance=ExtResource("2_fsqxc")] +[node name="Health" parent="." instance=ExtResource("2_fsqxc")] diff --git a/network/Network.gd b/network/Network.gd deleted file mode 100644 index bc75d85..0000000 --- a/network/Network.gd +++ /dev/null @@ -1,26 +0,0 @@ -extends Node - -var udp := PacketPeerUDP.new() -var handlers: Array[Node] = [] - -func _init(): - handlers.resize(256) - udp.connect_to_host("127.0.0.1", 4242) - -func _process(_delta): - if udp.get_available_packet_count() <= 0: - return - - var packet := udp.get_packet() - var type := packet.decode_u8(0) - var handler := handlers[type] - - if handler == null: - push_warning("Unknown packet type %d" % type) - return - - handler.handle_packet(packet.slice(1)) - -func add_handler(packet: int, node: Node): - assert(node.has_method("handle_packet")) - handlers[packet] = node diff --git a/network/NetworkNode.gd b/network/NetworkNode.gd new file mode 100644 index 0000000..bdba115 --- /dev/null +++ b/network/NetworkNode.gd @@ -0,0 +1,23 @@ +class_name NetworkNode +extends Node + +var handlers: Array[Node] = [] + +func _init(): + handlers.resize(256) + +func get_handler(index: int) -> PacketHandler: + return handlers[index] + +func set_handler(index: int, node: PacketHandler): + handlers[index] = node + +func handle_packet(packet: PackedByteArray, peer: PacketPeer): + var type := packet.decode_u8(0) + var handler := get_handler(type) + + if handler == null: + push_warning("Unknown packet type %d" % type) + return + + handler.handle_packet(packet.slice(1), peer) diff --git a/network/Packet.gd b/network/Packet.gd index ca76b6e..cac9caa 100644 --- a/network/Packet.gd +++ b/network/Packet.gd @@ -1,4 +1,5 @@ class_name Packet + enum { PING = 1, LOGIN = 2, diff --git a/network/PacketHandler.gd b/network/PacketHandler.gd new file mode 100644 index 0000000..aab25ea --- /dev/null +++ b/network/PacketHandler.gd @@ -0,0 +1,5 @@ +class_name PacketHandler +extends Node + +func handle_packet(_data: PackedByteArray, _peer: PacketPeer): + pass \ No newline at end of file diff --git a/network/client/Client.gd b/network/client/Client.gd new file mode 100644 index 0000000..3bc1587 --- /dev/null +++ b/network/client/Client.gd @@ -0,0 +1,15 @@ +extends NetworkNode + +@export var ip := "127.0.0.1" +@export var port := 4242 + +var socket := PacketPeerUDP.new() + +func _init(): + super._init() + socket.connect_to_host(ip, port) + +func _process(_delta): + while socket.get_available_packet_count() > 0: + var packet := socket.get_packet() + handle_packet(packet, socket) \ No newline at end of file diff --git a/network/Login.gd b/network/client/Login.gd similarity index 53% rename from network/Login.gd rename to network/client/Login.gd index 7639428..a493627 100644 --- a/network/Login.gd +++ b/network/client/Login.gd @@ -1,11 +1,11 @@ -extends Node +extends PacketHandler @export var playerScene: PackedScene var logged_in := false func _ready(): - %Network.add_handler(Packet.LOGIN, self) + %Client.set_handler(Packet.LOGIN, self) send_login() func send_login(): @@ -14,16 +14,16 @@ func send_login(): var buffer := StreamPeerBuffer.new() buffer.put_8(Packet.LOGIN) - buffer.put_data("password".to_utf8_buffer()) - %Network.udp.put_packet(buffer.data_array) - print("Connecting...") + buffer.put_data(JSON.stringify(["username", "password"]).to_utf8_buffer()) + %Client.socket.put_packet(buffer.data_array) + print("[Client] Connecting...") -func handle_packet(data: PackedByteArray): +func handle_packet(data: PackedByteArray, _peer: PacketPeer): if data[0] != 0: - print("Login failed.") + print("[Client] Login failed.") return - print("Login succeeded.") + print("[Client] Login succeeded.") logged_in = true Global.player = spawn_player() diff --git a/network/Ping.gd b/network/client/Ping.gd similarity index 70% rename from network/Ping.gd rename to network/client/Ping.gd index 86a705c..c6e3230 100644 --- a/network/Ping.gd +++ b/network/client/Ping.gd @@ -1,4 +1,4 @@ -extends Node +extends PacketHandler signal changed(ping: float) @@ -11,13 +11,13 @@ func _init(): history.resize(HISTORY_SIZE) func _ready(): - %Network.add_handler(Packet.PING, self) + %Client.set_handler(Packet.PING, self) func send_ping(): var buffer := StreamPeerBuffer.new() buffer.put_8(Packet.PING) buffer.put_8(count) - %Network.udp.put_packet(buffer.data_array) + %Client.socket.put_packet(buffer.data_array) history[count] = Time.get_unix_time_from_system() count += 1 @@ -25,8 +25,8 @@ func send_ping(): if count >= HISTORY_SIZE: count = 0 -func handle_packet(data: PackedByteArray): - var id := data.decode_u8(0) +func handle_packet(data: PackedByteArray, _peer: PacketPeer): + var id := data[0] var ping := Time.get_unix_time_from_system() - history[id] changed.emit(ping) diff --git a/network/server/Login.gd b/network/server/Login.gd new file mode 100644 index 0000000..5f68537 --- /dev/null +++ b/network/server/Login.gd @@ -0,0 +1,35 @@ +extends PacketHandler + +enum { + SUCCESS = 0, + FAIL = 1, +} + +func _ready(): + %Server.set_handler(Packet.LOGIN, self) + +func handle_packet(data: PackedByteArray, peer: PacketPeer): + var data_string = data.get_string_from_utf8() + var login_request = JSON.parse_string(data_string) + + if login_request.size() < 2: + fail_login(peer) + return + + var username = login_request[0] + var password = login_request[1] + + if username != "username" || password != "password": + fail_login(peer) + return + + var buffer := StreamPeerBuffer.new() + buffer.put_8(Packet.LOGIN) + buffer.put_8(SUCCESS) + peer.put_packet(buffer.data_array) + +func fail_login(peer: PacketPeer): + var buffer := StreamPeerBuffer.new() + buffer.put_8(Packet.LOGIN) + buffer.put_8(FAIL) + peer.put_packet(buffer.data_array) \ No newline at end of file diff --git a/network/server/Ping.gd b/network/server/Ping.gd new file mode 100644 index 0000000..f53762c --- /dev/null +++ b/network/server/Ping.gd @@ -0,0 +1,20 @@ +extends PacketHandler + +func _ready(): + %Server.set_handler(Packet.PING, self) + +func handle_packet(data: PackedByteArray, peer: PacketPeer): + # var response := PackedByteArray() + # response.resize(2) + # response.encode_u8(0, Packet.PING) + # response.encode_u8(1, data[0]) + # peer.put_packet(response) + + var buffer := StreamPeerBuffer.new() + buffer.put_8(Packet.PING) + + if data.size() > 0: + buffer.put_8(data[0]) + + peer.put_packet(buffer.data_array) + diff --git a/network/server/Server.gd b/network/server/Server.gd new file mode 100644 index 0000000..f4542ca --- /dev/null +++ b/network/server/Server.gd @@ -0,0 +1,29 @@ +extends NetworkNode + +@export var port := 4242 +@export var max_pending_connections := 4096 + +var server := UDPServer.new() +var last_statistics := Time.get_ticks_msec() +var packet_count := 0 + +func _init(): + super._init() + server.set_max_pending_connections(max_pending_connections) + server.listen(port) + +func _process(_delta): + server.poll() + + while server.is_connection_available(): + var peer: PacketPeerUDP = server.take_connection() + + while peer.get_available_packet_count() > 0: + var packet = peer.get_packet() + handle_packet(packet, peer) + packet_count += 1 + + if Time.get_ticks_msec() > last_statistics + 1000: + print("[Server] %d packets per second" % packet_count) + packet_count = 0 + last_statistics = Time.get_ticks_msec() diff --git a/player/Player.tscn b/player/Player.tscn index a139b93..35388df 100644 --- a/player/Player.tscn +++ b/player/Player.tscn @@ -21,14 +21,14 @@ model = NodePath("Model") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0) mesh = SubResource("PrismMesh_y7abh") -[node name="CollisionShape" type="CollisionShape3D" parent="."] +[node name="Collision" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0) shape = SubResource("CapsuleShape3D_2f50n") -[node name="HealthComponent" parent="." instance=ExtResource("2_np5ag")] +[node name="Animation" type="AnimationPlayer" parent="."] -[node name="PlayerController" type="Node" parent="." node_paths=PackedStringArray("character")] +[node name="Health" parent="." instance=ExtResource("2_np5ag")] + +[node name="Controller" type="Node" parent="." node_paths=PackedStringArray("character")] script = ExtResource("3_oox5k") character = NodePath("..") - -[node name="AnimationPlayer" type="AnimationPlayer" parent="."] diff --git a/player/PlayerController.gd b/player/PlayerController.gd index 859b6a5..e60c44d 100644 --- a/player/PlayerController.gd +++ b/player/PlayerController.gd @@ -1,5 +1,5 @@ class_name PlayerController -extends CharacterController +extends Node @export var character: Character var move: Vector2 @@ -12,7 +12,7 @@ func _input(_event): if Input.is_action_just_pressed("jump"): character.jump() - + if Input.is_action_just_pressed("dash"): character.dash() diff --git a/world/shader/Outline.gdshader b/shader/Outline.gdshader similarity index 100% rename from world/shader/Outline.gdshader rename to shader/Outline.gdshader diff --git a/world/shader/OutlineMaterial.tres b/shader/OutlineMaterial.tres similarity index 85% rename from world/shader/OutlineMaterial.tres rename to shader/OutlineMaterial.tres index 863f2c6..69b48ea 100644 --- a/world/shader/OutlineMaterial.tres +++ b/shader/OutlineMaterial.tres @@ -1,6 +1,6 @@ [gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://ddy5gkw0k16dq"] -[ext_resource type="Shader" path="res://world/shader/Outline.gdshader" id="1_fmkjv"] +[ext_resource type="Shader" path="res://shader/Outline.gdshader" id="1_fmkjv"] [resource] render_priority = 0 diff --git a/server/core/Client.go b/tools/server/core/Client.go similarity index 100% rename from server/core/Client.go rename to tools/server/core/Client.go diff --git a/server/core/Server.go b/tools/server/core/Server.go similarity index 94% rename from server/core/Server.go rename to tools/server/core/Server.go index 93e69ce..a265f58 100644 --- a/server/core/Server.go +++ b/tools/server/core/Server.go @@ -109,15 +109,15 @@ func (s *Server) read() { continue } - go s.handle(buffer[:n], addr) + s.handle(buffer[:n], addr) } } - +var packets = 0 // handle deals with an incoming packet. func (s *Server) handle(data []byte, addr *net.UDPAddr) { c := s.getClient(addr) c.lastPacket = time.Now() - // fmt.Printf("Received %d bytes from %s: %s\n", len(data), c, string(data)) + //fmt.Printf("Received %d bytes from %s: %s\n", len(data), c, string(data)) handler := s.handlers[data[0]] @@ -127,6 +127,8 @@ func (s *Server) handle(data []byte, addr *net.UDPAddr) { } handler(data[1:], c) + packets++ + fmt.Println(packets) } // getClient either returns a new or existing client for the requested address. diff --git a/server/go.mod b/tools/server/go.mod similarity index 100% rename from server/go.mod rename to tools/server/go.mod diff --git a/server/login.go b/tools/server/login.go similarity index 100% rename from server/login.go rename to tools/server/login.go diff --git a/server/main.go b/tools/server/main.go similarity index 100% rename from server/main.go rename to tools/server/main.go diff --git a/server/packet/types.go b/tools/server/packet/types.go similarity index 100% rename from server/packet/types.go rename to tools/server/packet/types.go diff --git a/server/ping.go b/tools/server/ping.go similarity index 100% rename from server/ping.go rename to tools/server/ping.go diff --git a/tools/stresstest/go.mod b/tools/stresstest/go.mod new file mode 100644 index 0000000..b6ebb6f --- /dev/null +++ b/tools/stresstest/go.mod @@ -0,0 +1,3 @@ +module stresstest + +go 1.21.6 diff --git a/tools/stresstest/main.go b/tools/stresstest/main.go new file mode 100644 index 0000000..7685946 --- /dev/null +++ b/tools/stresstest/main.go @@ -0,0 +1,61 @@ +package main + +import ( + "flag" + "fmt" + "net" + "sync" + "time" +) + +const ( + serverAddress = "127.0.0.1:4242" +) + +var ( + numClients = flag.Int("c", 10, "number of clients") + message = []byte{1} +) + +func init() { + flag.Parse() +} + +func udpClient(wg *sync.WaitGroup) { + defer wg.Done() + + clientAddr, err := net.ResolveUDPAddr("udp", serverAddress) + if err != nil { + fmt.Println("Error resolving UDP address:", err) + return + } + + conn, err := net.DialUDP("udp", nil, clientAddr) + if err != nil { + fmt.Println("Error connecting to UDP server:", err) + return + } + defer conn.Close() + + for { + _, err := conn.Write(message) + if err != nil { + fmt.Println("Error sending message:", err) + return + } + time.Sleep(50 * time.Millisecond) // Adjust the sleep duration as needed + } +} + +func main() { + var wg sync.WaitGroup + + // Start multiple UDP clients in separate goroutines + for i := 0; i < *numClients; i++ { + wg.Add(1) + go udpClient(&wg) + } + + // Signal all client goroutines to stop + wg.Wait() +} diff --git a/world/Arena.blend.import b/world/Arena.blend.import new file mode 100644 index 0000000..45dca01 --- /dev/null +++ b/world/Arena.blend.import @@ -0,0 +1,56 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://tgmbtt7u172g" +path="res://.godot/imported/Arena.blend-c720f6651d38b4cfd30aa3f4d2266924.scn" + +[deps] + +source_file="res://world/Arena.blend" +dest_files=["res://.godot/imported/Arena.blend-c720f6651d38b4cfd30aa3f4d2266924.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"nodes": { +"PATH:Plane": { +"physics/shape_type": 2 +} +} +} +gltf/naming_version=1 +gltf/embedded_image_handling=1 +blender/nodes/visible=0 +blender/nodes/punctual_lights=true +blender/nodes/cameras=true +blender/nodes/custom_properties=true +blender/nodes/modifiers=1 +blender/meshes/colors=false +blender/meshes/uvs=true +blender/meshes/normals=true +blender/meshes/tangents=true +blender/meshes/skins=2 +blender/meshes/export_bones_deforming_mesh_only=false +blender/materials/unpack_enabled=true +blender/materials/export_materials=1 +blender/animation/limit_playback=true +blender/animation/always_sample=true +blender/animation/group_tracks=true diff --git a/world/Game.tscn b/world/Game.tscn index ce75ecf..6df2994 100644 --- a/world/Game.tscn +++ b/world/Game.tscn @@ -1,61 +1,90 @@ -[gd_scene load_steps=22 format=3 uid="uid://b40y7iuskv1ar"] +[gd_scene load_steps=23 format=3 uid="uid://b40y7iuskv1ar"] [ext_resource type="Script" path="res://world/Game.gd" id="1_xmqq4"] -[ext_resource type="Script" path="res://network/Network.gd" id="4_ao4cj"] -[ext_resource type="Script" path="res://network/Ping.gd" id="4_vx388"] +[ext_resource type="Script" path="res://network/client/Client.gd" id="4_ao4cj"] +[ext_resource type="Script" path="res://network/client/Ping.gd" id="4_vx388"] [ext_resource type="PackedScene" uid="uid://2lcnu3dy54lx" path="res://player/Player.tscn" id="5_6c2x8"] [ext_resource type="Environment" uid="uid://dixa0yso2s1u3" path="res://world/Environment.tres" id="5_bll74"] [ext_resource type="Script" path="res://world/Sun.gd" id="5_pf5uw"] [ext_resource type="CameraAttributesPractical" uid="uid://b835orxyqq6w5" path="res://world/CameraAttributes.tres" id="6_8wfwf"] [ext_resource type="PackedScene" uid="uid://cch67vqpsmtej" path="res://ui/debug/DebugLabel.tscn" id="6_076g5"] -[ext_resource type="Script" path="res://network/Login.gd" id="6_augbg"] +[ext_resource type="Script" path="res://network/client/Login.gd" id="6_augbg"] [ext_resource type="Script" path="res://ui/debug/FPSLabel.gd" id="7_3qgww"] +[ext_resource type="Script" path="res://network/server/Ping.gd" id="7_8mtv7"] [ext_resource type="Script" path="res://ui/debug/PingLabel.gd" id="7_kmy1y"] +[ext_resource type="Script" path="res://network/server/Login.gd" id="8_1y1wq"] [ext_resource type="Script" path="res://ui/debug/PositionLabel.gd" id="8_fge13"] [ext_resource type="Script" path="res://ui/debug/VelocityLabel.gd" id="9_f25hg"] [ext_resource type="Script" path="res://world/Camera.gd" id="9_qfhy4"] -[ext_resource type="Material" uid="uid://ddy5gkw0k16dq" path="res://world/shader/OutlineMaterial.tres" id="10_dii8l"] +[ext_resource type="Material" uid="uid://ddy5gkw0k16dq" path="res://shader/OutlineMaterial.tres" id="10_dii8l"] [ext_resource type="PackedScene" uid="uid://hnn0n1xc2qt7" path="res://world/Tree.blend" id="15_csh38"] [ext_resource type="PackedScene" uid="uid://cb2t7bvvf3gwh" path="res://enemy/Slime.tscn" id="16_fuixr"] +[ext_resource type="PackedScene" uid="uid://tgmbtt7u172g" path="res://world/Arena.blend" id="17_q45cd"] +[ext_resource type="Script" path="res://network/server/Server.gd" id="19_bwh1t"] [sub_resource type="QuadMesh" id="QuadMesh_7yiqd"] material = ExtResource("10_dii8l") flip_faces = true size = Vector2(2, 2) -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r8n03"] -diffuse_mode = 3 -albedo_color = Color(0.482353, 0.470588, 0.47451, 1) - -[sub_resource type="BoxMesh" id="BoxMesh_0bujj"] -material = SubResource("StandardMaterial3D_r8n03") -size = Vector3(20, 0.5, 20) - -[sub_resource type="BoxShape3D" id="BoxShape3D_58ws3"] -size = Vector3(20, 0.5, 20) - [node name="Game" type="Node"] script = ExtResource("1_xmqq4") -[node name="Network" type="Node" parent="."] +[node name="Client" type="Node" parent="."] unique_name_in_owner = true script = ExtResource("4_ao4cj") +ip = null +port = null -[node name="Ping" type="Node" parent="Network"] +[node name="Ping" type="Node" parent="Client"] unique_name_in_owner = true script = ExtResource("4_vx388") -[node name="Timer" type="Timer" parent="Network/Ping"] +[node name="Timer" type="Timer" parent="Client/Ping"] autostart = true -[node name="Login" type="Node" parent="Network"] +[node name="Login" type="Node" parent="Client"] script = ExtResource("6_augbg") playerScene = ExtResource("5_6c2x8") -[node name="Timer" type="Timer" parent="Network/Login"] +[node name="Timer" type="Timer" parent="Client/Login"] wait_time = 10.0 autostart = true +[node name="Server" type="Node" parent="."] +unique_name_in_owner = true +script = ExtResource("19_bwh1t") + +[node name="Ping" type="Node" parent="Server"] +script = ExtResource("7_8mtv7") + +[node name="Login" type="Node" parent="Server"] +script = ExtResource("8_1y1wq") + +[node name="Players" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="Enemies" type="Node3D" parent="."] + +[node name="Slime" parent="Enemies" instance=ExtResource("16_fuixr")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.53558, 1.28057, -3.79687) + +[node name="Slime2" parent="Enemies" instance=ExtResource("16_fuixr")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.00829, 1.28057, -1.95247) + +[node name="Slime3" parent="Enemies" instance=ExtResource("16_fuixr")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.53558, 1.28057, -0.306177) + +[node name="World" type="Node3D" parent="."] + +[node name="Tree" parent="World" instance=ExtResource("15_csh38")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.11323, 0, -4.64839) + +[node name="Tree2" parent="World" instance=ExtResource("15_csh38")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.11323, 0, 5.35161) + +[node name="Arena" parent="World" instance=ExtResource("17_q45cd")] + [node name="UI" type="Control" parent="."] layout_mode = 3 anchors_preset = 0 @@ -96,7 +125,7 @@ script = ExtResource("8_fge13") layout_mode = 2 script = ExtResource("9_f25hg") -[node name="SubViewportContainer" type="SubViewportContainer" parent="."] +[node name="Viewport" type="SubViewportContainer" parent="."] texture_filter = 1 anchors_preset = 15 anchor_right = 1.0 @@ -105,14 +134,14 @@ grow_horizontal = 2 grow_vertical = 2 stretch = true -[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"] +[node name="SubViewport" type="SubViewport" parent="Viewport"] handle_input_locally = false size = Vector2i(1152, 648) render_target_update_mode = 4 -[node name="CameraPivot" type="Node3D" parent="SubViewportContainer/SubViewport"] +[node name="CameraPivot" type="Node3D" parent="Viewport/SubViewport"] -[node name="Camera" type="Camera3D" parent="SubViewportContainer/SubViewport/CameraPivot" node_paths=PackedStringArray("center")] +[node name="Camera" type="Camera3D" parent="Viewport/SubViewport/CameraPivot" node_paths=PackedStringArray("center")] transform = Transform3D(0.707107, 0.353554, -0.612372, 0, 0.866026, 0.5, 0.707107, -0.353554, 0.612372, -10, 10, 10) projection = 1 current = true @@ -123,52 +152,20 @@ script = ExtResource("9_qfhy4") center = NodePath("..") follow_speed = 5.0 -[node name="PostProcessing" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/CameraPivot/Camera"] +[node name="PostProcessing" type="MeshInstance3D" parent="Viewport/SubViewport/CameraPivot/Camera"] unique_name_in_owner = true extra_cull_margin = 16384.0 mesh = SubResource("QuadMesh_7yiqd") -[node name="Sun" type="DirectionalLight3D" parent="SubViewportContainer/SubViewport"] -transform = Transform3D(0.984808, 0.122788, -0.122788, 0, 0.707107, 0.707107, 0.173648, -0.696364, 0.696364, 0, 5, 0) +[node name="Sun" type="DirectionalLight3D" parent="Viewport/SubViewport"] +transform = Transform3D(0.984808, 0.122788, -0.122788, 0, 0.707107, 0.707107, 0.173648, -0.696364, 0.696364, 0, 10, 0) shadow_enabled = true directional_shadow_mode = 0 script = ExtResource("5_pf5uw") -[node name="Environment" type="WorldEnvironment" parent="SubViewportContainer/SubViewport"] +[node name="Environment" type="WorldEnvironment" parent="Viewport/SubViewport"] environment = ExtResource("5_bll74") camera_attributes = ExtResource("6_8wfwf") -[node name="World" type="Node3D" parent="SubViewportContainer/SubViewport"] - -[node name="Ground" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.25, 0) -mesh = SubResource("BoxMesh_0bujj") -skeleton = NodePath("../../../..") - -[node name="Ground" type="StaticBody3D" parent="SubViewportContainer/SubViewport/World/Ground"] - -[node name="CollisionShape3D" type="CollisionShape3D" parent="SubViewportContainer/SubViewport/World/Ground/Ground"] -shape = SubResource("BoxShape3D_58ws3") - -[node name="Tree" parent="SubViewportContainer/SubViewport/World" instance=ExtResource("15_csh38")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.11323, 0, -4.64839) - -[node name="Tree2" parent="SubViewportContainer/SubViewport/World" instance=ExtResource("15_csh38")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.11323, 0, 5.35161) - -[node name="Players" type="Node3D" parent="SubViewportContainer/SubViewport"] -unique_name_in_owner = true - -[node name="Enemies" type="Node3D" parent="SubViewportContainer/SubViewport"] - -[node name="Slime" parent="SubViewportContainer/SubViewport/Enemies" instance=ExtResource("16_fuixr")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.53558, 1.28057, -3.79687) - -[node name="Slime2" parent="SubViewportContainer/SubViewport/Enemies" instance=ExtResource("16_fuixr")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.00829, 1.28057, -1.95247) - -[node name="Slime3" parent="SubViewportContainer/SubViewport/Enemies" instance=ExtResource("16_fuixr")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.53558, 1.28057, -0.306177) - -[connection signal="timeout" from="Network/Ping/Timer" to="Network/Ping" method="send_ping"] -[connection signal="timeout" from="Network/Login/Timer" to="Network/Login" method="send_login"] +[connection signal="timeout" from="Client/Ping/Timer" to="Client/Ping" method="send_ping"] +[connection signal="timeout" from="Client/Login/Timer" to="Client/Login" method="send_login"]