Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Dawnforth (Devlog)

A topic by Qory created Apr 07, 2022 Views: 808 Replies: 18
Viewing posts 1 to 13
(3 edits) (+3)

Yo,

I'm hoping that keeping a log will help motivate me to finish one of my projects. This is my first semi-serious attempt at making a game, so I'm not expecting it to be breaking any new grounds. Having said that, I'm hoping that it'll be fun to make, fun to play, and maybe that I can get some worthwhile experience out of the deal.

Enough meandering, let's talk the game.

Description

Dawnforth is an endless runner/beat-em-up hybrid in which you control a shadowed humanoid named Larkspur and race across night-clad landscapes, defeating a gang of bounty-hunters out for your head. Players jump through settings like quaint 10-story rooftops, forested plateaus, expansive mineshafts, and more, thrashing and tossing enemies left-and-right in order to maintain their speed.

Gameplay

In each level, Dawnforth begins in a set landscape, then starts randomly choosing landscapes from a set of predetermined options to supply the player with more grounds to run and jump. After a set point, the level's boss will appear on its own introduction platform, in which gameplay for the level will resume as before, this time to facilitate the player chasing down and battling a more powerful enemy.

Your main weapon are your wingfists, a set of unattached satellites that morph between wings and giant hands that propel outwards to punch enemies. When Larkspur lands an attack with these, if an enemy is staggered, he can then grab them in the same wingfist. While he has an enemy grabbed, you can toss the enemy for a powerful ranged attack, or to gain a little bit of airtime by tossing them downwards and potentially chaining together combos by grabbing the others caught in the impact. When your wingfists are unencumbered, you can use them to flutter in the air and potentially save you from bottomless pits (at the cost of some speed, potentially getting you an offscreen death if you aren't careful), or guard to save yourself from certain enemy attacks.

Ideally, I'd like to be able to toss in a more refined combo system to expand on these (i.e. if a player that "lobs" a grabbed enemy forward leads into a guard, it instead changes to a cartwheel-like chop that also deflects attacks), but I should get the basics finished before expanding.

Development Tools

  • Unity (C#)
  • Mixcraft 8 (Lol I know nothing about music)

I'd like to start with traditional drawing for the art, then after that's finished trace it all in something like Paint.Net to give it a solid, bright outline similar to synthwave aesthetics.

Currently I'm the only developer/contributor on the project, and because it's a personal one I'd like it to stay that way.

Screenshots/Art

At this stage, all of the spritework are placeholders I spent, like, five seconds making. I'd rather have a functioning game before making it pretty.

Sorry for the lack of anything too in-depth here, but it's kind of tough to show stuff like "the buildings here are completely random" or "the enemy is grabbed" from screenshots alone. As I refine this, I'll edit this to include more substantial information.

I currently have the wingfist backend-logic separate because I haven't worked out the animator for it yet. That's going to be an upcoming milestone. Currently it just hangs out offscreen until it's ready - the red line beside the black stick figure is where the sprite would spawn for things like fluttering.


Concept Art/Animation References

Player Run Cycle

(In order to keep things simple, I'd like to mostly create sprites by just cropping some key frames over a set number of torsos. The character will be mostly a solid black with a white outline, so this should work.)


Wingfist

(I haven't drawn a set of frames for the flutter yet.)


To-Do/Upcoming Milestones:

  • Refine enemy attacking - Currently the enemy just casts a ray in front of them to see if the player is in front, then subtracts some health. I'm not a fan of this since it limits what I can do for their behavior, and makes visualizing changes to the logic difficult. I'd like to set it to spawn some effect that handles damage instead.
  • Movement restrictions - Currently there's nothing to stop a player from going left or right past the scrolling camera. The right side will need to be locked, but in a way that conserves a player's remaining momentum. A player should feel "held back" when facing the edge of the screen, not feel as though they're bumping into it. The left side also needs refinement - buildings despawn if the camera moves a certain distance away, which will kill a stationary player regardless, but there's nothing currently preventing a player from hanging out between this cutoff point and the leftside offscreen. This should be changed to a kill-timer. Upper movement should not be restricted. Lower movement has a set kill-point.
  • Animators for Larkspur and the wingfists - shouldn't be that high, but the wingfist animation plays into the next item, and this will be an exercise in making sure I have Larkspur's movement stats finished.
  • Grabbing finalization - "Grabbed" objects need to have some indication - currently it just stores some projectile with set properties, but no indication of what is actually grabbed. More importantly, there's no feedback for how far a player's "grasping" will actually grab enemies. 
  • Item spawns? - Currently spawns work off of some set points from certain buildings, in which a "swarm" is created from a select set of options. I'm reeeeaaaally regretting setting this up as-is, since it doesn't really save me that much cpu and makes setting up spawns a massive pain.
  • UI - Nothing major, but there is no information about how much of Larkspur's health remains. Need to get that changed.
  • Parallaxing? - This would let me do things like adding foreground indicators to warn players of certain intense obstacles (i.e. some kind of caution sign in a mineshaft level in order to signal a vast bottomless pit the player will need to either hover over or "down-throw" an enemy to cross). However, I don't want to toss too much into the frame-by-frame functionality of this game. I'm not a clean coder, and I'm working on a laptop from 2013. In terms of design it might also encourage me to rely too much on setup-payoff types of situations rather than letting the player get by on reflex, which could hamper the gameplay flow. idk. I'll debate this. Not going to do parallaxing except for backgrounds, which comes with the rest of the art/animations.
  • Enemy behavior/movement - Enemies should move around a bit, and have some primitive edge detection. This is not a higher priority as some of the other items, but will be necessary for boss behaviors.
  • Bosses/level transitions - Besides more complex enemy behaviors, bosses signal the end of a level, or the start of the ending sequence. I'll need to work on that.
  • Music and sounds - Currently the game is dead silent. I also need to learn how to make some crappy little tunes.
(1 edit)

I don't know how much to include in the updates here, so I'll just treat this as an abridged blog. Maybe someone will find value in a meandering dev's thought process, someone can yell at me for doing something silly, or if nothing else I can sanity-check myself to make sure I'm on the right path by explaining my train of thought.

The list I gave above will need to be reordered, but the first item is probably the best to start regardless since enemy logic is broad. I say "logic" instead of attacking since I'm changing my approach. Before, I was using a very basic mob class and slapping an attack function on it. The attack function just checked if a player was within a line and ran a damage check on them. That's silly, shallow for gameplay, and would introduce a lot of redundant checks further in development. I realized it could be better.

Now, the base enemy class checks five zones (two are mirrored sets) for the player on each designated "awareness" frame.

Per diagram in order of priority, (1) does not mirror, and is for determining if the player is above the enemy (so they can do things like dodge an expected downthrow or thrust upwards). (2) detects incoming players and signals to use some range-centric attack. (3) both determines if there is ground adjacent to the enemy for possible dodges, and/or performs some close-range action when the player is near enough WITH a height cap (to allow players to do things like divebomb enemies). The actual actions taken and distance for each check can vary, but this is the general design philosophy that I'd like to follow when writing how each enemy handles which zone. Heck, if can even be used for bosses.

To debug this, I tested by making an enemy "hop" whenever the player enters one of its ranges, height-dependent on the zone. This is so stupid looking that I'm keeping it in the game and using it somewhere.


(All of these are placeholder sprites lol. Also on the to-do list, find a decent way to capture screens without making the game fullscreen.)

In accordance with this, I'm holding off on make a general "damage" prefab since this should be handled as an attack with any visual flare added in the sprite. This also crosses off edge-detection, so it's really just a matter of standardizing the hurtbox generation.

Up next, I'd like to do the movement restrictions and "grab" refinement.

(10 edits) (+1)

Yeah, it's been long time, and in that span I realized just how bad of a programmer I am, and how that worked in my benefit.

Behold: almost a month of programming:

I self-deprive myself, but there's a lot going on behind-the-scenes here.

So I started working on the code fro grabbing, and realized that a lot of my existing content needed reworked.

With the post above, I had the wonderful idea to try to set the enemy class to base off of an abstract base class. This will work good for setting up different enemies to behave differently, but I messed up in not transferring all of the content from the prototype enemy over to the new class, including how health was handled.


(There's a lot of garbage in here that needs cleared, but the main ones are EnemyBase, Hopper (the enemy to the right), and EnemyBehavior (the prototype with health).

I transferred functionality, then realized while testing that Unity's GetComponent function doesn't like returning an inherited class if you specified the generic type to be its parent. Which meant one of two things: either leave the classes split and set EnemyBehavior to a better name and dedicate it to player->enemy interactions, or use some magic with reflection to try to find whatever type was attached to the enemy. The results of this split are shown in the gif - the enemy to the left has the EnemyBehavior shown off but no associated AI, and the one to the right has the Hopper class and not the EnemyBehavior (so it, effectively, has no health). Since there's no issue with having one or both on an object, this means that, besides enemies with a primitive AI, I can also add in things like static destructible obstacles (like a box that drops an an item) and "triggered" environmental hazards of a stage (such as falling rocks in a cavern or an erupting steam vent) that can't be defeated in combat.

The sideways enemy after the guy to the left gets hit is an entirely new item defined as a grab-able drop that inherits a defeat sprite from the enemy. For the sprite itself, I made a placeholder based off of a teenager with a katana he bought at a flea market, because that's pretty non-threatening. Normally, the dropped enemy disappears after it lands back on the ground, but I locked that behind a flag for now since I need to work on "grabbing." One of the functions of the game will be the ability to grasp enemies while they're in the air, then launch them either to the side for a more powerful ranged attack, or downward to thrust yourself into the air a little bit. (Can you tell there's a Klonoa influence here?) This being a non-enemy object is why the projectile "lingers" a bit when rubbing up against it, rather than registering as a hit and returning to the player, though I should add in a safeguard against that...

The projectile itself was largely fixed. The "lingering" after an attack is completely intentional - the grab function checks within a certain range of the projectile, so this allows the player to more easily grab anything hit by the damage radius of the attack, even if the character himself is outside of range (this is possible since the game is an endless runner (right now for testing I just have the level speed set to 0)). Grabbing can be done while "lingering" or  if the projectile isn't encumbered (attacking or holding onto something).

(Levelspeed 12. Look ma, no breaks! If you look over to the left of the red dot, you can see the player character respawning from dying a few times after the building he's on despawns, or just spawning over a pit (which needs fixed). I also haven't updated the building prefabs to use the new enemy type, but the spawns for those need reworked entirely anyway and those are placeholders regardless. Since I'm not working with scrolling yet, the player's speed doesn't update with the level, so this state is completely unplayable.)

From here, I need to work on actually transferring the grabable object over to the player's grasp, then working out "throwing" it (the functionality for launching it is there, but there's no way to "tie it" to the player's control as of now). Internally, the game recognizes already the downed object as something that can be grasped, but it doesn't quite know what to do with it, especially since I've only just now gotten the rigidbody for the character's projectile to work correctly. In other words: actually finish the stuff I wanted to get done since last update.

(1 edit)

Had around a week of downtime since last update. Not going to write that long since the gifs speak for themselves.

Enemy hit by projectile attack, downed corpse item recognized as grabable. Before corpse can despawn, it's grabbed and carried by the player, then thrown for a more powerful attack (would help if I can hit). Red line spawned from the enemy on the right is just a corpse item I hadn't set a sprite for. It despawns since it wasn't grabbed after a short amount of time.

Flutter move added. Since the character has wings, if he's not encumbered, he can flap around in midair (meant to save the player from awkward pits). There's no limit to the number of times he can do this, but it locks horizontal movement to a value scaling on level speed, so doing this indefinitely will kill the player from autoscrolling. As long as the player has an enemy in his grasp, the player cannot flutter. However, as soon as the enemy is thrown, he can resume.


Finally, HUD. Does HUD things. Track's the player's life (5 HP so far, but you can't see a breakdown since the only hazard is a pit that just does 10 damage) and resets on death. Basic things like that. Important thing is that I'm starting to actually design the character's face, and this lets me do something with the player moving offscreen to the left or above by placing some marker and death-timer (a la Smash Bros).

In other words, animations soon, but first I'd like to get inputs for combos at least roadmapped, add in some pause functionality, and menuing, in that order. I'd like to do something similar to fighting games where, after a brief moment from player input, the player is able to push some other button to modify an attack (i.e. pressing the Down key immediately after throwing will toss the enemy downward instead, or pressing guard after an unarmed attack will cause the player to spin their wings around in a damaging shield. Not those specifically, just the means to queue inputs).

(5 edits) (+1)

Update gif:

(Right-clickers, yes I am typing this at 3:44 am. The background is messed up since I screwed up the camera with some file and I suck at Unity's UI enough to not care about fixing it, so ignore that. You can also see some of the test objects that I just leave laying around in the scene.)

Quite a bit is going on here, but I'll keep this brief.

The first change you see is the pause. That's nothing major, just a pause screen that can get toggled. I some checks for it on the base function for enemy attacks, so hopefully I'll not need to mess with that again except for cutscenes/transitions.

The second thing, more worthy of an update-blog, is the downward throw after the second enemy is grabbed (it's set to such a much higher velocity, hence the choppy animation). I added in a very primitive combo management system into the game - if the game is unpaused, and the player presses an attack/action key (stressing that left/right and jump are not included, for reasons I'll get to in a moment), the input gets logged into a keypress queue. Each item in the keypress queue is tied to a timer that lasts around a fifth of a second. After this, the queue is checked to see if the first item is expired. If it is, the queue is stepped through. This way, the player has time to press a follow-up key before their move actually executes. ALTERNATIVELY, once it reaches the end of the queue, if the player is at some move that has potential children, they're given a little more time to add new inputs to the queue before executing. This way they have time to input longer combinations.

To demonstrate, let's say use the simple [Strike(A), down] move in the gif. When the first item in the queue expires, the items get cycled through. All combos in the game are stored in a tree-node structure, beginning with a blank-input item that steps through children by the input key in the next queue item. The initial item, of course, has every key mapped, but for the children downwards, each of them has a moveID, and (possibly) children mapped to a follow-up input. So, the queue here goes from [start] to [horizontal strike]. If the next queue item is the down arrow (or S), then the returned move will be the [downward throw]. Otherwise, the [horizontal strike] is returned as the active move. Because of this, I can't do anything with left, right, and jump since it isn't fair to have a player screw up a combo by readjusting themselves in midair for an endless runner. On the other hand, I can easily map moves inputs without much effort, add them to the player's arsenal (making an unlock system), and even tie the same move to multiple input combinations, so I'm happy with the tradeoff. The main downside is that I cut myself off from doing complex followups for specific moves, so this is less "combo" and more "complex single-strikes," but whatever.

Once the player gets an active move that's actually a defined move (as opposed to up/down which just eats the input and moves onto the rest of the queue next frame), the move is executed, the queue-addition is locked for the attack duration, and the queue is cleared after the attack is finished. Hypothetically, this could be changed to include a follow-up move tree for complex multi-chain combos or whatever, but that's not what I want to do with this game.


A lot of the game base is close to completion now. That leaves only a few follow-ups: pickups, reworking object/platform spawning as the camera scrolls, external menuing and level transitioning, and animation/sounds. In that order, since doing animations start the official look of the game (that's why I've been mentioning it so often despite not having any plans for it - it marks the actual start of development).

EDIT (not worth separate post):

Turns out menus, powerups, and scene transitions aren't that difficult, so rather than just make an update that's just "the basics of a menu are made adding more later," I'd like to put some very specific goals here to come back to:

Edits as I do them preceded with an asterisk.

-Pickups

--Healing item (*Works, I think. I need to finish the training room's missile launcher so I have something that can damage the player without killing them.)

--Invincibility item

--Extra life(?)

--Damage-up (rework how damage is done, and limit this powerup to tier 1 stages)

-Menuing:

--(All) Options (volume for sounds, volume for music, cutscene mode (arcade/cinematic ; cutscenes minimal, or enabled with dialogue))

--(Main) Level Select (add in dynamic level loading) (*Works, but I don't like the UI for it so far. Need to change to a scroll-down list with a preview screen to the right. This isn't a high priority.)

--(Ingame) Combo List (build a list of all combos the player has access to. TODO: names each move the player has for IDs above 0) (*Horizontal Strike and Downward Throw name added, but no other important moves have been added so far.)

--Remember to pause/unpause timers correctly for scene transitions

-Levels:

--Set speed tiers (0-3)

--Practice Room (0): Very basic area enclosed off. Speed tier 0 (stationary). Only things there are a master-control computer (quits the scene if the player enters the far-range, aka leaves the room), provides a wall for other purposes, and drops a box if the player enters a certain range. Retain in final game for players to mess around in. (*Missile spawning instead of a box at the moment, to test damage. Missile needs finished before getting set to a prefab; will add this in addition to the box spawn.)

--Practice Rooftops (-): Like Practice Room, but with the speed tiered at 1 (5). Cut this off from player access - debug only for testing mobile objects

--Level-end move: If the player is above ground, grab all powerups, then slam down and immediately delete all enemies. Afterwards, the player's input is cleared and the game pseudo-paused.

(+1)

I'm back from my break.

Pretty much a lot of the outlined edits here, so I'll just briefly list what's been added. Also the gizmos are visible, in all their naked glory.

Foremost, the main menu. Nothing special - just a blank screen. with buttons. I like the lavender-purple-aqua color scheming that this is turning into. Play button goes to the first stage, which in this case is the practice room. Immediately afterwards, unpause and quit back. Second time around, there's a minor glitch in that the pause screen immediately shows since the stage never unpaused from last time. The missiles are allowed to hit the player, lowering their health (the detection on them is screwy - I tried box drawing where they're hitting, but apparently that isn't entirely working with the ranges they have - that's a fix for later. The second one will go and delete after hitting the wall to the left if it's allowed, but I didn't do that because I wanted to show the a second hit. After this, I went ahead and launched the fist towards the powerup. 

The powerup base classes all pretty much work the same, they have some set modifiers for what they boost, and a duration. This one heals 5 health (the player has 5 total) and increases the player's movement speed for a set duration. After this, I just jump into the pit and die. Bit of pause-schenanigans, then back to menu. The attack-power increase is getting shelved, so besides health and mobility, there's pretty much only "shielding" left for now.

Where to from here? Well, crap. Guess I need to start adding in sound and that combo-list I put off. Nothing major for the sound, just listeners for various events. Need to fix those missiles as well so that they can be set into a prefab to launch on-demand in the training room. Guarding needs made. Then the practice rooftops need made.

Yeah, I haven't worked on this in a while. Had issues with my internet, then I needed to reset my computer (I backed up everything, but still needed a few good days to reinstall everything), then I got sidetracked to rework a few D&D areas to stat out some NPCs for combat that I didn't think my party would be dumb enough to attack, then, last week, got COVID and needed a few good days to just sit in a bubble bath.

Anyway, what've I got to show for it?

 

Missile spawner works. The gray sphere is from me leaving gizmos on while a grabable is active. You can see me messing around with trying to spawn missiles overtop a thrown one just to mess with everything. There's also a weird glitch with some of them where an encumbered "corpse" lingers over the fist instead of being thrown, but as long as this doesn't stop the player from being able to attack I'm fine with it. Submenu works for loading available moves. Clicking that just brings up a description of the specific move. It would be scrollable, but there's nothing unlocked yet. No clue what's with the spacing on the left not cooperating.

(11 edits) (+1)

Took a break between posting on this. Worked on some offline projects (decorations and all that jazz), spent my weekends barhopping, and, more relevantly, worked on this in increments.

Progress notes:

Hey, look, it's starting to look like a game. A crappy game, but a game. I'm getting nauseous looking at that frame rate. Definitely need to rework the Update crap.

-Redid building spawning since that was a pain.

-Added borders for camera play to both hide a shortcoming in my logic (buildings visibly "pop into" existence visibly from the right edge, and I can't be arsed to mess with my offsets anymore), and give levels a bit of fluff (could add stuff like boss info later, and move the health bar into it, since currently the layout is screwy when it goes into fullscreen. I'd like to keep this game windowed, but that just highlights a shortcoming).

-Animation handler with some very crude sprites of what I want the character to look like (I'm not an animator, so forgive the crappy run cycle). No arms in sprite yet since I want those separate to denote player's move availability (i.e. arms outwards in a guard signal that they can't attack, arms "grasping" an enemy signals that they can't flutter-jump, close-to-torso means they're damaged, etc). Nothing for the mall-ninjas (I'm sticking with that since it's funny) yet since they don't have proper attack logic.

-Prefabs for two buildings, one with enemies, one without.

-Sounds added for player death.

Concerns/To-Do:

-Player is slow right now, even for a first level.  Make faster. ✓ (Level speed constants increased.)

-Fix bordering not appearing over enemies, and integrate UI into it so that it doesn't poop the bed when going fullscreen. Add in portraits of player and stage info on side. ✓ (Right border is now also the functioning border for gameplay. Left still allows slack. Note to self: add death timer.)

-While at it for the above two, scale player and enemies down a bit so that they can see what's coming for faster stages ✓ (Transform values)

-Fix initial building spawns. Stabilizes after a few, but at the first few within a stage, they 'smash together.' ✓ (Added in placeholder "ghost" buildings to occupy first slots. Whether or not they mesh is irrelevant. Sidesteps problem, and allows for scripting-object holders as potential building-spawns.)

-Add in a level of variance for how high a building can spawn (currently sets at a hard Y value - set this current value as the cap with some able to spawn lower in order to make more fun gameplay) ✓ (1.5 allows a nice variance.)

-Spawnings: Make player unable to push enemies off building. Add in breakable boxes. Have throwable corpse scale to sprite. ✓ (Boxes are the only thing I haven't done yet, but I'm not too worried since that's just an enemy without attacks at this point. I can handle them when adding Wingfist animations. More importantly, somehow changing the localscale somehow FUCKING CAUSED THE CORPSES TO DISAPPEAR FROM EXISTENCE. LIKE, HOW IN THE FUCK DOES THIS SHIT OF "ADDING INCONSEQUENTIAL LINES BREAKS EVERYTHING" KEEP HAPPENING. CHRIST ON A BIKE, IT'S LITERALLY JUST SETTING A LOCALSCALE. FUCK. <- Entirely my bad from setting an item on the lefthand side of the screen as the "border" for the right.)

-Two mall-ninja variants: standard (momentarily swings sword when player is in range), "hopper" (prepares a strike when player gets within "far distance," jumps up when player gets "near distance", swings and hurts with sword on way down) (Hurtbox instantiation works now. Thank goodness. Secondary global class is responsible for such. Now need to make sprites.) (Half-complete with this. The second enemy type works as intended (jumps, then cleaves as it falls). Need to redo how randomized spawning per building segment works, because that's an even bigger mess than the below.)

-Redo several logic portions to use FixedUpdate instead of regular update, now that we have fixed scrolling (NOTE TO SELF: Only do this for positioning-related (player set pos, death checks, etc.) Too much can go wrong. Save a backup before working on ANY class that uses this.)

-Just fix everything with the update because that cork board is still a fucking mess and it's doing way too much on each frame. (Global loadedlevel pretty much handles most of this. Only ambiguity is how much of it is focused on the camera object. Focus on its role after cleanup from above point. For now, I think I have everything diagrammed:

LoadedLevel - Handles loaded level properties (expected boss, possible building spawns, possible enemies, etc) and behind-the-scenes management (hiding/showing pause elements, transitions, etc). Bound on a self-destructive class run on first frame since instantiation is otherwise wonky.

CameraHandler - Ties the player to the LoadedLevel (sets movement speed, loads building spawns, checks if player's fallen behind, etc. Internally referenced as "GM," which I think is apt: D&D-wise this is the GM, LoadedLevel is the notes.

globals - Static functions. Internally stores LoadedLevel to allow anything to reference its properties (i.e. setting pause elements) or do some meta-function (loading/unloading parts of a level after a stage clear, etc)

Shouldn't be too complacent with how the Updates handle everything, but for now everything is around 30. Yeah, some nerds are going to hate me saying "good enough" here, but, fuggetaboutit, I'm not looking to make this a hyper-polished AAA title, and 30 really doesn't bother me. It's my first game, it's for me to learn and to make gameplay fun, not to fulfill any high expectations, especially my own with "have shit work when I write it." And I'm not fucking with it right now if setting a transform scale somehow fucks my shit up. Really most of the cleanup at this point is removing the Debug.Log shit.)

-CONSIDER BUYING A NEW COMPUTER RATHER THAN THIS TEN YEAR OLD LAPTOP.

-First boss: "Neromo, the Unbound Girl" - Jet-augmented youth who stays in the same Y-axis. Phase 1 launches a missile at regular range against the player with a slight height variance (can be dodged by just not jumping). Phase 2 opens up 3 "missile lanes." Shoots one in each of them per cycle, the order varies. Less variance on the height. Pitch: 4 lanes instead. Sets boss structure (Phase 1: full-60% health. Phase 2: 60% to 10%. Pitch: 10%-defeat. Good gameplay can skip the pitch, but Phase 2 always gets hit if the boss is at Phase 1 (use the damage function for determining).

(5 edits) (+1)

Holidays are a timesink.

Gave no craps about just plopping the boss in. Prototype sprites are prototypes.

Frontend update notes:

Enemies mostly have fixed collision. Player can pass through them, and they can pass through each other. Minor glitch with hitboxes "bumping" into a player, but I actually like it that way since I can add an effect to let the player know where they were hit.

Enemy corpse impact affects other enemies now - chain reactions possible.

"Jumping mall ninja" coded. Unlike the other one,  this one actually has an attack.

First boss has primitive pattern - occasionally fires at the player (the exact time delay is determined by the distance check). Fires one during phase 1, three for phase 2, and four for phase 3. Phase 3 ("pitch") is impossible to access at the current health - functionality is added for potential rematch. Skips phase 2 in this gif because of a glitch (see below). At set intervals, she'll warp to one of three locations to shake things up a bit.

Behind the scenes updates:

First part of cleanup underway as the game's identity is forming. 


Really doesn't seem like a lot, but the .vs folder autocreated is taking up 296 KB (303,328 bytes) (Disk:) 304 KB (311,296 bytes), and this was just cleaning up a lot of debug code that I'm finished with. I'll take the, what, 15% reduction. Small victories.

The other main thing here is that throwables and grabables are pretty stable, and an expansion of globals is letting me make a f#(\<ing hurtbox without causing all of my project to somehow break.

To-Do:

Left boundary - Player should have an arrow appear over them when they cross the left border, along with a countdown timer spawning. When that timer reaches zero, the player dies.

Timer revisions - This one is going to be a doozy. One of the most rudimentary classes I coded is called "lockTimer." It stores a token, and a comparison value to be checked against the Unity's deltaTimer. Deceptively simple. The problem is that it inherits from monobehavior. In other words, for every timer, I have a bunch of Update functions everywhere. In my player and wingfist classes combined, I have 11 of those things. A lot of my prior headaches also came from these timers also being somehow called before they had everything set (which beat the purpose of me deriving them from monobehavior in the first place). There's no reason why I can't have lockTimer instead keep an enumeration of possible values (with appropriate labels) to save update functions and better manage null references. For my player/wingfist, I can turn that 11 into 2! Probably will end up saving, like, 1fps after setting everything (some of the jitter comes from gifcam, but then again I did say 30fps was good enough so it's mostly my fault lol), and I'm still not going to be anal about optimizing performance yet, but this will probably save me a lot of headaches later. I spend a lot of time discussing this because this rewrite is where a bulk of my focus is going to be.

Repeat-strike glitch - Under certain circumstances, the thrown enemy does not disappear after hitting another. This makes it possible to kill bosses with a single attack. Fix this!

Cleanup part 2 - Remove defunct class types, and physically map out each function/prefab. Consider cutting single-use 1-line functions.

Increase thrown enemy speed - Too slow right now.

Fix swarm spawning to space enemies out - previously used the natural collision to shove everything around. Can't do that anymore.

Boss HP visibility, spawn, despawn, and transition - self-explanatory.

Glint - Add in an effect whenever an enemy/thrownenemy hits something to signal feedback to the player

Fix audio manager

Add in a first-draft sprite for both wingfists - I'm sick of looking at a white circle!

ENDGOAL:

Have level 1 in a playable state from start to finish.

Sidenote: I think I like this frontend/backend/todo/endgoal format. Probably going to stick to it in the future. Also, since this is starting to turn into a bit of a necroposting thread, I'll look into getting something more proper set up in the developer logs. I just want to actually have a game to devlog about first.

(3 edits)

Important aside: Reflecting on playtesting so far, there’s a glaring problem in that there’s no penalty for dying. A lot of people view lives as outdated, but not having a hard reset point means that the short length of this game will be glaring, since players would just brute force the game.

Thus, the working solution for now is a credit system. Copypasted from my code comments: (This also means I’m implementing a score system)

This works as a happy medium between the two; players that endlessly die are punished, but not barred from continuing play, just the final level (think something like how Touhou manages continues).

Besides solving the player-punishment problem, this allows me to introduce a “speed up” ability that I was originally planning on as a stage gimmick, except as a dedicated unlockable mechanic to both reward riskier play and make repeated playthroughs quicker (plus if they mastered the later levels, they can just p***take the earlier ones, since credits don’t dip into the negatives).

Most importantly, in order to mitigate scope creep and make scaling credit spending feasible, this decision gives me a definitive stage quantity. I can now roadmap updates based on some definitive theme/goal (similar to how this one is the “stage 1 playable” goal, next one can be the “UI feedback” update or similar). I have a rough roadmap for this planned, but I won’t dump it until the next post.

Unfortunately, I can’t fully implement this system yet until level transitions are finalized, but I can start doing things like adding in distance-based and boss-credits.

Note to self for later: 1 2 3 4 5 6 2 2 3 4 5 6 6 3 3 3 5 5 5

(+1)

I like this. It's surreal platforming. The speed and quality of movement is good, reminiscent of Kid Icarus.

(+1)

Thank you!

(5 edits)

Posting at early-early morning. Forgive typos.

Update:

Complete level 1 base. Forgive lossy-quality, had to compress in order to save size due to length.

Front-end:

Fixed-spawns for building lineup in order to trigger specific set pieces/level updaters. The crappy water tower and billboard there demonstrate this. (Sidenote, billboard: I like the idea of the antagonists being extreme body-modders since that means a bunch of silly designs like “girl with jet wings” and “breakdancer with detachable legs” in some setting where that’s just a thing people can do, with the main character being a natural anomaly that’s under bounty from people who want to dissect him. Doesn’t need to be deep, this is arcade-style play. The billboard is just a crappy little logo for the company that placed the bounty.)

Prior milestones hit: Arrow with player-kill indicator when they go offscreen for too long. “Glint” effect when hit by enemy and when thrown enemy hits. Wingfist sprites.

Run speed fixed to match level by default.

Neroma’s throwable (I’m going to stop calling them ‘corpses’ since it implies that you’re killing all of these people in-story, and I don’t call them that in-code anyway) now triggers the level-end functionality when it despawns (allowing the player to do things like just let her fall, throw her into a goon for a little extra points, etc). Resets the player’s position and freezes them in place relative to the screen, but since I don’t have a level-end screen proper it just boots them to the menu immediately with nothing else. Throwable is colored differently just to match closer to some concept art I’m starting to settle on (going with “of course the boss of the mall ninjas is a plump emo girl.” Chubby girls are fun. Bite me.)

Backend Updates:

Timers overhauled. Managing them for smaller classes is now a bit more annoying, but now I don’t have to type the instantiation of 800 different variables on each startup.

Animator set up for first wingfist with some stand-in sprites. Default wing size is too large for my liking, but might keep it if it means clearer communication to the player about their status.

Credits are added along with score and “score banking” (see below), but this isn’t relayed to the player yet.

Boss flag tied to health class; triggers level-end as described above when a boss is defeated. A boss, not a designated boss. More of a note-to-self thing for later.

A bunch of other misc backend tracking to make the next parts easier.

To-Do:

Boss i-frames/“pierce”: Right now the boss doesn’t stagger when hit. Besides making attacking weird, this means that the player can just whale on them as shown in the gif by punching them. Change this to give them a temporary defense buff, but said buff can be pierced by attacks with a designated “pierce” value set (throwing enemies should have this set to 1, punches 0).

UI: Main goal of next update.

-[s]Player score should be visible on the left-hand side of screen. Credits should either be shown by this score, or below health.[/s] Done, although the 20000 reset isn’t conveyed to the player. Consider revising this.

-[s]Optional combo-helper (logs current move inputs to demonstrate how to input them) on left side of screen. Beside this in the options should be an ability to modify combo input window (more: more forgiving combo inputs, but more time until execution. less: stricter time limits, but snappier moves)[/s] Mostly done. The ability to make it optional hasn’t been added since this means overhauling the options screen. In terms of the delay change and combo logging, though, this works.

-[s]Progress-to-boss should be shown on the right. After ‘boost flight’ is unlocked, percentage should be shown of how far the player’s flown (can worry about this part later, just account for space).[/s] Boost percentage isn’t implemented yet. Will probably save that for the update for boost flight.

-Boss health bar: did not get around to this since it seemed more fitting to group here with the rest of the stuff.

-[s]Consider redoing health bar position.[/s] It’s not any worse than any of the other HUD clutter. This is kind of a pain that’s going to need fixed in a polish update.

[s]GUI anchoring to allow for resizing: Putting this at its own item since it’s going to be the biggest backend problem, since the borders on the screen actually serve a purpose for tracking level objects, but the UI should still utilize them.[/s] Not doing this. After thinking over what I want to do for art, I want to try to lift a page from how the Genesis renders sprites in terms of art direction, and tweak it a bit so it’s not just another “retro but not really” game. To this end, I think having a fixed resolution is for the best, although I’m NOT happy with what it’s currently set to.

End of level screen and transition: Tally and bank score, credits addition feedback, give option to buy checkpoint, then transition level. All the while the level “freezes.” Credits, banked-score, and checkpoint progress should all transfer between scenes. (Sidenote, “Banking credits:” Whenever a player gets 10,000 points at this level, they’ve given another credit. At the end of a level, any remainder points are added to the bank. Then the game converts every 10000 banked points into another credit, and the new remainder becomes the balance. In addition to this, the player should start their next level with a score equal to their new balance. This balance resets after a player quits.)

Endgoal: UI feedback and level end screen. Go from “functional level” to “fundamental scene template.”

EDIT: It might seem like I’m putting a lot of crap off until later, and that’s because I am. I do NOT want to spend that much more time on level 1 playing around with cosmetics instead of getting the rest of the game actually MADE!

(8 edits)

Milestone roadmap:

*-Stage 1 start-end (Finished)

*–UI (Functional displays)

*-Stage 2 start-end

*–Transitions and menu re-functionality (Main: Level select, start. Shared: options)

*-Stage 3 start-end

*–Challenge Mode implementation and moves 1 (unlocked after beating stages 1-3):

–(start) Drop (↓ -> ↓; Drops Larkspur down rapidly)

–(1) Spiral Slash (↑ -> Attack or vice-versa; strikes a short range behind and in front of player when unencumbered) EDIT: Changed to make dash gliding more fun. New attack: Uprising Strike (Puts the wingfist in front of the player as they’re thrust upwards. Pierce-damages if an enemy is encumbered).

–(2) Dash Glide (Shift; increases Larkspur and level scroll speed. Enables Challenge credits)

–(2) Drop Kick (Attack -> Attack; launches two strikes if unencumbered, or hurls all grabbed enemies at a massive pace. Deals piercing damage) EDIT: Changed for simplicity. New attack: Kick Launch (Launches a single piercing strike at high speed if unencumbered. Otherwise launches the first thrown enemy at high speeds, and tosses the rest at a slightly lower speed that ‘shotguns’).

–(3) Banishing Wing (Guard -> Attack; Circular short-ranged attack that shields player)

*-Stage 4 start-end

*–Save/Load and practice-room fixing

*-Stage 5 start-end

*–Sound overhaul and moves 2 (Stages 4-6):

–(4) Gatling Dance (↓ -> ↑ -> Attack; When encumbered, shoots Larkspur straight into the air at a rapid pace until he reaches the ceiling. For each point of health on each enemy found horizontally in front of him, Larkspur launches a held item at a rapid pace, starting from the bottom)

–(5) Bewitched Pull (Attack -> Guard -> ↓; When unencombered, pulls all non-boss enemies down. Any previously on the ground are damaged)

–(6) Regnant Cannon (Attack -> Attack -> Attack; When encumbered, launches a projectile that deals damage equal to twice the number of grabbed objects)

*-Stage 6 start-end

*–Parralaxing, and UI cleanup/resolution

*-Stage 7 start-end

*–Graphical overhaul and cutscene establishment

*-Polish/Complete playtest

*-Publish

Two gifs to not put up with that stupid compression dance from before, even though gifcam still makes it a bit choppy. Oh well.


Main menu -> First stage.


First stage end -> End level screen -> Main menu.

Front end/backend (interjoined because UI):

Pretty much all of the UI updates outline above. Not too crazy about the layout, but everything's slapped into a prefab, so I can touch up that later. Boss health bar appears with player as well.

No load screens yet to hide some of the initializations between scenes.

Options right now has an attack slider to control lag between an input starting and its execution. Default it's at .2 (what you see in the first gif. Changed it before the second to show off the change to show a more delayed one and how easier it is to pull off combo inputs, then changed it back to .1 and whaled on the enemy.

The boss's health bar looks a bit inconsistent at first glance, but there's a bit of logic to it. Thrown enemies carry a "pierce" flag that gets around i-frames. Normal punches do not. So, if you stock up on enemies to throw, you can throw them in succession to quickly deal a lot of damage (in the future, your options will be expanded upon to also be able to do a few other moves, but that's for later)

The screen transition really isn't that big of a deal. If a move is available to be learned, the player will get a prompt (similar to Mega Man's weapon get screens), but since none are available right now, this just ends. At the screen, the player gets the option to buy the next open stage for level select (after they buy the ability to select levels; players can't buy levels higher than their current). The portrait also has a little flair in that it changes poses depending on the difference in credits a player has - if a player has 2 or more credits than they entered the stage with, the portrait switches to a more cocky art. 2 or less, and it's careful. You're seeing a neutral one right now because from level 1, it's currently impossible to get 2 or more credits through gameplay unless you grind during the boss fight (you see two on the buy screen because I left in a line adding 1 after this check is made in order to test the menu). (Also, portraits are placeholder, though this is the design I want to use for the character, even if I did screw up the eyes).

The level select being access to the practice room is a remnant from the older main menu version. I'll need to fix this to be a separate menu choice altogether.

TO-DO:

-Create a second level (transit complex) using the first as a template.

--Three hostile enemy types, a passive threat, and one boss (placeholder until basis established)

--Six platform types: three fixed, three random

Also...

--Add character's arms and second wing in

Forgot to actually specify that as a thing needed done and didn't think about it until after I put the portrait in. -_-

(6 edits)

Intermediate update to show I'm not dead, and since "make level 2" is a bit ambitious of an update goal.

Level 2. Issues with the UI not being properly laid out, and not having good overlays that separate each element are very apparent here.

Level theme is going to be primarily an Amtrack-like train running through a shopping plaza (it'll be more apparent once I start working on backgrounds). Kinda like Tower City, except with a color scheme like out of the 1920s. Enemies: Placeholder sprites are placeholder (lol they're just the old enemy placeholder sprites from before). Enemies this time around are going to be parkour/dancers that jump at you from the sides, either on scenery or from the spawned rails. I think it's funny to have the mall ninjas be the enemies on the rooftops and the parkour freaks be enemies in the mall. Since the last batch only really had the "Hoppers" that test you dodging by weaving under/around a threat, these ones teach you about going over/under. "Railspinners" (the mobs with the poles) don't spawn after the boss threshold is met. They're pretty much set as far as behavior is concerned. I think I forgot to give them health. The "kickflippers" (the other ones) are majorly broken right now. I screwed up their player detection. The idea is that they lunge towards you, similar to the Railspinners, except instead of always being a threat, they only activate their attack after they get very close to you, then spin backwards and into the air to try and nail you for carelessly running forward. They can linger after this attack, that's fine, but I overlooked adding in a "reset" for after they ground once they've made their attack, and them spawning multiple hurtboxes is just a major oversight for more reasons than just being able to tear the player apart (there's one part in the gif where you can see two of them just juggle the player). Should probably remove the rotation altogether since that's a bit ugly.

Building spawns are completely busted. I screwed a bit with adding in an alternate way to randomize everything other than Unity's default random function, since I was unhappy with how many times it was just giving me lowrolls (read: ~70% or smth of building spawned were just the first option, and spawns followed a similarly bad odds (BO-RING!)). The chaos at the beginning is not going to survive into the final game, at least not this early into the level, since the only reason it's there is because of a screwup with building spawns. That's going to be my primary focus for the next bit of dev work, with kickflippers being second. Reason being that after I get that finished, since I have a lot of this initialization crap fresh in my mind, I'm going to just get placeholders made for the other 5 stages, since scene templating was a bust, and I have some notes nearby for how to actually re-tie the prefabs together. Next update will be proper.

Lastly, I know I mentioned that I was going to fix the spawning spacing issues, but, honestly, I don't really need to at this point. More spacing around a spawn point doesn't make it much less boring. Why spawn 1-3 enemies around 1 spawn point for each one, when I can change each building to have 3 spawn points that each spawn 0-1 enemies? Save me some work, and help diversify the placements a little better. The "robust" answer would be to have each spawn point become a spawn "range" or sorts, but honestly that seems like overkill for this type of thing.

Level 2 is in a playable state.

Brief display of some more hectic spawning. Seems like it's all-or-nothing with the way these work. Fixed segments (the pillar buildings with the pink 'dropslashers' need more spacing in order to not "pop in." Also have an annoying glitch with the one railspinner (grayshirt) not shooting off. Don't know what I'm doing with the sprite on that one; sweater and khakis just doesn't seem fitting. Need to go full emo instead. Kickflippers (green shirt blue hair) are as harassing as I expect, will probably reuse them for a later level.

Snippet of boss fight against 'Davus.' Didn't realize that GifCam wasn't recording when I did most of the fight. AI is a combination of both enemies, basically. He starts out idle, then when the player gets to close, he attacks. When he attacks, he moves to the left, then when the player gets within his 'near detection,' he starts moving back to the right and launches knife-looking projectiles for a very short duration, then sets a recalibration point to the right of camera. When he gets to that recalibration point, he gets the player's expected y position at the far-read trigger, and moves up/down accordingly (I have code for spawning a rail object when he does this so it looks like he's sliding up/down it, but I'm not worried about adding it back in). If the player moves too far ahead, he shoots to the right more rapidly.

This can be a pain, especially with the kickflippers harassing you when you jump over his attack, which, due to the rapid nature of it also keeps him under you, but it's nothing that can't be managed. Railspinners are set to not spawn when Davus is out. 

I'm just going to vary some of the spawn points a little more and start working on the next milestone, since I'm getting tired of looking at green, and I really want to get to "the Furnace."

TODO:

-Screen transitions (enter level, exit level, intermediary, exit to menu)

-Rework in-game menu

-Rework main menu and level select

-Rework timing for button inputs to make three-button combos more forgiving with default setup.

Endgoal:

Be able to transition a player through the first half of the main game without awkward 'jutting,' as well as utilize what they unlock within.

Very important update.


Foremost, in terms of control, combo input rework.

In the options, I set the attack delay to a full .5. You can see the delay with the first input after the unpause. This is normal. The updates come from a special bit with the input logging. For a while, potential moves are logged with a recursive comboTree class that logs an input key, children for next combos, a moveID, and lifetime for the move input

Here's a crude diagram of what's set during level 1 (not counting the shield key tree).


Any check against inputs starts at the base of the tree, then, for each key entered in the input queue, moves down a slot if it's available. If there isn't anything, then return the selected ID, and execute the move associated with it. Before, I was (stupidly) just leaving it up to the expiration timer, which meant that if you did something like continually press attack over and over, you wouldn't actually attack until the entire queue was ready. "Why wait on something if the queue is ready?" This behavior was altered to split the lookup into a more simple function that gets called in the input and timer expiration. Now, whenever you press a key, one of three things happens: (1) if the move in the input tree has potential children the player could execute, wait a delay before executing, (2) it's the last key of a branch, and immediately executes that next move, and (3) if the pressed key does not have any associated moves 'down the branches,' execute the current one. All three are in display in the gif in order after unpause (I pressed up on the third one to get it to attack immediately).

Second important update, level transitions:


The coroutine is a bust for now. It was working fine a moment ago, but then I got smart and added in some checks to the fade to black, and suddenly it wants to shutter now. I'll need to get that sorted out. The important thing here is that all levels are mapped (I'm not going through the full display right now) with their place in the build order and 'next' selection, and basically just need to be 'filled in' with enemies, bosses, and platforms in order to be functional.

After buying, the player is able to buy into the level select now. Fading to black in order to access the end-of-level screen nets a credit, beating a boss gets another. I think I'll leave the test-credit in there since buying stage 1 after beating it makes more sense than beating two levels to get the privilege of starting at the first.

Haven't really messed with any options yet since there's nothing to customize. Hating the way these placeholder menus look.

To-do:

-Level 3

--Enemies (3)

--Platforms (3)

--Boss

-Rework platform spawning to be more randomized (hating how many sections repeat)

Endgoal:

Playable level 3 with substantial platform variety.

(4 edits)

Holy crap it's been a while since I posted on this. I shook up my schedule a bit (got a tablet that I want to do art on, and worked mostly without incremental updates) I think I want to do every other week switching between gamedev to working on a comic.

Anyway, Level 3 is mostly playable from start to end.

Theming is going to be an underground excavation site for some fossils before they're fully destroyed by subterranean heat, hence the roof. Obligatory lava level is obligatory.

The longer I go on, the less I care about the prototype sprites.

Randomization took a crap on me and wasn't giving me anything I like, so I changed it up slightly to go off of a digit in the camera's position. This means that level segments are appearing in the same sequences during startup. I'll need to fix that and add in some other factor, but I like it for this level, so I'll keep it here.

Increased movement speed is a preview of the upcoming glide move. On each frame a player holds shift, if they're not on the ground and if their defense is 0 (read: they're not guarding and/or taking damage), the scroll speed increased. If they've spent 65% or more of the pre-boss level doing this, they get an extra life. Normally they're supposed to only be able to do this after they beat the boss for this level, but, screw it, it's fun so I'm going to give it to them early, because the long expanses are good for playing around with gliding.

Aside: Kind of unintuitive in hindsight I chose to not check if the player was unencumbered before letting them boost-glide, since this also limits if they can flutter. I should change something here...

Bucket drones there don't do anything except maybe scoot sometimes, unless they have a pillar tying them to the ceiling. The movement from them is a glitch caused by the red rocks shoving them, but it makes them something besides just another stupid stationary turret, and it actually makes it easier to dodge, which, given how crap I'm playing here, is a necessity. I like it, so it stays. I'm sensing a theme here...

I'm really rushing it for the sake of getting gifs. Players normally have access to a quick-drop move by now, so it's not like they don't have options.

Boss isn't anything special, at least compared to how annoying the last one was. This guy just latches onto a wall and bursts a short round of bullet hell-esque shots at the player. Hit him, the wall moves back and has a bit of random height. Don't, and he shoves you behind the camera before moving back. Not the most complicated, but given how busy the rest of the stage is, I don't want to overload everything. This is stage 3/7, after all.

TO DO:

  • Rework credits since that code is all over the place. (Edit: Need to add stuff for displaying properly at the start of a level)
  • Special moves tied to certain levels. (Up -> Attack, Attack -> Attack, Guard -> Attack). All moves should be better to use than an unmodified sequence of their inputs. (Edit: Need guard -> attack, and to nerf up -> attack. Current setup is too broken. Also need to verify that dynamic-adding works)
  • Platform randomization mode toggling (Edit: done)
  • Verification that none of this is breaking prior levels. (Edit: It makes the levels easier, but that's okay for replays. Need to rework level 1's spawns though so that it's less boring since most of it, wait for it, is boring, especially compared to level 2's chaos).