Problem pre-loading images (Sugarcube 2.31.1)

Twine 2, (Sugarcube 2.31.1)

Hi folks,

Twine 2, (Sugarcube 2.31.1)

I’ve been using TME’s pre-loading image function (Javascript + CSS) which has been working really well with absolute image URLS. I’ve just changed to relative URLS and can’t get it to work. Any ideas where I’ve gone wrong?

Here’s my Javascript:

/*PRELOADING IMAGES SO THERE'S LESS DELAY -( JAVASCRIPT)*/
(function () {
	var sources = [			
"images/cave3.jpg",
"images/cave4.jpg",
"images/dragon.jpg",
"images/dungeon4.jpg",
"images/forestbest.jpg",
"images/forestdark.jpg",
"images/forestwolf.jpg",
"images/lake.jpg",
"images/mountain.jpg",
"images/ruin.jpg",
"images/sewers.jpg",
"images/swamp.jpg",
"images/tower.jpg",
"images/alley2.jpg"
	],
	docFrag = document.createDocumentFragment(),
		imgBox  = document.createElement("div");
	imgBox.id = "imgloader-box";
	docFrag.appendChild(imgBox);
	sources.forEach(function (src) {
		var image = document.createElement("img");
		image.src = src;
		imgBox.appendChild(image);
	});
	document.body.appendChild(docFrag);
}());
/*END PRELOADING IMAGES SO THERE'S LESS DELAY*/

Here’s the partner CSS for the above JAVASCRIPT

#imgloader-box{position:fixed;left:0;top:0;width:2px;height:2px;overflow:hidden;z-index:0}
#imgloader-box img{position:absolute;left:0;top:0;width:1px;height:1px}

And here’s a background image class

body.forest {
	background-image: url("images/forestbest.jpg");
	background-repeat:no-repeat;
	background-attachment: fixed;
	background-position: center;
	background-size:cover;
	margin: 0;    
}

So that background image is loading, but it’s loading really slowly. Before when the images were absolute URLS it was basically instant, so I’ve got something wrong somewhere.

Not sure if it’s worth mentioning, but suddenly some of my fonts are not loading properly either, and my text animations are also not working? Don’t know if that’s related, but anyway I’d love to hear your thoughts!

When you were using absolute URLs, where were they pointing? Somewhere online or to somewhere on your computer? If it’s the latter, that would explain the difference.

Also, you may not want to load all of the images simultaneously like that since, if you’re on a slow enough connection, that will slow down loading all of the images, due to the fact that they’re all downloading at the same, producing the opposite of the effect you want at first. It’s better to have the images in the list be ordered by the ones you’ll likely need first at the top of the list, and the ones you’ll need last at the end of the list. Then, just start loading the first few images, and only pre-load more as the previous ones complete.

If you need help with that, you could take a look at the cacheImages() related code in UInv’s UniversalInventorySystem.js file, since that’s what it does. If you want to simply copy it to your code, that’s fine too.

If you need any help after that, just ask. :slight_smile:

2 Likes

Thanks so much for your help. Really appreciate your wisdom.

So my absolute links were all pointing to a folder of images online. And I’m wanting a relative system that will also link to files online. Is that possible?

I’ll check out your caching example. That sounds awesome!

Yeah, you should be able to do it pretty easily. You just need to put the HTML file in the same folder that holds your “images” directory online.

1 Like

If the images aren’t “too big”, you might want to consider including them in the game’s HTML, so they don’t have to be loaded at runtime. That’d be at the expense of making the game’s HTML file itself that much larger and slower to load, of course.

1 Like

Base64/UTF8 encoded images included in the HTML will be about twice the file size of the equivalent JPEG/PNG/etc. image file. As such, I’d only recommend using that for very small images, such as icons and the like, which absolutely need to be there correctly every time.

Thanks for your input guys.

So just to be clear, the relative links (ie for that CSS class) ARE working. And my twine file is in the same directory as my “images” folder.

What isn’t working is the image preloading, which worked before using absolute urls and was totally awesome. As much as I hate absolute urls, I’d go back to that if it’s the only way to get images loading fast. I just can’t understand why it’s not loading the relative links?

Ok so I managed to isolate the problem by taking out bits of my javascript one at a time. By itself the preloader works just fine. It seems to be conflicting with HiEv’s handy pathing javascript below. When both are present the images don’t load properly, but the pathing is super handy for testing in desktop twine. Can I keep both somehow?

Any ideas what I’m doing wrong?

/PRELOADING IMAGES SO THERE’S LESS DELAY -( JAVASCRIPT)/
(function () {
var sources = [
“images/cave3.jpg”,
“images/cave4.jpg”,
“images/dragon.jpg”,
“images/dungeon4.jpg”,
“images/forestbest.jpg”,
“images/forestdark.jpg”,
“images/forestwolf.jpg”,
“images/lake.jpg”,
“images/mountain.jpg”,
“images/ruin.jpg”,
“images/sewers.jpg”,
“images/swamp.jpg”,
“images/tower.jpg”,
“images/alley2.jpg”
],
docFrag = document.createDocumentFragment(),
imgBox = document.createElement(“div”);
imgBox.id = “imgloader-box”;
docFrag.appendChild(imgBox);
sources.forEach(function (src) {
var image = document.createElement(“img”);
image.src = src;
imgBox.appendChild(image);
});
document.body.appendChild(docFrag);
}());
/END PRELOADING IMAGES SO THERE’S LESS DELAY/

/Get correct path. - Start (HiEv’s)/
if (window.hasOwnProperty(“storyFormat”) || document.location.href.toLowerCase().includes(“/temp/”)) {
// Change this to the path where the HTML file is
// located if you want to run this from inside Twine.
setup.Path = “F:/My Drive/Game Design Stuff/gogamewise/gamifiedwriting/fantasy/”; // Running inside Twine application
} else {
setup.Path = “Fantasy Creative Writing Prompt • GameWise”; // Running in a browser

setup.ImagePath = setup.Path + “images/”;
setup.SoundPath = setup.Path + “sounds/”;
/*Get correct path. - End */

There should be no difference in speed for relative vs absolute paths, if the images are at the same site.

You should check the console log to see if the images are loading properly. Just look in the “Console” window after opening up the “Developer Tools” windows, and you should see errors if they don’t load correctly.

1 Like

You know what’s weird? In my twine Javascript that pathing Javascript definitely has “/Get correct path. - Start (HiEv’s)/” but here it displays without the “*”. Hmm could that be something?

That line should just be:

setup.Path = "";

There shouldn’t be a path in there, since it should be using a relative path.

You have to write your code within a “Preformatted text” block (use the </> button), otherwise this forum screws up the formatting.

1 Like

AH! Viola! I’ll test that right now. Thanks!!!

Hmm ok the images are still not loading properly (throwing an error in console) and now I’m getting an “Enexpected end of input” error when the game starts up too. Here’s the current code:

/*Get correct path. - Start*/
if (window.hasOwnProperty("storyFormat") || document.location.href.toLowerCase().includes("/temp/")) {
	// Change this to the path where the HTML file is
	// located if you want to run this from inside Twine.
	setup.Path = "";  // Running inside Twine application
} else {
	setup.Path = "";  // Running in a browser

setup.ImagePath = setup.Path + "images/";
setup.SoundPath = setup.Path + "sounds/";
/*Get correct path. - End */

Any ideas?

Ah ok cool. I seem to forget that every time xP

You’re missing a closing } before setup.ImagePath = setup.Path + "images/";

This is just a guess, but if you accidentally had that } placed further down earlier, then that means the setup.ImagePath (etc) stuff was only being set for your browser code and would not be set for inside twine.

Another issue:
setup.ImagePath = setup.Path + "images/";
So the path is images/ right?
var sources = [“images/cave3.jpg”, (snippet)
Does that mean it’s looking for images/images/cave3.jpg?

I don’t know how the mechanics of this script works under the hood, so forgive me if I’m coming to the wrong conclusion.

1 Like

Thanks for that. Very helpful.
I’ve fiddled around with it for hours now. Just can’t get it the images to work offline (ie when I click play in twine). But it’s working online now with relative links which is a massive relief.

As tayruh mentioned, you got rid of a “}” that was supposed to be there. Also, you weren’t supposed to remove the path from both lines, just the one.

The code should be like this:

/* Get correct path. - Start */
if (window.hasOwnProperty("storyFormat") || document.location.href.toLowerCase().includes("/temp/")) {
	// Change this to the path where the HTML file is
	// located if you want to run this from inside Twine.
	setup.Path = "F:/My Drive/Game Design Stuff/gogamewise/gamifiedwriting/fantasy/";  // Running inside Twine application
} else {
	setup.Path = "";  // Running in a browser
}
setup.ImagePath = setup.Path + "images/";
setup.SoundPath = setup.Path + "sounds/";
/* Get correct path. - End */

The first path is for when it’s launched from Twine and needs an absolute path (as noted in the comments in that code), and the second (blank) path is for all other cases, where it uses a relative path.

Put that absolute path back in there and then it should work when you hit Play from Twine, unless your computer doesn’t use a path with “/temp/” in it when launching from Twine. In that case you just have to replace the string in the .includes("/temp/") bit of code with a lowercase string which does always appear in the path.

If you still have problems, then we’ll need to see the code you use to display images in your passages.

Hope that solves it! :slight_smile:

1 Like

Ok so thanks so much for all your help.

No the code still didn’t work with “temp” or any other part of the file name, BUT…I just checked the URL in the browser (launched through offline twine, ie on my windows 10 laptop), and noticed that the file directory was completely different. Looks like the game is booting from “file:///C:/Users/gibbw/AppData/Local/Temp/”.
I copied my images folder into “Temp”, and lo and behold, the links work in offline twine!!!

One question though…I’d really rather not store all my images etc. in that Temp folder…is there a work around or something? I’m not even sure what Temp does, but it doesn’t sound safe! :confused:

You can cheat the system using a symlink (symbolic link). It’ll make Twine (or anything in windows) think that the files are really there when they’re actually somewhere else on your PC. I do this myself with other applications.

With a symlink, if the temp folder gets cleared, only the the link will disappear, not the files.

Here’s a bunch of info on it.

If that’s info overkill, the steps are this:

  1. move your image folder somewhere else
  2. open the windows command console
  3. type this into the console:
    mklink /j "C:/Users/gibbw/AppData/Local/Temp/images" "<image directory>"

That’s it. It should create something that looks like a windows shortcut named “images” inside your temp directory, but that shortcut is actually a symlink.

1 Like

Thanks heaps that’s really cool. I’ll have a look into implementing that.

As a side note, I feel it’s a bit of a shame that workarounds like this are needed though :frowning:
I guess I’m not a programmer, but I wouldn’t have thought it was so hard to allow people to just load stories from wherever they want.

Hmm I guess maybe that’s the best solution we have at the moment though?

Yes, just do the thing I’ve told you to do from the beginning. That’s the whole point of that code. :expressionless:

Use the exact code I gave you above, except change that one line (and only that line) with the path to the directory where your “images” folder is.

If you’re doing this on two different computers (something which you hadn’t mentioned before), then you’ll either have to set up the files at the same location on both machines -or- you’ll have to change that path depending on what computer you’re working on.

If it doesn’t work, then you have the path wrong. It’s that simple.

Sorry if I sound a bit frustrated, but I’ve never had anyone have this much trouble implementing this simple bit of code.