Posted: 24th Apr 2021 20:24
i posted this at itch then thought to post here since it's AppGameKit (classic)-specific and figured someone might have already solved:
"
Posted: 25th Apr 2021 2:59
I believe this could be due to a Cross-site cookie issue, it appears that SameSite=None; Secure attribute is required now when setting cookies.

https://hacks.mozilla.org/2020/08/changes-to-samesite-cookie-behavior/

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

https://web.dev/samesite-cookie-recipes/

Itch.io use an IFRAME so that could be causing the problem, to be honest, i've only just found out about this, so it's an interesting
issue you raised.

I tested your game via https://v6p9d9t4.ssl.hwcdn.net/html/2709328/index.html - without IFRAME

then tested;

https://virtual-nomad.itch.io/p3 - with IFRAME

The p3scores cookie was saved with values 5000|4000|3000|2000|1000 without issue without the IFRAME, but was not saved when the game is called from the IFRAME.

You should be able to enable this behaviour in most browsers. If you use Chrome, you can type in chrome://flags/ in the address bar and I think you enable SameSite by default cookies
and Cookies without SameSite must be secure

If you find out any other info, workarounds etc.. Please post back, I'd like to learn more about this.

I'm not sure if you can set it from javascript, but a possible solution could be something like this:

If you look in HTML5Core.cpp, you may be able to add SameSite=None; Secure to the end of document.cookie, then rebuild agktier2.

+ Code Snippet
void agk::SaveSharedVariable( const char *varName, const char *varValue )
{
	EM_ASM_({
		var cookieName = UTF8ToString($0);
		var cookieValue = UTF8ToString($1);
		var d = new Date();
		d.setTime(d.getTime() + (5 * 365 * 24 * 60 * 60 * 1000)); // 5 years
		var expires = "expires="+d.toUTCString();
		document.cookie = cookieName + "=" + cookieValue + ";" + expires + ";path=/";
	}, varName, varValue);
}


OR manually edit AGKPlayer.js and find:

+ Code Snippet
  document.cookie=cookieName+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/"


Replace with:

+ Code Snippet
document.cookie=cookieName+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=None; Secure"


I'm not so sure that will work.
Posted: 25th Apr 2021 6:31
running it "direct" via https://v6p9d9t4.ssl.hwcdn.net/html/2709328/index.html & it did save, as you said. and, searching "cookie" @ itch provided the same insight offered above.

meanwhile, i'm on Edge atm and whitelisting itch.io + 3rd party cookies + the same for hwcdn.net didn't resolve saves from within the iframe/at itch.io like i'd hoped. and, i can't see a SameSite setting anywhere but will continue the hunt!

thanks pointing me in the right direction, tboy.
Posted: 25th Apr 2021 14:43
I've created a little test https://tvault.itch.io/test2 uses SameSite=None; Secure

and

https://tvault.itch.io/test3 not use SameSite=None; Secure

It creates a basic canvas with "Hello, World" and creates a highscores cookie set to 100

setting document.cookie = "highscores=100; SameSite=None; Secure"; seems to do the trick.

+ Code Snippet
<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>

<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World",10,50);

document.cookie = "highscores=100; SameSite=None; Secure";

</script>

</body>
</html>



I've also set chrome://flags/ to defaults, so no special options have been set.
Posted: 25th Apr 2021 16:35
is that something we can insert into the AGK-generated HTML file somewhere?
+ Code Snippet
<!doctype html>
<html lang="en-us">
  <head>
    <title>AppGameKit Web App</title>
    
    <meta charset="utf-8"/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="viewport" content="user-scalable=no"/>
    
    <style>

        div, a, span {
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }

        body {
            font-family: Helvetica, Arial, sans-serif;
            line-height: 1.25em;
            margin: 0;
            padding: 0;
            padding-top: 0px;
            background-color: #000;
            background-image: url("background.jpg");
            background-repeat: no-repeat;
            background-size: cover;
        }
        
        .container {
            position: relative;
            text-align: center;
            margin-top: 0;
            min-height: 300px;
        }
        
        .footer {
            width: 500px;
            margin: 0 auto;
            padding: 20px 20px;
            position: relative;
            text-align: center;
        }
        
        .footer a.link {
            font-weight: bold;
            font-family: Helvetica, Arial, sans-serif;
            font-size: 12px;
            text-align: center;
            color: #fff;
            text-decoration: none;
            padding: 8px 10px;
            border-radius: 6px;
            color: #ccc;
            -moz-transition: all .3s;
            transition: all .3s;
        }
        
        .footer a.link:hover {
            color: #fff;
            background-color: rgba(0,0,0,.5);
        }

        .footer a.logo {
            display: block;
            margin: 0 auto;
            padding-bottom: 8px;
            margin-bottom: 10px;
            border-bottom: 1px solid rgba(255,255,255,0.2);
            -moz-transition: all .3s;
            transition: all .3s;
        }
        
        .footer img {
            height: 54px;
            display: block;
            margin: 0 auto;
        }
        
        /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
        canvas.emscripten { background: #000; border: 0px none; padding-right: 0; margin-left: auto; margin-right: auto; display: block; }

    </style>
  </head>
  <body>
    
    <div style="text-align: center">
        <div> <span id="agkstatus" style="color:#7f7f7f"></span> </div>
        <div style="display: inline-block; border: 1px solid; margin: 0px auto">
            <canvas class="emscripten" id="canvas" width="800" height="600" oncontextmenu="event.preventDefault()"></canvas>
            <video crossOrigin="anonymous" style="display:none" id="AGKVideo" src=""></video>
        </div>
    </div>
    
    <div class="footer">
        <a class="logo" href="http://www.appgamekit.com" target="_blank"><img src="made-with-appgamekit.png" alt="Made with AppGameKit"></a>

        <a class="link" href="#" onclick="Module.requestFullScreen(false,true)">Run game in fullscreen mode</a>
        <a class="link" href="http://www.appgamekit.com" target="_blank">Learn more about AppGameKit</a>
    </div>
    
    <script type='text/javascript'>
      var agkStatus = document.getElementById("agkstatus");
      if ( agkStatus )
      {
        agkStatus.textContent = "Loading...";
      }

      var Module = {
        preRun: [],
        postRun: [],
        print: function(text) {},
        printErr: function(text) {},
        canvas: (function() {
          var canvas = document.getElementById('canvas');

          canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);

          return canvas;
        })(),
        setStatus: function(text) {},
        totalDependencies: 0,
        monitorRunDependencies: function(left) {}
      };
      window.onerror = function(text) {
        // TODO: do not warn on ok events like simulating an infinite loop or exitStatus
        var agkStatus = document.getElementById("agkstatus");
        if ( agkStatus )
        {
          agkStatus.style.color = "Red";
          agkStatus.textContent = text;
        }
        //alert(text);
      };
    </script>

    <script>

    var script = document.createElement('script');
    script.src = "AGKPlayer.asm.js";
    script.onload = function() {
      setTimeout(function() {
        
          (function() {
            var memoryInitializer = 'AGKPlayer.html.mem';
            if (typeof Module['locateFile'] === 'function') {
              memoryInitializer = Module['locateFile'](memoryInitializer);
            } else if (Module['memoryInitializerPrefixURL']) {
              memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer;
            }
            var xhr = Module['memoryInitializerRequest'] = new XMLHttpRequest();
            xhr.open('GET', memoryInitializer, true);
            xhr.responseType = 'arraybuffer';
            xhr.send(null);
          })();

          var script = document.createElement('script');
          script.src = "AGKPlayer.js";
          document.body.appendChild(script);

      }, 1); // delaying even 1ms is enough to allow compilation memory to be reclaimed
    };
    document.body.appendChild(script);

</script>

  </body>
</html>


and, forgive my HTML ignorance but would:

+ Code Snippet
document.cookie = "highscores=100; SameSite=None; Secure";


not set highscores to 100 each time it loads?

and, i'm assuming we could access (variable name) "highscores" via Save/LoadSharedVariable ?

thanks agan.
Posted: 25th Apr 2021 20:16
It really needs to be changed in the main AppGameKit sourcecode so everyone can benefit from the changes.

If you consider HTML5Core.cpp in AGKTier2, you'll need to edit:

+ Code Snippet
void agk::SaveSharedVariable( const char *varName, const char *varValue )
{
    EM_ASM_({
        var cookieName = UTF8ToString($0);
        var cookieValue = UTF8ToString($1);
        var d = new Date();
        d.setTime(d.getTime() + (5 * 365 * 24 * 60 * 60 * 1000)); // 5 years
        var expires = "expires="+d.toUTCString();
        document.cookie = cookieName + "=" + cookieValue + ";" + expires + ";path=/; SameSite=None; Secure";
    }, varName, varValue);
}


I know someone figured out how to run javascript code from their HTML5 project from Tier1, but as previously suggested it needs to be changed at the source.

If you're willing to provide me with your project media folder and bytecode.byc I could try and build a WebAssembly
version on my PI4 with the suggested changes and find out if it works.
Posted: 25th Apr 2021 20:45
Glad to provide the files when i return home in a day or 2.
Posted: 26th Apr 2021 22:31
Source now available. thanks for looking
Posted: 27th Apr 2021 21:41
I've change HTML5Core.cpp to:

+ Code Snippet
void agk::SaveSharedVariable( const char *varName, const char *varValue )
{
	EM_ASM_({
		var cookieName = UTF8ToString($0);
		var cookieValue = UTF8ToString($1);
		var d = new Date();
		d.setTime(d.getTime() + (5 * 365 * 24 * 60 * 60 * 1000)); // 5 years
		var expires = "expires="+d.toUTCString();
		document.cookie = cookieName + "=" + cookieValue + ";" + expires + ";path=/; SameSite=None; Secure";
	}, varName, varValue);
}


Adding SameSite=None Secure allows you to set and get the cookie on itch.io

Demo: https://tvault.itch.io/cookie

Tier2 code:
+ Code Snippet
#include "template.h"

using namespace AGK;

app App;

void app::Begin(void)
{
  agk::SetErrorMode(2); 
  
  agk::SetVirtualResolution(640, 480);
  agk::SetClearColor(0, 0, 0);
  agk::SetScissor(0, 0, 0, 0);
  
  agk::SetWindowSize(640, 480, 0);
  agk::SetWindowTitle("CookieTest");
  agk::SetWindowAllowResize(0);
  
  agk::UseNewDefaultFonts(1);
  agk::SetPrintSize(30);
  agk::SetPrintColor(255, 255, 255);

  agk::SaveSharedVariable("highscores", "1000");
}

int app::Loop(void)
{
  agk::ClearScreen();
  
  agk::Print("Cookie Test");
  
  agk::PrintC("Highscores Cookie:" );
  agk::PrintC(agk::LoadSharedVariable("highscores", "Coooooooooookie!"));
  
  agk::Sync();
  
  return 0;
}

void app::End(void)
{
}



If you edit AGKPlayer.js and search for document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/"

Change:

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/"

to

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/; SameSite=None; Secure"

It should solve your issue.
Posted: 27th Apr 2021 23:07
Your game:

https://tvault.itch.io/test-game

I can't get true type fonts displaying at the moment, there seems to be a problem with shooting bullets, triple shoot instead of single shot, but I will look into it.
Posted: 28th Apr 2021 3:31
triple shoot

i had updated the source "devlog" notes to advise that i had tinkered with the idea of power-ups after the jam so the triple shot is intentional (and easy enough to return back to single).

otherwise, with vanilla Classic/Studio, if i alter the .JS as mentioned above, it should work? or, do i have re-compile the player? IE, HTML5Core.cpp, (while i have 0 tier-2 experience).
Posted: 28th Apr 2021 6:46
Ah! That's fine then, I thought the triple shoot was an issue my-side, no problem.

I just thought if you change AGKPlayer.js with the suggested change it will get you up and running asap.

Edit the player that you uploaded with the game and see if it has the desired result.

On the Pi version, there is only one entry document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/"

then change to:

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/; SameSite=None; Secure"
Posted: 30th Apr 2021 5:42
Did you get it working?

I once tried using a MySQL highscore table from itch.io but I think itch was blocking the request, it worked fine on desktop, mobile and my own server as soon as it went up to itch it stopped working
Posted: 1st May 2021 12:30
The suggested change seems to work, I uploaded Virtual Nomad's game on my Itch.io page and the cookies saved via the IFRAME.

I've only tested on Chromium and Firefox.
Posted: 5th May 2021 20:42
If you edit AGKPlayer.js, Change:

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/"

to

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/; SameSite=None; Secure"

this does seem to have resolved the issue (tested on Edge). thanks, tboy!!
Posted: 13th Jul 2021 12:30
Sorry for bringing up this old thread again, I just wanted to say big thanks for the solution. Works like a charm!
Posted: 6th Oct 2021 20:40
Thanks to tboy for posting this and thanks to Virtual Nomad for providing the link to this thread. I have used this to save the game statistics in my html5 games. I initially had a syntax error and had to delete the last quotation mark i.e

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/; SameSite=None; Secure""

to

document.cookie=cookieName+"="+cookieValue+";"+expires+";path=/; SameSite=None; Secure"
Posted: 7th Oct 2021 3:41
@zaxxan,

that last quote (") is from me quoting tboy. i removed the formatting so its a simple copy/paste line, now.

and, who do i have to pay to change their avatar to avoid confusion, for me. you or hosch?

that is, unless, you 2 are actually twins. then, i expect its something i'll have to contend with (forever)

either way, yall know you can attach an image to a post and then use that image URL in your Pofile's "Custom Avatar" field, right?

there are so many stock avs on the forum ATM... and, we're too creative for that!
Posted: 7th Oct 2021 5:20
I'll change mine, I never really liked it anyway! But I don't have one to upload at the moment so I'll change it to another stock one