Status of AsciiBrain - end of 2023
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
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.
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 :-)
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 :-)
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
Burningstatus 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
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
Lavawil deal 1 point of immediate damage and apply the
Burningeffect (hint: don’t do it)
- Stepping on
Moneywill 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!
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.
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
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 :’-)
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
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!
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
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!