Some time ago now, we made a decision on Ludus which was a particularly tough call to make. We had been working on Ludus for a while, art, code and design all along side eachother. We had made economical decisions based on our scope and our minimal budget.

I’ve been working as a technical artist for 10 or so years now, so I have come to expect that expectations tend to change over the course of a production, but I somehow didn’t quite foresee that my own would change quite so much. Nevertheless, through habit more than clairvoyance, I knew things tend to change, and I knew that the best way of dealing with this is to always try to build a system that does whatever some job is, rather than focusing on doing the job itself.

So when it came to creating the characters, I set out making a system that would instead generate characters on my behalf from a set of models that had the same topology so that they could morph into each-other and consequently be mixed in any variation.

I started by grabbing some gladiator armor meshes from TurboSquid and Rob fitted them to a model exported from MakeHuman, then I exported some more characters of different shapes from MakeHuman to serve as the morph targets. I linked the bone positions to the vertex positions in the mesh so that I could correct the rig after morphing the vertices, and computed an automatic weight for the clothing meshes to follow the underlying geometry.

The results seemed promising and after a while of ironing out some vertex order and other kinks we had a system that could produce characters of lots of different shapes and sizes. As you can see from some of the in-progress images below, this process was easy peasy lemon sqeezy.

We continued working with these models and preparing new gladiator armour models for them. Time passed by, and after a while we had quite a lot of art built around this system. But something wasn’t quite right; the model we used was from an earlier version of MakeHuman, and the base model itself had some slightly peculiar proportions. All the variations consequently just looked a bit off.

We made the call to change the base mesh, and with it, all the character art had to be altered as well. A tough call to make on a minimal budget. So I made another system, this one ripped some code from the character generator to morph all the clothing meshes into a new base pose, which we made by pushing the rig into a pose similar to the new character base mesh we had, and then refining the model somewhat using standard modeling tools.

Bar a few errant vertices that needed to be cleaned up by hand, this system was able to salvage most of the data.

Adding the new character and new rig to the old system was an immediate success as made evident by the image below.

After a bit of massaging (read: near complete rewrite) the system was able to produce some plausible looking characters of many different shapes and sizes though, and we had improved the overall quality in the process without completely killing the art budget.

In the game, we have also tied the attributes of the characters to their visual appearance, so a generated character with a high strength value will look stronger, or a character with a high constitution appear more full bodied. After a little while of playing, you get quite good at judging the abilities of an opponent.

One of the absolute key parts of Ludus is the ability to interact with NPCs and participate in the Roman society from the perspective of a lanista. To achieve this we needed a competent dialogue system. I think anyone who has worked with dialogue trees will know what type of features to expect from that kind of tool, but with our emphasis on modability I think some of our decisions in the actual implementation might be different from some other games.

While we have developed quite ambitous plans for the ways you can interact with the NPCs in Ludus in addition to simple scripted dialogues which rely on what will hopefully be a pretty sophisticated AI – we still maintain that it is important to be able to create more tailor-made content which we can mix with the more spontaneous systems we’re attempting to develop.

Even though simulating almost everything fully is super awesome – if you sprinkle in some more set-in-stone-ish events, we can hopefully put the player in awe of what outcomes arise during the course of the game. It should hopefully also be hard to tell what was scripted and what was simulated, just that we would like to guarantee or at least make it more likely that interesting things happen no matter what.

One way we can do this is to make dialogues that will push the simulation quite hard in a certain direction with the side effects that occur on certain dialogue nodes.

So that’s the justification for still having hardcoded dialogues in the game, but how do you actually go about authoring the dialogues?

Initially when we started we were using a tool called ChatMapper which is a fairly decent choice. But we soon realized that in order to actually export dialogues that the conversation middleware could use, every modder would have to buy a license. Since we care a lot about modders we decided that this was not acceptable so we got rid of both ChatMapper and the middleware. After researching alternatives, we set out to create our own way of authoring dialogues and our own dialogue system.

We wanted a plain text format that could easily be edited by hand and read with eyes (instead of toes!). A common choice for hierarchical data would be XML or JSON, but we’re not huge fans of those. As an Emacs user I soon had the epiphany that the Emacs Org Mode format would be quite nice for modeling a dialogue tree. It has nice properties such as not having to worry about closing tags or parenthesis for the tree nodes. Emacs comes with nice ways to edit and view it, which certainly helps, and we could add extensions to make it even nicer to edit. However if we have the time we might even put an editor for dialogues in the game itself.

Either way if you are not familiar with org-mode, you might want an explanation on how the format is structured! The way you write an org document is that you create a headline which you do by putting a number of asterisks (*) and a space, and then the name of the headline. After that you put a newline and anything you put below that will belong to the headline. Examples of things you’d put in the headlines are things such as paragraphs and source blocks and various attributes and such. The nesting level of the headline is determined by the number of asterisks before the name of the headline. Here’s a very simple example of a document:

* My headline
This is a pragraph that belongs to "My headline"
** My child headline
This paragraph is in a headline which is a child to "My headline"

Here's another pragraph, they are separated by two newlines.
*** My grandchild headline
This paragraph belongs to headline which is a child to "My child headline"!
** My second child headline
This is the second child to "My headline"
* My other headline
This headline is not a child of "My headline" it is a sibling.
** My other child headline
And so on!

It might be hard to read at first but again just pay attention to the asterisks before the headline title and you should be able to visualize the nesting. Emacs makes it much easier to visualize the nesting since you can turn on “org-indent-mode” which is very helpful. You usually indent the text under a headline in emacs but I stopped doing that when I noticed that it broke org-indent-mode which looks much nicer anyway. Even so, even without any indentation to make it more clear I find this format to be less noisy than something like XML or JSON. I think this format could be pleasant for other things than just dialogues, for example I think it could fit quite well as a plain-text representation of a scene-graph.

I mentioned that other than paragraphs you could put things such as source blocks and attributes under a paragraph. Let’s discuss the syntax of these a little bit. For source blocks we use the exact same syntax as Emacs org-mode, which looks like this

If you have a keen eye you’ll notice that we explicitly say that the language for the source is “boo”, you’ll be able to use any language here that there exists a driver for, and even add your own language driver if your favorite is missing (assuming everything goes right). But that’s for another post about the scripting system!

Attributes have a similar syntax and can be put on their own or attached to another element in the headline’s section, such as a source block or paragraph. For example, we support an attribute called WHEN which you attach to a source block to specify when that script should run, a particularly useful stage to run a script is “condition” which can help filter out certain dialogue nodes if the script condition script returns false. An example could look something like this

This example also shows the attributes ACTOR and CONVERSANT which, unlike the WHEN attribute, is not directly attached to an element of the headline – instead it is an element itself. What distinguishes an attribute element from an attribute for an element is the two newlines separating the elements, just like with paragraphs. The main thing that distinguishes an attribute element from a regular element is that you can’t attach attributes to attributes.

That is really almost all of the syntax, the last thing that you might be yearning for is text substitution. Well for that you can use a macro language which again is just any programming language that has a driver for the scripting system. In order to set the property for what macro language to use you use what is called a “property drawer”. Which looks like this:

:PROPERTIES:
:MACRO-LANGUAGE: boo
:END:

Once you’ve done this you can use boo in order to evaluate any code that will in the end return a string for what should be substituted. Like this:

And that's the way {{{ script_return "it is!" }}}!

Finally in org-mode, headlines can have keywords prepended to them, such as TODO. We decided to adopt this for creating link headlines by adding the keyword LINK to designate that the headline is a link. The way you write a link is as follows:

As you can see this means that it is good practice to name your headline something unique.

That covers basically most of it, there are other useful features as well such as running a script when entering and exiting a dialogue (and even individual dialogue nodes) for setup and cleanup etc. But this article isn’t really intended to fully document every feature of our dialogue format, but rather to introduce you to the basic ideas and principles on how we (and hopefully modders!) will write dialogues for the game. We suspect that the format will evolve over time so documenting everything right now would probably be time down the drain.

If you want to you can take a look here in order to read an example of a dialogue that I’ve been using for testing which showcases everything I mentioned in this post. It kind of lives in its own space for now in that it doesn’t have any real side effects in the real game, but it illustrates how you can arrange a dialogue – quite sloppily though because it was quickly thrown together for testing purposes, the result of running that dialogue (with a work-in-progress UI) can be seen below (click to maximize)! Thanks for reading!

In the first instance, it was suggested to attempt to write traditionally authentic historical music but the lack of bona fide material from the time coupled with my concern for its relevance to today’s audience encouraged me to explore a different route. The decision was made to combine authenticity with a more accessible ‘contemporary Hollywood sound’. I started by referencing historical musical sources to help define my instrumental palette and inform my musical decisions. I wanted to focus on writing strong melodies using instrumentation and musical language associated with the genre and time period I was writing in. I combined this methodology with contemporary stylistic decisions to create a traditional yet cinematic crossover.

We decided to write music that was culturally inspired by different geographical areas of the far reaching Roman Empire. From Hispania in the west, we went through Celtic Gaul to Britannia and Germania in the north. We then followed along the Macedonian province and the Greek Isles east through Thrace and Cilicia all the way to the Parthian border and then back along Aegyptus and Numidia. We decided to title the tracks in such a way that if someone looks up the titles, they will find some interesting piece of history from the region they are inspired by.

Whilst I was given a healthy amount of creative freedom I was also instructed for each genre to cover the 3 main themes of general tasking, action based and intrigue/plotting. Writing in so many different genres with which I had little experience, was a daunting yet fun challenge.

The other requirement for this prototype was to ensure that all of the music written for the game could interweave and loop at random. I made the decision to write everything in the same tempo and complimentary key signatures, keeping the development relatively linear yet at the same time ensuring there was enough variation in content, style and melody, to keep the listener interested.

Production wise, I used a combination of digitally sampled instruments and real live performances to make sure the recordings had enough realism. String sections were the most predominant instruments throughout most of the compositions and due to their nature it was vital the majority of them were recorded for real.

I have now spent over a year composing music for this project on and off. It has been a unique and interesting challenge and I like how it has encouraged me to explore and write in styles and genres I wouldn’t have necessarily written in otherwise.

My artsy illustration degree was about as useful as a chocolate teapot in setting me up for my job as technical director. When I read white papers, I feel dyslectic when looking at the wall of math and the academic wording. Now after some years of experience, I want to share some core code bits and understandings of the stuff that makes it possible to make pretty pictures, animations and games on the computer in a wording that I hope will be a bit more understandable than many of those white papers. First up: Spherical Spline Quaternion Interpolation or SQUAD for short.

What is it?
It’s a formula that makes it possible to smoothly go between a set of rotations.

Where would I use it?
If you were making some animation code where you wanted some 3d object to go through a set of keyframes of different rotations for example, ‘tweening’ smoothly.

What do I need to understand to use it?
A basic understanding of Quaternions helps, but mainly you need to know that:
– Quaternions are rotations
– They are different to Euler angles, but they don’t suffer from gimbal lock.
– They’re not as straightforward to understand as Euler angles and have different problems to Euler angles.
– If you try to visualize them, your head explodes.

How does it work?
Do you know splines / curves from animation programs or vector drawing programs? It’s a lot like that but in crazy quaternion space. The trick is that you need to compute something sensible as the tangents so that you can go smoothly through a bunch of keyframes.

What problem does it solve?
Normally, you might reasonably interpolate between Quaternions using SLerp (Spherical Linear Interpolation) or Lerp (Linear Interpolation) but if you’re going to go between more than two key rotations, these functions are visually to the surface of a sphere what a straight line is to a sheet of paper.

Let’s take a look at it visually. Here is a vector being rotated by SLerp through several rotations:

Although it’s smoothly interpolating in time, it’s not really affected by what the next quaternion after the current two is, so it just moves in a straight line from one quaternion to the next. If you have lots of keyframes this could still appear smooth, but with just a few spaced out ones, it doesn’t look smooth. Now let’s look at what this looks like with SQUAD interpolation:

Much better! The rotations appear to be anticipating where it’s going to go next, and we get a smooth curve occuring on the surface of the sphere. These rotations are much more visually pleasing and we need a lot fewer keyframes to achieve a smooth looking motion.

Because it’s properly interpolating over all the different axis we can now get some interesting tangents by rotating the quaternions about the twist axis:

Unity Implementation
The unity project with source code and an example of use file can be downloaded here

Unity’s Quaternion class isn’t quite enough for to implement SQUAD, so we need to expand on that a bit first. The first script in the package below (QuaternionExtensions.boo) helps us extend the Quaternion class with functions that we need to complete the SQUAD calculations. Among other things we need a version of SLerp that’s a bit different to the SLerp method in Unity in that it doesn’t flip, as well as some basic things like scaling or adding to the Quaternion directly.

The second script (SQUAD.boo) contains the implementation of SQUAD itself. Looking at the code top down, our entry point might be something like the method Spline() with a number of quaternions that make up the spline, and a value t along that curve.

SplineSegment() returns the interpolated value between the 4 quaternions it’s operating on (the part it’s working on is the “line segment” between q1 and q2, the first and final quaternion are the previous and next quaternion after this line segment).

Intermediate() is the function that produces the nice and smooth tangent values between the rotations. There’s some magic stuff going on in there and I’ll let you play with the -0.25 value yourself. I’ll cover briefly what is happening but I don’t have a very deep understanding of why this works myself.
First it transforms the first and last quaternions by the inverse of the middle quaternion putting them in world space.
It then performs the quaternion Log function on them that we added in QuaternionExtensions.boo, adds them together, scales them by a magic number and performs quaternion Exp before transforming them back into the space of the middle quaternion and normalizing the Quaternion.

SQUAD() is then called on q1 and q2 with the two tangent values we got from Intermediate(). This is where we need to use the SlerpNoInvert() method we added to the Quaternion class. If we just use the Slerp() function from Unity there will come a point where unity clamps the domain of the Quaternion which basically looks like our poor vector travels through interdimensional space and ends up in some completely different place in our puny 3 dimensional world.

Recently, I have been moving some of our important and core code out of the Unity Assets directory and instead compiling them in to a .NET dll. When I did this I encountered in to the issue of all the scenes and prefabs that were using MonoBehaviours from those scripts had lost their reference.

I found this surprising initially because I thought the references to components were simply using the .NET assembly name of the class with all the namespaces etc, perhaps in combination with something else to be able to track renames of classes. However it turns out that all it basically does is to put a GUID in the script .meta file which it in turn puts in the guid property of the m_Script field of the objects in the .unity scene files – along with a fileID property. The fileID property is always the same for scripts in the Assets directory, but it is different for every class in a dll – I suppose it uses this to narrow down the search for the assembly reference or something like that.

Now this is very little information to work with, so it’s actually harder than it should be to resolve these references. You basically can’t see the name of any script it was using or anything useful besides the GUID. When you look at the scene file you can even see that it has an m_Name and m_EditorClassIdentifier property, but it doesn’t fill them in! This is most likely why, when you look at a missing script in the inspector, it doesn’t even show you the name of it, so you have to rely on your memory to figure out what it was if you are going to fix it by hand – and I don’t know about you, but I certainly can’t do that. TL;DR the format was meticulously designed to break your heart.

If you are in total panic right now, and don’t have any way to recover the meta files associated with your old scripts, then anything in this post beyond this paragraph won’t be useful to you. All the advice I can give is that you may be able to look in the scene files at the field names shown for the component and see how the variable names line up with those in your classes. Then you figure out what the new GUID and fileID for those are and edit it in there by hand. That will take quite some time however and I wouldn’t wish it upon my worst enemy. You could probably make some really fancy analysis program for recovery, and someone should maybe do so, but that would take a lot of effort. The best way to not end up in big trouble is to backup your stuff and put your meta files in version control. And also to use the plain text unity scene/prefab format (check the Editor Settings and/or rtfm). Do this, and the gods will smile upon you, or at the very least, I will.

I did look around a bit to see if someone already solved the problem, but pretty much the only “solution” I could find was scripts that would find the missing script references and let you assign them manually, which doesn’t help at all because you can’t get any hint of what the script was named so it’s only slightly better than checking every component manually by clicking on it. But that’s not good enough.

I managed to make a solution that does eliminate a large portion of the manual labor. There is still some set up that you do for every missing component, but it’s relatively small. I’ll describe the workflow first, and then tell you how it works internally. Finally I will share the script with you in case you don’t want to write your own.

You start out by figuring out which components possibly could be the ones that are missing. For me this was easy, I knew that the references went missing when I compiled things in to a DLL, so all I really had to do was to search through all of the source files for the DLL for lines containing “MonoBehaviour“. If you don’t know, then one thing you might do is simply to check the scripts from your recently removed meta files. Unity removes these automatically because it hates you so I can’t stress enough how it’s important to have them in version control. Once you’ve done that you can search through the file that the meta file was for in your sources for MonoBehaviours.

Now that you hopefully know which components likely went missing, and have those written down somewhere. You can create a fresh new empty scene, and have it contain nothing but an empty object containing just the MonoBehaviour you are currently fixing.

Save this scene – locate your meta file. Once you have done this, you are set up to run my script to fix one component in your entire project.

What you do is that you pass the script the meta file, as well as the scene you just set up and saved, and also one or more paths that it should search through for scenes and prefabs. It does this recursively so you don’t need to specify every subdirectory of every subdirectory etc. Passing multiple directories is mainly useful if you have a huge Assets directory and want it to only look through “Assets/Scenes” and “Assets/MyPrefabs” or something like that. I just passed it “Assets” and it was fast enough.

What the script will then do is that it will read your meta file, and find the guid that used to be correct. Then it will read your scene file to extract what the new guid is, and also the new fileID. Knowing what the old fileID was is not important, it will simply replace the old one with the new one, it only needs to know what the old guid was to be able to locate it in scenes and prefabs. Once it has the data it asks you if the data seems to make sense to you, and if you answer “y”, then it will start replacing all of the old references for you. Here is a sample invocation of the script, cleaned up a little to remove some of the verbosity:

I’m going to replace guid 79e4e0dfe8d9bf94b9622e6d68377772 with d79c0ede0316c2b429fad82aa7fc643f and set the file ID to 1803148156, is this ok?(y/n): y
Okay proceeding…
Found old reference(s) in C:\Users\usefulProgrammer\src\boo\ludus\Assets\ExperimentsArchive\drawcalltest\crowd.unity, replacing..
Found old reference(s) in C:\Users\usefulProgrammer\src\boo\ludus\Assets\Scenes\Crowd.unity, replacing..
Found old reference(s) in C:\Users\usefulProgrammer\src\boo\ludus\Assets\Scenes\CrowdPoses.unity, replacing..
<… and so on>

Done!

Once it’s finished you remove the component from the empty object in the scene and add the next component, save and change the meta file to the current relevant one. If you accidentally start mixing meta files etc then you will pretty much be screwed, so be careful with this. Also don’t forget to back up everything before you do this! Cool? Cool.

And that’s really all there is to it, I wrote the script using Racket, which was very pleasant. The script is available here under a CC0 license.

This process could probably be improved somewhat, for example you could script the editor to add all of the components for you and try to figure out which meta file it should look at etc, but that is definitely more difficult to implement and probably rather error prone. If Unity actually used the m_Name field or m_EditorClassIdentifier that they simply left empty – then it would have been less of an undertaking to automate this further. For me, going further than this would stop saving time for us in this situation, which is why I started writing the script in the first place. If we end up having a bigger catastrophy which requires really intense recovery then I’ll let you know what I do about it. But since we are using version control I suspect we won’t need anything more sophisticated than this.

I hope this post helped you out, or at the very least made you put your .meta files in version control because otherwise you could lose everything. See you next time.

As we mentioned in the previous blog-post we want to make Ludus very easily mod-able, and because we are a small team we need to make sure that the tools we create help us fill in the world as quickly and easily as possible. We decided that the most efficient way of making the world was to generate a part of it procedurally whenever practical. At the same time we want to maintain control over the design and make it as easy as possible to design new areas of the world, both for us and the modders. The system we came up with was kind of interesting so we wanted to share the thinking behind it in this blog-post.

This picture is all that’s needed to design the terrain for one of the levels in Ludus. but how does it work? Let’s break it down.

The red channel indicates the area where the buildings will be. We want to make sure that the ground here is relatively level, and we also artistically decided to slightly raise the ground just beyond where the buildings make contact with the ground. This channel is currently derived from the 3d placement of the buildings rather than the other way around, and only affects the terrain.

The green channel dictates the playable area, this is what should be accessible to the player, the system should make sure that this area looks and acts like a walkable terrain and that it doesn’t contain any overly steep inclines etc. It also helps indicate where to use most of the vertices of the terrain itself.

Finally the blue channel is used in the texturing process, it instructs the material to say that this area should be using a second blended material (specifically in the current case, this makes it a paved area, while the rest is sand, but this is set up in the material settings)

The image we had before is the final output of the ‘design’ image, All the modder/designer needs to define is there. This is then processed and combined in a procedural material from substance designer to output the image we see above. You can recognize some parts but others have come from procedural noise and various processes the image goes through to create a heightmap that is usable in the terrain generation in substance designer. The playable and building area is leveled out and raised, and a bit of height is added just around the buildings.

Each pixel in the procedural texture is scored by neighboring height difference and whether it’s in the playable area, and we create a vertex on each ‘important’ pixel. This makes sure that the vertex budget we have for the terrain is used in an optimized way. In the image above you can see the resulting mesh. Note that it uses fewer vertices on the flat areas and that the area defined as non-playable has a natural in-accessibility because of the steep inclide.
Lastly, similar to the Mosaic effect, we use Delaunay triangulation of these vertices to combine it into a mesh.

Although the coding and procedural material process to achieve this takes more time than making one or two terrain models, the ease with which we can add new areas, using a very broad-strokes method, to the game means we can make a much more interesting and expansive world. We intend to take the system further and add set dressing like barrels etc automatically based on the original image input as well.

Making a game properly mod-able and data driven is something one should make a decision about early on because it impacts so much of the structure of the code and data. In our case with Ludus we decided that the mod-ability would be a key focus both because we are interested in what players will do with it and because we want to be able to easily extend the game without having to re-work things at the core of the code-base. Keeping things easy to change is hugely important when projects grow into a larger scope. It also forces us to drive a bit of a wedge between data and the core systems that process that data in a good way.

We use a number of external tools when developing the game such as Chat mapper (A great non linear dialogue editor with Lua support) and a whole host of graphics programs. Unity’s general approach to data loading at runtime is to have ‘asset bundles’ but this would require that the asset are first opened by the modder in Unity Pro (a paid license) and then turned into asset bundles one by one. We instead wanted to use more open, easily editable file formats that can be edited by standard programs for its data type, and also be editable using only cost free software so we don’t place any extra cost on people who would want to mod the game.

Helpfully, Unity comes with a ‘StreamingAssets’ folder which doesn’t get compressed when built, so we have an easy place to put any files that we want to ship with the game, and in doing so providing a great example of how to create content for the game for the modders since that is also where we store most of our own data. We make extensive use of this folder and have made several simple file loaders in the game to deal with each type of data. The data ranges from simple things like weapon attributes and character names to more extensive data like dialogue files, scripts and graphics.

The ‘Gladius’ equipment folder containing all the information needed to load the sword in game.

The image above is a typical data folder as we have it right now. The game knows to look in the Equipment folder any time it needs to load (Surprise!) equipment data into the game, and all the file types are easily editable. The .obj file for the mesh can be edited in any 3d program, the stats/attributes and descriptions can be opened in any text editor, and the diffuse, normal and specular maps can be opened in regular image editors. The folder contains everything the game needs to know about the piece of equipment, and can be copied and renamed to make a new version of the Gladius.

The equipment stats and other small data are done as easily readable .txt files with key-value pairs.

Luckily there isn’t anyone in the executive, legal or marketing departments that have thrown a fit about us openly sharing the raw content from our game with the players, mostly because those departments don’t exist, so we will most likely share all this content under the CC by NC license.

One of the issues of making the game so mod-able is the impact it has on performance and this is a compromise we have to work with. Luckily since we made the choice to make it mod-able early on, we could have this and other pit-falls in mind from the start and do some things to mitigate this such as compiling new assets automatically and thereby loading them faster next time.

This is a short summary of the art process used in creating the armour sets in Ludus.

Beginning with some research into Roman style art and props, I took a trip to the British Museum. I was looking mainly at Roman relics and weapons/armour that were on display to get into the mood of that era.

To help aid with the visual background, Vegard had gone to a one day event organised by Britannia Gladiators and had taken many photos of the re-enactments of gladiator combat along with reference images for the armour. These got the ball rolling and I began to design some of the shields based on the photos.

The re-enactment team done an amazing job of re-creating designs of the era, so we piggy-backed on their hard work and based a lot of our designs on their physical armor sets. Here are a few of the 3d models for the shields created and textured based on those reference images.

The modelling process for the Gladiators started with high poly geometry done along with some digital sculpting in preparation for extracting a low-poly or game friendly version.

I worked by sculpting directly onto the basemesh and extracting the various parts for texturing on a per-part basis, which enabled more control of the final UV area of the complete armour set.

Part of the workflow was to divide the UV area into 4 areas that would enable the meshes to be recombined in the game at runtime to reduce draw calls.

After each part was sculpted and retopologised, they were given quick UVs to get started with the painting and texture generation. Here is an example of one of the arm padding unwraps that would later have its UVs moved and rebaked into the correct UV area.

As you can see the same normal map could then be rebaked to a new location by cloning the original mesh and moving its UVs. I used 3d Coat’s texture baking tool for the rebaking, assigning the original mesh to the scene with the original normal map and assigning the target mesh (the one with the new UVs). This process would prove useful if ever we had to alter the UV layout in the future for any particular reason.

So the Process was as follows: Sculpt the Highpoly mesh, create the Lowpoly geometry from the high poly and bake out a normal map using Xnormal, from here I took the low poly mesh and the normal map into Substance Designer/Knald to extract more useful texture maps such as AO, Cavity and Curvature maps.

In Ludus we are using Physically Based Rendering which requires us to create Diffuse, Specular Colour Maps and Roughness Maps. We chose the Specular and Roughness map approach over the Metalness/Roughness workflow, as we found it more straight forward and easy to read visually in Photoshop. We are using the Lux shaders for Unity that support this visual approach well.

Now that I have 2k textures for each part, I can go ahead and texture each part using Quixel suite:

Quixel suite allows for full control of edge wear, dirt trapped in occluded areas and most importantly the mega scan based materials.

I also created a few custom materials based on photos of various cloths and metals to aid in the process.

I created ID maps for all the different parts so the materials could easily be assigned in Quixel Suite and we could make easy adjustments to the final textures.

The ID map defines different materials on this wrist guardOne of my custom Brass metal materials

The greatest part of this process is messing around with various materials based of the ID’s, instant texturing has arrived!

With everything created and rebaked using this process we end up with the final texture maps and a new ID map based on the new UVs which is used on the final model.

Finally here is the full textured version of the Hoplomachus Armourset.

In Ludus we are trying to make the code completely modular, so all the systems exist on their own with as few dependencies as possible. The systems fetch all their information from the world, process it, and then put the information back into the world instead of sending information around to different systems.

We don’t have too many things in the architecture that we are strict about but this part is important because we want to be able to replace and improve the systems independently without affecting too much of the code-base. The bigger the code base becomes and the more sub-systems that are put into the simulation, the more important it becomes to be able to work on something without breaking something else. It also helps make it easier to implement and debug just one aspect of the game, and also means by serializing just one class we can save and load everything we need simply by ‘saving the world’.

In our case, the world object currently keeps track of only a handful of primary things:
-The characters in the world.
-The relationship between those characters.
-The upcoming set of gladiator games.
-The active rumours in the world.
It also has a bunch of helper methods to for example find a character with a certain profession or to get the asymmetrical relationship between two characters (I like you but you don’t necessarily like me).

Almost all the characters in our game are generated at runtime and as I mentioned are stored as data in the world object. The world object is persistent between the scenes and so when we for example need to load the slave trader into the market scene, we first use a simple proxy object to place the character visually in the level editor. The proxy object has a little replacement script on it that finds the world object and requests any character in the world that fits the description, in this case: the occupation ‘slave trader’. The world object finds the most appropriate character or generates a new one with the required properties so the important professions will always available in the game. This is extra important because in our dynamically changing world with senators vying for position and fighting out personal vendettas, some of them have a tendency to lose their heads, both figuratively and literally. In other words, if something unfortunate has befallen Quintus the slave trader; Julia, whom just so happened to recently move here from Aegyptus, will be there to replace his function in the game. She may not be as friendly on the prices, but she’s got a keen eye for gladiator talent and you can start a brand new professional relationship with her. That’s a good thing because Quintus had been getting on your nerves and that was why you told everyone he was sleeping with the magistrate’s wife .

Quintus position has become untenable and he gets replaced by the more favorable Julia.

As you trade and talk with this new character, the state of your relationship is updated from the conversation system to and from the world object, but the character placement system only knows that there has to be a character in this 3D position with the occupation ‘slave trader’ and the corresponding conversation trigger on it.

Now a small anecdote which originally lead to this blogpost:
Upon realizing that I needed to store all the things in the world in some way, I adapted the already existing inventory system to use as a kind of world state for the prototype. Gradually I added more things and realized I needed to store arrays of characters in there. This lead to conceptually peculiar parts of the code-base like Inventory.AddSlave() and Inventory.GetCharacter(occupation as string). The principle of idea of the world object was good though, and it’s still called Inventory in the codebase.

Ludus is a business simulation game crossed with a role-playing game, where you play as the head of a gladiator school. In your pursuit of becoming a successful Lanista, you must procure good slaves, train them as gladiators of the arena and put on amazing shows to the roar of the crowds.

In order to be commissioned for new games, you must also pick your friends and enemies carefully as you navigate your way through the deceitful social environment where every pleb, magistrate and senator is looking out for themselves. Socialize with the best people in society, and cut deals with the worst.

The gameplay consists of two phases; the Managerial & Role-playing phase and the Games Resolution phase

During the Managerial & Role-playing phase, you have many options available to you, but only a limited amount of Action Points [AP]. You can upgrade your Ludus and the Arena, hire new staff and set out the training schedule of your gladiators. You may also choose to buy slaves at the market, buy new armour and weapons from the blacksmith, advertise your up-coming games to build hype, visit the bath-house for a chance of bumping into the upper echelons of society (and gain new patronage), visit the tavern to learn about rumours and place unsavoury bets, or carry out missions to gain the patronage of ambitious magistrates. Various events will take place in this phase where you have multiple options to choose from and that affect your social position, the gladiators, your Ludus, or even your personal character. The role-playing aspects of the game immerses you in the role of the gladiator manager, and provides you with a lot of options to fit your player style and helps you carve out your character’s vices and virtues.

In The Games Resolution phase of the game, you take the role of the tactical coach, while the matches that you have set up for the current Games play out in the arena. You shout instructions to your gladiators to change their stance or alter their attacking intensity. The gladiators attempt to follow your orders as best they can, though it is not always easy to get a new order across to a gladiator mid-fight when his leg has just taken a knock from a sledge hammer and his helmet is obscuring his vision and hearing. Your objective is to give the audience a great show whilst not killing off or heavily injuring too many of your gladiators. The gladiators play as either Heroes or Villains, and their aptitude for this is determined by their statistics as well as how you have kitted them out. It is not enough to just fight, the gladiators must excite their audience by doing so in an impressive manner. The excitement of the audience must at least match the hype that you have built up for the games for the audience not to go home unimpressed, and the Editor/Sponsor of the games being displeased with your show.