Converting to a database-driven model
I spent most of memorial day weekend pacing back and fourth in my apartment trying to devise the best possible drupal architecture to share and manage game content.
Currently the games data consists mostly of URIs and object properties relevant to the various different kinds of game objects (trees, units, buildings, etc). The kind of information that would ideally fit in a database. But because the game runs on the client side, it made sense to put everything into a single JSON file. After all, it isn’t that much data and it isn’t going to change all that much, except when new versions of the game are released.
Now that I want people to be able to add their own content to the game and share it publicly, I have to rethink that approach. The data isn’t static - it changes, and frequently, sometimes in the same user session. And it isn’t a small amount of data we’re talking about anymore. The database size has the potential to become extremely large if enough people contribute to the public repo. Game content needs to load dynamically from the server instead of from a single static JSON file. In addition, data is retrieved/output based on parameters specific to users.
Say Armando uploads a texture and puts it in the public repository. Emilio, browsing the public repository, loves Armando’s texture, so he click the “add to account” button. From that point on, Emilio will always have access to Armando’s texture in the map editor. The next time Emilio browses the public repository and sees Armando’s texture, a button, “remove from account” will appear in place of the “add to account” button. In addition, Emilio can remove the texture from his account from within the map editor interface.
I won’t go into the nitty-gritty of how I rewrote the data model to satisfy both Armando’s and Emilio’s needs, but the end result is that I’m using the same (or variations of the same) server-side code (a la drupal views) to retrieve and output data from the database, wether that data is specific to Emilio’s account i.e.:
- Stuff Emilio has uploaded and kept private
- Public assets Emilio has added to his account from other accounts
Or, if that data is universal, i.e:
- Public assets
- Official game assets
And, on the client-side, the JS functions I’m writing to load content into the game world will work from the same output structure by the above scenarios, regardless of wether that content is:
- Added dynamically, from the database, after the game has loaded when a user clicks “add to account” when browsing the public repo
- Added Emilio-specific content from the database at the beginning of the browser session
In summary, i’m killing a whole flock of birds with just one stone. Granted it’s not just any old stone - it’s a special stone, a stone I spent all weekend chiseling, smoothing and perfecting. Because I’m thinking long-term here. I’m thinking about how this thing is going to scale and how efficiently the server will operate running 2 or 3 queries to load game content instead of just one. And it’s a heck of a lot easier to make a change in 1 place as opposed to 2 or 3.
If it’s anything writing code for this game has taught me it’s how to abstract code in such a way that in can be re-usable in different scenarios. Of course, as a web dev, I’ve always been aware of this concept but it takes on a whole new meaning when developing a game.