UGC - nkrapivin/GMEXT-Steamworks GitHub Wiki
This section is for those users that have been given access to the Steam API for publishing your game to that platform and that want to use the possibilities that the Steam Workshop and Community gives you for adding and generating user content in your projects. The simplest form of user generated content is the ability for the user to take and share screenshots, which is facilitated using the following two functions:
-
Before using any of the built in functions for the Steam UGC (User Generated Content) API you need to have set up your game correctly from the Steam dashboard and you should have read through the required documentation found here:
ℹ️ NOTE
You need to have your game accepted for the Steam online store and have access to the developer areas of the Steam API documentation.
All subscribed UGC items will be downloaded by the Steam client automatically, and you should have code in the Steam Asynchronous Event to catch this and store the ID of the UGC that has been downloaded for use in the other UGC functions.
⚠️ IMPORTANTSteam UGC IDs can be huge numbers This means that sometimes you may need to store these as a string rather than try and store them as a real value, especially if working with buffers or trying to write the value to a text file (since this will convert it to a simplified standard format like "6.6624e+003" which will cause issues being read back).
The normal workflow for getting UGC into your game would be as follows:
- The user would subscribe to an item (either from your game using [steam_ugc_subscribe_item](#steam_ugc_subscribe_item) or from the client/browser). If done from the game you are able to "listen" to the callback from the Steam Async Event.
- When you get a successful subscription callback this means that your game is now downloading the UGC. You would then check if the item is installed (ie: download completed) with [steam_ugc_get_item_install_info](#steam_ugc_get_item_install_info).
- If the item is not completely installed, you can use [steam_ugc_get_item_update_info](#steam_ugc_get_item_update_info) to track the download progress.
The following functions are essentially "wrapper" functions for those supplied in the Steam API for creating and uploading content to their servers. As such, we recommend that you read over the linked Steam documentation before using them to gain a greater understanding of how they work: Creating And Uploading Content.
- steam_ugc_create_item
- steam_ugc_delete_item
- steam_ugc_start_item_update
- steam_ugc_set_item_title
- steam_ugc_set_item_description
- steam_ugc_set_item_visibility
- steam_ugc_set_item_tags
- steam_ugc_set_item_content
- steam_ugc_set_item_preview
- steam_ugc_submit_item_update
- steam_ugc_get_item_update_progress
Once your user content has been created and the workshop has it available for download, people can subscribe to it through the Steam App or through the Web portal. However GameMaker Studio 2 also includes the following functions to use the Steam API for creating and canceling subscriptions as well as for getting information about what the user is subscribed to currently:
- steam_ugc_subscribe_item
- steam_ugc_unsubscribe_item
- steam_ugc_num_subscribed_items
- steam_ugc_get_subscribed_items
- steam_ugc_get_item_install_info
- steam_ugc_get_item_update_info
- steam_ugc_request_item_details
There are also a large number of functions available to query the Steam API about the UGC items available:
-
You can get a preview image of any UGC item from the workshop by using the function steam_ugc_send_query to get the preview file handle of the image, and then calling the following function:
This section also provides a set of constants to be used along side the functions provided above:
-
This function will poll the Steam API to see if the key for taking a screenshot of the game has been pressed. The function will only return true for one step (game tick) when the key is pressed, and will return
false
at all other times. Please note that if the screenshot key is pressed, this function will only returntrue
once for each step that it is pressed, and returnfalse
for any subsequent calls within the same step. For example, if a screenshot is requested in the current frame and you call this function in the Step event to find that out, you will gettrue
; however, if you call it again in Draw GUI to check whether a screenshot was requested, you will getfalse
as the function had already been "used up" in the Step event. To use the function's return value multiple times within the same frame, it is recommended to store it in a variable and read that instead of calling the function again.ℹ️ NOTE
This function does not take a screenshot for you. This only signals that the key has been pressed and you must use the GameMaker Studio 2 functions screen_save or screen_save_part to save a local copy of the file to be uploaded.
Syntax:
steam_is_screenshot_requested();
Returns:
Bool
Example:
if steam_is_screenshot_requested() { var file = "Catch_The_Haggis_" + string(global.scrn_num) + ".png"); screen_save(file) steam_send_screenshot(file, window_get_width(), window_get_height()); global.scrn_num += 1; }
The above code will poll the Steam API for a screenshot request and if it has been, a unique name for the image file will be generated, a screenshot will be taken, and the file will be sent to the Steam Community page for the user.
With this function you can upload a screenshot to the Steam Community profile page of the currently logged in user. The filename you supply is the name of the local file that was created when you took the screenshot using the GameMaker Studio 2 functions screen_save or screen_save_part. The width and height define the image size, and the function will return a value of 0 if it fails for whatever reason and a value greater than 0 if it succeeds.
Syntax:
steam_send_screenshot(filename, width, height);
Argument Type Description filename string The name of the image file to upload. width real The width of the image. height real The height of the image.
Returns:
Real
Example:
if steam_is_screenshot_requested() { var file = "Catch_The_Haggis_" + string(global.scrn_num) + ".png"); screen_save(file) steam_send_screenshot(file, window_get_width(), window_get_height()); global.scrn_num += 1; }
The above code will poll the Steam API for a screenshot request and if it has been, a unique name for the image file will be generated, a screenshot will be taken, and the file will be sent to the Steam Community page for the user.
This function is used to prepare the Workshop API and generate a published file ID for the item to be added. The function must be called before doing anything else with the item to be uploaded, as you will be required to use the unique published ID value that it returns in the Steam Async Event for updating. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_create_item(consumer_app_id, file_type);
Argument Type Description consumer_app_id integer The unique App ID for your game on Steam. file_type constant.UGCFileType One of the available file type constants (see UGCFileType constants).
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_create_item"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)legal_agreement_required bool Will be true or false (see the Steam docs for more details) published_file_id int64 This key holds the unique published ID for the item (you may need to cast it using the int64() function)
Extended Example:
In this example we first call the function and store the async ID value in a variable:
var app_id = steam_get_app_id(); new_item = steam_ugc_create_item(app_id, ugc_filetype_community);
This would then send off a request to the Steam API to create the new Workshop item, generating an async event which we would deal with as follows:
var event_id = async_load[? "id"]; if event_id == new_item { var type = async_load[? "event_type"]; if type == "ugc_create_item" { global.Publish_ID = async_load[? "published_file_id"]; } }
The above code checks the event type and if it is "ugc_create_item" then it retrieves the published file ID and stores it in a global variable for future reference.
This function attempts to delete a previously published UGC item. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_delete_item(ugc_query_handle);
Argument Type Description ugc_query_handle real The query handle to use.
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_item_delete"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)
Example:
steam_ugc_delete_item(ugc_query_handle);
The above code creates a deletion request for
ugc_query_handle
.
This function must be called before adding or updating information on a UGC item. You need to supply the unique App ID for your game on Steam, along with the unique published file ID that was returned for the item when you created it using the function steam_ugc_create_item. The function will return a unique update handle for the item, which you can then use in the UGC item functions to update (or add) information for uploading.
Syntax:
steam_ugc_start_item_update(consumer_app_id, published_file_id);
Argument Type Description consumer_app_id real The unique App ID for your game on Steam. published_file_id int64 The unique published file ID value for the item.
Returns:
Real
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will set the title to be used for the given item. The function will return
true
if the API was successfully accessed andfalse
if there was an issue.
Syntax:
steam_ugc_set_item_title(ugc_update_handle, title);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) title string The title (max 128 characters) to be used for the item.
Returns:
Bool
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will set the description to be used for the given item. The function will return
true
if the API was successfully accessed andfalse
if there was an issue.
Syntax:
steam_ugc_set_item_description(ugc_update_handle, description);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) description string The description (max 8000 characters) to be used for the item.
Returns:
Bool
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will set the visibility of the given item, using one of the UGCFileVisibility constants. The function will return
true
if the API was successfully accessed andfalse
if there was an issue.
Syntax:
steam_ugc_set_item_visibility(ugc_update_handle, visibility);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) visibility constant.UGCFileVisibility The visibility to be used for the item (see UGCFileVisibility constant)
Returns:
Bool
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will set the tags to be used for the given item. The tags should be added to a 1D array as string elements and the array passed to the function. The function will return
true
if the API was successfully accessed andfalse
if there was an issue.
Syntax:
steam_ugc_set_item_tags(ugc_update_handle, tags);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) tags string The tags (as an string json array) to be used for the item.
Returns:
Bool
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, string(tagArray)); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will set the content path to be used for the given item, and it should be a relative path to the folder which contains the content files to upload - which in turn should be in the save are or the game bundle (ie: an included file). The function will return
true
if the API was successfully accessed andfalse
if there was an issue.
Syntax:
steam_ugc_set_item_content(ugc_update_handle, content);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) content string The content path to be used for the item
Returns:
Bool
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will set the preview image to be used for the given item. The image should be supplied as either a PNG, JPG or GIF format file with a maximum size of 1MB. The path to the image should be a relative path in the save are or the game bundle (ie: an included file). The function will return
true
if the API was successfully accessed andfalse
if there was an issue.
Syntax:
steam_ugc_set_item_preview(ugc_update_handle, preview);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) preview string The preview image (JPG, GIF or PNG - max size 1MB) to be used for the item.
Returns:
Bool
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
This function will submit the UGC item indexed by the given handle to the Steam Workshop servers, adding the change notes to be used for the given item. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_submit_item_update(ugc_update_handle, change_note);
Argument Type Description ugc_update_handle real The unique handle for the UGC to be updated (returned from steam_ugc_start_item_update) change_note string The change notes to be used for the item.
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_update_item"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)legal_agreement_required bool Will be true or false (see the Steam docs for more details)
Example:
var app_id = steam_get_app_id(); var updateHandle = steam_ugc_start_item_update(app_id, global.Publish_ID); steam_ugc_set_item_title(updateHandle, "My workshop item(3)!"); steam_ugc_set_item_description( updateHandle, "testing workshop..."); steam_ugc_set_item_visibility(updateHandle, ugc_visibility_public); var tagArray; tagArray[0] = "Test"; tagArray[1] = "New"; steam_ugc_set_item_tags(updateHandle, tagArray); steam_ugc_set_item_preview(updateHandle, "promo.jpg"); steam_ugc_set_item_content(updateHandle, "WorkshopContent1"); requestId = steam_ugc_submit_item_update(updateHandle, "Version 1.2");
The above code gets the game ID, then uses that along with a previously stored published file ID to generate an update handle for the item. This handle is then used to update various pieces of information before the update is pushed to the Workshop servers.
---
This function can be used to track the update status for an item. You give the item handle (as returned by the function [steam_ugc_start_item_update](#steam_ugc_start_item_update)) and an empty [DS map](https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Data_Structures/DS_Maps/DS_Maps.htm) which will then be populated with the update information (see table below) If there is an error the function will return `false` and the map will be empty, otherwise the function returns `true`.
Syntax:
steam_ugc_get_item_update_progress(ugc_update_handle, info_map);
Argument Type Description ugc_update_handle integer The unique handle for the UGC to be updated. info_map DS Map ID A (previously created) DS map index. Key Type Description status_code real The Steam status code status_string string A string for the current status bytes_processed real The bytes processed so far bytes_total real The total number of bytes in the update
Returns:
Bool
Example:
var uploadMap = ds_map_create(); steam_ugc_get_item_update_progress(global.itemHandle, uploadMap); var statusCode = uploadMap[? "status_code"]; var status = uploadMap[? "status_string"]; var processed = uploadMap[? "bytes_processed"]; var total = uploadMap[? "bytes_total"]; draw_text(32, 0, "Upload info for item:" + string(global.itemHandle)); draw_text(32, 15, "status code:" + string(statusCode)); draw_text(32, 30, "status:" + string(status)); draw_text(32, 45, "bytes processed:" +string(processed)); draw_text(32, 60, "bytes total:" + string( total)); ds_map_destroy(uploadMap);
The above code will query the upload status of the item indexed in the global variable "itemHandle", using a <tt>DS Map</tt> to store the information. This is then parsed and the resulting values drawn to the screen. <!-- KEYWORDS
steam_ugc_get_item_update_progress -->
This function can be used to subscribe to a UGC item. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_subscribe_item(published_file_id);
Argument Type Description published_file_id int64 The unique file ID for the UGC to subscribe to.
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_subscribe_item"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)published_file_id int64 This key holds the unique published ID for the item (you may need to cast it using the int64 function, before passing it to subsequent functions)
Example:
steam_sub = steam_ugc_subscribe_item(global.pubFileID);
The above code will subscribe (and download) the item with the file ID stored in the global variable "pubFileID".
This function can be used to unsubscribe from a UGC item. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_unsubscribe_item(published_file_id);
Argument Type Description published_file_id int64 The unique file ID for the UGC to unsubscribe from.
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_unsubscribe_item"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)published_file_id int64 This key holds the unique published ID for the item (you may need to cast it using the int64 function)
Example:
steam_sub = steam_ugc_unsubscribe_item(global.pubFileID);
The above code will unsubscribe (and remove) the item with the file ID stored in the global variable "pubFileID".
This function can be used to get the number of items that the current user has subscribed to.
Syntax:
steam_ugc_num_subscribed_items();
Returns:
Real
Example:
numSub = steam_ugc_num_subscribed_items();
The above code will store the number of subscribed items in a variable.
---
This function will populate a DS list with all the published file IDs for the items that the user is currently subscribed to. You must first create the list and store the index in a variable, then pass this to the function. The function will return <tt></tt>`true` if everything is correct and the Steam API is initialized, or `false` if there is an error.
Syntax:
steam_ugc_get_subscribed_items(item_list);
Argument Type Description item_list DS List ID A (previously created) DS list index.
Returns:
Bool
Example:
steam_list = ds_list_create(); steam_ugc_get_subscribed_items(steam_list);
The above code will create an empty DS list and then populate it with the file IDs for all subscribed items for the user. <!-- KEYWORDS
steam_ugc_get_subscribed_items -->
---
This function can be used to retrieve information about any given published file item that has been subscribed to and downloaded to the Steam local storage area for your game. You give the item ID and supply the index to an empty [DS map](https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Data_Structures/DS_Maps/DS_Maps.htm) which will then be populated with the install information (see table below). If the item exists (ie.: as been subscribed and download was complete) then the function will return `true` and populate the map, otherwise it will return `false` and the map will remain empty.
Syntax:
steam_ugc_get_item_install_info(published_file_id, info_map);
Argument Type Description published_file_id int64 The unique handle for the UGC to be updated. info_map DS Map ID A (previously created) DS map index. Key Type Description size_on_disk real The file size on disk (in bytes) legacy_item bool Will be true or false depending on whether it is a legacy file or not folder string This is the full path to the installed content ( please refer to "Item Installation" in Steam SDK docs, as "legacy" items uploaded with the old method, are treated differently)
Returns:
Bool
Example:
var item_map = ds_map_create(); steam_ugc_get_item_install_info(global.fileID, item_map);
The above code will query the install status of the item indexed in the global variable "fileID", using a <tt>DS Map</tt> to store the information. <!-- KEYWORDS
steam_ugc_get_item_install_info -->
---
This function can be used to retrieve information about the current download state for the given file ID. You give the item ID and supply the index to an empty [DS map](https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Data_Structures/DS_Maps/DS_Maps.htm) which will then be populated with the update information (see table below). If the item exists then the function will return `true` and populate the map, otherwise it will return `false` and the map will remain empty.
Syntax:
steam_ugc_get_item_update_info(published_file_id, info_map);
Argument Type Description published_file_id int64 The unique file ID for the UGC to be checked. info_map DS Map ID A (previously created) DS map index. Key Type Description needs_update bool Whether the item needs an update or not is_downloading bool Whether the item is currently downloading or not bytes_downloaded real The number of bytes that has been downloaded bytes_total real The total size (number of bytes) required for the item on disk
Returns:
Bool
Example:
var info_map = ds_map_create(); var info = steam_ugc_get_item_update_info(global.fileID, info_map); if info { draw_text(32, 15, "needs_update: " + string(info_map[? "needs_update"])); draw_text(32, 30, "is_downloading: " + string(info_map[? "is_downloading"])); draw_text(32, 45, "bytes_downloaded: " + string(info_map[? "bytes_downloaded"])); draw_text(32, 60, "bytes_total: " + string(info_map[? "bytes_total"])); }
The above code will query the download status of the item indexed in the global variable "fileID", using a <tt>DS Map</tt> to store the information. <!-- KEYWORDS
steam_ugc_get_item_update_info -->
This function can be used to retrieve information about a given file ID. You give the file ID and supply a maximum age for checking (see the Steam docs for more information). This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_request_item_details(published_file_id, max_age_seconds);
Argument Type Description published_file_id real The unique file ID for the UGC to be checked. max_age_seconds real The age of the data to check (recommended 30 - 60 seconds).
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_item_details"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)cached_data bool Will be true if the returned details are from the local cache or false if they are taken from the server published_file_id int64 This key holds the unique published ID for the item (you may need to cast it using the int64 function) file_type string The type of file used creator_app_id real The Steam ID of the item creator consumer_app_id real The Steam ID of the item consumer title string The title of the item description string The description of the item steam_id_owner real The Steam ID of the item owner time_created real The time the item was first created time_uploaded real The last time the item was updated time_added_to_user_list real The time that the item was subscribed to visibility constant.UGCFileVisibility The visibility of the item (see UGCFileVisibility constant) banned bool Whether the item has been banned or not accepted_for_use bool Whether the item has been accepted for use or not tags_truncated array Short version of the tags as an array tags array An array of the tags for the item handle_file int64 The unique file handle for the item handle_preview_file int64 The unique handle for the image preview for the item (can be used with steam_ugc_download to download a preview image) filename string The name of the item file file_size real The size of the item file preview_file_size real The size of the preview image url string The full URL for the item up_votes real The number of up-votes received down_votes real The number of down-votes received score real The overall score of the item account_id_owner real The account ID from the Steam ID owner (this can be used in function steam_ugc_create_query_user_ex)
Extended Example:
In this example we send off a details request for an item and then parse the resulting async_load DS map to set some variables. First we send of the request:
steam_details = steam_ugc_request_item_details(global.fileID, 60);
The above code will request details on the item with the file ID stored in the global variable and will trigger a Steam Async event with the returned information. In this event we can then parse the map and store some of the values in variables which can then be used to display the information to the user:
var map_id = async_load[? "id"]; var result = async_load[? "result"]; if (map_id == steam_details) && (result == ugc_result_success) { mTitle = async_load[? "title"]; mDesc = async_load[? "description"]; mTags = async_load[? "tags"]; m_hPreviewFile = async_load[? "handle_preview_file"]; m_hOwnerSteamId = async_load[? "steam_id_owner"]; mOwnerAccountId = async_load[? "account_id_owner"]; mPubFileId = async_load[? "published_file_id"]; mScore = async_load[? "score"]; }
This function can be used to query the UGC data base. The function automatically uses the default ID for the app, user and assumes that the query is being done by the consumer (rather than the creator). The function requires you to use the following constants for the type of data to query (UGCListType), the type of item to match (UGCMatchType) and the order in which the returned items will be sorted (UGCListSortOrder), as well as a page number - note that a query will return a maximum number of 50 items. The function returns a unique query handle value which should be stored in a variable for use in the other query functions. Note that this function only prepares the query but does not actually send it - for that you must call the function steam_ugc_send_query - and you can use further
steam_ugc_query_*()
functions to refine the search request before it is actually sent.
Syntax:
steam_ugc_create_query_user(list_type, match_type, sort_order, page);
Argument Type Description list_type constant.UGCListType The type of data list to create (see UGCListType constants) match_type constant.UGCMatchType The type of UGC items to query (see UGCMatchType constants) sort_order constant.UGCListSortOrder The way that data should be ordered (see UGCListSortOrder constants) page real The page number to query.
Returns:
Real
Example:
query_handle = steam_ugc_create_query_user(ugc_list_Published, ugc_match_Items, ugc_sortorder_TitleAsc, 1);
The above code creates a query request and stores it's handle in a variable for future use.
This function can be used to query the UGC data base. The function requires the ID value for the user and the ID of the game that is going to consume the item and/or the ID of the game that created the item. You also need to use the following constants for the type of data to query (UGCListType), the type of item to query (UGCMatchType) and the order in which the returned items will be sorted (UGCListSortOrder), as well as a page number - note that a query will return a maximum number of 50 items. The function returns a unique query handle value which should be stored in a variable for use in the other query functions. Note that this function only prepares the query but does not actually send it - for that you must call the function steam_ugc_send_query - and you can use further
steam_ugc_query_*()
functions to refine the search request before it is actually sent.
Syntax:
steam_ugc_create_query_user_ex(list_type, match_type, sort_order, page, account_id, creator_app_id, consumer_app_id);
Argument Type Description list_type constant.UGCListType The type of data list to create (see UGCListType constants) match_type constant.UGCMatchType The type of UGC items to query (see UGCMatchType constants) sort_order constant.UGCListSortOrder The way that data should be ordered (see UGCListSortOrder constants) page real The page number to query account_id real The Steam account ID creator_app_id real The item creator app ID consumer_app_id real The consumer app ID
Returns:
Real
Example:
query_handle = steam_ugc_create_query_user_ex(ugc_list_Published, ugc_match_Items, ugc_sortorder_TitleAsc, page, global.AccountID, 0, global.GameID);
The above code creates a query request and stores it's handle in a variable for future use.
This function can be used to query the UGC data base using some predefined query types. The function requires the following constants for the type of query to create (UGCQueryType), the type of item to match (UGCMatchType) and the page number to query - note that a query will return a maximum number of 50 items. The function returns a unique query handle value which should be stored in a variable for use in the other query functions. Note that this function only prepares the query but does not actually send it - for that you must call the function steam_ugc_send_query - and you can use further
steam_ugc_query_*()
functions to refine the search request before it is actually sent.
Syntax:
steam_ugc_create_query_all(query_type, match_type, page);
Argument Type Description query_type constant.UGCQueryType The type of query to create (see UGCQueryType constants) match_type constant.UGCMatchType The type of UGC items to query (see UGCMatchType constants) page real The page number to query
Returns:
Real
Example:
query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1);
The above code creates a general query request and stores it's handle in a variable for future use.
This function can be used to query the UGC data base. The function requires the ID of the game that is going to consume the item and/or the ID of the game that created the item, and you need to use the following constants for the type of query to create (UGCQueryType), the type of item to match (UGCMatchType) and the page number to query. Note that a query will return a maximum number of 50 items. The function returns a unique query handle value which should be stored in a variable for use in the other query functions. Note that this function only prepares the query but does not actually send it - for that you must call the function steam_ugc_send_query - and you can use further
steam_ugc_query_*()
functions to refine the search request before it is actually sent.
Syntax:
steam_ugc_create_query_all_ex(query_type, match_type, page, creator_app_id, consumer_app_id);
Argument Type Description query_type constant.UGCQueryType The type of query to create (see UGCQueryType constants) match_type constant.UGCMatchType The type of UGC items to query (see UGCMatchType constants) page real The page number to query creator_app_id integer The item creator app ID consumer_app_id integer The consumer app ID
Returns:
Real
Example:
query_handle = steam_ugc_create_query_all_ex(ugc_query_RankedByVote, page, global.AccountID, 0, global.GameID);
The above code creates a query request and stores it's handle in a variable for future use.
This function can be used to further filter any given UGC query, specifically to check and see if a Workshop item file name must match or not. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is either
true
orfalse
depending on whether you require the file names to match. The function will returntrue
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_cloud_filename_filter(ugc_query_handle, should_match);
Argument Type Description ugc_query_handle integer The query handle to use. match_cloud_filename bool Sets whether the UGC item file name should match or not.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1); steam_ugc_query_set_cloud_filename_filter(query_handle, true); steam_ugc_query_add_excluded_tag(query_handle, "nasty chips"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to switch on or off tag matching. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is either
true
orfalse
depending on whether you require a check for matching tags. The function will returntrue
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_match_any_tag(ugc_query_handle, match_any_tag);
Argument Type Description ugc_query_handle integer The query handle to use. match_any_tag bool Sets whether the UGC item tags should match anything or not.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1); steam_ugc_query_set_match_any_tag(query_handle, false); steam_ugc_query_add_excluded_tag(query_handle, "walking simulator"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to search for the given string in the title and description of the UGC items. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is a string you want to use as the search term. The function will return
true
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_search_text(ugc_query_handle , search_text);
Argument Type Description ugc_query_handle real The query handle to use. search_text string The search text to use for the query.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1); steam_ugc_query_set_search_text(query_handle, "texture"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any UGC query made using the
ugc_query_RankedByTrend
constant (UGCQueryType), specifically to search over a number of days. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is the number of days over which you want the query to run. The function will returntrue
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_ranked_by_trend_days(ugc_query_handle, days);
Argument Type Description ugc_query_handle real The query handle to use. days real The number of days to query.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByTrend, ugc_match_Items, 1); steam_ugc_query_set_ranked_by_trend_days(query_handle, 5); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to search only those UGC items with the given tag. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is a string you want to use as the tag to include. The function will return
true
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_add_required_tag(ugc_query_handle, tag_name);
Argument Type Description ugc_query_handle integer The query handle to use. tag_name string The tag name to include.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByTrend, ugc_match_Items, 1); steam_ugc_query_add_required_tag(query_handle, "RPG"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to exclude a given UGC from the query request. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is a string you want to use as the tag to exclude. The function will return
true
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_add_excluded_tag(ugc_query_handle, tag_name);
Argument Type Description ugc_query_handle integer The query handle to use. tag_name string The tag name to exclude.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1); steam_ugc_query_add_excluded_tag(query_handle, "walking simulator"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to retrieve the long description text in the call back event triggered when the query was sent. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is either
true
orfalse
. The function will returntrue
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_return_long_description(ugc_query_handle, should_return);
Argument Type Description ugc_query_handle real The query handle to use. long_description bool Whether to have the query return the long description text.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to request only the number of results without any other information (meaning that the DS map generated by the send function will contain the key "num_results" without any further map data). The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is either
true
orfalse
. The function will returntrue
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_return_total_only(ugc_query_handle , total_only);
Argument Type Description ugc_query_handle real The query handle to use. total_only bool Whether to have the query return only the total number of hits or not.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByVote, ugc_match_Items, 1); steam_ugc_query_set_return_total_only(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
This function can be used to further filter any given UGC query, specifically to request that the query check the local cache rather than online. The query handle is the value returned when you created the query (using, for example, steam_ugc_create_query_user) and the second argument is either
true
orfalse
. The function will returntrue
if the query filter was correctly set, orfalse
otherwise.
Syntax:
steam_ugc_query_set_allow_cached_response(ugc_query_handle , check_cache);
Argument Type Description ugc_query_handle integer The query handle to use. cache bool Whether to have the query check the local cache or not.
Returns:
Bool
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByTrend, ugc_match_Items, 1); steam_ugc_query_add_required_tag(query_handle, "RPG"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query.
---
This function can be used to send a query request. You first define the query using one of the following function:
-
steam_ugc_create_query_user_ex
which will return a query handle. This handle is then used to set filters etc.... before being used in this function to send off the query request. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_send_query(ugc_query_handle);
Argument Type Description ugc_query_handle real The query handle to send.
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_query"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs, for more details)cached_data bool Will be true if the returned details are from the local cache or false if they are taken from the server total_matching real The total number of matching results num_results real The number of results returned (max 50) results_list DS List ID A DS list index, where each list entry is a DS Map index containing details of the particular item (see table below) Key Type Description published_file_id int64 This key holds the unique published ID for the item (you may need to cast it using the int64 function) file_type string The type of file used creator_app_id real The Steam ID of the item creator consumer_app_id real The Steam ID of the item consumer title string The title of the item description string The description of the item steam_id_owner real The Steam ID of the item owner time_created real The time the item was first created time_uploaded real The last time the item was updated time_added_to_user_list real The time that the item was subscribed to visibility constant.UGCFileVisibility The visibility of the item (see UGCFileVisibility constant) banned bool Whether the item has been banned or not accepted_for_use bool Whether the item has been accepted for use or not tags_truncated array Short version of the tags as an array tags array An array of the tags for the item handle_file int64 The unique file handle for the item handle_preview_file int64 The unique handle for the image preview for the item (can be used with steam_ugc_download to download a preview image) filename string The name of the item file file_size real The size of the item file preview_file_size real The size of the preview image url string The full URL for the item up_votes real The number of up-votes received down_votes real The number of down-votes received score real The overall score of the item account_id_owner real The account ID from the Steam ID owner (can be used in the function steam_ugc_create_query_user)
Example:
var query_handle = steam_ugc_create_query_all(ugc_query_RankedByTrend, ugc_match_Items, 1); steam_ugc_query_add_required_tag(query_handle, "RPG"); steam_ugc_query_set_return_long_description(query_handle, true); steam_ugc_query_set_allow_cached_response(query_handle, true); query_ID = steam_ugc_send_query(query_handle);
The above code creates a query request and stores it's handle in a local variable for future use in the rest of the functions which further define the query request before sending the query. <!-- KEYWORDS
steam_ugc_send_query -->
With this function you can download a preview image for any given UGC item. The ugc_handle is the unique identifying value for the image (which you can get using the function steam_ugc_send_query), and the destination filename is the name (and local path within the Steam sandbox) that you wish to give the image file when the download is complete. This is an asynchronous function that will return an asynchronous id and trigger the Steam Async Event when the task is finished.
Syntax:
steam_ugc_download(ugc_handle, dest_filename);
Argument Type Description ugc_handle int64 The unique handle for the preview to be downloaded. dest_filename string The file name to save the preview with.
Returns:
Real
Triggers:
Asynchronous Steam Event
Key Type Description id real The asynchronous request ID event_type string The string value "ugc_create_item"
result real This will either be the GML constant ugc_result_success
or some other real number (see theSteam docs under EResult, for more details)original_filename string This key holds the original name of the image file on the server (a string) dest_filename string This key holds the image file name you passed in (a string) ugc_handle integer
Extended Example:
In this example we first call the function and store the async ID value in a variable:
steam_get = steam_ugc_download(steam_handle, "\UGC\Preview_file.png");
This would then send off a file request to the Steam API, generating an async event which we would deal with as follows:
var event_id = async_load[? "id"]; if event_id == steam_get { var type = async_load[? "event_type"]; if type == "ugc_download" { sprite_delete(preview_sprite); preview_sprite = sprite_add(async_load[? "dest_filename"], 0, false, false, 0, 0); } }
The above code checks the event type and then creates a sprite from the downloaded image.
These constants specify the way that a shared file will be shared with the community and should be used while creating a new item with steam_ugc_create_item.
ℹ️ NOTE
See Steam Docs for more details.
UGC File Type Constant Description ugc_filetype_community
This is used to create files that will be uploaded and made available to anyone in the community ugc_filetype_microtrans
This is used to describe files that are uploaded but intended only for the game to consider adding as official content
These constants specify possible visibility states that a Workshop item can be in. They are used with the function steam_ugc_set_item_visibility and are an async callback parameter for the functions steam_ugc_request_item_details and steam_ugc_send_query.
ℹ️ NOTE
See Steam Docs for more details.
UGC File Visibility Constant Description ugc_visibility_public
Set the item to be publicly visible ugc_visibility_friends_only
Set the item to be visible to only people on the users friends list ugc_visibility_private
Set the item to be private
These constants specify the sorting order of user published UGC lists from queries created using one of the following functions:
ℹ️ NOTE
See Steam UGC Docs for more details.
UGC List Sort Order Constant Description ugc_sortorder_CreationOrderDesc
Returns items by creation date. Descending - the newest items are first ugc_sortorder_CreationOrderAsc
Returns items by creation date. Ascending - the oldest items are first ugc_sortorder_TitleAsc
Returns items by name ugc_sortorder_LastUpdatedDesc
Returns the most recently updated items first ugc_sortorder_SubscriptionDateDesc
Returns the most recently subscribed items first ugc_sortorder_VoteScoreDesc
Returns the items with the more recent score updates first ugc_sortorder_ForModeration
Returns the items that have been reported for moderation
These constants specify the type of published UGC list to obtain from queries created using one of the following functions:
ℹ️ NOTE
See Steam UGC Docs for more details.
UGC List Type Constant Description ugc_list_Published
List of files the user has published ugc_list_VotedOn
List of files the user has voted on. Includes both VotedUp and VotedDown ugc_list_VotedUp
List of files the user has voted up (restricted to the current user only) ugc_list_VotedDown
List of files the user has voted down (restricted to the current user only) ugc_list_WillVoteLater
⚠️ DEPRECATEDugc_list_Favorited
List of files the user has favorited ugc_list_Subscribed
List of files the user has subscribed to (restricted to the current user only) ugc_list_UsedOrPlayed
List of files the user has spent time in game with ugc_list_Followed
List of files the user is following updates for
These constants specify the types of UGC to obtain from queries created using one of the following function:
- steam_ugc_create_query_all
- steam_ugc_create_query_all_ex
- steam_ugc_create_query_user
- steam_ugc_create_query_user_ex
ℹ️ NOTE
See Steam UGC Docs for more details.
UGC Match Type Constant Description ugc_match_Items
Both microtransaction items and Ready-to-use items ugc_match_Items_Mtx
Microtransaction items ugc_match_Items_ReadyToUse
Regular in game items that players have uploaded ugc_match_Collections
Shared collections of UGC ugc_match_Artwork
Artwork which has been shared ugc_match_Videos
Videos which have been shared ugc_match_Screenshots
Screenshots which have been shared ugc_match_AllGuides
Both web guides and integrated guides ugc_match_WebGuides
Guides that are only available on the steam community ugc_match_IntegratedGuides
Guides that you can use within your game (like Dota 2's in game character guides) ugc_match_UsableInGame
Ready-to-use items and integrated guides ugc_match_ControllerBindings
Controller Bindings which have been shared
These constants specify the sorting and filtering for queries across all available UGC, and are to be used with the following functions:
ℹ️ NOTE
See Steam UGC Docs for more details.
UGC Query Type Constant Description ugc_query_RankedByVote
Sort by vote popularity all-time ugc_query_RankedByPublicationDate
Sort by publication date descending ugc_query_AcceptedForGameRankedByAcceptanceDate
Sort by date accepted (for mtx items) ugc_query_RankedByTrend
Sort by vote popularity within the given "trend" period (set in steam_ugc_query_set_ranked_by_trend_days) ugc_query_FavoritedByFriendsRankedByPublicationDate
Filter to items the user's friends have favorited, sorted by publication date descending ugc_query_CreatedByFriendsRankedByPublicationDate
Filter to items created by friends, sorted by publication date descending ugc_query_RankedByNumTimesReported
Sort by report weight descending ugc_query_CreatedByFollowedUsersRankedByPublicationDate
Filter to items created by users that the current user has followed, sorted by publication date descending ugc_query_NotYetRated
Filtered to the user's voting queue ugc_query_RankedByTotalVotesAsc
Sort by total # of votes ascending (used internally for building the user's voting queue) ugc_query_RankedByVotesUp
Sort by number of votes up descending. Will use the "trend" period if specified (set in steam_ugc_query_set_ranked_by_trend_days) ugc_query_RankedByTextSearch
Sort by keyword text search relevancy