mob/var
hunger = 100
mob/proc/HungerDecrease()
if(src.hunger == 0)
src.stat1 -= 10
src.stat2 -= 10
src.statRes -= 20
src.statRest -= 20
sleep(3000)
src.hp -= 50
src << "You should eat something really fast!"
src.HungerDecrease()
else if(src.hunger >= 30 && src.hunger <= 60)
sleep(6000)
src.hunger--
src << "You are starting to starve.."
src.HungerDecrease()
Problem description: Well I haven't test that code yet, I have been studying DM language for a month, so to pratice I decided to clean and tweak the code of Rise of Heroes (No ideas to release it, my goal is to make an original game).
I have some questions, do I really need to put
src.HungerDecrease() to run the code again ?
If I set a variable to 1, and if I call it like
if(varExample)
Hope I was clear enough.
Basically, for the compiler to brings changed variable values across from one procedure call to another (even the same procedure calling itself, as in your example), the variable needs to belong to an object or be global. In your example, hunger belongs to src (hence src.hunger to read the variable), and so yes, changes to src.hunger will be seen by the compiler after the procedure finishes.
A procedure calling itself, in the manner you have shown, is a known as recursion, and the procedure could be called a recursive procedure. Recursion has quite a few nice properties, particularly in terms of re-using code and sometimes solving a problem in a very straight-forward way. However it does have a few drawbacks.
The main drawback people find is that each time the procedure calls itself, it has to (temporarily) grab a bit of memory to record information about the procedure call it is making (local variables, who is src, who is usr etc). If the number of times your procedure calls itself is not very large, this possibly isn't a problem for you.
In your example though, the procedure calls itself on every possible route through the code. This is called infinite recursion, as the procedure can never complete, it will just keep calling itself forever. There's an issue with this. Each time the procedure calls itself, it allocates a bit of memory. That memory is freed when the procedure finishes. In your example, the procedure never finishes, and the memory is never freed. Worse still, it keeps allocating more memory (as it keeps calling itself) which cannot be freed either.
Eventually, BYOND would run out of free memory to allocate and crash. To protect itself from this, BYOND will throw a runtime error once it's reached X many deep calls. So although it may take some time, it is guaranteed that your example will throw a runtime exception, and the "hunger system" will stop working for a particular user.
A simple fix for this (although maybe not the best idea in the long term, as far as design goes) would be to do something like this:
And spawn() the self-call off. The spawn()'d code will execute after the current procedure is finished, and so that little bit of memory is freed. The code still has the same behaviour to the user and use of hunger as seen before, but now that infinite recursion problem is 'fixed', as spawn() makes the self-call happen after the current call has finished.
I hope that offers some explanation, and makes sense. If it does, please +1 my post, so that other people in the future can see it was helpful. If not, please don't hesitate to ask more questions about this bit of code. Thanks.