Click or drag to resize
Sprite Rules

Sprite rules are used to define the general behavior of a sprite, and are often independent of which map the sprite is on (they apply generally throughout the game). (Behaviors specific to a particular map or a particular area are usually better represented as a "Plan" object.) The rules accomplish such tasks as moving the sprite, making it react to solidity on the map, making it switch states depending on which direction it's going, and changing it's velocity based on input.

Sprite Rules are only one aspect of the Sprite Definition. For information about other aspects of the sprite definition, see:

Sprite Rules

Sprite Rules are very similar to plan rules defined in the Edit Plans window. They do differ somewhat, however, because the rules within a sprite definition operate within the context of a sprite instance. A sprite instance of a particular type could be running on any map, so the sprite definition can't (or shouldn't) include map-specific rules. Plan Rules, by contrast, operate within the context of a layer, which may be running many different sprites. Therefore the types of rules and the specific parameters accepted by certain rules will differ based on the fact that the rules are targeted for a different context. For example, the ModulateColor function available in the plan editor is nice to have as an option there because there may be a specific event that occurs on the map that should change the color of the sprite (maybe it just went underwater), but then it requires a parameter to determine which sprite's color to change. The sprite definition rule editor, on the other hand, doesn't have a ModulateColor function because it has ModulateRed, ModulateGreen, ModulateBlue and ModulateAlpha properties that can be set directly with the "=" function, and there's no need to specify a specific sprite because these rules are operating on a sprite. Those properties may be useful in a more general context of setting the sprite color based on when it collides with another type of sprite, for example. Similarly there are many functions available in a Sprite Definition such as ReactToSolid, LandDownOnPlatform and SnapToGround that make more sense within the context of a sprite's general behavior than a specific layer, and thus have no counterpart in the Plan Editor.

Rule Editing
Rules Toolbar

A toolbar appears above the hierarchical list of rules to manage the creating, deleting and moving of rules in the list. The same commands appear in the "Sprite Definition" menu.

  • Add Rule: Create a new rule with a default name including a uniquely identifying number. The rule is inserted after the currently highlighted rule in the list, or at the end if no rule is highlighted.
  • Remove Rule: Delete the selected rule. Note that only one rule can be deleted at a time, and subordinate rules are not deleted when a parent rule is deleted. If a rule represents a condition, and contains a number of rules inside it, and you delete the condition, then all the rules inside it move up a level and are executed without checking the condition (because the condition has been deleted and is gone). The rule marking the end of the condition, however, will not be deleted and should be updated appropriately if it is no longer to mark the end of a block.
  • Move Rule Up: Swaps the selected rule with the rule above it. Note that this does not skip over nested rules, or move nested rules as a group. If you move the beginning of a condition, the rule preceding the condition will be moved into the condition block rather than after the end of the entire condition block. Likewise, if you move a rule after the end of the condition up, it will move into the condition instead of jumping over the entire block.
  • Move Rule Down: Swaps the selected rule with the rule below it. Note that this does not skip over nested rules, or move nested rules as a group. If you move the beginning of a condition, the first rule nested within the condition will be moved outside the condition block rather than moving the entire condition block down. Likewise, if you move the rule representing the end of the condition down, it will move the following rule into the condition.
  • Copy Rules: Various copy commands will copy all the details of the specified rule or rules so that the rule can be easily transferred, for example, to another sprite. The rule can also be pasted to a plan, but since sprite rules are not always compatible with plan rules, some tweaking may be necessary when doing so. The sub-items in this menu allow you to copy the currently highlighted rule including all the rules contained within it (in the tree node), or excluding them, or copy all the rules displayed in the tree.
  • Cut Rules: Various cut commands will cut all the details of the specified rule or rules so that the rules can be easily transferred or deleted. This is the same as Copy Rules, but also deletes the rules from their current location as they are copied to the clipboard. The sub-items in this menu allow you to affect the currently highlighted rule including all the rules contained within it (in the tree node), or excluding them, or affect all the rules displayed in the tree.
  • Paste Rules: Once rules have been copied from a sprite definition or a plan, they can be pasted into a sprite definition using this command. Note that when pasting plan rules into a sprite definition, some tweaking may be necessary to make the rules conform to the features supported by sprite definitions. Not all functions available in a plan are available for sprite definitions. The sub-items in this menu allow you to paste the copied rules either before or after the selected rule. If no rule is selected, they will be pasted at the end of the list.
  • Toggle Suspend for This and Child Rules: This will toggle the state of the "Suspend this rule" checkbox for the current rule, and set all the child rules' state to be the same. Normally, toggling the checkbox affects only the current rule, but it often doesn't make sense to turn off a parent rule without also turning off all the children, so this toggle can come in handy for disabling (or re-enabling) entire branches of rules.
  • Convert Rules to Function: There are two versions of this command. One will convert all enabled rules in the tree and the other will convert the currently selected rule and all its children. The command to convert all rules is only available from the menu (not available on the toolbar). If you have too many rules to easily manage in the tree view, you can use this command to convert groups of rules into single functions that can be called with a single rule. The converted function will be added to a source code object (or copied to the clipboard if you prefer to look at the code or add it somewhere manually). This action cannot be reversed, so make sure the rules are set up how you would like, and that you do not want to edit the rules in the tree view any more before converting them. Once the rules are converted, they can only be edited as source code in the Code Editor. Another reason to do this is if you need more control over your rules that the rule editor cannot provide. Editing them directly exposes the full power of the C# language. The converted rules will be implemented as a function specifically available to this sprite only. You may manually add up to 3 parameters to the converted function (in the code editor, assuming you are familiar with C#) if you would like to be able to create rules that pass different parameter values to this function (you can use functions from SpriteBase as an example), but it will still only be accessible to this sprite. However, if your rules are not dependent on anything specific to this sprite, you may move the code or change the code declaration to put the function in the SpriteBase class. Then it will be accessible to all sprites.
Rule List

This displays a list of rules associated with the current sprite definition in a hierarchical view. When a rule represents a condition or a loop that affects a number of nested rules, the nested rules are indented under that rule and can be collapsed into it. Note that a condition (a rule of type "If") can also include an "Else" rule, which defines a series of rules to apply when the "If" condition was false. Since the else also depends on the same condition described in the "If" rule, it (and the statements applying to it) is included as a nested rule along with the rest of the rules nested in the condition. That may be difficult for programmers used to writing indented code to get used to because often times code is written with the "Else" being un-indented to the same level as the "If". But when displaying the rules in a hierarchy it truly is part of the same condition, and therefore is nested within the condition. (The code generated by the rules when the project is compiled *is* indented as a programmer would expect, however.)

Rule Name

The name of a rule is used to uniquely identify the rule within the sprite definition. Therefore the name must be unique among all rules within the same sprite definition. A rule name is not constrained by the same limitations as most names because it does ot represent the name of an object that gets converted into source code. The name of a rule simply becomes a comment in the generated code when the project is compiled. The name of a rule can contain any characters that can be typed into a single line. Some good guildelines or considerations for naming rules will help to quickly understand rules when looking at them in the rule list:

  • Use the word "Else" at the beginning of rules of type "Else" so it's easy to tell when statements in a conditional rule apply to the false case of the condition.
  • Use the word "And" at the beginning of rules of type "And" so its easy to distinguish components of the initial condition from rules that apply within the condition.
  • Use the word "Or" at the beginning of rules of type "Or" so its easy to distinguish components of the initial condition from rules that apply within the condition.
  • Prepend a "* " to the names of rules that have been suspended so its easy to find rules that are not active but could easily be turned on.
  • Include details about the context of a rule in its name so that it won't collide with the names of other rules performing similar things in a different context. For example, instead of naming a rule "Switch state", name it "Switch from right to left".
  • Keep in mind, the more details that are included in the rule names, the more information will be available when reading the rule list. But also keep in mind that there is no word wrapping in the rule list, so space is limited.

Of course you are free to devise your own guidelines as well, but these guidelines are used in the included samples and following them will make your rules consistent with any imported samples.

Suspend this rule

This will exclude the rule from being included in the generated project. It will be treated as if it does not exist when compiling and running the project. A good example is an imported player sprite. The imported player sprite template may have rules that make the sprite react to ladders based on a tile category named "Ladders". However, in order to support projects that may not have ladders or have not yet defined a tile category for ladders, the sprite sprite definition (in its exported, stand-alone form) would probably suspend the rules relating to ladders, so that the project designer who imports the sprite definition can choose whether and when to enable ladders.

Note: It is strongly recommended when suspending a rule that contains nested rules, all the nested rules also be suspended. Unexpected behavior may occur if a rule is suspended without suspending all of the rules nested within it. See the "Toggle Suspend for This and Child Rules" command above.

Rule Type

There are 8 fundamental classes of rules that can be defined using the first dropdown list. If the descriptions of these types seem overwhelming or confusing, skip them for now and just try out some examples (look at some existing sample rules in other projects). These should be relatively self explanatory, but you can refer to these descriptions for detailed information about how they behave and why they exist. Before proceeding, let's establish some terminology. A "Rule Type" is one of these 8 types selected in the first dropdown list. And the term "Rule Function" (described in more detail below) will be used to refer to a specific function selected in the second dropdown list.

DoThis simplest of rule types indicates that some action will be performed rather than defining a condition or loop. Note that rule functions that are normally associated with "If" type rules can also be used with "Do", and any action that they perform will be executed, but the result will be ignored instead of used to define a condition.
IfThis defines the beginning of a condition. Rules that come after an "If" rule will be nested within it until one of the rules uses the "End If" checkbox to end the condition. The set of rule functions available with an "If" type rule is limited. Only functions that return a true or false value can be used with "If". (In the source code, the function must return "bool".) When the rule returns success/true, the conditions nested in the "If" conditions will also apply, otherwise they are skipped. (There are exceptions, see "Else" below.)
AndThis rule type can only be used immediately after an "If", "ElseIf", "While", "And" or "Or" type rule, to extend the condition. The rules contained inside the condition will only be applied if all the rules combined with "And" return success/true. The same list of rule functions will be available for this rule type as are available for the "If" rule type.
OrThis rule type can only be used immediately after an "If", "ElseIf", "While", "And" or "Or" type rule, to extend the condition. The rules contained inside the condition will be applied if any one of the rules combined with "Or" return success/true. The same list of rule functions will be available for this rule type as are available for the "If" rule type.
ElseIfThis rule type can only be used within a block of rules started by "If" or another "ElseIf". It begins a new condition block nested yet another level below that of the current rule. The condition is only checked when the initial condition failed (returned false), and the statements nested under this rule are only applied if the initial condition failed and the condition specified in this rule succeeds (returns true). Because the statements are nested another level, you must remember to include at least two End If rules, one to finish the nested condition and one to finish the initial condition. If there are rules between the end of the inner condition and the end of the outer condition, they will be executed when the outer condition's expression is false regardless of the result of the inner condition.
ElseThis rule type can only be used within a block of rules started by an "If". It causes the rules within the block after this one to be applied only if the condition specified with "If" failed. This is actually more like an "Else Do" than a plain "Else" because it also includes the ability to perform a function within the same rule.
EndNormally when you create a rule, in order to make it the last rule in a nested block of statements (the last rule that depends on an "If" condition, for example) you can check the "End If/End While" box. However, there is no way to indicate that a statement should be the last statement of two nested conditions (for example, the end of an "If" block as well as another "If" block containing that). That's the purpose of the "End" rule type. It's the only rule type that doesn't perfom any action in itself (there's no rule function associated with it). It just ends a block of nested statements that eas started by an "If", "ElseIf" or "While".
WhileThis begins a block of statements that will execute repeatedly ("loop") as long as a rule function returns success/true. This can be used in conjunction with "And" and "Or" rule types to form complex conditions that must be met to continue the loop. The same list of rule functions will be available for this rule type as are available for the "If" rule type. It cannot be used in conjunction with ElseIf or Else rules. In other words, you can nest a "While" inside and "If" or an "ElseIf" block, and you can nest an "Else" or "ElseIf" rule inside an "If" block contained within a "While", but you cannot directly include an "Else" or "ElseIf" rule within a "While" block. Be careful with this rule type because it could easily result in endless loops that will make the game freeze if used incorrectly. It can also make the game run slowly.
Not

This checkbox can be used with the "If", "ElseIf", "While", "And" or "Or" rule type to invert the result of the rule. For example, you can check the "Not" box on a rule that reads "If - IsInputPressed" and then the rules contained in this block will only apply when the specified key is not pressed.

Rule Function

The second dropdown list on this form represents the rule function associated with the rule. Here you can select one of the many functions available to define sprite behavior, including functions defined yourself by editing files in the "Source Code" folder of the project. For more details about defining your own rule functions, see the coding reference . A number of pre-defined functions exist to perform simple comparisons, calculations and copying of values:

-Subtract the "left operand" in the second parameter from the "right operand" in the first parameter and put the result in the variable provided in "Output to".
!=Compare the values of the first two parameters and return true/success if they are different, or false/failure if they are equal.
+Compute the sum of the first two parameters and output the result to the variable provided in "Output to"
<Compare the values of the first two parameters and return true/success if "left operand" is less than "right operand", or false/failure otherwise.
<=Compare the values of the first two parameters and return true/success if "left operand" is less than or equal to "right operand", or false/failure otherwise.
=Copy the value provided in the first parameter to the variable provided in "Output to"
==Compare the values of the first two parameters and return true/success if they are equal, or false/failure if they are different.
>Compare the values of the first two parameters and return true/success if "left operand" is greater than "right operand", or false/failure otherwise.
>=Compare the values of the first two parameters and return true/success if "left operand" is greater than or equal to "right operand", or false/failure otherwise.

When defining an "If", "While", "And", "Or", "ElseIf", or "While" type rule, the list of functions displays only rules that return a true or false value (sometimes thought of as success or failure). These rule functions are referred to as "boolean" functions. When defining a "Do" type rule, all rule functions are available for use, and if a boolean function is used, the function will perform its usual work (if any) but the result will simply be ignored. This might be useful because some functions actually do something that affects the game and then return a value indicating some true or false value. The LandDownOnPlatform function is a good example because it makes the sprite ride on a platform if it just hit a platform from above, and it returns true if the sprite just landed on a platform. But you don't have to check the return value in order for the sprite to land on the platform; only if you care to know whether the sprite landed on a platform or not.

After selecting a function, some or all of the parameter fields below will open up for input. Each function has its own set of parameters, and depending on how many parameters it uses and what types of parameters they are, the boxes below will become available and present different options in the dropdown lists. The box immediately below the rule function box will also display a brief description of what the function is and how to use it. Furthermore, if the function can output a number, the "Output to" box will open up and allow you to select a counter or plan parameter in which to store the result.

If there is an error compiling the project or processing the function name (it's possible to type an arbitrary name into the function field in case you want to call an undocumented function) then the description field will contain a generic error message and all the parameters will be available for input, but without names. This is to allow a function to be specified even if the environment doesn't know that it's valid.

Function Description

After a function is selected, a brief description of the function is displayed in the box below. Don't forget that this box can scroll and there may be more information than is initially displayed. Usually a description will also include information about the meaning of the parameters and output value if any.

Function Parameters

Many rule functions can accept parameters that specify details about how they should operate or what they should affect. In most cases a helpful list of suggested values is provided in the dropdown list for each parameter based on the type of the parameter, but any value can be manually typed because not all possible values can be predicted. For example if you want to call a function to display a message, you obviously won't be able to select the message from the dropdown list, you'll have to type it in. That brings up another important topic. When providing text for a parameter (also known as a "string") you must enclose the text in quotes. This (indirectly) allows you to include special formatting characters in the text. These are inserted with "escape codes". Here are the most important escape codes with which you should be familiar when entering a string into a parameter value:

CodeResultExample parameterExample result
\r\nInserts a line break"Display me on\r\nTwo Lines"Display me on

Two Lines

\"Embeds a double-quote in the text"He said his name was \"Little John\""He said his name was "Little John"

Many other parameter types are available when defining rules for sprite definitions. Below is a list, but it is by no means comprehensive because the list is customizable. It can be expanded by adding your own enumerations in the game project's source code folder:

Type Name / SummaryDescription/SourceExample
KeypressPreset list of static values, each value representing a key on the keyboardKey.A
DirectionPreset list of "Up", "Right", "Down" and "Left"SpriteBase.Direction.Down
Relative PositionPreset list of pre-defined corner or centered positions within a rectangle (especially the sprite's solidity rectangle).RelativePosition.BottomCenter
SpriteSince sprite definitions don't know about specific instances on maps, this list will provide a "this" option referring to the current sprite instance being processed. This usually applied to parameters of custom rules or other rules that can apply either a plan or a sprite definition.this
SpriteAnimationTypePreset list of "ByFrame", "ByHorizontalVelocity", "ByVerticalVelocity" and "ByVectorVelocity"SpriteBase.SpriteAnimationType.ByHorizontalVelocity
Sprite CollectionDisplays a list of sprite categories defined in the project. (A sprite category object includes all sprite instances within a particular category for the layer on which the current sprite resides.)ParentLayer.m_SpriteCategories.Enemies
booleanTrue of falsetrue
SolidityDisplays a list of all the solidity definitions in the project.Solidity.StandardSolid
CounterDisplays a list of counters in the project.Counter.Lives
ColorDisplays a preset list of colors.System.Drawing.KnownColor.Crimson
Sprite InputBitsDisplays a preset list of inputs that can affect a sprite.SpriteBase.InputBits.Button1
MapDisplays a list of maps defined in the project. (They are referred to by type instead of specific map instances because it's conceivable that you could have multiple copies of the same map loaded.)typeof(Level_1_Map)
Sprite DefinitionDisplays a list of Sprite Definitions. This differs from the other sprite parameter types because they require a specific sprite instance on the layer whereas this lists Sprite Definitions which are independent of the maps.typeof(Sprites.Explosion)
Sprite StateDisplays a list of all states in a particular sprite (if no previously specified parameters have specified a sprite, this won't display a list).(int)Sprites.Player.State.Left
IntegerDisplays a list of all counters, all parameters defined on the Parameters tab, and miscellaneous other shared integer variables. Some rules may want to alter a parameter value that is passed in (receive the parameter "by reference" so it can be changed). In these cases the values in the list are preceded by "ref" indicating that the variable that is provided may have a different value afterwards (failing to pass a a variable by reference where a reference is required will result in an error.) Some properties of a sprite (besides those listed on the Parameters tab) are numeric, but they are not integersl; these can be provided as a normal input parameter, but will not be available for use with "ref" parameter. Furthermore, counters cannot be provided to a parameter requiring a reference to an integer either, but another version of the rule function may be available that accepts a counter, or the value can be stored in a parameter and subsequently be copied into the counter with an "=" rule.Counter.Lives.CurrentValue
TilesetDisplays a list of Tilesets defined within the project.Tileset.FireText
Output to

Some functions output integer values. For those that do, this field is enabled to allow you to specify where to put the result. If you want to store it in a value specific to this sprite, select one of the provided sprite parameter values. Many other values, including all the counters, are also provided. You can add any number of parameters to a sprite (on the sprite parameters tab) if you need to store many values. Keep in mind that each instance of a sprite has its own copy of each value. But each copy only requires 4 bytes so there's little risk of being a memory hog until you have hundreds of sprites each wich hundreds of parameters.

Whereas parameters are all required, the "Output to" box can be left blank if you don't care about storing or using the result of a rule function.

End If / End While

If you want to mark this rule as the last rule in a block that was started with an "If", "ElseIf", or "While" type rule, check this box. Note that if you need to end two (or more) blocks at once, you will need to also add an "End" type rule after this. The "End" type rule will allow you to add another rule that has no function or parameters, and just checks the "End If / End While" box.

Take care to match every "If", "ElseIf" and "While" with one and only one matching rule that has the "End If / End While" box checked. The code generator will automatically close the remainder of your blocks if you have some unfinished blocks at the end of your plan, but other failures to match the beginnings of blocks with an end could result in unwanted behavior. One occasion when this can be particularly tricky is when deleting a rule that begins or ends a block. Be careful to find the corresponding rule at the other end of the block and delete or adjust it appropriately too.