From: Stefan F. (web.de) <ste...@we...> - 2010-06-25 22:23:50
|
Erik: I agree that hardening Rails is important, and I believe that this includes improving the internal structure: Before starting the route calculation I was looking into some core mechanisms in Rail and I would like to return to this task now: In the process of planning the changes required for 1870, I realized that some additional structures would help to deal with some of challenges, that new 18xx might bring to the table. I will shortly outline my ideas, before I make more detailed suggestions and/or provide some prototype implementation. I hope for some feedback? The proposals are mainly independent, but they link with each other well. A) Triggerable Events 18xx games have a major class of triggers: Purchases of trains can change the (game) Phase, which themselves (potentially) impact any dimension of the game play. Rails implements that already with the Phase/PhaseManager class. But digging deeper, nearly every 18xx has some actions, which have side-effect, but are not (full) phase changes. Even in 1830 there is at least one example: The purchase of the first train by public B&O closes the private B&O. A very striking case is the destination run in 1870. Each tile lay a public company can trigger this sequence of several actions for any other company. On the first glance I believe there should be a a trigger / triggerable interface combination. But Rails already has a potential trigger infrastructure in the state/move objects. Thus triggerable objects should define the potential moves/state changes and register themselves to those changes. B) Round/Turn Sequence and Queuing The sequence of rounds and that of activities inside of rounds is currently managed inside the classes implementing the executing logic. There is no (additional) framework/classes controlling the sequence alone. Any interruption of the standard sequence requires some tweaks to make that happen. And one has to be carefull to make it undo-proof. There are several examples already in Rails for such interruptions (especially the treasury shares and merger rounds). 1870 would add for example share protection here, which changes the sequence inside a stock round. A general framework (call it SequenceManager) which controls the sequence of rounds and turns (activities inside a round) would make thoses cases easier. New rounds/turns would register themselves with the SequenceManager, which should also support the queueing of rounds/turns (take merger rounds as example, which might occur only after the round/set of rounds is finished). It also manages the consequences of undoing those sequence changes. C) Splitting of the Round Classes The two subclasses of Round are currently the swiss army knives of Rails: StockRound and OperatingRound are the main generator and consumer of actions (in addition they are responsible for the correct sequence of activities during Rounds, see above). This has some benefits (espcially synergies with respect to joint variables and commonly used methods), but would work not very well with the more flexible structure suggested in B. To gain the full benefits breaking up of the round classes into smaller sub-units is required, at least from my point of view. My suggestion here is to use an action type as the atomic unit for such a split. Thus for example a LayTile action works in parallel with a LayTileController, which generates the action and processes the actions. The final configuration would look like that (somehow simplified): A (simplified) OperatingRound controls the sequence by adding the different Controllers (LayTile, LayToken, Revenue, BuyTrain) to the SequenceManager. The SequenceManager would activate the controllers according to the defined sequence. The controllers would generate actions and process the responses from the UI. After executing their actions the controllers would deregister themself from the SequenceManager. How does a destination run in 1870 work? This special (game specific) object is triggerable by TileMoves and checks if the conditions for a destination run is met: If so, it adds itself (or if possible a modified Revenue and LayToken controller) to the SequenceManager with the instruction that those actions are queued at the end of the turn of the acting company. I have already some ideas, how that structure offers better support for optional actions and special properties, but I want to focus on the general ideas first. So what are you comments? All of this will for sure not be done in a single step, but only step-by-step. Stefan On Friday 25 June 2010 11:15:35 Erik Vos wrote: > Stefan, > > Thanks for your analysis. Yes, I agree that Rails should be further > hardened in the aspects you mentioned. > Anyway, I think I'll remain in bug-fixing-and-hardening mode for some time! > > Erik. |