ID:154097
Jun 10 2002, 6:03 pm
|
|
Ok, so it's not really an art. I just needed a corny title to get you in here. :P Either way, what are the biggest ouchs in coding effciency?
|
Jun 10 2002, 6:07 pm
|
|
Inability to find the piece of code you're looking for in the middle of 2,000 lines of text.
|
Rewriting the same proc over and over when you could simply be running it through the same one multiple times.
<code>mob/verb/buy(mob/M) if(!M.shopowner) return var/list/shop = list() for(var/obj/O in M.contents) shop["[O.name] - [O.price]"] = O var/selection = input("Buy what?") in shop+list("Nothing...") if(!selection) src << "Come again!" return var/obj/item = shop[selection] if(src.money < item.price) src << "You don't have enough money." return else if(!item.Move(src)) item.loc = src.loc src << "You purchase [item]."</code> That has nothing to do with what I just said, but it turned out nice so I left it in. Not sure if it works right though. |
Use of anything that requires 100% attention of the CPU, such as sleep() procs.
Use of loops in an online game. Non-use of object-oriented approaches ( Seriously, OO really saves a lot of processing power ). |
In response to ShadowWolf
|
|
OO saves a lot of brainpower, too! In my humble opinion, it's far better to spend the time making an accessable OO sysem then to write the same sort of thing over and over again or to rewrite a proc for each instance of something!
-LoW |
In response to ShadowWolf
|
|
Why are loops bad in an online game?
Anyway, plan ahead to reduce redundancy. Anticipating future needs is a must. In one of my more recent projects I basically started over because I thought of a better way of doing it once certain difficulties arose. Planning ahead would have saved me a lot of trouble. |
In response to Lord of Water
|
|
What is OO?
|
In response to Sariat
|
|
I think it stands for Object Oriented.
|
In response to ShadowWolf
|
|
ShadowWolf wrote:
Use of anything that requires 100% attention of the CPU, such as sleep() procs. sleep() does not take up 100% of the CPU. It just lets the current proc wait for a certain amount of time and lets other procs get a chance to run if there are any. Since it isn't doing anything its not what is causeing the CPU usage. Use of loops in an online game. Loops are slow but the alternatives are usually slower. To make a game more effecient you should make sure if the loop is long that what's inside should be well optimized though. Non-use of object-oriented approaches ( Seriously, OO really saves a lot of processing power ). Object-oriented programming is only a certain style of programming. When it is compiled it ends up being procedural. So Object-oriented programming is more effecient for programming in but in the end it will be slower. |
Polatrite wrote:
Ok, so it's not really an art. I just needed a corny title to get you in here. :P Either way, what are the biggest ouchs in coding effciency? Well for the most part the more code you have to execute the slower your game goes. So you want to avoid things that are uneccesary. Here is an example. Say you have monster AI where you want it to chase a player once it see it. The first obvious solution probably goes as such. On mob Creation while not dead check for players if one is found chase and attack the player wait for a short while (Note: For those that don't know what psuedocode is don't bother compiling this :) ) The big problem with this is that the more monsters you have the more times you're running this. If you have a large world this will be a big CPU hog. With this method you'll have lots of monster all over your world searching for player in thier view despite there may only be one player on the other side of the world which is kinda dumb. Here is a better solution to the problem. On Player Move for each monster in view tell monster that a player moved in thier view On Player Sighted chase and attack the player With this method you could have millions of monsters and not slow down the game since none of the monster will do a thing unless a player moves near them. Another big CPU sucker is recovery. Here is a slow solution I see often. On mob creation spawn Regenerate Regenerate Restore health to creature wait a little while spawn Regenerate While this doesn't look like it'd be slow even in large amounts because there is overhead involved when calling a function so it's best to condense a lot of function calls in to one function call. Here's the better solution On world creation spawn RegenerateAll RegenerateAll for each mob in world heal mob some wait a little spawn RegenerateAll Actually it's best to include this with something called a Tick function. A Tick function is something started at world creation and then spawns itself at a regular interval. This is pretty much the heartbeat of the world and if you need something to be run at a certain time you can call it from here. And you do maintanence stuff like the health regenerate or other regeneration here. on world creation spawn Tick Tick Ticks++ Heal all mobs some Do other routine stuff wait a certain amount of time spawn Tick The reason for the Ticks++ is so that you can be able to do stuff at certain intervals of tick. Say you want to call a proc every other time instead of everytime, then you could do something like this. Tick the other Tick junk if(Ticks % 2) SomeProc wait spawn Tick If you want every third proc you just replace the two with a three and so on. Anyway my post is getting kinda large so I'll end it here. I guess I should write I tutorial on this stuff if someone already hasn't since it's good stuff to know :). |
In response to Theodis
|
|
While this doesn't look like it'd be slow even in large amounts because there is overhead involved when calling a function so it's best to condense a lot of function calls in to one function call. Here's the better solution My methodology is similar, but I use an additional consideration -- divvying up the processor time. That is, rather than having sudden spurts of CPU usage every n seconds, it tries to maintain a very low CPU profile perpetually. #define REGENERATEDELAY 10000 var/delay var/list/mobs_in_world = list() var/last_mob_in_world = 1 proc/RegenerateAll() if (!mobs_in_world.len) spawn(REGENERATEDELAY) RegenerateAll return var/time_to_regen time_to_regen = REGENERATEDELAY / mobs_in_world.len var/newindex if(last_mob_in_world >= mobs_in_world.len) newindex = 1 else newindex = last_mob_in_world++ //do regeneration delay = time_to_regen - round(delay) spawn(round(delay)) RegenerateAll() Essentially, this makes every single mob/obj in the world get updated once every REGENERATEDELAY seconds, but none of them are updated at the same time -- it divides up the delay appropriately and ensures that each gets its own timeshare divided up. Of course, the divide operation is costly, logic-wise, so there are some cases in which your much simpler method is far more practical (especially in circumstances where you only intend to handle in the vicinity of a couple dozen objects). This is definitely not an OOP-based approach, but it's more than easy to convert it to be contained rather than global. |
In response to English
|
|
Loops are alright, but irresponsible use of loops is bad.
The big nono is for(filteredvar in world) This has to internally go through every area, turf, obj, mob, and specialized atom in the world and reject everything that doesn't fit the filter. It is far better to keep smaller lists that don't have the extraneous data. for(var/mob/M in players) is much faster than for(var/mob/M in world) You can add things to their appropriate list in their New() proc, and remove them in the Del() proc. var/list/players = list() mob/player New() ..() players += src Del() players -= src ..() Another problem I see when troubleshooting for others is that they like to filter the same list twice or more. That means that internally, BYOND is going through the same list over and over. It would be better to go through the list only once and use a switch() or if() statements to do the appropriate thing. Bad: // goes through the same list twice for(var/mob/M in Turf.contents) // do the mob thing for(var/obj/O in Turf.contents) // do the obj thing Good: // only goes through the loop once for(var/A in Turf.contents) if(ismob(A)) // do the mob thing else if(isobj(A)) // do the obj thing |
The -biggest- area that you can loose efficiency in can be completely eradicated with intellegent design.
Avoid Loops if -possible-, if not possible, make sure that the only things happening in the loop is what -has- to happen, not just what you -think- should happen, and make sure that it only happens the minimum number of times you need it to. Walk through decision trees -very- carefully. A lot of times if you look closely at complex ifthen structures, then you'll find that some decisions dont need to be made at all. Do complex bits of code -once- if at all possibly. Instead of bringing it up every time you think its neccisary, walk yourself through the code and make sure its only called the minimum times needed. And the last one is a biggie ^_~ Dont get too overreaching in your code. If you try to build huge areas of expandibility into the code (while it might seem like a good idea at the time) it general just adds stuff that the system has to deal with, and most of the time that stuff never gets used anyways. The above came from my programming classes at the college, from my experience of course, I dont belive half the crap that the instructor spews at us @.@ *LOL* One point I picked up from -here- tho ^_~ Never be afraid of tossing your entire project and starting from scratch. If you've done it once, chances are you can do it again in 1/5th the time, with twice as much accuraccy and effieciency. I tried this once with a lab exam at the college, and wound up getting one mark from perfect (the mark wrong was that I forgot to set up a document header with my name in it @.@;;;;) Elorien |
In response to Elorien
|
|
One point I picked up from -here- tho ^_~ Never be afraid of tossing your entire project and starting from scratch. If you've done it once, chances are you can do it again in 1/5th the time, with twice as much accuraccy and effieciency. I tried this once with a lab exam at the college, and wound up getting one mark from perfect (the mark wrong was that I forgot to set up a document header with my name in it @.@;;;;) Heh. Whenever I write a test, I *always* put in a header, and I even write a humorous explanatory comment. My favourite one was: "Question 4 - Test of a Test: This code tests the sorting algorithm in the previous question. I do, however, find it quite ironic that on a test I am writing a test to test an algorithm. - Jeremy "Spuzzum" Gibson (2/23/02)" Another one I liked was "Chapter 4 Exercise 3 - Reversing Text: This very simple function takes a simple text string and reverses its order. - Ymerej "Muzzups" Nosbig (3/12/02)" |
In response to English
|
|
English wrote:
I think it stands for Object Oriented. It is usually referred to as OOP, though. (Object Oriented Programming) BYOND is actually the first OOP language I've used, and it seems to be a great foundation for learning it too, as I had troubles with C++. Oh, how I despise procedural languages now. >:) - Malver |
In response to Garthor
|
|
Garthor wrote:
Inability to find the piece of code you're looking for in the middle of 2,000 lines of text. You *do* know what CTRL+F does, don't you? O.O |
In response to ShadowWolf
|
|
Why do you always say loops are bad in an online game? What there good in a Playstation game?
You use loops in almost all games, And the game without loops, are most likely gonna eather be crappy or is gonna make your fingers hurt from typing or clicking. Also, you have to use the sleep proc in alot of cases, unless you plan on making like 5 different procs so you can use the spawn proc instead, when with the sleep proc, you can make it all one proc. |
Scanning a whole map or world does.
Bad: var/H = input("This input is not efficient:","Bad:") as atom in world Good: var/PCmobs = list() for(var/mob/PC/P in world) PCmobs += P var/G = input("This input is efficient:","Good:") in PCmobs But of coarse, sometimes you have to scan all atoms or whatever :P I'm just saying that it lags down the game if you have a big one. |
In response to Kunark
|
|
Kunark wrote:
Why do you always say loops are bad in an online game? What there good in a Playstation game? You most definately don't have to use sleep, atleast not for what your thinking of. Here's a nice alternative mob/var/next_forage_chance=0 Alathon\\ |
In response to Kunark
|
|
But of coarse, sometimes you have to scan all atoms or whatever :P I'm just saying that it lags down the game if you have a big one. Actually, that's not much of an improvement -- internally, BYOND still needs to filter the world.contents list. I presume you meant: "Bad: var/H = input("This input is not efficient:","Bad:") as mob in world" since otherwise the two procs are very different in functionality. (In this case, they're still different in functionality (one only reports PCs, while the other reports all other mobs), but that's moot.) |