Darwinbots 3
Check the following link for a real-time discussion of features and progress: IRC
Darwinbots 3 is a long term project to recode Darwinbots in C# as a brand new program. Every feature and aspect is going to be examined and refined as its added, in a framework that will ensure robustness and agility in handling bugs and new features. The code can be browsed: http://www.darwinbots.com/svn/Darwinbots3/
Contents
- 1 Compiling the code
- 1.1 Getting the compiler
- 1.2 Downloading the dependencies
- 1.3 Get either Subversion or a Subversion client
- 1.4 Accessing the repository and committing
- 1.5 How you should set up your SVN projects and local directories
- 1.6 Visual Studio solution files
- 1.7 Junk directories and bin folders
- 1.8 You have the code, now what?
- 2 Coding standards
- 3 Modules
- 4 Release pattern
- 5 Architecture (Out of date)
- 6 Design
- 7 Milestones
- 8 Subarticles
- 9 DNA
Compiling the code
Getting the compiler
You'll need a version of Visual C# 2008 (this all might run under Mono in Linux, but I don't have either so no promises). You can download C# express for free. If you're prompted on whether to install any SQL components, choose yes. The whole process will probably take several hours to do. The good news is that even if you never start programming Darwinbots, you just found a free high quality compiler :D
Downloading the dependencies
To compile the project, you need:
- XNA 3.0 - A game library released by Microsoft which is used for graphics and math related things.
To help work on parts of the project, you need:
- NVidia Shader Debugger - Makes building and debugging the shaders in Graphics.XNA much easier.
To distribute the project, you need:
- ILMerge - Allows multiple .NET assemblies (.DLLs) to be packaged into a single assembly.
- NETz - Allows packing of the exe to make it smaller.
- Double check what needs to be installed .NET wise and XNA wise (redistributables).
Get either Subversion or a Subversion client
For those unfamiliar with version control, it's basically a way to ensure that multiple people can work on the same source code. You "check out" a copy of the current source code from the repository and store it locally on your computer. You then change the source code in places and "commit" it back to the repository. If there have been changes in the mean time that conflict with your changes (should be a pretty rare occurrence), SVN will notify you and ask you to resolve the problem before the commit is applied to the central code repository. Another advantage of working this way is that the entire evolution of the code is tracked. If some bug is found that was introduced months ago, you can browse through the repository at different versions of the program to find what changes caused it.
You can either try one of the Subversion commandline builds if you're into that sort of thing, or try one of the GUI based Subversion clients. Numsgil uses SmartSVN, which he highly recommends.
Accessing the repository and committing
http://www.darwinbots.com/svn/Darwinbots3/ This is the link for the repository. It has anonymous access, so anyone can download and browse it. To commit changes, you need a username and password. Post a request for one here. If you haven't registered in the forum yet, please do so. It's important that progress is talked about so others can see what's going on.
How you should set up your SVN projects and local directories
I recommend setting up two SVN projects. One for the 3rd party libraries, and one for the current branch your working on (or trunk or a specific tag or what have you). It doesn't matter where you put the source code, as long as the current branch you're working on is a sibling to the 3rdParty folder. For example, this is the suggested setup:
- \Darwinbots3
- \Source
- \3rdParty <-- sync this to the 3rd party directory in the repository
- \Trunk (actual name doesn't matter) <-- sync this to the trunk directory in the repository, or one of the tags or branches if you're working from them
- \Source
Again, the source folder doesn't have to be inside your Darwinbots3 folder, but 3rdParty and Trunk (or whatever you name it) need to be siblings.
Visual Studio solution files
Instead of one large master solution file to build the entire project, each module maintains its own solution file for just that solution. Usually it will contain the module itself, some unit tests, and a test app. This is to make checking unit tests for errors simpler, among other purposes. To build the entire project, you'll need to run one of the build scripts in the Scripts directory. Note that you shouldn't need to do this very often, since the end binaries are submitted to the repository.
Junk directories and bin folders
The projects are set up to place bulky build files in the Junk directory. This directory should always be empty on the repository, except for the "About This Folder.txt" file. Final EXEs are built to the Bin folder. Only release binaries are on the repository, and are what projects use when they want to import another (for instance, the release build of UnitTestSharp is used for the unit testing projects). Note that this can cause weird problems if you build a project in debug mode and not in release mode, and then submit code changes to the repository, since the binary and source code will be out of date (if anyone can think of a better way to handle this sort of thing, I'm all ears).
Under the scripts directory, there are scripts for publishing from the Bin directory to the top level Darwinbots3 directory (essentially publishing locally) and scripts to clean the junk folders (delete files and such).
This setup is subject to change based on usability issues.
You have the code, now what?
Each module has its own solution file. Because many modules have interdependencies, the release libraries are on the repository so you shouldn't need to compile all the projects first time. You can just open one up randomly and compile it and it'll work. Alteratively, in the Scripts folder, there is a batch file called BuildAll-Release. Run that file. You might need to run it more than once depending on what order the batch file decides to build the modules in.
Coding standards
Basic Standards
I'm using this standard, or trying to anyway.
Repository etiquette
- Prefer to post lots of small, atomic changes over large, far-reaching changes. It's easier to integrate for other people, and minimizes the possibility of commit conflicts.
- Keep the repository's code running. Don't commit a change that would break the program, or worse, prevent it from compiling. If you do anyway, fix the problem immediately.
- Be careful what files you submit. If it's a large file it will take up repository space for ever and ever, even if you remove it from the repository later. Repository space is not unlimited.
Unit testing
Unit testing is a way to ensure that a function or section of code works like you think it should. It is immeasurably important for keeping the code robust and bug free. It also makes refactoring much easier. this site is an excellent introduction to Unit Testing for games.
Ideally, you would write the tests first and then "fix" the program to pass those tests. This requires some discipline that I personally don't always have, so I'm not going to strongly enforce this. Aim for this standard anyway. Definitely unit test as many aspects of the code you're working on as possible, even if it's after the fact.
Design patterns
I'm not too concerned about strictly following design patterns, but you should at the least be aware of them. This article shows the more common design patterns and examples for them. Personally I've found various factory patterns useful for things like the DNA language parsing and unparsing.
Modules
Modules generally have the following structure: there's a "core" API which is essentially a wrapper around different implementations (for examples, see the graphics modules). These "core" APIs will automatically search for and load any appropriate implementations in the same assembly or search for assemblies in the same working directory.
Each of these implementations will have the core library, a unit testing project, and a demo framework. The unit testing project is built with UnitTestSharp and is designed to be run as a post build step of itself in the solution. So if you build the implementation in the IDE you might notice that the unit testing project is reporting that it's failing to build. This can be either an actual compile error or a failing test (which will be treated as a compile error. Double clicking on the error will usually take you to where in source it's failing). The demo framework is a (generally untested) simple app which can be used to interact with various aspects of the module in question without waiting for it to be integrated into Darwinbots3 in the final stage. For instance, for DNA there's a console version which let's you write DNA code and see the results. For physics there's a "physics playground" with various physics scenarios presented to the user to inspect. These demo frameworks generally won't be presented to the end user. They're more for developers.
Release pattern
When a new release is ready, it's given a version number. The format is:
- Darwinbots3 AXXXXX.exe - An alpha release. The XXXXX is the source control revision (ie: the changelist number in the SVN) corresponding to the executable
- Darwinbots3 BXXXXX.exe - A beta release. The XXXXX is the source control revision corresponding to the executable
- Darwinbots3.0.exe - The first feature complete and stable release.
- Darwinbots3.XXX RC1 - A release candidate. The number after RC is the release candidate version. The XXX is the version number (starts at 001, goes to 999).
- Darwinbots3.XXX - The stable release for version XXX.
Note that these files alphabetically sort according to when they are expected to release. This is important.
Architecture (Out of date)
I'm designing the program around the idea of "data-centered". You can read a paper about it here (just browse through it, it's pretty big. Focus on the part near the beginning where he explores different architecture models).
Basically, each module interacts only indirectly with other modules through a central data repository. Instead of a something like monster[456].Draw(), you'd have Draw(Monster[456]). The benefit of a design like this is that it allows you to swap different modules (change your graphics from OpenGL to Ogre, for instance) easily, lowers the allowed interdependency between modules, and lets the modules themselves be reused in different projects.
In general, all the game data, such a bots, shots, ties, etc., go into a central repository. A method goes into class of a data object only if it's strictly involved with manipulating the data and not doing something to it. For instance, a function that takes an amount a bot is supposed to be charged in nrg and gives it waste too should go with the bot's class. A function that handles collisions between bots and shots should probably go in a module. It's not strictly black and white, but generally ask yourself if adding a function ties the data directly together with a module. If we wanted to swap out one of the modules, would we find it difficult to disentangle the data repository from it? If so, it belongs in a module (in the case of the bot shot collision, it would probably belong in the game logic module).
The following is a rough draft of the different modules I'm planning:
- DNAModule AKA Sunweaver - A fairly self contained module that handles most of its own functions, parsing, etc. Very little interfacing is needed with it beyond a few "black box" controls.
- Graphics Module - Consists strictly of calls to OpenGL, assuming I use OpenGL.
- GUI Module - Contains the dialog boxes and windows the user will probably use and see, all written with Forms.
- Game Logic Module - Handles the core simulation, minus physics and DNA.
- Math library AKA Azimuth - A low level library of basic math primitives and functions like vectors, matrices, and solving systems of linear equations.
- Physics Module AKA Lodestone - The physics engine for Darwinbots, coded for a great deal of feedback as far as collision forces, etc.
- Networking - Handles interfacing with the internet. Users could download bots from an online database right from the program, for instance. Also internet sharing, program updates, etc.
- Disk IO - Handles serializing the data. Data will probably be saved as zipped XML files, to allow for outside manipulation through scripting languages.
- MainExe - Basically nothing more than calls to the different modules to initialize them and start the game loop, calling each module in the proper order.
- Central Data Repository - Stores references to bots, shots, ties, DNA, etc. Very little algorithmic work going on.
These modules ideally would end up as seperate DLLs to help enforce modularity, but this might cause cyclic dependancies, so I'm not holding my breath.
Design
Visit the wish list to see the major features under consideration from the point of view of the end result. Discuss them in the forum.
Milestones
Milestone 1 - Basic functionality version
Subarticles
- Physics explanation - An explanation in plain of how the physics engine works.
- Modules - A list of modules involved in Darwinbots3 and an explanation of how each works.
- Tasks - A list of relatively self contained tasks which need doing.
DNA
Visit the Robot DNA page to see how the DNA will work.