├── Godot4MultiplayerMVPClient
├── .godot
│ ├── .gdignore
│ ├── editor
│ │ ├── favorites.Node
│ │ ├── recent_dirs
│ │ ├── create_recent.Node
│ │ ├── filesystem_update4
│ │ ├── NetworkingClient.gd-folding-2b49d5740c9df0058e75f7de6fc91fed.cfg
│ │ ├── NetworkingClient.tscn-folding-db6bc7cdfc97dc30471557a80338ec26.cfg
│ │ ├── script_editor_cache.cfg
│ │ ├── filesystem_cache8
│ │ ├── project_metadata.cfg
│ │ ├── editor_layout.cfg
│ │ └── NetworkingClient.tscn-editstate-db6bc7cdfc97dc30471557a80338ec26.cfg
│ ├── global_script_class_cache.cfg
│ ├── uid_cache.bin
│ └── imported
│ │ ├── icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5
│ │ └── icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex
├── project.godot
├── NetworkingClient.tscn
├── icon.svg.import
├── NetworkingClient.gd
└── icon.svg
├── Godot4MultiplayerMVPServer
├── .godot
│ ├── .gdignore
│ ├── editor
│ │ ├── favorites
│ │ ├── favorites.Node
│ │ ├── recent_dirs
│ │ ├── create_recent.Node
│ │ ├── Server.gd-folding-2b2621a7b090c62b8f0ac723b752e775.cfg
│ │ ├── filesystem_update4
│ │ ├── NetworkingServer.gd-folding-3fd6ff85ef556bad8ca8fdf00b6645d4.cfg
│ │ ├── server.tscn-folding-c89a2950482f3a432bab03a0591e8d28.cfg
│ │ ├── NetworkingServer.tscn-folding-67ca15145d9bad4a4322ef1520d60e36.cfg
│ │ ├── script_editor_cache.cfg
│ │ ├── filesystem_cache8
│ │ ├── project_metadata.cfg
│ │ ├── editor_layout.cfg
│ │ ├── server.tscn-editstate-c89a2950482f3a432bab03a0591e8d28.cfg
│ │ └── NetworkingServer.tscn-editstate-67ca15145d9bad4a4322ef1520d60e36.cfg
│ ├── global_script_class_cache.cfg
│ ├── uid_cache.bin
│ └── imported
│ │ ├── icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5
│ │ └── icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex
├── NetworkingServer.tscn
├── project.godot
├── icon.svg.import
├── NetworkingServer.gd
└── icon.svg
├── .gitignore
├── README.md
└── LICENSE
/Godot4MultiplayerMVPClient/.godot/.gdignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/.gdignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/favorites:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/favorites.Node:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/favorites.Node:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/recent_dirs:
--------------------------------------------------------------------------------
1 | res://
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/recent_dirs:
--------------------------------------------------------------------------------
1 | res://
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/create_recent.Node:
--------------------------------------------------------------------------------
1 | Node
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/global_script_class_cache.cfg:
--------------------------------------------------------------------------------
1 | list=[]
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/global_script_class_cache.cfg:
--------------------------------------------------------------------------------
1 | list=[]
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/create_recent.Node:
--------------------------------------------------------------------------------
1 | Button
2 | Node2D
3 | Node
4 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/filesystem_update4:
--------------------------------------------------------------------------------
1 | res://NetworkingClient.tscn
2 | res://NetworkingClient.gd
3 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/Server.gd-folding-2b2621a7b090c62b8f0ac723b752e775.cfg:
--------------------------------------------------------------------------------
1 | [folding]
2 |
3 | sections_unfolded=PackedStringArray()
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Godot-specific ignores
3 | .import/
4 | export.cfg
5 | export_presets.cfg
6 |
7 | # Mono-specific ignores
8 | .mono/
9 | data_*/
10 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/uid_cache.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zwometer/Godot4MultiplayerMVP/HEAD/Godot4MultiplayerMVPClient/.godot/uid_cache.bin
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/filesystem_update4:
--------------------------------------------------------------------------------
1 | res://Server.gd
2 | res://server.tscn
3 | res://NetworkingServer.tscn
4 | res://NetworkingServer.gd
5 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/uid_cache.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zwometer/Godot4MultiplayerMVP/HEAD/Godot4MultiplayerMVPServer/.godot/uid_cache.bin
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/NetworkingClient.gd-folding-2b49d5740c9df0058e75f7de6fc91fed.cfg:
--------------------------------------------------------------------------------
1 | [folding]
2 |
3 | sections_unfolded=PackedStringArray()
4 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/NetworkingServer.gd-folding-3fd6ff85ef556bad8ca8fdf00b6645d4.cfg:
--------------------------------------------------------------------------------
1 | [folding]
2 |
3 | sections_unfolded=PackedStringArray()
4 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/server.tscn-folding-c89a2950482f3a432bab03a0591e8d28.cfg:
--------------------------------------------------------------------------------
1 | [folding]
2 |
3 | node_unfolds=[]
4 | resource_unfolds=[]
5 | nodes_folded=[]
6 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/NetworkingClient.tscn-folding-db6bc7cdfc97dc30471557a80338ec26.cfg:
--------------------------------------------------------------------------------
1 | [folding]
2 |
3 | node_unfolds=[]
4 | resource_unfolds=[]
5 | nodes_folded=[]
6 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5:
--------------------------------------------------------------------------------
1 | source_md5="5ddad973d6395e772f8dfeaeed15f0a0"
2 | dest_md5="070132ccfe7233bfc44d6742a65b3739"
3 |
4 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/NetworkingServer.tscn-folding-67ca15145d9bad4a4322ef1520d60e36.cfg:
--------------------------------------------------------------------------------
1 | [folding]
2 |
3 | node_unfolds=[]
4 | resource_unfolds=[]
5 | nodes_folded=[]
6 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5:
--------------------------------------------------------------------------------
1 | source_md5="5ddad973d6395e772f8dfeaeed15f0a0"
2 | dest_md5="070132ccfe7233bfc44d6742a65b3739"
3 |
4 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zwometer/Godot4MultiplayerMVP/HEAD/Godot4MultiplayerMVPClient/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zwometer/Godot4MultiplayerMVP/HEAD/Godot4MultiplayerMVPServer/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/NetworkingServer.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://c5c1usc5scxln"]
2 |
3 | [ext_resource type="Script" path="res://NetworkingServer.gd" id="1_acvag"]
4 |
5 | [node name="Networking" type="Node"]
6 | script = ExtResource("1_acvag")
7 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/script_editor_cache.cfg:
--------------------------------------------------------------------------------
1 | [res://NetworkingServer.gd]
2 |
3 | state={
4 | "bookmarks": PackedInt32Array(),
5 | "breakpoints": PackedInt32Array(),
6 | "column": 34,
7 | "folded_lines": [],
8 | "h_scroll_position": 0,
9 | "row": 5,
10 | "scroll_position": 0.0,
11 | "selection": false,
12 | "syntax_highlighter": "GDScript"
13 | }
14 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/script_editor_cache.cfg:
--------------------------------------------------------------------------------
1 | [res://NetworkingClient.gd]
2 |
3 | state={
4 | "bookmarks": PackedInt32Array(),
5 | "breakpoints": PackedInt32Array(),
6 | "column": 36,
7 | "folded_lines": [],
8 | "h_scroll_position": 0,
9 | "row": 44,
10 | "scroll_position": 16.0,
11 | "selection": false,
12 | "syntax_highlighter": "GDScript"
13 | }
14 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/filesystem_cache8:
--------------------------------------------------------------------------------
1 | 0b7126e0c6e86d3ec295a72f5aa6e0bd
2 | ::res://::1674841528
3 | icon.svg::CompressedTexture2D::4915867829030184995::1674833617::1674833621::1::::<><>::
4 | NetworkingServer.gd::GDScript::-1::1674841450::0::1::::<>Node<>::
5 | server.tscn::PackedScene::6884250739622452943::1674841528::0::1::::<><>::res://NetworkingServer.gd
6 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/filesystem_cache8:
--------------------------------------------------------------------------------
1 | 0b7126e0c6e86d3ec295a72f5aa6e0bd
2 | ::res://::1675057476
3 | icon.svg::CompressedTexture2D::6373733551754743652::1674840975::1674840979::1::::<><>::
4 | NetworkingClient.gd::GDScript::-1::1674845757::0::1::::<>Node<>::
5 | NetworkingClient.tscn::PackedScene::656575761024644187::1674848215::0::1::::<><>::res://NetworkingClient.gd
6 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/project_metadata.cfg:
--------------------------------------------------------------------------------
1 | [editor_metadata]
2 |
3 | executable_path="C:/Progs/Dropbox/Torben-JP/Godot/Godot_v4.0-beta15_win64.exe"
4 |
5 | [debug_options]
6 |
7 | run_live_debug=true
8 | run_reload_scripts=true
9 |
10 | [script_setup]
11 |
12 | last_selected_language="GDScript"
13 |
14 | [recent_files]
15 |
16 | scripts=["Node", "SceneTree", "MultiplayerAPI", "Array", "MultiplayerPeer", "res://Server.gd"]
17 | scenes=["res://server.tscn"]
18 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/project_metadata.cfg:
--------------------------------------------------------------------------------
1 | [editor_metadata]
2 |
3 | executable_path="C:/Progs/Dropbox/Torben-JP/Godot/Godot_v4.0-beta16_win64.exe"
4 | use_advanced_connections=false
5 |
6 | [debug_options]
7 |
8 | run_live_debug=true
9 | run_reload_scripts=true
10 |
11 | [recent_files]
12 |
13 | scenes=["res://NetworkingClient.tscn"]
14 | scripts=["@GDScript", "MultiplayerPeer", "Object", "res://NetworkingClient.gd"]
15 |
16 | [script_setup]
17 |
18 | last_selected_language="GDScript"
19 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="Godot 4 Multiplayer Client"
14 | run/main_scene="res://NetworkingClient.tscn"
15 | config/features=PackedStringArray("4.0", "GL Compatibility")
16 | config/icon="res://icon.svg"
17 |
18 | [rendering]
19 |
20 | renderer/rendering_method="gl_compatibility"
21 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="Godot 4 Multiplayer Server"
14 | run/main_scene="res://NetworkingServer.tscn"
15 | config/features=PackedStringArray("4.0", "GL Compatibility")
16 | config/icon="res://icon.svg"
17 |
18 | [rendering]
19 |
20 | renderer/rendering_method="gl_compatibility"
21 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/editor_layout.cfg:
--------------------------------------------------------------------------------
1 | [docks]
2 |
3 | dock_filesystem_split=0
4 | dock_filesystem_display_mode=0
5 | dock_filesystem_file_sort=0
6 | dock_filesystem_file_list_display_mode=1
7 | dock_split_2=0
8 | dock_split_3=0
9 | dock_hsplit_1=0
10 | dock_hsplit_2=270
11 | dock_hsplit_3=-270
12 | dock_hsplit_4=0
13 | dock_3="Scene,Import"
14 | dock_4="FileSystem"
15 | dock_5="Inspector,Node,History"
16 |
17 | [EditorNode]
18 |
19 | open_scenes=["res://NetworkingClient.tscn"]
20 |
21 | [ScriptEditor]
22 |
23 | open_scripts=["res://NetworkingClient.gd"]
24 | open_help=[]
25 | script_split_offset=70
26 | list_split_offset=0
27 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/editor_layout.cfg:
--------------------------------------------------------------------------------
1 | [docks]
2 |
3 | dock_filesystem_split=0
4 | dock_filesystem_display_mode=0
5 | dock_filesystem_file_sort=0
6 | dock_filesystem_file_list_display_mode=1
7 | dock_split_2=0
8 | dock_split_3=0
9 | dock_hsplit_1=0
10 | dock_hsplit_2=270
11 | dock_hsplit_3=-270
12 | dock_hsplit_4=0
13 | dock_3="Scene,Import"
14 | dock_4="FileSystem"
15 | dock_5="Inspector,Node,History"
16 |
17 | [EditorNode]
18 |
19 | open_scenes=["res://NetworkingServer.tscn"]
20 |
21 | [ScriptEditor]
22 |
23 | open_scripts=["res://NetworkingServer.gd"]
24 | open_help=["Array", "MultiplayerAPI", "MultiplayerPeer"]
25 | script_split_offset=70
26 | list_split_offset=0
27 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/NetworkingClient.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://jmbybekwvead"]
2 |
3 | [ext_resource type="Script" path="res://NetworkingClient.gd" id="1_rlsr6"]
4 |
5 | [node name="Networking" type="Node"]
6 | script = ExtResource("1_rlsr6")
7 |
8 | [node name="Lobby" type="Node2D" parent="."]
9 |
10 | [node name="ConnectBtn" type="Button" parent="Lobby"]
11 | offset_left = 437.0
12 | offset_top = 166.0
13 | offset_right = 619.0
14 | offset_bottom = 243.0
15 | text = "Connect"
16 |
17 | [node name="DisconnectBtn" type="Button" parent="Lobby"]
18 | offset_left = 437.0
19 | offset_top = 261.0
20 | offset_right = 619.0
21 | offset_bottom = 338.0
22 | text = "Disconnect"
23 |
24 | [connection signal="pressed" from="Lobby/ConnectBtn" to="." method="_on_connect_btn_pressed"]
25 | [connection signal="pressed" from="Lobby/DisconnectBtn" to="." method="_on_disconnect_btn_pressed"]
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Godot4MultiplayerMVP
2 | A minimal working prototype for Godot 4 multiplayer using ENetMultiplayerPeer.
3 |
4 | This project is using a separate client and server.
5 | There is no implementation of player characters, names, or other things. Only setting up the connection and syncing the player list.
6 |
7 | ## Server Output
8 | 
9 | ## Client Output
10 | 
11 | ## Client UI
12 | 
13 |
14 |
15 |
16 |
17 |
18 |
19 | Resources I used:
20 | - https://godotengine.org/article/multiplayer-changes-godot-4-0-report-2/
21 | - https://github.com/TheGodojo/Godot-4-Networking-Demonstration-Complete/
22 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cw2qpwg50jusy"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/lossy_quality=0.7
20 | compress/hdr_compression=1
21 | compress/bptc_ldr=0
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/icon.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://ccbjvioeil0v4"
6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.svg"
14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/lossy_quality=0.7
20 | compress/hdr_compression=1
21 | compress/bptc_ldr=0
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 zwometer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/NetworkingClient.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | const DEV = true
4 |
5 | @onready var connect_btn = $Lobby/ConnectBtn
6 | @onready var disconnect_btn = $Lobby/DisconnectBtn
7 |
8 | var multiplayer_peer = ENetMultiplayerPeer.new()
9 | var url : String = "your-prod.url"
10 | const PORT = 9009
11 |
12 | var connected_peer_ids = []
13 |
14 |
15 | func _ready():
16 | if DEV == true:
17 | url = "127.0.0.1"
18 | update_connection_buttons()
19 | multiplayer.server_disconnected.connect(_on_server_disconnected)
20 |
21 | @rpc
22 | func sync_player_list(updated_connected_peer_ids):
23 | connected_peer_ids = updated_connected_peer_ids
24 | multiplayer_peer.get_unique_id()
25 | update_connection_buttons()
26 | print("Currently connected Players: " + str(connected_peer_ids))
27 |
28 |
29 | func _on_connect_btn_pressed() -> void:
30 | print("Connecting ...")
31 | multiplayer_peer.create_client(url, PORT)
32 | multiplayer.multiplayer_peer = multiplayer_peer
33 | update_connection_buttons()
34 |
35 |
36 | func _on_disconnect_btn_pressed():
37 | multiplayer_peer.close()
38 | update_connection_buttons()
39 | print("Disconnected.")
40 |
41 |
42 | func _on_server_disconnected():
43 | multiplayer_peer.close()
44 | update_connection_buttons()
45 | print("Connection to server lost.")
46 |
47 |
48 | func update_connection_buttons() -> void:
49 | if multiplayer_peer.get_connection_status() == multiplayer_peer.CONNECTION_DISCONNECTED:
50 | connect_btn.disabled = false
51 | disconnect_btn.disabled = true
52 | if multiplayer_peer.get_connection_status() == multiplayer_peer.CONNECTION_CONNECTING:
53 | connect_btn.disabled = true
54 | disconnect_btn.disabled = true
55 | if multiplayer_peer.get_connection_status() == multiplayer_peer.CONNECTION_CONNECTED:
56 | connect_btn.disabled = true
57 | disconnect_btn.disabled = false
58 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/NetworkingServer.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | const DEV = true
4 |
5 | var multiplayer_peer = ENetMultiplayerPeer.new()
6 | var url : String = "your-prod.url"
7 | const PORT = 9009
8 |
9 | var connected_peer_ids = []
10 |
11 |
12 | func _ready():
13 | if DEV == true:
14 | url = "127.0.0.1"
15 | multiplayer_peer.create_server(PORT)
16 | multiplayer.multiplayer_peer = multiplayer_peer
17 | multiplayer_peer.peer_connected.connect(_on_peer_connected)
18 | multiplayer_peer.peer_disconnected.connect(_on_peer_disconnected)
19 | print("Server is up and running.")
20 |
21 |
22 | func _on_peer_connected(new_peer_id : int) -> void:
23 | print("Player " + str(new_peer_id) + " is joining...")
24 | # The connect signal fires before the client is added to the connected
25 | # clients in multiplayer.get_peers(), so we wait for a moment.
26 | await get_tree().create_timer(1).timeout
27 | add_player(new_peer_id)
28 |
29 |
30 | func add_player(new_peer_id : int) -> void:
31 | connected_peer_ids.append(new_peer_id)
32 | print("Player " + str(new_peer_id) + " joined.")
33 | print("Currently connected Players: " + str(connected_peer_ids))
34 | rpc("sync_player_list", connected_peer_ids)
35 |
36 |
37 | func _on_peer_disconnected(leaving_peer_id : int) -> void:
38 | # The disconnect signal fires before the client is removed from the connected
39 | # clients in multiplayer.get_peers(), so we wait for a moment.
40 | await get_tree().create_timer(1).timeout
41 | remove_player(leaving_peer_id)
42 |
43 |
44 | func remove_player(leaving_peer_id : int) -> void:
45 | var peer_idx_in_peer_list : int = connected_peer_ids.find(leaving_peer_id)
46 | if peer_idx_in_peer_list != -1:
47 | connected_peer_ids.remove_at(peer_idx_in_peer_list)
48 | print("Player " + str(leaving_peer_id) + " disconnected.")
49 | rpc("sync_player_list", connected_peer_ids)
50 |
51 |
52 | @rpc
53 | func sync_player_list(_updated_connected_peer_ids):
54 | pass # only implemented in client (but still has to exist here)
55 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/server.tscn-editstate-c89a2950482f3a432bab03a0591e8d28.cfg:
--------------------------------------------------------------------------------
1 | [editor_states]
2 |
3 | Anim={
4 | "visible": false
5 | }
6 | 2D={
7 | "grid_offset": Vector2(0, 0),
8 | "grid_snap_active": false,
9 | "grid_step": Vector2(8, 8),
10 | "grid_visibility": 1,
11 | "ofs": Vector2(-165, -110),
12 | "primary_grid_steps": 8,
13 | "show_edit_locks": true,
14 | "show_guides": true,
15 | "show_helpers": false,
16 | "show_origin": true,
17 | "show_rulers": true,
18 | "show_transformation_gizmos": true,
19 | "show_viewport": true,
20 | "show_zoom_control": true,
21 | "smart_snap_active": false,
22 | "snap_guides": true,
23 | "snap_node_anchors": true,
24 | "snap_node_center": true,
25 | "snap_node_parent": true,
26 | "snap_node_sides": true,
27 | "snap_other_nodes": true,
28 | "snap_pixel": true,
29 | "snap_relative": false,
30 | "snap_rotation": false,
31 | "snap_rotation_offset": 0.0,
32 | "snap_rotation_step": 0.261799,
33 | "snap_scale": false,
34 | "snap_scale_step": 0.1,
35 | "zoom": 1.0
36 | }
37 | 3D={
38 | "fov": 70.01,
39 | "gizmos_status": {
40 | "AudioListener3D": 0,
41 | "AudioStreamPlayer3D": 0,
42 | "CPUParticles3D": 0,
43 | "CSGShape3D": 0,
44 | "Camera3D": 0,
45 | "CollisionObject3D": 0,
46 | "CollisionPolygon3D": 0,
47 | "CollisionShape3D": 0,
48 | "Decal": 0,
49 | "FogVolume": 0,
50 | "GPUParticles3D": 0,
51 | "GPUParticlesCollision3D": 0,
52 | "Joint3D": 0,
53 | "Light3D": 0,
54 | "LightmapGI": 0,
55 | "LightmapProbe": 0,
56 | "Marker3D": 0,
57 | "NavigationLink3D": 0,
58 | "NavigationRegion3D": 0,
59 | "OccluderInstance3D": 0,
60 | "Path3D": 0,
61 | "PhysicalBone3D": 0,
62 | "RayCast3D": 0,
63 | "ReflectionProbe": 0,
64 | "ShapeCast3D": 0,
65 | "Skeleton3D": 0,
66 | "SoftBody3D": 0,
67 | "SpringArm3D": 0,
68 | "VehicleWheel3D": 0,
69 | "VisibleOnScreenNotifier3D": 0,
70 | "VoxelGI": 0
71 | },
72 | "local_coords": false,
73 | "preview_sun_env": {
74 | "environ_ao_enabled": false,
75 | "environ_enabled": true,
76 | "environ_energy": 1.0,
77 | "environ_gi_enabled": false,
78 | "environ_glow_enabled": true,
79 | "environ_ground_color": Color(0.2, 0.169, 0.133, 1),
80 | "environ_sky_color": Color(0.385, 0.454, 0.55, 1),
81 | "environ_tonemap_enabled": true,
82 | "sun_color": Color(1, 1, 1, 1),
83 | "sun_enabled": true,
84 | "sun_energy": 1.0,
85 | "sun_max_distance": 100.0,
86 | "sun_rotation": Vector2(-1.0472, 2.61799)
87 | },
88 | "rotate_snap": 15.0,
89 | "scale_snap": 10.0,
90 | "show_grid": true,
91 | "show_origin": true,
92 | "snap_enabled": false,
93 | "translate_snap": 1.0,
94 | "viewport_mode": 1,
95 | "viewports": [{
96 | "auto_orthogonal": false,
97 | "auto_orthogonal_enabled": true,
98 | "cinematic_preview": false,
99 | "display_mode": 20,
100 | "distance": 4.0,
101 | "doppler": false,
102 | "frame_time": false,
103 | "gizmos": true,
104 | "half_res": false,
105 | "information": false,
106 | "listener": true,
107 | "position": Vector3(0, 0, 0),
108 | "use_environment": false,
109 | "use_orthogonal": false,
110 | "view_type": 0,
111 | "x_rotation": 0.5,
112 | "y_rotation": -0.5
113 | }, {
114 | "auto_orthogonal": false,
115 | "auto_orthogonal_enabled": true,
116 | "cinematic_preview": false,
117 | "display_mode": 20,
118 | "distance": 4.0,
119 | "doppler": false,
120 | "frame_time": false,
121 | "gizmos": true,
122 | "half_res": false,
123 | "information": false,
124 | "listener": false,
125 | "position": Vector3(0, 0, 0),
126 | "use_environment": false,
127 | "use_orthogonal": false,
128 | "view_type": 0,
129 | "x_rotation": 0.5,
130 | "y_rotation": -0.5
131 | }, {
132 | "auto_orthogonal": false,
133 | "auto_orthogonal_enabled": true,
134 | "cinematic_preview": false,
135 | "display_mode": 20,
136 | "distance": 4.0,
137 | "doppler": false,
138 | "frame_time": false,
139 | "gizmos": true,
140 | "half_res": false,
141 | "information": false,
142 | "listener": false,
143 | "position": Vector3(0, 0, 0),
144 | "use_environment": false,
145 | "use_orthogonal": false,
146 | "view_type": 0,
147 | "x_rotation": 0.5,
148 | "y_rotation": -0.5
149 | }, {
150 | "auto_orthogonal": false,
151 | "auto_orthogonal_enabled": true,
152 | "cinematic_preview": false,
153 | "display_mode": 20,
154 | "distance": 4.0,
155 | "doppler": false,
156 | "frame_time": false,
157 | "gizmos": true,
158 | "half_res": false,
159 | "information": false,
160 | "listener": false,
161 | "position": Vector3(0, 0, 0),
162 | "use_environment": false,
163 | "use_orthogonal": false,
164 | "view_type": 0,
165 | "x_rotation": 0.5,
166 | "y_rotation": -0.5
167 | }],
168 | "zfar": 4000.01,
169 | "znear": 0.05
170 | }
171 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPServer/.godot/editor/NetworkingServer.tscn-editstate-67ca15145d9bad4a4322ef1520d60e36.cfg:
--------------------------------------------------------------------------------
1 | [editor_states]
2 |
3 | Anim={
4 | "visible": false
5 | }
6 | 2D={
7 | "grid_offset": Vector2(0, 0),
8 | "grid_snap_active": false,
9 | "grid_step": Vector2(8, 8),
10 | "grid_visibility": 1,
11 | "ofs": Vector2(-165, -110),
12 | "primary_grid_steps": 8,
13 | "show_edit_locks": true,
14 | "show_guides": true,
15 | "show_helpers": false,
16 | "show_origin": true,
17 | "show_rulers": true,
18 | "show_transformation_gizmos": true,
19 | "show_viewport": true,
20 | "show_zoom_control": true,
21 | "smart_snap_active": false,
22 | "snap_guides": true,
23 | "snap_node_anchors": true,
24 | "snap_node_center": true,
25 | "snap_node_parent": true,
26 | "snap_node_sides": true,
27 | "snap_other_nodes": true,
28 | "snap_pixel": true,
29 | "snap_relative": false,
30 | "snap_rotation": false,
31 | "snap_rotation_offset": 0.0,
32 | "snap_rotation_step": 0.261799,
33 | "snap_scale": false,
34 | "snap_scale_step": 0.1,
35 | "zoom": 1.0
36 | }
37 | 3D={
38 | "fov": 70.01,
39 | "gizmos_status": {
40 | "AudioListener3D": 0,
41 | "AudioStreamPlayer3D": 0,
42 | "CPUParticles3D": 0,
43 | "CSGShape3D": 0,
44 | "Camera3D": 0,
45 | "CollisionObject3D": 0,
46 | "CollisionPolygon3D": 0,
47 | "CollisionShape3D": 0,
48 | "Decal": 0,
49 | "FogVolume": 0,
50 | "GPUParticles3D": 0,
51 | "GPUParticlesCollision3D": 0,
52 | "Joint3D": 0,
53 | "Light3D": 0,
54 | "LightmapGI": 0,
55 | "LightmapProbe": 0,
56 | "Marker3D": 0,
57 | "NavigationLink3D": 0,
58 | "NavigationRegion3D": 0,
59 | "OccluderInstance3D": 0,
60 | "Path3D": 0,
61 | "PhysicalBone3D": 0,
62 | "RayCast3D": 0,
63 | "ReflectionProbe": 0,
64 | "ShapeCast3D": 0,
65 | "Skeleton3D": 0,
66 | "SoftBody3D": 0,
67 | "SpringArm3D": 0,
68 | "VehicleWheel3D": 0,
69 | "VisibleOnScreenNotifier3D": 0,
70 | "VoxelGI": 0
71 | },
72 | "local_coords": false,
73 | "preview_sun_env": {
74 | "environ_ao_enabled": false,
75 | "environ_enabled": true,
76 | "environ_energy": 1.0,
77 | "environ_gi_enabled": false,
78 | "environ_glow_enabled": true,
79 | "environ_ground_color": Color(0.2, 0.169, 0.133, 1),
80 | "environ_sky_color": Color(0.385, 0.454, 0.55, 1),
81 | "environ_tonemap_enabled": true,
82 | "sun_color": Color(1, 1, 1, 1),
83 | "sun_enabled": true,
84 | "sun_energy": 1.0,
85 | "sun_max_distance": 100.0,
86 | "sun_rotation": Vector2(-1.0472, 2.61799)
87 | },
88 | "rotate_snap": 15.0,
89 | "scale_snap": 10.0,
90 | "show_grid": true,
91 | "show_origin": true,
92 | "snap_enabled": false,
93 | "translate_snap": 1.0,
94 | "viewport_mode": 1,
95 | "viewports": [{
96 | "auto_orthogonal": false,
97 | "auto_orthogonal_enabled": true,
98 | "cinematic_preview": false,
99 | "display_mode": 20,
100 | "distance": 4.0,
101 | "doppler": false,
102 | "frame_time": false,
103 | "gizmos": true,
104 | "half_res": false,
105 | "information": false,
106 | "listener": true,
107 | "position": Vector3(0, 0, 0),
108 | "use_environment": false,
109 | "use_orthogonal": false,
110 | "view_type": 0,
111 | "x_rotation": 0.5,
112 | "y_rotation": -0.5
113 | }, {
114 | "auto_orthogonal": false,
115 | "auto_orthogonal_enabled": true,
116 | "cinematic_preview": false,
117 | "display_mode": 20,
118 | "distance": 4.0,
119 | "doppler": false,
120 | "frame_time": false,
121 | "gizmos": true,
122 | "half_res": false,
123 | "information": false,
124 | "listener": false,
125 | "position": Vector3(0, 0, 0),
126 | "use_environment": false,
127 | "use_orthogonal": false,
128 | "view_type": 0,
129 | "x_rotation": 0.5,
130 | "y_rotation": -0.5
131 | }, {
132 | "auto_orthogonal": false,
133 | "auto_orthogonal_enabled": true,
134 | "cinematic_preview": false,
135 | "display_mode": 20,
136 | "distance": 4.0,
137 | "doppler": false,
138 | "frame_time": false,
139 | "gizmos": true,
140 | "half_res": false,
141 | "information": false,
142 | "listener": false,
143 | "position": Vector3(0, 0, 0),
144 | "use_environment": false,
145 | "use_orthogonal": false,
146 | "view_type": 0,
147 | "x_rotation": 0.5,
148 | "y_rotation": -0.5
149 | }, {
150 | "auto_orthogonal": false,
151 | "auto_orthogonal_enabled": true,
152 | "cinematic_preview": false,
153 | "display_mode": 20,
154 | "distance": 4.0,
155 | "doppler": false,
156 | "frame_time": false,
157 | "gizmos": true,
158 | "half_res": false,
159 | "information": false,
160 | "listener": false,
161 | "position": Vector3(0, 0, 0),
162 | "use_environment": false,
163 | "use_orthogonal": false,
164 | "view_type": 0,
165 | "x_rotation": 0.5,
166 | "y_rotation": -0.5
167 | }],
168 | "zfar": 4000.01,
169 | "znear": 0.05
170 | }
171 |
--------------------------------------------------------------------------------
/Godot4MultiplayerMVPClient/.godot/editor/NetworkingClient.tscn-editstate-db6bc7cdfc97dc30471557a80338ec26.cfg:
--------------------------------------------------------------------------------
1 | [editor_states]
2 |
3 | Anim={
4 | "visible": false
5 | }
6 | 2D={
7 | "grid_offset": Vector2(0, 0),
8 | "grid_snap_active": false,
9 | "grid_step": Vector2(8, 8),
10 | "grid_visibility": 1,
11 | "ofs": Vector2(-318.687, -96.8157),
12 | "primary_grid_steps": 8,
13 | "show_edit_locks": true,
14 | "show_guides": true,
15 | "show_helpers": false,
16 | "show_origin": true,
17 | "show_rulers": true,
18 | "show_transformation_gizmos": true,
19 | "show_viewport": true,
20 | "show_zoom_control": true,
21 | "smart_snap_active": false,
22 | "snap_guides": true,
23 | "snap_node_anchors": true,
24 | "snap_node_center": true,
25 | "snap_node_parent": true,
26 | "snap_node_sides": true,
27 | "snap_other_nodes": true,
28 | "snap_pixel": true,
29 | "snap_relative": false,
30 | "snap_rotation": false,
31 | "snap_rotation_offset": 0.0,
32 | "snap_rotation_step": 0.261799,
33 | "snap_scale": false,
34 | "snap_scale_step": 0.1,
35 | "zoom": 1.41421
36 | }
37 | 3D={
38 | "fov": 70.01,
39 | "gizmos_status": {
40 | "AudioListener3D": 0,
41 | "AudioStreamPlayer3D": 0,
42 | "CPUParticles3D": 0,
43 | "CSGShape3D": 0,
44 | "Camera3D": 0,
45 | "CollisionObject3D": 0,
46 | "CollisionPolygon3D": 0,
47 | "CollisionShape3D": 0,
48 | "Decal": 0,
49 | "FogVolume": 0,
50 | "GPUParticles3D": 0,
51 | "GPUParticlesCollision3D": 0,
52 | "Joint3D": 0,
53 | "Light3D": 0,
54 | "LightmapGI": 0,
55 | "LightmapProbe": 0,
56 | "Marker3D": 0,
57 | "NavigationLink3D": 0,
58 | "NavigationRegion3D": 0,
59 | "OccluderInstance3D": 0,
60 | "Path3D": 0,
61 | "PhysicalBone3D": 0,
62 | "RayCast3D": 0,
63 | "ReflectionProbe": 0,
64 | "ShapeCast3D": 0,
65 | "Skeleton3D": 0,
66 | "SoftBody3D": 0,
67 | "SpringArm3D": 0,
68 | "VehicleWheel3D": 0,
69 | "VisibleOnScreenNotifier3D": 0,
70 | "VoxelGI": 0
71 | },
72 | "local_coords": false,
73 | "preview_sun_env": {
74 | "environ_ao_enabled": false,
75 | "environ_enabled": true,
76 | "environ_energy": 1.0,
77 | "environ_gi_enabled": false,
78 | "environ_glow_enabled": true,
79 | "environ_ground_color": Color(0.2, 0.169, 0.133, 1),
80 | "environ_sky_color": Color(0.385, 0.454, 0.55, 1),
81 | "environ_tonemap_enabled": true,
82 | "sun_color": Color(1, 1, 1, 1),
83 | "sun_enabled": true,
84 | "sun_energy": 1.0,
85 | "sun_max_distance": 100.0,
86 | "sun_rotation": Vector2(-1.0472, 2.61799)
87 | },
88 | "rotate_snap": 15.0,
89 | "scale_snap": 10.0,
90 | "show_grid": true,
91 | "show_origin": true,
92 | "snap_enabled": false,
93 | "translate_snap": 1.0,
94 | "viewport_mode": 1,
95 | "viewports": [{
96 | "auto_orthogonal": false,
97 | "auto_orthogonal_enabled": true,
98 | "cinematic_preview": false,
99 | "display_mode": 20,
100 | "distance": 4.0,
101 | "doppler": false,
102 | "frame_time": false,
103 | "gizmos": true,
104 | "half_res": false,
105 | "information": false,
106 | "listener": true,
107 | "position": Vector3(0, 0, 0),
108 | "use_environment": false,
109 | "use_orthogonal": false,
110 | "view_type": 0,
111 | "x_rotation": 0.5,
112 | "y_rotation": -0.5
113 | }, {
114 | "auto_orthogonal": false,
115 | "auto_orthogonal_enabled": true,
116 | "cinematic_preview": false,
117 | "display_mode": 20,
118 | "distance": 4.0,
119 | "doppler": false,
120 | "frame_time": false,
121 | "gizmos": true,
122 | "half_res": false,
123 | "information": false,
124 | "listener": false,
125 | "position": Vector3(0, 0, 0),
126 | "use_environment": false,
127 | "use_orthogonal": false,
128 | "view_type": 0,
129 | "x_rotation": 0.5,
130 | "y_rotation": -0.5
131 | }, {
132 | "auto_orthogonal": false,
133 | "auto_orthogonal_enabled": true,
134 | "cinematic_preview": false,
135 | "display_mode": 20,
136 | "distance": 4.0,
137 | "doppler": false,
138 | "frame_time": false,
139 | "gizmos": true,
140 | "half_res": false,
141 | "information": false,
142 | "listener": false,
143 | "position": Vector3(0, 0, 0),
144 | "use_environment": false,
145 | "use_orthogonal": false,
146 | "view_type": 0,
147 | "x_rotation": 0.5,
148 | "y_rotation": -0.5
149 | }, {
150 | "auto_orthogonal": false,
151 | "auto_orthogonal_enabled": true,
152 | "cinematic_preview": false,
153 | "display_mode": 20,
154 | "distance": 4.0,
155 | "doppler": false,
156 | "frame_time": false,
157 | "gizmos": true,
158 | "half_res": false,
159 | "information": false,
160 | "listener": false,
161 | "position": Vector3(0, 0, 0),
162 | "use_environment": false,
163 | "use_orthogonal": false,
164 | "view_type": 0,
165 | "x_rotation": 0.5,
166 | "y_rotation": -0.5
167 | }],
168 | "zfar": 4000.01,
169 | "znear": 0.05
170 | }
171 |
--------------------------------------------------------------------------------