PythonDND

Gavin Whitson, 6/10/2024

Background

Unfortunately, I did not write a development log through the course of this project. This is a retrospect on the project where I will comment on the goals that I had and what I believe I did right and wrong.

PythonDND was the first personal project that I did. Admittedly, I went into this project blind. I had been searching for a project and found one when I started playing DND with a group of friends and there was an admitted lack of table top figures for a table top role playing game. I decided that I could make an interactive battle map for Dungeons and Dragons (DND) in which the Dungeon Master (DM) can place make maps and place whatever entities they want depending on the encounter they wanted to create. This would (ideally) be complete with different types of attacks that work on different ranges and have different areas of effect and what not. I did not know what I was getting into.

I have a few regrets with this project. Namely, that it is purely in python. This comes with a couple of issues as it is difficult to make a performant GUI application within this language. I worked around this by having it to where a new frame is generated only when a change happens, however that does nothing to speed up the frame generation itself. I would love to revisit this project. Preferably, I would make this into a server based application that presents a website for clients to connect to. And if I wanted to do a full rewrite, I would not use python, at least not to this degree.

Implementation

Initially this project was OOP hell. I did not understand how to properly cleanup and update objects which led to a lot of wasted memory. This was however a fantastic learning experience. I created a class for the entities, for the map, for player controls, they got passed to each other, there were callbacks. I was drowning from objects that were created needlessly and the processing time of the too many for loops that I had used. I knew that I had to restructure these so that everything was not being stored in memory. I was learning about SQL at the time so of course, I figured I could use and SQL database to store objects, attacks, game state, etc. etc. This is an interesting decision, and in retrospect, I probably should have reworked by original classes so that they were more streamlined. Regardless, I created a SQL database using SQLite as the idea of using a local file as the database appealed to me since it eliminates the need to have a working instance of some external service being available and it can simply read some text from a file.

I took this idea way too far however. I do still agree that using a SQLite database is fitting for some parts of this application. The main drawback of using one is increased IO time as your query is processed and results are returned. I feel as though for storing entity types, attack types, saved game state and other static information that needs to be loaded in initially is a good application. I took my use of the database a bit far in this project, however at the time it solved my problems and allowed me to continue working on features.

Start Menu

Starting an instance of the app, you are greeted by the top left menu. The settings option allows you to adjust the keybinds that are currently available, otherwise you can create or load a campaign. A campaign is a collection of encounters, entities, and attacks that have been customized by the DM to suite the needs of the campaign. This came around as it follows the structure of the game itself as well allows the DM to easily reuse the characters for other sessions. You can setup a campaign multiple encounters ready to go so that the DM could multiple scenes ready to go. Encounters are selected by the other menu shown above.

Loading into an encounter presents you with a map with whatever entities exist in the encounter placed on it. If you have not assigned a sprite image to the entities, they are assigned a color based on their role, blue for players, red for enemies. Sprites are added by uploading the image that you want to be used to the "res/sprites" directory. A blank is provided to let people have something to easily fill in.

Future Work

I truly love this project, it is what really ignited my passion for programming and just as advice tells you not to do--I made a project I cared about for my first one. Even when finishing it up, this project felt incomplete. With what I have learned since, I know that with a revisit instead of a rewrite, I could fix some things. I want to expand on the attack system and actually manage to implement targeting to have different ranges and shapes for who gets selected. I feel as though I could expand on the code that I have already written to patch this project up in some regards. Doing full justice for the initial ideas I had for this project however would require a full rewrite and a rename since PythonDND would no longer be accurate. I will embark on creating my initial vision at one point in time, however fully recognizing the scale of this project now, I am waiting until I find the proper tools to build my app with.