Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Inconsistency in use of language Tier1

Author
Message
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 29th Jul 2012 05:33
I wrote function in about 5 minutes to move my objects. I then WASTED 30 minutes trying to debug it because it crashed my code.

This works ... ( but I don't want to put all my code in one function - I want to be able to separate it)


This doesn't - seriously, what's the difference??? If you can tell by my restrained tone I am really getting frustrated with this 'young' product.
Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 29th Jul 2012 05:58
Have you tried doing it like this?


Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 29th Jul 2012 08:44 Edited at: 30th Jul 2012 14:30
If I do that it still doesn't work - and that shouldn't make any difference because the THEN command should work. However I have found that if I omit these lines with the comment double slashes it works.

If I change the gPlayerBasePosition to a constant like 90 it still crashes.

It's just so random, it seems like memory overruns to me.


EDIT: I managed to fix this by moving the processUpKeep() call to be above the processEnemy() call like this... what ever happens in process processEnemy causes i to go out of range.
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 29th Jul 2012 11:10
Try changing i in the function to a different variable name. I'm not saying your code is wrong, but this may fix it for you if the bug is related to the variable name.

Digital Awakening
AGK Developer
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Sweden
Posted: 29th Jul 2012 11:18
Try adding brackets () to your first function. I think you should have brackets even when the function doesn't require any values. At least that's how I code.

Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 29th Jul 2012 13:58
Neither of those changes made any difference to the function if the IF condition was put it. If I commented out the IF condition it worked fine - but it worked fined before by omitting the IF condition - very unusual behaviour... buggy

Kevin Picone
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 29th Jul 2012 14:46 Edited at: 29th Jul 2012 14:48
it does sound a bit odd, providing gPlayerBasePosition been declared global and initialized previously.

Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 29th Jul 2012 15:04
Yes it has, but I just change the line to this it still crashes.

FakeBlood
21
Years of Service
User Offline
Joined: 18th Nov 2002
Location: Alabama, United States
Posted: 29th Jul 2012 16:32
Shouldnt the next be "next i" instead of just next?
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 29th Jul 2012 16:40 Edited at: 29th Jul 2012 16:41
Ahh... I was really hoping that was it... but alas changing it to next i did not fix the crash.
FakeBlood
21
Years of Service
User Offline
Joined: 18th Nov 2002
Location: Alabama, United States
Posted: 29th Jul 2012 16:41
arrghh! lol
FakeBlood
21
Years of Service
User Offline
Joined: 18th Nov 2002
Location: Alabama, United States
Posted: 29th Jul 2012 17:13 Edited at: 29th Jul 2012 17:15
I did a simple test to make sure it's not an issue of AppGameKit calling a function w/ parameters inside another function..but this simple test works

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 30th Jul 2012 01:03
An old quirk from DBP... Copy and paste your code into notepad to remove any hidden, obscure characters. Then paste it back into AGK.

I had to do this a few times with DBP.

Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 30th Jul 2012 10:44 Edited at: 30th Jul 2012 14:12
@BatVink - I tried cleaning the text using that method but it didn't change anything.

I wonder if it's something to do with calling one function from one file in another file? I reckon it's got something to do with my use of global functions and perhaps I've not created them correctly - so it's just creating random errors.

I'm going to pull it apart and transplant the code from scratch to see where I went wrong.
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 30th Jul 2012 11:07
I had a similar issue a while ago using "i" as a variable name for a "for" loop and in a function called as part of that loop, but only when I used the same variable name (i) within the function. Try changing your second function like this:

It might just work. I have a feeling it's some kind of compiler bug where it is lining the code up and not checking for variable names that match or something...


this.mess = abs(sin(times#))
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 30th Jul 2012 14:09
Here's another inconsistency

This code locks the game up so I just see black with the two print commands before the next loop


But if I do it this way it works fine... what the???? That's not me, that's the compiler screwing up I reckon.
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 30th Jul 2012 14:11 Edited at: 30th Jul 2012 14:14
And another one. Unless I put this print command at the top of this function it never returns from this function. How is print affecting the code like this?
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 30th Jul 2012 14:26 Edited at: 30th Jul 2012 14:32
Here's another one - If I use the first code snippet - the first enemy appears and moves, but none do after that.

If I change it to this code - which is the opposite way to stop them, they all appear correctly one after the other and move along. What's the difference? Why does the top code cause this glitch?
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 30th Jul 2012 16:19
Can you please post the whole code (if not too big). I get the impression there are things happening that we aren't seeing that would help us figure out what the problem is.

There is no issue with calling functions across files, I do it constantly.

I suspect the issue is more in the something about the loop calling the function and not in the function itself.

Cheers,
Ancient Lady
AGK Community Tester
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 30th Jul 2012 19:16
Seems to me there is something far more fundamental going on here... Post something we can compile and run and you might find the cause yourself, otherwise we can at least tell you if we're getting the same result.

My crystal ball is a bit foggy...


this.mess = abs(sin(times#))
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 30th Jul 2012 19:26
I've emailed a build to Ancient Lady.
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 30th Jul 2012 21:27
I got the project.

The first major issue is that in your main.agc file, you are using GoSub with all the function names.

And a quick search shows that you are using gosub in a bunch of places when you are trying to execute functions.

GoSub and functions do NOT work together.

Change all cases where you use gosub to call something declared as a function to just the function name and a parenthesis set. Eg. "initHUD()" instead of "gosub initHUD".

Fix all those gosubs and then see how it works. I found gosub calls in the main.agc and input.agc.

I'm actually surprised it worked at all.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 30th Jul 2012 22:57
I think this illustrates how important it is to include an entire sequence when reporting a potential problem!

-- Jim
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 31st Jul 2012 03:10
So when are gosub's used then? Why even have them if function calls are used?
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 31st Jul 2012 03:15
Did all the changes - weird behaviour gone. Sweet thanks guys for your help. Thanks for looking at the project Ancient Lady
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 31st Jul 2012 09:13
Quote: "So when are gosub's used then? Why even have them if function calls are used?"


Gosub was removed from Visual Basic when the .NET version came out. It's much more primitive than a function call because it's really a GOTO followed by another GOTO on the RETURN statement. Most crucially, a subroutine cannot have local variables (the scope is traditionally always global) and this can cause a lot of problems.

I don't know if it's true of AppGameKit Basic, but in many varieties a missing RETURN statement will cause the code to "drop through" the bottom and carry on from the next line!

So, you're right. There's a good argument for deprecating it and removing it from the language.

-- Jim
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 31st Jul 2012 11:08
gosubs are useful when you don't want to pass more than a few variables without creating monster function calls though. They are fine and very useful in some circumstances as long as you know how they work.

I actually had the same problem a while ago but didn't make the connection. My "clearLevel()" function was originally a gosub and I forgot to change the gosub calls. TGC are aware of this bug (the compiler should detect when a function is called as a sub-routine and fire an error message). It may even be fixed for the next version I'm not sure...


this.mess = abs(sin(times#))
Hodgey
14
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 31st Jul 2012 11:42
Quote: "It may even be fixed for the next version I'm not sure..."

http://code.google.com/p/agk/issues/detail?id=311&can=1&q=function

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 31st Jul 2012 11:44
There ya go!

+1


this.mess = abs(sin(times#))
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 31st Jul 2012 12:23
It certainly explains the weirdness with variables. I'm glad everyone came to my rescue - I was so close to chucking it in the bin. Onwards and upwards. Thanks for everyone's input

I just didn't want to put the game up for everyone to look at because it's a bit of secret at the moment.
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 31st Jul 2012 16:46
Psycho Psam, I promise not to reveal anything I saw. The little bit of play that did work before it died was interesting.

Good luck with it!

Happy Programming!

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 31st Jul 2012 22:39
Quote: "gosubs are useful when you don't want to pass more than a few variables without creating monster function calls though."


Bax - I don't understand that at all. What has a deprecated coding approach have to do with "monster function calls"?

-- Jim
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 31st Jul 2012 22:48
JimHawkins, in Tier 1, there is a limit of 9 calling parameters allowed (or it might be 10). If you pass more than the limit, you get randomish values.

It took me a couple of hours to find out that that was causing my app to behave badly.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Aug 2012 00:07
Thanks - but I don't see how GOSUB helps that!

I'm being thick tonight. Six hours driving to a funeral and back through driving rain doesn't help.

If I need to pass more than five or six parameters I will usually pass a struct because, as Niklaus Wirth observed a long time ago, more than that becomes incomprehensible and dangerous.

-- Jim
Psycho Psam
16
Years of Service
User Offline
Joined: 3rd Apr 2008
Location: Western Australia
Posted: 1st Aug 2012 04:47
@Ancient Lady, as soon as I have an alpha build I'll invite people to sign up for the test group and newsletter to try it out.
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 1st Aug 2012 11:32
Jim, I'm not saying there aren't better ways to pass data between different parts of your code. Using UDT's in T1 would be a far better way to code (and how I'm trying to force myself to code these days!). What I'm saying is that it's possible when using gosubs to separate a section of code that you might use a number of times without having to pass anything into or out of it manually and without creating unnecessary UDT's.

A small example might be if you were using a section of code multiple times in your code and decided to re-factor. You could create a function and a UDT to store the data and copy all the required variables into it (doubling the memory used for each variable, small but unnecessary) each time you wanted to run the function or you could just call a gosub and not have to change anything, just copy the code that is repeated into a subroutine swap the repeated code for the gosub call.

I know it's not ideal but it serves a purpose and makes sense to a lot of beginner programmers. I often use it myself, and most likely will for some time.

It's better to have tools like this that are easy to understand in a "basic" language. People often learn in basic and move on to better ways of programming later. I'm trying.


this.mess = abs(sin(times#))
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Aug 2012 12:21
Fair enough! Although it does rely on having lots of globals, since as far as I can see from the language definition help file, you can't pass parameters to subroutines. Globals have long been regarded as evil in programming terms, but unfortunately AppGameKit Basic makes them impossible to avoid, hence drawing new programmers into dangerous practices from day one.

If AppGameKit Basic had been designed in a more modern way as an Object Orientated language like Visual Basic, a lot of these problems would have gone away. For example, an instance of a UDT could be created: "New MyUDT" and thrown away after use. That's a more memory-efficient way of doing things than having to create static variables that live for ever.

Hey - it's all good fun. Err - maybe no all!

-- Jim
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 1st Aug 2012 12:32
Quote: "Although it does rely on having lots of globals, since as far as I can see from the language definition help file, you can't pass parameters to subroutines."

Not true. You don't need the variables to be globals. Anything in the scope of the code where the gosub is called is fine.

I guess you can see it's not quite as evil as you might have thought? I hope so

Yes it would be nice to be able to create UDT's in functions and throw them away after use!


this.mess = abs(sin(times#))
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Aug 2012 12:38
How do you pass a parameter to a subroutine? How do you get a result from a subroutine?

-- Jim
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 1st Aug 2012 12:40
You don't. You just run a slab of code and it is run as if part of the current scope.

It's a simple way to avoid repetition without creating functions but I'm not sure if that's the only intended use.


this.mess = abs(sin(times#))
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Aug 2012 12:56
So why not use a function????

-- Jim
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 1st Aug 2012 12:58
Quote: "If AppGameKit Basic had been designed in a more modern way as an Object Orientated language like Visual Basic"


It's a nice idea, but I don't think we would have AppGameKit today. From what I see, DBP has been used as the basis for AppGameKit, which makes good sense from a commercial perspective.

Personally I never use Gosubs. I'm a function man through and through. For newcomers to programming I would always recommend functions. But I see no harm in leaving Gosub there for oldbies who prefer it. I think the help files - although not a learning tool -should perhaps provide guidance on virtual-depreciation of older commands.

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 1st Aug 2012 13:03 Edited at: 1st Aug 2012 13:05
Quote: "So why not use a function????"

Again, so you don't have to pass a bunch of variables into a UDT or as globals or as function parameters... using a gosub you don't have to worry about passing anything anywhere.

EDIT: I agree to an extent with what you're saying too Batvink but I still think gosub has its place in AppGameKit T1. It saves a lot of unnecessary juggling occasionally.


this.mess = abs(sin(times#))
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Aug 2012 13:44
Interesting discussion. You don't have to pass a load of parameters to a function. You can - but it's not a requirement. Consequently, gosub seems to me to be redundant, and as we have seen in this thread, a source of confusion.

With no parameters at all a gosub can only "import" global scope data by definition. Yes - it can use local variables - but it's a bit of a halfway-house.

Steve - how much DBPro source can actually be imported into AppGameKit? The regime is quite a bit different. Building an OOP Basic version for AppGameKit could well preserve backward compatibility whilst (commercially) being able to say - "Wow! Look what you can do now!"

-- Jim
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 1st Aug 2012 13:55
Quote: "how much DBPro source can actually be imported into AppGameKit?"


Directly - none. The commandset we get is abstracted from the underlying functionality. Pre-AGK, there was an open discussion on the preference for the syntax.

I'm only speculating, but I would imagine that the core commands have reused a lot of DBP code. As a consequence it's likely they've used the same framework to build AGK.

Does AppGameKit Pascal give you the OO-platform you talk of?

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 1st Aug 2012 14:07 Edited at: 1st Aug 2012 14:08
Quote: "You can - but it's not a requirement."

Yes, that's true but when you HAVE to pass a lot of parameters to make the function work a gosub would be easier. That's my whole point.

A gosub cannot only import global variables, you can use other variables that are local to where it is called from...

IE.

EDIT: this will print both values

A simple example but imagine the chunk of code you are turning into a function contains 50 variables that change between each use of the function. You would have to somehow pass each and every none global value into the function. Using a gosub you wouldn't have to even declare it locally in the function, or change your code... the variable would be accessible with its current value.


this.mess = abs(sin(times#))
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 1st Aug 2012 14:13
Quote: "Does AppGameKit Pascal give you the OO-platform you talk of?"


Yes. I didn't want to mention that! Whilst the C++ users are moaning about 1076 templates, the Pascal templates are fine. I think it's better than either Basic or C++ - but until people try it, they won't know.

-- Jim
Impetus73
12
Years of Service
User Offline
Joined: 28th Aug 2011
Location: Volda, Norway
Posted: 2nd Aug 2012 11:26
baxslash, for what it's worth, I understand you I can't understand why JimHawkins don't "get it" though...

I guess you use gosub to streamline your code, by removing repeated segments of the "main" program and still being able to manipulate all local cariables in the main code without having to declare them as globals, or parameters, for a function to get access to them.

You can also use gosubs inside a function, to remove repeated code inside that function.

----------------
AGK programmer
Did Amiga / AMOS programming in the 90's.
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 2nd Aug 2012 11:29
Bingo


this.mess = abs(sin(times#))

Login to post a reply

Server time is: 2024-04-28 18:58:44
Your offset time is: 2024-04-28 18:58:44