GDScript (Godot) SDK
Installation (Coming Soon)
Section titled “Installation (Coming Soon)”Install from the Godot Asset Library:
- Open your Godot project
- Go to AssetLib tab
- Search for “Sieve Moderation”
- Click Install
Quick Example (Coming Soon)
Section titled “Quick Example (Coming Soon)”extends Node
var sieve = SieveClient.new("mod_live_your_key")
func _ready(): add_child(sieve)
func moderate_chat(message: String, username: String): var result = await sieve.moderate_text(message, "chat", username)
match result.action: "block": show_warning("Message blocked: " + result.primary_category) "flag": send_message(message) # Show but log "allow": send_message(message)Using the API Directly
Section titled “Using the API Directly”Until the addon is available, use Godot’s HTTPRequest node to call the Sieve API:
extends Node
const API_URL = "https://api.getsieve.dev/v1/moderate/text"var api_key = "mod_live_your_key" # Load from config in production
func moderate_message(message: String, username: String) -> void: var http = HTTPRequest.new() add_child(http) http.request_completed.connect(_on_moderation_response.bind(http, message))
var headers = [ "Authorization: Bearer " + api_key, "Content-Type: application/json" ]
var body = JSON.stringify({ "text": message, "context": "chat", "username": username })
http.request(API_URL, headers, HTTPClient.METHOD_POST, body)
func _on_moderation_response(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray, http: HTTPRequest, original_message: String) -> void: http.queue_free()
if result != HTTPRequest.RESULT_SUCCESS or response_code != 200: # Fail open -- show the message if API is unreachable _display_message(original_message) return
var json = JSON.parse_string(body.get_string_from_utf8())
match json["action"]: "block": _show_blocked_warning(json["primary_category"]) "flag": _display_message(original_message) _log_flagged(json) "allow": _display_message(original_message)
func _display_message(message: String) -> void: # Add to your chat UI pass
func _show_blocked_warning(category: String) -> void: # Show warning to the player pass
func _log_flagged(result: Dictionary) -> void: # Log flagged content for review pass# SieveModeration.gd -- Add as an Autoload in Project Settingsextends Node
const API_URL = "https://api.getsieve.dev/v1/moderate/text"var api_key: String
signal moderation_complete(original_text: String, result: Dictionary)
func _ready(): # Load API key from a config file (never hardcode in production) var config = ConfigFile.new() config.load("user://sieve.cfg") api_key = config.get_value("api", "key", "")
func moderate(text: String, context: String = "chat", username: String = "") -> void: var http = HTTPRequest.new() add_child(http) http.request_completed.connect( _on_response.bind(http, text))
var headers = [ "Authorization: Bearer " + api_key, "Content-Type: application/json" ]
var body = JSON.stringify({ "text": text, "context": context, "username": username })
http.request(API_URL, headers, HTTPClient.METHOD_POST, body)
func _on_response(result: int, code: int, headers: PackedStringArray, body: PackedByteArray, http: HTTPRequest, original_text: String) -> void: http.queue_free()
if result != HTTPRequest.RESULT_SUCCESS or code != 200: moderation_complete.emit(original_text, {"action": "allow"}) return
var json = JSON.parse_string(body.get_string_from_utf8()) moderation_complete.emit(original_text, json)# ChatUI.gd -- Connect to the autoload signalextends Control
func _ready(): SieveModeration.moderation_complete.connect(_on_moderation)
func _on_send_pressed(): var message = $LineEdit.text SieveModeration.moderate(message, "chat", Global.player_name) $LineEdit.clear()
func _on_moderation(text: String, result: Dictionary): match result["action"]: "block": $WarningLabel.text = "Message blocked" $WarningLabel.visible = true _: add_chat_message(text)Username Moderation
Section titled “Username Moderation”Moderate player display names during character creation or name changes:
func _on_name_submit_pressed(): var display_name = $NameInput.text
var http = HTTPRequest.new() add_child(http) http.request_completed.connect(_on_name_check.bind(http, display_name))
var headers = [ "Authorization: Bearer " + api_key, "Content-Type: application/json" ]
var body = JSON.stringify({ "text": display_name, "context": "username" })
http.request(API_URL, headers, HTTPClient.METHOD_POST, body)
func _on_name_check(result: int, code: int, headers: PackedStringArray, body: PackedByteArray, http: HTTPRequest, name: String): http.queue_free()
var json = JSON.parse_string(body.get_string_from_utf8())
if json["action"] != "allow": $ErrorLabel.text = "That name is not allowed. Please choose another." $ErrorLabel.visible = true else: accept_name(name)Latency Tips for Games
Section titled “Latency Tips for Games”- Fire and forget: Send the moderation request when the player submits a message. Display it immediately and retroactively hide it if blocked. Most players won’t notice the sub-200ms window.
- Preemptive allow: For Tier 0 catches (60-70% of requests), the response comes back in under 5ms — effectively instant.
- Timeout: Set a 1-2 second timeout on the HTTPRequest. If moderation doesn’t respond, fail open.
# Fire-and-forget patternfunc send_chat(message: String): # Show immediately add_chat_bubble(message, Global.player_name)
# Moderate async SieveModeration.moderate(message, "chat", Global.player_name)
func _on_moderation(text: String, result: Dictionary): if result["action"] == "block": remove_chat_bubble(text) show_warning("Your message was removed.")