Add Multiplayer Demo

This commit is contained in:
2026-02-16 14:25:33 +01:00
commit 4a82f8bc6e
55 changed files with 2059 additions and 0 deletions

4
.editorconfig Normal file
View File

@@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

108
MainScene.tscn Normal file
View File

@@ -0,0 +1,108 @@
[gd_scene format=3 uid="uid://d0cdnl2m2h2ub"]
[ext_resource type="Script" uid="uid://dab50n01raf5a" path="res://main.gd" id="1_3mqji"]
[ext_resource type="PackedScene" uid="uid://dmkufuydplu0c" path="res://Player.tscn" id="2_x4av3"]
[ext_resource type="PackedScene" uid="uid://b82x5u0b3cpwv" path="res://lobbyListItem.tscn" id="3_rpqi1"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uxrcv"]
bg_color = Color(0.17641908, 0.17641911, 0.17641899, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_x4av3"]
size = Vector3(100, 0.2, 100)
[sub_resource type="BoxMesh" id="BoxMesh_rpqi1"]
size = Vector3(100, 0.2, 100)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_uxrcv"]
albedo_color = Color(0.22670749, 0.22670749, 0.22670746, 1)
[node name="Main" type="Node3D" unique_id=1379208683 node_paths=PackedStringArray("lobby_list")]
script = ExtResource("1_3mqji")
player_scene = ExtResource("2_x4av3")
lobby_list_item = ExtResource("3_rpqi1")
lobby_list = NodePath("UI/LobbyListSection/LobbyListScrollContainer/LobbyList")
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="." unique_id=1659402982]
_spawnable_scenes = PackedStringArray("uid://dmkufuydplu0c")
spawn_path = NodePath("..")
[node name="UI" type="Control" parent="." unique_id=1161351898]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="HostJoinSection" type="Control" parent="UI" unique_id=1616716395]
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="HostButton" type="Button" parent="UI/HostJoinSection" unique_id=2090245336]
layout_mode = 0
offset_right = 246.0
offset_bottom = 137.0
text = "HOST"
[node name="JoinButton" type="Button" parent="UI/HostJoinSection" unique_id=1557404200]
layout_mode = 0
offset_top = 156.0
offset_right = 241.0
offset_bottom = 271.0
disabled = true
text = "JOIN"
[node name="LobbyIdPrompt" type="LineEdit" parent="UI/HostJoinSection" unique_id=1258785698]
layout_mode = 0
offset_left = 2.0
offset_top = 269.0
offset_right = 243.0
offset_bottom = 318.0
placeholder_text = "LOBBY ID"
[node name="LobbyListSection" type="Control" parent="UI" unique_id=1788551827]
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="ListLobbiesButton" type="Button" parent="UI/LobbyListSection" unique_id=1172260789]
layout_mode = 0
offset_left = 317.0
offset_top = 6.0
offset_right = 477.0
offset_bottom = 98.0
text = "List Lobbies"
[node name="LobbyListScrollContainer" type="ScrollContainer" parent="UI/LobbyListSection" unique_id=1433036296]
layout_mode = 0
offset_left = 256.0
offset_top = 109.0
offset_right = 543.0
offset_bottom = 437.0
theme_override_styles/panel = SubResource("StyleBoxFlat_uxrcv")
[node name="LobbyList" type="VBoxContainer" parent="UI/LobbyListSection/LobbyListScrollContainer" unique_id=330790523]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="World" type="Node3D" parent="." unique_id=2003993590]
[node name="StaticBody3D" type="StaticBody3D" parent="World" unique_id=1187840452]
[node name="CollisionShape3D" type="CollisionShape3D" parent="World/StaticBody3D" unique_id=448167956]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.29736328, 0)
shape = SubResource("BoxShape3D_x4av3")
[node name="MeshInstance3D" type="MeshInstance3D" parent="World/StaticBody3D" unique_id=1016103612]
mesh = SubResource("BoxMesh_rpqi1")
surface_material_override/0 = SubResource("StandardMaterial3D_uxrcv")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="World" unique_id=2131172420]
transform = Transform3D(1, 0, 0, 0, 0.10017079, 0.9949703, 0, -0.9949703, 0.10017079, 0, 50, 0)
[connection signal="pressed" from="UI/HostJoinSection/HostButton" to="." method="_on_button_pressed"]
[connection signal="pressed" from="UI/HostJoinSection/JoinButton" to="." method="_on_join_button_pressed"]
[connection signal="text_changed" from="UI/HostJoinSection/LobbyIdPrompt" to="." method="_on_lobby_id_text_changed"]
[connection signal="pressed" from="UI/LobbyListSection/ListLobbiesButton" to="." method="_on_list_lobbies_button_pressed"]

49
Player.tscn Normal file
View File

@@ -0,0 +1,49 @@
[gd_scene format=3 uid="uid://dmkufuydplu0c"]
[ext_resource type="Script" uid="uid://two86gol65q7" path="res://player.gd" id="1_kpjcp"]
[sub_resource type="BoxMesh" id="BoxMesh_xhfnw"]
size = Vector3(0.5, 0.5, 0.5)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kpjcp"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_kpjcp"]
properties/0/path = NodePath(".:position")
properties/0/spawn = true
properties/0/replication_mode = 1
properties/1/path = NodePath(".:rotation")
properties/1/spawn = true
properties/1/replication_mode = 1
properties/2/path = NodePath("Camera3D:position")
properties/2/spawn = true
properties/2/replication_mode = 1
properties/3/path = NodePath("Camera3D:rotation")
properties/3/spawn = true
properties/3/replication_mode = 1
[sub_resource type="CapsuleMesh" id="CapsuleMesh_kne1u"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xhfnw"]
albedo_color = Color(0, 0, 0, 1)
[node name="PlayerCharacter" type="CharacterBody3D" unique_id=1396857835]
script = ExtResource("1_kpjcp")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1215710820]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Camera3D" unique_id=1962930017]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.65276957, -0.46588755, -0.53100395)
mesh = SubResource("BoxMesh_xhfnw")
[node name="CollisionShape2D" type="CollisionShape3D" parent="." unique_id=885240432]
transform = Transform3D(7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0)
shape = SubResource("CapsuleShape3D_kpjcp")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=672339529]
replication_config = SubResource("SceneReplicationConfig_kpjcp")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=73905185]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
mesh = SubResource("CapsuleMesh_kne1u")
surface_material_override/0 = SubResource("StandardMaterial3D_xhfnw")

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016-2023 The Godot Engine community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
[configuration]
entry_symbol = "git_plugin_init"
compatibility_minimum = "4.2.0"
[libraries]
linux.editor.x86_64 = "linux/libgit_plugin.linux.editor.x86_64.so"
macos.editor = "macos/libgit_plugin.macos.editor.universal.dylib"
windows.editor.x86_64 = "windows/libgit_plugin.windows.editor.x86_64.dll"

View File

@@ -0,0 +1 @@
uid://dv1130hdjqtry

Binary file not shown.

View File

@@ -0,0 +1,28 @@
[configuration]
entry_symbol = "godotsteam_init"
compatibility_minimum = "4.4"
[libraries]
android.debug.arm64 = "res://addons/godotsteam/androidarm64/libgodotsteam.android.template_debug.arm64.so"
android.release.arm64 = "res://addons/godotsteam/androidarm64/libgodotsteam.android.template_release.arm64.so"
linux.debug.arm64 = "res://addons/godotsteam/linuxarm64/libgodotsteam.linux.template_debug.arm64.so"
linux.debug.x86_64 = "res://addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so"
linux.debug.x86_32 = "res://addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so"
linux.release.arm64 = "res://addons/godotsteam/linuxarm64/libgodotsteam.linux.template_release.arm64.so"
linux.release.x86_64 = "res://addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so"
linux.release.x86_32 = "res://addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so"
macos.debug = "res://addons/godotsteam/osx/libgodotsteam.macos.template_debug.dylib"
macos.release = "res://addons/godotsteam/osx/libgodotsteam.macos.template_release.dylib"
windows.debug.x86_64 = "res://addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll"
windows.debug.x86_32 = "res://addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll"
windows.release.x86_64 = "res://addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll"
windows.release.x86_32 = "res://addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll"
[dependencies]
android.arm64 = { "res://addons/godotsteam/androidarm64/libsteam_api.so": "" }
linux.arm64 = { "res://addons/godotsteam/linuxarm64/libsteam_api.so": "" }
linux.x86_64 = { "res://addons/godotsteam/linux64/libsteam_api.so": "" }
linux.x86_32 = { "res://addons/godotsteam/linux32/libsteam_api.so": "" }
macos.universal = { "res://addons/godotsteam/osx/libsteam_api.dylib": "" }
windows.x86_64 = { "res://addons/godotsteam/win64/steam_api64.dll": "" }
windows.x86_32 = { "res://addons/godotsteam/win32/steam_api.dll": "" }

View File

@@ -0,0 +1 @@
uid://pq484s3me3fu

View File

@@ -0,0 +1,23 @@
MIT License
Copyright (c) 2015-Current | GP Garcia, Chris Ridenour, and Contributors
View all contributors at https://godotsteam.com/contribute/contributors/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

87
addons/godotsteam/readme.md Executable file
View File

@@ -0,0 +1,87 @@
# GodotSteam for GDExtension | Community Edition
An ecosystem of tools for [Godot Engine](https://godotengine.org) and [Valve's Steam](https://store.steampowered.com). For the Windows, Linux, and Mac platforms.
Additional Flavors
---
Standard Module | Standard Plug-ins | Server Module | Server Plug-ins | Examples
--- | --- | --- | --- | ---
[Godot 2.x](https://codeberg.org/godotsteam/godotsteam/src/branch/godot2) | [GDNative](https://codeberg.org/godotsteam/godotsteam/src/branch/gdnative) | [Server 3.x](https://codeberg.org/godotsteam/godotsteam-server/src/branch/godot3) | [GDNative](https://codeberg.org/godotsteam/godotsteam-server/src/branch/gdnative) | [Skillet](https://codeberg.org/godotsteam/skillet)
[Godot 3.x](https://codeberg.org/godotsteam/godotsteam/src/branch/godot3) | [GDExtension](https://codeberg.org/godotsteam/godotsteam/src/branch/gdextension) | [Server 4.x](https://codeberg.org/godotsteam/godotsteam-server/src/branch/godot4) | [GDExtension](https://codeberg.org/godotsteam/godotsteam-server/src/branch/gdextension) | [Skillet UGC Editor](https://codeberg.org/godotsteam/skillet/src/branch/ugc_editor)
[Godot 4.x](https://codeberg.org/godotsteam/godotsteam/src/branch/godot4) | --- | --- | --- | ---
[MultiplayerPeer](https://codeberg.org/godotsteam/multiplayerpeer)| --- | --- | --- | ---
Documentation
---
[Documentation is available here](https://godotsteam.com/). You can also check out the Search Help section inside Godot Engine. [To start, try checking out our tutorial on initializing Steam.](https://godotsteam.com/tutorials/initializing/) There are additional tutorials, with more in the works. You can also [check out additional Godot and Steam related videos, text, additional tools, plug-ins, etc. here.](https://godotsteam.com/resources/external/)
Feel free to chat with us about GodotSteam or ask for assistance on the [Stoat server](https://stt.gg/9DxQ3Dcd) or [IRC on Libera Chat](irc://irc.libera.chat/#godotsteam).
Donate
---
Pull-requests are the best way to help the project out but you can also donate through [Github Sponsors](https://github.com/sponsors/Gramps) or [LiberaPay](https://liberapay.com/godotsteam/donate)! [You can read more about donor perks here.](https://godotsteam.com/contribute/donations/) [You can also view all our awesome donors here.](https://godotsteam.com/contribute/donors/)
Current Build
---
You can [download pre-compiled versions of this repo here](https://codeberg.org/godotsteam/godotsteam/releases).
**Version 4.17.1 Changes**
- Changed: SCsub and config.py for ARM64 and Android
- Fixed: potential crash in disconnect_peer; thanks to ***bearlikelion***
[You can read more change-logs here](https://godotsteam.com/changelog/gdextension/).
Compatibility
---
While rare, sometimes Steamworks SDK updates will break compatilibity with older GodotSteam versions. Any compatability breaks are noted below. Newer API files (dll, so, dylib) _should_ still work for older versions.
Steamworks SDK Version | GodotSteam Version
---|---
1.63 or newer | 4.17
1.62 | 4.14 or 4.16.2
1.61 | 4.12 to 4.13
1.60 | 4.6 to 4.11
1.59 | 4.6 to 4.8
1.58a or older | 4.5.4 or older
Versions of GodotSteam that have compatibility breaks introduced.
GodotSteam Version | Broken Compatibility
---|---
4.8 | Networking identity system removed, replaced with Steam IDs
4.9 | sendMessages returns an Array
4.11 | setLeaderboardDetailsMax removed
4.13 | getItemDefinitionProperty return a dictionary, html_needs_paint key 'bgra' changed to 'rbga'
4.14 | Removed first argument for stat request in steamInit and steamInitEx, steamInit returns intended bool value
4.16 | Variety of small break points, refer to [4.16 changelog for details](https://godotsteam.com/changelog/godot4/)
4.17 | Windows projects using Steam SDK 1.63 are meant to work with Proton 11 or Experimental on Linux / Steam Deck.
Known Issues
---
- GDExtension for 4.4 is **not** compatible with 4.3.x or lower. Please check the versions you are using.
- Overlay will not work in the editor but will work in export projects when uploaded to Steam. This seems to a limitation with Vulkan currently.
Quick How-To
---
For complete instructions on how to build the GDExtension version of GodotSteam, [please refer to our documentation's 'How-To GDExtension' section.](https://godotsteam.com/howto/gdextension/) It will have the most up-to-date information.
Alternatively, you can just [download the pre-compiled versions in our Releases section](https://codeberg.org/godotsteam/godotsteam/releases) or [from the Godot Asset Library](https://godotengine.org/asset-library/asset/2445) and skip compiling it yourself!
Usage
---
Do not use the GDExtension version of GodotSteam with any of the module versions whether it be our pre-compiled versions or ones you compile. They are not compatible with each other.
When exporting with the GDExtension version, please use the normal Godot Engine templates instead of our GodotSteam templates or you will have a lot of issues.
License
---
MIT license

Binary file not shown.

Binary file not shown.

BIN
export.tar.gz Normal file

Binary file not shown.

BIN
export/export.zip Normal file

Binary file not shown.

BIN
export/export/export Executable file

Binary file not shown.

BIN
export/export/export.pck Normal file

Binary file not shown.

4
export/export/export.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
printf '\033c\033]0;%s\a' SteamMultiplayerDemo
base_path="$(dirname "$(realpath "$0")")"
"$base_path/export" "$@"

Binary file not shown.

BIN
export/export/libsteam_api.so Executable file

Binary file not shown.

46
export_presets.cfg Normal file
View File

@@ -0,0 +1,46 @@
[preset.0]
name="Linux"
platform="Linux"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="export/export.zip"
patches=PackedStringArray()
patch_delta_encoding=false
patch_delta_compression_level_zstd=19
patch_delta_min_reduction=0.1
patch_delta_include_filters="*"
patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
shader_baker/enabled=false
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
export DISPLAY=:0
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
pkill -x -f \"{temp_dir}/{exe_name} {cmd_args}\"
rm -rf \"{temp_dir}\""

1
icon.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 995 B

43
icon.svg.import Normal file
View File

@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d11oh0720w01q"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

20
lobbyListItem.tscn Normal file
View File

@@ -0,0 +1,20 @@
[gd_scene format=3 uid="uid://b82x5u0b3cpwv"]
[ext_resource type="Script" uid="uid://cqixg3gdwlwj5" path="res://lobby_list_item.gd" id="1_s80bd"]
[node name="HBoxContainer" type="HBoxContainer" unique_id=928830224]
script = ExtResource("1_s80bd")
lobby = {
"LobbyName": "ABC"
}
[node name="Label" type="Label" parent="." unique_id=1285645000]
layout_mode = 2
size_flags_horizontal = 3
text = "Name: LobbyName"
[node name="Button" type="Button" parent="." unique_id=1078250063]
layout_mode = 2
text = "Join"
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]

12
lobby_list_item.gd Normal file
View File

@@ -0,0 +1,12 @@
class_name LobbyListItem
extends HBoxContainer
@export var lobby: Dictionary
signal on_lobby_join_clicked(lobby_id: int)
@onready var label: Label = $Label
func _ready() -> void:
label.text = lobby.get("LobbyName")
func _on_button_pressed() -> void:
on_lobby_join_clicked.emit(lobby.get("LobbyId"))

1
lobby_list_item.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://cqixg3gdwlwj5

128
main.gd Normal file
View File

@@ -0,0 +1,128 @@
extends Node3D
@export var player_scene : PackedScene;
@export var lobby_list_item : PackedScene;
@export var lobby_list : VBoxContainer;
@onready var lobby_id_prompt: LineEdit = $UI/HostJoinSection/LobbyIdPrompt
@onready var join_button: Button = $UI/HostJoinSection/JoinButton
@onready var ui: Control = $UI
@onready var ui_host_join_section: Control = $UI/HostJoinSection
@onready var ui_lobby_list_section: Control = $UI/LobbyListSection
func _exit_tree():
if !is_in_lobby:
return
Steam.leaveLobby(lobby_id)
var lobby_id: int = 1;
var peer : SteamMultiplayerPeer;
var is_host : bool = false;
var is_joining : bool = false
var is_in_lobby : bool = false;
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
print("Steam initialized" , Steam.steamInit(480,true));
Steam.initRelayNetworkAccess();
Steam.lobby_match_list.connect(on_lobby_match_list)
Steam.lobby_created.connect(on_lobby_created);
Steam.lobby_joined.connect(on_lobby_joined);
multiplayer.connection_failed.connect(on_connection_failed);
func on_connection_failed():
print("Connection Failed")
func host_lobby():
if is_in_lobby:
return;
Steam.createLobby(Steam.LobbyType.LOBBY_TYPE_PUBLIC, 16);
func join_lobby(joining_lobby_id: int):
if is_in_lobby:
return;
is_joining = true;
Steam.joinLobby(joining_lobby_id)
func on_lobby_joined(joined_lobby_id: int, _permissions: int, _locked: bool, _response: int):
if !is_joining:
return;
self.lobby_id = joined_lobby_id;
peer = SteamMultiplayerPeer.new();
peer.server_relay = true;
peer.create_client(Steam.getLobbyOwner(joined_lobby_id))
multiplayer.multiplayer_peer = peer;
is_joining = false;
is_in_lobby = true;
func on_lobby_created(result: int, created_lobby_id: int):
if result == Steam.Result.RESULT_OK:
self.lobby_id = created_lobby_id
peer = SteamMultiplayerPeer.new()
peer.server_relay = true
peer.create_host();
multiplayer.multiplayer_peer = peer;
multiplayer.peer_connected.connect(add_player)
multiplayer.peer_disconnected.connect(remove_player)
add_player();
is_in_lobby = true;
is_host = true;
Steam.setLobbyData(created_lobby_id,"LobbyName", "Lobby "+str(created_lobby_id))
Steam.setLobbyData(created_lobby_id,"LobbyType", "GodotSteamDemo")
print("Created Lobby, Id: ", created_lobby_id)
func add_player(id: int = 1):
var player : Node3D = player_scene.instantiate();
player.position = Vector3(0,2,0)
player.name = str(id);
call_deferred("add_child",player);
func remove_player(id: int):
if !self.has_node(str(id)):
return
self.get_node(str(id)).queue_free();
func on_lobby_match_list(lobby_ids: Array):
print(lobby_ids)
var _lobbys = lobby_ids.map(func(id):
var result = Dictionary()
var lobbyType = Steam.getLobbyData(id,"LobbyType");
var lobbyName = Steam.getLobbyData(id,"LobbyName");
result.set("LobbyId", id)
result.set("LobbyType", lobbyType)
result.set("LobbyName", lobbyName)
return result;
).filter(func filterOwnLobbyType(lobby_data: Dictionary):
return lobby_data.get("LobbyType") == "GodotSteamDemo"
);
for lobby in _lobbys:
var list_item : LobbyListItem = lobby_list_item.instantiate();
list_item.lobby = lobby
list_item.on_lobby_join_clicked.connect(join_lobby)
lobby_list.add_child(list_item)
print(_lobbys);
func _on_button_pressed() -> void:
host_lobby();
func _on_join_button_pressed() -> void:
join_lobby(lobby_id_prompt.text.to_int())
func _on_lobby_id_text_changed(new_text: String) -> void:
join_button.disabled = new_text.length() <=0
func _on_list_lobbies_button_pressed() -> void:
Steam.requestLobbyList()
func _physics_process(_delta):
if (Input.is_action_just_pressed("ui_toggle")):
ui.visible = !ui.visible
if (Input.is_action_just_pressed("ui_toggle_host_join_section")):
ui_host_join_section.visible = !ui_host_join_section.visible
if (Input.is_action_just_pressed("ui_toggle_lobby_list_section")):
ui_lobby_list_section.visible = !ui_lobby_list_section.visible
pass

1
main.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://dab50n01raf5a

45
player.gd Normal file
View File

@@ -0,0 +1,45 @@
extends CharacterBody3D
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var speed = 5
var jump_speed = 5
var mouse_sensitivity = 0.002
@onready var camera_3d: Camera3D = $"Camera3D"
func _enter_tree():
set_multiplayer_authority(name.to_int())
func _ready():
if !is_multiplayer_authority():
return;
camera_3d.make_current()
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _input(event):
if !is_multiplayer_authority():
return;
if event.is_action_pressed("ui_cancel"):
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
rotate_y(-event.relative.x * mouse_sensitivity)
camera_3d.rotate_x(-event.relative.y * mouse_sensitivity)
camera_3d.rotation.x = clampf(camera_3d.rotation.x, -deg_to_rad(70), deg_to_rad(70))
func _physics_process(delta):
if !is_multiplayer_authority():
get_multiplayer_authority()
return;
velocity.y += -gravity * delta
var input = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
var movement_dir = transform.basis * Vector3(input.x, 0, input.y)
velocity.x = movement_dir.x * speed
velocity.z = movement_dir.z * speed
move_and_slide()

1
player.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://two86gol65q7

74
project.godot Normal file
View File

@@ -0,0 +1,74 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="SteamMultiplayerDemo"
run/main_scene="uid://d0cdnl2m2h2ub"
config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="res://icon.svg"
[editor]
version_control/plugin_name="GitPlugin"
version_control/autoload_on_startup=true
[input]
move_forward={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
]
}
move_backward={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
move_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
move_right={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
]
}
ui_toggle={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":85,"key_label":0,"unicode":117,"location":0,"echo":false,"script":null)
]
}
ui_toggle_host_join_section={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":72,"key_label":0,"unicode":104,"location":0,"echo":false,"script":null)
]
}
ui_toggle_lobby_list_section={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":76,"key_label":0,"unicode":108,"location":0,"echo":false,"script":null)
]
}
[physics]
3d/physics_engine="Jolt Physics"
[rendering]
rendering_device/driver.windows="d3d12"
[steam]
initialization/app_id=0
initialization/initialize_on_startup=false
initialization/embed_callbacks=false
multiplayer_peer/max_channels=4