07  ·  Ashen Cathedral  ·  paused
projectsabout

Sydney

07 · Ashen Cathedral

First-person Diablo, more or less

When GPT-6 Astra came out, I tried asking it to make a first-person version of Diablo 1 in Unreal Engine 5. Basically that was the brief. I wanted to see how far it could get from an idea like that.

The result was… passable for a 2010 game, I suppose, but still not there yet. There's a village, a cathedral to descend through and a Butcher to fight. It's paused at the moment.

unreal 5.8c++blender pythonpaused
Building it

Working without the editor open

The rules live in ordinary C++ headers, separate from the Unreal actors.

Combat, items, trading and exploration can be checked without launching Unreal. The actors call those rules when something happens in the game. That makes a small rules change much cheaper to try.

The test script compiles those pieces directly with Clang and sanitizers. It also checks the asset scripts. Most of that work doesn't need the editor or GPU.

There are some checks for absurd coordinates in the fog-of-war code too. The plain C++ version makes those cases easy to exercise.

FIG. 1 · one of eight sanitizer runs
clang++ -std=c++17 -Wall -Wextra -Werror \
  -fsanitize=address,undefined \
  Tests/RulesTests.cpp -o Saved/Tests/rules
ASAN_OPTIONS=detect_leaks=0 Saved/Tests/rules
From Scripts/test_rules.sh. The other seven follow the same pattern for items, trade, enemies, exploration, town map, abilities and UI geometry.
The game

What you can walk around in

Built at runtime

The game constructs the dungeon and encounters when the level loads. The map asset itself mostly gives it a starting point.

Fog of war

In the dungeon the minimap reveals cells by integer line of sight (mapLineOfSight in Exploration.h). Rays reveal a closed door but cannot see through it, or diagonally between two wall corners. Rooms you have left stay dimly drawn.

Grid inventory

A 10 by 4 pack. Each item kind has its own footprint, and drag, swap and equip all check the footprint against the grid.

The Butcher

The Butcher attacks faster once he drops below half health. His wind-up is the chance to guard or get out of the way.

Greyhollow

A small village with a healer, a blacksmith who buys and sells, and the church you descend through. A labelled town map tracks your facing.

A short run

It's a short slice of a game, with no mid-run save.

The art

Making things with Blender scripts

A lot of the assets come from Blender Python scripts, followed by import steps in Unreal.

The scripts make props, parts of the town and character candidates. If something looks wrong, the iteration is changing the script and rendering it again. The results vary quite a bit.

The first Butcher was built from primitives, and you can tell. The replacement starts with CC0 MakeHuman anatomy and goes through another set of scripts to add detail and bake the materials. Both versions are below.

FIG. 2 · the Butcher, idle, wind-up, walk, death
Four renders of the Butcher: standing with a cleaver, raising it overhead, walking, and lying dead.
A review sheet from ArtSource/Candidates/ButcherDetail/Review, rendered in Blender.
FIG. 3 · the procedural Butcher it replaced
A blocky pink-orange Butcher figure with a plank mask and a cleaver.
SM_Butcher, a static mesh from primitives. Docs/ART.md keeps it as a legacy source asset.
The incident

Then the GPU fell off the bus

Sources: Docs/GPU_INCIDENT.md and Docs/RESOURCE_LIMITS.md.

During a packaged run on 7 September 2026, the kernel logged “GPU has fallen off the bus.” Unreal lost the device, the driver stopped answering queries, and the machine needed a restart.

I still don't know what caused it. There wasn't a temperature history to check, and the logs didn't establish overheating or identify a particular Unreal feature as the culprit.

After that I put heavy jobs behind a resource guard: one at a time, with CPU limits and temperature and memory readings. Blender uses CPU rendering for these previews, and native captures are short and guarded.

The guard has since stopped a job when the CPU reached 88.5 °C. That's useful, but it doesn't explain the original GPU fault.

For now

An experiment to come back to

The latest town, enemy and lighting revision still needs native validation. The launcher uses an older standalone package until that happens. Between that and the GPU trouble, this is parked for now.

Open question

I'd like to get back to the question I started with: how close can an agent get to the game in my head? There's still quite a gap, especially in the art.

MaterialsUnreal Engine 5.8.2, C++17, Blender Python
VintageSeptember 2026
StatusPaused WIP
Sourceprivate
Press / for the other projects07 / 12
Index12 / 12

  • 01Tauri ExplorerMy file explorer · Rust and Svelte · notes on building it
  • 02ScrivoMy Markdown reader and editor · Typora-style live preview
  • 03BallastMy mood diary · Markdown files · desktop and Android
  • 04Quickshell barMy Hyprland bar · agent state and quota pacing
  • 05Tableau FrogData exploration · linked charts · AI experiments
  • 06LambdaQueryPython-to-SQL compiler · started in 2017, revisited in 2026
  • 07Ashen CathedralA first-person Diablo experiment · Unreal Engine 5 · paused
  • 08Brood War AIBrood War agent · imitation learning · work in progress
  • 09AutomatedSpikeMagic deck search · learned pilots · XMage experiments
  • 10Zheng Shang YouOur family card game · learning agents · playable version
  • 11EskivA game from high school · recreated during Covid · search-based bot
  • 12Intuition on the Central Limit TheoremCentral limit theorem · interactive mathematical exposition
↑↓ move↵ openesc closeTap a project to open it