Crusader: Action RPG inspired by Vampire Survivors
-
Crusader
download code: 1C233MND5G
Formerly known as "Grave Danger" from the Fuze Halloween 2023 Game Jam.
This a demo for an Action RPG inspired by games like Vampire Survivors.
I've been adding features to the game to help set it apart from being another Vampire Survivors clone. I've added NPCs, buying and selling items in your inventory, traveling to different areas, and even sections that switch to 2D Platforming style gameplay.Leveling up system is more based on increasing player stats than upgrading weapons like in vampire survivors. I plan on working on it more and adding more kinds of stats to level up for your character. I also want to add different characters to play as.
I've just finished not only adding a main menu but also finally got the game to loop back to it after getting a game over, so now the game can be replayed without having to restart it.
I'm hoping to keep adding more to it. Currently there's just three different areas to travel to:
small overworld, where you explore and travel to different areas. Also can find chests to unlock.
house, where you can talk to NPCs and shop.
caves, which shows off 2D platforming gameplay.I'm planning on having more areas to explore along with a story and main objective to complete other than surviving for as long as you can.
I've been meaning to make a page in the forums to share updates on the game with the Fuze community. I feel like it's at point where I can at least start showing off it's development. There's currently over 5000 lines of code and I plan on adding more to it and sharing updates as I go along.
Feel free to test it out and share any feedback here. My goal is to make the game good enough for the 'Made for Fuze' program. And get the game published on Nintendo's eShop!
I'll share more pictures as I continue to work on the game.
-
I haven't played Vampire Survivors, but this reminds me of some zombie apocalypse flash games from the 2000's.
My first run I made it to 11am with like 13 hp and so many enemies swarming me. Then I tried to duck into the caves and crashed. Line 1392, function len, variable does not exist: cw. The problem is you declare and define cw inside an if block, you need an else statement setting cw to an empty array.
You need a loading sequence, before the title screen and before you do most of your initialization (loading sprites, sounds, etc.) This could be a simple printf("Loading...") update() clear() at the very top of your code.
The title is very cool. It would be nice to have a little sound effect when switching menu elements.
You have a great concept for the intro sequence. I hope you come up with a great backstory and add it as scrolling text! I think the second screen, saying you will die on the 7th day, should have a different typeface. It would look really cool if the letters on that screen were dripping blood.
One important thing that wasn't clear to me is how far each enemy can reach, especially in the vertical direction. I'm not sure how to approach that problem, maybe a little effect sprite that shows the reach of the attack?
You have a problem with projectiles. It looks very weird to throw a dagger under the cave entrance or house and see it come out the other side. The daggers should stop at the house/cave entrance. I would split your trees into two sprites, one for the leaves and one for the trunk. Projectiles and flying books should go be drawn before the leaves but after the trunk.
I'm not a fan of the exclamation mark. Personally I prefer when games have a blinking icon of the button that needs to be pressed to interact with something.
Now speaking of difficulty. My second run, I made it to 4:05 pm just on the overworld. Day one. With all the curses it was taking five hits or more to down a single skeleton. And the screen was filled with enemies, to the point that I was constantly retreating to a corner and taking hits. The enemies walk right through the obstacles, too. I'm not sure if the agility, mind, body, speed, or attack attributes are implemented yet but they didn't seem to help me. The HP bonus and berries did increase my life, but I quickly ran out of trees. I think a pause action that shows your character sheet and what each stat does would be very helpful. I would also prefer a little downtime between waves and maybe a way to stave off or counteract the curses. It would be great if the shop sold berries that restock each wave or something. Right now it seems he only sells rings, and I already got one from the chest.
Speaking of the shop, I crashed when buying a life ring to replace my existing life ring. Line 3653, function shopMenu(), no element with name: removed. Per line 403, the item struct has an element named "remove" (no "d"). In a separate game, I sold all my items except the book and dagger, then bought all three rings. For the third ring I replaced the dagger. When I closed the shop interface the pictures of items from my inventory appeared on the rug behind the shopkeeper. I also tried speaking to the shopkeeper from the side, slightly above him, and the buy and sell buttons were drawn out of place.
As for code style, I took a quick glance and notice that you have a lot of really long functions. If that works for you, great! But if you're having trouble navigating the code, I recommend splitting those big functions into smaller ones. My rule of thumb is: one function per function. The principle is basically to do only one thing per function, so that you can look at a function and understand in one glance what it is doing and how it is done. If done right you should never have to waste time scrolling through a long function, trying to find the part where you implement certain logic.
For example, take the function spawnEnemies(). I might write it something like this,
/* argument map: mapData */ function spawnEnemies(ref map) int i if map.hasFixedSpawnPoints == TRUE then for i = 0 to map.numberOfSpawnPoints loop spawnEnemyFromPoint(map, i) repeat else for i = 0 to len(WAVES) loop trySpawnWave(map, i) repeat endif return void
So while the function is named spawnEnemies(), and the ultimate result of calling that function is to spawn enemies, it only takes one glance to understand this code is either looping over spawn points or waves. The actual spawning of an individual enemy is delegated to another function, and you can get there by pressing the 'R' button (by default) in the code editor.
-
@max_shen Thanks for the feedback!
I'll look into getting those errors fixed. Splitting the trees into two separate sprites might be hard because the tree sprites I'm using are setup to be just one full sprite. I'm working on adding more items too for the shop and chests. There's still alot I want to add to the game to make it a full experience and not just a short demo. But there's still some refining that needs to be done to the current code and gameplay for sure. I'll put the errors and improvements you suggested at the top of the list of what needs updating. Stay tuned!