How to Restart a Bogged Down Program
#1
Hey coding wizards,

Help! The game I'm working on is misbehaving and I don't understand why. When I go to a certain subroutine it all runs fine, but then if I go back to the beginning of the program - the main loop - the game slows to a crawl and starts crashing over issues that ran perfectly well before that subroutine. I tried using CLEAR, ERASE and RUN in different ways to wipe the slate clean and reload assets, but each of those commands just crashes the program. Thoughts? Suggestions? I'm using QB64 Version 2.0.2 because it runs well on an older Mac I use for coding.

Thanks very much,
Befuddled Ted
Reply
#2
Code? At least for subroutine changing the main loop progress, is it a Gosub or real Sub?

I bet you are using a Gosub and it is messing with main loop variables.
b = b + ...
Reply
#3
This is described too generally. What does the subroutine do? Doesn't it stay running after you leave it? Does it change the variables somehow? Is it a SUB? If so, do you know that the parameters in parentheses (function arguments) change and return changed if SUB changes them? Are you creating virtual screens there and not freeing memory? Or do you work with fonts? Or with an eight-bit and a 32-bit screen? There are too many questions, I can try to advise you, but you need to be more specific.


Reply
#4
I don't know how you code. But if you put subroutines at the end please put a lonely "END" or "SYSTEM" statement to define the end of the main program!

If you use $CONSOLE:ONLY then SYSTEM should do it if you don't want the "Press enter to continue" prompt. Otherwise use END.

Trying to use CLEAR just causes trouble anyhow. That statement should be deprecated and made unavailable for anything.

If you put subroutines mingling with other parts of the main program code then I don't know what to tell you. There are no more excuses for spaghetti code much later than the 1980's.
Reply
#5
Hi Naked - This happens to me a lot. One thing that I picked up on this site (sorry I'm not sure who to give the credit to) was positioning some code inside a loop when it should have been outside the loop. I've also, and one would wonder how I did this, but I accidentally had a recursive call coded. And don't get me stated on division by zero. If you do find the cause, I'd love to hear how you resolved.
Reply
#6
Thanks for the quick responses. I'm using real SUBs not GOSUBs. The subroutine in question creates a moving star field at warp, so there's a lot going on, but the sub has no parameters. It uses 3 large shared arrays of star TYPEs (x,y,z,vector,color) with about 7000 total array elements in play. The sub terminates when the user goes back to the beginning. I have a SYSTEM statement at the end of my main loop. There are a lot of flags to track events, but it all runs fine till after that warp sub. I was inspired by Terry's tutorial, so I've worked hard to do everything the right way and avoid spaghetti coding. I do load fonts, but learned to use ones that don't bog everything down too much with onscreen displaying and moving. I'm not using any virtual screens. I am at a high resolution of 1600 x 900, but again it works fine till after the warp sub. Thnx
Reply
#7
Without seeing the code itself, my initial guess would be probable corruption via a passed parameter.

Let's say we have some simple code like this:

Code: (Select All)
delay = 10 'we start with a limit of 10 loops per second as a manual/visable pause

Do
    For pause = 1 To delay 'just a pause for 1 second
        _Limit 10 'we'll run this loop 10 times per second, which is how we get a 1 second pause.
    Next
    k = _KeyHit
    Select Case k
        Case 32 'call the sub and watch what happens
            SlowDown delay
        Case 27
            System
    End Select

    Print count, "We had to run the pause loop "; delay; "times, which took "; delay / 10; "seconds."
    count = count + 1

Loop


Sub SlowDown (l)
    l = l * 2
End Sub


Compile and run the above.  You'll see that we start out printing text to the screen every second.  Hit the spacebar however, and trigger our SUB, and we double the delay in printing.   Our SUB is passing values back and forth via the parameters, and that's changing how the main program works afterwards,

IF this corruption via parameter is your issue, the simple solution is to pass a value and then assign it to a different variable inside the sub afterwards, preserving the original completely.

Code: (Select All)
Sub SlowDown (templ)
    l = templ 'assign the passed value to a different variable so its value won't change when leaving the sub or function.
    l = l * 2
End Sub
Reply
#8
(04-21-2023, 08:08 PM)NakedApe Wrote: ...the sub has no parameters. 

You posted while I was typing a response, so it seems my guess was wrong.  Tongue

Without seeing the actual code in question, I don't think anyone is going to be of much help in finding/fixing the issue for you.  Can you share the program, or at least the problem SUB, with us for reference?
Reply
#9
Yeah, real sub but no parameters, OK

So look at what is being shared between main and sub, All or nearly all just about like a Gosub (I bet), or none which would make the bogged down issue really curious for sure.

More: The word Restart is in the title. Maybe you have start code in the real sub that should be removed and done once at the beginning separate from the Sub code.

BTW is the Sub basically the entire program? Where is the main loop? In the Sub or the main calling the SUB.
b = b + ...
Reply
#10
If the SUB-program is the only one being called by the main program, why declare large arrays globally? If it's not needed by main module-level code, then could declare such arrays with STATIC inside the SUB. However, then you would have to initialize it the first time the SUB is called, or when the user of the program "goes back to the beginning".

Otherwise if it's a few variables to share between main program and SUB, and only the large arrays declared globally then everything has been already said here.

If there's only one SUB which involves changing values from a large array, you have to be very careful about those changes. The indexes (subscripts) of the arrays might be going out of bounds. I forgot how to get QB64 to compile with "debug" information enabled so the program returns a runtime error at a subscript less than LBOUND() and greater than UBOUND().

It's easy to be confused by a statement such as LOCATE when the user wants "array(x,y)" and LOCATE terminally insists in "y, x" or "row, column". Then it would be easy to track an out-of-range error when there are way more columns across the screen than rows.
Reply




Users browsing this thread: 9 Guest(s)