Day 3 - Actual Shark Attack & The enemy of all games
Aug 20, 2023
Slept on it
So I came back to the code I had written and had the classic “slept on it - aha!” moment. I saw two things that I hadn’t realized before.
“bite!” spam
The first thing was the fact that in the console the string "bite!"
was appearing loads of times despite me only clicking once. I don’t know the specifics of all things user input on computers but in my head I thought that the Input
listener was being called multiple times per frame. So to fix that, I added another condition to the conditional to check whether we’re already biting. If we are, then we don’t bite again. This is also needed to prevent someone from spam biting lol.
So from this:
if Input.is_action_pressed("bite"):
print("bite!")
To this:
if Input.is_action_pressed("bite") and is_biting == false:
print("bite!")
Notice the added and is_biting == false
at the end. And that worked! Now the console only prints "bite!"
once per left click.
No animation whatsoever
The next thing I realized was that when I left clicked all animation stopped completely, but at the same time there was no error or the program would crash. So that means whatever was stopping the animation was a logic error. I looked at my code and saw there was only one place where I called .stop()
on any animation, and that’s where I was checking if it should play the "move"
animation!
if velo.length() > 0 and is_biting == false:
$AnimatedSprite2D.play("move")
else:
$AnimatedSprite2D.stop()
Whenever the first condition comes out to be false, the second $AnimatedSprite2D.stop()
is hit, and stops all animations, and that means the "bite"
never finishes, so is_biting
never goes back to false
, and the normal "move"
animation is never played again. Fixing that was actually simple, all it needed was an elif
statement.
if velo.length() > 0 and is_biting == false:
animated_sprite.play("move")
elif is_biting == true:
animated_sprite.play("bite")
else:
animated_sprite.stop()
It’s funny, this is one of those things where in hindsight, and as I’m writing this I’m wondering “How did I not see this/think of this before?! It’s so obvious!” but remember that “Hindsight is 20/20.” It’s super easy to look back at things and think something was obvious but that’s almost always because now you already know it’s the answer.
But I’m glad it was a simple fix, and now Bruce has a bite!

But when testing it, and watching this gif, I saw another issue, and it’s the enemy of all games…
(Optional) Bit of background for anyone unfamiliar with elif/conditionals
:

GDScript
instead of saying else if
they've opted for the abbreviation elif
which is just a bit shorter to type.The enemy of all games
There’re some really annoying issues that are unfortunately fairly common in games, pay-to-win games, unfair bits, lack of balance, developers that seem to not care about the communities surrounding a game, and more. But there’s one thing that rises above the rest in terms of much of an impact on the game, when it’s bad it can EASILY make the game legitimately unplayable, you might’ve guessed it by now but yep, it’s lag. Real quick lets talk about what lag is.
Lag?
What can easily be the most painful aspect of any game, lag.
What is it?
Lag in terms of games, and computer software in general, the usage of the word lag
is true to definition of the word:
lag - fall behind in movement, progress, or development; not keep pace with another or others.
Source is google!
When a game is lagging, it’s falling behind what you’re doing. Let’s say you press the "jump"
button in a game, normally you’d see your character jump right away but if the game is lagging, you might see your character jump a second or two later. The game is lagging behind what you’re doing.
Why does it happen?
Lag is unfortunately one of those things that can be quite hard to pin down it’s source as there’s a variety of possible causes. Typically though lag is caused by:
- Slow or unstable internet connection
- Low frame rates
- Games listen to input every frame, so higher fps = more responsive while the opposite is also true, lower fps = less responsive
- High system load
- Poor game optimization
But these are just some of the most common causes, and it can be hard to narrow down even these, especially since sometimes it can be a combination of different things.
Diving Into it
I noticed that when I was moving my mouse the preview window started lagging pretty badly, and it only got worse unfortunately. Minutes later it reached this point:

Not gonna lie when I saw this I was feeling really defeated, I had just gotten Bruce’s bite working and it looked great and boom out of nowhere I’m hit with this, and I was barely into development of the game. I had no idea what was causing this, and I was worried that it was something caused by me, and that it would only get worse if I ignored it - and it was already so bad I could not ignore it. I was worried that I’d have to scrap the project and start over, or that I’d have to spend a lot of time trying to figure out what was causing this and that it’d be something I couldn’t fix.
I was feeling pretty down, but I decided to take a break and come back to it later, I’m not giving up that easy.
The next day
When I came back to it, I had done some brainstorming. Whenever something breaks, the goal usually is to revert back to before things broke. That means undoing any changes made. So I made a mental list of what I remember having changed/done since before:
- Fixed the bite animation logic
- Changed some editor settings
- Updated Godot to the latest version
In hindsight the first thing I should have done was revert to the previous version of Godot. Unfortunately I didn’t though, note to self is to try that first, it’s the simplest thing to do and probably has the highest chance of working. As I write this I feel like this:

My own code?
But instead I initially thought it was something I wrote, I always look at what I’m doing before blaming external factors. And in my head it sorta made sense, my thoughts were something like this:
- I had this function
_physics_process(delta)
that was being called every frame - My computer is pretty dang strong, and I had what I thought initially was a pretty fair bit of of code in there
- I checked and the FPS was around 3-4k
- High fps + complex math per fps = lag?
I reverted to what I previously had but it didn’t seem to make much of a difference. Then I realized, I had most of the '''complex math''' the whole time. Plus even though it seemed relatively complicated to me, to a computer this is like a walk in the park. So it couldn’t be that.
That also ruled out ‘high system load’ since I checked task manager to confirm and yeah nothing was eating up all the resources.
After a bit more googling and trying things to no avail, I had yet another realization. It only lagged badly when I moved my mouse, and I knew exactly why.
The culprit
So a few years ago I got a new mouse, the Razer Viper V2 Ultimate to be exact and I loved it. In fact it’s the best mouse I’ve ever used, and I’ve gone through a lot of mice. One of the things that this mice did was add a super high polling rate - 1k. Around the time I got this mouse I realized that in valorant whenever I moved my mouse I got really bad lag spikes. After much research into the issue, I found out from some reddit comments that it was the polling rate. Lowering it to 500 pretty much eliminated the lag altogether.
So I had the same thought since the lag was only when my mouse was moving, and sure enough lowering the polling rate pretty much completely got rid of the lag. I might still try rolling back the version of Godot I’m on but at least I know the lag isn’t really a huge issue. I’m still gonna try to optimize the code as much as I can, but I’m glad it’s not something I did.
After a bit more googling I actually found this issue on github, so it’s actually a known bug. Glad that’s solved. Onto spawning some fish!
Goals
Alright here are my current goals:
- Spawn in some
basic_fish
out of sight from the player’s camera
Stretch goals:
- Spawn the
basic_fish
in clumps (fish swim in schools!) - Apply boid based movement to
basic_fish
clusters.