HatBot (dino game)

Created: Feb 28, 2023Published: Mar 28, 2023Last modified: Apr 25, 2023
Word count: 2966Backlinks: 5

A Dino game.

---

I landed on 'HatBot' to name the entry for the Metroidvania Month (jam) 19.

Named after the main character, who runs around in a floppy mad hatter hat.

Also called: mvania19 (dino game) for the first half of the jam.

world outline

> landing site

grassy cave

tall walls that need to be climbed

wooden blocks blocking path to wall-climb power up

enemies:

  • floor walker goombas
  • punk-kicky turtles

powerups:

  • jump
  • wall-climb

required:

  • wall-climb to reach snow/volcano
  • wood-smash to reach wall-climb
  • wood-smash to reach kingdom?

underground access to simulation and kingdom

climb the wall to reach the snow/volcano door

> simulation

spaceship/facility full of wood and metal

powerups:

  • dash boots (a horizontal dash, for more quickly crossing a room)
  • wood-smashing bat

enemies:

  • robot enemies crawl on all walls

dash levels need to be crossed before doors close

wooden blocks need to be destroyed

later, revisit to destroy metal blocks

> kingdom

purple stone and gilded temple

powerups:

  • double jump
  • magnet

enemies:

  • bats
  • floaty witches casting spells
  • coins to gather to open doors

required:

  • wooden block smash

need magnet power up to get to double jump room

(gather both?)

> hot and cold

snow, volcano

a world split in two directions, choose which to tackle

enemies:

  • hot boss
  • cold boss
  • wall-walkers
  • floaty snow/lava tossers

required:

  • wooden block smash
  • magnet
  • double jump
  • dash

magnet-requiring coin door rooms

double jumps required

dash required for timer rooms

wooden blocks to destroy

postmortem

> Longest jam i've done (1 month)

before now my longest was 9 days

> ~10 minutes to play through

now that's alot of content!

> built for native platforms!

not just web this time

linux/osx/windows/html

the web build was scrappy, so now we're getting more native experience

>> codesiging /notarizing/staple was a pain

but i learned/got it done on apple

>> skipped code-signing on windows

> 5 metroidvania areas/zones

The world outline above and the tileset focus day helped get the envs going.

>> Level Zero

Very happy about this area - it was the last one added, and solved a few things at once: tutorial, a secret-end-game reward room.

It also gave space for some title and credits setup.

>>> Tutorial

>>> Credits

>>> Secret room

>> The Landing Site

Env intended as a metroid reference.

Could have used some space-ship wreckage art.

drop in from unreachable level zero elevator.

climbing gloves found here, but sword is required to get to them.

with climbing gloves, can climb to the volcano.

otherwise, can walk through enemy + candle rooms to simulation elevator.

>> Simulation

Intended as a mechanical/robot/programmed world. got some 'spaceship' naming integrated. Ended up kind of plain overall. needs more world building!

sword is accessible through a few rooms.

with sword, can collect coins to open door to candle and then boss room.

elevator to kingdom beyond boss room. technically, you can run by the boss if you want.

originally connected to the kingdom elevator right next door to the landing site elevator, but I moved it b/c it was too easy/available to skip the first boss. Otherwise there was no real reason to even go to the boss, especially with a lack of a reward.

>> The Kingdom

'golden' or 'gilded'.

tileset a bit different - blockier, less natural-looking, more man-made, in an ancient pyramids kind of vibe.

lots of coin rooms (3?) - along the gilded theme.

long fall to the double jump powerup, then double jump your way back up.

a tough enemy + coins room, with a ceiling exit - only accessible way back to level zero.

'throne room' named for the boss room. I guess the Monstroar is the King?

beyond the throne, an elevator back to under the landing site, where you have to jump and blindly double-jump and sword up to get out. a bit clumsy.

>> Volcano

You climb up to the elevator with the climbing gloves, and need them for a few of the rooms.

You know, volcano. b/c it's red!

had a red-ish canvas modulate for a while, but went to more black after a few days - felt like everything was getting washed, and the tilesets look better with the colors popping.

one coin room with a bunch of goons. probably some of the harder enemy rooms.

a long climb to the final boss, preceded by a forgiving candle room.

Then, the final boss fight.

> 3 boss battles

>> beefstronaut

fires arrows that can be knocked back with the sword.

intended flow was knock a missile back, then jump and slash while they're stunned.

normal gravity applies, but maybe it could not?

art was a strange one - weird legs and an astronaut helmet... just went with it!

i like some of the animations - the firing one lends itself to the direction it could grow in - a strong arm that wires around. maybe digital arms, something reconfigurable for a few attacks?

>> monstroar

'swoops' at you. you kind of knock at them while trying not to get hit.

floats (no gravity except in knocked-back/stunned/dead states)

art was odd too - ended up with a head and big handlebar mustache. kind of works for a 'floating head' thing.

>> both

warp around between multiple fixed points.

knocked back -> stunned -> warp phase

'laugh' state, largely unrealized

>> fighting both at the same time

both made for the most fun fight, i think. probably these bosses belong together more than they belong apart. maybe that makes sense b/c of how they were conceived - one boss broken into two, then both added to the same final fight.

> 3 mechanics

>> sword

impled in isolation - could be attached to any node (in theory)

tying it to a beehive state could be interesting - could those states be reused

by player, boss, and enemy machine? makes me think of a mirror/copy enemy/boss

ended up with a large hitbox - i exaggerated the strike alot more in a second version of the animation.

can be aimed up/down/left/right based on player input. kind of hollow knightish.

feels chunky, not really nimble. maybe i know the code too much to really feel it? not sure what i'd do differently yet.

an interesting thing done here (and on the kick) was supporting attacks on specific frame numbers of the animation. it's tricky to support not hitting things multiple times, but also making sure more than just the first frame is used to determine what to hit.

>> double jump

Not too bad to impl, but some crossover/overlap with the coyote jump i'd originally handled. should a coyote jump support an extra/double afterwards? or does introducing the double mean dropping coyote?

i leaned towards more generous air time. not much in the game to really enforce or hold players back from reaching something they're going for.

jump/double jump still feels a bit clunky, passing double-jump allowed flags between jump/fall/etc states.

>> climb

first wall climb impl!

used a few ray casts:

  • high/low on players' top/bottom
  • can't remember what these do...
  • to-ground ray cast
  • helped prevent wall-climbing when it's not necessary, like climbing stairs

the state may have been complicated, or maybe not enough. I ended up with a fixed climbing speed, and you can just hang-forever, no worries.

> boss rewards ( dev secrets )

an interesting move - rather than unlocking/earning mechanics, you get some developer tip.

>> shift for slowmo

>> e for screenshake

>> p for debug ui

> 3 non-boss enemy types

>> soldier (turtle)

more potential here, and made 5 other alt sprites for it.

each with their own weapon. expanding on these would be good pixel art practice at the least.

I also realized i could add some of them as background art, especially b/c they have idle states already. (feeling street fighter bg art-ish).

>>> kick attack

similar impl to the sword's attack - check specific frames for hitbox collision.

fighting games probably have hitboxes per frame of the animation - i wonder if i should reach for that soon. so far i've been leaving things a bit loose.

>> goomba

doesn't do much.

borrowed art from gloomba in ghost.

added a death state towards the end.

should we remove enemy collision layers when they die? sometimes they dead enemies stack in awkward ways, b/c the collision shape is pretty large vs the death art frame. would be fine if the collision shape for the death anim was more accurate, but i tend to just leave them.

maybe animationTree style characers lend themselves to multiple collision shapes more easily.

>> shooty-crawly

sticks to whatever wall it starts near - kind of a nice impl.

also does some 'laughy' things when it hits.

their bullets can be fired back with the sword - it completely reuses the boss bullet script.

> game objects

>> coins

collect to open coin-doors... and that's it

>> doors

open from one side, not the other

energy/fancy animation

>> elevators

pretty cool, travel between areas

godot ui for selecting destination (in editor)

>> candles

provide light. can light them, then sit to heal (then they go out).

they are also checkpoints that you return to.

>> bullet (boss and enemy created)

can be fired back

pop animation

> new addons

>> Hotel

DB for game state + node lifecycle

named for it's original purpose: room management.

grew out of how weird it was to select a destination elevator in the ui. like, why don't we have this data?

>>> api

  • book(path or packed scene) static data
  • register(node) in _ready() (calls check_out then check_in)
  • check_out(data) stored data setup a node based on whatever data was stored
  • check_in(node, optional_data) updates to the data health loss, open/close of door, on/off candle, etc
  • hotel_data() - impled on a node to build data dict

>>> query(opts)

a nice query-dictionary for fetching things in a group, with a growing list of

other convenient filters, and an anon func option like:

Hotel.query({"filter": func(ent): return is_thing(ent) and is_other_thing(ent)})

>>> Hotel UI

interactive filtering/toggling to see what the db data is

>>> HUD elems read from hotel updates now

nicer than tying HUD to player somewhere

and easy to add more HUD elems - everything just comes from a

hotel.entry_updated signal

>>> boilerplate is a little much still

two functions, plus a call in 'register'

but that's a mixin, i suppose

>>> when to book? probably in ready/register, if it hasn't been booked already.

>>> learned to read data from packed scenes!

>> Debug

Logging with pretty-printing!

a huge win, really. Debugging/scanning the output so much easier

plus it made for really easy re-use in HotelUI

>>> learned to read the stack

unfortunately it doesn't work in prod

> extended addons

>> Hood

>>> Actions Hint component

got a ton of use out of this.

includes an 'action' to 'key' map, which is nice for not hard-coding keys everywhere

>>> Actions api/abstraction

ActionDetector on actor, ActionArea on interactable object, Action as a class

>>> Jumbotron component

presenting an interstitial to the player

>> Camera

>>> in-game Debugging UI

>>> POAs added for 'anchoring' points

> mvania19 dir

>> MvaniaGame, MvaniaArea, MvaniaRoom

Three classes that support a metroidvania -like game.

areas are sometimes called zones

some leakage of the MvaniaGame.player into other classes (bosses, enemies).

>> maps > demoland

Bunch of areas where we tried out some tiling techniques (solid blocks,

autotiling tilemaps)

also got enemies, and elevators working, and refactored hotel to support

persisting mvania data

>> maps > hatbot

the areas themselves, plus some quests that were reused across them

> reused entities

>> DungeonCrawler Coin

With a pretty large addition to the script

>> Ghosts Gloomba

> potential refactors/abstractions

>> 'Player' autoload/api?

Feels like we could use a shared 'Player' abstraction or autoload somewhere. There's dependence on Hood to find it, but Camera needs it as well, plus a few other things.

probably useful for managing upgrades/spawn points, etc

>> 'Room' abstraction?

runnerRoom, mvaniaRoom - there were a few times i needed to connect to the current thing's room to get a trigger/event. plus the whole thing depended on the room for some life-cycle stuff (pause/unpause).

>> quests system

quests were created adhoc, but it feels like they could be codified

  • jumbotron intro
  • jumbotron on complete
  • jumbotron for progress? via pause menu
  • other progress/completion components/code helpers

>>> CoinDoorQuest

>>> BossDefeatQuest

>> jumbotron/action-hint based dialog/menu abstraction

something data-driven that presents text, arbitrary components, and a set of options for interacting with the whole thing?

>> Mvania Area/Room editor tools

level editor? maybe.

might be low lift to add features right on top of godot's editor.

I have in mind a room regenerator that can scale/shrink rooms without breaking door constraints. maybe crazy, but it's what i want. easier in the editor, or in a full 'game' level editor?

>> sprite animation management - aseprite import helper?

adding a frame to an aesprite tag pushes all the frames down, which updates animations in place in godot's animatedsprite2d. feels like we could be creating the godot sprite_frames from the aesprite file directly....

i have some concern about losing control in this process, or needing to edit/tweak things. we'll still need to set animation speeds and looping/not-looping, for example.

> takeaway/cleanup todos

>> Remove/reduce other game autoloads

They're noisy in the logs/errors when the game runs

we should be able to work around them, or at least the preload errors they thow

>> handle licenses and game assets properly

currently symlinking in fonts, which means the repo is broken

>> build for platforms in the cloud, not on my machine

be nice to offload the build process, now that we're building for 4 platforms

>> add tileset alts, apply color-swap shader

tilesets could be providing more variety - alternate tilesets make things much

nicer

>> could learn/reimpl with animation tree-based state machines

i've seen this recommended, but can't tell if it's better for less-code-y folks

or if it's actually cleaner/better for other reasons

> wish i could have

>> env/aesthetic particle effects

I dream of celeste-level feel. I really want this!

Closing this gap is progress for me - i want something that looks fuller, more alive.

I think it's just checking more of the boxes.

I didn't hit:

  • mid-ground particle effects
  • props (of any kind)
  • bg props
  • foreground art
  • multiple tilesets - i did this in elevator rooms, but not across areas
  • alt tiles - i made sure this was possible, but mostly i need to setup a better tile aseprite file in general
  • player movement dust

>> destructible wood animation

I tried this a few times, hoping to do something simple based on the tileset as source.

one surprise, i had trouble applying a shader to a single cell in a tileset. I could create a separate piece of art to slice and animate, but that's annoying.... but if necessary, i can do it. just was surprising that it wasn't quick to do.

>> proper third boss in volcano

the first two bosses exhausted me to work on. could have been the inflection point of my burn out, and was also the first time i'd approached something like this. boss battles seem very 'custom', but ultimately i landed on a shared state machine, and each 'boss attack' (swoop, fire, laugh, warp) is impled as a separate state in that machine, so not too bad, really.

I'd say it's not reusable either, but apparently it is, when you can just throw them into a room together later.

Still - what should this game's boss have been? overall there's not much throughline/world cohesion happening.

>> foreground, background props/art items

trees, lava, snow, etc

>> bring the rooms/envs to life more

birds, critters, leaves, foliage, etc

>> space ship wreakage art in landing site

make a space ship, then wreak it. could be better to make a whole animation?

>> boss battle background art

anything to make these big rooms more interesting

>> volcano level lava pits

i looked into a water tutorial, and it seems doable, tho a bit of a lift. would be good to reach for something fancy like that, it's a great feature for interesting environments.

>> more interesting title screen

maybe fog of war and move the mouse around to uncover it

>> MUSIC!

>> laugh

I like this idea and want it! Probably works with a player 'stunned' state, that waits for input to get back up again.

Probably helps to prevent repeatedly kicking the player while they're trying to figure out what's going on.

>>> 'laugh' sound, for bosses and enemies

>>> better/exaggerated 'laugh' animation, for bosses and enemies

>> use the extra turtle art/characters i made

cuz duh

> future work/unused ideas

>> fast travel elevators

>> light flooding into rooms through unused doors

>> SPIKES?

lava? water?

untraversable tiles of some kind

>> beefstronaut more animations

give those arms/legs/whatever more abilities - punches, stomps, knocking arrows back again?

>> boss rush mode

a new area?

or a fancy bit of code to drop you in boss rooms? would need to close the doors, so players don't just run right off during the fights.

>> extra turtle art + characters

created idle states for ~6 turtles, but only used one with a kick... and called it a soldier? didn't like that much.

More chars might be less work here, especially if we're sharing state machines.

>> enemy goon groups - packs of enemies

feels like ai should be more enemies moving in packs, like they should know about each other and even travel-around together.

I was close this idea in protomoon - like, a level 3 em with level 2s nearby, those with level 1s near them.

> happy about

>> level zero and secret room

>> hotel db

>> camera focus improvements

>> room-oriented apis

>> candles as save and healing points

>> elevators and selecting a destination

>> bunch of tilesets created

more world building components

>> tileset process learned/improved

>> 'laugh' state in enemies/bosses

not impled well, but a nice idea


Backlinks

I love rooms (game design element) as a unit of game design and iteration. A rooms api should support that.

Dino has seen a few different rooms api approaches already. The Runner Room code managed cycling rooms ahead of the player so they could be revisited. In Tower Jet, the Reptile Room was built up to generate (and regenerate) the tiles based on noise images. Then, Mvania / Hatbot featured a fuller room and area management, including room data lifecycle via hotel and pausing/unpausing the rooms based on the player location.

A month-long game jam for making a metroidvania!

Something about that game that only the devs know - maybe it's a tool they use to test things that was left in just for fun.

hatbot used dev secrets as rewards for winning the boss battles.

A Godot monorepo full of games, addons, and scripts.