32 Commits

Author SHA1 Message Date
WiseNoodle
7a1dcc0e01 save work 2025-08-07 22:09:07 -04:00
ee01d29d7b basic grass texture 2025-08-07 20:12:03 -04:00
WiseNoodle
144bd3d2af Inital commit 2025-08-07 18:57:07 -04:00
468050e8c9 Merge pull request 'Merge multiplayer to dev branch' (#2) from multiplayer into develop
Reviewed-on: #2
2025-08-07 22:06:01 +00:00
9970146660 Add textures to tent model 2025-08-07 15:27:52 -04:00
420d6ef950 added the 0 to create_client 2025-08-07 12:51:54 -05:00
74dab08fb2 Add dynamic audio and particle system for the campfire 2025-08-07 13:42:45 -04:00
64d086bfcf Add dynamic audio and particle system for the campfire 2025-08-07 13:42:09 -04:00
767244d814 ai slop lobby fix test 2025-08-07 12:13:58 -05:00
4f5ba495a9 made ai add a bunch of logging to diagnose the connection 2025-08-07 11:45:57 -05:00
c560c9cbb7 added the chat update to see if the steam connection is right and its just the godot one that is broken 2025-08-07 00:09:32 -05:00
b0199aff09 add the p2p signal 2025-08-07 00:03:08 -05:00
00e408d46e Hopefully fix the client issue 2025-08-06 23:55:22 -05:00
50a8424217 Merge branch 'multiplayer' of https://git.bellsworne.tech/Bellsworne/splunk into multiplayer 2025-08-06 23:40:32 -05:00
ca299dbd87 host shouldnt try to create a second client 2025-08-06 23:38:58 -05:00
WiseNoodle
9d6e19f5be Tweak tents and campfire 2025-08-07 00:20:33 -04:00
63a7762206 Forgot to create client peer 2025-08-06 23:15:30 -05:00
df83434130 append Lobby test 2 2025-08-06 22:59:49 -05:00
WiseNoodle
be2f304621 Campfire textures and particles 2025-08-06 23:50:51 -04:00
fe647b432b append Lobby test 2025-08-06 22:46:26 -05:00
53b974faae Lobby test 2025-08-06 22:40:07 -05:00
WiseNoodle
f0ce6b1994 Add basic campfire and tent models 2025-08-05 00:33:03 -04:00
6425be5cb0 Added input mapping; Begin multiplayer work; added steam integration 2025-08-04 23:19:20 -05:00
WiseNoodle
7a29a7ae82 Add multiplayer debug ui 2025-08-04 22:39:38 -04:00
003fae1d3a basic player controller 2025-08-04 21:36:01 -05:00
WiseNoodle
74226d7032 Add basic lobby terrain for testing 2025-08-04 00:16:35 -04:00
WiseNoodle
1f534907c4 Add freecam and add basic tools and references 2025-08-03 23:20:45 -04:00
WiseNoodle
9b2ee4e41d remove temp files 2025-08-03 22:19:43 -04:00
WiseNoodle
b723c97b52 fill folders 2025-08-03 22:19:22 -04:00
WiseNoodle
a6c55dde51 Add basic scenes 2025-08-03 22:18:42 -04:00
WiseNoodle
ac9ff136d3 Add basic file structure 2025-08-03 22:16:59 -04:00
WiseNoodle
5b21ed431a Turn on Jolt physics 2025-08-03 22:12:17 -04:00
107 changed files with 1987 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
extends Camera3D
## Camera with flying script attached to it.
class_name Freecam3D
##
## Camera with toggleable freecam mode for prototyping when creating levels, shaders, lighting, etc.
##
## Usage: Run your game, press <TAB> and fly around freely. Uses Minecraft-like controls.
##
## Customize your own toggle key to avoid collisions with your current mappings.
@export var toggle_key: Key = KEY_TAB
## Speed up / down by scrolling the mouse whell down / up
@export var invert_speed_controls: bool = false
@export var overlay_text: bool = true
## Pivot node for camera looking around
@onready var pivot := Node3D.new()
## Main parent for camera overlay.
@onready var screen_overlay := VBoxContainer.new()
## Container for the chat-like event log.
@onready var event_log := VBoxContainer.new()
const MAX_SPEED := 4
const MIN_SPEED := 0.1
const ACCELERATION := 0.1
const MOUSE_SENSITIVITY := 0.002
## Whether or not the camera can move.
var movement_active := false:
set(val):
movement_active = val
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED if movement_active else Input.MOUSE_MODE_VISIBLE)
display_message("[Movement ON]" if movement_active else "[Movement OFF]")
## The current maximum speed. Lower or higher it by scrolling the mouse wheel.
var target_speed := MIN_SPEED
## Movement velocity.
var velocity := Vector3.ZERO
## Sets up pivot and UI overlay elements.
func _setup_nodes() -> void:
self.add_sibling(pivot)
pivot.position = position
pivot.rotation = rotation
pivot.name = "FreecamPivot"
self.reparent(pivot)
self.position = Vector3.ZERO
self.rotation = Vector3.ZERO
# UI stuff
screen_overlay.add_theme_constant_override("Separation", 8)
self.add_child(screen_overlay)
screen_overlay.add_child(_make_label("Debug Camera"))
screen_overlay.add_spacer(false)
screen_overlay.add_child(event_log)
screen_overlay.visible = overlay_text
func _ready() -> void:
_setup_nodes.call_deferred()
_add_keybindings()
func _process(delta: float) -> void:
if Input.is_action_just_released("__debug_camera_toggle"):
movement_active = not movement_active
if movement_active:
var dir = Vector3.ZERO
if Input.is_action_pressed("__debug_camera_forward"): dir.z -= 1
if Input.is_action_pressed("__debug_camera_back"): dir.z += 1
if Input.is_action_pressed("__debug_camera_left"): dir.x -= 1
if Input.is_action_pressed("__debug_camera_right"): dir.x += 1
if Input.is_action_pressed("__debug_camera_up"): dir.y += 1
if Input.is_action_pressed("__debug_camera_down"): dir.y -= 1
dir = dir.normalized()
dir = dir.rotated(Vector3.UP, pivot.rotation.y)
velocity = lerp(velocity, dir * target_speed, ACCELERATION)
pivot.position += velocity
func _input(event: InputEvent) -> void:
if movement_active:
# Turn around
if event is InputEventMouseMotion:
pivot.rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
rotation.x = clamp(rotation.x, -PI/2, PI/2)
var speed_up = func():
target_speed = clamp(target_speed + 0.15, MIN_SPEED, MAX_SPEED)
display_message("[Speed up] " + str(target_speed))
var slow_down = func():
target_speed = clamp(target_speed - 0.15, MIN_SPEED, MAX_SPEED)
display_message("[Slow down] " + str(target_speed))
# Speed up and down with the mouse wheel
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed:
slow_down.call() if invert_speed_controls else speed_up.call()
if event.button_index == MOUSE_BUTTON_WHEEL_DOWN and event.pressed:
speed_up.call() if invert_speed_controls else slow_down.call()
## Pushes new message label into "chat" and removes the old ones if necessary
func display_message(text: String) -> void:
while event_log.get_child_count() >= 3:
event_log.remove_child(event_log.get_child(0))
event_log.add_child(_make_label(text))
func _make_label(text: String) -> Label:
var l = Label.new()
l.text = text
return l
func _add_keybindings() -> void:
var actions = InputMap.get_actions()
if "__debug_camera_forward" not in actions: _add_key_input_action("__debug_camera_forward", KEY_W)
if "__debug_camera_back" not in actions: _add_key_input_action("__debug_camera_back", KEY_S)
if "__debug_camera_left" not in actions: _add_key_input_action("__debug_camera_left", KEY_A)
if "__debug_camera_right" not in actions: _add_key_input_action("__debug_camera_right", KEY_D)
if "__debug_camera_up" not in actions: _add_key_input_action("__debug_camera_up", KEY_SPACE)
if "__debug_camera_down" not in actions: _add_key_input_action("__debug_camera_down", KEY_SHIFT)
if "__debug_camera_toggle" not in actions: _add_key_input_action("__debug_camera_toggle", toggle_key)
func _add_key_input_action(name: String, key: Key) -> void:
var ev = InputEventKey.new()
ev.physical_keycode = key
InputMap.add_action(name)
InputMap.action_add_event(name, ev)

View File

@@ -0,0 +1 @@
uid://8vyuhyx0xogt

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c4kitg6s5bcqu"
path="res://.godot/imported/mc-camera2.png-fe60f555c5ea92c0796267cd654ef834.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/freecam_3D/mc-camera2.png"
dest_files=["res://.godot/imported/mc-camera2.png-fe60f555c5ea92c0796267cd654ef834.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@@ -0,0 +1,7 @@
[plugin]
name="Freecam3D"
description="A flying freecam with Minecraft-like controls."
author="Vojtech Struhar"
version="1.2.0"
script="plugin.gd"

View File

@@ -0,0 +1,20 @@
@tool
extends EditorPlugin
##
## Bootstraps the Freecam3D node.
##
func _enter_tree() -> void:
print("[Freecam3D Plugin] Loaded.")
add_custom_type(
"Freecam3D",
"Camera3D",
preload("freecam.gd"),
preload("mc-camera2.png"))
func _exit_tree() -> void:
remove_custom_type("Freecam3D")

View File

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

View File

@@ -0,0 +1,22 @@
[configuration]
entry_symbol = "godotsteam_init"
compatibility_minimum = "4.4"
[libraries]
macos.debug = "res://addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework"
macos.release = "res://addons/godotsteam/osx/libgodotsteam.macos.template_release.framework"
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"
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.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"
[dependencies]
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": "" }
linux.x86_64 = { "res://addons/godotsteam/linux64/libsteam_api.so": "" }
linux.x86_32 = { "res://addons/godotsteam/linux32/libsteam_api.so": "" }

View File

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

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>libgodotsteam.debug</string>
<key>CFBundleIdentifier</key>
<string>org.godotsteam.godotsteam</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>libgodotsteam.debug</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.15</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>4.15</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
</dict>
</plist>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>libgodotsteam</string>
<key>CFBundleIdentifier</key>
<string>org.godotsteam.godotsteam</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>libgodotsteam</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.15</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>4.15</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
~*.dll

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Expresso Bits
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.

View File

@@ -0,0 +1,87 @@
# <img src="https://raw.githubusercontent.com/expressobits/steam-multiplayer-peer/main/icon.png" alt= “icon” width="32" height="32"> Welcome to Expresso Steam Multiplayer Peer 👋
![Version](https://img.shields.io/badge/version-0.2.0-blue.svg?cacheSeconds=2592000)
[![Documentation](https://img.shields.io/badge/documentation-no-red.svg)](todo-doc)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](MIT)
See demos in:
Github: [Branch demos](https://github.com/expressobits/steam-multiplayer-peer/tree/demos)
Godot Asset Lib: https://godotengine.org/asset-library/asset/2258
## Tutorial and Learnings (How to use)
See post of Michael Macha
https://michaelmacha.wordpress.com/2024/04/08/godotsteam-and-steammultiplayerpeer/
See too on youtube videos
https://www.youtube.com/playlist?list=PLg_8mgEWE2p8ZA-AqUUJ3CYEtrRVFhl_v
Thank you Michael!
## Features
✔️ Change easy Enet peer to Steam Peer
✔️ Use Steam Sockets (Low level like enet).
✔️ GDExtension (Easy to add your project)
✔️ No dependency with GodotSteam, but demo use GodotSteam to handle connections with lobbies (See lobbies tutorial in Godot Steam [here](https://godotsteam.com/tutorials/lobbies/)).
## GodotSteam SteamMultiplayerPeer Differences
| Differences | This SteamMultiplayerPeer | GodotSteam SteamMultiplayerPeer |
|---|---|---|
| Lib Type | GDExtension, add on your project libs to use easy. | C++ module, you need to use the precompiled <br>ones from godotsteam or compile it yourself |
| Steam Connection | Steam Sockets [Steam Docs](https://partner.steamgames.com/doc/api/ISteamNetworkingSockets)<br>Steam's lowest connection level,<br>manages a connection <br>(It's very close to Enet, <br>that's why I chose this approach for the plugin) | Steam Messages [Steam Docs](https://partner.steamgames.com/doc/api/ISteamNetworkingMessages)<br>Without a connection idea,<br>the connection is managed by the lobby,<br>Need Steam lobbies. |
| TODO | | |
## Known issues
⚠️ Features No channel support currently
At some point I intend to integrate channels to be used in rpcs commands, but currently it is only necessary to use channel 0 or the default rpcs.
## In Progress
🔨 Bugs fixes
## Planneds
📅 No planned features.
<!-- ## Install
See in [Wiki](https://github.com/ExpressoBits/inventory-system/wiki) -->
## Authors
👤 **Rafael Correa**
* Twitter: [@ScriptsEngineer](https://twitter.com/ScriptsEngineer)
* Github: [@scriptsengineer](https://github.com/scriptsengineer)
👤 **Zennyth**
* Github: [@Zennyth](https://github.com/Zennyth)
👤 **greenfox1505**
* Github: [@greenfox1505](https://github.com/greenfox1505)
👤 **MichaelMacha**
* Github: [@MichaelMacha](https://github.com/MichaelMacha)
## 🤝 Contributing
Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/ExpressoBits/steam-multiplayer-peer/issues).
To suggest or discuss some project structure, feel free here [discussions page](https://github.com/expressobits/steam-multiplayer-peer/discussions)
## Show your support
Give a ⭐️ if this project helped you!
## 📝 License
This project is [MIT](MIT) licensed.

View File

@@ -0,0 +1,25 @@
[configuration]
entry_symbol = "steam_multiplayer_peer_init"
compatibility_minimum = 4.2
[libraries]
linux.debug.x86_64 = "./linux/libsteam-multiplayer-peer.linux.template_debug.x86_64.so"
linux.release.x86_64 = "./linux/libsteam-multiplayer-peer.linux.template_release.x86_64.so"
linux.debug.arm64 = "./linux/libsteam-multiplayer-peer.linux.template_debug.arm64.so"
linux.release.arm64 = "./linux/libsteam-multiplayer-peer.linux.template_release.arm64.so"
linux.debug.rv64 = "./linux/libsteam-multiplayer-peer.linux.template_debug.rv64.so"
linux.release.rv64 = "./linux/libsteam-multiplayer-peer.linux.template_release.rv64.so"
macos.debug = "./macos/libsteam-multiplayer-peer.macos.template_debug.universal.dylib"
macos.release = "./macos/libsteam-multiplayer-peer.macos.template_release.universal.dylib"
windows.debug.x86_32 = "./windows/steam-multiplayer-peer.windows.template_debug.x86_32.dll"
windows.release.x86_32 = "./windows/steam-multiplayer-peer.windows.template_release.x86_32.dll"
windows.debug.x86_64 = "./windows/steam-multiplayer-peer.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "./windows/steam-multiplayer-peer.windows.template_release.x86_64.dll"
[dependencies]
linux.x86_64 = { "linux/libsteam_api.so": "" }
linux.arm64 = { "linux/libsteam_api.so": "" }
linux.rv64 = { "linux/libsteam_api.so": "" }
macos.universal = { "macos/libsteam_api.dylib": "" }
windows.x86_64 = { "windows/steam_api64.dll": "" }
windows.x86_32 = { "windows/steam_api.dll": "" }

View File

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

View File

@@ -0,0 +1,3 @@
[gd_scene format=3 uid="uid://bw4do4mo0s5hw"]
[node name="Piton" type="Node3D"]

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,53 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://ceovc780lyj1r"
path="res://.godot/imported/campfire.blend-0f4f394f7ed7f3b3e2d3c3ac81a19ebb.scn"
[deps]
source_file="res://levels/lobby-scene/campfire/campfire.blend"
dest_files=["res://.godot/imported/campfire.blend-0f4f394f7ed7f3b3e2d3c3ac81a19ebb.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
blender/nodes/visible=0
blender/nodes/active_collection_only=false
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/colors=false
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/export_geometry_nodes_instances=false
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true

View File

@@ -0,0 +1,22 @@
extends Node3D
@export var campfire_lit: bool = false
@export var fire_particles: GPUParticles3D
@export var smoke_particles: GPUParticles3D
@export var audio_stream_player_3d: AudioStreamPlayer3D
@export var sfx_files: Array[AudioStreamWAV] = []
func _ready() -> void:
audio_stream_player_3d.finished.connect(play_random_sfx)
play_random_sfx()
func light_campfire():
fire_particles.emitting = true
smoke_particles.emitting = true
func play_random_sfx():
audio_stream_player_3d.stream = sfx_files.pick_random()
audio_stream_player_3d.play()

View File

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

View File

@@ -0,0 +1,144 @@
[gd_scene load_steps=19 format=3 uid="uid://wcsd1tb0quj3"]
[ext_resource type="PackedScene" uid="uid://ceovc780lyj1r" path="res://levels/lobby-scene/campfire/campfire.blend" id="1_5k61m"]
[ext_resource type="Script" uid="uid://mjtng3tgusx0" path="res://levels/lobby-scene/campfire/campfire.gd" id="1_pgdjc"]
[ext_resource type="Texture2D" uid="uid://ciegdylo5csyt" path="res://levels/lobby-scene/campfire/textures/smoke-particle-texture.png" id="2_4swet"]
[ext_resource type="AudioStream" uid="uid://bx01sxorforuo" path="res://levels/lobby-scene/campfire/fire.wav" id="4_u2sse"]
[sub_resource type="Gradient" id="Gradient_5k61m"]
offsets = PackedFloat32Array(0.175439, 0.859649)
colors = PackedColorArray(0, 0, 0, 1, 0.52549, 0.180392, 0.0745098, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_4swet"]
gradient = SubResource("Gradient_5k61m")
[sub_resource type="Curve" id="Curve_pgdjc"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.25, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.393258), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="CurveTexture" id="CurveTexture_wwyeu"]
curve = SubResource("Curve_pgdjc")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_js7yv"]
angle_min = 1.07288e-05
angle_max = 360.0
direction = Vector3(0, 1, 0)
spread = 0.0
initial_velocity_min = 1.0
initial_velocity_max = 4.0
angular_velocity_min = -1.60933e-05
angular_velocity_max = 40.0
gravity = Vector3(0, 0, 0)
linear_accel_min = 0.999998
linear_accel_max = 5.0
scale_min = 0.1
scale_max = 0.6
scale_curve = SubResource("CurveTexture_wwyeu")
color_initial_ramp = SubResource("GradientTexture1D_4swet")
hue_variation_min = -1.0
hue_variation_max = -0.75
turbulence_enabled = true
turbulence_noise_strength = 0.1
turbulence_noise_scale = 10.0
turbulence_influence_min = 0.01
turbulence_influence_max = 0.03
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5k61m"]
transparency = 1
blend_mode = 1
shading_mode = 0
disable_fog = true
vertex_color_use_as_albedo = true
albedo_color = Color(0.352941, 0.117647, 0.0666667, 1)
billboard_mode = 3
billboard_keep_scale = true
particles_anim_h_frames = 1
particles_anim_v_frames = 1
particles_anim_loop = false
[sub_resource type="QuadMesh" id="QuadMesh_p40iq"]
material = SubResource("StandardMaterial3D_5k61m")
[sub_resource type="Gradient" id="Gradient_4swet"]
offsets = PackedFloat32Array(0.175439, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_pgdjc"]
gradient = SubResource("Gradient_4swet")
[sub_resource type="Curve" id="Curve_wwyeu"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.25, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.393258), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="CurveTexture" id="CurveTexture_js7yv"]
curve = SubResource("Curve_wwyeu")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_0feaq"]
angle_min = 1.07288e-05
angle_max = 360.0
direction = Vector3(0, 1, 0)
spread = 0.0
initial_velocity_min = 1.0
initial_velocity_max = 4.0
angular_velocity_min = -1.60933e-05
angular_velocity_max = 40.0
gravity = Vector3(0, 0, 0)
linear_accel_min = 0.999998
linear_accel_max = 2.0
scale_min = 0.1
scale_curve = SubResource("CurveTexture_js7yv")
color_initial_ramp = SubResource("GradientTexture1D_pgdjc")
hue_variation_min = -2.23517e-08
hue_variation_max = 0.03
turbulence_enabled = true
turbulence_noise_strength = 0.1
turbulence_noise_scale = 1.76
turbulence_influence_min = 0.01
turbulence_influence_max = 0.01
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_p40iq"]
transparency = 1
shading_mode = 0
vertex_color_use_as_albedo = true
albedo_texture = ExtResource("2_4swet")
billboard_mode = 3
billboard_keep_scale = true
particles_anim_h_frames = 1
particles_anim_v_frames = 1
particles_anim_loop = false
[sub_resource type="QuadMesh" id="QuadMesh_8eekk"]
material = SubResource("StandardMaterial3D_p40iq")
[node name="Campfire" type="Node3D" node_paths=PackedStringArray("fire_particles", "smoke_particles", "audio_stream_player_3d")]
script = ExtResource("1_pgdjc")
fire_particles = NodePath("FireParticles")
smoke_particles = NodePath("SmokeParticles")
audio_stream_player_3d = NodePath("AudioStreamPlayer3D")
sfx_files = Array[AudioStreamWAV]([ExtResource("4_u2sse")])
[node name="campfire" parent="." instance=ExtResource("1_5k61m")]
[node name="FireParticles" type="GPUParticles3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0211215, 0.220129, -0.0153611)
amount = 500
lifetime = 0.3
explosiveness = 0.08
randomness = 1.0
draw_order = 3
process_material = SubResource("ParticleProcessMaterial_js7yv")
draw_pass_1 = SubResource("QuadMesh_p40iq")
[node name="SmokeParticles" type="GPUParticles3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0211215, 0.220129, -0.0153611)
amount = 100
lifetime = 2.0
explosiveness = 0.06
randomness = 1.0
draw_order = 3
process_material = SubResource("ParticleProcessMaterial_0feaq")
draw_pass_1 = SubResource("QuadMesh_8eekk")
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="."]
stream = ExtResource("4_u2sse")
volume_db = -15.0
unit_size = 5.0

Binary file not shown.

View File

@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://bx01sxorforuo"
path="res://.godot/imported/fire.wav-db183a1afec86c3f7b0347a0f68a8c78.sample"
[deps]
source_file="res://levels/lobby-scene/campfire/fire.wav"
dest_files=["res://.godot/imported/fire.wav-db183a1afec86c3f7b0347a0f68a8c78.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bjlwlqwdnhyqa"
path.s3tc="res://.godot/imported/ashes.png-e3ed397e6960eee2c0384b2e7628d89b.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/campfire/textures/ashes.png"
dest_files=["res://.godot/imported/ashes.png-e3ed397e6960eee2c0384b2e7628d89b.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://mwhsj8t5w8u2"
path.s3tc="res://.godot/imported/log.png-dedb4a0d507c4374c4a0430aa0b04240.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/campfire/textures/log.png"
dest_files=["res://.godot/imported/log.png-dedb4a0d507c4374c4a0430aa0b04240.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ciegdylo5csyt"
path.s3tc="res://.godot/imported/smoke-particle-texture.png-a6c9ad64e49d68633ab3bfabe9f168c2.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/campfire/textures/smoke-particle-texture.png"
dest_files=["res://.godot/imported/smoke-particle-texture.png-a6c9ad64e49d68633ab3bfabe9f168c2.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cwwjn82mmy6oc"
path.s3tc="res://.godot/imported/stone.png-282edc18bd8fc87daf754e087f67344d.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/campfire/textures/stone.png"
dest_files=["res://.godot/imported/stone.png-282edc18bd8fc87daf754e087f67344d.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

View File

@@ -0,0 +1,60 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://b5xb0fsfpn7r3"
path="res://.godot/imported/lobby-terrain.blend-a6c0be77548df4815861d8f088c594f5.scn"
[deps]
source_file="res://levels/lobby-scene/lobby-terrain/lobby-terrain.blend"
dest_files=["res://.godot/imported/lobby-terrain.blend-a6c0be77548df4815861d8f088c594f5.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={
"materials": {
"Material.001": {
"use_external/enabled": true,
"use_external/path": ""
}
}
}
blender/nodes/visible=0
blender/nodes/active_collection_only=false
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/colors=false
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/export_geometry_nodes_instances=false
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dpkeaqjnr3bsb"
path.s3tc="res://.godot/imported/grass.png-72267d35d6d4105c20ad91641e676c75.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/lobby-terrain/textures/grass.png"
dest_files=["res://.godot/imported/grass.png-72267d35d6d4105c20ad91641e676c75.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

View File

@@ -0,0 +1,80 @@
[gd_scene load_steps=10 format=3 uid="uid://bj52j4ew2lfr6"]
[ext_resource type="PackedScene" uid="uid://5vggmy1srgxb" path="res://tools/human-height-reference.tscn" id="1_yyu2g"]
[ext_resource type="PackedScene" uid="uid://bhgahenvxqhec" path="res://levels/lobby-scene/tree/tree.blend" id="3_0u2wx"]
[ext_resource type="PackedScene" uid="uid://b5xb0fsfpn7r3" path="res://levels/lobby-scene/lobby-terrain/lobby-terrain.blend" id="3_f73ky"]
[ext_resource type="PackedScene" uid="uid://csmfxg011xisf" path="res://player/Player.tscn" id="4_0aw1h"]
[ext_resource type="PackedScene" uid="uid://c4cew4af3h306" path="res://levels/lobby-scene/tent/tent.blend" id="4_qjimh"]
[ext_resource type="PackedScene" uid="uid://wcsd1tb0quj3" path="res://levels/lobby-scene/campfire/campfire.tscn" id="5_qjimh"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_f73ky"]
[sub_resource type="Sky" id="Sky_0aw1h"]
sky_material = SubResource("ProceduralSkyMaterial_f73ky")
[sub_resource type="Environment" id="Environment_72fkp"]
background_mode = 2
sky = SubResource("Sky_0aw1h")
ssao_enabled = true
ssil_enabled = true
sdfgi_use_occlusion = true
glow_enabled = true
volumetric_fog_enabled = true
volumetric_fog_density = 0.0
[node name="Lobby" type="Node3D"]
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_72fkp")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="WorldEnvironment"]
transform = Transform3D(0.915754, 0.29917, -0.268128, 0.115653, 0.442845, 0.889108, 0.384733, -0.845214, 0.370937, 0, 0, 0)
shadow_enabled = true
shadow_transmittance_bias = 5.628
[node name="Human-height-reference" parent="." instance=ExtResource("1_yyu2g")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.33741, 0.953, -5.00694)
[node name="lobby-terrain" parent="." instance=ExtResource("3_f73ky")]
[node name="Node3D" type="Node3D" parent="lobby-terrain"]
[node name="tree" parent="lobby-terrain/Node3D" instance=ExtResource("3_0u2wx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.47232, 0, -12.0981)
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("uid://csmfxg011xisf")
spawn_path = NodePath("../Marker3D")
spawn_limit = 1
[node name="Marker3D" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.269072, -8.35164)
[node name="Player" parent="." instance=ExtResource("4_0aw1h")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.444747, 0.992996, -4.71496)
[node name="Campsite" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.724, 0, -17.6721)
[node name="TentPlot1" type="Marker3D" parent="Campsite"]
transform = Transform3D(-0.998887, 0, -0.0471587, 0, 1, 0, 0.0471587, 0, -0.998887, -0.468871, 0.334599, -6.31805)
[node name="tent" parent="Campsite/TentPlot1" instance=ExtResource("4_qjimh")]
[node name="TentPlot2" type="Marker3D" parent="Campsite"]
transform = Transform3D(-0.240973, 0, -0.970532, 0, 1, 0, 0.970532, 0, -0.240973, -6.46887, 0.334599, -2.31805)
[node name="tent" parent="Campsite/TentPlot2" instance=ExtResource("4_qjimh")]
[node name="TentPlot3" type="Marker3D" parent="Campsite"]
transform = Transform3D(0.689594, 0, -0.724196, 0, 1, 0, 0.724196, 0, 0.689594, -4.46887, 0.334599, 4.68195)
[node name="tent" parent="Campsite/TentPlot3" instance=ExtResource("4_qjimh")]
[node name="TentPlot4" type="Marker3D" parent="Campsite"]
transform = Transform3D(-0.0217975, 0, 0.999762, 0, 1, 0, -0.999762, 0, -0.0217975, 6.53113, 0.334599, -2.31805)
[node name="tent" parent="Campsite/TentPlot4" instance=ExtResource("4_qjimh")]
[node name="Campfire" parent="Campsite" instance=ExtResource("5_qjimh")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.392361, 0)

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,53 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c4cew4af3h306"
path="res://.godot/imported/tent.blend-cfe1cab2c3640ecea475631183f479bf.scn"
[deps]
source_file="res://levels/lobby-scene/tent/tent.blend"
dest_files=["res://.godot/imported/tent.blend-cfe1cab2c3640ecea475631183f479bf.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
blender/nodes/visible=0
blender/nodes/active_collection_only=false
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/colors=false
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/export_geometry_nodes_instances=false
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bj1old20eraxq"
path.s3tc="res://.godot/imported/line.png-f1d79c528b79a3f4f23586b0c1ab0a22.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/tent/textures/line.png"
dest_files=["res://.godot/imported/line.png-f1d79c528b79a3f4f23586b0c1ab0a22.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://4wydw131ad3q"
path.s3tc="res://.godot/imported/pins.png-be03801b8319596d167e68e302ab146f.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/tent/textures/pins.png"
dest_files=["res://.godot/imported/pins.png-be03801b8319596d167e68e302ab146f.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://by6dlbdsfkf1c"
path.s3tc="res://.godot/imported/tent-canvas.png-22002e3ff42d8a628cf6a049cdff6002.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/tent/textures/tent-canvas.png"
dest_files=["res://.godot/imported/tent-canvas.png-22002e3ff42d8a628cf6a049cdff6002.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bd53ybrlho0d1"
path.s3tc="res://.godot/imported/leaves.png-530373898a77b84d2e3909cbed29021f.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/tree/textures/leaves.png"
dest_files=["res://.godot/imported/leaves.png-530373898a77b84d2e3909cbed29021f.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cxuxtdscvpcru"
path.s3tc="res://.godot/imported/trunk.png-4d6cd7f252205478b8e4bf2b892c9b44.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://levels/lobby-scene/tree/textures/trunk.png"
dest_files=["res://.godot/imported/trunk.png-4d6cd7f252205478b8e4bf2b892c9b44.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
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=0

Binary file not shown.

View File

@@ -0,0 +1,53 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bhgahenvxqhec"
path="res://.godot/imported/tree.blend-2e97b0c94b4b9f627dfe10b7f953c7fe.scn"
[deps]
source_file="res://levels/lobby-scene/tree/tree.blend"
dest_files=["res://.godot/imported/tree.blend-2e97b0c94b4b9f627dfe10b7f953c7fe.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
blender/nodes/visible=0
blender/nodes/active_collection_only=false
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/colors=false
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/export_geometry_nodes_instances=false
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://chrva3l6shfhg"
path="res://.godot/imported/trunk.png-b162fd3ffcc29a857809c16bdc1c00bb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://levels/lobby-scene/tree/trunk.png"
dest_files=["res://.godot/imported/trunk.png-b162fd3ffcc29a857809c16bdc1c00bb.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@@ -0,0 +1 @@
extends Node

View File

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

View File

@@ -0,0 +1,296 @@
extends Node
var is_owned: bool = false
var steam_app_id: int = 480
var steam_id: int = 0
var steam_username: String = ""
var lobby_id = 0
var lobby_max_members = 4
var lobby_members: Array = []
var steam_initialized: bool = false
var peer: SteamMultiplayerPeer
func _ready() -> void:
OS.set_environment("SteamAppId", str(steam_app_id))
OS.set_environment("SteamGameId", str(steam_app_id))
steam_initialized = init_steam()
if not steam_initialized:
print("!!! Steam did not initialize. Multiplayer will be disabled.")
return
# Connect Steam lobby signals
Steam.lobby_created.connect(_on_lobby_created)
Steam.lobby_joined.connect(_on_lobby_joined)
#Steam.lobby_match_list.connect(_on_lobby_match_list)
Steam.lobby_chat_update.connect(_on_lobby_chat_update)
Steam.lobby_data_update.connect(_on_lobby_data_update)
#Steam.join_requested.connect(_on_lobby_join_requested)
Steam.persona_state_change.connect(_on_persona_change)
# Setup multiplayer signals
multiplayer.peer_connected.connect(_on_peer_connected)
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
multiplayer.connected_to_server.connect(_on_connected_to_server)
multiplayer.connection_failed.connect(_on_connection_failed)
multiplayer.server_disconnected.connect(_on_server_disconnected)
Steam.p2p_session_request.connect(_on_p2p_session_request)
check_command_line()
func _on_p2p_session_request(steam_id_remote: int) -> void:
## ADDED: More detailed logging to confirm P2P acceptance.
print("[P2P] ==> Session request from: %s. Accepting." % steam_id_remote)
var accepted = Steam.acceptP2PSessionWithUser(steam_id_remote)
if not accepted:
print("[P2P] !!! Failed to accept P2P session with %s." % steam_id_remote)
func _process(delta):
## ADDED: Guard clause in case Steam fails to initialize.
if not steam_initialized:
return
Steam.run_callbacks()
if Input.is_action_just_pressed("interact"):
## ADDED: Replaced simple print with a detailed diagnostic function.
log_multiplayer_info()
func check_command_line() -> void:
var args: Array = OS.get_cmdline_args()
if args.size() > 0:
if args[0] == "+connect_lobby":
if args.size() > 1 and int(args[1]) > 0:
print("Command line lobby ID: %s" % args[1])
join_lobby(int(args[1]))
func init_steam() -> bool:
var response: Dictionary = Steam.steamInitEx()
print("Steam init response: %s " % response)
if response['status'] > 0:
print("!!! Failed to init steam! Code: %s " % response)
return false
is_owned = Steam.isSubscribed()
steam_id = Steam.getSteamID()
steam_username = Steam.getPersonaName()
print("Steam initialized successfully for %s (ID: %s)." % [steam_username, steam_id])
if !is_owned:
print("!!! WARNING: Steam reports you do not own App ID %s." % steam_app_id)
# You might want to return false here in a real game
# return false
return true
func setup_multiplayer_peer(is_host: bool = false) -> void:
## ADDED: Check if a peer is already active before creating a new one.
if multiplayer.multiplayer_peer and multiplayer.multiplayer_peer.get_connection_status() != MultiplayerPeer.CONNECTION_DISCONNECTED:
print("[Multiplayer] Peer already exists. Disconnecting old one.")
multiplayer.multiplayer_peer.close()
peer = SteamMultiplayerPeer.new()
if is_host:
print("[Multiplayer] Creating Host...")
var err = peer.create_host(0) ## REMOVED: Channel is handled by the peer automatically now.
if err != OK:
print("[Multiplayer] !!! Failed to create host. Error: %s" % err)
return
multiplayer.multiplayer_peer = peer
print("[Multiplayer] Host created successfully. My Peer ID: %s" % multiplayer.get_unique_id())
else:
if lobby_id == 0:
print("[Multiplayer] !!! Cannot create client, not in a lobby.")
return
var host_id = Steam.getLobbyOwner(lobby_id)
print("[Multiplayer] Creating Client, attempting to connect to host: %s" % host_id)
var err = peer.create_client(host_id, 0) ## REMOVED: Channel is handled by the peer automatically.
if err != OK:
print("[Multiplayer] !!! Failed to create client. Error: %s" % err)
return
multiplayer.multiplayer_peer = peer
print("[Multiplayer] Client peer created. Waiting for connection...")
func create_lobby():
if lobby_id == 0:
print("Creating lobby...")
Steam.createLobby(Steam.LOBBY_TYPE_FRIENDS_ONLY, lobby_max_members)
func _on_lobby_created(connect: int, this_lobby_id: int):
if connect == 1:
lobby_id = this_lobby_id
print("Lobby created with id `%s`" % lobby_id)
Steam.setLobbyJoinable(lobby_id, true)
Steam.setLobbyData(lobby_id, "name", steam_username + "'s Lobby")
Steam.setLobbyData(lobby_id, "mode", "Splunk")
Steam.allowP2PPacketRelay(true)
setup_multiplayer_peer(true) # Setup as host
else :
print("!!! Failed to create lobby.")
func join_lobby(this_lobby_id: int):
print("Attempting to join lobby: %s" % this_lobby_id)
lobby_members.clear()
Steam.joinLobby(this_lobby_id)
func _on_lobby_joined(this_lobby_id: int, permissions: int, locked: bool, response: int):
if response == Steam.CHAT_ROOM_ENTER_RESPONSE_SUCCESS:
lobby_id = this_lobby_id
print("Successfully joined lobby: %s" % lobby_id)
get_lobby_members()
# FIXED: Use Steam.getLobbyOwner() to determine if we should be host or client
var lobby_owner_id = Steam.getLobbyOwner(lobby_id)
var am_i_owner = (lobby_owner_id == steam_id)
print("[Multiplayer] Lobby Owner: %s, My Steam ID: %s, Am I Owner?: %s" % [lobby_owner_id, steam_id, am_i_owner])
if not am_i_owner:
print("[Multiplayer] I am not the lobby owner, setting up as client...")
setup_multiplayer_peer(false) # Setup as client
else:
print("[Multiplayer] I am the lobby owner, but multiplayer peer should already be set up as host.")
else:
## ADDED: Log the specific reason for the join failure.
print("!!! Failed to join lobby. Reason: %s" % get_join_fail_reason(response))
func get_lobby_members() -> void:
lobby_members.clear()
if lobby_id == 0: return
var num_members = Steam.getNumLobbyMembers(lobby_id)
print("--- Refreshing Lobby Members (%s) ---" % num_members)
for i in range(num_members):
var member_id = Steam.getLobbyMemberByIndex(lobby_id, i)
var member_name = Steam.getFriendPersonaName(member_id)
lobby_members.append({
"steam_id": member_id,
"steam_name": member_name
})
print(" - %s (%s)" % [member_name, member_id])
print("---------------------------------")
func _on_lobby_data_update(lobby: int, user: int, success: int) -> void:
if success:
if lobby == user:
print("Lobby data for lobby %s has been updated." % lobby)
var lobby_name = Steam.getLobbyData(lobby, "name")
print(" > New lobby name: %s" % lobby_name)
else:
print("Data for member %s in lobby %s has been updated." % [user, lobby])
func _on_persona_change(steam_id_changed: int, flag: int) -> void:
# This can be spammy, but useful for debugging name changes.
# print("Persona state changed for %s. Refreshing lobby members." % steam_id_changed)
get_lobby_members()
func leave_lobby() -> void:
pass
func _on_lobby_chat_update(lobby_id_update: int, user_changed_id: int, user_making_change_id: int, chat_state: int):
var state_string = "UNKNOWN"
match chat_state:
Steam.CHAT_MEMBER_STATE_CHANGE_ENTERED: state_string = "ENTERED"
Steam.CHAT_MEMBER_STATE_CHANGE_LEFT: state_string = "LEFT"
Steam.CHAT_MEMBER_STATE_CHANGE_DISCONNECTED: state_string = "DISCONNECTED"
Steam.CHAT_MEMBER_STATE_CHANGE_KICKED: state_string = "KICKED"
Steam.CHAT_MEMBER_STATE_CHANGE_BANNED: state_string = "BANNED"
print("[Lobby] Chat Update: User %s has %s." % [user_changed_id, state_string])
# Any change in lobby membership should trigger a refresh.
get_lobby_members()
func _on_peer_connected(id: int) -> void:
print("[Multiplayer] ✅ Peer connected: %s" % id)
# It's good practice to re-check lobby members when a peer connects successfully.
get_lobby_members()
func _on_peer_disconnected(id: int) -> void:
print("[Multiplayer] ❌ Peer disconnected: %s" % id)
func _on_connected_to_server() -> void:
print("[Multiplayer] ✅ Successfully connected to the host.")
print("[Multiplayer] - My Peer ID is now: %s" % multiplayer.get_unique_id())
func _on_connection_failed() -> void:
print("[Multiplayer] ❌ Connection to the host failed.")
func _on_server_disconnected() -> void:
print("[Multiplayer] ❌ Disconnected from the host.")
## ADDED: New function to log all relevant multiplayer and lobby information.
func log_multiplayer_info():
print("\n--- DIAGNOSTIC INFO ---")
print("## Multiplayer Status:")
if multiplayer.multiplayer_peer:
print(" - Peer State: Active")
print(" - Connection Status: %s" % get_connection_status_string(multiplayer.multiplayer_peer.get_connection_status()))
print(" - Is Server?: %s" % multiplayer.is_server())
print(" - My Peer ID: %s" % multiplayer.get_unique_id())
print(" - Connected Peer IDs: %s" % multiplayer.get_peers())
else:
print(" - Peer State: Inactive (null)")
print("\n## Steam Lobby Info:")
print(" - In Lobby?: %s" % (lobby_id != 0))
print(" - Lobby ID: %s" % lobby_id)
if lobby_id != 0:
print(" - Lobby Owner Steam ID: %s" % Steam.getLobbyOwner(lobby_id))
print(" - My Steam ID: %s" % steam_id)
print(" - Lobby Members Array (%s):" % lobby_members.size())
for member in lobby_members:
print(" - %s (%s)" % [member.steam_name, member.steam_id])
print("-------------------------\n")
## ADDED: Helper function to get a human-readable string for connection status.
func get_connection_status_string(status: int) -> String:
match status:
MultiplayerPeer.CONNECTION_DISCONNECTED: return "Disconnected"
MultiplayerPeer.CONNECTION_CONNECTING: return "Connecting"
MultiplayerPeer.CONNECTION_CONNECTED: return "Connected"
_: return "Unknown Status"
func get_join_fail_reason(response: int) -> String:
match response:
Steam.CHAT_ROOM_ENTER_RESPONSE_DOESNT_EXIST: return "Lobby no longer exists"
Steam.CHAT_ROOM_ENTER_RESPONSE_NOT_ALLOWED: return "Not allowed to join"
Steam.CHAT_ROOM_ENTER_RESPONSE_FULL: return "Lobby is full"
Steam.CHAT_ROOM_ENTER_RESPONSE_ERROR: return "Unknown error"
Steam.CHAT_ROOM_ENTER_RESPONSE_BANNED: return "You are banned"
Steam.CHAT_ROOM_ENTER_RESPONSE_LIMITED: return "Limited account"
Steam.CHAT_ROOM_ENTER_RESPONSE_CLAN_DISABLED: return "Lobby is locked"
Steam.CHAT_ROOM_ENTER_RESPONSE_COMMUNITY_BAN: return "Community locked"
Steam.CHAT_ROOM_ENTER_RESPONSE_MEMBER_BLOCKED_YOU: return "A member blocked you"
Steam.CHAT_ROOM_ENTER_RESPONSE_YOU_BLOCKED_MEMBER: return "You blocked a member"
_: return "Unknown reason"

View File

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

78
splunk/player/Player.tscn Normal file
View File

@@ -0,0 +1,78 @@
[gd_scene load_steps=8 format=3 uid="uid://csmfxg011xisf"]
[ext_resource type="Script" uid="uid://dopyfulbw2mx5" path="res://player/player.gd" id="1_ulp21"]
[ext_resource type="PackedScene" uid="uid://8phs2e161db1" path="res://ui/multiplayer-debug-ui/multiplayer-debug-ui.tscn" id="2_3c3w1"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ehsmr"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_ulp21"]
radius = 0.3
height = 1.5
[sub_resource type="PrismMesh" id="PrismMesh_3c3w1"]
size = Vector3(0.5, 0.5, 0.5)
[sub_resource type="SphereMesh" id="SphereMesh_wnvi2"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_ulp21"]
properties/0/path = NodePath(".:position")
properties/0/spawn = true
properties/0/replication_mode = 2
properties/1/path = NodePath(".:rotation")
properties/1/spawn = true
properties/1/replication_mode = 2
properties/2/path = NodePath("Label3D:text")
properties/2/spawn = true
properties/2/replication_mode = 1
[node name="Player" type="CharacterBody3D"]
collision_layer = 2
collision_mask = 3
script = ExtResource("1_ulp21")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.399442, 0.0644827)
cull_mask = 1048573
current = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_ehsmr")
[node name="Mesh" type="Node3D" parent="."]
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0, 0, 0)
[node name="MeshInstance3D" type="MeshInstance3D" parent="Mesh"]
transform = Transform3D(1, 0, 0, 0, 0.89961, 0, 0, 0, 1, 0, -0.318288, 0)
layers = 2
mesh = SubResource("CapsuleMesh_ulp21")
skeleton = NodePath("../..")
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Mesh"]
transform = Transform3D(1.41676, 0, 0, 0, 1.31718, 0, 0, 0, 1.22029, 0, 0.415995, 0)
layers = 2
mesh = SubResource("PrismMesh_3c3w1")
skeleton = NodePath("../..")
[node name="MeshInstance3D3" type="MeshInstance3D" parent="Mesh"]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, -0.0855882, 0.409407, 0.293333)
layers = 2
mesh = SubResource("SphereMesh_wnvi2")
skeleton = NodePath("../..")
[node name="MeshInstance3D4" type="MeshInstance3D" parent="Mesh"]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0.0770122, 0.409407, 0.293333)
layers = 2
mesh = SubResource("SphereMesh_wnvi2")
skeleton = NodePath("../..")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_ulp21")
[node name="Label3D" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.887858, 0)
billboard = 1
text = "Username"
[node name="CanvasLayer" type="CanvasLayer" parent="."]
[node name="Multiplayer-debug-ui" parent="CanvasLayer" instance=ExtResource("2_3c3w1")]

60
splunk/player/player.gd Normal file
View File

@@ -0,0 +1,60 @@
extends CharacterBody3D
@export var speed = 5.0
@export var jump_velocity = 4.5
@export var mouse_sensitivity = 0.002
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var camera_node: Camera3D
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
camera_node = $Camera3D # Assuming Camera3D is a direct child
$Label3D.text = SteamManager.steam_username
func _physics_process(delta):
# Apply gravity
if not is_on_floor():
velocity.y -= gravity * delta
# Handle Jump
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# Get the input direction and apply movement
var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if is_on_floor():
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
else:
# Air control
velocity.x = lerp(velocity.x, direction.x * speed, delta * 5.0)
velocity.z = lerp(velocity.z, direction.z * speed, delta * 5.0)
move_and_slide()
func _input(event):
if event is InputEventMouseMotion:
# Rotate the CharacterBody3D around the Y-axis for horizontal look
rotate_y(-event.relative.x * mouse_sensitivity)
# Rotate the Camera3D around its local X-axis for vertical look
var change = -event.relative.y * mouse_sensitivity
var new_x_rotation = camera_node.rotation.x + change
camera_node.rotation.x = clamp(new_x_rotation, deg_to_rad(-90), deg_to_rad(90))
if event.is_action_pressed("ui_cancel"): # Typically Escape key
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if event.is_action_pressed("toggle_watch"):
$"CanvasLayer/Multiplayer-debug-ui".visible = !$"CanvasLayer/Multiplayer-debug-ui".visible

Some files were not shown because too many files have changed in this diff Show More