Developer docs
Everything you need to publish an HTML5 game on UNTILS. Pick a section below.
Build your game, pack the zip and pick the right size.
Quick start
- Make your game as a normal HTML5 game with an
index.html. - (Recommended) Download the SDK below and add it to your game.
- Put everything in one .zip file.
index.htmlmust be at the top level of the zip. - Open your dashboard, press + ADD NEW GAME, fill in the details, add your icon and zip, and press UPLOAD GAME.
- Our team reviews it (up to 2 days). After approval we make it live on UNTILS.
The starter game already uses every SDK command. Upload it as a test game to see how publishing works.
Game package (the zip)
| Item | Rule |
|---|---|
| Format | One .zip file. index.html at the top (not inside a sub-folder). |
| Max size | 50 MB. We recommend under 20 MB so the game loads fast on mobile data. |
| File paths | Use relative paths: game.js, img/hero.png. Do not start paths with /, because your game runs inside /live/.... |
| Technology | HTML5, JavaScript, Canvas, WebGL, WebAssembly. Web exports from Unity, Cocos and Godot work as long as the export has an index.html. Unity, Cocos and Godot each have their own SDK. |
| Starts by itself | No login, no installs, no pop-ups. The game must start from the Play screen. |
localStorage is saved for you automatically, and the SDK gives you a cleaner way to save (see below).Device: mobile or desktop
When you upload, choose Mobile game if it plays well on phones and PC. Choose Desktop game if it needs a keyboard or mouse. Desktop games show "This game is for desktop (PC) only" on phones instead of a Play button.
Recommended game size (what the player sees)
| Where | What to do |
|---|---|
| PC | Design for 1280 x 720 (16:9 landscape). The game area is shown in a 16:9 frame and can go fullscreen. |
| Phone | When the player presses Play, the game opens fullscreen. Support portrait (720 x 1280) or landscape, and tell players if one is required. |
Most important: make the game responsive. It must fill the window (window.innerWidth x window.innerHeight), keep its aspect ratio, and never need scrolling. Add this to your page:
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
<style>html,body{margin:0;height:100%;overflow:hidden;touch-action:manipulation}</style>
Unity, Cocos, Godot and other engines
Web (HTML5) exports from game engines work if the zip follows the same rules as above: index.html at the top, relative paths, under 50 MB.
Unity (WebGL)
- File → Build Settings → WebGL → Build.
- In Player Settings → Publishing Settings: Compression Format can be Brotli, Gzip or Disabled (UNTILS serves all three). We recommend Gzip with Decompression Fallback ON. Turn Data Caching OFF.
- Zip the contents of the build folder (
index.html,Build/,TemplateData/) soindex.htmlis at the top of the zip. - Make the canvas fill the window so it works on phones and PC.
UntilsPrefs so progress is saved.Cocos Creator (Web)
- Project → Build → Platform Web Mobile → Build.
- Zip the contents of the build folder, so
index.htmlis at the top of the zip.
UntilsPrefs so progress is saved, and sends loading and pause events for you.Godot
Icon, banner, thumbnail, screenshots, text logo and video for your game page.
Game icon (logo) - required
| Item | Rule |
|---|---|
| Shape | Square (width = height). |
| Size | Minimum 512 x 512 px. We recommend 1024 x 1024 px. Smaller or non-square icons are rejected by the upload form. |
| Format | PNG, JPG or WebP. Under 2 MB. |
What to put in it:
- One clear subject: your main character, object or logo mark, in the centre.
- Keep about 10% empty space around the edges. UNTILS rounds the corners itself, so do not round them.
- Bright, high-contrast colours and a solid background. It must look good very small (about 60 px).
- Little or no text. Tiny text becomes unreadable. A short game name in large letters is fine.
- No borders, no store badges, no "NEW" or "FREE" stickers, no blurry or stretched images.
- Only artwork you made or are allowed to use. No copied characters or logos.
The icon is shown on the game card, the Play screen, "More games" and the popular banner.
Popular banner - optional
If the UNTILS team marks your game as Popular, it appears in the big banner at the top of the home page. A banner is optional, but without one your game shows only its icon on a gradient.
| Item | Rule |
|---|---|
| Size | 1920 x 400 px (ratio about 4.8 : 1). Minimum 1600 px wide. |
| Format | PNG, JPG or WebP. Under 2 MB. |
| Safe area | The banner is cropped on small screens. Keep important art in the centre 1000 x 190 px. |
| Text | Do not write the game name or a Play button on it. UNTILS adds the title and a Play Now button on the left, with a dark fade for readability. Keep the left side calm. |
How to upload: choose it in the Popular banner field when you add the game. You can also add or change it later: open your dashboard, click the game, pick a new banner, and press SAVE CHANGES.
Thumbnail - optional
The thumbnail is a wide picture that shows your game at a glance. UNTILS can use it on game cards and in lists, so players see the real look of your game together with its name.
| Item | Rule |
|---|---|
| Shape | Landscape (wider than tall). We recommend 1280 x 720 px (16 : 9). Minimum 960 px wide. |
| Format | PNG, JPG or WebP. Under 2 MB. |
| Name logo | Put your game name as a text logo slightly above the centre of the picture, in large, easy-to-read letters. |
| Centre | Below the logo, in the middle, show only the core of your game: the main character, object or scene. |
| No UI | No other UI and no other text. No buttons, scores, menus, joysticks, slogans, store badges or "NEW" / "FREE" stickers. |
Tip: keep the important art away from the edges, because the picture is cropped a little on small cards.
Screenshots - optional
| Item | Rule |
|---|---|
| Count | Up to 5. |
| Size | Minimum 640 px wide. We recommend 1280 x 720 (landscape) or 720 x 1280 (portrait for phone games). |
| Format | PNG, JPG or WebP. Under 2 MB each. |
What to show: real screenshots taken from your running game, exactly as the player sees it, with all the UI, text and buttons (menu, gameplay, a level, a win or upgrade screen). They must not be edited, redrawn or mocked up. No device frames, no added promo text, no screens from other games.
Screenshots appear at the very bottom of your game page. Click one to see it large. You can remove or add screenshots later from the dashboard.
Text logo - optional
The text logo is your game name drawn as a logo (a wordmark). UNTILS can show it on top of your popular banner and on your game page, so players see a clean title instead of plain text.
| Item | Rule |
|---|---|
| File size | Under 1 MB. |
| Format | PNG or WebP with a transparent background. Do not use a white or coloured box behind it. |
| Size | Wide shape. We recommend 1200 x 400 px. Minimum 600 px wide. |
| Content | Only your game name in large, easy-to-read letters. No slogan, no small text, no other logos or store badges. Keep about 10% empty space around it. |
| Colours | It must stay readable on a dark fade and on a bright background. Add a thin outline or shadow if needed. |
Gameplay video - optional
A short video that shows how your game plays. UNTILS can show it on your game page before the screenshots.
| Item | Rule |
|---|---|
| Length | Maximum 15 seconds. Longer videos are rejected. |
| Format | MP4 (H.264) or WebM. Under 20 MB. |
| Size | 1280 x 720 (landscape) or 720 x 1280 (portrait for phone games). |
| Sound | The video starts muted, so sound is optional. If you add sound, keep it quiet and without copyrighted music. |
| No UI | The video must have no UI at all: no text, no buttons, no controls, no score, no joystick, no menus, no tutorials. Show only the core of the game: the main characters and the action. |
| Content | Real gameplay only: start with the action in the first second, show the main mechanic, end cleanly. No fake or edited-in scenes, no ads or promo banners, no watermarks, no black bars, no scenes from other games. |
See art styles that work well, and pick the one that fits your game.
2D Art
Choose one 2D style and use it everywhere: characters, backgrounds, buttons and icons. A game that looks the same from screen to screen feels finished. Tap any example to see it bigger.
- Use PNG or WebP for art. Keep images only as big as they are shown, so your zip stays small (the limit is 50 MB).
- Keep buttons and important things big enough for a thumb on a phone.
- Make sure text and the player stay easy to see against the background.
3D Art Style
For 3D games, pick one style and keep every model, texture and light in the same style. Tap any example to see it bigger.
- Keep models light (fewer triangles) so the game runs smoothly on phones.
- Use small, compressed textures, and share one texture between many objects when you can.
- Go easy on real-time shadows and effects. Test on a mid-range phone, not only on a PC.
Connect your game to UNTILS: HTML5, Unity, Cocos and Godot, and every SDK command.
HTML SDK
HTML SDK (version 1.2.0) is one small file, untils.js, for HTML5 games. It gives your game progress saving, pause/resume, share links, language, fullscreen and event tracking. Ads and leaderboards are reserved and will work later without changing your code. It is optional, but recommended.
Import
- Download untils.js.
- Put it next to your
index.htmlinside your game folder (and so inside the zip). - Add this in your page before your own game script:
<script src="untils.js"></script>
Using a local copy means your game also runs on your own PC without UNTILS. In that case the SDK switches to offline mode: saves go to your browser and ads are skipped, so nothing crashes.
Full flow
async function main() {
await Untils.init(); // 1. always first
Untils.loadingStart(); // 2. assets start loading
await loadAssets();
Untils.loadingFinished(); // 3. menu is ready
let level = await Untils.load("level", 1); // 4. read saved progress
playBtn.onclick = () => {
Untils.gameplayStart(); // 5. player starts playing
};
function onGameOver() {
Untils.gameplayStop(); // 6. player died / opened menu
Untils.save("level", level); // 7. save progress
Untils.showAd("interstitial"); // 8. ad between levels (not live yet)
}
rewardBtn.onclick = async () => {
const watched = await Untils.showAd("rewarded"); // 9. watch ad for a reward
if (watched) giveCoins();
};
Untils.onPause(() => pauseGame()); // tab hidden / app switched
Untils.onResume(() => resumeGame());
}
main();
SDK commands
| Command | What it does | Status |
|---|---|---|
await Untils.init({ debug }) | Starts the SDK. Call it first. Resolves with { name, version, env, isMobile, player, language }. env is "untils" on the site or "offline" on your own PC. Never fails. Waits up to 3 seconds for UNTILS. | Live |
loadingStart() / loadingFinished() | Tell UNTILS when your game is loading and when the menu is ready. | Live |
gameplayStart() / gameplayStop() | Call when real play starts and stops (death, menu, pause). Repeated calls are ignored. When the tab is hidden, the SDK stops gameplay for you, so call gameplayStart() again when the player returns. | Live |
Untils.save(key, value) | Saves any JSON value (number, text, object, array). Returns true or false. | Live (this browser) |
await Untils.load(key, fallback) | Reads it back. Returns fallback if nothing is saved. | Live (this browser) |
remove(key), clearSave(), keys() | Delete one value, delete everything, or list saved keys. | Live |
onPause(fn) / onResume(fn) | Runs when the player leaves or returns to the tab. Pause your game and sound here. | Live |
await getPlayer() | Returns { guest, name }. Everyone is "Guest" for now. | Basic |
Untils.getLanguage() | Player's language as a 2-letter code, like "en" or "hi". | Live |
Untils.shareableURL({ level: 5 }) | Returns a link to your game with your own values in it. Show it in a "Share" button. | Live |
Untils.getURLParam("level") | Reads a value from the link the player opened. Returns undefined if missing. | Live |
requestFullscreen() / exitFullscreen() | Asks UNTILS to enter or leave fullscreen. Call it from a button click. | Live |
Untils.track(name, data) | Sends your own event, like track("level_complete", { level: 3 }). Name up to 40 characters. Stats for developers are coming later. | Reserved |
Untils.setDebug(true) | Prints SDK activity to the browser console while you build. | Live |
Untils.isMobile, env, isReady, version | Handy flags. | Live |
await showAd("interstitial" | "rewarded"), commercialBreak(), rewardedBreak() | Ads are not live yet. Until then interstitial returns true at once and rewarded returns false, so you can write your ad code now. commercialBreak() and rewardedBreak() are shortcuts. | Coming soon |
await submitScore(board, score) | Sends a score. Returns false until leaderboards go live. Safe to call now. | Coming soon |
save() returns false and prints a warning. Save small things (level, coins, settings), not big data. Today saves stay in the player's browser on that device. When player accounts arrive, the same save and load will work on every device, so your game needs no change.Unity SDK (beta, Unity 2020.1 to Unity 6, WebGL)
Pick the package for your Unity version from the list below, newest first (Unity 2019 and older are not supported, they use an older WebGL loader). Every package has everything you need: the C# SDK, the Untils WebGL template (it appears in Player Settings, like other platform SDK templates), UntilsPrefs (a save-safe replacement for PlayerPrefs), an editor menu and a sample script.
| Your Unity version | SDK version | Download |
|---|---|---|
| Unity 6 (6000.x) (latest) Unity 2023.x can use this one too | Unity SDK 1.1.0 | |
| Unity 2022.3 LTS | Unity SDK 1.1.0 | |
| Unity 2021.3 LTS | Unity SDK 1.1.0 | |
| Unity 2020.3 LTS | Unity SDK 1.1.0 |
Install and build
- Unzip the file into your Unity project folder (the one that contains
Assets). Merge theAssetsfolder. - In Unity open the menu Untils → Apply recommended WebGL settings. This sets everything in the table below for you.
- In your first script call
Untils.Init(...)and useUntilsPrefsinstead ofPlayerPrefs(see the code below). - File → Build Settings → WebGL → Build.
- Zip the contents of the build folder, so
index.htmlis at the top of the zip, and upload it in your dashboard. UNTILS then opens the Inspector view to check your SDK.
| Player Settings (WebGL) | Value |
|---|---|
| Resolution and Presentation → WebGL Template | Untils |
| Publishing Settings → Compression Format | Gzip (Brotli or Disabled also work) |
| Publishing Settings → Decompression Fallback | On |
| Publishing Settings → Data Caching | Off |
The template makes your game fill the whole window (phones and PC), shows a loading bar, loads untils.js, starts the SDK, and tells UNTILS when loading starts and finishes. You do not need to call LoadingStart yourself.
Code
using UnityEngine;
public class GameManager : MonoBehaviour
{
int level;
void Start()
{
Untils.Init(ok =>
{
level = UntilsPrefs.GetInt("level", 1); // saved progress
StartGame();
});
Untils.OnPause += () => Debug.Log("paused"); // optional
Untils.OnResume += () => Debug.Log("resumed");
}
public void OnPlayPressed() { Untils.GameplayStart(); }
public void OnGameOver()
{
Untils.GameplayStop();
UntilsPrefs.SetInt("level", level); // saved automatically
Untils.CommercialBreak(() => ShowGameOverScreen()); // ads not live yet: continues at once
}
public void OnRewardButton()
{
Untils.RewardedBreak(rewarded => { if (rewarded) GiveCoins(); });
}
}
Commands
| Command | What it does | Status |
|---|---|---|
Untils.Init(Action<bool> onReady) | Starts the SDK and loads saved data. Call it first. onReady runs when ready. | Live |
UntilsPrefs.SetInt / GetInt / SetFloat / GetFloat / SetString / GetString / HasKey / DeleteKey / DeleteAll / Save | Same as PlayerPrefs. Saves itself shortly after each change. About 900 KB per game. | Live (this browser) |
Untils.GameplayStart() / GameplayStop() | Real play starts / stops (death, menu, pause). | Live |
Untils.LoadingStart() / LoadingFinished() | Done for you by the template. Only call them if you load more content later. | Live |
Untils.OnPause / OnResume | Events when the tab is hidden or shown. With Untils.AutoPause = true (default) the SDK also pauses Time.timeScale and audio for you. | Live |
Untils.IsMobile, Language, Env, IsReady, Player | Handy values. Env is "untils" on the site and "editor" in the Unity Editor. | Live |
Untils.GetPlayer(callback) | Returns the player (guest, name). Everyone is "Guest" for now. | Basic |
Untils.ShareableURL(dictionary) / GetURLParam(name) | Make a share link with your values, and read them back when the game is opened from that link. | Live |
Untils.RequestFullscreen() / ExitFullscreen() | Ask UNTILS to enter or leave fullscreen. Call from a button press. | Live |
Untils.Track(name, json) | Send your own event, like Track("level_complete", "{\"level\":3}"). Stats come later. | Reserved |
Untils.CommercialBreak(callback), RewardedBreak(callback), ShowAd(type, callback) | Ads are not live yet. The interstitial continues at once; the rewarded callback gets false. | Coming soon |
Untils.SubmitScore(board, score, callback) | Leaderboards. Returns false until they go live. | Coming soon |
Untils.SetDebug(true) | Prints SDK activity in the browser console. | Live |
UntilsPrefs uses PlayerPrefs, and rewarded ads return Untils.EditorRewardedResult (default true) so you can test your reward code.If something goes wrong
- "untils.js is not loaded" in the browser console: the WebGL template is not set to Untils. Run the menu Untils → Apply recommended WebGL settings and build again.
- Progress is not saved: you used
PlayerPrefs. Change it toUntilsPrefs. Unity's own save uses IndexedDB, which is blocked in the UNTILS sandbox. - The game stays on the loading bar: open the browser console (F12). Check that the zip has
index.htmlat the top and theBuildfolder next to it. - Very large builds: keep the zip under 50 MB. Compress textures and audio.
This SDK is in beta. If you find a problem, please tell us through the contact page and include your Unity version.
Cocos SDK (beta, Cocos Creator 2.4 and 3.x, Web)
Pick the package for your Cocos Creator version. Both have the same commands. Each one has everything you need: the SDK script, UntilsPrefs (a save-safe replacement for the local storage), a sample script, and untils.js already placed in build-templates, so it is copied into your build for you.
| Your Cocos Creator version | SDK version | Download |
|---|---|---|
| Cocos Creator 3.x (3.0 and newer) TypeScript | Cocos SDK 1.0.0 | |
| Cocos Creator 2.4.x JavaScript | Cocos SDK 1.0.0 |
Install and build
- Unzip the file into your Cocos project folder (the one that contains
assets). Merge the folders. You getassets/UntilsSDKandbuild-templates/web-mobile/untils.js. - In your first script call
Untils.init()and useUntilsPrefsinstead of the local storage (see the code below). - Project → Build → Platform: Web Mobile → Build. Web Mobile works on phones and PC. Set the build Orientation to match the Mobile screen option you choose in the dashboard.
- Open the build folder and check that
untils.jsis next toindex.html. - Zip the contents of the build folder, so
index.htmlis at the top of the zip, and upload it in your dashboard. UNTILS then opens the Inspector view to check your SDK.
You do not need to call loadingStart / loadingFinished: the SDK sends them for you (set Untils.autoLoading = false to do it yourself). When the tab is hidden the SDK also pauses the game and sound, and resumes them when the player returns (set Untils.autoPause = false to handle it yourself).
Code
Cocos Creator 3.x (TypeScript)
import { _decorator, Component } from 'cc';
import { Untils, UntilsPrefs } from './UntilsSDK/Untils';
const { ccclass } = _decorator;
@ccclass('GameManager')
export class GameManager extends Component {
level = 1;
start() {
Untils.onPause(() => console.log('paused')); // optional
Untils.onResume(() => console.log('resumed'));
Untils.init().then(() => {
this.level = UntilsPrefs.getInt('level', 1); // saved progress
this.startGame();
});
}
onPlayPressed() { Untils.gameplayStart(); }
onGameOver() {
Untils.gameplayStop();
UntilsPrefs.setInt('level', this.level); // saved automatically
Untils.commercialBreak().then(() => this.showGameOverScreen()); // ads not live yet: continues at once
}
onRewardButton() {
Untils.rewardedBreak().then((rewarded) => { if (rewarded) this.giveCoins(); });
}
}
Cocos Creator 2.4.x (JavaScript)
const { Untils, UntilsPrefs } = require("Untils");
cc.Class({
extends: cc.Component,
start: function () {
var self = this;
Untils.onPause(function () { cc.log("paused"); }); // optional
Untils.onResume(function () { cc.log("resumed"); });
Untils.init().then(function () {
self.level = UntilsPrefs.getInt("level", 1); // saved progress
self.startGame();
});
},
onPlayPressed: function () { Untils.gameplayStart(); },
onGameOver: function () {
Untils.gameplayStop();
UntilsPrefs.setInt("level", this.level); // saved automatically
Untils.commercialBreak().then(function () { /* show game over screen */ });
},
onRewardButton: function () {
Untils.rewardedBreak().then(function (rewarded) { if (rewarded) { /* give coins */ } });
}
});
Commands
| Command | What it does | Status |
|---|---|---|
Untils.init({ debug }) | Starts the SDK and loads saved data. Call it first. Returns a promise that resolves with { name, version, env, isMobile, player, language }. Never fails. Waits up to 3 seconds for UNTILS. | Live |
UntilsPrefs.setInt / getInt / setFloat / getFloat / setString / getString / setBool / getBool / setJSON / getJSON / hasKey / keys / deleteKey / deleteAll / save | Save and read your data, like the local storage. Saves itself shortly after each change. About 900 KB per game. setJSON keeps any object or array. | Live (this browser) |
Untils.save(key, value), load(key, fallback), remove(key), clearSave(), keys() | The same saves in the style of the HTML SDK (promises). | Live (this browser) |
Untils.gameplayStart() / gameplayStop() | Real play starts / stops (death, menu, pause). Repeated calls are ignored. | Live |
Untils.loadingStart() / loadingFinished() | Done for you. Only call them yourself if you set autoLoading = false, or if you load more content later. | Live |
Untils.onPause(fn) / onResume(fn) / offPause(fn) / offResume(fn) | Runs when the tab is hidden or shown. With Untils.autoPause = true (default) the SDK also pauses the game loop and sound for you. | Live |
Untils.isMobile, language, env, isReady, player, version | Handy values. env is "untils" on the site and "offline" in the Cocos preview or on your own PC. | Live |
Untils.getPlayer() | Promise with { guest, name }. Everyone is "Guest" for now. | Basic |
Untils.shareableURL({ level: 5 }) / getURLParam("level") | Make a share link with your values, and read them back when the game is opened from that link. | Live |
Untils.requestFullscreen() / exitFullscreen() | Ask UNTILS to enter or leave fullscreen. Call from a button press. | Live |
Untils.track(name, data) | Send your own event, like track("level_complete", { level: 3 }). Name up to 40 characters. Stats come later. | Reserved |
Untils.commercialBreak(), rewardedBreak(), showAd(type) | Ads are not live yet. The interstitial continues at once; the rewarded promise gives false. | Coming soon |
Untils.submitScore(board, score) | Leaderboards. Returns false until they go live. | Coming soon |
Untils.setDebug(true) | Prints SDK activity in the browser console. | Live |
Untils.editorRewardedResult (default true) so you can test your reward code.If something goes wrong
- "untils.js was not found" in the browser console: the file is not next to
index.htmlin your build. Check thatbuild-templates/web-mobile/untils.jsexists in your project and build again. - Progress is not saved: you used the engine's own local storage. Change it to
UntilsPrefs. Browser storage is blocked in the UNTILS sandbox. - The game stays on the loading screen: open the browser console (F12). Check that the zip has
index.htmlat the top, with theassetsandsrc(orcocos-js) folders next to it. - Sound does not start: browsers only allow sound after the first tap or click. Start your music from a button press.
- Very large builds: keep the zip under 50 MB. Compress textures and audio.
This SDK is in beta. If you find a problem, please tell us through the contact page and include your Cocos Creator version.
Godot SDK (beta, Godot 3.x and 4.x, Web)
Pick the package for your Godot version. Both have the same commands. Each one is a Godot plugin: it adds the Untils Autoload for you, with saves (like PlayerPrefs), loading and gameplay events, pause handling, and a sample script. The web SDK is already inside it, so there is nothing else to copy.
| Your Godot version | SDK version | Download |
|---|---|---|
| Godot 4.x GDScript 2, "Web" export | Godot SDK 1.0.0 | |
| Godot 3.x (3.5 recommended) GDScript, "HTML5" export | Godot SDK 1.0.0 |
Install and export
- Unzip the file into your Godot project folder (the one that contains
project.godot). Merge the folders. You getaddons/untils_sdk. - Project → Project Settings → Plugins: tick Enable for UNTILS SDK. This adds the Autoload
Untils. (You can also addaddons/untils_sdk/Untils.gdyourself as an Autoload namedUntils.) - In your first script call
Untils.init()and useUntils.set_int / get_int ...instead ofuser://files (see the code below). - Project → Export → Add... → Web (Godot 3: HTML5). Turn Thread Support off (Godot 3: Export Type Regular), because threads need special server headers. In Project Settings → Display → Window → Stretch use Mode
canvas_items(Godot 3:2d) and Aspectexpandso the game fits phones and PC. - Click Export Project, name the file
index.html, and export into an empty folder. Zip the contents of that folder, soindex.htmlis at the top of the zip, and upload it in your dashboard. UNTILS then opens the Inspector view to check your SDK.
You do not need to call loading_start / loading_finished: the SDK sends them for you (set Untils.auto_loading = false to do it yourself). When the tab is hidden the SDK also pauses the game and sound, and resumes them when the player returns (set Untils.auto_pause = false to handle it yourself).
Code
Godot 4.x
extends Node
var level = 1
func _ready():
Untils.paused.connect(func(): print("paused")) # optional
Untils.resumed.connect(func(): print("resumed"))
var info = await Untils.init()
level = Untils.get_int("level", 1) # saved progress
start_game()
func on_play_pressed():
Untils.gameplay_start()
func on_game_over():
Untils.gameplay_stop()
Untils.set_int("level", level) # saved automatically
await Untils.commercial_break() # ads not live yet: continues at once
show_game_over_screen()
func on_reward_button():
var rewarded = await Untils.rewarded_break()
if rewarded:
give_coins()
Godot 3.x
extends Node
var level = 1
func _ready():
Untils.connect("paused", self, "_on_paused") # optional
Untils.connect("resumed", self, "_on_resumed")
var info = yield(Untils.init(), "completed")
level = Untils.get_int("level", 1) # saved progress
start_game()
func on_play_pressed():
Untils.gameplay_start()
func on_game_over():
Untils.gameplay_stop()
Untils.set_int("level", level) # saved automatically
yield(Untils.commercial_break(), "completed") # ads not live yet: continues at once
show_game_over_screen()
func on_reward_button():
var rewarded = yield(Untils.rewarded_break(), "completed")
if rewarded:
give_coins()
Commands
| Command | What it does | Status |
|---|---|---|
Untils.init(debug) | Starts the SDK and loads saved data. Call it first. Returns a Dictionary { name, version, env, isMobile, player, language } (also sent with the initialized signal). Never fails. Waits up to 3 seconds for UNTILS. | Live |
Untils.set_int / get_int / set_float / get_float / set_string / get_string / set_bool / get_bool / set_json / get_json / has_key / keys / delete_key / delete_all / save_now | Save and read your data, like PlayerPrefs. Saves itself shortly after each change. About 900 KB per game. set_json keeps any Dictionary or Array (JSON types only). | Live (this browser) |
Untils.gameplay_start() / gameplay_stop() | Real play starts / stops (death, menu, pause). Repeated calls are ignored. | Live |
Untils.loading_start() / loading_finished() | Done for you. Only call them yourself if you set auto_loading = false, or if you load more content later. | Live |
Signals paused / resumed | Run when the tab is hidden or shown. With Untils.auto_pause = true (default) the SDK also pauses the game (get_tree().paused) and mutes the Master audio bus for you. | Live |
Untils.is_mobile, language, env, is_ready, player | Handy values. env is "untils" on the site, "offline" in a web build on your own PC, and "editor" when you run from the Godot editor. | Live |
Untils.get_player() | Dictionary with guest and name. Everyone is "Guest" for now. | Basic |
Untils.shareable_url({ "level": 5 }) / get_url_param("level") | Make a share link with your values, and read them back when the game is opened from that link. | Live |
Untils.request_fullscreen() / exit_fullscreen() | Ask UNTILS to enter or leave fullscreen. Call from a button press. | Live |
Untils.track(name, data) | Send your own event, like track("level_complete", {"level": 3}). Name up to 40 characters. Stats come later. | Reserved |
Untils.commercial_break(), rewarded_break(), show_ad(type) | Ads are not live yet. The interstitial continues at once; rewarded_break() gives false. Also sends the ad_finished signal. In the editor and offline, a rewarded ad gives Untils.editor_rewarded_result (default true) so you can test your reward code. | Coming soon |
Untils.submit_score(board, score) | Leaderboards. Returns false until they go live. | Coming soon |
Untils.set_debug(true) | Prints SDK activity in the Output panel and the browser console. | Live |
If something goes wrong
- "Call Untils.init() first" warning: you used a save or event command before
init()finished. Wait forawait Untils.init()(Godot 3:yield(Untils.init(), "completed")) in your first script. Untilsis not found: the plugin is not enabled. Tick Enable in Project Settings → Plugins, or addUntils.gdas an Autoload namedUntils.- Progress is not saved: you used
user://files orConfigFile. Browser storage is blocked in the UNTILS sandbox. UseUntils.set_intand the other save commands. - The game does not start, or shows a "SharedArrayBuffer" error: Thread Support is on. Turn it off in the export settings and export again (Godot 3: Export Type Regular).
- Sound does not start: browsers only allow sound after the first tap or click. Start your music from a button press.
- Large exports: keep the zip under 50 MB. Compress textures and audio, and remove unused export templates.
This SDK is in beta. If you find a problem, please tell us through the contact page and include your Godot version.
Check your game in the Inspector, pass review and go live.
Inspector view and SDK check
Before a game or a new version (new zip) is uploaded, UNTILS checks your zip for the Untils SDK. If the SDK is missing, a red panel appears and the upload does not start, so integrate the SDK first and upload again. After the upload, UNTILS opens an Inspector view panel in your dashboard. It starts your game in the background and checks whether the Untils SDK is running, and the panel confirms the result.
The panel always has a link to the Inspector page. There your game opens like on UNTILS, with a console on the side that shows each event as it happens:
- init: the SDK started (and which SDK and version).
- loading start and finished, gameplay start and stop.
- save: how many keys and how big, and track events with their data.
- ad and score requests (ads and leaderboards are not live yet).
- error: errors from your game, when the SDK is running.
Chips at the top turn green when an event has fired. You can switch between Desktop and Phone size, restart the game, and copy the log.
Review and going live
- PENDING - your game is waiting. Our team plays it on PC and phone and writes reviews. Review takes up to 2 days. While you wait, click your game in the dashboard and press Preview on UNTILS to play it on a UNTILS game page. The preview link works for 24 hours.
- APPROVED or REJECTED - the leader decides. If rejected, a note explains why on your dashboard, and you can fix it and upload again.
- LIVE - the game is public on UNTILS. A green PLAY button appears next to it in your dashboard, together with plays, players and likes. Messages from our team also show there, next to the game.
Rules
- Your game must be yours, or you must have the right to publish it.
- No adult content, hate, or violence aimed at real people.
- No malware, crypto-mining, tracking, or collecting players' personal data.
- No misleading names, icons, screenshots or banners.
- The game must work, load in a reasonable time, and not crash.
Questions? Use the contact page.
