The UGC API covers replays, screenshots, custom levels, mods, and other player-owned files.
UGC types
| Type | Value | Use for |
|---|---|---|
screenshot | 0 | Still captures |
video | 1 | Clips or recordings |
community | 2 | Levels, mods, maps |
game_managed | 3 | Replays, saves |
other | 4 | Anything else |
Visibility
| Value | Constant | Who sees it |
|---|---|---|
0 | PUBLIC | Everyone |
1 | FRIENDS_ONLY | Friends of the creator |
2 | PRIVATE | The creator only |
Create and upload
func _ready():
WavedashSDK.ugc_item_created.connect(_on_ugc_created)
func create_level_share(abs_path: String) -> void:
WavedashSDK.create_ugc_item(
WavedashConstants.UGC_TYPE_COMMUNITY,
"Custom arena",
"Uploaded from editor",
WavedashConstants.UGC_VISIBILITY_PUBLIC,
abs_path
)
func _on_ugc_created(response):
if response.get("success", false):
print("ugc id: ", response["data"])
In Godot, pass a real filesystem path under OS.get_user_data_dir(). Virtual user:// paths are not valid for the web export bridge.
Update an item
WavedashSDK.update_ugc_item(ugc_id, "Renamed level", "Fixed spawn", WavedashConstants.UGC_VISIBILITY_FRIENDS_ONLY, null)
Download content
func download_into_user_data(ugc_id: String, file_name: String) -> void:
var dir = OS.get_user_data_dir() + "/downloads"
DirAccess.make_dir_recursive_absolute(dir)
WavedashSDK.download_ugc_item(ugc_id, dir + "/" + file_name)
Attach UGC to a leaderboard entry
Pass the ugcId into the score upload call:
const lb = await WavedashJS.getOrCreateLeaderboard("speedrun-times", 0, 2);
const ugc = await WavedashJS.createUGCItem(3, "Replay", "", 0, "replays/run.dat");
if (lb.success && ugc.success) {
await WavedashJS.uploadLeaderboardScore(lb.data.id, 12345, true, ugc.data);
}