18. December 2009 21:56 by David in
Over the next couple of blog posts I will be creating a simple DSL for a Role Playing Game (RPG). DSLs are often used in the games industry to combat the huge amounts of complex data within AAA titles. A RPG will often have thousands of different characters spread throughout the environment each having different:
- Animation cycles and sound effects
- Characteristics such as hit points and strength
- Armour and weapons
All of this information eventually gets fed into a C++ engine that actually runs the game. This means either all of the members of the team need to be professional programmers or the game’s data needs to be managed and manipulated elsewhere. While a CSV or XML file can provide some assistance eventually the designer will need to be input state based behaviour:
If HiPoints > 20
Attack closest player
Else
Run away
This type of logic is extremely difficult to embed into a CSV file. However it is relatively simple to create a DSL allows the Game Designer to define each creature’s characteristics and the effects of items and spells.
DSL Background - Ubiquitous Language
A core tenet of Domain Driven Design is the Ubiquitous Language where business users and developers, use a shared language and terminology to define each concept, within the domain. Instead of leaving this information in a document they are embedded into the domain objects within the system that is being built. By both groups using the same terminology the opportunities for miscommunication are greatly reduced. Further as the business and developers come to understand and respect the other group’s expertise the language becomes richer and the definition’s gain greater clarity resulting in the the domain objects being updated to replicate the new richer model.
DDD and Acceptance testing are a perfect fit. By having tests written using terminology from the Ubiquitous Language allows the business to create test cases early in the development process. These tests can form the basis of the project’s detailed requirements and allows the development team to build the meaty parts of the application extremely quickly and to a very high quality.
Business writing the software
The natural question to ask is “If the business can write the tests can they also write the software”? The answer is a resounding NO. Software development is very complex. Modern generic programming languages are designed to execute an infinite number of different programs. They do this by having a type system that maps to the architecture of the underlying computer. We use ints, floats and strings in our programs to represent concepts such as age, weight and names. Programmers are easily able to do the mental jump between built in types and the abstract concepts that are being simulated by the program and are described in the Ubiquitous Language. Further developers are able to look at control structures such as for loops and instantly recognise that some action is occurring on each element within an array. These skills are not universal and without them it is very difficult to understand any non-trivial piece of software.
The problem space that the DSL solves is making a programming language that allows a user to explain a business activity or business data using concepts from the Ubiquitous Language directly. So instead of having to understand an entire application with five hundred files, tens of thousands of lines of code and concepts such as component layering and patterns. They can either write or approve a small code fragment that looks surprising close to the Acceptance tests that they may are already actively creating.
Examples of useful DSLs:
DSL Requirements
If we treat our DSL as a tool to allow a business analyst or fairly technical business user to interact with our application we can quickly come up with some high level requirements:
- The language should use business or problem space terminology – Its pointless creating a DSL that isn’t intermit with the domain
- The language should include the smallest number of control structures as possible – The more complex the language the more difficult it is to learn and maintain. If statements and assignment should be adequate for the majority of problems.
- The DSL user code should be treated as any other development artefact
- Should be in source control
- Build server should validate any user generated code on check in – Very important since DSL syntax will change over time hence its vital to know when a script is no longer valid
- DSL should be very focussed – There is no reason not to have a couple of complementary DSLs on a single project each solving a single problem is a clear and simple manner