From: Erik V. <eri...@xs...> - 2010-06-26 14:01:52
|
See below. -----Original Message----- From: Stefan Frey (web.de) [mailto:ste...@we...] Sent: Saturday 26 June 2010 00:24 To: Development list for Rails: an 18xx game Subject: Re: [Rails-devel] 1856 bugs in Rails 1.3 -- undo duringCGRformationhangs game 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. [EV] Perhaps a better example is the existing Phase.addObjectToClose() method, which in fact provides a register-for-callback function. It's currently used to close/remove some specific privates, bonuses and bonus tokens; in this case, on phase changes only. Indeed I already had in mind for some time to extend this function for wider use. Closeable could be extended to (or become a subinterface of) Triggerable. [EV] I doubt if it would be wise to overload State/Move with such new functionality. It's low-level, and IMO should stay so. 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. [EV] This reminds me of an idea that Brett and I have discussed several years ago (should be in the archive): to make the [OR] actions and their sequence configurable (in Game.xml). Some actions can only be done in the proper sequence, like tile/token laying. Some steps are optional or conditional (e.g. must have the money to lay a token). Some can be executed at any time (private buying). An XML structure should be designed to cover all such possibilities. [EV] Currently, sequence management is shared between the rounds and the game manager. I don't know how that could be pulled out into a separate structure, and whether it should, but it might be an idea worth further consideration. 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. [EV] How about the fact that several different actions types might be allowed simultaneously? Such as private buying and loan taking, that in many games can be done at all times during an OR turn? 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. [EV] OK, this kind of answers my question above. However, I would rather trigger it by the LayTileController finding that the action is/can be/has been executed, rather than the TileMove, which is only the physical execution phase. See my comment above. 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. [EV] I wonder to what extent this can be done 'step by step'. In particular C) will be hard to do stepwise. I would propose to start with a pretty isolated case, like the 18EU start round. Or the 1835 start round, which has old code that needs an overhaul anyway. [EV] It's too early to give a final answer to your ideas, but it all sounds rather good, and, as said, partially fits with ideas I already had. But you are going a lot further, and I can't yet quite oversee everything. An actual working case might make it much clearer. Erik. |