It’s been a while since the last post here. v0.3.7 was the last build pushed to itch; eight versions happened since and none of them shipped here — so this build catches you up on all of it, then gets into what actually prompted this post.
What you missed, in one pass
v0.3.8— a deeper map. Missions run taller now (~6 floors / ~42 rooms instead of the old ~4×13 corridor). A guaranteed chapel sits before the boss door and heals 50% max HP once — the run finally has a pressure valve.v0.3.9— a real moveset. One attack button, four different hits depending on context: hit 1 ≠ hit 2, a rising slash (↑+attack), a stomp (↓+attack in the air, fast fall + short recovery), and a dash-attack follow-through.v0.4.0— enemies that come to you. A foe who sees you can now jump a gap, hop a step, or drop down to reach you, instead of stopping dead at anything taller than a curb.v0.4.1— a cleanup pass. No gameplay change on purpose, same asv0.3.7was.v0.4.2— a crowd that behaves like one. Allies queue instead of stacking on one pixel, an archer with no shot circles for one or steps in to brawl instead of just backing away forever.v0.4.3— AI stopped doing dumb things. A chasing enemy no longer freezes mid-pursuit when its home tile falls out of the streaming window; repeating the same attack is discouraged; archers hunt a perch up to 240 px away instead of only just past their feet.v0.4.4— a debug console. Backtick opens a tester console: a live tail of the engine log, a handful of cheats (god,heal,kill_all,give_relic,give_tattoo,tp,timescale), and areportcommand that drops a log + version/scene/seed/HP dump into a file and opens it in your file manager — drag it straight into a bug report.v0.4.5— save slots. Three save slots, chosen at “Start”; the game auto-saves on every room entry, on quitting, and on closing the window. Continue on the main menu jumps straight back into your last save, and the pause menu got a Return to hub for voluntarily bailing on a run without closing the game. A saved run carries its entire resolved map, not just a seed, so it survives room-pool updates without drifting.
If you played back at v0.3.7, that’s the gap. Full detail on any of these is in the itch.io comments or the game’s changelog on the repo.
v0.4.6 — the actual point of this post
Two playtest reports, both about touching things that shouldn’t grab you.
Catching a ledge used to read as sliding down the wall
Reaching for a ledge at speed, holding toward it, would often just… slide. Not fall past it — stick to the wall and slowly slide down, never catching, even when you were clearly aimed right at the lip.
The cause: the wall-slide and the ledge-grab share a single frame of logic, and the wall-slide spins the character to visually face away from the wall it’s sliding down (so the sprite reads right). The ledge-grab was reusing that same “which way am I facing” value to decide which direction to check for a ledge — so the instant a slide started, the grab check was looking the wrong way, every single frame, for as long as contact lasted. It wasn’t a near-miss or a timing window; once a slide began, a grab in that same motion was never going to land. Now the grab checks the direction you’re actually pressing or moving, not the (possibly reversed) sprite facing — and the character’s facing is set explicitly the instant a grab lands, so the hang pose doesn’t inherit whatever the slide left behind.
You could bounce off enemies like a wall
The player, every enemy, and the level all share one physics layer — that’s deliberate, it’s what makes bodies block each other. But wall-slide and wall-jump were reading “touching anything solid” as “touching a wall”, with no check for what that something was. Stand next to an enemy and press into them mid-air, and you’d slide down their body and could kick off them like they were a wall. Wall-slide and wall-jump are a level-traversal tool, not a way to spring off a person.
Fixed by asking, specifically, whether the thing you’re pressed against is actually part of the level (the same check the ledge system already used to make sure a grabbable edge is level geometry, never a body) — an enemy standing next to a wall you’re sliding is unaffected, but an enemy standing alone no longer behaves like one.
Both came from two lines in a running to-do list, not from a bug hunt — the report was specific enough to go straight to the cause. Both have a regression test that’s confirmed to fail on the old code and pass on the fix, and both were confirmed fixed by hand in the editor before this build went out.
Controls
Unchanged in shape since v0.3.7, plus the moveset and stomp that landed in v0.3.9.
| Action | Keyboard | Pad (Xbox) |
|---|---|---|
| Move | ← / → | left stick / d-pad |
| Jump (double) | Space / Enter | A |
| Wall-slide / wall-jump | hold toward the wall in the air to slide · jump to kick off | same |
| Melee (3-hit combo) | A — tap | RB |
| Charged attack | A — hold ≥ ~0.5 s | RB — hold |
| Third-hit variant | hold ↓ heavy · nothing = fast · ↑ = air launcher | same |
| Stomp | ↓ + attack in the air | same |
| Block / parry | D — hold / tap just before the hit | LT |
| Riposte | automatic — hit within 0.4 s of a parry, same enemy | same |
| Dodge (dash, i-frames) | Shift | LB |
| Shoot (8-way) | S | RT |
| Reload | R (auto on empty) | Y |
| Interact / throw-out | E | X |
| Look up / down | ↑ / ↓ held (standing still) | same |
| Full map + overview (held) | Tab | Select |
| Pause / menu | Esc | Start |
| Ledge grab | automatic; climb = jump / ↑, drop = ↓ | same |
| Debug console | ~ (backtick) | — |
How to run it
| System | File | Notes |
|---|---|---|
| Windows | ultraviolet.exe (+ ultraviolet.pck beside it) | SmartScreen may warn about an unsigned file — “More info” → “Run anyway”. |
| Linux | ultraviolet.x86_64 (+ .pck beside it) | chmod +x, then ./ultraviolet.x86_64. |
| macOS | Ultraviolet.app | Unsigned: right-click → Open → confirm, or xattr -dr com.apple.quarantine Ultraviolet.app. |
Quitting: Esc in the main menu closes the game. In a run, Esc opens the pause menu — quit or return to hub from there. Continue on the main menu resumes your last save.
Still pre-alpha — what’s not here
- Placeholder art. The player has a stand-in sprite pack; enemies, terrain and UI are coloured rectangles.
- Placeholder sound. Rough stand-ins, two music tracks on loop.
- No continuous save. Auto-save fires on room entry, hub arrival, quitting and closing the window — a hard crash still loses whatever happened since the last one of those.
- Balance is untuned — damage, enemy HP, costs, the per-room enemy-count ramp.
- No death screen, no attempt counter, no meta-progression beyond tattoos and the first soul from Legion.
How to report feedback
The fastest path is now the debug console: press ~, type report, and it drops a log + version/scene/seed/HP file straight into your file manager — drag that into a comment or a message.
BUG — what happened, where, how to reproduce, which platform. A report dump covers most of this automatically.
FEEL
- The two fixes above — does a ledge grab feel reliable now, or are there still spots where it slides instead of catching? Does anything still feel like it’s bouncing off something that shouldn’t be solid?
- Save/resume — does Continue put you back where you expect? Any run that came back somewhere wrong?
- The console — useful, or clutter? Anything you wish a cheat did that none of them do?
- Getting from entrance to boss — can you actually do it? Where does a run fall apart?
Leave feedback in the comments under the game or this post.
Thanks for playing something that’s still mostly rectangles.
— SolarNine · v0.4.6-pre-alpha