ID:153204
 
Well, I brought this subject up cause infinite loops can get on my nerves. If you have an infinite loop, you're Seeker/Daemon will crash/freeze sometime or another. Mine usually stays up for 3 hours tops without reboot or anything. I just want to know how to make alternatives ways of coding without using infinite loops like HP bar, walking NPC's, etc.. If anyone knows some way, please reply. Below are the 3 main infinite loops I've encountered.

1) Auto reboot -spawn on world.New() every xxx seconds/minutes
2) NPC movement, while still alive in world, move random
3) HP Bar - updates every second with mob/Stat()
ZDarkGoku wrote:
1) Auto reboot -spawn on world.New() every xxx seconds/minutes

Just use spawn() on world/new and reboot it. No infinite loop needed.
2) NPC movement, while still alive in world, move random

In my opinion, having them move when nothing is on the screen is pointless. If you don't see it, who cares right? Just call their AI when they are attacked, or a mob comes in view.
3) HP Bar - updates every second with mob/Stat()

Update the bars everytime HP is changed, no infinite loop required.
Well if something is locking up you're probably just doing something wrong.

1) Auto reboot -spawn on world.New() every xxx seconds/minutes

Well anything automatic needs to be triggered by something. If it's time related and periodic then you need it to be part of some infinite loop.

2) NPC movement, while still alive in world, move random
Again this either needs to be triggered by an event or a loop.

3) HP Bar - updates every second with mob/Stat()
This doesn't need to be in a loop since you should be able to control when the HP changes and thus know when you need to update the bar. Just have something like

mob/poc/ChangeHP(newval)
HP = newval
UpdateHPBar()

then rather than directly changing the mobs HP call the ChangeHP() proc and it'll update the bar everytime the mobs HP changes rather than wasting time in a loop constantly checking the health.

As far as having infinite loops go its best to have one event loop that spawns timed events rather than a bunch of small loops. Here's an example of how to set one up

//A tick will be 1 second
#define TICK_LEN 10
//Second duration assuming world.tick_lag is 1
#define SECOND 10/TICK_LEN
var/ticks = 0

world/New()
//Other world init stuff
spawn(0)
Tick()

proc/Tick()
ticks++
if(!(ticks % round(SECOND)))
;//Do events that occur every second
if(!(ticks % (SECOND * 60))
;//Do events that occur every minute here
if(!(ticks % (SECOND * 3600))
;//Do events that occur every hour here
spawn(TICK_LEN)
Tick()


Then in various areas I commented you put in the events that happen at various time frequencies like respawning monsters or regenerating mob health.
In response to Theodis
These days I prefer to use while() and sleep() rather than spawn()ing off a new copy of the proc all the time, but that's just me.
In response to Crispy
These days I prefer to use while() and sleep() rather than spawn()ing off a new copy of the proc all the time, but that's just me.

Doing an infinite while loop with a sleep() doesn't work as well for profiling though and your core event loop is definitely something you want to be able to profile and optimize. The overhead of a proc call isn't all that expensive especially considering the size of the event loop generally makes it neglegable.
In response to Theodis
True. But the profiler is just broken in that respect. =P
In response to Theodis
For the NPC/Enemy Movement, I had a var/activated on the enemy and when I attack the enemy, the activate var becomes 1 and calls the enemy's activation proc. In the activation proc, it wanders while it is activated. in the wander proc, it steps to a player with <font color=blue>for</font>(<font color=blue>var</font>/mob/PC/P <font color=blue>in</font> oview(13,src)). but if the player (mob/PC/P) is not in the oview, the enemy should be unactivated. I think that this is a decent way for monsters since it only acts upon activation and when a player is in it's view. The only problem I have concerning this way is that I don't know how to make it unactivate when there is noone around. I tried <font color=blue>if</font>(!<font color=blue>var</font>/PC/P <font color=blue>in</font> oview(13,src)) and that doesn't work.
Don't forget Deadron has an excellent Event Loop library at http://developer.byond.com/hub/Deadron/EventLoop .

This can easily be used for NPC movement as well as a host of other things.

Don't forget Stat() procs if you want to update your HP bar, but manually updating it whenever you modify HP is preferable.

I don't think most games need an "autoreboot" at all. If you want to continually have monsters or something appear, use spawners instead. The only way I think an "autoreboot" is really useful is when it is attached to the servers cron function to make sure you file doesn't stay down. I used such a feature in a Text MUD I ran for a while. That combined with a copyover (makes sure that most values modified at runtime carry to the next reboot) made for a MUD that never seemed to go down to the players. Even better, once my partner and I cleaned up the dirty stock code, it never did crash!

In response to Jmurph
Jmurph wrote:
Even better, once my partner and I cleaned up the dirty stock code, it never did crash!

I seem to have the opposite effect on most MUDs I come near. One I occasionally code on starts crashing as soon as I get near it or the shell :/

Alafobia?
In response to Alathon
Heh, nah, most stock MUD code is rife with problems such as bad memory handling, bad string handling, etc. And most MUD owners don't know enough to correct them. As new features are added, it usually compounds the problem, especially given the level of quality of many neophyte MUD programmers.

Probably has nothing to do with you, though, so much as existing dirty code.
In response to Jmurph
Jmurph wrote:
Heh, nah, most stock MUD code is rife with problems such as bad memory handling, bad string handling, etc. And most MUD owners don't know enough to correct them. As new features are added, it usually compounds the problem, especially given the level of quality of many neophyte MUD programmers.

Probably has nothing to do with you, though, so much as existing dirty code.

True. We fixed a lot more crash bugs than we caused in the current code. I suppose my reluctance to work on it further has to do with BYOND and knowing that my ability to use DM is far beyond that of C/C++, and that if I spend enough time I can drum up a much nicer codebase with DM.
In response to Alathon
Very, very true. DM is much cleaner than 99% of the C stuff out there, and optimized for applications such as MUDs! WHat more could you ask?
In response to Crispy
True. But the profiler is just broken in that respect. =P

Heh well think about it. How do you tell how long a proc takes to run if it doesn't end :)?
In response to Theodis
Simple. You just don't count the time that it sleep()s for, which is entirely possible to do given that you're running the program yourself, from compiled bytecode. =P

Of course, the proc would only show up as being run once, but it would still give a much better indication of how much CPU time the proc is taking up.
In response to Crispy
The point is that the only possible information you could get is how long the proc has been running(minus time slept) which is next to useless for optimization. You need to be able to tell the average time of an iteration to get any kind of useful information.