From 62c734c3eca3e252b992700dc3bdd032b00d00c6 Mon Sep 17 00:00:00 2001 From: Artsiom Trubchyk Date: Sun, 28 Dec 2025 23:28:19 +0300 Subject: [PATCH 1/3] Add extension properties file --- ext.properties | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 ext.properties diff --git a/ext.properties b/ext.properties new file mode 100644 index 0000000..28fe028 --- /dev/null +++ b/ext.properties @@ -0,0 +1,18 @@ +[yagames] +title = YaGames +group = Runtime +help = Settings for the YaGames extension + +sdk_url.type = string +sdk_url.label = SDK URL +sdk_url.default = /sdk.js + +sdk_init_options.type = string +sdk_init_options.label = SDK Init Options. Example: `{ signed: true }`. + +sdk_init_snippet.type = string +sdk_init_snippet.label = SDK Init Snippet. `ysdk` is the Yandex Games SDK object. Example: `console.log(ysdk);`. + +service_worker_url.type = string +service_worker_url.label = Service Worker URL (Deprecated) + From 462cc117cd37375d27ed6f2a27d4f15670a87f3a Mon Sep 17 00:00:00 2001 From: Artsiom Trubchyk Date: Sun, 28 Dec 2025 23:35:28 +0300 Subject: [PATCH 2/3] Remove deprecated Service Worker and related files; update README and build scripts for new demo structure. --- .github/workflows/main.yml | 11 +--- README.md | 16 ++--- build_example.sh | 5 -- example/bundle/web/icon/splash.png | Bin 26525 -> 0 bytes example/bundle/web/sw.js | 66 --------------------- example/bundle/web/yandex-manifest.json | 27 --------- game.project | 1 - ext.properties => yagames/ext.properties | 6 +- yagames/manifests/web/sw.js | 5 ++ yagames/manifests/web/yandex-manifest.json | 27 --------- 10 files changed, 19 insertions(+), 145 deletions(-) delete mode 100755 example/bundle/web/icon/splash.png delete mode 100755 example/bundle/web/sw.js delete mode 100755 example/bundle/web/yandex-manifest.json rename ext.properties => yagames/ext.properties (57%) delete mode 100755 yagames/manifests/web/yandex-manifest.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14438b5..4c532d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: "temurin" - java-version: "21" + java-version: "25" - name: Build 🔧 env: @@ -31,11 +31,6 @@ jobs: mkdir -p build/bundle/public - # This demo doesn't implement Service Worker and Native Cache, so remove them from the settings: - sed -i 's/service_worker_url = .*//' game.project - sed -i 's/manifest_url = .*//' game.project - rm -rf example/bundle/web - BOB_SHA1=${DEFOLD_BOB_SHA1:-$(curl -s 'https://d.defold.com/stable/info.json' | jq -r .sha1)} BOB_LOCAL_SHA1=$((java -jar build/bundle/bob.jar --version | cut -d' ' -f6) || true) if [ "${BOB_LOCAL_SHA1}" != "${BOB_SHA1}" ]; then wget --progress=dot:mega -O build/bundle/bob.jar "https://d.defold.com/archive/${BOB_SHA1}/bob/bob.jar"; fi @@ -44,13 +39,13 @@ jobs: TITLE=$(awk -F "=" '/^title/ {gsub(/[ \r\n\t]/, "", $2); print $2}' game.project) java -jar build/bundle/bob.jar --email foo@bar.com --auth 12345 --texture-compression true --bundle-output build/bundle/js-web --platform js-web --architectures wasm-web --archive --variant release resolve build bundle - (cd build/bundle/js-web/${TITLE} && zip -r ../../public/demo_no-sw_no-native-cache.zip .) + (cd build/bundle/js-web/${TITLE} && zip -r ../../public/demo.zip .) - name: Upload Result uses: actions/upload-artifact@v4 with: name: bundle - path: build/bundle/public/demo_no-sw_no-native-cache.zip + path: build/bundle/public/demo.zip - name: Deploy to Pages 🚀 if: github.ref == 'refs/heads/master' diff --git a/README.md b/README.md index 7499d0d..be8a444 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ You can use it in your own project by adding this project as a [Defold library d ## Code Examples -Take a look at the demo project inside `example` directory. It has quite a few buttons to test all APIs. You can use it in your game as a debug screen or simply [download/upload a pre-built .zip archive](https://github.com/indiesoftby/defold-yagames/blob/gh-pages/demo_no-sw_no-native-cache.zip?raw=true) to make sure that you implemented SDK in the right way. +Take a look at the demo project inside `example` directory. It has quite a few buttons to test all APIs. You can use it in your game as a debug screen or simply [download/upload a pre-built .zip archive](https://github.com/indiesoftby/defold-yagames/blob/gh-pages/demo.zip?raw=true) to make sure that you implemented SDK in the right way. ![YaGames Demo](screenshot.png) @@ -3212,28 +3212,28 @@ end ```ini [yagames] sdk_url = /sdk.js -sdk_init_options = {} -sdk_init_snippet = console.log("Yandex Games SDK is ready!"); +sdk_init_options = { signed: false } +sdk_init_snippet = console.log("Yandex Games SDK is ready!", ysdk); service_worker_url = sw.js ``` * `sdk_url` - Sets the URL of the Yandex.Games SDK. In July 2024 the platform changed the URL of its SDK and now it can be of two kinds. First is the local `/sdk.js` for games you upload as an archive (default, **suitable for 99% of games**). The second is for iFrame games - `https://sdk.games.s3.yandex.net/sdk.js`. -* `sdk_init_options` - JavaScript Object that is passed as-is into the Yandex Games SDK initialization options for [the JS `YaGames.init` function](https://yandex.ru/dev/games/doc/dg/sdk/sdk-about.html?lang=en). Example: `{ orientation: { value: "landscape", lock: true } }`. +* `sdk_init_options` - JavaScript Object that is passed as-is into the Yandex Games SDK initialization options for [the JS `YaGames.init` function](https://yandex.ru/dev/games/doc/dg/sdk/sdk-about.html?lang=en). Example: `{ signed: true }`. * `sdk_init_snippet` - JavaScript code that is passed as-is and called when the `ysdk` variable becomes available. Example: `console.log(ysdk);`. **Use with care, and don't forget to put a semicolon `;` at the end.** -* `service_worker_url` - Relative URL to the Service Worker file. Usually it's `sw.js`. Set the URL to enable Service Worker. +* `service_worker_url` - (deprecated) Relative URL to the Service Worker file. Usually it's `sw.js`. Set the URL to enable Service Worker. ### Misc > [!TIP] > We don't use these features in our games as we don't see any improvements in our games metrics, and the complexity of its integration and support is quite high. -#### Service Worker How-To +#### Service Worker -Yandex dropped the Service Worker description page in their docs, but it still allows to integrate Service Worker into your game to be able to run both offline and online. +Yandex dropped the Service Worker description page in their docs, but it still allows to integrate Service Worker into your game to be able to run both offline and online. This feature is deprecated and will be removed in the future. 1. Set the path to the file `sw.js` in the `game.project` settings. 2. Copy the `yagames/manifests/web/sw.js` file to the root directory of your release build. -3. Edit the list of all game files inside your `sw.js`. Omit `sw.js` and `yandex-manifest.json`. +3. Edit the list of all game files inside your `sw.js`. Omit `sw.js`. 4. You should increment the version inside `sw.js` on every update of your game on Yandex.Games. ## Credits diff --git a/build_example.sh b/build_example.sh index 7632e64..44d0332 100644 --- a/build_example.sh +++ b/build_example.sh @@ -6,10 +6,6 @@ # Immediately exit if any command has a non-zero exit status: set -e -# This demo doesn't implement Service Worker and Native Cache, so remove them from the settings: -sed -i 's/service_worker_url = .*//' game.project -sed -i 's/manifest_url = .*//' game.project - mkdir -p build/bundle BOB_SHA1=${BOB_SHA1:-$(curl -s 'https://d.defold.com/stable/info.json' | jq -r .sha1)} @@ -20,7 +16,6 @@ SETTINGS="--build-server https://build.defold.com --variant debug --email foo@ba PLATFORM=js-web ARCHITECTURES=wasm-web java -jar build/bob.jar ${SETTINGS} --bundle-output build/bundle/${PLATFORM} --platform ${PLATFORM} --architectures ${ARCHITECTURES} --archive resolve build bundle -perl -pi -e "s/cachePrefix \+ \"-v1\"/cachePrefix + \"-v$(date +%s)\"/g" "build/bundle/${PLATFORM}/${TITLE}/sw.js" if [ $# -eq 1 ]; then PORT=$1 diff --git a/example/bundle/web/icon/splash.png b/example/bundle/web/icon/splash.png deleted file mode 100755 index 33f1b2f7e97deb35e30362c2a81cf1c2e17364dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26525 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 U;^kdg9RL6T07*qoM6N<$f&qx5;s5{u diff --git a/example/bundle/web/sw.js b/example/bundle/web/sw.js deleted file mode 100755 index 720d9c6..0000000 --- a/example/bundle/web/sw.js +++ /dev/null @@ -1,66 +0,0 @@ -// 1. Put here the name of your game: -const cachePrefix = "yagames-example"; - -// 2. Increment the version every time you publish your game! -const cacheName = cachePrefix + "-v1"; - -const cacheList = [ - "https://yandex.ru/games/sdk/v2", - - // 3. Add ALL your game files to the list: - "index.html", - "dmloader.js", - "yagames.wasm", - "yagames_wasm.js", - "yagames_asmjs.js", - "archive/archive_files.json", - "archive/game.arcd0", - "archive/game.arci0", - "archive/game.dmanifest0", - "archive/game.projectc0", - "archive/game.public.der0", -]; - -// Installation of the service worker -self.addEventListener("install", function (event) { - event.waitUntil( - caches.open(cacheName).then((cache) => { - return cache.addAll(cacheList); - }) - ); -}); - -// Deletion of old cache -self.addEventListener("activate", function (event) { - console.assert(typeof cacheName === "string"); - console.assert(typeof cachePrefix === "string"); - - event.waitUntil( - caches.keys().then((keyList) => { - return Promise.all( - keyList.map((key) => { - if (key.indexOf(cachePrefix) === 0 && key !== cacheName) { - return caches.delete(key); - } - }) - ); - }) - ); -}); - -// Handling of data stored in the device cache with exceptions -self.addEventListener("fetch", function (event) { - if ( - event.request.method !== "GET" || - event.request.url.indexOf("http://") === 0 || - event.request.url.indexOf("an.yandex.ru") !== -1 - ) { - return; - } - - event.respondWith( - caches.match(event.request, { ignoreSearch: true }).then(function (response) { - return response || fetch(event.request); - }) - ); -}); diff --git a/example/bundle/web/yandex-manifest.json b/example/bundle/web/yandex-manifest.json deleted file mode 100755 index 1e610e0..0000000 --- a/example/bundle/web/yandex-manifest.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "icons": [ - { - "src": "icon/splash.png", - "sizes": "256x256", - "type": "image/png" - } - ], - "yandex": { - "splash_screen_color": "#FFFFFF", - "cache": { - "resources": [ - "index.html", - "dmloader.js", - "yagames.wasm", - "yagames_wasm.js", - "yagames_asmjs.js", - "archive/archive_files.json", - "archive/game.arcd0", - "archive/game.arci0", - "archive/game.dmanifest0", - "archive/game.projectc0", - "archive/game.public.der0" - ] - } - } -} diff --git a/game.project b/game.project index 80acde2..ce8ce87 100755 --- a/game.project +++ b/game.project @@ -13,7 +13,6 @@ high_dpi = 1 title = yagames version = 0.18.0 developer = Indiesoft LLC -bundle_resources = example/bundle/ dependencies#0 = https://github.com/subsoap/defos/archive/v2.8.3.zip dependencies#1 = https://github.com/Insality/druid/archive/0.6.0.zip dependencies#2 = https://github.com/britzl/ludobits/archive/7.1.0.zip diff --git a/ext.properties b/yagames/ext.properties similarity index 57% rename from ext.properties rename to yagames/ext.properties index 28fe028..8277f3e 100644 --- a/ext.properties +++ b/yagames/ext.properties @@ -1,6 +1,6 @@ [yagames] title = YaGames -group = Runtime +group = Distribution help = Settings for the YaGames extension sdk_url.type = string @@ -8,10 +8,10 @@ sdk_url.label = SDK URL sdk_url.default = /sdk.js sdk_init_options.type = string -sdk_init_options.label = SDK Init Options. Example: `{ signed: true }`. +sdk_init_options.label = SDK Init Options sdk_init_snippet.type = string -sdk_init_snippet.label = SDK Init Snippet. `ysdk` is the Yandex Games SDK object. Example: `console.log(ysdk);`. +sdk_init_snippet.label = SDK Init Snippet service_worker_url.type = string service_worker_url.label = Service Worker URL (Deprecated) diff --git a/yagames/manifests/web/sw.js b/yagames/manifests/web/sw.js index 00ef724..ed79664 100644 --- a/yagames/manifests/web/sw.js +++ b/yagames/manifests/web/sw.js @@ -1,3 +1,8 @@ +// Service Worker was officially supported and recommended for implementation +// on Yandex Games until 2024, but then became optional and was even removed +// from the documentation. This example and connection options are left for +// legacy projects. + // 1. Put here the name of your game: const cachePrefix = "your-game-name"; diff --git a/yagames/manifests/web/yandex-manifest.json b/yagames/manifests/web/yandex-manifest.json deleted file mode 100755 index 97a85f4..0000000 --- a/yagames/manifests/web/yandex-manifest.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "icons": [ - { - "src": "icon/splash.png", - "sizes": "256x256", - "type": "image/png" - } - ], - "yandex": { - "splash_screen_color": "#FFFFFF", - "cache": { - "resources": [ - "index.html", - "dmloader.js", - "dmengine.wasm", - "dmengine_wasm.js", - "dmengine_asmjs.js", - "archive/archive_files.json", - "archive/game.arcd0", - "archive/game.arci0", - "archive/game.dmanifest0", - "archive/game.projectc0", - "archive/game.public.der0" - ] - } - } -} From 972a0c72595aa47f4ebfc4c697dca565b77ef408 Mon Sep 17 00:00:00 2001 From: Artsiom Trubchyk Date: Sun, 28 Dec 2025 23:39:28 +0300 Subject: [PATCH 3/3] Update README to enhance clarity on SDK initialization and advertisement implementation steps. --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be8a444..c24d06e 100644 --- a/README.md +++ b/README.md @@ -29,18 +29,20 @@ You can use it in your own project by adding this project as a [Defold library d - Icon 512 x 512 px. - Cover 800 x 470 px. - Screenshots. -4. Add [the extension](https://github.com/indiesoftby/defold-yagames/archive/master.zip) as a Defold library dependency to your project. -5. Enable monetization and earn revenue from placing ad blocks in your game. Ad blocks are available in the following formats: +4. Add [the extension](https://github.com/indiesoftby/defold-yagames/archive/master.zip) as a Defold library dependency to your project. +5. Initialize the SDK in your game - see [Initialization](#-initialization-docs) section below for the API details. +6. Implement advertisement in your game - see [Advertisement](#-advertisement-docs) section below for the API details. +7. Enable monetization and earn revenue from placing ad blocks in your game. Ad blocks are available in the following formats: - **Interstitial blocks**: ad blocks that completely cover the app background and show up at certain points (for example, when accessing the next game level). *Important: Mute sounds before showing the ad!* - **Rewarded videos**: blocks with video ads that the user can choose to view and earn a reward or in-game currency. *Important: Mute sounds before showing the ad!* - **Sticky banners**: banner ads, super easy to setup. - **In-game purchases**: earn revenue by providing paid services to your users. -5. You can [publish your game on Yandex.Games](https://games.yandex.ru/console/) from this moment. +8. You can [publish your game on Yandex.Games](https://games.yandex.ru/console/) from this moment. ### Best Practices & Tips 1. The YaGames extension imitates a real API on *non-HTML5* platforms. The idea is to allow to you quickly implement API on your favourite platform (macOS, Windows, Linux) and don't spend time on slowly rebuilding/uploading the game to the Yandex. -2. The code from `yagames/manifests/web/engine_template.html` is always added to your HTML5 template. This behaviour can't be disabled. Tip: use Git-branching for every HTML5 platform and do not mix platform-specific code between them. +2. The code from `yagames/manifests/web/engine_template.html` is always added to your HTML5 template. **This behaviour can't be disabled.** Tip: use Git-branching for every HTML5 platform and do not mix platform-specific code between them. 3. You don't need to set up any cache-busting techniques, since Yandex.Games hosts each version of your game in separate paths. ## Code Examples