Kunark gave me some sweet ideas for intelligent AI for my game on my members blog. I consider myself decent at making code do what I want it to, but most of the time it isn't in the most efficient way and I end up with obsessive lag. So what I'm wandering is are there any tips for writing optimized/optimizing code? Maybe somethings not to do? I'd really appreciate any help because I usually quit my projects because there is too much lag. I'm not talking about a few lines of coding like simple verbs, I mean long procedures, such as the AI system I developing.
-FFG
ID:152763
Nov 1 2005, 12:21 pm (Edited on Nov 1 2005, 12:54 pm)
|
|
In response to Unknown Person
|
|
Yea I was mainly just asking for general rules for things such as if statements and for() loops. Um, what do you mean by indexes?
|
In response to FinalFantasyGamer
|
|
I pretty much meant how to recall elements in a list, and manipulating them (like their associations). What I suggest is to start creating your artificial intelligence, and start questioning stuff which might be slow for you. Generally programming stuff in DM wouldn't be that slow to optimize your programs until you find it is being a pain in the neck. For example, you might need to multiply something by two without accuracy being a problem, you could use a bitwise operator to speed it up a little. It really depends on what you might need to speed up on. As I said, don't worry about speed until you meet some conflicts with them.
~~> Unknown Person |
In response to Unknown Person
|
|
Before you start running into conficts, though, remember that if your code is not flexible, it could mean hours and hours of work. If it IS flexible, it could mean editing one variable in the proc and being done.
The kind of flexibility method I started using in my last 3 games goes like this: have all mobs use the same movement proc (in which you define). Have them all use the same proc to take damage. Have them all use the same proc to calculate damage, etc. in other words, Flexible: mob/proc/Attack(mob/Victim) Not Flexible: mob/proc/Attack(mob/Victim) Okay, now for AI, generally what you need to do is make sure all the guys in the world aren't running at the same time. Of course if you avoid it too much, the AI starts to look unnatural and bad or slow. What I am planning on using in my RPG is a system that will make only a z area of mobs appear when players first go to that area, and then when Players get near the mobs, it will activate the mob's AI. Activation is alright to have the mob sit there until the player is in view, but deactivation has to be done a bit differently or the monsters will be extremely easy to escape from. (Note that I may not use this exact system, it's only my plan to.) For activation, they will activate via the player's movement proc or regeneration proc: mob/proc/MoveMe(turf/T) For deactivation, I will use x y z variables to determine if the player is anywhere near the monster: mob/proc/MoveMe(turf/T) |
In response to Kunark
|
|
One general Tip i would like to give, remember it always really kicked me in the but when i wasnt really good in coding, is that you use for() instead of while()
I don't know why but along the way i learned to do this and many might disagree with me but i tend to bann while(). Basic use of for() var/i Get the idea? Oh and if you do use while() make sure you build in some sort of delay. My experience is that a while() proc without a delay prevents anything else from happening if it has to do alot of things for a "long" while. A simple sleep(1) makes a big difference. Don't use this last thing as a "general tip" though, its ment to be a pointer. Hope it will help a bit! [Fint] |
In response to Fint
|
|
Firstly, that's not an optimisation; that's obfuscation. Secondly, double-yew tee eff mate?
There's no reason not to use while() if it's the right situation. for() loops are right for some situations, and while() loops are right for others. Sure, one can be used in place of the other, but then you're just confusing people who read your code (including yourself in the future, once you've forgotten what the code was supposed to do). I think what you're trying to get at is to make sure that: 1. All loops end. 2. If they don't end, then (A) this should be deliberate and (B) they must have sleep() in them at regular intervals. However, randomly replacing while() loops with for() loops isn't the way to do this. |
In response to Crispy
|
|
Well since english ain't my first language I guess i had a hard time explaning it.
Its not optimalisation indeed, but i don't think the problem of his games being "lagging" has anything to do with optimalisation, more to do with propper use of loops. So i thought explaning the for() proc for him might help and remind him to . . . well to keep in mind #2 on your list to make sure his games don't end up lagging. Crispy wrote: However, randomly replacing while() loops with for() loops isn't the way to do this. Not what i tried to say, but you got the point. Anyways, thanks for kinda clearing things up. |
In response to Fint
|
|
My experience is that a while() proc without a delay prevents anything else from happening if it has to do alot of things for a "long" while. However you have to remember that when you sleep it lets other things happen so references which were once good might have been deleted(or the object they are referenceing to has changed) during the delay. So after you sleep it is best to check any references which could have potentially changed during the wait. |
In response to Fint
|
|
To clear it up for everyone, this is how it goes:
for() is used for going through lists from beginning to end, like this: for(var in list) That is a quicker method for accessing through list elements than the one below, but the one below can be useful in rare situations, particularly when going backwards through a list: var/list/L = list() for(var/i = 10,i > 0,i--) world << L[i] //That would display a list backwards. Now, with this AI, however, we aren't accessing list elements. In this case, here's the general rule: for() is used for ending the loop after a countdown, such as if you'd need to create a certain number of objects, while() is used whenever you only want the loop to end after a condition (which can much more easily be something other than a number, unlike for() loops) has been met. These two can be interchanged with each other, but generally while() loops are easier to use and easier to interchange. while(src&&src.Moving == 1) //this will be much easier and more logical to write than the loop below. sleep(1) for(var/i = 1,i > 0,i++) //infinite loop if(!src||src.Moving == 0) break |
In response to Kunark
|
|
Kunark wrote:
for(var/i = 0,i < 0,i++) //infinite loop Actually, that won't execute at all, because it only executes if i<0; but i is always positive or zero. =) But otherwise, yes. |
In response to Crispy
|
|
Woops, fixed.
|
In response to Kunark
|
|
for(var/i = 1,i > 0,i++) //infinite loop And even simpler infinite loop :) for(;;) [Edit] Actually I think for() also works. |
In response to Theodis
|
|
Theodis wrote:
for(var/i = 1,i > 0,i++) //infinite loop I personally like
#define EVER ;;
for(EVER)
|
In response to Kunark
|
|
for(var/i = 1,i > 0,i++) //infinite loop I wouldn't actually recommend this, simply because it's doing a whole bunch of needless operations. A for loop like this: for(Initialise(), Condition(), Statement()) translates to the following: Initialise() Notice those extra computation steps in there; the Initialise() and the Statement() procs are both being executed. A while loop, on the other hand, such as this: while(Condition()) translates to the following: Start: As you can see, there is no initialisation or additional statement to worry about. Now, if you're not defining the initialisation, condition, or statement for the for() loop, then it's no different than using a while loop (I'm assuming that BYOND doesn't insert do-nothing statements, and optimises the bytecode). But if you are defining them, then it's less efficient than using a while loop. |
~~> Dragon Lord