• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

GAF Indie Game Development Thread 2: High Res Work for Low Res Pay

Status
Not open for further replies.

bkw

Member
What engine? Maybe people here will have some suggestions.

Can you identify the performance bottleneck?

What engine?

Can you use a profiler? If you use Unity, it has a great one. It can find both performance bottlenecks and the source of memory allocations (the latter of which was very helpful for me given the way Lupinball does online).

Thanks!!


Turn off all the effects / features / render layers / view distance and turn them on one by one and see where your performance starts to drop massively.
Thanks guys. I'm using Unity. With the profiler, I can see that it's my platforming code that's taking a long time. It's being called in FixedUpdate, so once I hit that 20ms cliff, everything's falling apart. I'm doing a bunch of OverlapSphere checks and boxcasts (my own code, as this was pre 2D stuff). I think I just don't know how to use the profiler properly to see which chunk of code is the culprit... Or maybe my expectations are off. (I have about 80 of these "platformer" game objects right now... maybe that's too much to ask?)

Being the platforming code, it's so integral to the game, so I'm stressing out that I can't fix it. I'm almost tempted to switch over to the Unity 2D physics stuff, but this late in the game... that's a pretty big change.
 

Kalentan

Member
Make sure the vars are in the same object. If you can't figure it out still, post the error message.

variables?

Wait I have just Str[0] = 25

Should I do:

var mainS = 25;
Str[0] = mainS;

?

Honestly I have no idea if I'm even doing the Character Stats and Equipment Stats correctly.

How I'm doing stats is thusly:

On one script I have everyone's stats for the 8 party members:

Str[0..7] = x;
Agi[0..7] = x;

And so on.

For Weapons/Armor I do this:
W[n,0] = "Weapon Name"
W[n,1] = Damage
Same for Armor just replace Damage with Def.

I was going to populate my Weapons and Armors script pages with the 'n' determining which weapon/armor it is.

Then for each character I have:
Wep[n, 0] = W[Mequip,0] //Mequip is changed based on what equipment the player has put on.
Wep[n, 1] = W[Mequip,1]
Helm[n, 0] = H[Mequip, 0]
Helm[n,1] = H[Mequip, 0]

So then after all that's loaded...

Then I want to do Atk[0] = Str[0] + Wep[n,1]...
 
Thanks guys. I'm using Unity. With the profiler, I can see that it's my platforming code that's taking a long time. It's being called in FixedUpdate, so once I hit that 20ms cliff, everything's falling apart. I'm doing a bunch of OverlapSphere checks and boxcasts (my own code, as this was pre 2D stuff). I think I just don't know how to use the profiler properly to see which chunk of code is the culprit... Or maybe my expectations are off. (I have about 80 of these "platformer" game objects right now... maybe that's too much to ask?)

Being the platforming code, it's so integral to the game, so I'm stressing out that I can't fix it. I'm almost tempted to switch over to the Unity 2D physics stuff, but this late in the game... that's a pretty big change.
Define "platformer" objects/code - in what context? The player controller? Object physics? Collision? Etc.

Overlap will be called every frame no matter what, IIRC (someone correct me, I don't use it). I prefer to check only on collision, which checks only the frame it occurs in.

80 is nothing. I have tested hundreds of objects with my own physics and unity's Rigidbodies colliding with each other updated at both the framerate with my phys and interpolation on with Rigidbody in fixedupdate. On both XO and PS4 I hit 100+ when the shit hits the fan in my stress tests for effects with boh methods. Needless to say I get far higher numbers on PC.

If you look at the profiler - check the chunk with the largest time. Will point you to a script.

Are you using any 3rd party plugins?
 

bkw

Member
Define "platformer" objects/code - in what context? The player controller? Object physics? Collision? Etc.

Overlap will be called every frame no matter what, IIRC (someone correct me, I don't use it). I prefer to check only on collision, which checks only the frame it occurs in.

80 is nothing. I have tested hundreds of objects with my own physics and unity's Rigidbodies colliding with each other updated at both the framerate with my phys and interpolation on with Rigidbody in fixedupdate. On both XO and PS4 I hit 100+ when the shit hits the fan in my stress tests for effects with boh methods. Needless to say I get far higher numbers on PC.

If you look at the profiler - check the chunk with the largest time. Will point you to a script.

Are you using any 3rd party plugins?
Oh sorry, should have clarified that. By platformer, I mean the script that handles the collisions. The script that controls how objects collide with the ground and walls, and lets the player pass through one way platforms, etc. The player controller feeds a velocity into this script.

I don't think I can avoid the overlap sphere call, so the best I can do is minimize it (unless I "roll my own" and don't rely on unity physx to find nearby colliders and such.) 80 objects does seem very low, so the issues probably lie with my code.

I think I'm getting the hang of the profiler a bit now. Going to try to get rid of some GetComponent calls. Didn't think I'd have issue with those, but maybe calling them every phys frame isn't smart. Haven't found any single chunk of code that's bringing everything down though. Maybe it's just a whole bunch of inefficiencies everywhere that's adding up.

No 3rd party plugins. Not for the gameplay part at least.
 
variables?

Wait I have just Str[0] = 25

Should I do:

var mainS = 25;
Str[0] = mainS;

?

Honestly I have no idea if I'm even doing the Character Stats and Equipment Stats correctly.

How I'm doing stats is thusly:

On one script I have everyone's stats for the 8 party members:

Str[0..7] = x;
Agi[0..7] = x;

And so on.

For Weapons/Armor I do this:
W[n,0] = "Weapon Name"
W[n,1] = Damage
Same for Armor just replace Damage with Def.

I was going to populate my Weapons and Armors script pages with the 'n' determining which weapon/armor it is.

Then for each character I have:
Wep[n, 0] = W[Mequip,0] //Mequip is changed based on what equipment the player has put on.
Wep[n, 1] = W[Mequip,1]
Helm[n, 0] = H[Mequip, 0]
Helm[n,1] = H[Mequip, 0]

So then after all that's loaded...

Then I want to do Atk[0] = Str[0] + Wep[n,1]...

No, don't use a var declaration. That will ensure the scope is only the script, Which is exactly what you don't want in this case. I was only asking if all your variables are in the same object. Otherwise they would be out of scope and not be able to be referenced.


Honestly, the error message should be telling you exactly what's wrong. Without it I'm just guessing.
 

Kalentan

Member
No, don't use a var declaration. That will ensure the scope is only the script, Which is exactly what you don't want in this case. I was only asking if all your variables are in the same object. Otherwise they would be out of scope and not be able to be referenced.


Honestly, the error message should be telling you exactly what's wrong. Without it I'm just guessing.

Ah, yeah. Here it is. Also yes, the scripts that are called are set in one object.

___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Create Event
for object Obj_Base:

DoAdd :: Execution Error
at gml_Script_Character_AtkDef (line 1) - Atk[0] = Str[0] + Wep[0,1];
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_Character_AtkDef (line 1)
called from - gml_Script_Character_Sheets (line 6) - Character_AtkDef();
called from - gml_Object_Obj_Base_CreateEvent_1 (line 3) - Character_Sheets();
 
That's weird cause these are what they're:

Str[0] = 24;
Wep[0,1] = 25;

Neither are a string.
I believe you, but I'm just telling you what that error message means. Is it at all possible that the wires get crossed somewhere? I know you're assigning a string to one of the slots in the array. Maybe one time you set it up as [n, 0] and another time it's [0, n].
 

Kalentan

Member
I believe you, but I'm just telling you what that error message means. Is it at all possible that the wires get crossed somewhere? I know you're assigning a string to one of the slots in the array. Maybe one time you set it up as [n, 0] and another time it's [0, n].

Hm... Let me check. It's certainly possible.

So I got through the error... Rather than using Wep[0,1] I just used W[0,1] directly. It works for now, but eventually I will need to fix that. Cause as it is, it's making the Attack Rating off of a set weapon damage rather than what is equipped.
 
Oh sorry, should have clarified that. By platformer, I mean the script that handles the collisions. The script that controls how objects collide with the ground and walls, and lets the player pass through one way platforms, etc. The player controller feeds a velocity into this script.

I don't think I can avoid the overlap sphere call, so the best I can do is minimize it (unless I "roll my own" and don't rely on unity physx to find nearby colliders and such.) 80 objects does seem very low, so the issues probably lie with my code.

I think I'm getting the hang of the profiler a bit now. Going to try to get rid of some GetComponent calls. Didn't think I'd have issue with those, but maybe calling them every phys frame isn't smart. Haven't found any single chunk of code that's bringing everything down though. Maybe it's just a whole bunch of inefficiencies everywhere that's adding up.

No 3rd party plugins. Not for the gameplay part at least.
Holy cow. Yes. Stop that lol. I use <GetComponent> all the time but only when I need to like collision, i then store the component as a reference if necessary.

I also do not store the component if I don't have to.

So say my weapon needs to crack the DamageObject() function on an enemy.

I can

void OnTriggerEnter2D(Collider2D collision)
{
EnemyHealth _eHealth = collision.GetComponent<EnemyHealth>();
_eHealth.DamageObject(damageAmount);
}

Right?

I can just do this:
{
collision.GetComponent<EnemyHealth>().DamageObject(damageAmount);
}

Now instead of taking a step to cache the object on collision and then apply damage or what have you - we just tell the component directly without caching, if it's not needed.

But yes - we cut down on calls this way by not getting components every fixed time step. Any time we can cut out a middle man we do. Another trick using the same collision check as above:

if (collision.gameObject.tag == "BadGuy")

tag == "" will call the function compareTag. That's 2 steps. We can shorten it with:
if (collision.gameObject.compareTag("BadGuy"))

Now it's just one step.

So if you absolutely need to do things every fixed time or every frame - cut out as many middlemen as you can. With checking physics layers check by number instead of name.

All of this assuming you are checking what you are colliding with via overlap or collision by tag or layer. Trim some if you haven't
 

bkw

Member
Holy cow. Yes. Stop that lol.
Yeah, that was pretty dumb. I was coding without considering efficiency, thinking I could deal with it later. Guess it's biting me in the butt now. Should have profiled and started optimizations a lot sooner. After working in the mobile space I didn't think I'd have to deal with this stuff as much... Guess not. =P
I use <GetComponent> all the time but only when I need to like collision, i then store the component as a reference if necessary.

I also do not store the component if I don't have to.

So say my weapon needs to crack the DamageObject() function on an enemy.

I can

void OnTriggerEnter2D(Collider2D collision)
{
EnemyHealth _eHealth = collision.GetComponent<EnemyHealth>();
_eHealth.DamageObject(damageAmount);
}

Right?

I can just do this:
{
collision.GetComponent<EnemyHealth>().DamageObject(damageAmount);
}

Now instead of taking a step to cache the object on collision and then apply damage or what have you - we just tell the component directly without caching, if it's not needed.

But yes - we cut down on calls this way by not getting components every fixed time step. Any time we can cut out a middle man we do. Another trick using the same collision check as above:

if (collision.gameObject.tag == "BadGuy")

tag == "" will call the function compareTag. That's 2 steps. We can shorten it with:
if (collision.gameObject.compareTag("BadGuy"))

Now it's just one step.

So if you absolutely need to do things every fixed time or every frame - cut out as many middlemen as you can. With checking physics layers check by number instead of name.

All of this assuming you are checking what you are colliding with via overlap or collision by tag or layer. Trim some if you haven't
Do these changes actually make much of a difference? Stuff like your _eHealth example, I would think/hope the compiler is smart enough to make that optimization.

Kinda surprised that the OverlapSphere calls are taking as much time as they are. Unfortunately I can't rely on the physics trigger/collision events to do things, since way way back we decided to just do our own collision stuff (4.3 days). Probably not the best of decisions, but too late to change now. Going to tone down the amount of objects if I can't find any more time. (They're just showers of coins. So now, it's more of a sprinkling rather than a shower...) Sucks though... Lesson learned for the next project I suppose.
 

Blizzard

Banned
I can

void OnTriggerEnter2D(Collider2D collision)
{
EnemyHealth _eHealth = collision.GetComponent<EnemyHealth>();
_eHealth.DamageObject(damageAmount);
}

Right?

I can just do this:
{
collision.GetComponent<EnemyHealth>().DamageObject(damageAmount);
}

Now instead of taking a step to cache the object on collision and then apply damage or what have you - we just tell the component directly without caching, if it's not needed.
Have you timed the difference between running those two cases say, 10000 times? I don't know what kind of compiler Unity is using, but I would expect almost any decent compiler to have VERY little difference between making a local variable and dereferencing it, and doing it all in one line.

I could believe that the compareTag() case could save a little time because of reduced function call overhead, but that's a different situation. I don't really know how the operator overloading works in that case -- whether there actually is a different method, whether it all gets inlined, or what.

What I could DEFINITELY believe affects performance is calling something like GetComponent() every update cycle instead of saving references to everything. If there is some major object that persists throughout the level and you can save a reference, that should be better than calling GetComponent() repeatedly and having the same thing returned every time. This would presumably be because actual code is being skipped, plus function call overhead is being reduced.
 

Ventron

Member
Thanks guys. I'm using Unity. With the profiler, I can see that it's my platforming code that's taking a long time. It's being called in FixedUpdate, so once I hit that 20ms cliff, everything's falling apart. I'm doing a bunch of OverlapSphere checks and boxcasts (my own code, as this was pre 2D stuff). I think I just don't know how to use the profiler properly to see which chunk of code is the culprit... Or maybe my expectations are off. (I have about 80 of these "platformer" game objects right now... maybe that's too much to ask?)

You can narrow down the code in the profiler by using samples.

Code:
Profiler.BeginSample("suspect_code_1");
// ... SUSPECT CODE
Profiler.EndSample();
Profiler.BeginSample("suspect_code_2");
// ... OTHER SUSPECT CODE
Profiler.EndSample();

They'll show up as you named them in the profiler, so you can narrow down your code even further than function-level.
 
Yeah, that was pretty dumb. I was coding without considering efficiency, thinking I could deal with it later. Guess it's biting me in the butt now. Should have profiled and started optimizations a lot sooner. After working in the mobile space I didn't think I'd have to deal with this stuff as much... Guess not. =P

Do these changes actually make much of a difference? Stuff like your _eHealth example, I would think/hope the compiler is smart enough to make that optimization.

Kinda surprised that the OverlapSphere calls are taking as much time as they are. Unfortunately I can't rely on the physics trigger/collision events to do things, since way way back we decided to just do our own collision stuff (4.3 days). Probably not the best of decisions, but too late to change now. Going to tone down the amount of objects if I can't find any more time. (They're just showers of coins. So now, it's more of a sprinkling rather than a shower...) Sucks though... Lesson learned for the next project I suppose.
The compiler compiles what you write. It doesn't modify or optimize for you. If you want to create a reference to a component - the compiler doesn't make the call that you don't need the reference and simply call the function on the component - if compilers chose to do stuff like that - your game would break 100% of the time. If you request a reference - it will reference it for you. That's why we write explicit code.

Also - what does your overlap do, exactly? What information does it look for and what changes when you overlap, say, the ground? What is its main function?

Have you timed the difference between running those two cases say, 10000 times? I don't know what kind of compiler Unity is using, but I would expect almost any decent compiler to have VERY little difference between making a local variable and dereferencing it, and doing it all in one line.

I could believe that the compareTag() case could save a little time because of reduced function call overhead, but that's a different situation. I don't really know how the operator overloading works in that case -- whether there actually is a different method, whether it all gets inlined, or what.

What I could DEFINITELY believe affects performance is calling something like GetComponent() every update cycle instead of saving references to everything. If there is some major object that persists throughout the level and you can save a reference, that should be better than calling GetComponent() repeatedly and having the same thing returned every time. This would presumably be because actual code is being skipped, plus function call overhead is being reduced.
I have no idea how his code is written or even what his overlap checks so I am blind firing. I'm unsure about how much execution time is saved for those exact instances - but you are cutting an extra step for both - doing that EVERY frame with GetComponent will yield horrible results, so I suggested streamlining based on little to no information or parameters to work with.

It's difficult to say what is doing what or how it can be improved without any material to go on.
 

Blizzard

Banned
The compiler compiles what you write. It doesn't modify or optimize for you. If you want to create a reference to a component - the compiler doesn't make the call that you don't need the reference and simply call the function on the component - if compilers chose to do stuff like that - your game would break 100% of the time. If you request a reference - it will reference it for you. That's why we write explicit code.
Maybe I'm ignorant, but I'm really not sure this is true. Compilers obviously do optimize (thus the different optimization levels in say, gcc or MSVC++), but my experience is primarily in embedded systems and C/C++, so the compiler used by Unity might be different.

To take a simple example, why would a game break if a compiler chose to skip making a local reference variable that doesn't get used anywhere else?

One thing I do feel fairly confident in is, if there's ever a question of whether something speeds up code (like converting those 2 lines into 1), it can be worthwhile to do a simple test. Taking an average of a game loop time before, taking the average afterwards, checking whether it changes. Or calling a function that does that 10000 times, and precisely timing the overall execution time with a profiler or some other technique. Otherwise, one may THINK that one is being clever with optimization or explicitly telling the compiler what to do, when in practice what happens may be slightly different. *edit* This is speaking in general, and applies to most any case of course. I agree that we don't know much about the other case, but the compiler optimization mentions caught my attention specifically so I wanted to discuss that.
 

Kalentan

Member
After working for hours wondering why this wasn't working... I fixed my issue... and the solution is bullshit. So I made this image:

Jq5b.png


Sure, talkM and talkQ are both global variables... but if the script on the left is literally written right above the drag and drop on the right... Why should this make a difference?
More so since talk1, talk2, and talkCon are established and based in the very object I have all of this in.
 
Maybe I'm ignorant, but I'm really not sure this is true. Compilers obviously do optimize (thus the different optimization levels in say, gcc or MSVC++), but my experience is primarily in embedded systems and C/C++, so the compiler used by Unity might be different.

To take a simple example, why would a game break if a compiler chose to skip making a local reference variable that doesn't get used anywhere else?

One thing I do feel fairly confident in is, if there's ever a question of whether something speeds up code (like converting those 2 lines into 1), it can be worthwhile to do a simple test. Taking an average of a game loop time before, taking the average afterwards, checking whether it changes. Or calling a function that does that 10000 times, and precisely timing the overall execution time with a profiler or some other technique. Otherwise, one may THINK that one is being clever with optimization or explicitly telling the compiler what to do, when in practice what happens may be slightly different. *edit* This is speaking in general, and applies to most any case of course. I agree that we don't know much about the other case, but the compiler optimization mentions caught my attention specifically so I wanted to discuss that.

I'm not questioning whether it's used elsewhere - Unity will tell you if you have anything that you don't use in the console window. I'm saying it won't correct your errors or omissions for you. It can't "combine" your code. If you call "tag ==" instead of "compareTag" - the compiler will not skip "tag ==" and turn it into "compareTag" because "tag ==" is valid. It just so happens that "tag ==" will call "compareTag" for you and yes, it's faster not using "tag ==".

And yes, shit can break if your compiler decides to ignore explicit code on its own, regardless of whether or not it is used. You can create a variable and not assign it. You will be notified it is not assigned. After compile, you can easily call that variable despite it not being used. It will return null/0 - the compiler won't skip it just because, it won't modify it, it won't streamline anything for you.
 

bkw

Member
Also - what does your overlap do, exactly? What information does it look for and what changes when you overlap, say, the ground? What is its main function?
I use it to get an array of nearby (box) colliders, which I do my own boxcast against.

And yes, shit can break if your compiler decides to ignore explicit code on its own, regardless of whether or not it is used. You can create a variable and not assign it. You will be notified it is not assigned. After compile, you can easily call that variable despite it not being used. It will return null/0 - the compiler won't skip it just because, it won't modify it, it won't streamline anything for you.
The compiler won't skip it in this case, since you are using the variable, but if you declare a variable and never use it (pull a value out from it?), I would think the compiler will strip it out for you.
 

Blizzard

Banned
I'm not questioning whether it's used elsewhere - Unity will tell you if you have anything that you don't use in the console window. I'm saying it won't correct your errors or omissions for you. It can't "combine" your code. If you call "tag ==" instead of "compareTag" - the compiler will not skip "tag ==" and turn it into "compareTag" because "tag ==" is valid. It just so happens that "tag ==" will call "compareTag" for you and yes, it's faster not using "tag ==".

And yes, shit can break if your compiler decides to ignore explicit code on its own, regardless of whether or not it is used. You can create a variable and not assign it. You will be notified it is not assigned. After compile, you can easily call that variable despite it not being used. It will return null/0 - the compiler won't skip it just because, it won't modify it, it won't streamline anything for you.
Combining code in this case would be is "inlining" if I understand it correctly, which you can (in C/C++ at least) explicitly mark certain functions for. Here's a link about C#: http://stackoverflow.com/questions/473782/inline-functions-in-c

I found this page about C# as well: http://stackoverflow.com/questions/3236575/inline-expansion-in-c-sharp

The conclusion reached there was that for JIT (Just-In-Time compilation), certain functions MAY be inlined automatically, and some may not. A quick Google search suggests Unity uses JIT for some platforms, but I don't 100% know. I guess the ideal set of steps if one encountered a situation like this would be:

1. Does the Unity profiler indicate a certain script section is slow?
2. If so, use the Profiler.BeginSample and Profiler.EndSample calls as described by Ventron above to surround the specific script section with the questionable lines.
3. Check how much time is spent in that section.
4. Change it to eliminate the suspected middleman, and run again to check how much time is spent in that section.

My personal suspicion is that inlining would not help much unless the method in question is called a LOT for each cycle of the game loop. Thousands or millions of times? For sure, it could help.
 

Lautaro

Member
Check if you have warnings in the profiler (last column), also check that every object with a collider that moves has a rigidbody (even if its kinematic).

If you are doing lots of overlapsphere or something like a radar maybe you can do it every 0.1 seconds instead of every frame (also make sure that you check it against only the colliders that you need, for example a overlap sphere that detects enemies should only use the layer of the enemies to improve performance).

----------------

I uploaded a new patch! http://steamcommunity.com/games/371010/announcements/detail/130958205690271634

This one doesn't have much stuff so I won't use one of my rounds but I think I prefer to make these smaller patches to keep a sense of progress. Also sweet sweet beam weapons:

OQXiciw.gif
 
I use it to get an array of nearby (box) colliders, which I do my own boxcast against.
That will be crazy depending on how much information you need with BoxCast. You still haven't gone into how you are using any of it so I really can't help. Are you just checking for a collision type? Slope? Direction? BoxCast can be heavy, especially every frame or fixed time. I have no idea if your platformer has any crazy geometry or other meshes where requiring a BoxCast is a must - so I can't go much further.

The compiler won't skip it in this case, since you are using the variable, but if you declare a variable and never use it (pull a value out from it?), I would think the compiler will strip it out for you.
In my limited testing - nope. You will get a log in the console window and that's it. Assign a key to print to a mesh at runtime.

Combining code in this case would be is "inlining" if I understand it correctly, which you can (in C/C++ at least) explicitly mark certain functions for. Here's a link about C#: http://stackoverflow.com/questions/473782/inline-functions-in-c

I found this page about C# as well: http://stackoverflow.com/questions/3236575/inline-expansion-in-c-sharp

The conclusion reached there was that for JIT (Just-In-Time compilation), certain functions MAY be inlined automatically, and some may not. A quick Google search suggests Unity uses JIT for some platforms, but I don't 100% know. I guess the ideal set of steps if one encountered a situation like this would be:

1. Does the Unity profiler indicate a certain script section is slow?
2. If so, use the Profiler.BeginSample and Profiler.EndSample calls as described by Ventron above to surround the specific script section with the questionable lines.
3. Check how much time is spent in that section.
4. Change it to eliminate the suspected middleman, and run again to check how much time is spent in that section.

My personal suspicion is that inlining would not help much unless the method in question is called a LOT for each cycle of the game loop. Thousands or millions of times? For sure, it could help.
Which is the case we are talking about this whole time as stated by bkw a long time ago and myself as reinforcement. I feel like what I write is falling on blind eyes as I've addressed this.

Check if you have warnings in the profiler (last column), also check that every object with a collider that moves has a rigidbody (even if its kinematic).
NOPE. Only one object in a two-object collision needs a RigidBody component to detect collision in either direction - even an object without a RigidBody can detect collision of the other object has a RigidBody. ONLY use RigidBodies if needed on that object - even if you don't use the RB - you are still calculating physics even when standing still. You want to LIMIT RigidBody use as much as possible pretty much at all times.
 

bkw

Member
That will be crazy depending on how much information you need with BoxCast. You still haven't gone into how you are using any of it so I really can't help. Are you just checking for a collision type? Slope? Direction? BoxCast can be heavy, especially every frame or fixed time. I have no idea if your platformer has any crazy geometry or other meshes where requiring a BoxCast is a must - so I can't go much further.
Yeah, probably crazy... For each object, on every fixed update frame, I use overlap sphere to get the nearby colliders. From those colliders, I use their bounds and check for collision against the object's own bounds by my own boxcast code. The collision checks determine if the object should stop moving in a particular direction or not. This includes stopping when it hits a ceiling, and stopping -y so the object doesn't sink into the ground.

I'm basically using overlapsphere as a spatial partitioning thing.

I probably should have just let PhysX deal with this stuff, but way back, I couldn't figure out how to do one way platforms with it.
 

Jumplion

Member
Does anyone know how to access the gyroscope from a phone in Unity? I've looked around and apparently iOS you can do that natively but you can't do that with Androids yet (which sucks because I have an Android). Would rather avoid the $45 plugin for Android, but might have to suck it up.
 

Blizzard

Banned
Blizzard said:
My personal suspicion is that inlining would not help much unless the method in question is called a LOT for each cycle of the game loop.
Which is the case we are talking about this whole time as stated by bkw a long time ago and myself as reinforcement. I feel like what I write is falling on blind eyes as I've addressed this.
Are we talking about different things? I am specifically talking about method inlining. I believe method inlining is what your example does (changing the == operator override to a direct compareTag() call). See the stackoverflow links for more details.

Am I wrong on that term and it should be called something else?

If I'm right on the term, where did bkw ever say he had a call that could be inlined? That's what I'm confused about, since I thought it was only in your example, and bkw didn't mention it at all.
 

bkw

Member
If you are doing lots of overlapsphere or something like a radar maybe you can do it every 0.1 seconds instead of every frame (also make sure that you check it against only the colliders that you need, for example a overlap sphere that detects enemies should only use the layer of the enemies to improve performance).

----------------

I uploaded a new patch! http://steamcommunity.com/games/371010/announcements/detail/130958205690271634

This one doesn't have much stuff so I won't use one of my rounds but I think I prefer to make these smaller patches to keep a sense of progress. Also sweet sweet beam weapons:
I think I have my layermasks in order. Unfortunately I overlapSphere for movement, so I can't do it in longer intervals. (Or maybe I can.... hmmm.....) Your game's looking good. It's also done in Unity I presume?

NOPE. Only one object in a two-object collision needs a RigidBody component to detect collision in either direction - even an object without a RigidBody can detect collision of the other object has a RigidBody. ONLY use RigidBodies if needed on that object - even if you don't use the RB - you are still calculating physics even when standing still. You want to LIMIT RigidBody use as much as possible pretty much at all times.
I think Lautaro was referring to the penalty of moving static colliders.
 
Yeah, probably crazy... For each object, on every fixed update frame, I use overlap sphere to get the nearby colliders. From those colliders, I use their bounds and check for collision against the object's own bounds by my own boxcast code. The collision checks determine if the object should stop moving in a particular direction or not. This includes stopping when it hits a ceiling, and stopping -y so the object doesn't sink into the ground.

I'm basically using overlapsphere as a spatial partitioning thing.

I probably should have just let PhysX deal with this stuff, but way back, I couldn't figure out how to do one way platforms with it.
Raycast
Check distance to what you hit
At current speed, will we collide?
No - keep going
Yes - only move X distance to close gap

Collision with raycasts. Just check the distance, math with speed, move full step based on time since last frame if far, only move enough to "collide" if the distance is shorter than the speed can travel based on that deltaTime. You don't need overlaps or BoxCasts. Just my .02

Are we talking about different things? I am specifically talking about method inlining. I believe method inlining is what your example does (changing the == operator override to a direct compareTag() call). See the stackoverflow links for more details.

Am I wrong on that term and it should be called something else?

If I'm right on the term, where did bkw ever say he had a call that could be inlined? That's what I'm confused about, since I thought it was only in your example, and bkw didn't mention it at all.
He never did. Which I explained that I didn't know which is why I used those as examples. I even stated I didn't have much to go on more than once. Matter of fact I stated it a few times to drive that point home, fishing for more information. I'm not sure what is so confusing so I'm just going to bed.
 

Lautaro

Member
NOPE. Only one object in a two-object collision needs a RigidBody component to detect collision in either direction - even an object without a RigidBody can detect collision of the other object has a RigidBody. ONLY use RigidBodies if needed on that object - even if you don't use the RB - you are still calculating physics even when standing still. You want to LIMIT RigidBody use as much as possible pretty much at all times.

This is not something that I invented, moving a collider that doesn't have a rigidbody is "moving a static collider" and many videos and the Unity forums advice to not do it, you can also see it here in the documentation (the static colliders section): http://docs.unity3d.com/Manual/CollidersOverview.html

Now, apparently the situation is better with Unity 5 but is still expensive. I had the chance to see the effect in Unity 4.6 with my game: one of my capital ships had several colliders (to simulate a concave collider) and the performance (when moving) was shit until I added kinematic rigidbodies to them and now the game runs at a pretty stable 60fps.
 

bkw

Member
Raycast
Check distance to what you hit
At current speed, will we collide?
No - keep going
Yes - only move X distance to close gap

Collision with raycasts. Just check the distance, math with speed, move full step based on time since last frame if far, only move enough to "collide" if the distance is shorter than the speed can travel based on that deltaTime. You don't need overlaps or BoxCasts. Just my .02
I think I'm doing something similar, but with a boxcast. I actually recall trying to do this with raycasts a while back, but couldn't get it to work properly. Perhaps raycasting is a lot cheaper. How many rays do you cast? Where do they originate from?
 

Blizzard

Banned
He never did. Which I explained that I didn't know which is why I used those as examples. I even stated I didn't have much to go on more than once. Matter of fact I stated it a few times to drive that point home, fishing for more information. I'm not sure what is so confusing so I'm just going to bed.
I'm not attacking you. I hope I have not been rude and we are just misunderstanding each other.

1. My point was that method inlining would only help in certain cases, unless the method inline candidate is called many times in a single update cycle.

2. You replied that "Which is the case we are talking about this whole time as stated by bkw a long time ago and myself as reinforcement", which I understood to mean "bkw stated the method inline candidate is called many times in a single update cycle".

3. I didn't see bkw state "the method inline candidate is called many times in a single update cycle" (because bkw wasn't talking about inlining)

4. As far as I can tell, you have now replied and said bkw -didn't- state the method inline candidate is called many times in a single update cycle a long time ago, contradicting what I understood in step 2 above. So maybe we agree on this point and it was just a misunderstanding earlier!



Compiler optimization is a subject of interest to me, and I have personally experienced odd things one might not expect -- code that behaves differently at different gcc optimization levels, for example. As such, all I wanted to say in reply was a general statement of caution on the subject of optimization -- sometimes compilers can do strange things one doesn't expect, and sometimes apparent optimizations may produce very little change, while hurting readability and maintainability.

And that's why, overall, I wanted to chime in and say "Careful though, profile changes to make sure it really helps".
 

Lautaro

Member
I think I have my layermasks in order. Unfortunately I overlapSphere for movement, so I can't do it in longer intervals. (Or maybe I can.... hmmm.....) Your game's looking good. It's also done in Unity I presume?


I think Lautaro was referring to the penalty of moving static colliders.

Yes to both.
 
After working for hours wondering why this wasn't working... I fixed my issue... and the solution is bullshit. So I made this image:

Jq5b.png


Sure, talkM and talkQ are both global variables... but if the script on the left is literally written right above the drag and drop on the right... Why should this make a difference?
More so since talk1, talk2, and talkCon are established and based in the very object I have all of this in.

talk = false is not comparing, it's assigning a value, and then it's registering as true if the assignment was successful. You have to use a double equals sign to compare: (talk == false), or a logical not: (!talk)
 

Kalentan

Member
Anyone else whose using Game Maker mind giving me some tips?

So currently I'm trying to design a system in which it allows me to:

  1. Select Dialogue Options
  2. Dependent on Character
  3. Dependent on Day range

Originally I was going to have a timeline per character but eventually I thought of a better idea of one timeline.
I began with a 2D array:
Code:
Chat[0,0] = "Character 1 Name"
Chat[1,0] = "Character 2 Name"
Chat[0,1] = "Character 1 Introduction"
Chat[1,1] = "Character 2 Introduction"

Now there is 6 dialogue options per character and so what I was going to do was:
Timeline Step 0
Code:
Text1 = Chat[menu, 0] //Where Menu is the spot in which the character was selected
Text2 = Chat[menu, 1]

Timeline Step 50, 51 would then pause for a moment to allow the person to press enter before using step 51 to open up the dialogue options menu.

Timeline Step 100, 150, 151 would be a loop. The idea being that it will go through it depending on how many pieces of dialogue there is per option.

Here in lies my issue.

I was thinking of doing more Arrays like:
Code:
script - Character 2 Dialogue
if (day > 1 and day < 4)
{
//Option 0 (choice 1)
Chat[1,10] = "Dialogue here"
Chat[1,20] = "Dialogue here"
//Option 1 (choice 2)
Chat[1,11] = "Dialogue here"
Chat[1,22] = "Dialogue here"
}

So as you can see, 1 [0], 2 [0] is for option 0, and 1 [1], 2 [2], is for option 2.

the problem with this is that those numbers are set in stone on their place in the array and I'm unsure of how I could make a loop based around that. Since depending on the day, there could be more dialogue options and I'd rather try and make one solution than unique solution for every difference. I want to make it so I can easily change the day and the dialogue (and thus how many times something must loop to show all dialogue in that option) without having to add additional code to the timeline.

talk = false is not comparing, it's assigning a value, and then it's registering as true if the assignment was successful. You have to use a double equals sign to compare: (talk == false), or a logical not: (!talk)

You know, when I was in my last semester class they told us to always use == to compare... but then I watched a video for Game Maker a few days ago and the guy said you can use = to compare and that screwed me up. Thanks for clairfying.
 
Holy cow. Yes. Stop that lol. I use <GetComponent> all the time but only when I need to like collision, i then store the component as a reference if necessary.

I also do not store the component if I don't have to.

So say my weapon needs to crack the DamageObject() function on an enemy.

I can

void OnTriggerEnter2D(Collider2D collision)
{
EnemyHealth _eHealth = collision.GetComponent<EnemyHealth>();
_eHealth.DamageObject(damageAmount);
}

Right?

I can just do this:
{
collision.GetComponent<EnemyHealth>().DamageObject(damageAmount);
}

Now instead of taking a step to cache the object on collision and then apply damage or what have you - we just tell the component directly without caching, if it's not needed.

But yes - we cut down on calls this way by not getting components every fixed time step. Any time we can cut out a middle man we do. Another trick using the same collision check as above:

if (collision.gameObject.tag == "BadGuy")

tag == "" will call the function compareTag. That's 2 steps. We can shorten it with:
if (collision.gameObject.compareTag("BadGuy"))

Now it's just one step.

So if you absolutely need to do things every fixed time or every frame - cut out as many middlemen as you can. With checking physics layers check by number instead of name.

All of this assuming you are checking what you are colliding with via overlap or collision by tag or layer. Trim some if you haven't

Just a note, I'm not sure having GetComponent<>() as a single-step process is really a good idea, mainly because it's also very good practice to check if the component is null before actually calling the function just in case it's not present for some reason. But GetComponent<>() is something I don't really use for anything other than specific types of collisions such as damage that obviously don't occur every frame.
 
I got curious about the GetComponent() issue, so I ran a quick test with 1000000 iterations of each case (a few times for consistency; Bar() is an empty method):

GetComponent<Foo>().Bar(): 0.1440470s

var foo = GetComponent<Foo>(); foo.Bar();: 0.1429270s

var foo = GetComponent<Foo(); before the loop, then loop foo.Bar(): 0.0105720s

Of course these kinds of micro-optimizations pale in comparison to the larger-scale physics stuff you were discussing, but it's good to keep in mind.
 

Blizzard

Banned
I got curious about the GetComponent() issue, so I ran a quick test with 1000000 iterations of each case (a few times for consistency; Bar() is an empty method):

GetComponent<Foo>().Bar(): 0.1440470s

var foo = GetComponent<Foo>(); foo.Bar();: 0.1429270s

var foo = GetComponent<Foo(); before the loop, then loop foo.Bar(): 0.0105720s

Of course these kinds of micro-optimizations pale in comparison to the larger-scale physics stuff you were discussing, but it's good to keep in mind.
Thanks for experimenting! That's interesting, since the case with the variable is actually faster?

The last case makes sense because 1000000 GetComponent() calls get completely removed, but I would not have guessed the second result.
 
Thanks for experimenting! That's interesting, since the case with the variable is actually faster?

The last case makes sense because 1000000 GetComponent() calls get completely removed, but I would not have guessed the second result.

Yeah, it's a bit counter-intuitive but I'll just file it under Scary Compiler Magic™. The moral of the story is to always profile and test instead of going with your guts. And, if this was a problem that could affect my game, I'd run the test on an actual build on an actual device.
 

HelloMeow

Member
talk = false is not comparing, it's assigning a value, and then it's registering as true if the assignment was successful. You have to use a double equals sign to compare: (talk == false), or a logical not: (!talk)

I swear I remember using just "=" as a comparison operator in GML back in the day. GLM was so forgiving...
 
This is not something that I invented, moving a collider that doesn't have a rigidbody is "moving a static collider" and many videos and the Unity forums advice to not do it, you can also see it here in the documentation (the static colliders section): http://docs.unity3d.com/Manual/CollidersOverview.html

Now, apparently the situation is better with Unity 5 but is still expensive. I had the chance to see the effect in Unity 4.6 with my game: one of my capital ships had several colliders (to simulate a concave collider) and the performance (when moving) was shit until I added kinematic rigidbodies to them and now the game runs at a pretty stable 60fps.
Truthfully, beats me. I had the opposite experience when working on our mobile stuff - which shouldn't be. I chalk it up to //because unity
/shrug

I think I'm doing something similar, but with a boxcast. I actually recall trying to do this with raycasts a while back, but couldn't get it to work properly. Perhaps raycasting is a lot cheaper. How many rays do you cast? Where do they originate from?
4 up and down and 6 side to side only in the direction we are moving.
I also do not do this on every object.
I also don't know what is more expensive as I haven't tested.

Just a note, I'm not sure having GetComponent<>() as a single-step process is really a good idea, mainly because it's also very good practice to check if the component is null before actually calling the function just in case it's not present for some reason. But GetComponent<>() is something I don't really use for anything other than specific types of collisions such as damage that obviously don't occur every frame.
This has more to do with knowing your logic than anything else. A component not existing is either a major bug or its not supposed to be there. If it's not supposed to be there then why would we look for it?

If we want to double check every time we can or just add a catch. I prefer to double down because I know what I'm looking for and that it exists before I look for it.
 

snarge

Member
I just wanted to add for bkw, another example of a characterController:

https://github.com/prime31/CharacterController2D

This one uses the new Unity / Box2D Physics stuff, but if you just look over it, you should see what you can get away with, performance wise.

Also, I believe the latest Unity platformer code has a better example of a platformer controller. I dunno if that helps, but I always learn from reading other people's code.
 

purdobol

Member
Is there any online course or book (book would be better) that solely focus on texture work that gaf would recommend? Doesn't have to be free as long as its good :p
Since I'm going to try make new project and finish it this time. I would like to learn how professionals are doing that sort of stuff. As of right now it's black magic to me.
 

JNT

Member
Thanks for experimenting! That's interesting, since the case with the variable is actually faster?

The last case makes sense because 1000000 GetComponent() calls get completely removed, but I would not have guessed the second result.
Yeah, it's a bit counter-intuitive but I'll just file it under Scary Compiler Magic&#8482;. The moral of the story is to always profile and test instead of going with your guts. And, if this was a problem that could affect my game, I'd run the test on an actual build on an actual device.
One thing I learned very quickly in programming is that short code does not mean fast code. However, I have a gut (ha!) feeling that the first and second tests will actually perform the same if you average the results over several separate benchmarks, as I'm fairly certain that a moderately clever compiler will generate the same code in both cases. Also note that the third test will perform even better than it already does in relation to the first and second tests when the object contains more components as a tree traversal is involved when fetching a component (although, in theory, not significantly better).

Edit: Edited my answer because I derped.
 

KevinCow

Banned
Does anyone have any experience with importing Spine animations into Unity? It seems that's what my artist wants to do, but I can't find any great documentation on how to do it, just stuff that says it is possible.
 

_machine

Member
That looks great and remedies the distinct lack of motorbikes in the thread :)

Though I personally feel that the trail renderers aren't necessary and don't work so well if you rotate camera enough for the player to see the end of them and how "rigid" they can look.
 

Pehesse

Member
I was going to leave this page as a pure code poetry continuity, but since we have a motorbike breaking the combo already (very cool motorbike too! Maybe just add a scarf to it? :v)... then have another combo breaker. Or just combo.

http://gfycat.com/BlissfulConsiderateCoral

Long story short: adding in the audience. I wanted to try for more cameos, but as you can see, it's a bit tiny... we won't really see the characters. Next time, though!
 

Kalentan

Member
That feeling that you get when you finally thought something out and realized the solution... To then remember your at work for another hour and can't go and implement it. :(
 
Status
Not open for further replies.
Top Bottom