*looplimit doesn't work

Hi, so I’m experiencing a kind-of weird bug.
Let’s say that I have string variable ‘history’ where I store all the important decisions/choices the player makes. When needed, I then use a ‘find’ function of the cslibrary to check whether that choice has been taken or not (now, I understand that it’s far from the most efficient way to do so, but it’s much easier for me to keep track of everything like this instead of creating dozens/hundreds of variables - afaik speed is not the concern of CS games).

When testing the game with randomtest, I encountered an error:
RANDOMTEST FAILED: Error: cslib_string line 117: visited this line too many times (1000)
After some poking around, I figured out that it happens whenever the ‘history’ variable gets above a certain size. With google as my best friend, I managed to find the supposed solution for this: *looplimit command should get rid of the limit on lines visited/increase that limit.

Thing is, it doesn’t work. Idk, maybe I’m stupid or something, but *looplimit has no effect at all for me (the limit is still 1000 no matter what amount I set; I put the *looplimit command right after the achievements as it seems to be the only suitable place). I’ve compiled the game and changed up the variable for looplimit manually in the html file and the bug disappears, everything works fine, but this way I can neither use randomtest / playtest in CSIDE.

Anyone knows what to do? Thanks in advance :slight_smile:


I know this technically doesn’t answer your question, but are you sure you are jumping to that label 1000 times during an organic playthrough? Disabling the loop limit might hinder you from discovering infinite loops you would not find otherwise.

I am. I basically have all the choices there, so the ‘history’ var looks like "lost_tournaments|took_first_place_tournament|killed_annoying_guy_tournament|". As far as I understand, the ‘find’ function in cslib works by separating the string into characters and looping through them, so I easily reach 1000 iterations in a big string.

Like I said, I’ve compiled the game into a html file and changed the looplimit there by hand - everything works fine, no errors. I’ve even filled the ‘history’ var with like 50k chars just for the hell of it, still no problems :sweat_smile:

1 Like

I mean… appending strings to a variable to emulate boolean variables is kind of overkill, but you do you I guess. Just keep in mind that if you have infinite loops somewhere else, random test won’t pick up on them.

1 Like

At work now, but you can raise the loop limit. Had the same issue in Fallen Hero Retribution. Try *looplimit 3000 or something, can’t remember where I put it and don’t have code at work.

It could be an issue with CSIDE, or perhaps randomtest doesn’t honour looplimit? Either way, if you wouldn’t mind sending me a working example of your code/game (feel free to reduce it down to a minimal case), I’ll do some investigation.

1 Like

That’s exactly my problem, *looplimit doesn’t change anything. Like, the limit of iterations is always 1000, no matter what I put. If I change it in the html file, then everything’s fine :sob:
I’ve tried it on dashingdon, the game works fine there - but I’ve also tried doing something akin to *looplimit 50 and it still iterated through a loop thousands of times without any errors, so I assume they have a set looplimit and the command doesn’t modify it either.

PMed you!


So it looks like *looplimit doesn’t set a global value. It’s actually tied to the instance of scene it’s used in, so it won’t have an effect on loops caused by goto_scene or gosub_scene. I’ve no idea if this is an oversight or intentional behaviour. You’ll have to ask @dfabulich about that one.

For now, you can avoid the error in your particular use case by putting your *looplimit line inside your copy of the find cslib function:


*label find
*params p_str p_find_str
*looplimit 50000                              <------- I'M NEW!
*temp p_str_len length(p_str)
*temp p_find_str_len length(p_find_str)
*if (p_find_str = p_str)
	*set cslib_ret 1

This does raise a rather problematic issue with reusable code in ChoiceScript though… I really think looplimit should be a global variable, like implicit_control_flow.

@choicehacker , @cup_half_empty – curious to your takes on this?
Anything we could do on the CSLIB side?


Look, I’m fairly new to CS/programming in general, but looplimit looks like it’s supposed to be a global var/already is
For some reason, the *looplimit command just changes it temporarily? Idk, the javascript is still a mystery to me :sweat_smile:

Thank you for your help! At least I’ll be able to run randomtest now.

Well, you could always reroute all the functions (or just the ones that require looping) into another *gosub that sets the looplimit first :grin:


Look, I’m fairly new to CS/programming in general, but looplimit looks like it’s supposed to be a global var/already is

It’s defined as a property of any object created via the ‘Scene’ function, a new copy of which is created for every real scene your game jumps to, see the implementation of goto_scene:

The looplimit command sets this.looplimit_count. this is a magic programming keyword that refers to the instance of an object type within which it is scoped, in short: the currently active Scene.

tl;dr: Every scene you *goto_scene to effectively has its own private copy of looplimit_count.

That’s exactly what I’m hoping we won’t have to do :weary:


Appreciate the explanation! So doing something like this should do the trick:
Shame it can’t be done directly through the CS, unless *script but that’s not supported afaik?

Once again, thanks, it’s been very helpful :hugs:


Ash so that is why I had to have 5 instances of looplimit in my game…


I was reluctant to mess with *looplimit because I too thought it had a global effect. But if it is really constrained to the scope of the scene, maybe including a high loop limit to the subroutines that require it could be a “good-enough” solution, albeit not perfect, since it’s hard to predict the stress requirement.


This topic was automatically closed 24 hours after the last reply. If you want to reopen your WiP, contact the moderators.