MultiMachine Truckin FiledOn: [phylum]<loops>doc>MultiMachineTruckin.tty 1) Initializing the game: At some point we may want to have a description language to describe the state of a gameBoard at any point during the game. However, initially we will use the fact that the entire gameboard is generated deterministically (for a given Loops-Truckin version) from a single random number seed. Therefore, to get the game board initialized the same way on multiple machines, the only information that needs to be sent around is the initial seed. The needed remote call is: (NewGame randomSeed boardType gameType) To make a player one needs to specify the truckType, (className of truck) and the driver (label for the truck). (AddPlayerRequest localMachineID driverName playerClass truckType ) ****(In the following, some old vocabualry is used. This file has not yet been updated to use the new terms, User Interface, Simulation, Decision Module, and Communication Interface. Machine Configuration The game is actually run (the truth about the world is kept) in one machine. Let us call the gameMaster who runs this game the WorldMaster. The WorldMaster is the one who fields requests from the players to Buy, Sell, and Move, and who causes the GasTruck and Bandits to move, and who specifies the maximum move for any vehicle on each turn. Any other gameMaster who is following the game remotely let us call a SlaveMaster. The Slavemaster forwards requests from any player(s) on the machine, and receives messages that cause it to update the world. Two distinguished solutions to the updating problem occurred to us: Message centered updating and ActiveValue centered updating. Both would pass messages between the WorldMaster and the SlaveMasters through a Postmaster, which ensures communication without delaying the WorldMaster. In message centered updating, messages describe high level changes to the world. In activeValue centered updating, changes to appropriate instance variables of objects are passed across as messages, and receivers determine what to do on the basis of these changes of values. Details of Message Centered Updating In this style the WorldMaster sends to the SlaveMasters messages indicating what has happened in the game, from the point of view of the semantics of the game. The following are the messages (not including the two from above): (MoveMade playerName fromStop toStop reason penaltyAmount missTurns) reason is one of NIL(as requested), Bandit, WeighStation, NoFuel, UnionHall, OffBoardBeg, OffBoardEnd, ConsecMoves, IllegalLoc, MoreThanAllowed, AlreadyThere, NoRoom, LowFuel, NoRoomStayPut, BanditMove, IncorrectLoc, GameOver and is stored in Truck IV location:,reason fromStop is included for redundancy as is roadPosition below (BuyMade playerName roadPosition requestedQuantity quantity reason penaltyAmount fragility lifetime ) reason is: NIL (as requested), InsufficientCash, IncorrectLoc, NotProducer, Zero, MoreThanAvailable, InsufficientVolume, InsufficientWeight, GameOver (SellMade playerName roadPosition requestedQuantity quantity cargoPosition reason penaltyAmount) -- cargoPosition is specified as position in cargo list reason: NIL (as requested), IncorrectLoc, NotConsumer, CannotBuyZero, InvalidCommodity, NotOwned, MoreThanOwned, PerishedGoods, TooMuchQty, PriceHigh, GameOver (GasFill prevPosition newPosition newQuantity newPrice) (BreakCargo playerName cargoPosition) (SpoilCargo playerName cargoPosition) (MaxMove playerName maxMoveSize) (AddBandit name) (AddPlayer localMachineID playerName playerClass truckClass deniedFlg) (RemovePlayer playerName reason) (NewGame seed boardType gameType) (ReUseGame seed) (StartGame beginTime endTime) (ParkedAtAlice player time) (GameOver) The following messages are sent from a SlaveMaster to the WorldMaster: (MoveRequest playerName fromStop toStop systemReason) systemReason: NIL (user request), AliceTurn, AliceTime (BuyRequest playerName roadPosition requestedQuantity) (SellRequest playerName roadPosition cargoPosition requestedQuantity) (AddPlayerRequest localMachineID playerName playerClass truckType) (BeginGameRequest ) (NewGameRequest boardType) (ReUseGameRequest) (RemovePlayerRequest playerName reason) reason: NIL or LocalRequest (user request), Active Value Centered Updating In this scheme, active values would be placed on all appropriate variables to send the change. To communicate between machines, it might be useful to give canonical names to many objects. For example, the roadstops could be RS1, ... RS78. The players have their drivers name, and the trucks are named <driverName>Truck. When a commodity is created a message is passed which specifies (CommodityClass <newCommodGensym> <initialValues) The following are the set of instance variables which need to have avs which note when they are changed: Truck cashBox location location:,reason location:,maxMove weight volume fuel Commodities status owner fragility lifeTime BanditTruck location RoadStops quantity price parkingPlace1 parkingPlace1:,howLong parkingPlace1:,timeUsed parkingPlace2 parkingPlace2:,howLong parkingPlace2:,timeUsed GameMaster timeLeft currentPlayer players The advantage of the Active Value Centered Updating is that it requires no updating to the current gameMaster. The disadvantage is that while the slave machines get all the world changes, they have to reconstruct the scenario which led to the change - something which may not always be easy. Of course, active values (though a different set) may come in handy here, i.e., the active values on other machines would take some action when the changes took place. How do we setup these active values, so that different sets of active values may be installed for slave vs. main machines? Approach 1: Basically have a installation phase where different machines run a special code to install the appropriate active values. Testing out such an approach would be hard as it would require the multi-mc setup. Editing/changing this installation code could become quite messy. Approach 2: Keep different active values on distinguished properties of variables for which we need such active values. Then for each such type of active value (say SLAVE, MASTER, COMMENTATOR), when the instance of these classes are created, they could be sent a message asking them to ChangeMode to one of these kind. The ChangeMode method (possibly inherited from Object) could basically cycle thru all the IVs/CVs and if they had the distinguished property, would copy the active value expression from the property and wrap it around the copy of the local value. Adv: 1) These various active value expressions would be in the same class, thus easily inspectable and editable. 2) The mode of an object could be changed any time AND the decision would be made at instance creation time BUT not automatically apply to all instances of a class (as would happen if these active values were attached to the class). [Thus now instances not only have a class but also a mode] Postmasters Communication between machines can be handled by a PostMaster. PostMasters know about distribution lists. It ensures communication of all messages to all participants, and ensures that it will be available to listen within a short period of time. It accepts messages: (Register distributionListName nickName machineAddress) (ForwardToAll distributionListName message) (ForwardTo nickName message) (Unregister distributionListName nickName machineAddress) Letters to unregistered persons or lists are sent to the Dead Letter offfice (No returns, no notifications). On {phylum}<jonl>postmaster is an implementation of the postmaster functionality you requested. (Unfortunately, I've had to spend most of this past evening finding and changing parts of EVALSERVER to accommodate the new changes in fugue, so it's not very well tested) It assumes that the worldMaster will be doing (REMOTEVAL '(ForwardTo Harry (MoveMade ...)) <postmasterPUPaddress> 0) That is, ForwardTo and ForwardToAll are NLAMBDAs, and the worldMaster needn't wait for any results. On the otherhand, Register and Unregister generate errors for various conditions, so it would be wise for their usage to be like (REMOTEVAL '(Register GamePlayers Harry 240) <postmasterPUPaddress>) Both Register and Unregister are NLAMBDAs too. There is as yet no "hair" in it, but it can easily be added; e.g., grouping a bunch of messages together into one big PROGN, if there are multiple messages queued for some machine; or statistics and record keeping (beyond the basic DistributionList maintenance).