JProcWars Documentation JP Hindin Version 0.2 JProcWars: This game is a strange meeting of CoreWars and RoboWar (I think). The object of the game is to code a Warrior (out of perl) to defeat other warriors. Warriors start with 5 hit points. They can "hit" each other, they can replicate (produce identical copies of themselves), the usual. The Warriors name is that of its filename, nice and simple. A Warriors "full name" (Or its $0) is changed on initialisation (taken care of without your help or intervention) to something along the lines of: !mywarrior_5453, where mywarrior is the name of the Warrior (Gasp, horror, originality) and 5453 is its PID. Launcher: The central piece of software here is the launcher, which starts up the warriors and sets them in motion. As well as this, it keeps track of whats running, and passes messages between warriors. The launcher will continue running until either you tell it not to (SIGINT) or there is only one warrior type is left running. Messages: The launcher runs a UNIX-domain socket server to allow communication between warriors, and the server itself. Each transmission is called a message. Possible messages are listed in more detail below, however, an overview: When a warrior is generated (through game startup or replication) it registers with the server. When it dies, it deregisters. When a warrior hits another warrior, the message is passed via the server. You get the idea. You can also pass custom messages between warriors, but we'll get to that later. Messages for a warrior are stacked in a queue, and read once every time around the loop (See below). There is a message handler put into the while loop before the WCode, where the messages "Hit", and "Shutdown" are acted upon. All messages, regardless of whether the handler processes them or not, are pushed into @lmsg. This allows you to read over them yourself and perhaps decide on a different course of action - and to read your own custom messages passed between warriors. WarriorCode: Warrior code is any valid perl code, with a few exceptions. The code is in two sections, the pre-declaration and the main code. During runtime, the warrior code (WCode) is folded into the CS code to produce the final warrior, thus the need for the separate sections to allow for declaration of "global" variables. Everything inside the main section will sit inside a while(1){ } loop, and the pre-declaration section comes before this. WCode is sectioned as follows: ----------------------------[ ;predecl my $state = 0; ;main # Do something else ----------------------------] Exceptions to valid perl code: No forking, or local execution of commands (exec/system/backticks) The CS code: The Code.CS file contains three sections, which when combined with the loaded WCode, produce a working Warrior. The three sections are ;precode, ;header and ;trailer. The completed code is put together in the order: ;precode ;predecl ;header ;main ;trailer The purpose of the CS Code is to provide basic required game functions to the Warriors, to make sure that certain things are taking place (Example: Altering the warriors hit points after a hit). The Precode contains the system global declarations, and also contains parsed markers. These markers are filled in upon WCode compilation. The Header is made up of the opening while() loop, a quick printed status line, the server message check command, and what to do when we die. The Trailer ends the while() loop, and adds a 1 second delay to the code, in an attempt to slow down code execution a little. Messages passed between client and server - Only full names passed: Registering\aWarrior Register the warrior Warrior Deregistering\aWarrior Deregister the warrior Warrior Hit\aToWarrior*FromWarrior Hit ToWarrior from FromWarrior Read\aWarrior Send Warriors message queue to client (two-way) WarriorList\a:) Request for warrior list (two-way) Header\a:) Header of a message queue Available Variables: $me The name of the Warrior (corresponds to the filename) $DEBUG Universal debugging boolean $hits Hit points left $lhit_n Full name of warrior who hit me last $lhit_p PID of warrior who hit me last @lmsg Queue of last messages received. (See messages) Available Functions: FindWarriors(), returns HASH Returns a list of ALL warriors registered with the server, where the hash key is the warriors full name, and the value is its PID. FindEnemyWarriors(), returns HASH Returns a list of only ENEMY warriors registered with the server, in the same format as FindWarriors(). Hit($Warrior), returns BOOLEAN Hit $Warrior (full name), returning 1 if success, or undef if an unsuccessful write to the server occurred. Replicate(), returns BOOLEAN Spawn a new copy of myself. Returns 1 if successful, or undef if either: Replication is turned off, or there are too many existing processes to allow replication at this time. Msg($Warrior, $msg), returns BOOLEAN Send $Warrior the message $msg. Configurable values: In the launcher: $OutputMODE, when set to 1, will output the post-compiled WCode with a #! header for perusal. (NB: Without the launcher's server running, they don't do much); $DEBUG, system wide (Warriors included) debug boolean... I don't actually use it, but I figured other people might (Or I might later). In JProcLauncher.pm: $CS_Code is the name of the CS code file to load, which includes the ;precode, ;header and ;trailer code sections. In JProcRoutines.pm: $MaxProcs is the maximum number of processes warriors may use up, including replicated copies. Give a few on this number folks. (And if you're going to do a big tournament, you might want to change this number to make sure its greater than your number of combatents). $ReplicationAllowed, when 0 disallows replication of any kind. When a Warriors tries to Replicate(), they will be returned an undef.