Birdoggydog's Builds

Fixing list scrolling and drawing a melee slash in Godot

A scrolling inventory list that left its text behind, door prompts moved to the monsters' plate style, a bare vat name, and a faint slash on every melee blow.

I play the game and draw notes on the screen when something bothers me. Four of those notes got fixed today. A scrolling item list had its text stuck in place, the floating door prompts didn’t match the HUD, the inventory’s vat had two boxes nobody wanted, and melee blows had no visual at all.

48 seconds in four parts: the salvage locker’s list scrolled and a row picked far down, the prompts for a door, a chest and a body, the vat with only a name, and melee swings that each draw a faint stroke.

Why did the text stay put when the list scrolled?

In the salvage locker on floor 2, the cells of the list moved when I scrolled but the item names and the highlight stayed where they were. I wrote “This breaks scrolling inventory”, and it did.

The list draws its own strips on top of Godot’s ItemList: a name, a lamp and a kind for each row. It placed them with get_item_rect(), which gives a cell’s place in the list’s content and doesn’t subtract the scroll. So the engine moved the cells and my strips stayed at their unscrolled positions. I added one helper, row_rect(), that subtracts the scroll bar’s value, and the strips use it for their position and for skipping rows that are off the list. The creation screen’s list drew its rows the same way, so it got the same one-line fix.

Clicks were never wrong because the engine does its own hit testing. I wrote a test that scrolls the list to the bottom, picks a row far down, and checks that the row that is selected is the one I picked.

How do the prompts get the monsters’ plate style?

The floating label on a door ("[E] Close") looked nothing like the brass plate that shows up when I hover over a monster. My note said all the floating indicators should use that monster style.

Every door, chest, body, switch, lift and NPC already went through one function on the chat bubble, show_hint(). So I changed that function and not the callers. In that mode the bubble hides its speech column and shows a plate row instead, which has a lit lamp, the thing’s name at size 15 and the prompt at size 11, in the same box the monster plate uses. A prompt with a key in it is drawn in the bright tube color. A notice with no key, like “// DOORWAY OBSTRUCTED”, is dim, so it looks like writing and not something to press.

The plate is centered with its foot just above the party rack. If a monster’s plate is up, it stands on top of that one, using a new plate_room() on the monster hover that says how much height the plate takes. Two prompts up at the same time stack, the older one lower, with a 4 pixel gap. Plates hide while a screen like the inventory is open. Speech bubbles still sit beside whoever is talking.

What did the vat boxes do?

The vat in the inventory had a bar at its top that carried the member’s name and a bar at the bottom with nothing in it. I said the box wasn’t needed and the name was enough, and about the empty one I asked what it was for. They were the vat’s two end caps, so I took it as: draw no caps and keep the name. I deleted the two rectangles and moved the name up a little so it stands over the glass by itself.

Drawing a slash at the crosshair

Melee had no visual, and I didn’t want circles. I asked for something like a swipe through the air, small and transparent, over the place where the cursor is.

The new MeleeSlash is a canvas layer that draws each stroke in code, with no art file. A blow always hits whatever the crosshair is on, so the stroke goes at the middle of the screen, not at a free mouse that could be sitting on the rack. It’s called from three places: a melee hit, a swing at nothing, and a follow-up blow. Shots and spells draw nothing, since the shot is their picture.

The look depends on how the weapon strikes:

  • Slashing is a crescent polygon, 18 steps along an arc, thickest in the middle, with a bright thin line along its outer edge. Each swing flips direction, so a run of blows goes back and forth.
  • Blunt is a shorter, heavier arc brought down from above, and once it’s laid in, four short cracks spread out from the crosshair.
  • Piercing is a narrow tapering thrust that runs in to the crosshair.

A stroke is laid in over 0.08 seconds and fades over 0.17, so a quarter of a second in all, at 55 percent opacity at most. It’s 120 pixels long on a 1080 pixel high screen and scales with the screen. It runs on real time like the HUD’s other flashes, not on the game clock. Up to six can be up at once, for four members swinging together.

Also done

  • A test file with 46 checks covers all four fixes, including that shots from out of reach still fly as before.