Pre-Release Update 2: Postgres and Clerics

- (8 min read)

Note: This is a development blog. As such, anything shared here should be considered a work-in-progress and can change at any point.

Header Image

Since our last update we've been undergoing a major database change. While this work is not very exciting from a gameplay perspective it is a big improvement to the code base that will allow us to deliver a better experience down the line. We also share some of our thoughts on how we might change up the cleric class.

Commentary: Cleric redesign

We have recently been discussing and considering what to do with the cleric class in our game. Since we disabled dual-clienting, players will not be able to play one fighter class and a cleric simultaenously (nor should they HAVE to!). To adjust for this change in gameplay style we have been updating the player's base stats so that the game can be played with one character at a reasonable pace. One consequence of this design is that clerics now are even MORE overpowered since their buffs would stack ontop of the base stat increases we've added.

To counter-act this we've concluded that we need to change the cleric class from being a pure "buffer" to playing a support role in a different way. One thing we will be doing is temporarily removing the targetted buffs from the cleric so that they will not be able to buff other players. We will be keeping the party buffs to reinforce their role as a support player and to encourage collaborative gameplay.

Our current decisions on how to compensate for the removal of ~6 skills are still not firmly cemented but the current plan is to design the cleric to be played as a "summoner". We will be experimenting with giving the cleric different summon skills (e.g. removing them from the mage class and dealer class) whereby each summon has a different unique advantage. For example, one summon might be high damage but low health while another summon would be more tanky in nature. Clerics would have to decide which summons they would have to spawn and which ones they would want to level. We would also want to encourage clerics to use the various "pet capsules" that drop in the world to compliment their already summoned mobs. Currently, by repurposing the existing summon skills we are planning to have at leats 3 unique summons.

  • Phantom swords
    • High DPS, Low health summon
  • Elementals
    • Low dps, high health summon
  • Mercenary
    • Average dps, average health

The final results will require further design and testing but these are our current thoughts. Ultimately we want to preserve the support role that clerics play while updating them to fit the new single-client + stat changes we are introducing.

Cleric

Postgres

Currently we are migrating the codebase from Microsoft SQL Server to PostgreSQL. While normally such a big project is not advisable, in this case we felt that it would be a good investment in the long-term quality of the project. This decision began when we started to refactor parts of the database. We previously blogged about this issue in our last pre-release update. The main motivation to start the refactor was to remove binary fields from the database. While binary fields have some advantages such as making it easier to read/write bulk data, it also makes the data quite opaque once it goes into the database. For example, look at how inventory was previously stored:

Old Inventory Table

As you can see, this data is quite opaque without knowing the underlying C++ data structure behind the binary blob. For example only if we know this:

// 2-bytes total
struct Item {
    uint8_t id,
    uint8_t grade,
}

Can we know the first byte is the id and the next byte is the grade.

Furthermore, due to the implementation this setup is quite fragile. When first porting the server to a new compiler we discovered that the compiler caused changes in the size of certain types (larger) so they could not fit in the existing schema!

Additionally, when we wanted to implement some improvements to uniquely identify each item by generating a UUID for it we discovered more shortcomings of this design. By adding a new field to the type we changed the size and so our new type was no longer compatible with the data already existing in the database and was not compatible with the schema!

This prompted us to begin work to remove all binary blob fields from the database and to replace them with schemas that better leveraged the facilities available in the database. Our results were new tables like so:

New Inventory Table New Item Table

As we began converting the existing blob columns it slowly dawned on us that nearly all the gameplay information for the game was stored as a blob field. Information such as inventory, skills, stats, spawn zones, quests, hotbar icons, friends, storage, etc. was all stored in these opaque fields.

Blob fields

This meant to "de-blob" the database we would be touching nearly every database function in the code base! Furthermore, we had implemented a new ODBC wrapper and this meant that we need to rewrite nearly all the database functions in the server to use the new ODBC methods.

As we started to design the new schemas we learned that the idea of "blob" fields made sense in certain circumstances. For instance, a player's skills are stored in memory simply as a list of skill ids. Adding an additional table and extra joins on the SQL side didn't seem to warrant additional complexity where a simple array would suffice. However, MSSQL doesn't support the concept of an array or a similar type.

Since we were going to have to rewrite almost all the database interaction code anyway, we took the opportunity to evaluate whether it would be worth it to port that code to a different database at the same time. After reviewing the options and our requirements we ultimately decided on porting our code to PostgreSQL.

Why Postgres?

Postgres Banner

Cost

While Microsft SQL Server is a fine database engine it is primarily enterprise driven and propriatary. To license the non-developer version is costly and the cost scales up as you need more performance. Postgres is the same caliber as MSSQL but free and open source, a huge advantage for us when we are ready to open our server.

Performance + Complexity

This point is a bit dubious since the two databases are extremely fast and we would never push them to the limits of their capabilities. However, MSSQL and its tooling do feel as though they demand more run time resources compared to Postgres. Furthermore, MSSQL does feel more complex and unnecessarily complicated in certain areas. This is not helped by the complexity of its GUI driven tools such as SSMS and Server manager. Postgres on the otherhand is built more in the unix spirit and is more easily configurable using traditional configuration files. It also has better support in the open-source world with regards to tooling, drivers, community, etc.

Better SQL

While MSSQL T-SQL is fine it does not feel as modern as postgres. Things such as timezone-aware timestamps, serial columns, CTEs, etc. just make using SQL with postgres a much better developer experience.

JSONB

Another big selling point for Postgres is its built in support for json. We discussed above how saving the binary data is problematic but can be advantageous, JSONB in postgres seems like the best of both worlds! Rather than using binary blobs for certain fields we can use JSON. We get all the advantageous of blob data without the opacity. Postgres even supports querying the json data directly in a SQL statement!

JSONB columns

Postgres port status

As of today we have made huge strides in the Postgres port. We would estimate that we are 65% complete with the work and have already written the api and ported the major items related to character stats, equipment, inventory and quests (partial). This leaves us with only a few remaining minor items to port and two major item (storage, clans). Once the database work is complete we will be returning back to focusing entirely on bugs and the existing gameplay so that we can get this server launched!

Conclusion

Thanks for staying tuned with our updates. We hope that the next one won't be so technical and we can begin sharing some exciting new gameplay changes.

Don't forget to join our mailing list on https://www.rosenext.com and our Discord Server! If you'd like to keep-up-to-date on our blog posts then please checkout our RSS Feed.