ID:2342223
 
(See the best response by IainPeregrine.)
Hello im curently coding a game and the game lag when i walk it got some time that the game lag a bit i check the error log after doing some thing in the game but i got no error. 0 error and warning when i compile the game can you guy help me do you already see something like that and why islt doing that and how to fix it
Thanks you

If you don't know what i mean just say it lmao
Best response
If there are no runtime errors then you've probably got a runaway loop or recursive proc (a proc that somehow causes itself to be called again) that's eating up all your CPU power. I'll show you a basic mistake I've seen a lot:

// Attack whenever the player moves
mob/Move(newLoc)
// First, do the normal movement
var success = ..()
// If we succeeded, attack any enemies in range
if(success)
for(var/atom/nearAtom)
if(ismob(nearAtom))
attack(nearAtom)


The above example is a problem because it'll loop through ALL areas, turfs, objs, and mobs in the entire game every time any mob moves. It's an extreme example, but people do stuff like that all the time by mistake. Another example might be if any time a mob moves it alerts everything in view and then all those mobs in view update their targetting AI. If the targetting AI is complex or buggy, that could lock up the CPU for a moment.

The best way to tell what's locking up the CPU is by using the profiler in Dream Daemon. Start the game, start the profiler, walk around and make things laggy, and then refreshthe profile. It'll show you all the procs and verbs that are getting called, and you can see which procs are being called the most and which are taking the most time.
I got a cpu counter in my game and when i walk and the game lag a bit he dont move he still at 0.
but i will check the profiler in DM
i just check the profiler and this is what i get form walking a bit

Profile results (total time)
Proc Name Self CPU Total CPU Real Time Calls
----------------------------------- --------- --------- --------- ---------
/turf/GroundTurfs/GrassDark/Entered 0.000 0.000 0.000 80
/proc/LevelStat 0.000 0.001 0.001 19
/proc/CheckLevel 0.000 0.000 0.000 2
/mob/proc/UpdateInfo 0.001 0.001 0.001 20
/mob/proc/UpdateHUD 0.000 0.000 0.000 20
/mob/proc/Runup 0.000 0.000 0.000 16
/mob/proc/Run 0.004 0.005 0.005 205
/mob/proc/ActivateAI 0.002 0.002 0.002 205
/GAME_MOB/Bump 0.000 0.000 0.000 35
/client/West 0.000 0.000 0.000 38
/client/South 0.000 0.000 0.000 24
/client/North 0.000 0.000 0.000 75
/client/Move 0.000 0.000 0.000 205
/client/East 0.000 0.000 0.000 68
/atom/Click 0.000 0.000 0.000 2
/AI/proc/LookForTarget 0.012 0.012 0.012 14
/AI/proc/AI 0.000 0.012 25.236 14
Sorry for the messy text i dont know how to put it properly but i think if you copy past in a not it will be more easy to read
There's your answer, right there in the profiling data. Can you see it?

You can click the different columns up top and it'll arrange the data for you. If you click "Calls" then it'll arrange the procs by which has been called the most. In that case, we'd see that client/Move, mob/proc/ActivateAI, and mob/proc/Run are all being called 205 times. We can also look at what's taking the most time.

There are three columns for time. Real Time tells you how much Real World Time was spent in that proc between when it was called and when it returned. This includes time spent sleeping. Total CPU tells us how much time it takes the CPU to execute this proc, including time spent on other procs that this proc called. Self CPU shows how much time it takes for the CPU to execute code in this specific proc.

So let's look at AI/proc/AI:
Calls: 14
Real Time: 25.236 seconds
Total CPU: 0.012 seconds
Self CPU: 0.000 seconds

Right there you have a proc that's only being run 14 times, but took the game a total of 25 seconds to run. That being said, it only took the CPU 0.012 seconds to run the code itself (not much at all).

Now let's take a look at mob/proc/Run:
Calls: 205
Real Time: 0.005
Total CPU: 0.005
Self CPU: 0.004

That's a proc that's being call 205 times, and it has the second highest self CPU value of anything in this list (it's the 2nd most CPU expensive proc). 0.004 doesn't look like a lot of time, but if you run it 205 times then that's almost a whole second of CPU time. If you were only running this test for 10 seconds, then that means one tenth of all the time your game is running is spent in that proc. Now look at mob/proc/ActivateAI. It was also run 205 times and has a Self CPU value of 0.002, for a total time of about half a second.

AI/proc/LookForTarget is the most expensive proc with a Self CPU time of 0.012 seconds, but is only being called 14 times.

Are you starting to get a picture for what's happening in your game? Here are my suggestions: Take another look at LookForTarget and see if you can optimize it. Take another look at AI/proc/AI and see why that proc is running for so long. It might not be an issue unless it's taking control away from the players or pausing the game. Then take a look at Run and ActivateAI. Those two procs are being called a lot and are taking a lot of CPU time. Find out why.
Oh thanks you i will check that i will let you know. but the client/move if i move for like 1 minute it raise to 1642 call because i move and it take cpu 0.004 and real time 0.003 if move for like 30 min it is possible that make the game bug
I just test it again o raise it to 1800 call and the cpu and time stay at 0.000
Computer programming is about communicating precisely. You have to use words and symbols (like punctuation) to tell the computer exactly what to do. In order to communicate precisely, you have to learn how to think precisely. If you're going to get help with a computer problem, you also need to communicate precisely with the people helping you. In other words, I'm having a hard time understanding you because of the way you write.

I don't know why you're trying to increase the number of times that client/Move is being called. The profiling data says that client/Move is being called a lot, but isn't taking any time to execute. That means our problem probably isn't there.

AI/proc/AI is only being called 14 times, but the CPU is spending 25 seconds executing it. That means it's much more likely the problem is there. However, it has a self CPU time of 0.000 meaning that the problem isn't AI/proc/AI itself, but other procs that it calls while executing. One of those other procs is LookForTarget, which is being called the same number of times and has a high self CPU time of 0.012.

mob/proc/Run could also be the source of the problem because it's being called 205 times and has a self CPU time of 0.004.

Now that we've identified procs that could be causing the problem, put away the profiler. Go back to Dream Maker and investigate those procs. If you can't figure out what's wrong, then post them here and ask for help.
Im sorry my primary language is not english i do all my possible to write good.

I understand all of what you just say.
I remove the ActivateAI and Run proc i also remove the Ai in the worldmap.dmm so i can see if the lag is gone and yes the lag is gone but is still look slightly slow so i check the profiler everything is ok.
So i was wondering if the movement itself can be the problem in my game i use pixel movement. This is my last question for now i will check to optimises what i remove because i need it
Thanks you for you help if i need help i will post my code here.
Anything can cause a problem if it was programmed incorrectly. Go ahead and post the code here if you want, and we'll try and find any problem areas. Just post the procs we talked about before. No need to post the entire project.

We understand it's hard to learn to program when the only resources you have are in a different language. However, there are some things you can do to communicate more effectively that don't have to do with language. For instance, you've written several small posts one after another, like you were talking in a chat room. Think of writing a forum post like writing an email or a letter. You write it, think about it, go back and edit, make sure it says everything you want it to, edit again, and then send it. Hope that helps :)
so this is the proc where the player begin to Run and in this proc the player have a prob to get agility exp..
when i remove global.LevelStat(mob,"Agility") the game stop laging so the problem is not in the run proc..
Code:
        Run()
//set waitfor = 0
spawn()
var/GAME_MOB/mob = src
if(src.StepsTillRun > 24)
src.step_size = 18
if(!mob.swimming)src.icon_state = "run"
src.StepsTillRun+=1
if(src.StepsTillRun >= 100)
if(prob(35))
// if(mob.swimming)
// mob.agi_exp += rand(2,8)
// else
if(!mob.swimming)
mob.agi_exp += rand(1,5)
global.LevelStat(mob,"Agility")
// if(prob(2))
// mob.exp += 1
// global.CheckLevel(mob)
spawn(12)
if(src)
src.StepsTillRun-=5
if(src.StepsTillRun<25)src.Runup()

Runup()
var/GAME_MOB/mob = src
if(!mob.swimming)src.icon_state = ""
src.step_size = 12
if(src.StepsTillRun < 0)
src.StepsTillRun = 0



i think the problem is there. this is where the agility level up.
Code:
    LevelStat(GAME_MOB/mob, var/stat)
if(!mob.client)return
if(!mob||!stat)return
if(stat == "Agility")
if(mob.agi_exp >= mob.agi_max_exp)
mob.agi_exp -= mob.agi_max_exp
if(mob.agi_exp < 0)mob.agi_exp = 0
mob.agi_max_exp += (round(mob.agi_max_exp/10)+3)
mob.agility += 1
mob.m_agility += 1
mob << "<i><font color=yellow>Your agility has increased!"
//if(mob.client)mob.client.Save()
mob.UpdateInfo()
mob.exp += 1
spawn()global.CheckLevel(mob)
global.LevelStat(mob,stat)
if(mob)mob.UpdateInfo()

i realy think the problem is there did you see something wrong in this code
i hope you understand lmao :)
I don't know what exactly the problem is. There are structure issues here that are beyond the scope of this reply. For instance, is the call to LevelStat() from within LevelStat() supposed to be part of the spawn statement? Why is the call to Runup() being delayed by 12 (in the spawn statement)? Until that spawn(12) is executed, every time Run is called the value of StepsTillRun will still be above 100, so about one third of all calls will result in LevelStat being called.

That could be the problem. Or it could be that LevelStat is calling itself. When a proc calls itself, we say the proc is "recursive" and it is calling itself "recursively". That's what I mentioned in my first reply. Whenever the CPU locks up without any errors, you should check for run-away loops or recursion. Is that recursive call to LevelStat supposed to be part of the spawned statement above it? How many times is LevelStat being called?

I suggest putting in a diagnostic statement, like this:
world << "Calling LevelStat recursively"

Put that statement into your LevelStat proc, right before the line "global.LevelStat(mob,stat)"

If every time you move you see one or two of those messages, that's ok. If the CPU locks up and then you see a hundred of those messages, that means you have run-away recursion.
I just write world << "Calling LevelStat recursively" right before the line you say me and i only see it one time when my agillity raise by 1 level

The game lag when i get agillity exp

I realy thanks for helping me finding the problem i hope finding it soon :)
Remember the profile info you posted earlier today? That big block with proc names and times like 0.001? Are you sure that was the all the profile info? I'm wondering if there was more that you didn't post - like maybe there were scroll bars and a lot more data?
Code:
                             Profile results (total time)
Proc Name Self CPU Total CPU Real Time Calls
----------------------------------- --------- --------- --------- ---------
/mob/proc/Run 0.003 0.005 0.005 97
/proc/LevelStat 0.000 0.002 0.002 15
/mob/proc/UpdateInfo 0.002 0.002 0.002 16
/client/West 0.001 0.001 0.001 90
/client/Move 0.001 0.001 0.001 99
/mob/proc/Runup 0.000 0.000 0.000 16
/mob/proc/UpdateHUD 0.000 0.000 0.000 16
/client/South 0.000 0.000 0.000 9
/turf/GroundTurfs/GrassDark/Entered 0.000 0.000 0.000 8
/proc/CheckLevel 0.000 0.000 0.000 1
/atom/Click 0.000 0.000 0.000 1


this is all i have for moving a bit i remove look for target and ai i will work on them after i fix run

I only walk for like 10 sec
While I have no direct fix for your issue, I have this:

#define CHECK_TICK if(world.tick_usage > 80) sleep(world.tick_lag)

You can apply CHECK_TICK under your loops (Not movement though, since it does add a small delay) that should streamline your functions more and spread it over multiple ticks. Its been a very useful addition to SS13, and it may help you too. Just put it at the end (inside) your expensive loops that aren't reliant on performance (like movement!)
You mean define it like a proc and after i put CHECK_TICK() in the movement proc
nnnoooo I specifically said 2 times only in loops where you can afford the code to be a bit slower, if you add this to movement and there is lag your movement will probably act funky.

And you don't need to define it as a proc, thats what the #define does. You just copypaste the line somewhere on top of your code and paste CHECK_TICK at the end of expensive loops, which spreads out the load over multiple ticks