Im using twine in the harlowe 3.1.0 language and I need to speed up my game! Can anyone help me? Im pretty sure the way to fix this is to find away to get the engine to stop cloning variables but not sure. Plz help ASAP.
Iâve not heard of Twine cloning variables before. Could you post a snippet of your code that you think may be causing this behavior?
If youâre worried that posting parts of your game might be spoiler-ish, you can use a lorem ipsum generator to make some nonsense placeholder text.
Harlowe doesnât currently have any way to limit the amount of game history that is stored, unfortunately.
I believe that theyâre talking about how variables get copied in the gameâs history on every passage transition.
Yea thats what I mean, my game takes 5-10 second to load per link, also this is my first post since I have been finding most of my answers on already made forums. Do you know how I could make snippets of code?
Is there anyway I could split it into multiple games using external links if I canât stop the cloning proccess?
By âsnippetâ they just meant copy and paste some of your code that uses the variables here. We canât suggest fixes without seeing the problem. When you do post the code, be sure to use the little </>
button in the editor to format your code (it preserves spaces, tabs, and HTML tags that way).
I find it really hard to believe that your game actually needs 1000 variables. There must be something youâre doing that can be optimized to reduce the number.
Im having to make multiple variables for over 50 characters, 10 seperate times.
(set: $QB1ARMSTRENGTH1 to (random: 6,10))
(set: $QB1ACCURACY1 to (random: 4,10))
(set: $QB1SCRAMBLING1 to (random: 1,10))
(set: $QB2ARMSTRENGTH1 to (random: 4,10))
(set: $QB2ACCURACY1 to (random: 2,7))
(set: $QB2SCRAMBLING1 to (random: 1,10))
(set: $HB1SPEED1 to (random: 5,10))
(set: $HB1POWER1 to (random: 1,10))
(set: $HB1CATCH1 to (random: 3,10))
(set: $HB2SPEED1 to (random: 3,10))
(set: $HB2POWER1 to (random: 1,8))
(set: $HB2CATCH1 to (random: 2,10))
(set: $HB3SPEED1 to (random: 2,8))
(set: $HB3POWER1 to (random: 1,6))
(set: $HB3CATCH1 to (random: 1,8))
(set: $WR1SPEED1 to (random: 5,10))
(set: $WR1CATCH1 to (random: 7,10))
(set: $WR2SPEED1 to (random: 3,10))
(set: $WR2CATCH1 to (random: 4,10))
(set: $WR3SPEED1 to (random: 7,10))
(set: $WR3CATCH1 to (random: 2,8))
(set: $WR4SPEED1 to (random: 2,9))
(set: $WR4CATCH1 to (random: 1,6))
(set: $WR5SPEED1 to (random: 1,7))
(set: $WR5CATCH1 to (random: 1,5))
(set: $TE1SPEED1 to (random: 5,8))
(set: $TE1CATCH1 to (random: 4,7))
(set: $TE1BLOCK1 to (random: 2,10))
(set: $TE2SPEED1 to (random: 2,7))
(set: $TE2CATCH1 to (random: 2,5))
(set: $TE2BLOCK1 to (random: 1,7))
(set: $OG1SPEED1 to (random: 4,10))
(set: $OG1POWER1 to (random: 6,10))
(set: $OG2SPEED1 to (random: 4,10))
(set: $OG2POWER1 to (random: 6,10))
(set: $OG3SPEED1 to (random: 2,7))
(set: $OG3POWER1 to (random: 4,9))
(set: $OG4SPEED1 to (random: 2,7))
(set: $OG4POWER1 to (random: 4,9))
(set: $OT1SPEED1 to (random: 6,10))
(set: $OT1POWER1 to (random: 5,10))
(set: $OT2SPEED1 to (random: 6,10))
(set: $OT2POWER1 to (random: 5,10))
(set: $OT3SPEED1 to (random: 2,6))
(set: $OT3POWER1 to (random: 5,7))
(set: $OT4SPEED1 to (random: 2,6))
(set: $OT4POWER1 to (random: 5,7))
(set: $C1SPEED1 to (random: 7,10))
(set: $C1POWER1 to (random: 6,10))
(set: $C2SPEED1 to (random: 4,8))
(set: $C2POWER1 to (random: 3,7))
(set: $QB1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $QB2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $HB1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $HB2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $HB3one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $WR1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $WR2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $WR3one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $WR4one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $WR5one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $TE1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $TE2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OG1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OG2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OG3one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OG4one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OT1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OT2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OT3one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $OT4one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $C1one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
(set: $C2one to (either: "Luke","Donald","Conner","Alex","Taylor","Kaden","Trey","Tracey"))
I have 10 of these and then even more code.
It looks like most of this could be replaced with datamaps, which would probably cut your amount of variables to between 10 to 100, depending on how you want to divide it up (either by assigning a datamap to each player or each team). But Iâm not very familiar with Harlowe, so I donât know whether a datamap of 100 items is faster than 100 variables.
Either way, take a look at the reference and see if itâs something thatâll work for you.
Sorry for bothering you again but could you give me a small example of this using a few variables from my code because I donât understand how this would work? Thanks for the help either way.
(set: $team1 to (dm:
"QB1ARMSTRENGTH1", (random: 6,10),
"QB1ACCURACY1", (random: 4,10)
)
)
(print: $team1's "QB1ARMSTRENGTH1")
Like that, I believe. I donât use Harlowe except for occasionally trying to help people out, so hopefully the syntax is correct.
Wait what would I replace with that code? The either code?
(set: $QB1ARMSTRENGTH1 to (random: 6,10))
(set: $QB1ACCURACY1 to (random: 4,10))
becomes
(set: $team1 to (dm:
"QB1ARMSTRENGTH1", (random: 6,10),
"QB1ACCURACY1", (random: 4,10)
)
)
I only showed two of them to keep the example short, but you can add the rest below those two using the same format. Be sure to end each line with a comma (with the exception of the final line) or else itâll error.
Edit: Oh, and like in the print statement in the first example, instead of accessing the value using $QB1ARMSTRENGTH1
, youâll now access it using $team1's "QB1ARMSTRENGTH1"
.
I could be wrong here, but I donât think replacing a number of variables storing primitives with datamaps will be faster in Harlowe. Cleaner, perhaps, but not faster. Each time you modify any value within a datamap, the entire map will be copied rather than a single primitive value.
I wouldnât think that Harlowe should have issues with a large number of variablesâespecially that mostly hold primitives. Harlowe also does not clone on passage transitions, AFAIK, but on access, so itâs curious that youâre seeing the slowdown on activating passage links. Are you doing something involved each turn? E.g., looping, lots of calculations, etc.
Harloweâs Passage Transition process and associated History system works a little different to that of SugarCube, and is based on Object Prototype inheritance instead of a collection of Moments.
eg. the following is a very basic representation of how Harloweâs History is structured.
/* 1st Moment... */
state: {
name: "Jane Doe",
age: 21,
tags: ["aaa", "bbb", "ccc"]
}
/* 2nd Moment... */
state: {
prototype: {
name: "Jane Doe",
age: 21,
tags: ["aaa", "bbb", "ccc"]
}
}
/* 3rd Moment... , variable 'location' is created */
state: {
prototype: {
prototype: {
name: "Jane Doe",
age: 21,
tags: ["aaa", "bbb", "ccc"]
}
},
location: "Home"
}
/* 4th Moment, new tag is added. */
state: {
prototype: {
prototype: {
prototype: {
name: "Jane Doe",
age: 21,
tags: ["aaa", "bbb", "ccc"]
}
},
location: "Home"
}
tags: ["aaa", "bbb", "ccc", "ddd"]
}
note: The cloning of the âtagsâ collection in the 4th Moment is actually performed by the (set:)
macro that added the âdddâ value to the collection. eg. (set: $tags to it + (a: "ddd"))
And that cloning action is performed every time a collection object (like an Array or Data-Map) is modified using the (set:)
family of macros.
Right now Iâm just loading a ton of values for future use, almost no work in the game, just a basic interface.
Just a thought: you donât need to initialize all the variables that youâre ever going to need right at the beginning. You can simply create a variable by using it. â i.e.
(set: $myNewVariable to "whatever")
Obviously itâs a good idea to keep a separate note of where you first used a variable for debugging purposes. (Or, in my case, coding paranoia.)
So how about initializing only the absolutely essential variables right at the start? I know it seems like youâre only putting off the evil hour â but thatâs life!
I found out I can just make a twine game and then make new passages with it but the rest I do in notes by exporting file because it increases performance in every aspect including editing code and loading passages with most being instant and some being up to 5 times faster. But thanks for the help anyways!