Godot Version
4.5
Question
Can managing network logic in the scene tree be problematic?
example:
class_name Network
extends SceneTree
const PORT: int = 10000
const HOST: String = "ws://localhost:%d/connect" % PORT
const TICK: float = 0.10
var _tick_rate: float
var _finished: bool = false
var _peer := WebSocketPeer.new()
func _initialize() -> void:
_peer.free()
func _process(delta: float) -> bool:
_tick_rate += delta
if _tick_rate >= TICK:
_tick_rate -= TICK
_tick()
return _finished
func generate_id(value: int) -> String:
var alphabet: String = "PQRSTUVWXYZ0123456789ABCDEFGHIJKLMNO"
var result: String = ""
var number: int = abs(value)
while number > 0:
var index: int = int(number % alphabet.length())
result = alphabet[index] + result
number = int(number / 36.0)
while result.length() < 3:
result = alphabet[0] + result
return result
func _tick() -> void:
pass
class Connection:
signal connecting
signal connected
signal open
signal closing
signal closed
enum State {
## Socket has been created. The connection is not yet open.
STATE_CONNECTING,
STATE_CONNECTED,
## The connection is open and ready to communicate.
STATE_OPEN,
## The connection is in the process of closing. This means a close request has been sent to the remote peer but confirmation has not been received.
STATE_CLOSING,
## The connection is closed or couldn't be opened.
STATE_CLOSED,
}
var id: int
var peer: WebSocketPeer
var headers: PackedStringArray
var session_id: String
var auth_token: String
var _connected: bool
static func from_stream(stream: StreamPeerTCP) -> Connection:
var new_connection := Connection.new(true)
new_connection.peer.accept_stream(stream)
return new_connection
static func from_websocket(ws: WebSocketPeer) -> Connection:
var new_connection := Connection.new(false)
new_connection.peer = ws
return new_connection
func _init(create_id: bool) -> void:
id = get_instance_id() if create_id else id
peer = WebSocketPeer.new()
func connect_to_url(url: String) -> Error:
return peer.connect_to_url(url)
func poll() -> void:
peer.poll()
match get_state():
Connection.State.STATE_CONNECTING:
connecting.emit()
Connection.State.STATE_OPEN:
if _connected:
open.emit()
else:
_connected = true
connected.emit()
Connection.State.STATE_CLOSING:
closing.emit()
Connection.State.STATE_CLOSED:
closed.emit()
func get_state() -> WebSocketPeer.State:
return peer.get_ready_state()
func add_header(header: String) -> void:
headers.push_back(header)
func get_query() -> String:
var parts := []
for header: String in headers:
var key_value: PackedStringArray = header.split(": ", false, 2)
if key_value.size() == 2:
var key = key_value.get(0).uri_encode()
var value = key_value.get(1).uri_encode()
parts.append("%s=%s" % [key, value])
return "?%s" % "&".join(parts) if parts.size() > 0 else ""
class_name Game
extends Network
# client logic
class_name Server
extends Network
# server logic
