Project Roguelike: Gameplay and Combat
Development of Windra's Endgame continues. I'll have to start making the battle animations at some point...
Gate of Providence v1.0.2 was also released on rpgmaker.net. It gained more views in 2 days than it did ever on itch.io, which has been up for several months now. I suppose that's expected as it was on the front page of RMN for a week.
In the meantime, I've also been working on my roguelike project. Last time, I shared a bit of the character customization options. In this post, we'll be looking at the combat system and general gameplay.
Project Roguelike Combat Demonstration
Here is a video demonstrating the combat / gameplay. Turn on captions to see a bit of commentary.
The game features some typical roguelike mechanics:
- Permadeath - You die and your character is gone for good.
- Randomized gameplay - Explore randomized dungeons, filled with monsters and items that are randomly placed within.
- Hunger System - Keep track of your Stamina (Hunger), if it drops to zero, you die.
- Turn-based Movement - Monsters only move/attack after you do.
- Item Management - Manage your items carefully, as they have weight and you may not be able to carry everything you find.
Some non-typical mechanics include:
- Buying Levelups - Defeat monsters for currency that can be used to shop for things or spent to level up stats. This lets a player be able to (theoretically) beat the game at level 1 or without killing any monsters.
- Gathering and Crafting - Find and cook meat. Mine ores, smelt them into ingots, upgrade your equipment. Forage for herbs, brew potions.
Because of these added mechanics, I've decided to forgo an identification system. Plus it's complicated to make in RPG Maker anyway.
Eventing the Combat System
The turn-based, on-map battle system shown in the video was made with the event system of RPG Maker VX Ace. Making it was not too difficult. It involved several common events that called each other:
- Global Turn
- Enemy Turn
- Player Attack
- Damage Calculation
- Process Enemy
- Respawn Enemy
The player gets the first action. They can choose to move, attack (Player Attack), or use an item. All of these trigger Enemy Turn at the end.
Enemy Turn then iterates through all the enemies on the map, running Process Enemy for each. If it is time for an enemy to respawn, Respawn Enemy is called, and a new enemy is placed on the map. In Process Enemy, the enemy will move around or towards the player, depending on distance. If the enemy is within range of attacking the player, it will attack, which calls Damage Calculation.
After all enemies have acted, Global Turn is called. This handles HP regeneration and stamina depletion, and increases the turn count by 1. Control is given back to the player once again.
Enemies are stored in
$game_variables (yes, as in the variables used by the event system) as arrays that will filled at spawn. An enemy Slime, for example, would be stored as [1,1,0,10,1,[0,0],1,3,5,4]. The parameters are [enemy_id, enemy_level, respawn, hp, attack_animation, [status_effect, duration], range, hit_rate, str, def]. Script calls can grab parameters from the database using
$data_enemies[id]. I store everything that is mutable in the array and use the script call for anything that isn't, like the name of the enemy. This allows for status effects like buffs to work properly.
Changing the enemy graphic dynamically turned out to be a pain. For some reason, it refuses to work if done in the spawn enemy event, but works if I make another call to it in another event. In the end, I settled for a workaround using event pages using HimeWorks' Page Conditions that ended up being a better solution! It still takes up event pages though, so I will need to watch out for the limit of 99.
To be Done Next
I still need to figure out how to randomize items completely. The items need to be distributed with weighted probabilities. I'll also need to fully conceptualize the crafting system. I'm thinking of splitting armor categories into Light/Medium/Heavy and have crafting materials that correspond to each category.
That's all for now. It's best to approach things piece by piece.