|
Programming a Custom Scenario You can program your own custom Scenarios in Solar Vengeance using the C# programming language. You can write Scenario code in any text editor, but it is more productive to write the code in a full fledged development environment like Microsoft Visual Studio or SharpDevelop. In your Scenario programming, you can leverage the complete power of the .NET framework class library. The Scenario code is automatically compiled within the game, so executes very quickly during the game. A Scenario is a .NET class that derives from the Scenario base class. If you are using a development environment for editing, you should add a reference to the SCG.SolarVengeance.Engine assembly. Create a new .NET class, and make "Scenario" the base class. At a minimum you will then need to override the Description property and the BuildScenario method, described below. You can override other properties and methods to customize the Scenario further and introduce dynamic behaviors. You should give the Scenario class name the same name as the source code file that you create. For example, if you save the Scenario in a file called MyScenario.cs, the Scenario class name should be "MyScenario". Scenario Properties The Scenario base class contains a number of properties you can override in your derived class. Overriding these properties changes some aspect of the Scenario. public virtual bool AssignCapitalsThe default value of this property is true, and instructs SV5 to assign Capitals to Players if they are not assigned by the time the Scenario is created. If you override this to return false, Players will not have Capitals unless you assign them explicitly in the BuildScenario method. You may need to do this, for example, if your Scenario creates fleets of StarShips only, with no StarSystems. When writing a Scenario such as this, you should code your own Victory Conditions in the VictoryReached method. public virtual string
Author public virtual int CapitalValueOverride this property to specify a default value for players Capital StarSystems. The default value is 20, and this is also the maximum allowed. Players can modify this value manually when they select a Scenario to play. public virtual int DefaultResourcesOverride this property to specify the amount of Resources that players' Capital StarSystems should get at the start of the game. The default value is 100 and the maximum is 1,000. Players can modify this value manually when they select a Scenario to play. public virtual bool CapitalEliminationThe default value of this property is true. If you override and set to false, then a player is not eliminated from the game when their Capital is conquered. If you do this, be sure to specify your own custom Victory Conditions by overriding the VictoryReached method. public virtual int CapitalShieldsOverride this property to change the number of Shields that players' Capital StarSystems start with from the default value of 10. public virtual int CapitalScannersOverride this property to change the number of Scanners that players' Capital StarSystems start with from the default value of 10. public abstract string DescriptionOverride this property to return a description of the Scenario that appears when it selected from the list. public virtual Size MapSizeOverride this property to set a map size other than the standard 100x100. public virtual int MaxPlayersOverride this property to change the maximum number of players that the Scenario can accommodate. The default value is 10. public virtual PlayModeRecommendation RecommendationOverride this property if your Scenario is intended to be played only in solo mode, or multiplayer mode. Return PlayModeRecommendation.Solo or PlayModeRecommendation.MultiPlayer. If you return one of these values, a message appears above the Scenario preview when players select the Scenario before a game. Adding/Disallowing StarShip Types You can control what StarShip types are added and disallowed in your Scenario by using the two methods below. Create a List<StarShipType> and return it in these properties. StarShipType is an enum that represents all of the available StarShip types. public virtual IList<StarShipType > AddedStarShipTypesReturn a list of StarShipTypes that should be automatically added to each player's available list at the start of the game. public virtual IList<StarShipType > DisallowStarShipTypesReturn the StarShipTypes that should not be allowed in this Scenario. These StarShipTypes will be removed from players' selections at the start of the game. The BuildScenario Method public abstract void BuildScenario(int numPlayers, int capitalValues, int startingResources);You must override the BuildScenario method and provide the logic that actually creates the Scenario, using the various methods in the Scenario API described below. public virtual void NonHostInitialize()The NonHostInitialize method is called in MultiPlayer games by the other players who have joined the game. Implement this method to set up any data structures or perform initialization that was done in the BuildScenario method call. Because only the Host player calls BuildScenario, you can use NonHostInitialize to ensure that Clients are up to date with required information. You can pass information to Clients by using the ScenarioInfo properties of the SVGame, StarShip, and StarSystem classes (explained more in the Dynamic Scenario topic.) The Scenario API The Scenario API includes a set of methods that you can use in your implementation of BuildScenario to create StarSystems, StarShips, Nebula, and anything else you need to place in the Scenario. For more advanced control, it might be required to access the SVGame object provided by the Game property (see below). But for most applications you should be able to achieve what you need with the Scenario API. One of the best ways to learn how to build Scenarios is to examine the code for the Scenarios provided in the SV5 install. Start with simple Scenarios like Classic.cs, DoubleCluster.cs and MirrorImage.cs, then move your way up to the more advanced Scenarios like PsiWars.cs and CollectTheScientists.cs. protected void CreateBlackHole(int x, int y, int radius)Creates a Black Hole at the specified location, with the specified radius. The radius indicates how close StarShips must be to begin to be pulled into the Black Hole. protected void CreateNebula(int x, int y, int numArms, int numCells)This method is deprecated. Use CreateTerrain instead to create a variety of possible terrains, including Nebula. protected void CreatePulsar(int x, int y)Creates a Pulsar at the specified coordinates. protected void CreateStarCluster(int numStarSystems, int x1, int y1, int x2, int y2, int radius, int density)Call this method to produce a StarSystem cluster in the Scenario. The cluster will create StarSystems along a line specified by the coordinates x1,y1 to x2,y2. The coordinates pairs can both be the same to create a purely globular cluster. The radius parameter determines the maximum distance that StarSystems will be produced away from the line/point. The density parameter determines how many times the generated StarSystem positions are averaged together, leading to more highly dense clusters as the value increases. StarSystem Values, Resources, Shields, and Scanners are all randomized. protected StarShip CreateStarShip(int x, int y, Player owner, StarShipType shipType, int engines, int extra, bool cloaked)Creates a StarShip at the specified location, using the parameters to determine its StarShip type, Engines, and Primary System values (the "extra" parameter), as well as whether or not it should be cloaked. The Player property indicates the owner of the StarShip, and is an object of the Player class. You can access the Player objects via the Players property of the Game property. The Players property is a List<Player>. Example: Player p = Game.Players[0]; protected StarSystem CreateStarSystem(int x, int y)Creates a StarSystem at the specified location, using the same randomized Value, Resources, Shields, and Scanners for StarSystems that are created with CreateStarCluster. protected StarSystem CreateStarSystem(int x, int y, int value, int shields, int scanners, double resources)Creates a single StarSystem at the location specified in x,y. Specify the properties of the StarSystem in the parameters. To perform further modification of the StarSystem, set the properties in the StarSystem object that is returned by this method. protected void CreateTerrain(TerrainType tt, int x, int y, int numArms, int numCells)Creates a random span of terrain of the specified type. The current possible values of TerrainType are Clear and Nebula. The terrain mass is centered on the coordinates specified in x and y, and is randomly generated by moving a virtual pen around the map in random directions, for a number of times equal to the numCells parameter. The process is repeated, starting back at the origin, for a number of times specified by the numArms parameter. protected ScenarioImage CreateTerrainImage(TerrainType tt, string imageFileName, int x, int y, double alpha)Allows you to provide custom background images that will be displayed on the map, and optionally converted to terrain elements. Image files that are used as backgrounds must be in the "Scenarios" folder under the main SV5 install folder. Provide the name of the image file, with extension, in the imageFileName property. The x and y properties determine the coordinates where the image will be drawn on the map, specified in game map coordinates. If the tt property contains a terrain other than "Clear", the image will be examined cell by cell. A cell is a 30x30 pixel block that maps to a coordinate on the playing map. If a cell contains any non-black pixels, the corresponding map cell will be set to the specified terrain (currently the only terrain available is Nebula.) The alpha property specifies a transparency level to apply when rendering the image. Specify 1.0 for a fully opaque image. Values less that 1.0 indicate levels of transparency to apply to the image, which can lead to more pleasing effects when rendering cosmic images to the map. The method returns an instance of a ScenarioImage object, which you normally do not need to worry about. However, you can manipulate the Visible property of this object to show/hide images on the map. You might save this object to a local variable and manipulate it from the CheckVictory method, for example. protected UDO CreateUDO(string name, int x, int y, string imageName, bool autoPickUp)Creates a UDO (User-Defined Object). See the topic on UDOs for more information. protected void CreateWormhole(int x1, int y1, int x2, int y2)This method creates a Wormhole at location x1,y1, with a destination point at x2,y2. protected TerrainType GetTerrain(int x, int y)Returns the terrain at the specified location. TerrainType is an enum with possible values of Clear and Nebula. protected void SetTerrain(int x, int y, TerrainType terrain)Allows you to set the terrain on a coordinate by coordinate basis. Assigning Capitals protected bool AssignCapital(Player player, Rectangle area)You can call this method after all of your StarSystems are created to attempt to assign a Capital to a Player within an area of the map specified in the area parameter. This method is useful for assigning Capitals to alternating sides of the map, for example. See DoubleCluster.cs for an example of this technique. You can also assign capitals manually by manipulating the SVGame object exposed to you via the Game property. To assign a Capital, set the Player.Capital property to the desired StarSystem. See MirrorImage.cs for an example of explicitly assigning Player Capitals. //example - assign the first StarSystems we created as Capitals to the
Players in the game If you fail to set Capitals in your Scenario code, do not worry. SV5 does it automatically before the game starts, unless you disabled this by returning false when overriding the AssignCapitals Scenario property. Miscellaneous Methods of the Scenario Base Class protected double Distance(int x1, int y1, int x2, int y2)Calculates the accurate distance between two points. protected int DistanceQuick(int x1, int y1, int x2, int y2)Returns a quick calculation of distance between two points by adding the absolute values of the differences of the x and y coordinates. The performance of this method is much faster than the Distance method. public virtual void Initialize()SV5 calls the Initialize method before the game starts. The Initialize method is called in the Scenario object of all game participants in a MultiPlayer game. For the game host, it is called prior to BuildScenario, and for clients, prior to PostLoadInitialize.
protected int Random(int
from, int to) Custom Victory Conditions public virtual bool VictoryReached()If you override this method, you can have your Scenario specify its own specific victory conditions. This method is called after each Impulse is processed in Solar Vengeance. In this method you can examine the current game state by accessing the Game property, which is an instance of the SVGame class and contains the current state of the game. You can examine the game state by reading properties in the Game object, but do not change any values here. If you do, the changes will not be communicated to other players in a MultiPlayer game. When implementing this method, if you have determined that your custom victory conditions have been reached, you should set the Victor property to true for each Player object that has met the conditions, and then return true from this method. If your custom victory conditions have not been met, and you want to keep the default victory condition of Player elimination, be sure to return base.VictoryReached in your implementation. In MultiPlayer games, VictoryReached is executed in the Scenario object of the game "host" only, not the game "clients". If the host determines that victory has been achieved, by returning true here, the information is automatically passed to the clients by SV. See the Scenarios XMarksTheSpot.cs, RingNebula.cs, and CollectTheScientists.cs for some examples of how to code custom Victory Conditions. Persisting Information in Scenarios When a game is saved and reloaded, the BuildScenario method of the Scenario object is not called again. Rather, all of the game information is loaded from the save game file. Likewise, clients in MultiPlayer games do not have their BuildScenario called either. The Scenario framework provides a mechanism to persist data in the Scenario and to communicate it to clients in a MultiPlayer game. This is accomplished using the GetValue and SetValue methods, and the PostLoadInitialize method. protected void SetValue(string tag, string value)Call SetValue to save a value to the Scenario's persistent storage. The value will be reloaded when a saved game is restored, and also communicated to clients in a MultiPlayer game. During a game, you can call SetValue during the ProcessImpulse method, and the values you set will automatically be sent to clients in the game. protected string GetValue(string tag)Call GetValue to read a value that was previously stored by SetValue. public virtual void PostLoadInitialize()SV5 calls this method after a saved game loads and all of the persistent data was reloaded into the Scenario. SV5 also calls this method for clients in a MultiPlayer game. Override this call to read persistent data and make any required initialization. For example, the ChaosCluster Scenario uses this method to communicate the chance that a random chaos event will occur in the Scenario. The sequence of events is as follows:
In this way, required information is kept in synch between all participants in the game. Scenario Parameters protected ScenarioParameter CreateParameter(string name, int defaultValue, int minValue, int maxValue)Scenario Parameters are values that can be adjusted by the player before staring a game. They each have a name, a default value, and a minimum and maximum. If you want to provide Scenario Parameters in your Scenario, use the CreateParameter method in your Scenario class' constructor. Save the resulting ScenarioParameter values as private variables. In your BuildScenario code, when you want to access the values of a Scenario Parameter, use the Value property of the ScenarioParameter object that you created and saved in the constructor. See the Classic.cs Scenario for an example of a Scenario that creates and uses Scenario Parameters. The Game Property public SVGame GameThis property returns an instance of an SVGame class. The SVGame class contains all of the internal objects currently created in the game. For example, It contains a List of StarShip objects called StarShips, a List of StarSystem objects called StarSystems, etc. You can access this property during the BuildScenario method to gain information about the current state of the Scenario. During BuildScenario, you are also free to change information in the game state using properties in the SVGame class. For example, you can directly set the Values of StarSystems, assign Cargo to StarShips, or even change StarSystem Names. You will also need to access game information during the VictoryReached method, if you are providing your own Victory Conditions to the Scenario. Again, do not MODIFY information from within VictoryReached, because changes made there will not get communicated to other players in a MultiPlayer game. You can also access information from this property during the ProcessImpulse method, described below. However, do not CHANGE information during ProcessImpulse. Changes here are not communicated to other players in a MultiPlayer game. To make dynamic changes, use the methods of the DynamicEvents property, described next. The best way to learn about what's in the SVGame class is to explore its properties and methods with Intellisense from Visual Studio, all of the information is fairly self-documenting. If you have questions please post them on the Silicon Commander Games message board. The DynamicEvents property This property allows you to call methods that produce changes inside the game that are communicated to other players in a MultiPlayer game. It is your window to producing exciting, dynamic Scenarios for Solar Vengeance. It's use is documented in the Dynamic Scenarios topic. PaintHooks PaintHooks allow you to render your own graphics to the game map during a game. They are described in detail in the PaintHooks topic. How to Install your Scenario Making your Scenario available to Solar Vengeance 5 could not be easier. Simply copy or move the .cs source code file of your Scenario into the "Scenarios" folder under SV5's main installation folder. The next time you start SV5, your brand new Scenario will be available in the Scenarios list, complete with an automatically generated preview image. |