diff --git a/client/danmaku!/Board.tscn b/client/danmaku!/Board/Board.tscn similarity index 64% rename from client/danmaku!/Board.tscn rename to client/danmaku!/Board/Board.tscn index 7e92fd5..d1501f6 100644 --- a/client/danmaku!/Board.tscn +++ b/client/danmaku!/Board/Board.tscn @@ -1,9 +1,9 @@ [gd_scene load_steps=5 format=3 uid="uid://dsiowq0rnacln"] -[ext_resource type="PackedScene" uid="uid://qvo806pvgbdn" path="res://danmaku!/Player.tscn" id="1_22cjd"] -[ext_resource type="Script" uid="uid://ggkxv1cb1bjk" path="res://danmaku!/scaling.gd" id="1_o1mqp"] -[ext_resource type="Script" uid="uid://cd67rrch5h4t7" path="res://danmaku!/network_manager.gd" id="2_b2dol"] -[ext_resource type="Script" uid="uid://ddc5iqgtyv2ns" path="res://danmaku!/BulletManager.gd" id="4_ubrrh"] +[ext_resource type="PackedScene" uid="uid://qvo806pvgbdn" path="res://danmaku!/Player/Player.tscn" id="1_22cjd"] +[ext_resource type="Script" uid="uid://ggkxv1cb1bjk" path="res://danmaku!/Board/boardsize_worldscaling.gd" id="1_o1mqp"] +[ext_resource type="Script" uid="uid://6ssjul4hjmot" path="res://danmaku!/Board/world.gd" id="2_jxycg"] +[ext_resource type="Script" uid="uid://ddc5iqgtyv2ns" path="res://danmaku!/Board/bullet_path_manager.gd" id="4_ubrrh"] [node name="Board" type="Control"] custom_minimum_size = Vector2(607.5, 1080) @@ -15,7 +15,7 @@ size_flags_horizontal = 0 size_flags_vertical = 0 script = ExtResource("1_o1mqp") -[node name="ReferenceRect" type="ReferenceRect" parent="."] +[node name="DebugBoardBorder" type="ReferenceRect" parent="."] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -29,20 +29,22 @@ editor_only = false [node name="World" type="Node2D" parent="."] unique_name_in_owner = true scale = Vector2(6.75, 6.75) +script = ExtResource("2_jxycg") + +[node name="BulletPathManager" type="Node2D" parent="World"] +unique_name_in_owner = true +script = ExtResource("4_ubrrh") [node name="Player" parent="World" instance=ExtResource("1_22cjd")] unique_name_in_owner = true -[node name="BulletManager" type="Node2D" parent="World"] -unique_name_in_owner = true -script = ExtResource("4_ubrrh") +[node name="UI" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 -[node name="NetworkManager" type="Node" parent="World" node_paths=PackedStringArray("player")] -unique_name_in_owner = true -script = ExtResource("2_b2dol") -player = NodePath("../Player") - -[node name="GrazeLabel" type="RichTextLabel" parent="."] +[node name="GrazeLabel" type="RichTextLabel" parent="UI"] unique_name_in_owner = true z_index = 5 layout_mode = 1 diff --git a/client/danmaku!/BoardRenderer.tscn b/client/danmaku!/Board/BoardRenderer.tscn similarity index 75% rename from client/danmaku!/BoardRenderer.tscn rename to client/danmaku!/Board/BoardRenderer.tscn index c6f8004..f46f55d 100644 --- a/client/danmaku!/BoardRenderer.tscn +++ b/client/danmaku!/Board/BoardRenderer.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=5 format=3 uid="uid://b1m2pclbncn68"] +[gd_scene load_steps=6 format=3 uid="uid://b1m2pclbncn68"] -[ext_resource type="PackedScene" uid="uid://dsiowq0rnacln" path="res://danmaku!/Board.tscn" id="2_25dpb"] +[ext_resource type="Script" uid="uid://cnon26famcjo8" path="res://danmaku!/Board/board_renderer.gd" id="1_ggtde"] +[ext_resource type="PackedScene" uid="uid://dsiowq0rnacln" path="res://danmaku!/Board/Board.tscn" id="2_25dpb"] [sub_resource type="ViewportTexture" id="ViewportTexture_0pmy2"] viewport_path = NodePath("SubViewport") @@ -16,6 +17,7 @@ material = SubResource("StandardMaterial3D_foys1") size = Vector2(0.563, 1) [node name="BoardRenderer" type="Node3D"] +script = ExtResource("1_ggtde") [node name="BoardMesh" type="MeshInstance3D" parent="."] mesh = SubResource("QuadMesh_txqb1") @@ -26,3 +28,4 @@ handle_input_locally = false size = Vector2i(607, 1080) [node name="Board" parent="SubViewport" instance=ExtResource("2_25dpb")] +unique_name_in_owner = true diff --git a/client/danmaku!/Board/board_renderer.gd b/client/danmaku!/Board/board_renderer.gd new file mode 100644 index 0000000..26d5d73 --- /dev/null +++ b/client/danmaku!/Board/board_renderer.gd @@ -0,0 +1,4 @@ +extends Node3D + +func get_world() -> Node2D: + return %Board.get_world() diff --git a/client/danmaku!/Board/board_renderer.gd.uid b/client/danmaku!/Board/board_renderer.gd.uid new file mode 100644 index 0000000..1b859d4 --- /dev/null +++ b/client/danmaku!/Board/board_renderer.gd.uid @@ -0,0 +1 @@ +uid://cnon26famcjo8 diff --git a/client/danmaku!/scaling.gd b/client/danmaku!/Board/boardsize_worldscaling.gd similarity index 58% rename from client/danmaku!/scaling.gd rename to client/danmaku!/Board/boardsize_worldscaling.gd index 41e8d8a..230d782 100644 --- a/client/danmaku!/scaling.gd +++ b/client/danmaku!/Board/boardsize_worldscaling.gd @@ -1,6 +1,10 @@ @tool extends Control -func _process(delta: float) -> void: +# Maps from world coordinate space to the board size +func _process(_delta: float) -> void: var board_screen_size = self.get_rect() %World.scale = Vector2(board_screen_size.size.x / Globals.SERVER_SIZE.x, board_screen_size.size.y / Globals.SERVER_SIZE.y) + +func get_world() -> Node2D: + return %World diff --git a/client/danmaku!/scaling.gd.uid b/client/danmaku!/Board/boardsize_worldscaling.gd.uid similarity index 100% rename from client/danmaku!/scaling.gd.uid rename to client/danmaku!/Board/boardsize_worldscaling.gd.uid diff --git a/client/danmaku!/BulletManager.gd b/client/danmaku!/Board/bullet_path_manager.gd similarity index 55% rename from client/danmaku!/BulletManager.gd rename to client/danmaku!/Board/bullet_path_manager.gd index c57619f..19fbab7 100644 --- a/client/danmaku!/BulletManager.gd +++ b/client/danmaku!/Board/bullet_path_manager.gd @@ -1,21 +1,22 @@ extends Node2D var bullet_intraframe_mov_delta := 0.0 -var predicted_tick := 0 var bullets = [] func _ready() -> void: child_exiting_tree.connect(_on_child_exiting_tree) -func _process(delta: float) -> void: +func _process(_delta: float) -> void: + bullet_intraframe_mov_delta = LocalTimer.delta_counter / Globals.TICK_TIME + for bullet in bullets: - var prev_pos = bullet.get_current_pos(predicted_tick) - var next_pos = bullet.get_current_pos(predicted_tick + 1) + var prev_pos = bullet.get_current_pos(LocalTimer.predicted_tick) + var next_pos = bullet.get_current_pos(LocalTimer.predicted_tick + 1) var interpolated_pos = prev_pos.lerp(next_pos, bullet_intraframe_mov_delta) bullet.position = interpolated_pos - if bullet.beyond_kill_boundary(predicted_tick): + if bullet.beyond_kill_boundary(LocalTimer.predicted_tick): bullet.queue_free() func _on_child_exiting_tree(node: DanmakuBullet): diff --git a/client/danmaku!/BulletManager.gd.uid b/client/danmaku!/Board/bullet_path_manager.gd.uid similarity index 100% rename from client/danmaku!/BulletManager.gd.uid rename to client/danmaku!/Board/bullet_path_manager.gd.uid diff --git a/client/danmaku!/Board/world.gd b/client/danmaku!/Board/world.gd new file mode 100644 index 0000000..8e5c1d4 --- /dev/null +++ b/client/danmaku!/Board/world.gd @@ -0,0 +1,9 @@ +class_name World +extends Node2D + +@onready var player = %Player +@onready var ui = %GrazeLabel +@onready var bullet_manager = %BulletPathManager + +func set_player_controlled(val: bool): + %Player.controlled = true diff --git a/client/danmaku!/Board/world.gd.uid b/client/danmaku!/Board/world.gd.uid new file mode 100644 index 0000000..25037dc --- /dev/null +++ b/client/danmaku!/Board/world.gd.uid @@ -0,0 +1 @@ +uid://6ssjul4hjmot diff --git a/client/danmaku!/Game.tscn b/client/danmaku!/Game.tscn index 6e000a1..aa90abe 100644 --- a/client/danmaku!/Game.tscn +++ b/client/danmaku!/Game.tscn @@ -1,15 +1,14 @@ [gd_scene load_steps=2 format=3 uid="uid://3a8txh83qfu5"] -[ext_resource type="PackedScene" uid="uid://b1m2pclbncn68" path="res://danmaku!/BoardRenderer.tscn" id="1_pv3ov"] +[ext_resource type="PackedScene" uid="uid://e800nylcbhkx" path="res://danmaku!/Network/network.tscn" id="1_ls1em"] [node name="Game" type="Node"] -[node name="NetworkManager" type="Node" parent="."] +[node name="Network" parent="." node_paths=PackedStringArray("boards") instance=ExtResource("1_ls1em")] +boards = NodePath("../Boards") [node name="Boards" type="Node3D" parent="."] -[node name="PlayerBoard" parent="Boards" instance=ExtResource("1_pv3ov")] - [node name="Camera3D" type="Camera3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.699727) current = true diff --git a/client/danmaku!/Network/Game Modes/battle_royale_server_tick_manager.tscn b/client/danmaku!/Network/Game Modes/battle_royale_server_tick_manager.tscn new file mode 100644 index 0000000..2bfad90 --- /dev/null +++ b/client/danmaku!/Network/Game Modes/battle_royale_server_tick_manager.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://dji2asg6fknhf"] + +[ext_resource type="Script" uid="uid://dum1qusns10yo" path="res://danmaku!/Network/Game Modes/br_server_tick_manager.gd" id="1_h1jsh"] + +[node name="BattleRoyaleServerTickManager" type="Node"] +script = ExtResource("1_h1jsh") diff --git a/client/danmaku!/Network/Game Modes/br_server_tick_manager.gd b/client/danmaku!/Network/Game Modes/br_server_tick_manager.gd new file mode 100644 index 0000000..62f6452 --- /dev/null +++ b/client/danmaku!/Network/Game Modes/br_server_tick_manager.gd @@ -0,0 +1,66 @@ +extends Node + +@export var controlled_world: Node2D +@export var network: Network + +func _ready() -> void: + LocalTimer.next_tick.connect(_broadcast) + LocalTimer.start_ticking() + +func _broadcast() -> void: + if !controlled_world: + return + + var pos = controlled_world.player.position + var json_string = JSON.stringify({"x": pos.x, "y": pos.y}) + network.nakama_socket.send_match_state_async(network.current_match_id, 0, json_string) + +func _on_match_state(p_state : NakamaRTAPI.MatchData): + if !controlled_world: + return + + match p_state.op_code: + 2: + var data = JSON.parse_string(p_state.data) + + # Set player position if server demands a forced position + if data["forcePlayerPos"]: + controlled_world.player.set_position_data( + Vector2( + float(data["playerHitPos"]["x"]), + float(data["playerHitPos"]["y"]) + ), + float(data["playerHitPos"]["radius"]), + float(data["playerGrazePos"]["radius"]) + ) + controlled_world.ui.text = "Graze: " + str(data["graze"]) + + # Handle player death if there is an ongoing death timer + if int(data["deathTimer"]) > 0: + controlled_world.player.kill() + elif int(data["deathTimer"]) == 0: + controlled_world.player.resurrect() + + # Spawn new bullets + for b in data["newBullets"]: + var bullet = DanmakuBullet.new() + bullet.setup_bullet( + int(b["class"]), + int(b["tick"]), + b["x"], + b["y"], + b["radius"], + b["vel_x"], + b["vel_y"]) + bullet.texture = load("res://test-bullet.png") + bullet.position = bullet.get_current_pos(int(b["tick"])) + + # Reimplemented from ScalableSprite2D here atm + var scale_ratio = (b["radius"] * 2) / bullet.texture.get_width() + bullet.scale = Vector2(scale_ratio, scale_ratio) + bullet.z_index = 4 + + controlled_world.bullet_manager.add_child(bullet) + controlled_world.bullet_manager.bullets.append(bullet) + LocalTimer.predicted_tick = int(b["tick"]) + LocalTimer.delta_counter = 0 diff --git a/client/danmaku!/Network/Game Modes/br_server_tick_manager.gd.uid b/client/danmaku!/Network/Game Modes/br_server_tick_manager.gd.uid new file mode 100644 index 0000000..5294293 --- /dev/null +++ b/client/danmaku!/Network/Game Modes/br_server_tick_manager.gd.uid @@ -0,0 +1 @@ +uid://dum1qusns10yo diff --git a/client/danmaku!/Network/network.tscn b/client/danmaku!/Network/network.tscn new file mode 100644 index 0000000..0ac1c0b --- /dev/null +++ b/client/danmaku!/Network/network.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://e800nylcbhkx"] + +[ext_resource type="Script" uid="uid://cy6bf5qqnku6a" path="res://danmaku!/Network/network_state.gd" id="1_vo6kr"] +[ext_resource type="Script" uid="uid://de5tjg0h3aqrn" path="res://danmaku!/Network/session_manager.gd" id="1_wvqc0"] +[ext_resource type="Script" uid="uid://cy8homfyumhf2" path="res://danmaku!/Network/temp_test_match_maker.gd" id="4_ymcg2"] + +[node name="Network" type="Node"] +script = ExtResource("1_vo6kr") + +[node name="SessionManager" type="Node" parent="." node_paths=PackedStringArray("network")] +unique_name_in_owner = true +script = ExtResource("1_wvqc0") +network = NodePath("..") + +[node name="TempTestMatchMaker" type="Node" parent="." node_paths=PackedStringArray("network")] +script = ExtResource("4_ymcg2") +network = NodePath("..") diff --git a/client/danmaku!/Network/network_state.gd b/client/danmaku!/Network/network_state.gd new file mode 100644 index 0000000..72aa2d9 --- /dev/null +++ b/client/danmaku!/Network/network_state.gd @@ -0,0 +1,9 @@ +class_name Network +extends Node + +@export var boards: Node3D + +var nakama_client: NakamaClient +var nakama_session: NakamaSession +var nakama_socket: NakamaSocket +var current_match_id = "" diff --git a/client/danmaku!/Network/network_state.gd.uid b/client/danmaku!/Network/network_state.gd.uid new file mode 100644 index 0000000..2642b1b --- /dev/null +++ b/client/danmaku!/Network/network_state.gd.uid @@ -0,0 +1 @@ +uid://cy6bf5qqnku6a diff --git a/client/danmaku!/Network/session_manager.gd b/client/danmaku!/Network/session_manager.gd new file mode 100644 index 0000000..83167a5 --- /dev/null +++ b/client/danmaku!/Network/session_manager.gd @@ -0,0 +1,24 @@ +extends Node + +signal on_auth_success + +@export var network: Node + +func _ready() -> void: + print("Attempting auth.") + if await auth(): + print("Oh baby we're ready.") + on_auth_success.emit() + else: + print("That is so sad.") + +func auth() -> bool: + network.nakama_client = Nakama.create_client("defaultkey", "127.0.0.1", 7350, "http") + network.nakama_session = await network.nakama_client.authenticate_device_async(OS.get_unique_id()) + network.nakama_socket = Nakama.create_socket_from(network.nakama_client) + + var connected: NakamaAsyncResult = await network.nakama_socket.connect_async(network.nakama_session) + if connected.is_exception(): + print("An error occured when creating nakama socket: %s" % connected) + return false + return true diff --git a/client/danmaku!/Network/session_manager.gd.uid b/client/danmaku!/Network/session_manager.gd.uid new file mode 100644 index 0000000..dc07a05 --- /dev/null +++ b/client/danmaku!/Network/session_manager.gd.uid @@ -0,0 +1 @@ +uid://de5tjg0h3aqrn diff --git a/client/danmaku!/Network/temp_test_match_maker.gd b/client/danmaku!/Network/temp_test_match_maker.gd new file mode 100644 index 0000000..4956300 --- /dev/null +++ b/client/danmaku!/Network/temp_test_match_maker.gd @@ -0,0 +1,39 @@ +extends Node + +@export var network: Node + +var br_gamemode_manager = preload("res://danmaku!/Network/Game Modes/battle_royale_server_tick_manager.tscn") +var board = preload("res://danmaku!/Board/BoardRenderer.tscn") + +@onready var player_board = board.instantiate() +var player_world: Node2D + +func _ready() -> void: + player_world = player_board.get_world() + player_world.set_player_controlled(true) + %SessionManager.on_auth_success.connect(_make_br_match_post_auth_success) + network.boards.add_child(player_board) + +func _make_br_match_post_auth_success() -> void: + print("Attempting to create debug match.") + await create_and_join_debug_match() + var tick_manager = br_gamemode_manager.instantiate() + tick_manager.controlled_world = player_world + tick_manager.network = network + network.add_child(tick_manager) + network.nakama_socket.received_match_state.connect(tick_manager._on_match_state) + +func create_and_join_debug_match() -> void: + var response: NakamaAPI.ApiRpc = await network.nakama_client.rpc_async(network.nakama_session, "manual_force_create_br_match_rpc") + + if response.is_exception(): + print("An error occurred when calling manual_force_create_br_match_rpc: %s" % response) + return + + var debug_br_match: NakamaRTAPI.Match = await network.nakama_socket.join_match_async(response.payload) + + if debug_br_match.is_exception(): + print("An error occurred when joining debug BR match: %s" % response) + return + else: + network.current_match_id = response.payload diff --git a/client/danmaku!/Network/temp_test_match_maker.gd.uid b/client/danmaku!/Network/temp_test_match_maker.gd.uid new file mode 100644 index 0000000..672f18c --- /dev/null +++ b/client/danmaku!/Network/temp_test_match_maker.gd.uid @@ -0,0 +1 @@ +uid://cy8homfyumhf2 diff --git a/client/danmaku!/player.tscn b/client/danmaku!/Player/Player.tscn similarity index 92% rename from client/danmaku!/player.tscn rename to client/danmaku!/Player/Player.tscn index df6b685..faae785 100644 --- a/client/danmaku!/player.tscn +++ b/client/danmaku!/Player/Player.tscn @@ -1,9 +1,9 @@ [gd_scene load_steps=7 format=3 uid="uid://qvo806pvgbdn"] -[ext_resource type="Script" uid="uid://bhwiun72wpk6e" path="res://danmaku!/player.gd" id="1_r7xhp"] +[ext_resource type="Script" uid="uid://bhwiun72wpk6e" path="res://danmaku!/Player/player.gd" id="1_r7xhp"] [ext_resource type="Texture2D" uid="uid://bs3fntlmlqpt2" path="res://icon.svg" id="2_04s0l"] [ext_resource type="Texture2D" uid="uid://c3deywcu4du2b" path="res://test-collision.png" id="3_gf44i"] -[ext_resource type="Script" uid="uid://v6jris184o8u" path="res://danmaku!/ScalableSprite2D.gd" id="3_u0x7w"] +[ext_resource type="Script" uid="uid://v6jris184o8u" path="res://danmaku!/Utils/ScalableSprite2D.gd" id="3_u0x7w"] [ext_resource type="Texture2D" uid="uid://brcxly3s7d1jt" path="res://test-graze.png" id="5_273wv"] [ext_resource type="AudioStream" uid="uid://c5n7x6q67tp78" path="res://test-death-noise.mp3" id="5_poktv"] diff --git a/client/danmaku!/player.gd b/client/danmaku!/Player/player.gd similarity index 97% rename from client/danmaku!/player.gd rename to client/danmaku!/Player/player.gd index 704f239..88b534f 100644 --- a/client/danmaku!/player.gd +++ b/client/danmaku!/Player/player.gd @@ -2,6 +2,7 @@ class_name Player extends Node2D @export var speed = 80 +@export var controlled = false var velocity := Vector2.ZERO var hurt_collision: DanmakuCircle = DanmakuCircle.new() var graze_collision: DanmakuCircle = DanmakuCircle.new() diff --git a/client/danmaku!/player.gd.uid b/client/danmaku!/Player/player.gd.uid similarity index 100% rename from client/danmaku!/player.gd.uid rename to client/danmaku!/Player/player.gd.uid diff --git a/client/danmaku!/Utils/LocalTimer.tscn b/client/danmaku!/Utils/LocalTimer.tscn new file mode 100644 index 0000000..21b62df --- /dev/null +++ b/client/danmaku!/Utils/LocalTimer.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://d4dt7b4ewhl7u"] + +[ext_resource type="Script" uid="uid://dkv6vrgslqjvx" path="res://danmaku!/Utils/client_timer.gd" id="1_wgxit"] + +[node name="LocalTimer" type="Node"] +script = ExtResource("1_wgxit") diff --git a/client/danmaku!/ScalableSprite2D.gd b/client/danmaku!/Utils/ScalableSprite2D.gd similarity index 100% rename from client/danmaku!/ScalableSprite2D.gd rename to client/danmaku!/Utils/ScalableSprite2D.gd diff --git a/client/danmaku!/ScalableSprite2D.gd.uid b/client/danmaku!/Utils/ScalableSprite2D.gd.uid similarity index 100% rename from client/danmaku!/ScalableSprite2D.gd.uid rename to client/danmaku!/Utils/ScalableSprite2D.gd.uid diff --git a/client/danmaku!/Utils/client_timer.gd b/client/danmaku!/Utils/client_timer.gd new file mode 100644 index 0000000..fb29bb9 --- /dev/null +++ b/client/danmaku!/Utils/client_timer.gd @@ -0,0 +1,28 @@ +extends Node + +var predicted_tick := 0 +var delta_counter := 0.0 +var ticking := false + +signal next_tick + +func _process(delta) -> void: + if ticking == true: + predict_tick(delta) + +func predict_tick(delta) -> void: + delta_counter += delta + + if delta_counter >= Globals.TICK_TIME: + predicted_tick += 1 + delta_counter -= Globals.TICK_TIME + next_tick.emit() + +func set_tick_timer_state(new_tick_val) -> void: + predicted_tick = new_tick_val + delta_counter = 0 + +func start_ticking(): + predicted_tick = 0 + delta_counter = 0 + ticking = true diff --git a/client/danmaku!/Utils/client_timer.gd.uid b/client/danmaku!/Utils/client_timer.gd.uid new file mode 100644 index 0000000..8ceb038 --- /dev/null +++ b/client/danmaku!/Utils/client_timer.gd.uid @@ -0,0 +1 @@ +uid://dkv6vrgslqjvx diff --git a/client/danmaku!/globals.gd b/client/danmaku!/Utils/globals.gd similarity index 65% rename from client/danmaku!/globals.gd rename to client/danmaku!/Utils/globals.gd index e23bf41..41091d0 100644 --- a/client/danmaku!/globals.gd +++ b/client/danmaku!/Utils/globals.gd @@ -1,2 +1,3 @@ class_name Globals const SERVER_SIZE = Vector2(90.0, 160.0) +const TICK_TIME = 0.01666666666 diff --git a/client/danmaku!/globals.gd.uid b/client/danmaku!/Utils/globals.gd.uid similarity index 100% rename from client/danmaku!/globals.gd.uid rename to client/danmaku!/Utils/globals.gd.uid diff --git a/client/danmaku!/network_manager.gd b/client/danmaku!/network_manager.gd deleted file mode 100644 index 5524f1a..0000000 --- a/client/danmaku!/network_manager.gd +++ /dev/null @@ -1,110 +0,0 @@ -extends Node -var nakama_client: NakamaClient -var nakama_session: NakamaSession -var nakama_socket: NakamaSocket - -@export var player: Player - -var predicted_tick = 0 -var delta_counter = 0 -var current_match_id = "" - -func _ready() -> void: - print("Attempting auth.") - await attempt_auth() - print("Attempting to create debug match.") - await create_and_join_debug_match() - nakama_socket.received_match_state.connect(self._on_match_state) - -func _process(delta: float) -> void: - if current_match_id == "": - return - - %BulletManager.bullet_intraframe_mov_delta = predict_tick_and_broadcast(delta) - %BulletManager.predicted_tick = predicted_tick - -func _on_match_state(p_state : NakamaRTAPI.MatchData): - match p_state.op_code: - 2: - var data = JSON.parse_string(p_state.data) - - # Set player position if server demands a forced position - if data["forcePlayerPos"]: - player.set_position_data( - Vector2( - float(data["playerHitPos"]["x"]), - float(data["playerHitPos"]["y"]) - ), - float(data["playerHitPos"]["radius"]), - float(data["playerGrazePos"]["radius"]) - ) - %GrazeLabel.text = "Graze: " + str(data["graze"]) - - # Handle player death if there is an ongoing death timer - if int(data["deathTimer"]) > 0: - %Player.kill() - elif int(data["deathTimer"]) == 0: - %Player.resurrect() - - # Spawn new bullets - for b in data["newBullets"]: - var bullet = DanmakuBullet.new() - bullet.setup_bullet( - int(b["class"]), - int(b["tick"]), - b["x"], - b["y"], - b["radius"], - b["vel_x"], - b["vel_y"]) - bullet.texture = load("res://test-bullet.png") - bullet.position = bullet.get_current_pos(int(b["tick"])) - - # Reimplemented from ScalableSprite2D here atm - var scale_ratio = (b["radius"] * 2) / bullet.texture.get_width() - bullet.scale = Vector2(scale_ratio, scale_ratio) - bullet.z_index = 4 - - %BulletManager.add_child(bullet) - %BulletManager.bullets.append(bullet) - predicted_tick = int(b["tick"]) - delta_counter = 0 - -func attempt_auth() -> void: - nakama_client = Nakama.create_client("defaultkey", "127.0.0.1", 7350, "http") - nakama_session = await nakama_client.authenticate_device_async(OS.get_unique_id()) - nakama_socket = Nakama.create_socket_from(nakama_client) - - var connected: NakamaAsyncResult = await nakama_socket.connect_async(nakama_session) - if connected.is_exception(): - print("An error occured when creating nakama socket: %s" % connected) - return - print("Oh baby we're ready.") - -func create_and_join_debug_match() -> void: - var response: NakamaAPI.ApiRpc = await nakama_client.rpc_async(nakama_session, "manual_force_create_br_match_rpc") - - if response.is_exception(): - print("An error occurred when calling manual_force_create_br_match_rpc: %s" % response) - return - - var debug_br_match: NakamaRTAPI.Match = await nakama_socket.join_match_async(response.payload) - - if debug_br_match.is_exception(): - print("An error occurred when joining debug BR match: %s" % response) - return - else: - current_match_id = response.payload - -func predict_tick_and_broadcast(delta) -> float: - delta_counter += delta - - # New tick (60 tick rate), broadcast player inputs - var tick_time = 0.01666666666 - if delta_counter >= tick_time: - predicted_tick += 1 - delta_counter -= tick_time - var pos = %Player.position - var json_string = JSON.stringify({"x": pos.x, "y": pos.y}) - nakama_socket.send_match_state_async(current_match_id, 0, json_string) - return delta_counter / tick_time diff --git a/client/danmaku!/network_manager.gd.uid b/client/danmaku!/network_manager.gd.uid deleted file mode 100644 index 8d9b13d..0000000 --- a/client/danmaku!/network_manager.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cd67rrch5h4t7 diff --git a/client/project.godot b/client/project.godot index 07dd999..ff6862f 100644 --- a/client/project.godot +++ b/client/project.godot @@ -18,6 +18,7 @@ config/icon="res://icon.svg" [autoload] Nakama="*res://addons/com.heroiclabs.nakama/Nakama.gd" +LocalTimer="*res://danmaku!/Utils/LocalTimer.tscn" [display]