Tag: database

  • my great big spreadsheet ledger user interface adventure

    I’ve been thinking a lot this week about Dwarf Fortress. 

    Have you played Dwarf Fortress?

    Have you even heard of Dwarf Fortress? It’s a bit of a #iykyk kind of game, but one that some gamers have #k about for almost as long as the game has been in active development, which is well over 20 years.

    Two guys. One dream. One insanely complex game engine that fools you into thinking it is simplistic because its graphic design is, bluntly, outwardly visually rudimentary and (until recently) completely composed of colourful ASCII text characters.

    I’ve been thinking about this game, Dwarf Fortress, because as I develop my own little game project I’ve come to realize that many games, at their core, are essentially just pretty user interfaces for databases of varying complexity. I mean, I knew this. It’s always been my core understanding that to be a good games designer that at among many things you need a solid awareness of database design in your toolkit.

    My game is a database at its core. 

    I’ve mentioned this in a past post, but in creating my game I’m essentially designing a fancy UI for a really complex accounting ledger spreadsheet. THAT doesn’t sound nearly as much fun as a Science Fictional Supermarket, so you can see why I don’t lean into the former description in my marketing copy. That said, I am friends with more than a few accountants who might be into that, so—

    But I digress.

    Dwarf Fortress has been in active development for more than twenty years, because as the (perhaps apocryphal) story goes, the developers can’t seem to stop adding more rows and columns and macros to that game-as-spreadsheet metaphor.  The game is insanely complex. It is like the Matrix of database queries but with the cascading text representing dwarves and sheep and weapons and logs and, heck, I can’t even begin to name a fraction of a fraction of the elements here. I sure there is complexity layers in the game that are games in and of themselves that barely a handful of players have even discovered. It’s complex. Have I mentioned it is complex? 

    This complexity is on purpose, of course. (I assume.)

    I know many gamers who are (you know who you are) into wildly complex games with rules spanning many dozens or hundreds of pages, and in some cases, rule systems. DnD is essentially a giant rule system, that has depth and a bit of complexity but tries to keep it simple enough for our human brains to keep up. But Dwarf Fortress seems to embrace the complexity in the other direction and has both depth and complexity. Thousands of variables tangled in around themselves.

    Pleck’s Mart has from nearly the beginning had a database. But until yesterday that database was almost entirely about saving states and progressively loading game data.  Yesterday, tho, I added objects. And objects, see, are more than just a picture of something that appears in the game. Objects are the start of data complexity in the game. Objects are containers with variable states and value and properties that affect how they ultimately matter in the game. Objects are rows in that spreadsheet whose values react to conditions of the game, the passage of time, and the interaction by the player.

    It’s that start of my own game complexity that begins on one end of the spectrum with merely a virtual caselot of imaginary potatoes and ends all the way at the other scale with Dwarf Fortress.

    I’ve been thinking a lot about Dwarf Fortress this week not because Pleck’s Mart will ever be that complex but because it will always now, going forward, be some fraction as complex as Dwarf Fortress. 

    You might even call that a Dwarf Fortress Complexity Quotient, like as in Pleck’s Mart DFCQ equals about 0.01 as of right now. I’m striving for maybe about a 0.2, subjectively speaking of course.

    I have a long way to go, but the journey into a wildly entertaining spreadsheet ledger user interface adventure has begun. But let’s keep calling a game, ok.

  • story and art and code, oh my

    This game has become something of an obsession. Or, as the folks over in the meme-posting land of LinkedIn would tell you, a follow-your-passion moment worthy of some stock photography of me running through a field with my arms flung into the air.

    Seriously, in this few weeks of downtime between leaving my part time job and starting back up some professional upgrading and curricular activities—and still, given that the weather is in deep-winter mode—I have little else to occupy my time besides consuming books and Netflix or making something cool.  So the video game design project has won.

    All that is to say that I’m made some serious progress.

    I am nearing the home stretch of Space Carrot, which was my design phase set on building out the equivalent of a game board.  Yeah, there is still more to do as the game design progresses, but this phase was all about building the world in which the game takes place, and in addition to previous updates I’ve made on this phase in the last few days I have added a lot more stuff.

    I think the biggest of these is the furthering of my story system. Tweaks, again, will continue, but the core of it is in place.  The story-proper is a collection of ordered text events that appear on the screen moving the “plot” of the game along. When a room is first entered, when an area is first accessed, when anything of interest happens that could benefit from explanation, this all triggers a bit of the story to be loaded into the game and displayed on the screen. The game, as I have alluded to in other bits of writing, started as a story that I decided would make a good game, so there is a bunch of lore and narrative and characters that are all part of playing it.

    Another big behind the scenes piece is the database system that is coming closer to a solid initial implementation. Behind every good game is a good database, after all. Databases in games store more than just player information and scores, but are sort of the malleable memory of the game itself. I can set all the pieces up as a starting point in the code and have it all initialize when a player first starts the game, but from there the whole point is the player moving, changing, unlocking, and advancing the game itself. Every time something happens the game can try to keep track of this and save it at some point, or—as I am doing—it can basically save as it goes. The advantage of the first method is that someone can reload and go back. That is by design not an option in a rogue-like because the point isn’t to save and progress, but to play over and over again trying different approaches, so a point-in-time save file makes no sense for that. Instead, the state of the single play-through is pushed to the database frequently unlocking and changing the state of the game so that when the player “loses” the game goes back to an almost fresh state—but certain aspects stick and are unlocked ever after and for the next play. A tool. A room. Et cetera.  The foundations of that are now in place as I creep closer to the end of Space Carrot phase.

    And along with these two big bits of work I have not only done some bug clean up but also some key refactoring of the code as I (a) learn better approaches to things because I’m learning the language better and (b) encounter decisions that impede progress because of how I tackled it the first time. Not only does this mean simpler algorithms and code-reusability, but also building little functions that are like little single purpose tools to transform some data or extract a bit of something and give it to something else. 

    Oh, and I’ve leaned into public constants. As I build it’s often easier to hard code numbers into things for the sake of speed and debugging, but as things grow and complexify, one realizes that changing over, say, a number used eleven times to define a spawn point to a constant makes it easier to update when the map shifts ten pixels to the right because of a design change. I spent an afternoon just replacing hard-coded numbers.

    In the end, what this all means is that I am probably one more subversion away from declaring the end of Space Carrot phase and moving into the next one.  More on that later. So stay tuned.

    The obsession is palpable.  Maybe, those LinkedIn people are right and when you lay awake at night puzzling over a code problem and are not laying there dreading the morning, but rather considering creeping downstairs at 3am to try it out—maybe that is a passion project. Grab onto that, huh?

  • the obligatory “Hello world!”

    As of late 2024 I’ve been incrementally teaching myself how to do this Rust Language coding thing and it has somehow started to emerge as a game. My first love is and will always be words, tho, so here begins many, many words on the topic of building a game from scratch.

    So.

    Thing is, as of this week my efforts have come full circle.

    Kinda.

    An early attempt to build a game tick time loop was a factor of trying to create a series of nested loops that managed random things in a database. It would count off the seconds and if sufficient time had passed it would tell the database to +1 to the age of a game object —the game is about running a little [redacted] and [redacted] exists [redacted] but age consistently across all [redacted] blah blah—I’ll explain it more as we go, later. Needless to say I was leaning pretty heavily into the database design as an active tool to manage all my game variables all the time, including during the current screen gameplay.

    That was silly.

    So I started learning about this game engine called Bevy.

    Bevy handles all sorts of things. Or, essentially, it wraps all the regular pieces you would use—should use—for a game into objects that are then managed by the game engine. This means it can spawn a player and a board and objects and they can exist as virtual game pieces, but also as things that can display on the screen or whatever. It’s all neat and tidy.

    I wrote a bunch of code to use a bunch of array data, essentially an x and y grid of tiles that maps out a player area in the game. I call these simply, obviously rooms. A room can be something like the back store room where you keep and get new products. Or there are storefront rooms which are basically all the same across dimensions but may look slightly different or have different texture files, that type of thing. But the core here is that as much as a player can move around inside each room, there will be doors that take them to other rooms.

    Hense, the full circle.

    Aaaaand—now I am back to the database.

    I started encoding a bunch of database functions just this morning that are updated at various times during play. When a room is exited, I am thinking, the database will slurp up all the room data, store the state of all the objects in that room and essentially create a kind of mapped overlay of the base map for each room, but at coordinates there may be products or tools or other things that despawn out of the active play but can be respawned when the player re-enters that particular play area.

    I lean heavily into database driven design online and I am very comfortable thinking about things that way, but in many ways it this is because databases are virtually a necessity for web based stuff if only because you need preserve a lot of data between pages and across sessions. Each page is essentially a little app that builds itself dynamically from the data in the database and doesn’t rely on a system loading the entirety of the site into memory and keeping track of everything across every session then passing all of it from page to page. Now that would be silly,

    I figure, too, that this approach may really work to my advantage in the roguelite game plan that I am contemplating. Certain data can always be persisistent across runs of the game and just doesn’t get purged from the databse on initiation.

    I sat down here to write something about the abstractions of learning this language but now that my ideas are actually starting to take shape and form I’m noticing that I can write in more than abstractions. And that’s a good thing, right? Maybe silly. Maybe more.