inventory limit

insidethecircle
22 Oct 2009, 10:59
now i know this has been asked before but for the life of me i can't find it.
how you do express a limit on your inventory?
thanks

Overcat
22 Oct 2009, 11:27
If you're not considering weight and volume:

1. increment a numeric variable every time the player
a. takes something
b. is given something
2. decrement that same variable any time the player
a. drop something
b. has something taken from him/her

Before allowing the player to take something (or have something given to them), make sure that the numeric variable you're tracking would not exceed some maximum value.

Wonderjudge
22 Oct 2009, 13:42
Overcat's way is better than mine. I did a procedure checkinv. Every time the player types take <object> it runs
it sets a numeric variable to 0 then runs a check for every object in the game. if the player has the object it increments.
At the end if the variable is = (whatever limit) then you wont take it.
The only reason I did it this way was because I already had the game done and threw this in as an afterthought and it was easier than going back through all my code to see when a player lost or gained something.
Wonderjudge.

Freak
22 Oct 2009, 22:48
I disagree. Wonderjudge's method is better. Overcat's method violates "Don't repeat yourself". It's easy for things to get out of sync. (Every time you move something, you have to check whether it's being held. If you forget, the player will lose holding capacity for no reason.)

One other thing. Be careful about making held things concealed / invisible. This can also have the effect of taking away carrying capacity.

Wonderjudge
22 Oct 2009, 22:54
My method however created a little lag as I had so many ojects in the game. However I have just discovered a better way (alas it always happens after the work is done)
Items in inventory are actually stored in a hidden room that the game creates called "inventory".
So if you follow the same procedure but instead of running a script for each object in the game you do it for each object in the room "inventory". And you can save yourself a braincramp if you put in if the object is available increment variable.
Wonderjudge.

Freak
23 Oct 2009, 02:03
Did you actually test that second method for speed? I thought it would wind up doing the same thing.

(And how many objects did you have that looping over all of them produced a noticeable slowdown?)

Overcat
23 Oct 2009, 14:07
Getting out of sync may indeed by an issue down the road. Good point. Depends how you structure it, and if you expect your game to increase in complexity (a good bet?). It is easy to create a checkpoint procedure that fires whenever the player gains or loses something. You'd use this procedure instead of the built-in 'move', 'lose', or 'gain' script commands:

do <move(#object#; #room#)>

as opposed to

move <#object#; #room#>

It's not too lengthy, you only have to write it once (the procedure), and no looping is required in the logic. (Unfortunately, lag due to looping has been an issue for me in my Quest endeavors. Hence I look for ways to minimize it from the get-go.) Granted, if you only allow three-ish items in your inventory, it's not that big a deal to loop through them.

(And how many objects did you have that looping over all of them produced a noticeable slowdown?)



Anywhere from 5-50, depending on what you do with each object, I'll bet! It seems to me that calling certain built-in functions (such as $numberparameters$) bogs things right down. (This is an educated guess - still testing that.) I've also noticed tangible differences in performance between different machines, both Pentium 4.

Wonderjudge
23 Oct 2009, 14:51
Second method is way better. No lagg. In shipwrecked I allow you to carry 13 items. So since there is only ever 13 items in the room inventory it only needs to do the loop 13 times. No lagg. When I made shipwrecked I have it testing every item in the game which is like 100+. So there is a little lagg when you pick something up.
Wonderjudge.

Freak
23 Oct 2009, 17:11
A loop over all the objects in the game caused lag on a high-end computer with just a hundred objects? That sucks.

Overcat
23 Oct 2009, 18:48

A loop over all the objects in the game caused lag on a high-end computer with just a hundred objects? That sucks.



A discovery, to be sure, that took the bright out of my eye and the bushy from my tail. I found this problem whilst working on a large, single-player fantasy RPG. I assumed the lag issue would scale down.

Bad assumption.

After your remark about how this sucks, I decided to do a little testing. I threw together a small ASL file with 100 objects (generated on startup), and then forced the game to iterate over all those objects after every player turn. To my utter surprise, there was zero delay (using one of the aforementioned Pentium 4's). But I knew I was getting lag on other projects (including but not limited to the RPG). So what was going on?

Well, after a little messin' around, I decided to include a large library file (the full version of my list library endeavour). It's 191K, and about 6000+ lines of ASL (with generous white space). I didn't call any of the routines from this library file, mind you, just included it.

Lo' and behold, lag emerges. So I copied the library file two more times, renamed the copies, and then included them also. The lag tripled.

Does the total size of your ASL, regardless of whether or not it is being used, affect the speed of your game? Here is the ASL file I tested with:

'!include <type_list_full.lib>

define options
debug on
panes disabled
end define

define game <LoopLag>

asl-version <410>
gametype singleplayer
start <Home>
game version <1.0>
game author <J. Dobson>
game copyright <© 2009 JDG Inc.>

background <black>
default fontname <arial>
default fontsize <10>
foreground <White>

startscript {

set numeric <noObjects; 100>
clear
msg <Generating %noObjects% objects in %noObjects% different rooms...|xn>
pause <1>

set numeric <i; 0>
set numeric <n; 0>

for <i; 1; %noObjects%> {

create room <nowhere_%i%>
clone <someitem; someitem_%i%; nowhere_%i%>

}

msg <done!>
}

afterturn {

set <i; 0>
set string <msg; Tagged objects: >

for each object in game {

inc <i>
do <SomeProcedure(#quest.thing#)>
}

msg <Turn complete. Iterated over %i% objects: |n>
msg <#msg#>
}

end define

define room <Home>

alias <Home>
look <You're home.>

end define

define room <nowhere>

alias <Nowhere>
look <You really shouldn't be here.>

define item <someitem>

look <Some item.>

end define

end define

define procedure <SomeProcedure>

if ($numberparameters$ <> 1) then {

debug <Invalid number of parameters>
}
else {

set string <p1; $parameter(1)$>

set <n; $rand(1; 100)$>
if (%n% < 11) then property <#p1#; tagged> else property <#p1#; not tagged>

if property <#p1#; tagged> then set <msg; #msg# #p1#>
}

end define


I don't know whether total size affects speed, but it seems as though the more procedures one has defined, the longer it takes to call up any given procedure. I assume this is because, however the procedures are stored in Quest, the lookup speed for them is dismal. (Object and room definitions don't seem to have this problem.)

If I remove the single quote in front of the first line ('!include <type_list_full.lib), noticeable lag is produced. If I keep it there, the lag disappears. On the other hand, if I both remove the single quote, and move the functionality contained in SomeProcedure to execute in-line with the afterturn script, the lag is almost nil. (But not quite.)

I had always assumed the built-in script commands were causing the problem, but now it appears it's how routines are stored internally in Quest. A fix may be to store procedures/functions in the same manner that objects and rooms are stored. Any thoughts?

Wonderjudge
23 Oct 2009, 18:59
That is strange... Usually procedures are well liked by all because of they cut back on the amount of code you use and make it easier to detect a problem. Alot of procedures is usually the makings of a good programmer. I am usually not one of those. I have been accused of being spaghetti ish alot. I'm working on it though.
Wonderjudge.

Freak
23 Oct 2009, 20:43
That explains it. Quest handles braces by creating an internal procedure. If procedure calls are slow in bad situations, that explains why you had a problem.

Alex
24 Oct 2009, 10:57
I've had a look at this and the code for finding procedures was rather inefficient. I've now fixed this for Quest 4.1.2, and it's nice and speedy even with 100,000 procedures.

Overcat
24 Oct 2009, 11:42

I've now fixed this for Quest 4.1.2, and it's nice and speedy even with 100,000 procedures.



Great news, Alex! This means some of my earlier (discarded) efforts may just work their way out of the graveyard. (I assume the fix for the procedures affects functions equally. Am I wrong?) Looks like Adventure Co. is back in business! And the full version of the list library, which I knew to be too laggy, should now be release-able.

As a matter of curiousity, did any other of the ASL elements utilize the same/similar internal search routines as the procedures? So, for instance, if I have 100,000 types, will this cause lag as well? What about 100,000 actions within an object? 100,000 properties?

Alex
24 Oct 2009, 12:42
Functions, selection and text blocks should also be quicker, though procedures was by far the most significant, especially with big "for each" blocks as the same code would be called over and over again.

insidethecircle
26 Oct 2009, 12:20
whoah!
i came back from a nice wekend to see a virtual snowstorm of replies
thanks guys