Devlog - Starting Enemies and Loot


There were a number of small problems with my last code, especially now that this engine has knockback negations & moving platforms. I've cleaned up some of the bugs. Here is a quick list of things that were changed:

Refined Ejection Code during Hurt State:

When the player is knocked into [o_solid] under various conditions, their body may get stuck inside the walls of the level. To solve this problem, the game will push players outside of those walls / provide players a means to escape. It doesn't happen if the player is surrounded on all sides by [o_solid], but that really shouldn't happen unless I've done something wrong.
Ordinarily, the player will simply be ejected out of the wall. However, if there is a crawl space, the player will be pushed into a location that will allow them to crouch and slide out.
Being hurt inside o_solid will typically eject the player.


Compatibility: Moving Platforms & Sliding

Ordinarily, when on a moving platform, the platform will "pull" the player along with it. When a player slides, that means the player can slide too fast and fall off, so I've updated the behavior depending on the moving platform's direction.
If platform is moving horizontally, it will no longer pull the player with it (as the slide should be fast enough to prevent players being left behind and falling off). 

Other Bug Fixes:

Fixed a bug on vertical moving platforms in which crouch "knockback negation" would result in players falling through the moving platform.
Fixed minor bugs where the player stun timer wasn't always behaving as expected.

---

New Features:

I've started work on two new features: loot pickup & enemy behavior.

Loot Pickup:

This system is how I will handle items that players can pick up, such as sub-weapons, food, upgrades, etc. Of course, we're not quite ready for that yet -- but it's good to have a start.
The player object will detect [o_collectible] (and all of its child objects) using a simple script called [scr_detect_loot_pickup], and run the relevant code based on what type of collectible was detected (such as increasing hp, money, etc).
The child objects inherits most of its code from the parent, but will have their own read-only values. For example, the [o_coin] object can have its value assigned via Variable Definitions. So the only actual code "written" within the coin itself are a few variables for the parent object & detection scripts to read and perform their own code with.
This script detects contact with all collectible objects, then runs code based on that object's name.
Coin Object inherits the parent code, but has additional unique code / variables for further use.


If I change the "value_", touching this coin increases the player's "global.player_xp" value by its assigned number. If I set "hasGravity_" to True, then the object will fall down (code that was written within the parent [o_collectible] object so all of the children can simply reference it).
This is pretty basic, but the code will need to evolve once we have sub-weapon objects. Still, I think I should consider that a goal for a distant future.
Collectible Objects can have toggle-able gravity, allowing some collectibles to float (like these coins).


Enemy Behavior:

We have three enemy behavior features as of current:
  • Activation via Trigger Zones / Proximity
  • Horizontal Movement (Behavior Script)
  • Gravity (Falling / Jumping)

These tools allow me to quickly set up enemy types, and the two we have now are: the basic wandering zombie and jumping corpse. The zombie walks in a single direction until they are blocked by a wall, then they turn around. The jumping corpse jumps towards the player. 
In In the past, some enemies would have similar behavior, resulting in a lot of duplicated code. For example, many enemies had logic that said "move right until blocked by a wall, then turn around." So I've turned that behavior into a script that can be plugged into any object. I don't think I can make all behavior logic work like this, but I'll do what I can to reduce repeat code so that enemies can have much cleaner state machines.
Zombie Logic. Notice the use of "scr_actor_move_wander" near the bottom.

Jumper Logic. Although more complex, notice how it also uses the same script near the bottom.


For instance, both "wandering" and "jumping" enemies are using this new script for moving called [scr_actor_move_wander], which has a few different arguments to adjust its quirks. Since this behavior is ultimately coming from the same script, however, any changes made to this script will affect both enemies. This way, the code blocks of each enemy can instead be focused on navigating their unique state machines.
Although both enemies use the same script, the arguments (see the true / falses) allow them to have slightly different behavior. For example: the zombie has no [ _floor_hsp ], so they fall straight down when airborne, but jumpers needs [ _floor_hsp ] to jump towards the player.  
This script will move objects and interact with the environment differently based on the assigned variables.


This code only handles horizontal movement, doesn't account for enemies that patrol space between two points, and may need further edits (or a bit of repeated code), but we do already have other functionality that I'm not yet using...
Like: [_floor_aware] can be set to True for crawling zombies (from the old demo), which walk back and forth without falling into gaps. We could turn off [_wall_aware] to allow enemies to move through walls, like the old bat / flying head enemies.
As with collectibles, enemies also have a parent / child relationship, with their own variables to better curate their unique identity (such as hp, damage, etc).

Trigger System:

I've also simplified the enemy activation code into a single re-usable script. If the enemy has a "trigger tag", then the logic will ignore their usual proximity-based activation conditions. 
When the player touches an [o_trigger_activate] object, the game's "global.trigger_tag" will update to match whatever value was assigned to that object. Then enemies with that same trigger tag value will immediately activate.
Right now, this feature is only added for enemies, but it should be used for more in the future.
This script activates the object calling it, such as enemies. Proximity can be assigned if not using a trigger tag.


---

What's Next:

We almost have enough system bits to have a basic playable game, even if its not as much as the previous demo had in its entirety. I'm not sure what's next on my agenda, but here's some of ideas of stuff I need to do in the future:
  • More Enemy Behavior Scripts (sine wave pattern, patrols)
  • Combat Features (player weapon attack, enemy hurt state damage detection)
  • Enemy Spawner (low priority, has prerequisites)
  • Fine-Tune Knockback (low priority)

Don't forget to eat & sleep.