Nepeo's Forum Posts

  • I guess if you really wanted to you could stash a reference to the original console object and replace it with an object which has the same methods, but are no-ops. Then in your code use the original console object.

    You would likely need to add global error and unhandled promise rejection event listeners so that any errors wouldn't be printed to the log.

    This is likely to be pretty brittle. Things like failed network requests get printed to the log even if they are caught, and it won't intercept any logs from web workers. But it might work for your project. If not you might want to consider making a fake console window for your game.

  • Wave audio files are basically a wrapper with some header information around the plain PCM audio. All audio formats have to be converted back to PCM to be played by a computer anyway, that's one of the reasons that pretty much everything supports wave files.

    In terms of getting PCM audio you can use the web audio API. It provides a method that takes any audio file supported by the platform and converts it into an "AudioBuffer" object which is a loose wrapper around the PCM data. Once you have that you basically need to find a way to pack it into a wave file.

    I had a quick look and there's a rough method for creating a wave audio file here. It could do with tidying up, and it needs some minor adaptation but it's quite doable.

    Most of this requires some sort of JS knowledge unfortunately...

  • z-worker is part of the archiving process, so it would be affecting any form of saving not just cloud save. I don't think we've heard any other mentions of this. Best guess is some networking issue?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • You could set it up so that the page that links to the game opens it in a new window? Doesn't stop people copy pasting the URL but probably covers most situations.

  • I can't provide too much feedback, as I've read a fair amount about the app signing service but I haven't used it. There's a few advantages I can think of:

    1. You can use Android App Bundles
    2. Your application is protected against the loss of your keystore
    3. If your keystore is compromised your app is protected from a 3rd party creating a modified build

    Android App Bundles is another kinda large topic; it's basically an alternative way to publish your application. The play store uses the bundle to produce multiple APKs based on the requirements of different phones ( screen size and CPU architecture ), so that it can remove anything that isn't required by that device. As the play store has to sign those APKs you have to use the app signing service for this. Unfortunately construct apps don't really benefit from this, so there's not much to be gained from it.

    Sounds like your already fairly protected against #2.

    #3 is fairly important. Signing an application is basically your stamp as a developer to say that you made it. Several services rely on the application signature to ensure that the app is legit. If your keystore is compromised somebody could potentially produce a modified version of your application, with your signature on it. This would mean those services would trust the application. The amount of damage that could be done with this obviously varies on the service, but it's definitely something you want to avoid. Provided you keep the keystore in a safe location, and with a very strong password on it, this likely won't a problem. But by using the app signing service the malicious actor has to have both compromised your keystore, and have access to your application on the Google Play Console. If the keystore is compromised then you can revoke it with Google Play, which isn't something you can do without app signing.

    As a final note, your probably aware of this but once you publish an app your stuck with your decision!

    I seem to be able to publish to the Alpha channel without any problems

    CGamez there is someone on the cordova thread I linked who mentions that they received the warning whenever they tried to publish, but in fact it wasn't that which was preventing them from publishing. Just bad UI.

  • It's a reason I guess, although I'm not sure if an iframe is an actual workaround in this situation. There's a JS API window.open which creates a child window, either as a tab or a popup. That would be the standard use for this. I'm not entirely sure what your aiming for with this, but closing the iframe ( not the tab containing it ) doesn't sound that useful for you?

  • Probably worth looking at https://developer.mozilla.org/en-US/docs/Web/API/Window/close as that's the API which we use for Browser.Close in HTML5 exports.

    The obviously looking restriction is that it only works if the current window was spawned as a child of another window.

    This matches what the documentation says

    Security limitations sometimes prevent browser actions. For example, the window Close action can only be used when the window was created by a JavaScript window.open call.

  • While functions only support 3 primitive values (boolean, number and string) you can use a number parameter to pass the unique ID for an object instance.

    The event sheets use a selection/filtering technique for referring to an object. By default referring to "PlayerSprite" will affects all instances of "PlayerSprite", but some conditions can filter the selection down to some or one "PlayerSprite" instance. Conditions like collision triggers will only select the instance that collided for example. There's also some conditions that allow you to explicitly filter which ones you want, such as "compare instance variable" which allows you to choose instances with a certain value in an instance variable. One of the most useful it "Pick by UID" which allows you to filter to a single instance of an object, that matches a unique ID value. You can use this in combination with a function by adding a parameter for the UID ( which is a number ) then adding the "pick by UID" condition to the function itself. Like so:

  • tkain it's possible to do that fairly easily for cut and copy using document.execCommand("copy"), but paste has security restrictions that prevent that sort of trick.

    You can map a click event to use the navigator.clipboard.read(Text)? methods, but it requires figuring out the permissions APIs as I mentioned.

  • A few good suggestions here, kinda depends on what sort of pattern you want. The easiest solution I can think of is recursive subdivision. Basically everything starts as the largest size tile, then you split each tile into 4 smaller tiles, and repeat for as many divisions as you want.

    This algorithm is basically "quadtrees", which can be used for many things. Here's a cool quadtree art thing by Michael Fogleman, it's worth checking out his stuff because he has some very awesome projects!

  • The clipboard API is a little fiddly, it's possible to capture paste events with the contents. However, the Construct runtime blocks the context menu so users will only be able to paste by doing ctrl+v at the moment.

    Here's a snippet that allows you to listen to paste events and get any pasted files ( like images ).

    window.addEventListener('paste', event => {
    	for (const item of event.clipboardData.items) {
    		if (item.kind === 'file') {
    			console.log(item.getAsFile());
    		}
    	}
    });

    I briefly looked into the idea of triggering a paste manually, which obviously has strong security restrictions ( otherwise any website could look at the contents of you clipboard ). It's relatively easy to read text from the clipboard, although the user has to grant permission. Unfortunately arbitrary clipboard data is still under development by the browser teams. Diego did some work around this API recently and told me it's pretty awkward to work with, and it's only supported in the latest version of Chrome.

    This is the MDN article on reading clipboard text and this is the MDN article on reading arbitrary clipboard data.

    Small warning from the latter MDN article:

  • It's possible to process file drag and drops in the browser, but there are certain security restrictions. I'm not sure how you would do it with a piece of text, but it's probably possible.

    Dragging an image from another website for instance does not give you the image file, but will give you the URL for the image. You may or may not be able to request this file from the remote server, depending on the configuration of that server. But in most cases this is impossible without running your own server to download the images from the remote servers on demand and send them back to your game.

    Files dropped from the user file system will appear as a "file" object that can be read, but not written to.

    I don't know off the top of the head if we have a mechanism for this, I'm guessing that we don't as it's something that would likely require the binary data plugin and that is still quite new. But I can't see any reasons why we couldn't support it. Maybe do a bit more searching around and file a feature request if you can't find anything.

    If your happy with JS then you can use this snippet based on https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop to get a file dropped on the page.

    // Put any global functions etc. here
    
    runOnStartup(async runtime =>
    {
    	// Code to run on the loading screen
    	
    	runtime.addEventListener("beforeprojectstart", () => OnBeforeProjectStart(runtime));
    });
    
    function OnBeforeProjectStart(runtime)
    {
    	document.body.addEventListener("drop", dropHandler);
    	document.body.addEventListener("dragover", dragOverHandler);
    }
    
    function dropHandler(ev) {
    	console.log('File(s) dropped');
    
    	// Prevent default behavior (Prevent file from being opened)
     	ev.preventDefault();
    
     	if (ev.dataTransfer.items) {
     		// Use DataTransferItemList interface to access the file(s)
     		for (var i = 0; i < ev.dataTransfer.items.length; i++) {
     			// If dropped items aren't files, reject them
     			if (ev.dataTransfer.items[i].kind === 'file') {
     				var file = ev.dataTransfer.items[i].getAsFile();
     				console.log('... file[' + i + '].name = ' + file.name);
     			}
     		}
     	} else {
     		// Use DataTransfer interface to access the file(s)
    		 for (var i = 0; i < ev.dataTransfer.files.length; i++) {
    			 console.log('... file[' + i + '].name = ' + ev.dataTransfer.files[i].name);
    		 }
    	 }
    }
    
    function dragOverHandler(ev) {
     	console.log('File(s) in drop zone'); 
    	
     	// Prevent default behavior (Prevent file from being opened)
    	 ev.preventDefault();
    }
    

    It requires that you do not use "worker mode" on your game, which is under "advanced" in the project properties.

  • In worker mode the runtime runs in a WebWorker. WebWorkers are considered a separate "thread" that runs along side the main "thread". Threads cannot directly access each other, which means they can run on independent CPU cores and hence not interfere with each other. The only way they can communicate is to send messages using the MessageChannel API.

    Cordova code has to run on the main thread. As you cannot read/write to the variables of other threads this means it cannot be accessed from a WebWorker. For Construct plugins that need to run on the main thread they register an additional script that the runtime knows to start on the main thread, which can send/receive messages from the main part of the plugin.

    I don't believe we have a mechanism for registering a user script to run on the main thread yet. So if you want to interface directly with Cordova plugins you will not be able to use worker mode.

    Incidentally "window" is not the global object in worker mode, and in fact doesn't exist...

    If you want to listen to changes in sign in state you need to use the "setCallback" method that Eren mentions.