One other thing that people complain about alot that I need professional opinion on is the global variables. I admit I am guilty of using them often. But my question is in ideal conditions what do I replace them with? I made them public so they save state outside the scope of a subroutine. I could have gone with static but than I would not be able to capture there state for the save simulation code.
A strongly enforced
MVC distinction would help. Basically have the simulation state in an isolated bubble, and force communication to/from the simulation to go through specific channels, or at least specific places in code. The problem with globals is that you can't easily isolate what the side effects of a function are, which makes it difficult to test, and therefore difficult to modify. Rule one for responsible software engineering: clearly define what the inputs and outputs to a function are. If the input is the entire simulation, and the output is a slightly modified simulation, how can you ensure code correctness other than eyeballing it? Instead of passing in the entire simulation as globals, if you passed in just the info for robot X, that would be a step in the right direction. The narrower the input/output to a function, the easier it is to be sure it's working right and has minimal unintended side effects.
I will say this for the DB2 codebase: the overarching program flow is at least easy to understand. It's very easy to look at the code and figure out where some feature you'd want to add should go. But that does no good if you can't be sure you're not breaking something. Even simply refactors run the very real risk of breaking some feature or other, and we don't have good ways to know that something's broken. Even in a traditional video game, you can find bugs just by playing. With DB, if something is broken it just means that there might be some robots somewhere that don't work quite right. That's hard to catch.
Edit: A little follow up question: I think the code (although messy in a few places) is tied together reasonably well. I assume you mean there are better ways to tie code together in a more object driven language. Still more detail on this will be good. Edit: Actually answered this question myself by looking on the DB3 Core module that was just released. However, DB2 was never built object oriented, and refactoring it in a major way like this will probably break most of it. :/
Wouldn't have to be OO, though that's certainly the most common approach. It's more a matter of clearly separating code responsibilities, and you can do that in any language, VB6 included (I don't think VB6
forces you to write bad code). One part of code to manage DNA, one part of code to manage metabolic things like nrg and body and venom building, one part to draw things, etc. and making sure that the parts only communicate when they have to and through specific places in code. The problem with the code right now is that each part talks with each other part, often in strange places in code. Especially stuff around how the UI reads/writes data. Like, I wouldn't be surprised if there's some code in the DNA execution that updates a UI widget somewhere. That's convenient, easy, and wrong. Instead, you'd want the DNA to store relevant info in some debug data attached to the robot instance, and the UI widget to read from that debug data during some sort of "push sim data to the UI" method. Then you can test the creation of the debug data separately from the updating of the UI widget. It's not nearly as easy, and it's all sorts of extra hoops to jump through to get a new feature in, but it means you can test both halves in isolation.