HathoraHTTPRequest
A

Publisher

arkelen

HathoraHTTPRequest

Tools
HTTPRequest API Networking GDScript Hathora Integration V3 Room

HathoraHTTPRequest is a Godot 4.x plugin that extends HTTPRequest node to provide an easy access to Hathora API endpoints from GDScript.

plugin logo

HathoraHTTPRequest

What is it ?

HathoraHTTPRequest is a Godot 4.x plugin that extends HTTPRequest node to provide an easy access to Hathora API endpoints from GDScript.

You can find a complete description of the API on the Hathora website :

Disclaimer

I (the author of this plugin) am not part of Hathora company. I don't own any right or part of their work. This plugin is just an interface to ease the access of their API.

Licence

This plugin is under MIT license. Please see LICENSE file for more details.

Updates

  • 2023/November/22: Missing endpoint "UpdateRoomConfig" addition + roomConfig and 204 response body fixes.
  • 2023/September/14: Deprecated V2 Lobby endpoints are removed and replaced with new V3 ones.

How to use

Installation

If available, this plugin can be installed in your project from the Godot Asset Library. Or make a copy of this repo in your project addons folder and add/activate the extension.

Usage

Example with the editor :

Add a new child HathoraHTTPRequest node to your scene.

scene tree add child

Once added, your scene tree should be similar to this :

scene tree setup

And then connect the signals of HathoraHTTPRequest node to your node script. The error signal is recommanded to be subscribed in order to be informed when an error occurs. Other signals depend on your needs. Here in this example since we call the function login_anonymous we want to subscribe to the login anonymous response signal which will be triggered on login success.

connected signals

Once the signals connected, your script should looks like this :

extends Node

var app_id = "your-hathora-app-id"

# Called when the node enters the scene tree for the first time.
func _ready():
	$HathoraHTTPRequest.login_anonymous(app_id)

func _on_HathoraHTTPRequest_hathora_request_login_anonymous_result(login_anonymous_response_data):
	print (login_anonymous_response_data.token)

func _on_HathoraHTTPRequest_hathora_request_error(error_type, error_data):
	print (error_type, " ", error_data)

The login_anonymous function will be called when your node is ready. This function takes a parameter as input which is your Hathora application id you want to interact with.

On success, the function _on_HathoraHTTPRequest_hathora_request_login_anonymous_result will be called by the signal and will print the token which is part of the login API endpoint response.

On failure, the function _on_HathoraHTTPRequest_hathora_request_error will be called by the signal and will prints error details.

And that's all, with this basic code you did setup a call to the Hathora API that will be executed when you play this scene.

But if you prefer setup the same behavior by code that's also possible:

var hathora_http_request = HathoraHttpRequest.new()
hathora_http_request.connect("hathora_request_error", self, "_on_HathoraHTTPRequest_hathora_request_error")
hathora_http_request.connect("hathora_request_login_anonymous_result", self, "_on_HathoraHTTPRequest_hathora_request_login_anonymous_result")
add_child(hathora_http_request)
hathora_http_request.login_anonymous(app_id)

Export variables

The node HathoraHTTPRequest has 3 exported variables.

You can set them through the editor inspector :

export variables

Or directly by code if you prefer :

# with a HathoraHTTPRequest instanciated as a child of the scene tree :
	$HathoraHTTPRequest.with_dev_endpoints = false
	$HathoraHTTPRequest.verbose = false
	$HathoraHTTPRequest.headless_print = false
# or with a HathoraHTTPRequest instanciated by code :
	var hathora_http_request = HathoraHttpRequest.new()
	hathora_http_request.with_dev_endpoints = false
	hathora_http_request.verbose = false
	hathora_http_request.headless_print = false

with_dev_endpoints

This variable is a boolean. When its value is True, your personnal hathora dev token is read from the operating system ENV var named HATHORA_DEV_TOKEN. It allows the code to pass this token along the call to API endpoint which require it. Typically each endpoints that performs an action on server side or on your (the game developper) behalf requires this dev token. This ENV variable should NEVER be present in your game client distributed to player. It should only be declared on Hathora system where your game server is running. You can declare this ENV variable when you deploy your application or modify it on Hathora website console. If you're coding a admin backend that you will not distribute to clients, you can declare this ENV variable in your script with a GDScript method.

verbose

This variable is a boolean. When its value is True, every input and output parameters of each HTTPRequest sent to the Hathora API will print data schema and data content. It's usefull when coding and debugging but your should turn it off (False) as soon as possible. Especially on a server application since printing to the console slows down the code execution.

Below are a few examples of what you can except as printed informations: verbose examples

headless_print

This variable is a boolean. When its value is True, every print calls will use the GDScript printerr instead. That's usefull on a server application deployed on Hathora system. By default the linux binary used to execute your server code doesn't print data to standard output for performance reasons. So if you really want to see the HathoraHTTPRequest prints when verbose is True, then turn this variable to True also. Remember to turn it off once you've finished your test/debug. Meanwhile, every prints will be displayed in the Hathora room console log.

API Endpoint function signatures

AuthV1

func login_anonymous(app_id:String, callback:Callback = null) -> void:
func login_nickname(app_id:String, nickname:String, callback:Callback = null) -> void:
func login_google(app_id:String, id_token:String, callback:Callback = null) -> void:

DiscoveryV1

func get_ping_service_endpoints(callback:Callback = null) -> void:

LobbyV3

func create_lobby(app_id:String, visibility:String, room_config, region:String, short_code:String = "", callback:Callback = null) -> void:
func list_active_public_lobbies(app_id:String, region: String, callback:Callback = null) -> void:
func get_lobby_info_by_room_id(app_id:String, room_id:String, callback:Callback = null) -> void:
func get_lobby_info_by_short_code(app_id:String, short_code:String, callback:Callback = null) -> void:

ProcessesV1

func get_running_processes(app_id:String, region:String = "", callback:Callback = null) -> void:
func get_stopped_processes(app_id:String, region:String = "", callback:Callback = null) -> void:
func get_process_info(app_id:String, process_id:String, callback:Callback = null) -> void:

RoomV2

func create_room(app_id:String, room_config, region: String, room_id:String = "", callback:Callback = null) -> void:
func get_room_info(app_id:String, room_id:String, callback:Callback = null) -> void:
func get_active_rooms_for_process(app_id:String, process_id:String, callback:Callback = null) -> void:
func get_inactive_rooms_for_process(app_id:String, process_id:String, callback:Callback = null) -> void:
func destroy_room(app_id:String, room_id:String, callback:Callback = null) -> void:
func suspend_room(app_id:String, room_id:String, callback:Callback = null) -> void:
func get_connection_info(app_id:String, room_id:String, callback:Callback = null) -> void:
func update_room_config(app_id:String, room_id:String, room_config, callback:Callback = null) -> void:

Additional informations

  • Note that not every available Hathora API endpoints are wrapped in this plugin. Some are missing but are mainly usefull for designing a backend. The available functions in the plugin are all the necessary endpoints you need to create client/server applications for Hathora cloud system. In the future, other function could be added for the remaining endpoints.
  • Each function corresponds to an endpoint in the Hathora API, thus they have the same parameters. May be optional or required.
  • Each function has an extra parameter which is not part of the endpoint parameters. It can be used to specify a function in your project to call back once the request is responded. It replaces the signal system and allow to specifically call a different function to treat the response instead of the one which is connected to the signal. So you can use this callback technic all by itself, or mix it with the signals technic or not at all it's up to you. It just may be usefull in some situation when you want to treat a particular reponse in a different way than other ones for the same HathoraHTTPRequest function. In order to use the special callback, use the HathoraHTTPRequest.Callback class object. Below a simple example. The first login_anonymous call will see its response treated by the signal while the second one will see its response treated in the _on_alternative_login_anonymous_callback_response function. Note that you can pass along the callback a parameter of your choice with any type.
extends Node

var app_id = "your-hathora-app-id"

# Called when the node enters the scene tree for the first time.
func _ready():
	$HathoraHTTPRequest.login_anonymous(app_id)
	$HathoraHTTPRequest.login_anonymous(app_id, HathoraHttpRequest.Callback.new(self, "_on_alternative_login_anonymous_callback_response", "my_param_of_any_type"))

func _on_HathoraHTTPRequest_hathora_request_login_anonymous_result(login_anonymous_response_data):
	print (login_anonymous_response_data.token)

func _on_HathoraHTTPRequest_hathora_request_error(error_type, error_data):
	print (error_type, " ", error_data)

func _on_alternative_login_anonymous_callback_response(login_anonymous_response_data, user_parameter):
	print ("token: ", login_anonymous_response_data.token, " user_param: ", user_parameter)

Signals

Here's the list of signals you can subsribe from with their respective parameters types :

  • hathora_request_error(error_type, error_data)
    • error_type:int see HathoraHTTPRequest.ERROR_TYPE
    • error_data:String or Dictionary depending on error type
  • hathora_request_login_anonymous_result(login_anonymous_response_data)
    • login_anonymous_response_data:LoginAnonymousResponseData
  • hathora_request_login_nickname_result(login_nickname_response_data)
    • login_nickname_response_data:LoginNicknameResponseData
  • hathora_request_login_google_result(login_google_response_data)
    • login_google_response_data:LoginGoogleResponseData
  • hathora_request_get_ping_service_endpoints_result(get_ping_service_endpoints_response_data)
    • get_ping_service_endpoints_response_data:Array of PingServiceEndpointData
  • hathora_request_create_lobby_result(create_lobby_response_data)
    • create_lobby_response_data:CreateLobbyResponseData
  • hathora_request_list_active_public_lobbies_result(list_active_public_lobbies_response_data)
    • list_active_public_lobbies_response_data:Array of LobbyData
  • hathora_request_get_lobby_info_result(get_lobby_info_response_data)
    • get_lobby_info_response_data:GetLobbyInfoResponseData
  • hathora_request_get_running_processes_result(get_running_processes_response_data)
    • get_running_processes_response_data:Array of RunningProcessData
  • hathora_request_get_stopped_processes_result(get_stopped_processes_response_data)
    • get_stopped_processes_response_data:Array of ProcessInfoData
  • hathora_request_get_process_info_result(get_process_info_response_data)
    • get_process_info_response_data:ProcessInfoData
  • hathora_request_create_room_result(create_room_response_data)
    • create_room_response_data:CreateRoomResponseData
  • hathora_request_get_room_info_result(get_room_info_response_data)
    • get_room_info_response_data:GetRoomInfoResponseData
  • hathora_request_get_active_rooms_for_process_result(get_active_rooms_for_process_response_data)
    • get_active_rooms_for_process_response_data:Array of RoomData
  • hathora_request_get_inactive_rooms_for_process_result(get_inactive_rooms_for_process_response_data)
    • get_inactive_rooms_for_process_response_data:Array of RoomData
  • hathora_request_destroy_room_result()
    • this signal has no parameter
  • hathora_request_suspend_room_result()
    • this signal has no parameter
  • hathora_request_get_connection_info_result(get_connection_info_response_data)
    • get_connection_info_response_data:GetConnectionInfoResponseData
  • hathora_request_update_room_config()
    • this signal has no parameter

Enums

HathoraHTTPRequest.ERROR_TYPE defines each error type the HathoraHTTPRequest can raise

enum ERROR_TYPE {HATHORA_RESULT, JSON_PARSER, HTTP_REQUEST}

HathoraHTTPRequest.REGION defines every possible Hathora region

const REGION:Dictionary = {
	SEATTLE = "Seattle",
	WASHINGTON_DC = "Washington_DC",
	CHICAGO = "Chicago",
	LONDON = "London",
	FRANKFURT = "Frankfurt",
	MUMBAI = "Mumbai",
	SINGAPORE = "Singapore",
	TOKYO = "Tokyo",
	SYDNEY = "Sydney",
	SAO_PAULO = "Sao_Paulo",
}

HathoraHTTPRequest.STATUS defines Hathora room status

const STATUS:Dictionary = {
	SCHEDULING = "scheduling",
	ACTIVE = "active",
	SUSPENDED = "suspended",
	DESTROYED = "destroyed",
}

HathoraHTTPRequest.DEFAULT_VARIABLE defines the default variables accessible in Hathora system

const DEFAULT_VARIABLE:Dictionary = {
	HATHORA_APP_ID = "HATHORA_APP_ID",
	HATHORA_APP_SECRET = "HATHORA_APP_SECRET",
	HATHORA_PROCESS_ID = "HATHORA_PROCESS_ID",
	HATHORA_REGION = "HATHORA_REGION",
}

Environment variables

The function get_environment_variable(env_var_name:String) member of HathoraHTTPRequest class can be used to read an ENV var. You have to specify as parameter which ENV var you need to get. HathoraHTTPRequest.DEFAULT_VARIABLE can be used or any string if you have declared your own variables in your Hathora application settings.

Further details on Hathora ENV var can be found here :