This page is out of date

You've reached a page on the Ren'Py wiki. Due to massive spam, the wiki hasn't been updated in over 5 years, and much of the information here is very out of date. We've kept it because some of it is of historic interest, but all the information relevant to modern versions of Ren'Py has been moved elsewhere.

Some places to look are:

Please do not create new links to this page.


This page provides the documentation for the Unit Engine and its Unit objects. You may wish to read the ../Unit Engine Tutorial/.

Overview

The UnitEngine is an extension of the Tile Engine. The basic process of making use of the UnitEngine will look like this:

Conventions

All positions are given in (gridx, gridy) tuples. These are converted to screen co-ordinates internally by the TileEngine's GridToScreen() function. You never need to supply screen co-ordinates to any UnitEngine function.

The "user" always refers to the game creator who's making use of the UnitEngine in their game. The "player" always refers to the person playing that game. This document is aimed at users, not players, and so "you" also refers to the user.

Styles

The following styles are used by the Unit Engine:

In addition to these styles, all the buttons the UnitEngine displays, as well as any button displayed by a engine_button() call, will be styled with style.engine_button[yourText] and style.engine_button_text[yourText]; and any label displayed by a engine_label() call will be styled with style.engine_label[yourText] and style.engine_label_text[yourText]. See properties and styles for how to customise styles, and for how to make your game translate text.

UnitEngine object

You create a UnitEngine object with code like:

e = UnitEngine(map = myMap, tilewidth = 64, tileheight = 32,
               geometry = TileEngine.ISOMETRIC, movement_style = UnitEngine.MP)

Documentation on these parameters follows.

Required parameters:

In this release, only MP mode is supported. Identical to the TileEngine parameter map: the 2-dimensional array of tiles. Each tile must be an object (for example, a Struct) with properties lower and upper, each of which can be None, or the filename of an image. Identical to the TileEngine parameter tilewidth: the full width of one tile, in pixels. Identical to the TileEngine parameter tileheight: the full height of one tile, in pixels. This should be the base size that will be tiled. It doesn't matter if some of the tile images extend above this height.

Optional parameters:

All the TileEngine optional parameters are supported by the UnitEngine. The following additional optional parameters are supported: A filename or (idle, hover) tuple of filenames. The first filename is the image to display on squares to which the selected unit can move. The second, if present, is the image for such squares when the mouse is hovered over them. The images should probably be semitransparent. A filename or tuple of two filenames, as for move_square_highlight, but used for default highlighting in unit actions. This value is used in HighlightSquares if no highlight is specified in that function. A filename for an image, which is displayed underneath the currently selected unit. The function to display the unit_highlight, which must accept position properties - xpos, ypos, xanchor and yanchor. The default is . A list of the players in this game, in the order they'll take their turns. Each entry must be an object with properties name, control and HP_scale. Two predefined Players are provided: UnitEngine.PLAYER and UnitEngine.ENEMY. The control property of each object must be either UnitEngine.HUMAN or UnitEngine.COMPUTER. The HP_scale property is a floating-point number, by which the HP of all the player's units will be multiplied. This can provide a simple way of scaling difficulty. If True, after the player selects End Turn then an confirmation menu "End Turn" / "Cancel" is presented. If False (default), the turn will end without this confirmation menu. By default, when the player's last unit is finished moving and acting, the turn will end automatically. If this flag is False, instead the player must always select End Turn manually. By default, the game will end when all units left on the map are controlled by the player. If you want the game to continue in such circumstances (or the game without any non-player-controlled units), set this flag to False. By default, units can't end their movement in the same space another unit is in, but they can move through other units. If this flag is False, units will never be allowed to pass through a square another unit's in. This parameter must be either 4 or 8. If it's 8 (the default), all units can move diagonally or orthogonally. If it's 4, only orthogonal movement is allowed: nothing moves diagonally. This parameter must be either 1, 4 or 8, or the special value None, meaning to inherit from movement_directions, which is the default. If it's 8, units are assumed to have eight variant images for each unit status, one for each of the directions N, NE, E, SE, S, SW, W and NW. The direction_facing property of a unit may be any one of the parent UnitEngine's properties DIR_N, DIR_NW, etc. If this parameter is 4, units will only face in the four orthogonal directions (NW, SW, NE and SE for isometric; N, S, E and W for straight.) If this parameter is 1, units will not have their direction_facing property changed. Note that units will be created with their display_directions equal to the engine's display_directions, but it may be overridden on individual units. If this flag is True (the default), an overlay will be displayed giving information about the current selected unit, in style engine_frame["unit info"]. The information can be specified in unit_info. This may be None, meaning use some default unit information; or it may be a list of info items. Each info item is either a function, which should add a line of unit information to the info panel, or a (conditionfunction, infofunction) tuple, in which case the infofunction will only be called if the conditionfunction evaluates to True. The default for MP mode is:

[
self.ShowUnitName,
self.ShowUnitHP,
(self.IsPlayerUnit, self.ShowUnitMP),
(self.IsPlayerUnit, self.ShowUnitActionsLeft),
self.ShowUnitPosition
 ]

By default, the UnitEngine will show buttons to let the player instruct units to Move, Act, and so on. Set this parameter to False to hide these buttons. Note that the keyboard shortcuts are controlled separately by the keymap parameter. A dictionary mapping keysyms to functions. The functions must be wrapped in or something similar, as the result of calling the function will itself be called after ui.interact finishes. If this is None, the default keymap is used, which is:

To specify an empty keymap (disable keyboard control), use {}. A string that will be inserted as the status field into unit imagenames when units move. Default is "moving". A function that will be called when the current player has their controller property set to UnitEngine.COMPUTER. Default is e.AI_TakeTurn, which is a basic AI function.

Properties

In addition to the parameters above, the following properties are also available: Will be equal to one of UnitEngine.NOSELECTION, UnitEngine.UNITSELECTED, UnitEngine.MOVEMODE, UnitEngine.ACTMODE, UnitEngine.ENDOFTURN, UnitEngine.VICTORY or UnitEngine.DEFEAT. A list of the Units that have been created in the UnitEngine with its Unit() function. The Unit that the user has currently selected for moving or taking action. If not None, this indicates that each map square will have a StoredMovementCost property, indicating how many MP in total it would take for one particular unit to move to that square. The unit in question is stored in the stored_movement_costs_for_unit property. You can update these values by calling the UnitEngine's CalculateMovementCosts() function, which will set the stored_movement_costs_for_unit property as well. Once created, a UnitEngine will have a callbacks property, a struct with several fields, all of which default to None. You can assign a function to any of these fields, and that function will be called at the corresponding time. The available fields are:

Constants:

The following constants are provided:

Movement styles:

UnitEngine.MP and UnitEngine.AP are the two different movement styles. Note that in v1.0, AP mode doesn't fully work.

Player constants:

A UnitEngine's player_list property should be a list of Player structs. The default is [UnitEngine.PLAYER, UnitEngine.ENEMY], where:

UnitEngine.PLAYER = Struct(name = "Player", control = UnitEngine.HUMAN, HP_scale = 1.0)
UnitEngine.ENEMY = Struct(name = "Enemy", control = UnitEngine.COMPUTER, HP_scale = 1.0)

UnitEngine.HUMAN and UnitEngine.COMPUTER are the two possibilities for the control property of a Player struct.

Terrain types:

Each map square should have a terrain_type property, which must itself be a struct. UnitEngine.TT_GROUND and UnitEngine.TT_WALL are provided, and for many games, they're the only terrain types you'll need. Their values are:

TT_GROUND = Struct(MoveableThrough = True, MoveCost = 1)
TT_WALL   = Struct(MoveableThrough = False, MoveCost = 0)

You can define your own terrain types and use them, as long as they have the two properties MoveableThrough and MoveCost. You can give them extra fields if you like.

UnitEngine Functions:

Create and return a Unit object, which will be displayed on the UnitEngine's map. Parameters: A string name for this unit. This will be displayed in the default unit_info unless you override it. If not supplied, defaults to the sprite_base_name. Required. The filename from which the image names will be derived. The image filename used for the unit is derived as follows: The sprite_base_name is split at its last dot ("."). If the direction_facing.name is nonempty, it will be prefixed by a "-" and inserted before the last dot. Then if the sprite_status is nonempty, it also will be prefixed by a "-" and inserted before the last dot. So for example, if the sprite_base_name is "knight.png", the direction_facing is e.DIR_NW, and the sprite_status is "sword", the the image filename will be "knight-nw-sword.png". If not None, this is a filename which is used instead of the sprite_base_name when the mouse cursor is hovering over the unit. The direction_facing and sprite_status are inserted as per the sprite_base_name. The unit's maximum hit points. Defaults to None. The unit's maximum MP (if the UnitEngine is in MP mode). Defaults to None. The number of actions the unit's allowed to take each turn (if the UnitEngine is in MP mode). Defaults to 1. The unit's maximum AP (if the UnitEngine is in AP mode). Defaults to None. The direction the unit starts off facing. Should be one of the UnitEngine's DIR_* constants. Default is DIR_NEUTRAL. Where on the grid the unit is. Must be a (gridx, gridy) tuple. It can be (None, None), the default, in which case the unit won't be displayed until you change its position to something else. If False, the unit can't enter movement mode. Default is True. If False, the unit can't enter action mode. Default is True. A Player struct, which must be a member of the UnitEngine's player_list. If this unit has more or fewer distinct directions in which images are available, compared to the engine's display_directions, then you can override it on a per-unit basis by setting this property. This is a dictionary mapping action names to functions. If this property is None, the "Act" button is disabled. When the player selects "Act", if this dictionary has just one entry in it, that function is called; otherwise, a menu is presented of each of the action names, and when one is selected, the corresponding function is called. The function to be called when the unit is clicked. Two special values are understood: None means the unit does nothing when clicked, and -1 (the default) means to use the default clicked function, which will choose the unit as a target if the mode is ACTMODE, and otherwise make the clicked unit the selected unit. A string that gets inserted into the image filename. See sprite_base_name for details.

Show the map and units. Changes to map or units will only be displayed when this function is called. The same parameters are supported as TileEngine.Show().

Starts the game sequence, letting players take turns in sequence until the end game conditions are met.

Show any changes to the map, then let the user interact with the engine. Change the game mode to the specified mode. You can do this by just assigning to the UnitEngine's mode property, but if the mode is currently one of [UnitEngine.ENDOFTURN, UnitEngine.VICTORY, UnitEngine.DEFEAT], then the mode will not be changed unless the optional force parameter is True. Note that UnitEngine.MOVEMODE and UnitEngine.ACTMODE cannot be entered if the engine's selected_unit is None. The curried version is called CurriedSetMode. Cancel whatever's currently happening. If we're in Move or Act mode, return to Unit Selected mode. If we're in Unit Selected mode, select nothing. As a special case, if we've got nothing selected, then go to the game menu, as would normally happen for pressing Escape. Called by pressing Escape or clicking Cancel. Select the next unit which can do something. If the parameter keep_current is true, then the current unit will remain selected if there's anything it can do; otherwise, the next unit will be selected as usual. Selects the specified unit. Unselects whatever unit may be selected. Select the current unit if it's got anything left it can do, or the next unit otherwise. Pop up a menu asking the player if they really want to end their turn. End the current player's turn. Move the selected unit to the specified square. Remove all highlighting from the map. Display highlights on the squares which are moveable-to by the current unit, with its currently available MP. This is called automatically when the player enters movement mode. Highlight some map squares with a sprite, and make clicks on them call a function. A function which takes a (gx,gy) tuple, and should return true or false. Required. A string (image file name) or a pair of strings (normal image, hovered image). Default is the engine's act_square_highlight. Will be called with a (gx,gy) tuple after ui.interact. Default is None. If True (default), all squares which don't meet the criterion will have their highlights removed. If False, they won't be modified, and only the squares which do meet the criterion will have their highlight changed. Calculate how many MP the unit will take to move to each square of the map. The cost is stored in each map square's .StoredMovementCost property. Check if all the player's units are dead, or (if the engine's end_when_all_enemies_dead parameter is True) all enemies are dead. The engine's mode will be set to e.VICTORY or e.DEFEAT if appropriate. CheckEndGame itself returns True if the end-game conditions are met, or False if not. Return True if the engine's in the middle of its own ui.interact call. Clicked functions should condition on this before doing anything significant, so as to not also trigger if the item's clicked during a VN segment or similar. Example:

clicked = e.CurriedConditionallyReturn(e, e.IsInInteraction, myFunction)

Return value only if the conditionfunction evaluates to true. The curried version is called CurriedConditionallyReturn. A naive and stupid AI. This is an extremely simplistic AI. You'll probably want to write your own instead.

It takes the turn for e.current_player. It loops through each of that player's units in the order they were created. For each one, it tries to move as close to a unit controlled by e.PLAYER as it can, planning a route up to 4 turns ahead. Then it calls the first function in u.AttackFunctions, supplying the targeted unit as a parameter.

No consideration is given to weapon ranges, strategic considerations, or anything like that. It might do for attacks by melee-fighting beasts. Create a ui label showing the selected unit's name, suitable for inclusion in e.unit_info. The window will be in style style.engine_label["unit name"], and the text in style style.engine_label_text["unit name"]. Create a ui label showing the selected unit's HP, suitable for inclusion in e.unit_info. The window will be in style style.engine_label["HP"], and the text in style style.engine_label_text["HP"]. Create a ui label showing the selected unit's MP, suitable for inclusion in e.unit_info. The window will be in style style.engine_label["MP"], and the text in style style.engine_label_text["MP"]. Create a ui label showing the selected unit's AP, suitable for inclusion in e.unit_info. The window will be in style style.engine_label["AP"], and the text in style style.engine_label_text["AP"]. Create a ui label showing the selected unit's number of MP-mode actions left, suitable for inclusion in e.unit_info. The window will be in style style.engine_label["actions left"], and the text in style style.engine_label_text["actions left"]. Create a ui label showing the selected unit's (gridx, gridy) position, suitable for inclusion in e.unit_info. The window will be in style style.engine_label["position"], and the text in style style.engine_label_text["position"]. Return True if the specified square contains any unit. This criterion is suitable for use in a UnitEngine's HighlightSquares function. Return True if the specified square contains a unit controlled by the current player. This criterion is suitable for use in a UnitEngine's HighlightSquares function. Return True if the specified square contains a unit controlled by someone other than the current player. This criterion is suitable for use in a UnitEngine's HighlightSquares function. Return True if the specified square is within the specified number of orthogonal steps from the selected unit. This criterion is suitable for use in a UnitEngine's HighlightSquares function. Return True if the selected unit is controlled by the current player. This criterion is suitable for use in a UnitEngine's unit_info property. Return True if the selected unit is controlled by someone other the current player. This criterion is suitable for use in a UnitEngine's unit_info property. Replace the normal buttons with a menu offering the specified options. This can be used to provide action options when the user selects "Act", or at most other times. Do not call it from inside a Show callback. A list of (string, callback) tuples, each one corresponding to a menu item to be shown. If True (default), a button will be added at the end of the list, which will call e.CancelAction() when selected. Destroy the specified unit. The unit's is_alive flag is set to False, then the engine's callbacks.unit_destroyed function is called. Finally the unit is removed from the engine's units list and the map. Reduce the specified unit's HP by the specified amount, destroying it if the HP is now 0 or less. The amount of damage to deal. The unit to deal damage to. DamageUnitBy is the curried version. So for example, DamageUnitBy(30) will return a function that, when called with some unit, deals 30 damage to that unit. End processing of an action and return to UNITSELECTED mode. This should be called from the end of every user action function, once the action has completely finished, to return to normal operation. If the engine is in AP mode, the selected unit's AP will be reduced by this amount. Default is 1. If the engine is in MP mode, the selected unit's number of remaining actions will be reduced by this amount. Default is 1.

Unit object

When the UnitEngine's Unit() function is called, a Unit object is created. (They should not be created directly.) Unit objects provide the following functions:

Functions:

Turn the unit to point towards the target. The unit's direction_facing property will be updated. The number of possible values is the unit's display_directions property. Can be either a unit, or a (gridx, gridy) tuple. Find a path for the unit from its current position to the specified position and move it. The unit's position and direction_facing are updated at each step, and the engine's callbacks.unit_moves will be called. If True (default), the UnitEngine's viewport will be scrolled to centre on the unit at each step. If True (default), the unit's MP/AP total will be decreased at each step by the grid square's movement_cost. Return a path for the unit from its current position to the specified position. Output is a list of (gridx, gridy) positions. The target position, as a (gridx, gridy) tuple. Permanently remove the unit from the UnitEngine.