Salomonsson.se
Jan 05 2024

Status of AsciiBrain - end of 2023

Yikes, who's in charge of this enemy spawning X'-)

Haven’t posted in a while, so let’s do something about it! Big time!

Here’s a summary of all that’s happened to asciibrain (that I haven’t yet posted about) during at least the past 1,5 years. Quite a lot, this is still very much a live passion project for me.

New color scheme

Neovim terminal colorscheme 'OneDark'

Strict ascii-based terminal applications doesn’t have to be ugly green-on-black, and when I found the wonderful colorscheme “OneDark” for neovim I instantly fell in love (it even has fake transparencyin the popup!!! I’ve been toying with the idea but felt uncertain… until I saw this!).

So I had to give it a try, and I have to say I really like it! Since this screenshot I’ve modified it a bit, but I still think it shows it off wonderfully I think.

Initial mockup, has darkened it a bit since then

Chests

Any entity can be interacted with, which will build a sequence of actions for playback (so far monsters only show a text dialouge saying it growls at you) but chests do more fancy things! Each player controlled entity receives a random ability, and then it “exhausts” itself.

Since I see very little reason why a player would ever want to attack and kill a chest, I made the actionSelect system automatically identify a chest and select it as interact instead of melee attack. You can still hurt it with the blast of a fireball though, so be careful :-)

Doors

Also showing off my fancy walk range transition

Had long time coming, but finally here. If you choose the “interact” option on an open door it will also close.

Doors seemed like such a basic thing, yet it opened up a whole world of issues! My map generation did not do a good job at generating doors. I always knew it was temporary and “just good enough for now”, but fixing it just got a much bigger priority.

And as I change the mapgen, a lot of other things are in urgent need of fixing… (more on this in a bit). Nothing is ever easy in gamedev :-)

Status Effects

Any entity can have any number of statuses, which can apply positive or negative effects. Functionality-wise this is in place, but the presentation is still very crude, so I need to explain what you see:

  • All entities caught in a fireball blast gets the status Burning (even the chests…)
  • Entities with effects will blink with a ! during player input phase, to mark something’s up with them
  • The Burning status has the effect that it deals 5 points of damage at the end of the turn for that entity (pretty brutal for now)
  • So after the enemy has moved, it receives damage and dies

Yeah, needs a lot of refinement. But cool to have it in place.

Lava and Money

Textbox got a bit cut off, but player gets $100 from this effort

Another thing that’s been long in planning phase has it’s first implementation. Tile Effects are things on the floor that can affect an entity when stepping on it.

  • Stepping on Lava wil deal 1 point of immediate damage and apply the Burning effect (hint: don’t do it)
  • Stepping on Money will add $100 to your inventory

Let’s say that the total gain for the walk in the sequence above was a pretty bad move for the green player :-)

Also, you cannot really do anything with your hard earned money yet… But it will…

Lets talk a bit about code!

Configuration for two of the status effects used in the game

When it comes to the code, I try to make everything as data driven as possible. Everything is configured using the pattern seen above, to try and make it as readable as possible. Enitites (stats, tags, visuals), abilities (damage, effects, cost) and so on. So far it works really nice.

It should not be too much of an effort to configure the data objects from textfiles to support modding for example.

Memory

Bottom left corner of the game window

Last year I wrote a custom memory allocation system, just for fun. Pretty much everything in the game now uses an arena-based pre-allocated memory stack. It’s easier than it sounds, and really powerful, giving me full control over allocation and de-allocation with almost no overhead when allocating persistant objects.

Nessecary for an ascii roguelike? Hey, my passion project, my rules X-D

I currently have 4 arenas I can allocate to (but I’ll need to introduce a 5th soon).

  • Persistant (cleared when game shuts down)
  • Level (cleared when we move from one floor in the dungeon to the next)
  • Turn (cleared at the end of a turn)
  • Frame (cleared just before we call Game::Tick())

The 5:th I’ll need will be for a Game Session, since you might want to exit a game and start a new one without terminating the application :’-)

Text

Multiline textbox with word wrap

I’m not using std::string (in fact I don’t use standard library for anything other than a few of my oldest stuff that I haven’t had time to replace yet). But neither std::string nor const char* supports colors or my weird custom glyps…

But one more thing: since I use a stack based memory model, it should be super easy to concatenate strings (as long as I’m at the head of the stack) with zero overhead or copying.

So I started writing my own, simple, text handling framework, on top of my memory management. It works super nice! It’s these little things that makes me a happy programmer!

Custom glyphs, bg/fg color control and animated colors

CMake and cross platform

I have also added cmake build support, and successfully compiled and run the game on both OSX and Linux. I have written about this earlier, but still pretty proud.

The game uses SDL for window, input, file loading and rendering, but I only use a minimal set, and everything SDL-related is contained in a single cpp-file. The game code itself has no dependencies whatsoever to SDL or anything else, and uses no platform dependent code either. Porting to another backend, such as Raylib or GLFW is not only easy - I’ve already tried it, and it was quick and easy.

What I’m working on right now

In-game visualizer tool for my mapgen

As stated under doors, my previous dungeon generation algorithm is no longer enough, and it is finally time to start improving it!

If you are a sane developer - even a little - you will know that working with procedural generation without proper tools for testing your result will quickly end up in despair. The tool in the image above uses only in-game functionality and was thrown together in less than 2 days (with just a couple of hours in each).

But experimenting with levels quickly turned out to be a pandoras box! The only enemy attacks/ai I have implemented so far is melee based, and as soon as you expand a room this becomes obvious. This means I probably need to make at least one ranged enemy for testing.

But so far I only have a single ranged projectile: the fireball. It has very nice visuals, but they are hard coded, and I want it to be data driven too (an actual particle system).

LoL. Well, it sure seems like an interesting 2024, and I cannot wait to dive into it!

–Tommy