Vampire survivors looks so simple, I bet it's
only like … I don't know, 10 lines of code. [It’s only one banana, what could it cost,
10 dollars?] But seriously, it's not. This game is more complex than it looks. And still, we will try to make something similar
in just 10 lines of code. Can we do it? I don’t know. But we will suffer. A good vampire survivors like needs a few
things: Juice weapons
Evolutions Champion enemies
And chests And Metaprogression of course
But on this channel, we aim for the bare minimum. So let us get the basics in first:
We need a player. Then we need tons of enemies. And they need to spawn, oof. And then we need to kill these enemies with
tons of bullets. That might be the worst part, actually killing
stuff. We also need *some* kind of leveling. So if we count this all together we have…
2.5 lines for each feature. Oh boy. We need to lay some ground rules. We use Godot because we like it. In this engine you *could* cramp everything
in one line with semicolons. But using a semicolon counts as a line because
this would be stupid. Ok. I think we can do this. 2.5 lines is not that bad. Let's start with something easy for motivation. For the background, we can just use a very
large tilemap. Of course, there are much more efficient ways
to do this, but a tilemap should be simple and fast to do. We can even add some alternate tiles. Just draw a large border and we use the fill
tool. It seems to take a second to fill. Or two. ….Mhm. ... So it took 2 minutes, but here we are
with a large field of grass. Now that this went so smoothly, let’s add
a player scene, and give it a sprite with a nice animation, this is going great! Let’s give it its script. Oh damn, what is this? Can we get rid of that? - No, not really. Does it count as a line? - Pretty clearly, yeah. So…uhm, we have 1.5 lines left to make a
player controller. We need a process loop, there really is no
way around that. It's a function that gets called every frame. But we still don't do anything. For the movement we just need the inputs WASD
and built a vector out of that. Easy, in just … ok, we can’t do it like
this. We need to compress this. First of all, we can subtract opposing sides
from each other when we cast them to int. This removes a lot. We now can build the vector2 with both components
at once, and there we are. With just 3 lines… that's too much. I'm pretty sure the other features will be
harder than this, so we will need to find a way to reduce it later. But we can move. In just three lines, that's not bad actually. Don’t forget to add the camera as a child
so it moves with the player. No code, nice! OK, let's add the enemies. This can’t be that much harder, can it? Can it?! We do the same stuff, physics with the physics
process. But we need to move towards the player, so
we navigate to it in the scene tree. Calculate the vector towards and move with
a fixed speed. Ok, a bit of an ugly line, but it should work. And it does. There is one enemy and we can make it many
more just by …mapping a billion of them? That sounds bad, I think we need to spawn
them in. This could be a bit ugly as we are on six
lines right now. But maybe we can just delete this new line
here? It actually works. Only if we have no other statements within
this function, but for now we can remove that new line and are back down on 4 lines. We should add a spawner. Which costs a line by itself. And then we need to load the scene, instantiate
it, and position that thing. It's a shame we can not do it in one go. For the position, we just take a random position
on a circle around the player. Yes, this works! We cannot use 5 lines for this. But we cannot even delete this space. This is expensive. We are at [9] lines. And we still need to shoot. Don't panic, we will just start with a bullet. It needs to move and collide. Ok, maybe panic a little. It's time for dirty tricks. We cannot waste code for the movement path. But we can use an animation player to give
it a nice spiral motion. This actually is quite neat. And when the diablo 2 Hammerdin and nomad
survivors can do this, we are allowed to as well. We have to add another function to the player
to spawn the bullet, which is triggered by a looping animation. Adding the bullet as a child node under the
player makes it moves with the player, but at least it's automatically positioned on
the player. Now we need a script for the bullet. We can cram the collision code in a single
line as well. We just delete the enemy when we collide with
it. Waaait, we can even give it an animation player
and play a death animation before. The death animation will free the enemy at
the end. It still moves after it dies… But I guess there is nothing we can do about
this. Wait- we can disable the physics process in
the animation! Let’s flash the sprite on impact too. Just a little flash shader… wait, shaders
are code! Um, just turn the modulate really high! Okay, we can kill stuff! But we are over our line count at that point
and still have scaling to do. How? Honestly, how? We can combine these two lines, but then we
have no reference to the enemy to set its position. But maybe the enemy can do it itself! The ready function is called as soon as it
is added to the scene. We just need to navigate to the player. So we save 2 lines! Oh, and another thing is: we can let the player
spawn the enemies. This is terrible software design, but that's
kind of the point of the whole challenge. So move it over and we save a line. We dont need a spawner script anymore. And one more thing - wouldn't it be amazing
if the enemies could collide with each other? For that, we change them into kinematicBodies2D
and give them a collision shape. Instead of changing its position directly,
we call move_and_slide. This costs no lines! We are at 9 lines. That's surprisingly good. But no way this is enough for a levelup screen. We need to improvise a bit. Let's just increase the player's attack rate
and the enemy spawn rate based on another animation player that animation the speed
of the first one. This actually works. The game gets faster. We dont want to declare a variable because
it costs a line, but we can increase the movement speed by animating
the animated sprite’s speed scale and read that in the script as our speed. Oh, and yeah, we can not lose yet. We sacrifice another line to detect the enemy
hitbox. Then we play an animation and…? I don't know what else. We could delete the player but that would
just crash. So maybe we restart the game with get_tree()-reload_current_scene(). But I don't know how to teach that to the
death animation without using another line. So it's either- or. And we go with restarting. And I guess thats all we get out of 10 lines. There are some things missing of course, especially
the moonwalking skeletons are a thing. Do you have an idea how we can save a line? Let us know in the comment! Also let us and youtube know if you want more
video like this by pushing the like button.