The architecture of Scalar series has long been a secret, but with Scalar2, the design has finally reached a stable state.
Most bots follow hand-crafted Movement/Gun/Radar horizontal slices, but a component system is more suitable for "super-mega bots". And here is the evolvement of the component system of Scalar Series:
1. ScalarBot's component system is fairly simple, each component simplify has the raw events from robocode forwarded, like most robots' component system do.
2. ScalarN and ScalarR has a reflection based event dispatcher that decouples event firer and event listener, and some 'read-only' services provide information shared between Movement/Gun/Radar. This is essentially vertical slicing before Movement/Gun/Radar horizontal slicing. However, the horizontal slicing part is listening to raw events from robocode directly, as 'read-only' services do, which complicates the information sharing.
Like mentioned in User talk:Rednaxela/BotBase, the architecture of the "one" generation of Scalar series is already component based, service-oriented and event-driven, and ScalarR also features some data-centric approach. However, the flexibility provided by the component system also makes data logging and component simulating hard, as the dependency of each component is relatively unclear.
Then, with the experiment of ScalarG, a gun experiment platform that features multiple level of data logging and simulating, the successful component of ScalarN, ScalarR and ScalarG has been finally made into Scalar2.
Instead of being entirely built upon event based component system, Scalar2 has two vertical layer of components. The first level is event-driven, handing raw events from robocode and features full flexibility with highly decoupled information sharing. The second level is more like microservices, with self-contained functionality and clearly defined interfaces that each defines all input and output of a service, no more obscure dependencies at this level. Since the complexity of raw events are already consumed at the first level, anything needed in the second level is nothing more than some structs with no hidden states, even the need for 'read-only' services is eliminated. With this approach, each component at the second level is perfectly simulatable, making the use of machine learning methods such as genetic algorithms easy and feasible.
An example of microservices design of ScalarG/Scalar2 is Motion Representer service. It encapsulates the logic of representing the motion of a robot between a wave is fired and the wave hits it. Implementations of this service can be Guess Factor motion representer, Play It Forward motion representer, Displacement Vector motion representer etc. The difference between those motion representing methods are hidden under the interface, and the input of the service is also clearly defined, making the use of motion representer in simulated environment trivial.