http://powdertoy.co.uk/Wiki/api.php?action=feedcontributions&user=Maticzpl&feedformat=atomThe Powder Toy - User contributions [en]2024-03-29T06:40:31ZUser contributionsMediaWiki 1.30.0http://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Renderer&diff=9226Lua API:Renderer2024-03-28T23:06:52Z<p>Maticzpl: Remove old duplicate ren.decorations function documentation</p>
<hr />
<div>The renderer api can be used to control how the simulation in TPT gets rendered. You can set render / display modes, and change things related to the HUD / grid mode. Some renderer related functions are in the legacy tpt.* api.<br />
<br />
ren.* is an alias for renderer.* and can be used to write things shorter.<br />
<br />
== Methods ==<br />
<br />
=== renderer.renderModes ===<br />
table ren.renderModes()<br />
ren.renderModes(table newModes)<br />
If called with no arguments, returns a table containing the currently activated render modes. If called with a table argument, turns on all the render modes specified in the table. Render modes are typically used to change the way all particles render, display modes set extra added effects.<br />
<br />
Print out all current render modes in hex:<br />
<syntaxhighlight lang="lua"><br />
for k,v in pairs(ren.renderModes()) do<br />
print(k,"0x"..bit.tohex(v))<br />
end<br />
>>1, 0x00fff380; 2, 0xff00f270; 3, 0x0400f381<br />
</syntaxhighlight><br />
<br />
<br />
Set the current render mode to a weird form of blob display<br />
<syntaxhighlight lang="lua"><br />
ren.renderModes({ren.RENDER_BLOB, ren.RENDER_EFFE})<br />
</syntaxhighlight><br />
<br />
=== renderer.displayModes ===<br />
table ren.displayModes()<br />
ren.displayModes(table newModes)<br />
Works exactly like rennder.renderModes(). If called with no arguments, returns a table containing the currently activated display modes. If called with a table argument, turns on all the display modes specified in the table. Render modes are typically used to change the way all particles render, display modes set extra added effects.<br />
<br />
Print out all current display modes in hex:<br />
<syntaxhighlight lang="lua"><br />
for k,v in pairs(ren.displayModes()) do<br />
print(k,"0x"..bit.tohex(v))<br />
end<br />
>>1, 0x00000002; 2, 0x00000010<br />
</syntaxhighlight><br />
<br />
<br />
Set the current display mode to persistent with cracker velocity display<br />
<syntaxhighlight lang="lua"><br />
ren.displayModes({ren.DISPLAY_AIRC, ren.DISPLAY_PERS})<br />
</syntaxhighlight><br />
<br />
=== renderer.colourMode ===<br />
number ren.colourMode()<br />
ren.colourMode(number colourMode)<br />
<br />
number ren.colorMode<br />
ren.colorMode(number colourMode)<br />
<br />
This function takes one optional integer and sets which colour modes the currently appIying render mode uses. If the function is called with no arguments, it returns the current colour mode as an integer as well.<br />
<br />
A colour mode is basically a description of how particles are drawn. The other details which are considered when particles are drawn are fire mode, pixel mode and effect mode (rare cases like portals).<br />
<br />
On the bottom of this page there's [[#Color_modes|a list of descriptions]] of what each colour mode does.<br />
<br />
=== renderer.grid ===<br />
number ren.grid()<br />
ren.grid(number gridSize)<br />
If called with no arguments, returns the current grid size (normally set with 'g'). Grid sizes range from 0 (no grid) to 9. Each size increases the number of pixels between lines by 4.<br />
<br />
If an argument is passed in, sets the current grid size. There are no checks to make sure it is in the valid range, but if negative numbers are passed in it may cause strange behavior.<br />
<br />
=== renderer.hud ===<br />
Controls if the hud is shown or not.<br />
<br />
<pre>renderer.hud(enabled)<br />
enabled = renderer.hud()</pre><br />
* <code>enabled</code>: boolean flag that specifies if the HUD is enabled or not.<br />
<br />
=== renderer.debugHUD ===<br />
number ren.debugHUD()<br />
ren.debugHUD(number debugSetting)<br />
If called with no arguments, returns a 0 or a 1 representing whether the debug HUD (normally set with 'd') is on or off. If a number is passed in, turns the debug HUD on or off.<br />
<br />
=== renderer.showBrush ===<br />
number ren.showBrush()<br />
ren.showBrush(number brushSetting)<br />
If called with no arguments, returns a 0 or a 1 representing whether the brush is currently shown. If a number is passed in, disables rendering the brush. This function is intended for recording scripts which want to hide the brush and other hud elements.<br />
<br />
=== renderer.zoomEnabled ===<br />
ren.zoomEnabled(bool zoomState)<br />
bool ren.zoomEnabled()<br />
If called with no arguments, returns a boolean indicating whether the zoom window is open or not. <br />
If a number is passed in, it shows or hides the zoom window.<br />
<br />
=== renderer.zoomScope ===<br />
number, number, number ren.zoomScope()<br />
ren.zoomScope(number x, number y, number size)<br />
The zoom scope defines the area where to zoom in.<br />
If called with no arguments, returns 3 numbers: left top corner X position, left top corner Y position and its size. <br />
If arguments are passed then the zoom scope will be moved to the specified X and Y coordinates (from its top left corner). It will also make it span the amount of pixels specified by the 'size' argument equally in width and height.<br />
<br />
=== renderer.zoomWindow ===<br />
number, number, number, number ren.zoomWindow()<br />
ren.zoomWindow(number x, number y, number zoomFactor)<br />
The zoom window displays the magnified image.<br />
If called with no arguments, returns 4 numbers: left top corner X position, left top corner Y position, the zoom factor and the inner window size in pixels. <br />
If arguments are passed then the zoom window will be moved to the specified X and Y coordinates (from its top left corner) and change its zoom factor.<br />
<br />
=== renderer.decorations ===<br />
<br />
Controls whether the decorations layer is enabled.<br />
<br />
<pre>renderer.decorations(enabled)<br />
enabled = renderer.decorations()</pre><br />
* <code>enabled</code>: boolean true/false flag that specifies whether deco is on or off.<br />
<br />
=== renderer.fireSize ===<br />
<br />
Controls intensity of fire effects. The default is 1. Other values may cause glitchy graphics such as CELL borders appearing in fire effects.<br />
<br />
<pre>renderer.fireSize(size)<br />
size = renderer.fireSize()</pre><br />
* <code>size</code>: floating point value that specifies the fire intensity.<br />
<br />
=== renderer.useDisplayPreset ===<br />
<br />
Loads a standard display preset, as if you pressed a number key.<br />
<br />
<pre>renderer.useDisplayPreset(preset)</pre><br />
* <code>preset</code>: The preset to enable.<br />
<br />
Presets start at 0, so preset 0 is velocity display, and preset 3 is fire display. Most presets match the order of the in-game shortcuts, except for life gradient display - preset 9, and alternate velocity display - preset 10.<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with renderer.<constant name here><br />
<br />
=== Particle graphics function modes ===<br />
These should be used in lua graphics functions to set how particles will be drawn. Effects like fire, glowing, and flares are set here. How a particle is actually rendered depends on the current render and display modes.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>value</b><br />
|<b>description</b><br />
|-<br />
|PMODE<br />
|0x00000FFF<br />
|A bitmask which can be used to check if a particle has any PMODEs set.<br />
|-<br />
|PMODE_NONE<br />
|0x00000000<br />
|Don't draw a point where a particle is at all. Unused.<br />
|-<br />
|PMODE_FLAT<br />
|0x00000001<br />
|Draw a basic pixel, overwriting the color under it. Given by default to everything unless overridden, Doesn't support cola.<br />
|-<br />
|PMODE_BLOB<br />
|0x00000002<br />
|Draw a blob like in blob mode. Everything is given this in blob display mode, but can be set manually.<br />
|-<br />
|PMODE_BLUR<br />
|0x00000004<br />
|Blur effect, used in fancy display mode. Given to all liquids without a graphics functions by default, if not this isn't set.<br />
|-<br />
|PMODE_GLOW<br />
|0x00000008<br />
|Glow effect, used in elements like DEUT and TRON in fancy display mode, also given to radioactive elements.<br />
|-<br />
|PMODE_SPARK<br />
|0x00000010<br />
|Draws a very light sparkle around a particle.<br />
|-<br />
|PMODE_FLARE<br />
|0x00000020<br />
|Draws a flare around a particle, used by BOMB.<br />
|-<br />
|PMODE_LFLARE<br />
|0x00000040<br />
|Very large and bright flare, used by DEST when it hits something.<br />
|-<br />
|PMODE_ADD<br />
|0x00000080<br />
|Like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
|-<br />
|PMODE_BLEND<br />
|0x00000100<br />
|Basically the same thing as PMODE_ADD, but has better OpenGL support<br />
|-<br />
|PSPEC_STICKMAN<br />
|0x00000200<br />
|Used by stickmen. Won't do anything unless the element actually is a stickman.<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|OPTIONS<br />
|0x0000F000<br />
|A bitmask which can be used to check if a particle has any display options set.<br />
|-<br />
|NO_DECO<br />
|0x00001000<br />
|Prevents decoration from being shown on an element.<br />
|-<br />
|DECO_FIRE<br />
|0x00002000<br />
|Allows decoration to be drawn onto the fire effect. All gasses have this on by default.<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|FIREMODE<br />
|0x00FF0000<br />
|A bitmask which can be used to check if a particle has any fire graphics set.<br />
|-<br />
|FIRE_ADD<br />
|0x00010000<br />
|Adds a weak fire effect around an element. Does not support many colors like FIRE_BLEND does.<br />
|-<br />
|FIRE_BLEND<br />
|0x00020000<br />
|Adds a strong fire effect around an element. All gasses have this on by default.<br />
|-<br />
|FIRE_SPARK<br />
|0x00040000<br />
|Adds a moderate fire effect around an element. Used by SPRK.<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|EFFECT<br />
|0xFF000000<br />
|A bitmask which can be used to check if a particle has any special effects set.<br />
|-<br />
|EFFECT_GRAVIN<br />
|0x01000000<br />
|Adds a PRTI effect. Won't work unless .life and .ctype are set properly in an update function.<br />
|-<br />
|EFFECT_GRAVOUT<br />
|0x02000000<br />
|Adds a PRTO effect. Won't work unless .life and .ctype are set properly in an update function.<br />
|-<br />
|EFFECT_LINES<br />
|0x04000000<br />
|Used by SOAP to draw lines between attached SOAP particles. Ignored by everything else.<br />
|-<br />
|EFFECT_DBGLINES<br />
|0x08000000<br />
|Draw lines between particles of the same type with similar temperatures. Used by WIFI and portals to draw lines between particles of the same channel when in debug mode.<br />
|}<br />
<br />
=== Render modes ===<br />
These are the values used and returned by ren.renderMode. They are combinations of the above values, and sometimes overlap. All source definitions also include OPTIONS and PSPEC_STICKMAN (so that options can always be set and stickmen are always rendered), but they are not listed here.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>definition in source</b><br />
|<b>description</b><br />
|-<br />
|RENDER_EFFE<br />
| EFFECT | PMODE_SPARK | PMODE_FLARE | PMODE_LFLARE<br />
|Used in all display modes except for heat, nothing, heat gradient, and life gradient. Turns on all basic effects like flares and portal effects.<br />
|-<br />
|RENDER_FIRE<br />
| PMODE_ADD | PMODE_BLEND | FIREMODE<br />
|Used in fire, blob, and fancy display modes. Turns on all fire effects.<br />
|-<br />
|RENDER_GLOW<br />
|PMODE_GLOW | PMODE_ADD | PMODE_BLEND<br />
|Used in fancy display mode, so that radioactive elements glow.<br />
|-<br />
|RENDER_BLUR<br />
|PMODE_BLUR | PMODE_ADD | PMODE_BLEND<br />
|Used in fancy display mode, to turn on the liquid blur effect.<br />
|-<br />
|RENDER_BLOB<br />
|PMODE_BLOB | PMODE_ADD | PMODE_BLEND<br />
|causes every particle to get PMODE_BLOB.<br />
|-<br />
|RENDER_BASC<br />
|PMODE_FLAT | PMODE_ADD | PMODE_BLEND | EFFECT_LINES<br />
|Used by every single display mode, turns on PMODE_FLAT so particles get displayed.<br />
|-<br />
|RENDER_NONE<br />
|PMODE_FLAT<br />
|Not used at all, but would make sure at least each individual pixel gets drawn.<br />
|}<br />
<br />
=== Display modes ===<br />
These are the values used and returned by ren.displayMode. They can be set together, although no official display mode does this.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>value</b><br />
|<b>description</b><br />
|-<br />
|DISPLAY_AIRC<br />
| 0x00000001<br />
|Cracker air display mode, used in alternate velocity display.<br />
|-<br />
|DISPLAY_AIRP<br />
| 0x00000002<br />
|Used by pressure display mode.<br />
|-<br />
|DISPLAY_AIRV<br />
| 0x00000004<br />
|Used by velocity display mode.<br />
|-<br />
|DISPLAY_AIRH<br />
| 0x00000008<br />
|Used by heat display mode.<br />
|-<br />
|DISPLAY_AIR<br />
| 0x0000000F<br />
|A bitmask which can be used to check if an air display mode is set.<br />
|-<br />
|DISPLAY_WARP<br />
| 0x00000010<br />
|Used by fancy display mode, turns on gravity lensing, causing newtonian gravity areas to bend light.<br />
|-<br />
|DISPLAY_PERS<br />
| 0x00000020<br />
|Used by persistent display mode.<br />
|-<br />
|DISPLAY_EFFE<br />
| 0x00000040<br />
|Doesn't do anything at all, unless maybe OpenGL is on. Unclear what it does even then.<br />
|}<br />
<br />
=== Color modes ===<br />
These are the values used and returned by ren.colorMode. Only one can be set at a time, and they control which types of colors particles are drawn in.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>description</b><br />
|-<br />
|COLOUR_DEFAULT<br />
|Default colors, nothing gets changed.<br />
|-<br />
|COLOUR_HEAT<br />
|Render elements in heat display colors. Pink = hottest, Blue = coldest.<br />
|-<br />
|COLOUR_LIFE<br />
|Render elements in a greyscale gradient dependent on .life value.<br />
|-<br />
|COLOUR_GRAD<br />
|Render elements normally, but with a slight greyscale gradient dependent on a particle's temperature.<br />
|-<br />
|COLOUR_BASC<br />
|Remove all color changes from elements, elements get rendered in whichever color their element button is.<br />
|-<br />
|}<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Simulation&diff=9224Lua API:Simulation2024-03-27T21:41:04Z<p>Maticzpl: Fix some stuff</p>
<hr />
<div>The Simulation API allows for modifying the state and properties of particles, air and gravity<br />
<br />
== Methods ==<br />
<br />
=== simulation.addCustomGol ===<br />
nil sim.addCustomGol(string rule, string name, number color1, number color2)<br />
Adds a custom game of life type with the specified rule, name, and colors. Rule strings use B#/S#/# notation ([https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Variations more detail]). Colors are used when fading between multiple states. Names and rules cannot be duplicates.<br />
<br />
nil sim.addCustomGol(number rule, string name, number color1, number color2)<br />
Same as above, but takes a binary representation of the rule instead of a string. Bits 0-8 list stay values (starting at 0), bits 9-16 list begin values (starting at 1), and bits 17-20 are the number of states (decimal value added to 2). This is also how GOL rules are stored as ctypes.<br />
<br />
=== simulation.adjustCoords ===<br />
number, number sim.adjustCoords(number x, number y)<br />
Actually this is more of a UI method than a simulation method. Given a mouse position x, y in the window, this function returns the corresponding coordinates in the simulation (taking into account the visibility and position of the zoom window, if applicable). <br />
<br />
=== simulation.airMode ===<br />
number sim.airMode()<br />
Returns the current Air Simulation Mode.<br />
<br />
nil sim.airMode(number mode)<br />
Sets the Air Simulation Mode to mode.<br />
<br />
Mode numbers are as follows (not currently available as named constants):<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal<br />
|-<br />
|1<br />
|Pressure off<br />
|-<br />
|2<br />
|Velocity off<br />
|-<br />
|3<br />
|Velocity and pressure off<br />
|-<br />
|4<br />
|No update<br />
|}<br />
<br />
=== simulation.ambientAirTemp ===<br />
number sim.ambientAirTemp()<br />
Returns the current ambient temperature. When ambient heat mode is turned on, the air at the edges of the screen will remain at this temperature. <br />
<br />
nil sim.ambientAirTemp(number temp)<br />
Sets the ambient temperature. The temperature is measured in Kelvin. <br />
<br />
=== simulation.ambientHeat ===<br />
number sim.ambientHeat(number x, number y)<br />
Returns a value on the ambient heat map (the temperature of the air at that point). <br />
<br />
nil sim.ambientHeat(number x, number y, [number width, number height], number temp)<br />
Sets values on the ambient heat map. <br />
<br />
=== simulation.ambientHeatSim ===<br />
sim.ambientHeatSim(enabled)<br />
enabled = sim.ambientHeat()<br />
* <code>enabled</code>: Flag that specifies whether ambient heat is enabled or not.<br />
<br />
=== simulation.brush ===<br />
function sim.brush(number x, number y, [number brushWidth, number brushHeight], [number brushID])<br />
Returns an iterator over positions inside the specified brush.<br />
<br />
If width, height or ID is not provided, will use values of the current brush selected by user.<br />
<br />
Example:<br />
for x, y in sim.brush(300, 200, 100, 50, 0) do<br />
sim.partCreate(-1, x, y, elem.DEFAULT_PT_DUST)<br />
end<br />
<br />
=== simulation.can_move ===<br />
simulation.can_move(number movingElementID, number obstacleElementID, number method)<br />
Decides what a particle does when it hits another particle while moving. Method is one of the following:<br />
* 0: bounce off the obstacle<br />
* 1: swap places with the obstacle<br />
* 2: move over the obstacle<br />
<br />
number simulation.can_move(number movingElementID, number obstacleElementID)<br />
Returns what a particle does when it hits another particle while moving, a method like above.<br />
<br />
=== simulation.clearRect ===<br />
nil sim.clearRect(number x, number y, number width, number height)<br />
Clears all particles in a rectangle starting at x, y down and to the right width and height pixels respectively.<br />
<br />
=== simulation.clearSim ===<br />
nil sim.clearSim()<br />
Clears everything in the simulation.<br />
<br />
=== simulation.createBox ===<br />
nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])<br />
Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createLine ===<br />
nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])<br />
Creates a line of of either the user's currently selected type or the type specified at the specified coordinates.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createParts ===<br />
number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])<br />
Does something.<br />
<br />
=== simulation.createWallBox ===<br />
nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])<br />
Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWallLine ===<br />
nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])<br />
Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWalls ===<br />
number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])<br />
Does something. Probably with walls :/<br />
<br />
=== simulation.customGravity ===<br />
number, number sim.customGravity()<br />
Returns the current custom gravity settings as x and y values. Left and up are negative x and negative y respectively.<br />
<br />
nil sim.customGravity(number x, number y)<br />
Sets the custom gravity x and y values. Gravity mode must be set to "custom" to have any effect (see [[#simulation.gravityMode|sim.gravityMode]]).<br />
<br />
nil sim.customGravity(number y)<br />
Sets the custom gravity y value and sets the x value to 0.<br />
<br />
=== simulation.decoBox ===<br />
nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])<br />
Changes the decoration color of all particles in the specified coordinates.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoBrush ===<br />
nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Does something<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoColor ===<br />
number sim.decoColor()<br />
Returns the currently selected decoration color.<br />
<br />
nil sim.decoColor(number color)<br />
Sets the selected decoration color to color.<br />
color is in the format 0xAARRGGBB<br />
<br />
nil sim.decoColor(number r, number g, number b, [number a])<br />
Sets the selected decoration color to r,g,b,a<br />
<br />
=== simulation.decoColour ===<br />
Same as sim.decoColor()<br />
<br />
=== simulation.decoLine ===<br />
nil sim.decoLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Changes the decoration color of all particles in the line specified.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoSpace ===<br />
Controls the color space used by smudge tool.<br />
<br />
sim.decoLine(colorSpace)<br />
colorSpace sim.decoLine()<br />
* <code>space</code>: The color space, can be one of these constants:<br />
** <code>DECOSPACE_SRGB</code>: Standard SRGB color space<br />
** <code>DECOSPACE_LINEAR</code>: Linear color space<br />
** <code>DECOSPACE_GAMMA22</code>: Gamma 2.2<br />
** <code>DECOSPACE_GAMMA18</code>: Gamma 1.8<br />
** <code>NUM_DECOSPACES</code>: The total number of color spaces<br />
<br />
=== simulation.deleteStamp ===<br />
type sim.deleteStamp(string name)<br />
Deleting a stamp identified by filename or ID.<br />
<br />
=== simulation.edgeMode ===<br />
number sim.edgeMode()<br />
Returns the current Edge Mode<br />
<br />
nil sim.edgeMode(number mode)<br />
Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation. <br />
<br />
=== simulation.elecMap ===<br />
Interface with the elec map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map used to control powered walls like E-Wall and Detector.<br />
<br />
value sim.elecMap(x, y)<br />
sim.elecMap(x, y, value)<br />
sim.elecMap(x, y, w, h, value)<br />
* <code>value</code>: Elec map value. This is an integer that controls for how many frames wall electricity is active in this cell, 0 if there is no power.<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.elementCount ===<br />
number sim.elementCount(number type)<br />
Returns the number of particles of the specified type in the simulation.<br />
<br />
=== simulation.ensureDeterminism ===<br />
boolean sim.ensureDeterminism()<br />
nil sim.ensureDeterminism(boolean flag)<br />
<br />
'''Upcoming in version 98.0'''<br />
<br />
Fetch or set ensureDeterminism flag. When this flag is set, extra data is included in saves to ensure simulation RNG state is saved, along with other items needed to guarantee proper determinism upon loading the save. This is only useful for debugging, as different builds of the game may do things slightly differently on different machines. Further, Newtonian gravity is not deterministic with this flag enabled even in debugging scenarios.<br />
<br />
=== simulation.fanVelocityX ===<br />
Interface with the fan velocity map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map used to control fan velocity.<br />
<br />
value sim.fanVelocityX(x, y)<br />
sim.fanVelocityX(x, y, value)<br />
sim.fanVelocityX(x, y, w, h, value)<br />
* <code>value</code>: Fan X velocity, a floating point value<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.fanVelocityY ===<br />
Interface with the fan velocity map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map used to control fan velocity.<br />
<br />
value sim.fanVelocityY(x, y)<br />
sim.fanVelocityY(x, y, value)<br />
sim.fanVelocityY(x, y, w, h, value)<br />
* <code>value</code>: Fan Y velocity, a floating point value<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.floodDeco ===<br />
nil sim.floodDeco(number x, number y, number r, number g, number b, number a)<br />
Flood fills the color at position x, y with another color. Note: Color at position includes console overlay.<br />
<br />
=== simulation.floodParts ===<br />
number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])<br />
Flood fills either the user's currently selected type or the type specified at the coordinates given.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.floodWalls ===<br />
number sim.floodWalls(number x, number y, [number walltype], [number bm?])<br />
Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.framerender ===<br />
number sim.framerender()<br />
sim.framerender(number frames)<br />
Advances the simulation the given number of frames, even when paused. If called with no arguments, returns the number of frames currently to be rendered. Usually is 0.<br />
<br />
=== simulation.getSaveID ===<br />
number, number sim.getSaveID()<br />
Returns the save ID and the history offset of the currently loaded save or nil if the simulation is not a downloaded save. The history offset can be used with loadSave.<br />
<br />
=== simulation.gravityField ===<br />
Check the gravity output map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map that controls the output of Newtonian Gravity calculation.<br />
<br />
x-strength y-strength sim.gravityField(x, y)<br />
* <code>x-strength</code>: X strength of the gravity field at this location<br />
* <code>y-strength</code>: Y strength of the gravity field at this location<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
<br />
=== simulation.gravityMass ===<br />
Interface with the gravity input map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map that controls the input to the Newtonian Gravity calculation. The larger the value, the greater the mass / attraction to this location.<br />
<br />
strength sim.gravityMass(x, y)<br />
sim.gravityMass(x, y, strength)<br />
sim.gravityMass(x, y, w, h, strength)<br />
* <code>strength</code>: Strength of the input gravity at this location<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.gravMap ===<br />
'''DEPRECATED IN 98.0, replaced by sim.gravityMass and sim.gravityField'''<br />
<br />
number sim.gravMap(number x, number y)<br />
nil sim.gravMap(number x, number y, [number width, number height,] number value)<br />
Returns the newtonian gravity at the given coordinates in the simulation. If given a value, will set the newtonian gravity at those coordinates. Width and height refer to the rectangle of affected cells, starting with the coords. If not given, they will default to 1,1.<br />
<br />
=== simulation.gravityGrid ===<br />
number sim.gravityGrid()<br />
Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.<br />
<br />
nil sim.gravityGrid(number mode)<br />
Sets the setting for drawing the gravity grid to mode.<br />
<br />
=== simulation.gravityMode ===<br />
number sim.gravityMode()<br />
Returns the current gravity simulation mode.<br />
<br />
nil sim.gravityMode(number mode)<br />
Sets the gravity simulation mode to mode.<br />
<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal, vertical gravity<br />
|-<br />
|1<br />
|No gravity<br />
|-<br />
|2<br />
|Radial gravity<br />
|-<br />
|3<br />
|Custom gravity (see [[#simulation.customGravity|sim.customGravity]])<br />
|}<br />
<br />
=== simulation.gspeed ===<br />
number sim.gspeed()<br />
Returns the current GoL speed<br />
<br />
nil sim.gspeed(number newSpeed)<br />
Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.<br />
<br />
=== simulation.hash ===<br />
number simulation.hash()<br />
<br />
'''Upcoming in version 98.0'''<br />
<br />
Returns a 32-bit int represending the hash of the simulation's current state. Nearly all state is included, including particles, air, gravity, frame count, and rng state. Frame count's inclusion means that the hash changes every frame, even while paused).<br />
<br />
=== simulation.heatSim ===<br />
enabled = sim.heatSim()<br />
sim.heatSim(enabled)<br />
* <code>heatSim</code>: boolean flag that specifies whether heat simulation is turned on or off.<br />
<br />
=== simulation.historyForward===<br />
boolean simulation.historyForward()<br />
Tries restoring a redo snapshot (ctrl+y). Returns true on success, or false if there is no redo history to restore.<br />
<br />
=== simulation.historyRestore ===<br />
boolean simulation.historyRestore()<br />
Tries restoring a history snapshot (ctrl+z). Returns true on success, or false if there is no history to restore.<br />
<br />
=== simulation.lastUpdatedID ===<br />
type sim.lastUpdatedID()<br />
Returns the last updated particle ID, if the simulation is currently being stepped through particle-by-particle (either using sim.updateUpTo or user input with tpt.setdebug(0x8)). If subframe particle debugging isn't active, returns nil.<br />
<br />
=== simulation.listCustomGol ===<br />
table sim.listCustomGol()<br />
Returns a table of all custom game of life types. Each index has a name (string), rulestr (string), rule (number), color1 (number), and color2 (number) property. See [[#simulation.addCustomGol|sim.addCustomGol]] for details about properties.<br />
<br />
=== simulation.listStamps ===<br />
table sim.listStamps()<br />
Returns a table of stamps, in order. Stamp names are 10 characters, with no .stm extention or stamps/ prefix.<br />
<br />
=== simulation.loadSave ===<br />
nil sim.loadSave(number SaveID, [number hideDescription], [number history?])<br />
Loads the save associated with the specified SaveID.<br />
If hideDescription is non zero, the information for the save is not shown.<br />
<br />
=== simulation.loadStamp ===<br />
sim.loadStamp(string filename, number x, number y)<br />
sim.loadStamp(number id, number x, number y)<br />
Loads a stamp identified by filename or ID, and places it at position x,y. Filenames should be given without stamps/ or the .stm suffix. On success, returns 1. On failure, returns nil and the failure reason as a string.<br />
<br />
'''Changes staged for 98.0'''<br />
<br />
The signature changes to:<br />
<br />
sim.loadStamp(string filename, number x, number y, [boolean hflip, [number rotation, [boolean includePressure]]])<br />
sim.loadStamp(number id, number x, number y, [boolean hflip, [number rotation, [boolean includePressure]]])<br />
<br />
The following changes are applied to the stamp before pasting, in this order:<br />
* if hflip is true, a horizontal flip is applied to the save (same as pressing Shift+R when pasting)<br />
* if rotation is present, this number of 90-degree counterclockwise rotations are applied to the save (same as pressing R this many times when pasting)<br />
* if the position x,y is not CELL-aligned, the stamp is pasted with its top left corner at the nearest CELL-aligned position toward negative infinity, and the difference between this position and the requested one is achieved via "nudging" (same as pressing the arrow keys a few times when pasting)<br />
<br />
=== simulation.neighbors ===<br />
type sim.neighbors(number x, number y, [number rx], [number ry], [number type])<br />
Used for iterating through particles in an area centred on the given coordinates (x, y). Radius in the x and y directions is set by rx and ry. Default radius is 2, 2. If type is provided, only particles of the corresponding type will be returned.<br />
<br />
The size of the rectangular area is one plus twice the radius, so a radius of 2, 2 gives a 5x5 pixel area centred on x, y. Particles in the centre position x, y are excluded. Only one particle in each position is included, and energy particles (such as photons, neutrons, electrons) are ignored.<br />
<br />
Example (i is the index of the neighbouring particle and nx, ny are its coordinates):<br />
<syntaxhighlight lang="lua"><br />
for i,nx,ny in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
Or if coordinates of the neighbouring particles are not required:<br />
<syntaxhighlight lang="lua"><br />
for i in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.neighbours ===<br />
Same as sim.neighbors()<br />
<br />
=== simulation.newtonianGravity ===<br />
enabled = sim.newtonianGravity()<br />
sim.newtonianGravity(enabled)<br />
* <code>newtonianGravity</code>: boolean flag that specifies whether Newtonian Gravity is turned on or off.<br />
<br />
=== simulation.partChangeType ===<br />
nil sim.partChangeType(number index, number type)<br />
Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.<br />
<br />
=== simulation.partCount ===<br />
count = sim.partCount()<br />
* <code>count</code>: Total count of all particles in the sim.<br />
<br />
=== simulation.partCreate ===<br />
number sim.partCreate(number index, number x, number y, number type, [number v])<br />
Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure. <br />
<br />
Possible values for index are:<br />
<br />
* -1 : Normal particle creation. This is the most useful value. No particle is created if position x, y is occupied and the requested new particle type cannot pass through the particle that is already there.<br />
* -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.<br />
* -3 : Create particle without checking for collisions with existing particles. In most cases, this is a bad idea, since a lot of elements don't work properly when there are multiple particles in the same place. Particles may also turn into BHOL if there are too many in the same place. The exception to this is elements that have been specifically designed to cope with this (such as multiple energy particles like PHOT and NEUT in the same place). <br />
* particle index, >= 0 : Overwrite an existing particle with a new particle. At the moment no collision checking is performed, so the same considerations apply as for index=-3. It is usually safe if the new particle is in the same location as the old one. This is roughly equivalent to calling sim.partKill then sim.partCreate(-3, ...).<br />
<br />
=== simulation.partExists ===<br />
boolean sim.partExists(number index)<br />
Returns true if a particle exists at a given index.<br />
<br />
=== simulation.partID ===<br />
number sim.partID(number x, number y)<br />
Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.<br />
<br />
Example (though this is probably best done with sim.neighbours):<br />
<syntaxhighlight lang="lua"><br />
for fx = -1, 1, 1 do<br />
for fy = -1, 1, 1 do<br />
local i = sim.partID(x + fx, y + fy)<br />
if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then<br />
sim.partProperty(index, sim.FIELD_TEMP, 9999)<br />
end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.partKill ===<br />
nil sim.partKill(number index)<br />
nil sim.partKill(number x, number y)<br />
Reliably delete a particle at a specified index or location, this method avoids the side effects created by changing the type to 0/DEFAULT_PT_NONE with the "partProperty" method<br />
<br />
=== simulation.partNeighbors ===<br />
table sim.partNeighbours(number x, number y, number radius, [number type])<br />
Returns an array of indices of particles that neighbour the given coordinates and match the given type (if it is specified). The resulting array does not contain the particle at the specified position.<br />
<br />
=== simulation.partNeighbours ===<br />
Same as sim.partNeighbors()<br />
<br />
=== simulation.partPosition ===<br />
number x, number y sim.partPosition(number index)<br />
Get the location of the particle at the specified index <br />
<br />
=== simulation.partProperty ===<br />
nil sim.partProperty(number index, object field, object value)<br />
Set the property value on a particle specified by index<br />
<br />
object sim.partProperty(number index, object field)<br />
Get the property value on a particle specified by the index<br />
<br />
The "field" may be a field name or field ID, see FIELD constants below for valid fields.<br />
<br />
=== simulation.parts ===<br />
function sim.parts()<br />
Returns an iterator over particle indexes that can be used in lua for loops<br />
<br />
=== simulation.paused ===<br />
flag = sim.paused()<br />
sim.paused(flag)<br />
* <code>flag</code>: Boolean flag that says whether or not the sim is paused.<br />
<br />
Checks whether or not the simulation is paused. Processing may also continue if the 'f' framerender shortcut is used, which can last for long periods of time. [[#simulation.framerender|sim.framerender]] should be used to check for that<br />
<br />
=== simulation.pmap ===<br />
number sim.pmap(number x, number y)<br />
Get the index of the particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.partID, but excludes energy particles (such as PHOT, NEUT, ELEC).<br />
<br />
=== simulation.photons ===<br />
number sim.photons(number x, number y)<br />
Get the index of the energy particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.pmap<br />
<br />
=== simulation.pressure ===<br />
number sim.pressure(number x, number y)<br />
Returns a value on the pressure map.<br />
<br />
nil sim.pressure(number x, number y, [number width, number height], number pressure)<br />
Sets values on the pressure map.<br />
<br />
=== simulation.prettyPowders ===<br />
number sim.prettyPowders()<br />
nil sim.prettyPowders(mode)<br />
Sets whether the "pretty powders mode" (powders, such as SAND or BCOL, will be assigned random deco values) is on or off. When called with no arguments, returns a value determining whether it is on or off.<br />
<br />
=== simulation.randomSeed ===<br />
number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper sim.randomSeed()<br />
nil sim.randomSeed(number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper)<br />
<br />
'''Upcoming in version 98.0'''<br />
<br />
Retrieve or set the seed used for the Simulation RNG. This RNG is used by TPT to generate random numbers during sim contexts. The renderer RNG and interface RNG are unaffected.<br />
<br />
Because seeds are 64 bits, they are fetched/set in two sets of 32 bits integers.<br />
<br />
=== simulation.reloadSave ===<br />
nil sim.reloadSave()<br />
Reloading save.<br />
<br />
=== simulation.removeCustomGol ===<br />
boolean sim.removeCustomGol(string name)<br />
Removes all custom game of life types with the specified name. Returns true if any were removed.<br />
<br />
=== simulation.resetGravityField ===<br />
sim.resetGravityField()<br />
Resets the gravity field to 0. While this will temporarily stop all Newtonian Gravity output, any changes will regenerate the gravity map based on the gravity sources in the sim.<br />
<br />
=== simulation.resetPressure ===<br />
sim.resetPressure()<br />
Resets the pressure map to no pressure.<br />
<br />
=== simulation.resetSpark ===<br />
sim.resetSpark()<br />
Same effect as the ctrl+= shortcut. Removes all sparks from the simulation and resets them to .life = 0. SPRK with invalid ctypes are deleted. Also resets all wifi cooldowns.<br />
<br />
=== simulation.resetTemp ===<br />
sim.resetTemp()<br />
Resets the temperature of all particles to their spawn temperature.<br />
<br />
=== simulation.resetVelocity ===<br />
sim.resetVelocity()<br />
Resets the air velocity map to 0. This map controls the flow of air. Resetting this will have some effect on particles, but won't stop them in their tracks.<br />
<br />
=== simulation.replaceModeFlags ===<br />
number sim.replaceModeFlags()<br />
Returns the current replace mode flags.<br />
nil sim.replaceModeFlags(number flags)<br />
Sets the replace mode flags.<br />
<br />
If the first bit of that number is set (flags = 1), replace mode is enabled.<br />
<br />
If the second bit is set (flags = 2), specific delete is enabled.<br />
<br />
=== simulation.saveStamp ===<br />
string sim.saveStamp([number x, number y, number width, number height, [boolean includePressure]])<br />
Creates a stamp of the specified coordinates. Coordinates default to entire simulation.<br />
Returns the stamp id created.<br />
<br />
=== simulation.signs ===<br />
table simulation.signs<br />
A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.<br />
<br />
==== Constants ====<br />
* <code>sim.signs.MAX_SIGNS</code>: The maximum number of signs that can exist at once<br />
* <code>sim.signs.JUSTMODE_LEFT</code>: Left justification<br />
* <code>sim.signs.JUSTMODE_MIDDLE</code>: Middle (default) justification<br />
* <code>sim.signs.JUSTMODE_RIGHT</code>: Right justification<br />
* <code>sim.signs.JUSTMODE_NONE</code>: No justification, sign won't have any "tail"<br />
* <code>sim.signs.NUM_JUSTMODES</code>: The number of justification modes<br />
<br />
==== simulation.signs[n] ====<br />
table simulation.signs[n]<br />
A table which always contains the id property. May also contain text, x, y and justification. These properties can be directly modified to change a sign.<br />
A justification of 0 means left, 1 means right, 2 means middle and 3 means none.<br />
The text property cannot be larger than 45 in length.<br />
<br />
==== simulation.signs.delete ====<br />
nil simulation.signs.delete(number signID)<br />
Deletes the sign at the specified sign id.<br />
<br />
==== simulation.signs.new ====<br />
number simulation.signs.new([string text, number x, number y, number justification])<br />
Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).<br />
<br />
=== simulation.takeSnapshot ===<br />
nil sim.takeSnapshot()<br />
Takes a undo snapshot, for use with ctrl + z<br />
<br />
=== simulation.temperatureScale ===<br />
number sim.temperatureScale()<br />
Returns the current temperature scale. 0 = Kelvin, 1 = Celsuis, 2 = Fahrenheit<br />
<br />
nil sim.temperatureScale(number newTemperatureScale)<br />
Sets the current temperature scale. 0 = Kelvin, 1 = Celsuis, 2 = Fahrenheit. Other options are invalid and will throw an error.<br />
<br />
=== simulation.toolBox ===<br />
type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) in a rectangular area.<br />
<br />
=== simulation.toolBrush ===<br />
number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) on the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.toolLine ===<br />
type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) as if a line was drawn across the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.updateUpTo ===<br />
nil sim.updateUpTo([number upTo])<br />
Updates the simulation, but only up to the specified particle ID. Works as if shift+f is pressed while in particle debug mode (tpt.setdebug(0x8)). If no arguments are passed in, updates to the end of the frame.<br />
<br />
=== simulation.velocityX ===<br />
number sim.velocityX(number x, number y)<br />
Returns an X value on the velocity map.<br />
<br />
nil sim.velocityX(number x, number y, [number width, number height], number value)<br />
Sets X values on the velocity map.<br />
<br />
=== simulation.velocityY ===<br />
number sim.velocityY(number x, number y)<br />
Returns an Y value on the velocity map.<br />
<br />
nil sim.velocityY(number x, number y, [number width, number height], number value)<br />
Sets Y values on the velocity map.<br />
<br />
=== simulation.wallMap ===<br />
Interface with the wall map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map that specifies which walls are at what position.<br />
<br />
wallType sim.wallMap(x, y)<br />
sim.wallMap(x, y, wallType)<br />
sim.wallMap(x, y, w, h, wallType)<br />
* <code>wallType</code>: Wall type to set, wall type will be one of the constants in [[Lua_API:Simulation#Walls|sim.walls]]<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.waterEqualisation ===<br />
number sim.waterEqualisation()<br />
Returns the current Water equalisation setting.<br />
<br />
nil sim.waterEqualisation(number setting)<br />
Set the Water equalisation setting to setting.<br />
<br />
=== simulation.waterEqualization ===<br />
Same as sim.waterEqualisation()<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with simulation.<constant name here><br />
<br />
; XRES<br />
X Resolution of the sim<br />
; YRES<br />
Y Resolution of the sim<br />
; CELL<br />
Size of a wall / air simulation block<br />
; XCELLS<br />
The number of cells in the X direction<br />
; YCELLS<br />
The number of cells in the Y direction<br />
; NCELL<br />
The total number of cells in the simulation<br />
; NT<br />
No transition, used in *Transition [https://powdertoy.co.uk/Wiki/W/Element_Properties.html properties]<br />
; ST<br />
Special transition, used in *Transition properties, but there is no way to set a special transition handler from Lua<br />
; ITH<br />
Impossible temperature high, used along with NT to disable transitions<br />
; ITL<br />
Impossible temperature low, used along with NT to disable transitions<br />
; IPH<br />
Impossible pressure high, used along with NT to disable transitions<br />
; IPL<br />
Impossible pressure low, used along with NT to disable transitions<br />
; PT_NUM<br />
Maximum number of element IDs. Does not reflect the current number of elements, only the maximum that can be enabled at one time.<br />
; NUM_PARTS<br />
Not actually a constant, this is updated every frame to reflect the current number of particles in the sim. Deprecated by sim.partCount (TODO document that and remove this)<br />
; MAX_PARTS<br />
Maximum number of particles that can exist at once<br />
; R_TEMP<br />
Room temperature (22C), the default temperature for many elements<br />
; MAX_TEMP<br />
Maximum allowable temperature of the sim, in Kelvin<br />
; MIN_TEMP<br />
Minimum allowable temperature of the sim, in Kelvin<br />
; MAX_PRESSURE<br />
Maximum allowable pressure of the sim<br />
; MIN_PRESSURE<br />
Minimum allowable pressure of the sim<br />
; MAX_VELOCITY<br />
Particle velocity cap<br />
; ISTP<br />
Movement code step value. Particles scan their trajectory and only check for blockers each step.<br />
; CFDS<br />
Air sim related<br />
; PMAPBITS<br />
Number of bits used in pmap to store element type. This controls the element cap, which is 2^PMAPBITS<br />
; PMAPMASK<br />
Mask used to assign type to pmap. ((1<<PMAPBITS)-1)<br />
<br />
=== DECO ===<br />
Used in deco drawing functions<br />
; DECO_DRAW<br />
; DECO_CLEAR<br />
; DECO_ADD<br />
; DECO_SUBTRACT<br />
; DECO_MULTIPLY<br />
; DECO_DIVIDE<br />
; DECO_SMUDGE<br />
<br />
=== TOOL ===<br />
Used in tool drawing functions<br />
; TOOL_HEAT<br />
; TOOL_COOL<br />
; TOOL_VAC<br />
; TOOL_AIR<br />
; TOOL_PGRV<br />
; TOOL_NGRV<br />
; TOOL_MIX<br />
; TOOL_CYCL<br />
; TOOL_WIND<br />
<br />
=== FIELD ===<br />
Used in sim.partProperty<br />
; FIELD_TYPE<br />
; FIELD_LIFE<br />
; FIELD_CTYPE<br />
; FIELD_X<br />
; FIELD_Y<br />
; FIELD_VX<br />
; FIELD_VY<br />
; FIELD_TEMP<br />
; FIELD_FLAGS<br />
; FIELD_TMP<br />
; FIELD_TMP2<br />
; FIELD_TMP3<br />
; FIELD_TMP4<br />
; FIELD_DCOLOUR<br />
<br />
=== BRUSH ===<br />
Used in certain brush drawing functions<br />
; BRUSH_CIRCLE<br />
; BRUSH_SQUARE<br />
; BRUSH_TRIANGLE<br />
; NUM_DEFAULTBRUSHES<br />
Number of default brushes<br />
; BRUSH_NUM<br />
Number of total brushes, including any custom brushes<br />
<br />
=== EDGE ===<br />
Used in sim.edgeMode<br />
; EDGE_VOID<br />
; EDGE_SOLID<br />
; EDGE_LOOP<br />
; NUM_EDGEMODES<br />
<br />
=== AIR ===<br />
Used in sim.airMode<br />
; AIR_ON<br />
; AIR_PRESSUREOFF<br />
; AIR_VELOCITYOFF<br />
; AIR_OFF<br />
; AIR_NOUPDATE<br />
; NUM_AIRMODES<br />
<br />
=== GRAV ===<br />
Used in sim.gravityMode<br />
; GRAV_VERTICAL<br />
; GRAV_OFF<br />
; GRAV_RADIAL<br />
; GRAV_CUSTOM<br />
; NUM_GRAVMODES<br />
<br />
=== Walls ===<br />
; NUM_WALLS<br />
; walls<br />
sim.walls is a table containing a mapping of wall IDs to wall identifiers, and wall identifiers to wall IDs. This may come in handy for working with ui.activeTool, which uses identifiers.<br />
<br />
=== FLAG ===<br />
Used in .flags property<br />
; FLAG_MOVABLE<br />
; FLAG_PHOTDECO<br />
; FLAG_SKIPMOVE<br />
; FLAG_STAGNANT<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Simulation&diff=9216Lua API:Simulation2024-03-25T21:32:52Z<p>Maticzpl: Fix typo YELLS -> YCELLS in constants</p>
<hr />
<div>The Simulation API allows for modifying the state and properties of particles, air and gravity<br />
<br />
== Methods ==<br />
<br />
=== simulation.addCustomGol ===<br />
nil sim.addCustomGol(string rule, string name, number color1, number color2)<br />
Adds a custom game of life type with the specified rule, name, and colors. Rule strings use B#/S#/# notation ([https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Variations more detail]). Colors are used when fading between multiple states. Names and rules cannot be duplicates.<br />
<br />
nil sim.addCustomGol(number rule, string name, number color1, number color2)<br />
Same as above, but takes a binary representation of the rule instead of a string. Bits 0-8 list stay values (starting at 0), bits 9-16 list begin values (starting at 1), and bits 17-20 are the number of states (decimal value added to 2). This is also how GOL rules are stored as ctypes.<br />
<br />
=== simulation.adjustCoords ===<br />
number, number sim.adjustCoords(number x, number y)<br />
Actually this is more of a UI method than a simulation method. Given a mouse position x, y in the window, this function returns the corresponding coordinates in the simulation (taking into account the visibility and position of the zoom window, if applicable). <br />
<br />
=== simulation.airMode ===<br />
number sim.airMode()<br />
Returns the current Air Simulation Mode.<br />
<br />
nil sim.airMode(number mode)<br />
Sets the Air Simulation Mode to mode.<br />
<br />
Mode numbers are as follows (not currently available as named constants):<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal<br />
|-<br />
|1<br />
|Pressure off<br />
|-<br />
|2<br />
|Velocity off<br />
|-<br />
|3<br />
|Velocity and pressure off<br />
|-<br />
|4<br />
|No update<br />
|}<br />
<br />
=== simulation.ambientAirTemp ===<br />
number sim.ambientAirTemp()<br />
Returns the current ambient temperature. When ambient heat mode is turned on, the air at the edges of the screen will remain at this temperature. <br />
<br />
nil sim.ambientAirTemp(number temp)<br />
Sets the ambient temperature. The temperature is measured in Kelvin. <br />
<br />
=== simulation.ambientHeat ===<br />
number sim.ambientHeat(number x, number y)<br />
Returns a value on the ambient heat map (the temperature of the air at that point). <br />
<br />
nil sim.ambientHeat(number x, number y, [number width, number height], number temp)<br />
Sets values on the ambient heat map. <br />
<br />
=== simulation.ambientHeatSim ===<br />
sim.ambientHeatSim(enabled)<br />
enabled = sim.ambientHeat()<br />
* <code>enabled</code>: Flag that specifies whether ambient heat is enabled or not.<br />
<br />
=== simulation.brush ===<br />
function sim.brush(number x, number y, [number brushWidth, number brushHeight], [number brushID])<br />
Returns an iterator over positions inside the specified brush.<br />
<br />
If width, height or ID is not provided, will use values of the current brush selected by user.<br />
<br />
Example:<br />
for x, y in sim.brush(300, 200, 100, 50, 0) do<br />
sim.partCreate(-1, x, y, elem.DEFAULT_PT_DUST)<br />
end<br />
<br />
=== simulation.can_move ===<br />
simulation.can_move(number movingElementID, number obstacleElementID, number method)<br />
Decides what a particle does when it hits another particle while moving. Method is one of the following:<br />
* 0: bounce off the obstacle<br />
* 1: swap places with the obstacle<br />
* 2: move over the obstacle<br />
<br />
number simulation.can_move(number movingElementID, number obstacleElementID)<br />
Returns what a particle does when it hits another particle while moving, a method like above.<br />
<br />
=== simulation.clearRect ===<br />
nil sim.clearRect(number x, number y, number width, number height)<br />
Clears all particles in a rectangle starting at x, y down and to the right width and height pixels respectively.<br />
<br />
=== simulation.clearSim ===<br />
nil sim.clearSim()<br />
Clears everything in the simulation.<br />
<br />
=== simulation.createBox ===<br />
nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])<br />
Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createLine ===<br />
nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])<br />
Creates a line of of either the user's currently selected type or the type specified at the specified coordinates.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createParts ===<br />
number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])<br />
Does something.<br />
<br />
=== simulation.createWallBox ===<br />
nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])<br />
Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWallLine ===<br />
nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])<br />
Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWalls ===<br />
number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])<br />
Does something. Probably with walls :/<br />
<br />
=== simulation.customGravity ===<br />
number, number sim.customGravity()<br />
Returns the current custom gravity settings as x and y values. Left and up are negative x and negative y respectively.<br />
<br />
nil sim.customGravity(number x, number y)<br />
Sets the custom gravity x and y values. Gravity mode must be set to "custom" to have any effect (see [[#simulation.gravityMode|sim.gravityMode]]).<br />
<br />
nil sim.customGravity(number y)<br />
Sets the custom gravity y value and sets the x value to 0.<br />
<br />
=== simulation.decoBox ===<br />
nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])<br />
Changes the decoration color of all particles in the specified coordinates.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoBrush ===<br />
nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Does something<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoColor ===<br />
number sim.decoColor()<br />
Returns the currently selected decoration color.<br />
<br />
nil sim.decoColor(number color)<br />
Sets the selected decoration color to color.<br />
color is in the format 0xAARRGGBB<br />
<br />
nil sim.decoColor(number r, number g, number b, [number a])<br />
Sets the selected decoration color to r,g,b,a<br />
<br />
=== simulation.decoColour ===<br />
Same as sim.decoColor()<br />
<br />
=== simulation.decoLine ===<br />
nil sim.decoLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Changes the decoration color of all particles in the line specified.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoSpace ===<br />
Controls the color space used by smudge tool.<br />
<br />
sim.decoLine(colorSpace)<br />
colorSpace sim.decoLine()<br />
* <code>space</code>: The color space, can be one of these constants:<br />
** <code>DECOSPACE_SRGB</code>: Standard SRGB color space<br />
** <code>DECOSPACE_LINEAR</code>: Linear color space<br />
** <code>DECOSPACE_GAMMA22</code>: Gamma 2.2<br />
** <code>DECOSPACE_GAMMA18</code>: Gamma 1.8<br />
** <code>NUM_DECOSPACES</code>: The total number of color spaces<br />
<br />
=== simulation.deleteStamp ===<br />
type sim.deleteStamp(string name)<br />
Deleting a stamp identified by filename or ID.<br />
<br />
=== simulation.edgeMode ===<br />
number sim.edgeMode()<br />
Returns the current Edge Mode<br />
<br />
nil sim.edgeMode(number mode)<br />
Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation. <br />
<br />
=== simulation.elecMap ===<br />
Interface with the elec map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map used to control powered walls like E-Wall and Detector.<br />
<br />
value sim.elecMap(x, y)<br />
sim.elecMap(x, y, value)<br />
sim.elecMap(x, y, w, h, value)<br />
* <code>value</code>: Elec map value. This is an integer that controls for how many frames wall electricity is active in this cell, 0 if there is no power.<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.elementCount ===<br />
number sim.elementCount(number type)<br />
Returns the number of particles of the specified type in the simulation.<br />
<br />
=== simulation.ensureDeterminism ===<br />
boolean sim.ensureDeterminism()<br />
nil sim.ensureDeterminism(boolean flag)<br />
<br />
'''Upcoming in version 98.0'''<br />
<br />
Fetch or set ensureDeterminism flag. When this flag is set, extra data is included in saves to ensure simulation RNG state is saved, along with other items needed to guarantee proper determinism upon loading the save. This is only useful for debugging, as different builds of the game may do things slightly differently on different machines. Further, Newtonian gravity is not deterministic with this flag enabled even in debugging scenarios.<br />
<br />
=== simulation.fanVelocityX ===<br />
Interface with the fan velocity map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map used to control fan velocity.<br />
<br />
value sim.fanVelocityX(x, y)<br />
sim.fanVelocityX(x, y, value)<br />
sim.fanVelocityX(x, y, w, h, value)<br />
* <code>value</code>: Fan X velocity, a floating point value<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.fanVelocityY ===<br />
Interface with the fan velocity map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map used to control fan velocity.<br />
<br />
value sim.fanVelocityY(x, y)<br />
sim.fanVelocityY(x, y, value)<br />
sim.fanVelocityY(x, y, w, h, value)<br />
* <code>value</code>: Fan Y velocity, a floating point value<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.floodDeco ===<br />
nil sim.floodDeco(number x, number y, number r, number g, number b, number a)<br />
Flood fills the color at position x, y with another color. Note: Color at position includes console overlay.<br />
<br />
=== simulation.floodParts ===<br />
number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])<br />
Flood fills either the user's currently selected type or the type specified at the coordinates given.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.floodWalls ===<br />
number sim.floodWalls(number x, number y, [number walltype], [number bm?])<br />
Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.framerender ===<br />
number sim.framerender()<br />
sim.framerender(number frames)<br />
Advances the simulation the given number of frames, even when paused. If called with no arguments, returns the number of frames currently to be rendered. Usually is 0.<br />
<br />
=== simulation.getSaveID ===<br />
number, number sim.getSaveID()<br />
Returns the save ID and the history offset of the currently loaded save or nil if the simulation is not a downloaded save. The history offset can be used with loadSave.<br />
<br />
=== simulation.gravityField ===<br />
Check the gravity output map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map that controls the output of Newtonian Gravity calculation.<br />
<br />
x-strength y-strength sim.gravityField(x, y)<br />
* <code>x-strength</code>: X strength of the gravity field at this location<br />
* <code>y-strength</code>: Y strength of the gravity field at this location<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
<br />
=== simulation.gravityMass ===<br />
Interface with the gravity input map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map that controls the input to the Newtonian Gravity calculation. The larger the value, the greater the mass / attraction to this location.<br />
<br />
strength sim.gravityMass(x, y)<br />
sim.gravityMass(x, y, strength)<br />
sim.gravityMass(x, y, w, h, strength)<br />
* <code>strength</code>: Strength of the input gravity at this location<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.gravMap ===<br />
'''DEPRECATED IN 98.0, replaced by sim.gravityMass and sim.gravityField'''<br />
<br />
number sim.gravMap(number x, number y)<br />
nil sim.gravMap(number x, number y, [number width, number height,] number value)<br />
Returns the newtonian gravity at the given coordinates in the simulation. If given a value, will set the newtonian gravity at those coordinates. Width and height refer to the rectangle of affected cells, starting with the coords. If not given, they will default to 1,1.<br />
<br />
=== simulation.gravityGrid ===<br />
number sim.gravityGrid()<br />
Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.<br />
<br />
nil sim.gravityGrid(number mode)<br />
Sets the setting for drawing the gravity grid to mode.<br />
<br />
=== simulation.gravityMode ===<br />
number sim.gravityMode()<br />
Returns the current gravity simulation mode.<br />
<br />
nil sim.gravityMode(number mode)<br />
Sets the gravity simulation mode to mode.<br />
<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal, vertical gravity<br />
|-<br />
|1<br />
|No gravity<br />
|-<br />
|2<br />
|Radial gravity<br />
|-<br />
|3<br />
|Custom gravity (see [[#simulation.customGravity|sim.customGravity]])<br />
|}<br />
<br />
=== simulation.gspeed ===<br />
number sim.gspeed()<br />
Returns the current GoL speed<br />
<br />
nil sim.gspeed(number newSpeed)<br />
Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.<br />
<br />
=== simulation.hash ===<br />
number simulation.hash()<br />
<br />
'''Upcoming in version 98.0'''<br />
<br />
Returns a 32-bit int represending the hash of the simulation's current state. Nearly all state is included, including particles, air, gravity, frame count, and rng state. Frame count's inclusion means that the hash changes every frame, even while paused).<br />
<br />
=== simulation.heatSim ===<br />
enabled = sim.heatSim()<br />
sim.heatSim(enabled)<br />
* <code>heatSim</code>: boolean flag that specifies whether heat simulation is turned on or off.<br />
<br />
=== simulation.historyForward===<br />
boolean simulation.historyForward()<br />
Tries restoring a redo snapshot (ctrl+y). Returns true on success, or false if there is no redo history to restore.<br />
<br />
=== simulation.historyRestore ===<br />
boolean simulation.historyRestore()<br />
Tries restoring a history snapshot (ctrl+z). Returns true on success, or false if there is no history to restore.<br />
<br />
=== simulation.lastUpdatedID ===<br />
type sim.lastUpdatedID()<br />
Returns the last updated particle ID, if the simulation is currently being stepped through particle-by-particle (either using sim.updateUpTo or user input with tpt.setdebug(0x8)). If subframe particle debugging isn't active, returns nil.<br />
<br />
=== simulation.listCustomGol ===<br />
table sim.listCustomGol()<br />
Returns a table of all custom game of life types. Each index has a name (string), rulestr (string), rule (number), color1 (number), and color2 (number) property. See [[#simulation.addCustomGol|sim.addCustomGol]] for details about properties.<br />
<br />
=== simulation.listStamps ===<br />
table sim.listStamps()<br />
Returns a table of stamps, in order. Stamp names are 10 characters, with no .stm extention or stamps/ prefix.<br />
<br />
=== simulation.loadSave ===<br />
nil sim.loadSave(number SaveID, [number hideDescription], [number history?])<br />
Loads the save associated with the specified SaveID.<br />
If hideDescription is non zero, the information for the save is not shown.<br />
<br />
=== simulation.loadStamp ===<br />
sim.loadStamp(string filename, number x, number y)<br />
sim.loadStamp(number id, number x, number y)<br />
Loads a stamp identified by filename or ID, and places it at position x,y. Filenames should be given without stamps/ or the .stm suffix. On success, returns 1. On failure, returns nil and the failure reason as a string.<br />
<br />
'''Changes staged for 98.0'''<br />
<br />
The signature changes to:<br />
<br />
sim.loadStamp(string filename, number x, number y, [boolean hflip, [number rotation, [boolean includePressure]]])<br />
sim.loadStamp(number id, number x, number y, [boolean hflip, [number rotation, [boolean includePressure]]])<br />
<br />
The following changes are applied to the stamp before pasting, in this order:<br />
* if hflip is true, a horizontal flip is applied to the save (same as pressing Shift+R when pasting)<br />
* if rotation is present, this number of 90-degree counterclockwise rotations are applied to the save (same as pressing R this many times when pasting)<br />
* if the position x,y is not CELL-aligned, the stamp is pasted with its top left corner at the nearest CELL-aligned position toward negative infinity, and the difference between this position and the requested one is achieved via "nudging" (same as pressing the arrow keys a few times when pasting)<br />
<br />
=== simulation.neighbors ===<br />
type sim.neighbors(number x, number y, [number rx], [number ry], [number type])<br />
Used for iterating through particles in an area centred on the given coordinates (x, y). Radius in the x and y directions is set by rx and ry. Default radius is 2, 2. If type is provided, only particles of the corresponding type will be returned.<br />
<br />
The size of the rectangular area is one plus twice the radius, so a radius of 2, 2 gives a 5x5 pixel area centred on x, y. Particles in the centre position x, y are excluded. Only one particle in each position is included, and energy particles (such as photons, neutrons, electrons) are ignored.<br />
<br />
Example (i is the index of the neighbouring particle and nx, ny are its coordinates):<br />
<syntaxhighlight lang="lua"><br />
for i,nx,ny in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
Or if coordinates of the neighbouring particles are not required:<br />
<syntaxhighlight lang="lua"><br />
for i in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.neighbours ===<br />
Same as sim.neighbors()<br />
<br />
=== simulation.newtonianGravity ===<br />
enabled = sim.newtonianGravity()<br />
sim.newtonianGravity(enabled)<br />
* <code>newtonianGravity</code>: boolean flag that specifies whether Newtonian Gravity is turned on or off.<br />
<br />
=== simulation.partChangeType ===<br />
nil sim.partChangeType(number index, number type)<br />
Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.<br />
<br />
=== simulation.partCount ===<br />
count = sim.partCount()<br />
* <code>count</code>: Total count of all particles in the sim.<br />
<br />
=== simulation.partCreate ===<br />
number sim.partCreate(number index, number x, number y, number type, [number v])<br />
Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure. <br />
<br />
Possible values for index are:<br />
<br />
* -1 : Normal particle creation. This is the most useful value. No particle is created if position x, y is occupied and the requested new particle type cannot pass through the particle that is already there.<br />
* -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.<br />
* -3 : Create particle without checking for collisions with existing particles. In most cases, this is a bad idea, since a lot of elements don't work properly when there are multiple particles in the same place. Particles may also turn into BHOL if there are too many in the same place. The exception to this is elements that have been specifically designed to cope with this (such as multiple energy particles like PHOT and NEUT in the same place). <br />
* particle index, >= 0 : Overwrite an existing particle with a new particle. At the moment no collision checking is performed, so the same considerations apply as for index=-3. It is usually safe if the new particle is in the same location as the old one. This is roughly equivalent to calling sim.partKill then sim.partCreate(-3, ...).<br />
<br />
=== simulation.partExists ===<br />
boolean sim.partExists(number index)<br />
Returns true if a particle exists at a given index.<br />
<br />
=== simulation.partID ===<br />
number sim.partID(number x, number y)<br />
Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.<br />
<br />
Example (though this is probably best done with sim.neighbours):<br />
<syntaxhighlight lang="lua"><br />
for fx = -1, 1, 1 do<br />
for fy = -1, 1, 1 do<br />
local i = sim.partID(x + fx, y + fy)<br />
if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then<br />
sim.partProperty(index, sim.FIELD_TEMP, 9999)<br />
end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.partKill ===<br />
nil sim.partKill(number index)<br />
nil sim.partKill(number x, number y)<br />
Reliably delete a particle at a specified index or location, this method avoids the side effects created by changing the type to 0/DEFAULT_PT_NONE with the "partProperty" method<br />
<br />
=== simulation.partNeighbors ===<br />
table sim.partNeighbours(number x, number y, number radius, [number type])<br />
Returns an array of indices of particles that neighbour the given coordinates and match the given type (if it is specified). The resulting array does not contain the particle at the specified position.<br />
<br />
=== simulation.partNeighbours ===<br />
Same as sim.partNeighbors()<br />
<br />
=== simulation.partPosition ===<br />
number x, number y sim.partPosition(number index)<br />
Get the location of the particle at the specified index <br />
<br />
=== simulation.partProperty ===<br />
nil sim.partProperty(number index, object field, object value)<br />
Set the property value on a particle specified by index<br />
<br />
object sim.partProperty(number index, object field)<br />
Get the property value on a particle specified by the index<br />
<br />
The "field" may be a field name or field ID, see FIELD constants below for valid fields.<br />
<br />
=== simulation.parts ===<br />
function sim.parts()<br />
Returns an iterator over particle indexes that can be used in lua for loops<br />
<br />
=== simulation.paused ===<br />
flag = sim.paused()<br />
sim.paused(flag)<br />
* <code>flag</code>: Boolean flag that says whether or not the sim is paused.<br />
<br />
Checks whether or not the simulation is paused. Processing may also continue if the 'f' framerender shortcut is used, which can last for long periods of time. [[#simulation.framerender|sim.framerender]] should be used to check for that<br />
<br />
=== simulation.pmap ===<br />
number sim.pmap(number x, number y)<br />
Get the index of the particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.partID, but excludes energy particles (such as PHOT, NEUT, ELEC).<br />
<br />
=== simulation.photons ===<br />
number sim.photons(number x, number y)<br />
Get the index of the energy particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.pmap<br />
<br />
=== simulation.pressure ===<br />
number sim.pressure(number x, number y)<br />
Returns a value on the pressure map.<br />
<br />
nil sim.pressure(number x, number y, [number width, number height], number pressure)<br />
Sets values on the pressure map.<br />
<br />
=== simulation.prettyPowders ===<br />
number sim.prettyPowders()<br />
nil sim.prettyPowders(mode)<br />
Sets whether the "pretty powders mode" (powders, such as SAND or BCOL, will be assigned random deco values) is on or off. When called with no arguments, returns a value determining whether it is on or off.<br />
<br />
=== simulation.randomSeed ===<br />
number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper sim.randomSeed()<br />
nil sim.randomSeed(number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper)<br />
<br />
'''Upcoming in version 98.0'''<br />
<br />
Retrieve or set the seed used for the Simulation RNG. This RNG is used by TPT to generate random numbers during sim contexts. The renderer RNG and interface RNG are unaffected.<br />
<br />
Because seeds are 64 bits, they are fetched/set in two sets of 32 bits integers.<br />
<br />
=== simulation.reloadSave ===<br />
nil sim.reloadSave()<br />
Reloading save.<br />
<br />
=== simulation.removeCustomGol ===<br />
boolean sim.removeCustomGol(string name)<br />
Removes all custom game of life types with the specified name. Returns true if any were removed.<br />
<br />
=== simulation.resetGravityField ===<br />
sim.resetGravityField()<br />
Resets the gravity field to 0. While this will temporarily stop all Newtonian Gravity output, any changes will regenerate the gravity map based on the gravity sources in the sim.<br />
<br />
=== simulation.resetPressure ===<br />
sim.resetPressure()<br />
Resets the pressure map to no pressure.<br />
<br />
=== simulation.resetSpark ===<br />
sim.resetSpark()<br />
Same effect as the ctrl+= shortcut. Removes all sparks from the simulation and resets them to .life = 0. SPRK with invalid ctypes are deleted. Also resets all wifi cooldowns.<br />
<br />
=== simulation.resetTemp ===<br />
sim.resetTemp()<br />
Resets the temperature of all particles to their spawn temperature.<br />
<br />
=== simulation.resetVelocity ===<br />
sim.resetVelocity()<br />
Resets the air velocity map to 0. This map controls the flow of air. Resetting this will have some effect on particles, but won't stop them in their tracks.<br />
<br />
=== simulation.replaceModeFlags ===<br />
number sim.replaceModeFlags()<br />
Returns the current replace mode flags.<br />
nil sim.replaceModeFlags(number flags)<br />
Sets the replace mode flags.<br />
<br />
If the first bit of that number is set (flags = 1), replace mode is enabled.<br />
<br />
If the second bit is set (flags = 2), specific delete is enabled.<br />
<br />
=== simulation.saveStamp ===<br />
string sim.saveStamp([number x, number y, number width, number height, [boolean includePressure]])<br />
Creates a stamp of the specified coordinates. Coordinates default to entire simulation.<br />
Returns the stamp id created.<br />
<br />
=== simulation.signs ===<br />
table simulation.signs<br />
A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.<br />
<br />
==== Constants ====<br />
* <code>sim.signs.MAX_SIGNS</code>: The maximum number of signs that can exist at once<br />
* <code>sim.signs.JUSTMODE_LEFT</code>: Left justification<br />
* <code>sim.signs.JUSTMODE_MIDDLE</code>: Middle (default) justification<br />
* <code>sim.signs.JUSTMODE_RIGHT</code>: Right justification<br />
* <code>sim.signs.JUSTMODE_NONE</code>: No justification, sign won't have any "tail"<br />
* <code>sim.signs.NUM_JUSTMODES</code>: The number of justification modes<br />
<br />
==== simulation.signs[n] ====<br />
table simulation.signs[n]<br />
A table which always contains the id property. May also contain text, x, y and justification. These properties can be directly modified to change a sign.<br />
A justification of 0 means left, 1 means right, 2 means middle and 3 means none.<br />
The text property cannot be larger than 45 in length.<br />
<br />
==== simulation.signs.delete ====<br />
nil simulation.signs.delete(number signID)<br />
Deletes the sign at the specified sign id.<br />
<br />
==== simulation.signs.new ====<br />
number simulation.signs.new([string text, number x, number y, number justification])<br />
Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).<br />
<br />
=== simulation.takeSnapshot ===<br />
nil sim.takeSnapshot()<br />
Takes a undo snapshot, for use with ctrl + z<br />
<br />
=== simulation.temperatureScale ===<br />
number sim.temperatureScale()<br />
Returns the current temperature scale. 0 = Kelvin, 1 = Celsuis, 2 = Fahrenheit<br />
<br />
nil sim.temperatureScale(number newTemperatureScale)<br />
Sets the current temperature scale. 0 = Kelvin, 1 = Celsuis, 2 = Fahrenheit. Other options are invalid and will throw an error.<br />
<br />
=== simulation.toolBox ===<br />
type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) in a rectangular area.<br />
<br />
=== simulation.toolBrush ===<br />
number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) on the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.toolLine ===<br />
type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) as if a line was drawn across the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.updateUpTo ===<br />
nil sim.updateUpTo([number upTo])<br />
Updates the simulation, but only up to the specified particle ID. Works as if shift+f is pressed while in particle debug mode (tpt.setdebug(0x8)). If no arguments are passed in, updates to the end of the frame.<br />
<br />
=== simulation.velocityX ===<br />
number sim.velocityX(number x, number y)<br />
Returns an X value on the velocity map.<br />
<br />
nil sim.velocityX(number x, number y, [number width, number height], number value)<br />
Sets X values on the velocity map.<br />
<br />
=== simulation.velocityY ===<br />
number sim.velocityY(number x, number y)<br />
Returns an Y value on the velocity map.<br />
<br />
nil sim.velocityY(number x, number y, [number width, number height], number value)<br />
Sets Y values on the velocity map.<br />
<br />
=== simulation.wallMap ===<br />
Interface with the wall map, which is a [[Lua_API:Simulation#Constants_2|CELL-sized]] map that specifies which walls are at what position.<br />
<br />
wallType sim.wallMap(x, y)<br />
sim.wallMap(x, y, wallType)<br />
sim.wallMap(x, y, w, h, wallType)<br />
* <code>wallType</code>: Wall type to set, wall type will be one of the constants in [[Lua_API:Simulation#Walls|sim.walls]]<br />
* <code>x</code>: x position of the cell<br />
* <code>y</code>: y position of the cell<br />
* <code>w</code>: width (cell count) of the area to set<br />
* <code>h</code>: height (cell count) of the area to set<br />
<br />
=== simulation.waterEqualisation ===<br />
number sim.waterEqualisation()<br />
Returns the current Water equalisation setting.<br />
<br />
nil sim.waterEqualisation(number setting)<br />
Set the Water equalisation setting to setting.<br />
<br />
=== simulation.waterEqualization ===<br />
Same as sim.waterEqualisation()<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with simulation.<constant name here><br />
<br />
; XRES<br />
X Resolution of the sim<br />
; YRES<br />
Y Resolution of the sim<br />
; CELL<br />
Size of a wall / air simulation block<br />
; XCELLS<br />
The number of cells in the X direction<br />
; YCELLS<br />
The number of cells in the Y direction<br />
; NCELL<br />
The total number of cells in the simulation<br />
; NT<br />
No transition, used in *Transition [https://powdertoy.co.uk/Wiki/W/Element_Properties.html properties]<br />
; ST<br />
Special transition, used in *Transition properties, but there is no way to set a special transition handler from Lua<br />
; ITH<br />
Impossible temperature high, used along with NT to disable transitions<br />
; ITL<br />
Impossible temperature low, used along with NT to disable transitions<br />
; IPH<br />
Impossible pressure high, used along with NT to disable transitions<br />
; IPL<br />
Impossible pressure low, used along with NT to disable transitions<br />
; PT_NUM<br />
Maximum number of element IDs. Does not reflect the current number of elements, only the maximum that can be enabled at one time.<br />
; NUM_PARTS<br />
Not actually a constant, this is updated every frame to reflect the current number of particles in the sim. Deprecated by sim.partCount (TODO document that and remove this)<br />
; MAX_PARTS<br />
Maximum number of particles that can exist at once<br />
; R_TEMP<br />
Room temperature (22C), the default temperature for many elements<br />
; MAX_TEMP<br />
Maximum allowable temperature of the sim, in Kelvin<br />
; MIN_TEMP<br />
Maximum allowable temperature of the sim, in Kelvin<br />
; MAX_PRESSURE<br />
Minimum allowable pressure of the sim<br />
; MIN_PRESSURE<br />
Maximum allowable temperature of the sim<br />
; MAX_VELOCITY<br />
Particle velocity cap<br />
; ISTP<br />
Movement code step value. Particles scan their trajectory and only check for blockers each step.<br />
; CFDS<br />
Air sim related<br />
; PMAPBITS<br />
Number of bits used in pmap to store element type. This controls the element cap, which is 2^PMAPBITS<br />
; PMAPMASK<br />
Mask used to assign type to pmap. ((1<<PMAPBITS)-1)<br />
<br />
=== DECO ===<br />
Used in deco drawing functions<br />
; DECO_DRAW<br />
; DECO_CLEAR<br />
; DECO_ADD<br />
; DECO_SUBTRACT<br />
; DECO_MULTIPLY<br />
; DECO_DIVIDE<br />
; DECO_SMUDGE<br />
<br />
=== TOOL ===<br />
Used in tool drawing functions<br />
; TOOL_HEAT<br />
; TOOL_COOL<br />
; TOOL_VAC<br />
; TOOL_AIR<br />
; TOOL_PGRV<br />
; TOOL_NGRV<br />
; TOOL_MIX<br />
; TOOL_CYCL<br />
; TOOL_WIND<br />
<br />
=== FIELD ===<br />
Used in sim.partProperty<br />
; FIELD_TYPE<br />
; FIELD_LIFE<br />
; FIELD_CTYPE<br />
; FIELD_X<br />
; FIELD_Y<br />
; FIELD_VX<br />
; FIELD_VY<br />
; FIELD_TEMP<br />
; FIELD_FLAGS<br />
; FIELD_TMP<br />
; FIELD_TMP2<br />
; FIELD_TMP3<br />
; FIELD_TMP4<br />
; FIELD_DCOLOUR<br />
<br />
=== BRUSH ===<br />
Used in certain brush drawing functions<br />
; BRUSH_CIRCLE<br />
; BRUSH_SQUARE<br />
; BRUSH_TRI<br />
; NUM_DEFAULTBRUSHES<br />
Number of default brushes<br />
; BRUSH_NUM<br />
Number of total brushes, including any custom brushes<br />
<br />
=== EDGE ===<br />
Used in sim.edgeMode<br />
; EDGE_VOID<br />
; EDGE_SOLID<br />
; EDGE_LOOP<br />
; NUM_EDGEMODES<br />
<br />
=== AIR ===<br />
Used in sim.airMode<br />
; AIR_ON<br />
; AIR_PRESSURE_OFF<br />
; AIR_VELOCITY_OFF<br />
; AIR_OFF<br />
; AIR_NO_UPDATE<br />
; NUM_AIRMODES<br />
<br />
=== GRAV ===<br />
Used in sim.gravityMode<br />
; GRAV_VERTICAL<br />
; GRAV_OFF<br />
; GRAV_RADIAL<br />
; GRAV_CUSTOM<br />
; NUM_GRAV_MODES<br />
<br />
=== Walls ===<br />
; NUM_WALLS<br />
; walls<br />
sim.walls is a table containing a mapping of wall IDs to wall identifiers, and wall identifiers to wall IDs. This may come in handy for working with ui.activeTool, which uses identifiers.<br />
<br />
=== FLAG ===<br />
Used in .flags property<br />
; FLAG_MOVABLE<br />
; FLAG_PHOTDECO<br />
; FLAG_SKIPMOVE<br />
; FLAG_STAGNANT<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Elements:Liquids&diff=8752Elements:Liquids2023-01-18T18:18:33Z<p>Maticzpl: Fix previous edit</p>
<hr />
<div>{{Languages|Elements:Liquids}}<br />
Fluids of different densities, all have different properties. Different liquids may freeze, evaporate, melt, combust and/or conduct.<br />
<br />
Where present, P denotes pressure, and T denotes temperature (known as 'temp' in the HUD). For the temperature units, C denotes degrees Celsius and K denotes Kelvin; this is because the HUD only displays temperature in Celsius, while the console only accepts Kelvin units.<br />
<br />
=== [[File:WATR.png|WATR]] [[Element:WATR|Water]] ===<br />
'''Description:'''<br />
"Conducts electricity, freezes, and extinguishes fires."<br />
<br />
'''Spawn temp:''' +22.00 ''C'' ; 295.15 ''K''.<br />
<br />
Hex triplet colour: #2030d0.<br />
<br />
<br />
WATR evaporates to [[Element:WTRV|WTRV]] at any T ≥ [+99.86 + 2P] ''C'' \ [373.01 + 2P] ''K'' .<br />
<br />
WATR freezes to [[Element:ICE|ICE]] or [[Element:SNOW|SNOW]] (of ctype WATR) if at any T ≤ -0.01 ''C'' \ 273.14 ''K'', into ICE if the P is ≤ +0.79, or SNOW if the P is ≥ +0.80.<br />
<br />
Is a product of [[Element:DSTW|DSTW]] and most powders and liquids, with a slow but existent capacity to conduct [[Element:SPRK|SPRK]].<br />
<br />
Ignites [[Element:RBDM|RBDM]] and [[Element:LRBD|LRBD]] if in contact with them, but also extinguishes [[Element:FIRE|FIRE]].<br />
<br />
WATR converts DSTW to WATR upon contact. Similarly, WATR turns to [[Element:SLTW|SLTW]] if in contact with it.<br />
<br />
If irradiated with [[Element:NEUT|NEUT]], WATR transforms to DSTW.<br />
<br />
=== [[File:OIL.png|OIL]] [[Element:OIL|Oil]] ===<br />
'''Description:'''<br />
"Flammable, turns into GAS at low pressure or high temperature. Can be formed with NEUT and NITR."<br />
<br />
'''Spawn temp:''' +22.00 ''C'' / 295.15 ''K''.<br />
<br />
Hex triplet colour: #404010.<br />
<br />
<br />
OIL evaporates to [[Element:GAS|GAS]] at any T ≥ [+59.86 + 2P] ''C'' \ [333.01 + 2P] ''K'', if at any P ≤ +5.49. (Thus, if at any P ≤ -166.51, OIL of any T spontaneously evaporates to GAS.) This transformation produces +0.50 P at the location of each particle. <br />
<br />
OIL spontaneously produces pressure at any T ≥ [+59.86 + 2P] ''C'' \ [333.01 + 2P] ''K'', if at any P ≥ +5.50.<br />
The magnitude of pressure produced per particle is +0.50 for every whole T degree ≥ [+59.86 + 2P] ''C'' \ [333.01 + 2P] ''K''. For example, if the T is 4 ''C'' greater than [+59.86 + 2P] (if 4 ''K'' > [333.01 + 2P]), then the P produced is 4 ⨯ +0.50 : +2.00.<br />
<br />
If OIL is both at any P ≥ +5.50 and any T ≥ +571.86 ''C'' \ 845.01 ''K'', it spontaneously emits the maximum P of +256.00 per particle.<br />
<br />
If the pressure value emitted by spontaneously pressurised OIL is ≥ 0.50 below the equation level (due to a lower surrounding pressure), then the pressure value converges up to the equation level. This process repeats if the surrounding pressure is still below the OIL's. This is observed with the pressure value at the OIL oscillating quickly.<br />
<br />
If irradiated with [[Element:NEUT|NEUT]], [[Element:NITR|NITR]] transforms to OIL.<br />
<br />
=== [[File:LAVA.png|LAVA]] [[Element:LAVA|Lava]] ===<br />
'''Description:'''<br />
"Molten lava. Ignites Flammable Materials. Generated when metals and other materials melt, solidifies when cold."<br />
<br />
'''Spawn temp:''' +1522.00 ''C'' \ 1795.15 ''K''.<br />
<br />
Hex triplet colour: variable (#ff641a at T = +699.85 ''C'' \ 973.00 ''K'').<br />
<br />
<br />
LAVA without a ctype solidifies to [[Element:STNE|STNE]] at any T ≤ +699.84 ''C'' \ T ≤ 972.99 ''K''.<br />
<br />
If LAVA's ctype is changed (e.g. through the console) in certain ways, many bizarre forms of LAVA can result, such as molten [[Element:STKM|STKM]], molten [[Element:WATR|WATR]], or molten [[Element:FIRE|FIRE]]. These phenomena are glitches.<br />
<br />
The following materials become molten at high enough temperatures:<br />
<br />
* All electronics except for [[Element:BTRY|BTRY]], [[Element:INST|INST]], and [[Element:WWLD|WWLD]].<br />
<br />
* All powders except for [[Element:SNOW|SNOW]], [[Element:BREL|BREL]], [[Element:ANAR|ANAR]], [[Element:GRAV|GRAV]], [[Element:FRZZ|FRZZ]], [[Element:BCOL|BCOL]], [[Element:FSEP|FSEP]], [[Element:YEST|YEST]], and [[Element:DUST|DUST]].<br />
<br />
* The solids [[Element:BMTL|BMTL]] and [[Element:GLAS|GLAS]].<br />
<br />
=== [[File:ACID.png|ACID]] [[Element:ACID|Acid]] ===<br />
'''Description:'''<br />
"Dissolves almost everything."<br />
<br />
Spawn temp: +22.00 C<br />
<br />
Color: pink / purple<br />
<br />
Dissolves many things. Some notable exceptions are:<br />
LAVA and explosives (it will just ignite),<br />
elements in "special" and any other special element,<br />
GLAS (glass),<br />
QRTZ (quartz) and PQRT (broken quartz),<br />
DMND (diamond),<br />
and GOLD.<br />
<br />
ACID is also flammable, it burns when exposed to FIRE, SPRK (electricity), or LAVA. It generates heat when dissolving things. It turns into IZOS when exposed to NEUT.<br />
<br />
Has extra effect on TTAN (titanium).<br />
<br />
=== [[File:DSTW.png|DSTW]] [[Element:DSTW|Distilled Water]] ===<br />
'''Description:'''<br />
"Distilled water, does not conduct electricity."<br />
<br />
Spawn temp: +22.00 C<br />
<br />
Hex triplet colour: #1020c0.<br />
<br />
Product of cooling WTRV (water vapor), or introducing water to NEUT (neutrons). Does not conduct electricity. PLNT will not grow from this. Does not cause IRON to rust, undergoes electrolysis (seperates into HYGN (hydrogen) and OXYG (oxygen)) when in contact with sparked IRON.<br />
<br />
DSTW has the same boiling and freezing points as water, see WATR for more information.<br />
<br />
=== [[File:SLTW.png|SLTW]] [[Element:SLTW|Salt Water]] ===<br />
'''Description:'''<br />
"Saltwater, conducts electricity, difficult to freeze."<br />
<br />
Spawn temp: +22.00 C \ 295.15 K<br />
<br />
Product of [[Element:WATR|WATR]] and [[Element:SALT|SALT]]. <br />
<br />
SLTW evaporates to [[Element:WTRV|WTRV]] at a temp, T, and pressure, P, ≥ than (+109.86 C \ 383.01 K) + 2P. Evaporating SLTW may also produce some SALT alongside the WTRV.<br />
<br />
SLTW freezes into [[Element:ICE|ICE]] of ctype SLTW if the temp is ≤ -20.01 C \ 253.14 K, and if the pressure is < than +0.80.<br />
If the pressure is ≥ than +0.80, SLTW instead freezes into [[Element:SNOW|SNOW]] of ctype SLTW.<br />
<br />
SLTW also destroys [[Element:PLNT|PLNT]] with 1/40 chance each frame and makes [[Element:QRTZ|QRTZ]] grow slowly by replacing the SLTW. It also has a chance to turn salt into SLTW (1/2000) chance each frame.<br />
<br />
=== [[File:MWAX.png|MWAX]] [[Element:MWAX|Molten Wax]] ===<br />
'''Description:'''<br />
"Liquid Wax. Hardens into WAX at 45 degrees."<br />
<br />
Spawn temp: +50.00 C \ 323.15 K<br />
<br />
Molten wax. Burns to [[Element:FIRE|FIRE]] if in contact with other FIRE; or if at a temp, T, ≥ +399.85 C \ 673.00 K. Solidifies to [[Element:WAX|WAX]] at a temp, T, ≤ +44.84 C \ 317.99 K.<br />
<br />
=== [[File:LN2.png|LN2]] [[Element:LN2|Liquid Nitrogen]] ===<br />
'''Description:'''<br />
"Liquid Nitrogen. Very cold, disappears whenever it touches anything warmer."<br />
<br />
Spawn temp: -203.00 C \ 70.15 K<br />
<br />
Dissipates and generates pressure when transferring heat to a particle warmer than itself. LN2 and [[Element:NICE|NICE]] (nitrogen ice) are often used as cooling mechanisms, as LN2 disappears at any temp, T, ≥ -196.15 C \ 77.00 K. LN2 can stay liquid at over 300 C if it is under sufficient pressure.<br />
<br />
=== [[File:DESL.png|DESL]] [[Element:DESL|Diesel]] ===<br />
'''Description:'''<br />
"Liquid diesel. Explodes under high pressure and temperatures."<br />
<br />
Spawn temp: +22.00 C \ 295.15 K<br />
<br />
Flammable liquid, lighter than [[Element:WATR|WATR]]. DESL has the same characteristics as [[Element:NITR|NITR]] but ignites instead of exploding. Ignites to [[Element:FIRE|FIRE]] at a temp, T, ≥ +60.85 C \ 335.00 K, or at a pressure, P, ≥ +5.00. DESL will burn steadily (slower than OIL) if a small amount of [[Element:FIRE|FIRE]] touches it. Its burning also emits lot of [[Element:SMKE|SMKE]].<br />
<br />
=== [[File:LOXY.png|LOXY]] [[Element:LOXY|Liquid Oxygen]] ===<br />
'''Description:'''<br />
"Liquid Oxygen. Very cold. Reacts with fire."<br />
<br />
Spawn temp: -193.15 C \ 80.00 K<br />
<br />
Liquid form of [[Element:OXYG|OXYG]] (oxygen). Transforms to OXYG at a temp, T, ≥ -183.05 C \ ≥ 90.10 K.<br />
Ignites quickly into [[Element:FIRE|FIRE]] itself when in contact with other FIRE.<br />
<br />
=== [[File:GLOW.png|GLOW]] [[Element:GLOW|Glow]] ===<br />
'''Description:'''<br />
"Glow, Glows under pressure." <br />
<br />
Spawn temp: +42.00 C \ 315.15 K<br />
<br />
Glows when exposed to high pressure. Changes color with temperature. When [[Element:PHOT|PHOT]] passes through GLOW, PHOT will receive the same color. However, with the temperature of PHOT being about +900 C, it's fairly tough to keep GLOW at the proper temp. Glow also multiplies the number of PHOTs (photons) that come into contact with it.<br />
<br />
GLOW changes color under many different situations:<br />
Gray >> nothing<br><br />
Blue >> moving (like [METL])<br><br />
Luminous red >> high temp<br><br />
Dark green/blue >> low temp<br><br />
Luminous green >> high pressure<br><br />
Dark purple >> low pressure<br><br />
Yellow >> high temp and high pressure<br><br />
Luminous pink >> high temp and low pressure<br><br />
Slightly darker luminous green >> low temp and high pressure<br><br />
Dark blue >> low temp and low pressure<br />
<br />
Makes deuterium oxide ([[Element:DEUT|DEUT]]) when mixed to WATR.<br />
<br />
=== [[File:BUBW.png|BUBW]] [[Element:BUBW|Carbonated Water]] ===<br />
'''Description:'''<br />
"Carbonated water. Slowly releases CO2."<br />
<br />
Spawn temp: +20.00 C \ 293.15 K<br />
<br />
Releases [[Element:CO2|CO2]] when in contact with anything. The release of CO2 creates pressure, which then causes a large 'explosion' of BUBW. BUBW also spontaneously decomposes when left by itself. <br />
<br />
BUBW has the same boiling and freezing points as water, see WATR for more information. ICE and SNOW formed from BUBW is of ctype BUBW.<br />
<br />
=== [[File:BIZR.png|BIZR]] [[Element:BIZR|Bizarre]] ===<br />
'''Description:'''<br />
"Bizarre, contradicts the normal state changes. Paints other elements with it's deco color."<br />
<br />
Spawn temp: +22.00 C \ 295.15 K<br />
<br />
Contradicting 'normal' physics, this element solidifies at around +130 C, and evaporates around -170 C. When colored with [[deco| Decoration layer colors]], it will transfer it's color to other elements it touches. Bizarre will transform [[Element:PHOT|PHOT]] into [[Element:ELEC|ELEC]].<br />
<br />
=== [[File:PSTE.png|PSTE]] [[Element:PSTE|Paste]] ===<br />
'''Description:'''<br />
"Colloid, hardens under pressure."<br />
<br />
Spawn temp: +20.00 C \ 293.15 K<br />
<br />
Turns into solid [[Element:PSTS|PSTS]] at about +0.30 pressure. Becomes [[Element:BRCK|BRCK]] at around +480 C.<br />
<br />
=== [[File:GEL.png|GEL]] [[Element:GEL|Gel]] ===<br />
'''Description:'''<br />
"Gel. A liquid with variable viscosity and heat conductivity."<br />
<br />
Spawn temp: +20.00 C \ 293.15 K<br />
<br />
Added in 75.0, GEL can absorb WATR. While absorbing WATR, it becomes darker and less viscous and its heat conductivity increases. If in contact with SPNG (sponge), water passes from GEL to SPNG. When GEL touches [[Element:PSTE|PSTE]] it will drain the water from the PSTE and the PSTE becomes [[Element:CLST|CLST]].<br />
If a gas touches the surface, then it will be randomly pulled across it and deposited somewhere else, useful in liquid/gas separation. Also appears to "stick" to gases.<br />
<br />
=== [[File:SOAP.png|SOAP]] [[Element:SOAP|Soap]] ===<br />
'''Description:'''<br />
"Soap. Creates bubbles, Washes off deco color, and cures virus."<br />
<br />
Spawn temp: +20.00 C \ 293.15 K<br />
<br />
Creates bubbles at about +0.50 pressure, the bubbles have the same color as the soap. Removes decoration. Will remove virus, and turns virus back into what it was originally.<br />
<br />
Is quite dense, but adheres to OIL in a binary interaction. Because of this, SOAP put into a mixture of OIL and a denser fluid will adhere to the OIL instead of completely going to the bottom.<br />
<br />
Bubbles will freeze at lower temperatures.<br />
<br />
=== [[File:MERC.png|MERC]] [[Element:MERC|Mercury]] ===<br />
'''Description:'''<br />
"Mercury. Volume changes with temperature, conductive."<br />
<br />
Spawn temp: +22.00 C \ 295.15 K<br />
<br />
Mercury is a liquid that conducts electricity. When heated up, this liquid expands, and vice versa. Does not kill STKM. One of the heaviest liquids, it can even sink below some lighter elements like DUST. It is almost indestructible since it can't catch burn or vaporize., but certain elements such as BOMB will cause damage. Mercury set to very high temperature (like ≥7000ºC) can make it very annoying to destroy, as it can expand faster than it is being destroyed.<br />
<br />
=== [[File:VIRS.png|VIRS]] [[Element:VIRS|Virus]] ===<br />
'''Description:'''<br />
"Virus. Turns everything it touches into virus."<br />
<br />
Spawn temp: +72.00 C \ 344.15 K<br />
<br />
Will turn almost every element into more VIRS. VIRS has three states which depend on temperature only: solid, VRSS, liquid VIRS and gaseous VRSG. VIRS is highly flammable, but only to PLSM, to prevent random burning as FIRE or LAVA gets infected. The cure for VIRS is SOAP, this will make all VIRS turn back into what it was. VIRS decays to nothing after a while, but PROT (protons) stop this process from occuring if they pass through the VIRS in any state.<br />
<br />
Elements that are not 'infected' by VIRS are the energy-type elements (GRVT (gravitons), PROT, ELEC (electrons), PHOT (photons) and NEUT (neutrons)), SING (singularity), ATMR (antimatter), and DMND (diamond).<br />
<br />
<br />
<br />
[[Category:Elements]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Platform&diff=8745Lua API:Platform2023-01-04T19:54:19Z<p>Maticzpl: Added platform page</p>
<hr />
<div>== Methods ==<br />
<br />
=== platform.platform ===<br />
string plat.platform()<br />
Returns the platform that the game's executable is compiled for.<br />
<br />
Possible return values:<br />
* WIN64<br />
* WIN32<br />
* LIN64<br />
* LIN32<br />
* MACOSARM<br />
* MACOSX<br />
* UNKNOWN<br />
<br />
=== platform.ident ===<br />
string plat.ident()<br />
Returns the target triplet for the game's executable containing the CPU family, the OS name and C environment separated by dashes <br />
<br />
Possible return values:<br />
* For CPU family: [https://mesonbuild.com/Reference-tables.html#cpu-families]<br />
* For OS name: [https://mesonbuild.com/Reference-tables.html#operating-system-names]<br />
* For C environment:<br />
** msvc <br />
** mingw <br />
** macos <br />
** bionic <br />
** gnu<br />
<br />
<br />
=== platform.build ===<br />
string plat.build()<br />
'''THIS FUNCTION IS DEPRECATED''' <br />
<br />
Possible return values:<br />
* SSE3 <br />
* SSE2 <br />
* SSE <br />
* NO<br />
<br />
<br />
=== platform.releaseType ===<br />
string plat.releaseType()<br />
Returns the game's executable release type. <br />
<br />
Possible return values:<br />
* R ''(Release)''<br />
* B ''(Beta)''<br />
* S ''(Snapshot)''<br />
<br />
=== platform.exeName ===<br />
string plat.exeName()<br />
Returns the path to the game's executable.<br />
<br />
=== platform.restart ===<br />
nil plat.restart()<br />
Restarts the game<br />
<br />
=== platform.openLink ===<br />
nil plat.openLink(string URI)<br />
Opens the provided link in the default system browser.<br />
<br />
=== platform.clipboardCopy ===<br />
string plat.clipboardCopy()<br />
"Copies" or returns text from clipboard<br />
<br />
=== platform.clipboardPaste ===<br />
nil plat.clipboardPaste(string text)<br />
"Pastes" text to clipboard</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Simulation&diff=8662Lua API:Simulation2022-11-13T15:03:17Z<p>Maticzpl: Fix wrong argument stuff in sim.ambientHeat, velocityX, velocityY and gravMap >_></p>
<hr />
<div>The Simulation API allows for modifying the state and properties of particles, air and gravity<br />
<br />
== Methods ==<br />
<br />
=== simulation.addCustomGol ===<br />
nil sim.addCustomGol(string rule, string name, number color1, number color2)<br />
Adds a custom game of life type with the specified rule, name, and colors. Rule strings use B#/S#/# notation ([https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Variations more detail]). Colors are used when fading between multiple states. Names and rules cannot be duplicates.<br />
<br />
nil sim.addCustomGol(number rule, string name, number color1, number color2)<br />
Same as above, but takes a binary representation of the rule instead of a string. Bits 0-8 list stay values (starting at 0), bits 9-16 list begin values (starting at 1), and bits 17-20 are the number of states (decimal value added to 2). This is also how GOL rules are stored as ctypes.<br />
<br />
=== simulation.adjustCoords ===<br />
number, number sim.adjustCoords(number x, number y)<br />
Actually this is more of a UI method than a simulation method. Given a mouse position x, y in the window, this function returns the corresponding coordinates in the simulation (taking into account the visibility and position of the zoom window, if applicable). <br />
<br />
=== simulation.airMode ===<br />
number sim.airMode()<br />
Returns the current Air Simulation Mode.<br />
<br />
nil sim.airMode(number mode)<br />
Sets the Air Simulation Mode to mode.<br />
<br />
Mode numbers are as follows (not currently available as named constants):<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal<br />
|-<br />
|1<br />
|Pressure off<br />
|-<br />
|2<br />
|Velocity off<br />
|-<br />
|3<br />
|Velocity and pressure off<br />
|-<br />
|4<br />
|No update<br />
|}<br />
<br />
=== simulation.ambientAirTemp ===<br />
number sim.ambientAirTemp()<br />
Returns the current ambient temperature. When ambient heat mode is turned on, the air at the edges of the screen will remain at this temperature. <br />
<br />
nil sim.ambientAirTemp(number temp)<br />
Sets the ambient temperature. The temperature is measured in Kelvin. <br />
<br />
=== simulation.ambientHeat ===<br />
number sim.ambientHeat(number x, number y)<br />
Returns a value on the ambient heat map (the temperature of the air at that point). <br />
<br />
nil sim.ambientHeat(number x, number y, [number width, number height], number temp)<br />
Sets values on the ambient heat map. <br />
<br />
=== simulation.brush ===<br />
function sim.brush(number x, number y, [number brushWidth, number brushHeight], [number brushID])<br />
Returns an iterator over positions inside the specified brush.<br />
<br />
If width, height or ID is not provided, will use values of the current brush selected by user.<br />
<br />
Example:<br />
for x, y in sim.brush(300, 200, 100, 50, 0) do<br />
sim.partCreate(-1, x, y, elem.DEFAULT_PT_DUST)<br />
end<br />
<br />
=== simulation.can_move ===<br />
simulation.can_move(number movingElementID, number obstacleElementID, number method)<br />
Decides what a particle does when it hits another particle while moving. Method is one of the following:<br />
* 0: bounce off the obstacle<br />
* 1: swap places with the obstacle<br />
* 2: move over the obstacle<br />
<br />
number simulation.can_move(number movingElementID, number obstacleElementID)<br />
Returns what a particle does when it hits another particle while moving, a method like above.<br />
<br />
=== simulation.clearRect ===<br />
nil sim.clearRect(number x, number y, number width, number height)<br />
Clears all particles in a rectangle starting at x, y down and to the right width and height pixels respectively.<br />
<br />
=== simulation.clearSim ===<br />
nil sim.clearSim()<br />
Clears everything in the simulation.<br />
<br />
=== simulation.createBox ===<br />
nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])<br />
Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createLine ===<br />
nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])<br />
Creates a line of of either the user's currently selected type or the type specified at the specified coordinates.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createParts ===<br />
number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])<br />
Does something.<br />
<br />
=== simulation.createWallBox ===<br />
nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])<br />
Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWallLine ===<br />
nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])<br />
Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWalls ===<br />
number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])<br />
Does something<br />
<br />
=== simulation.decoBox ===<br />
nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])<br />
Changes the decoration color of all particles in the specified coordinates.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoBrush ===<br />
nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Does something<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoColor ===<br />
number sim.decoColor()<br />
Returns the currently selected decoration color.<br />
<br />
nil sim.decoColor(number color)<br />
Sets the selected decoration color to color.<br />
color is in the format 0xAARRGGBB<br />
<br />
nil sim.decoColor(number r, number g, number b, [number a])<br />
Sets the selected decoration color to r,g,b,a<br />
<br />
=== simulation.decoColour ===<br />
Same as sim.decoColor()<br />
<br />
=== simulation.decoLine ===<br />
nil sim.decoLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Changes the decoration color of all particles in the line specified.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.deleteStamp ===<br />
type sim.deleteStamp(string name)<br />
Deleting a stamp identified by filename or ID.<br />
<br />
=== simulation.edgeMode ===<br />
number sim.edgeMode()<br />
Returns the current Edge Mode<br />
<br />
nil sim.edgeMode(number mode)<br />
Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation. <br />
<br />
=== simulation.elementCount ===<br />
number sim.elementCount(number type)<br />
Returns the number of particles of the specified type in the simulation.<br />
<br />
=== simulation.floodDeco ===<br />
nil sim.floodDeco(number x, number y, number r, number g, number b, number a)<br />
Flood fills the color at position x, y with another color. Note: Color at position includes console overlay.<br />
<br />
=== simulation.floodParts ===<br />
number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])<br />
Flood fills either the user's currently selected type or the type specified at the coordinates given.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.floodWalls ===<br />
number sim.floodWalls(number x, number y, [number walltype], [number bm?])<br />
Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.framerender ===<br />
number sim.framerender()<br />
sim.framerender(number frames)<br />
Advances the simulation the given number of frames, even when paused. If called with no arguments, returns the number of frames currently to be rendered. Usually is 0.<br />
<br />
=== simulation.getSaveID ===<br />
number, number sim.getSaveID()<br />
Returns the save ID and the history offset of the currently loaded save or nil if the simulation is not a downloaded save. The history offset can be used with loadSave.<br />
<br />
=== simulation.gravMap ===<br />
number sim.gravMap(number x, number y)<br />
nil sim.gravMap(number x, number y, [number width, number height,] number value)<br />
Returns the newtonian gravity at the given coordinates in the simulation. If given a value, will set the newtonian gravity at those coordinates. Width and height refer to the rectangle of affected cells, starting with the coords. If not given, they will default to 1,1.<br />
<br />
=== simulation.gravityGrid ===<br />
number sim.gravityGrid()<br />
Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.<br />
<br />
nil sim.gravityGrid(number mode)<br />
Sets the setting for drawing the gravity grid to mode.<br />
<br />
=== simulation.gravityMode ===<br />
number sim.gravityMode()<br />
Returns the current gravity simulation mode.<br />
<br />
nil sim.gravityMode(number mode)<br />
Sets the gravity simulation mode to mode.<br />
<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal, vertical gravity<br />
|-<br />
|1<br />
|No gravity<br />
|-<br />
|2<br />
|Radial gravity<br />
|}<br />
<br />
=== simulation.gspeed ===<br />
number sim.gspeed()<br />
Returns the current GoL speed<br />
<br />
nil sim.gspeed(number newSpeed)<br />
Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.<br />
<br />
=== simulation.listCustomGol ===<br />
table sim.listCustomGol()<br />
Returns a table of all custom game of life types. Each index has a name (string), rulestr (string), rule (number), color1 (number), and color2 (number) property. See [[#simulation.addCustomGol|sim.addCustomGol]] for details about properties.<br />
<br />
=== simulation.loadSave ===<br />
nil sim.loadSave(number SaveID, [number hideDescription], [number history?])<br />
Loads the save associated with the specified SaveID.<br />
If hideDescription is non zero, the information for the save is not shown.<br />
<br />
=== simulation.loadStamp ===<br />
sim.loadStamp(string filename, number x, number y)<br />
sim.loadStamp(number id, number x, number y)<br />
Loads a stamp identified by filename or ID, and places it at position x,y. Filenames should be given without stamps/ or the .stm suffix. On success, returns 1. On failure, returns nil and the failure reason as a string.<br />
<br />
=== simulation.neighbors ===<br />
type sim.neighbors(number x, number y, [number rx], [number ry], [number type])<br />
Used for iterating through particles in an area centred on the given coordinates (x, y). Radius in the x and y directions is set by rx and ry. Default radius is 2, 2. If type is provided, only particles of the corresponding type will be returned.<br />
<br />
The size of the rectangular area is one plus twice the radius, so a radius of 2, 2 gives a 5x5 pixel area centred on x, y. Particles in the centre position x, y are excluded. Only one particle in each position is included, and energy particles (such as photons, neutrons, electrons) are ignored.<br />
<br />
Example (i is the index of the neighbouring particle and nx, ny are its coordinates):<br />
<syntaxhighlight lang="lua"><br />
for i,nx,ny in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
Or if coordinates of the neighbouring particles are not required:<br />
<syntaxhighlight lang="lua"><br />
for i in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.neighbours ===<br />
Same as sim.neighbors()<br />
<br />
=== simulation.partChangeType ===<br />
nil sim.partChangeType(number index, number type)<br />
Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.<br />
<br />
=== simulation.partCreate ===<br />
number sim.partCreate(number index, number x, number y, number type)<br />
Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure. <br />
<br />
Possible values for index are:<br />
<br />
* -1 : Normal particle creation. This is the most useful value. No particle is created if position x, y is occupied and the requested new particle type cannot pass through the particle that is already there.<br />
* -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.<br />
* -3 : Create particle without checking for collisions with existing particles. In most cases, this is a bad idea, since a lot of elements don't work properly when there are multiple particles in the same place. Particles may also turn into BHOL if there are too many in the same place. The exception to this is elements that have been specifically designed to cope with this (such as multiple energy particles like PHOT and NEUT in the same place). <br />
* particle index, >= 0 : Overwrite an existing particle with a new particle. At the moment no collision checking is performed, so the same considerations apply as for index=-3. It is usually safe if the new particle is in the same location as the old one. This is roughly equivalent to calling sim.partKill then sim.partCreate(-3, ...).<br />
<br />
=== simulation.partExists ===<br />
boolean sim.partExists(number index)<br />
Returns true if a particle exists at a given index.<br />
<br />
=== simulation.partID ===<br />
number sim.partID(number x, number y)<br />
Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.<br />
<br />
Example (though this is probably best done with sim.neighbours):<br />
<syntaxhighlight lang="lua"><br />
for fx = -1, 1, 1 do<br />
for fy = -1, 1, 1 do<br />
local i = sim.partID(x + fx, y + fy)<br />
if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then<br />
sim.partProperty(index, sim.FIELD_TEMP, 9999)<br />
end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.partKill ===<br />
nil sim.partKill(number index)<br />
nil sim.partKill(number x, number y)<br />
Reliably delete a particle at a specified index or location, this method avoids the side effects created by changing the type to 0/DEFAULT_PT_NONE with the "partProperty" method<br />
<br />
=== simulation.partNeighbors ===<br />
table sim.partNeighbours(number x, number y, number radius, [number type])<br />
Returns an array of indices of particles that neighbour the given coordinates and match the given type (if it is specified). The resulting array does not contain the particle at the specified position.<br />
<br />
=== simulation.partNeighbours ===<br />
Same as sim.partNeighbors()<br />
<br />
=== simulation.partPosition ===<br />
number x, number y sim.partPosition(number index)<br />
Get the location of the particle at the specified index <br />
<br />
=== simulation.partProperty ===<br />
nil sim.partProperty(number index, object field, object value)<br />
Set the property value on a particle specified by index<br />
<br />
object sim.partProperty(number index, object field)<br />
Get the property value on a particle specified by the index<br />
<br />
The "field" may be a field name or field ID, see FIELD constants below for valid fields.<br />
<br />
=== simulation.parts ===<br />
function sim.parts()<br />
Returns an iterator over particle indexes that can be used in lua for loops<br />
<br />
=== simulation.pmap ===<br />
number sim.pmap(number x, number y)<br />
Get the index of the particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.partID, but excludes energy particles (such as PHOT, NEUT, ELEC).<br />
<br />
=== simulation.photons ===<br />
number sim.photons(number x, number y)<br />
Get the index of the energy particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.pmap<br />
<br />
=== simulation.pressure ===<br />
number sim.pressure(number x, number y)<br />
Returns a value on the pressure map.<br />
<br />
nil sim.pressure(number x, number y, [number width, number height], number pressure)<br />
Sets values on the pressure map.<br />
<br />
=== simulation.prettyPowders ===<br />
number sim.prettyPowders()<br />
nil sim.prettyPowders(mode)<br />
Sets whether the "pretty powders mode" (powders, such as SAND or BCOL, will be assigned random deco values) is on or off. When called with no arguments, returns a value determining whether it is on or off.<br />
<br />
=== simulation.reloadSave ===<br />
nil sim.reloadSave()<br />
Reloading save.<br />
<br />
=== simulation.removeCustomGol ===<br />
boolean sim.removeCustomGol(string name)<br />
Removes all custom game of life types with the specified name. Returns true if any were removed.<br />
<br />
=== simulation.resetPressure ===<br />
nil sim.resetPressure()<br />
Resets the pressure map to no pressure.<br />
<br />
=== simulation.resetTemp ===<br />
nil sim.resetTemp()<br />
Resets the temperature of all particles to their spawn temperature.<br />
<br />
=== simulation.replaceModeFlags ===<br />
number sim.replaceModeFlags()<br />
Returns the current replace mode flags.<br />
nil sim.replaceModeFlags(number flags)<br />
Sets the replace mode flags.<br />
<br />
If the first bit of that number is set (flags = 1), replace mode is enabled.<br />
<br />
If the second bit is set (flags = 2), specific delete is enabled.<br />
<br />
=== simulation.saveStamp ===<br />
string sim.saveStamp([number x, number y, number width, number height])<br />
Creates a stamp of the specified coordinates. Coordinates default to entire simulation.<br />
Returns the stamp id created.<br />
<br />
=== simulation.signs ===<br />
table simulation.signs<br />
A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.<br />
<br />
==== simulation.signs[n] ====<br />
table simulation.signs[n]<br />
A table which always contains the id property. May also contain text, x, y and justification. These properties can be directly modified to change a sign.<br />
A justification of 0 means left, 1 means right, 2 means middle and 3 means none.<br />
The text property cannot be larger than 45 in length.<br />
<br />
==== simulation.signs.delete ====<br />
nil simulation.signs.delete(number signID)<br />
Deletes the sign at the specified sign id.<br />
<br />
==== simulation.signs.new ====<br />
number simulation.signs.new([string text, number x, number y, number justification])<br />
Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).<br />
<br />
=== simulation.takeSnapshot ===<br />
nil sim.takeSnapshot()<br />
Takes a undo snapshot, for use with ctrl + z<br />
<br />
=== simulation.toolBox ===<br />
type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])<br />
Does something<br />
<br />
=== simulation.toolBrush ===<br />
number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) on the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.toolLine ===<br />
type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Does something<br />
<br />
=== simulation.velocityX ===<br />
number sim.velocityX(number x, number y)<br />
Returns an X value on the velocity map.<br />
<br />
nil sim.velocityX(number x, number y, [number width, number height], number value)<br />
Sets X values on the velocity map.<br />
<br />
=== simulation.velocityY ===<br />
number sim.velocityY(number x, number y)<br />
Returns an Y value on the velocity map.<br />
<br />
nil sim.velocityY(number x, number y, [number width, number height], number value)<br />
Sets Y values on the velocity map.<br />
<br />
=== simulation.waterEqualisation ===<br />
number sim.waterEqualisation()<br />
Returns the current Water equalisation setting.<br />
<br />
nil sim.waterEqualisation(number setting)<br />
Set the Water equalisation setting to setting.<br />
<br />
=== simulation.waterEqualization ===<br />
Same as sim.waterEqualisation()<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with simulation.<constant name here><br />
<br />
=== DECO ===<br />
; DECO_DIVIDE<br />
; DECO_SMUDGE<br />
; DECO_ADD<br />
; DECO_SUBTRACT<br />
; DECO_CLEAR<br />
; DECO_DRAW<br />
; DECO_MULTIPLY<br />
<br />
=== FIELD ===<br />
; FIELD_DCOLOUR<br />
; FIELD_Y<br />
; FIELD_TEMP<br />
; FIELD_TYPE<br />
; FIELD_VY<br />
; FIELD_X<br />
; FIELD_TMP2<br />
; FIELD_TMP<br />
; FIELD_FLAGS<br />
; FIELD_VX<br />
; FIELD_CTYPE<br />
; FIELD_LIFE<br />
<br />
=== MAX ===<br />
; MAX_TEMP<br />
<br />
=== MIN ===<br />
; MIN_TEMP<br />
<br />
=== NUM ===<br />
; NUM_PARTS<br />
<br />
=== PT ===<br />
; PT_NUM<br />
<br />
=== R ===<br />
; R_TEMP<br />
<br />
=== TOOL ===<br />
; TOOL_VAC<br />
; TOOL_AIR<br />
; TOOL_NGRV<br />
; TOOL_PGRV<br />
; TOOL_HEAT<br />
; TOOL_WIND<br />
; TOOL_COOL<br />
<br />
=== Uncategorized ===<br />
; YRES<br />
; XRES<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Simulation&diff=8661Lua API:Simulation2022-11-13T14:06:32Z<p>Maticzpl: Fix wrong argument order in sim.pressure</p>
<hr />
<div>The Simulation API allows for modifying the state and properties of particles, air and gravity<br />
<br />
== Methods ==<br />
<br />
=== simulation.addCustomGol ===<br />
nil sim.addCustomGol(string rule, string name, number color1, number color2)<br />
Adds a custom game of life type with the specified rule, name, and colors. Rule strings use B#/S#/# notation ([https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Variations more detail]). Colors are used when fading between multiple states. Names and rules cannot be duplicates.<br />
<br />
nil sim.addCustomGol(number rule, string name, number color1, number color2)<br />
Same as above, but takes a binary representation of the rule instead of a string. Bits 0-8 list stay values (starting at 0), bits 9-16 list begin values (starting at 1), and bits 17-20 are the number of states (decimal value added to 2). This is also how GOL rules are stored as ctypes.<br />
<br />
=== simulation.adjustCoords ===<br />
number, number sim.adjustCoords(number x, number y)<br />
Actually this is more of a UI method than a simulation method. Given a mouse position x, y in the window, this function returns the corresponding coordinates in the simulation (taking into account the visibility and position of the zoom window, if applicable). <br />
<br />
=== simulation.airMode ===<br />
number sim.airMode()<br />
Returns the current Air Simulation Mode.<br />
<br />
nil sim.airMode(number mode)<br />
Sets the Air Simulation Mode to mode.<br />
<br />
Mode numbers are as follows (not currently available as named constants):<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal<br />
|-<br />
|1<br />
|Pressure off<br />
|-<br />
|2<br />
|Velocity off<br />
|-<br />
|3<br />
|Velocity and pressure off<br />
|-<br />
|4<br />
|No update<br />
|}<br />
<br />
=== simulation.ambientAirTemp ===<br />
number sim.ambientAirTemp()<br />
Returns the current ambient temperature. When ambient heat mode is turned on, the air at the edges of the screen will remain at this temperature. <br />
<br />
nil sim.ambientAirTemp(number temp)<br />
Sets the ambient temperature. The temperature is measured in Kelvin. <br />
<br />
=== simulation.ambientHeat ===<br />
number sim.ambientHeat(number x, number y)<br />
Returns a value on the ambient heat map (the temperature of the air at that point). <br />
<br />
nil sim.ambientHeat(number x, number y, number temp, [number width, number height])<br />
Sets values on the ambient heat map. <br />
<br />
=== simulation.brush ===<br />
function sim.brush(number x, number y, [number brushWidth, number brushHeight], [number brushID])<br />
Returns an iterator over positions inside the specified brush.<br />
<br />
If width, height or ID is not provided, will use values of the current brush selected by user.<br />
<br />
Example:<br />
for x, y in sim.brush(300, 200, 100, 50, 0) do<br />
sim.partCreate(-1, x, y, elem.DEFAULT_PT_DUST)<br />
end<br />
<br />
=== simulation.can_move ===<br />
simulation.can_move(number movingElementID, number obstacleElementID, number method)<br />
Decides what a particle does when it hits another particle while moving. Method is one of the following:<br />
* 0: bounce off the obstacle<br />
* 1: swap places with the obstacle<br />
* 2: move over the obstacle<br />
<br />
number simulation.can_move(number movingElementID, number obstacleElementID)<br />
Returns what a particle does when it hits another particle while moving, a method like above.<br />
<br />
=== simulation.clearRect ===<br />
nil sim.clearRect(number x, number y, number width, number height)<br />
Clears all particles in a rectangle starting at x, y down and to the right width and height pixels respectively.<br />
<br />
=== simulation.clearSim ===<br />
nil sim.clearSim()<br />
Clears everything in the simulation.<br />
<br />
=== simulation.createBox ===<br />
nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])<br />
Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createLine ===<br />
nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])<br />
Creates a line of of either the user's currently selected type or the type specified at the specified coordinates.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createParts ===<br />
number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])<br />
Does something.<br />
<br />
=== simulation.createWallBox ===<br />
nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])<br />
Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWallLine ===<br />
nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])<br />
Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWalls ===<br />
number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])<br />
Does something<br />
<br />
=== simulation.decoBox ===<br />
nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])<br />
Changes the decoration color of all particles in the specified coordinates.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoBrush ===<br />
nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Does something<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoColor ===<br />
number sim.decoColor()<br />
Returns the currently selected decoration color.<br />
<br />
nil sim.decoColor(number color)<br />
Sets the selected decoration color to color.<br />
color is in the format 0xAARRGGBB<br />
<br />
nil sim.decoColor(number r, number g, number b, [number a])<br />
Sets the selected decoration color to r,g,b,a<br />
<br />
=== simulation.decoColour ===<br />
Same as sim.decoColor()<br />
<br />
=== simulation.decoLine ===<br />
nil sim.decoLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Changes the decoration color of all particles in the line specified.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.deleteStamp ===<br />
type sim.deleteStamp(string name)<br />
Deleting a stamp identified by filename or ID.<br />
<br />
=== simulation.edgeMode ===<br />
number sim.edgeMode()<br />
Returns the current Edge Mode<br />
<br />
nil sim.edgeMode(number mode)<br />
Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation. <br />
<br />
=== simulation.elementCount ===<br />
number sim.elementCount(number type)<br />
Returns the number of particles of the specified type in the simulation.<br />
<br />
=== simulation.floodDeco ===<br />
nil sim.floodDeco(number x, number y, number r, number g, number b, number a)<br />
Flood fills the color at position x, y with another color. Note: Color at position includes console overlay.<br />
<br />
=== simulation.floodParts ===<br />
number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])<br />
Flood fills either the user's currently selected type or the type specified at the coordinates given.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.floodWalls ===<br />
number sim.floodWalls(number x, number y, [number walltype], [number bm?])<br />
Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.framerender ===<br />
number sim.framerender()<br />
sim.framerender(number frames)<br />
Advances the simulation the given number of frames, even when paused. If called with no arguments, returns the number of frames currently to be rendered. Usually is 0.<br />
<br />
=== simulation.getSaveID ===<br />
number, number sim.getSaveID()<br />
Returns the save ID and the history offset of the currently loaded save or nil if the simulation is not a downloaded save. The history offset can be used with loadSave.<br />
<br />
=== simulation.gravMap ===<br />
number sim.gravMap(number x, number y)<br />
nil sim.gravMap(number x, number y, [number width, number height, [number value]])<br />
Returns the newtonian gravity at the given coordinates in the simulation. If given a value, will set the newtonian gravity at those coordinates. Width and height refer to the rectangle of affected cells, starting with the coords. If not given, they will default to 1,1.<br />
<br />
=== simulation.gravityGrid ===<br />
number sim.gravityGrid()<br />
Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.<br />
<br />
nil sim.gravityGrid(number mode)<br />
Sets the setting for drawing the gravity grid to mode.<br />
<br />
=== simulation.gravityMode ===<br />
number sim.gravityMode()<br />
Returns the current gravity simulation mode.<br />
<br />
nil sim.gravityMode(number mode)<br />
Sets the gravity simulation mode to mode.<br />
<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal, vertical gravity<br />
|-<br />
|1<br />
|No gravity<br />
|-<br />
|2<br />
|Radial gravity<br />
|}<br />
<br />
=== simulation.gspeed ===<br />
number sim.gspeed()<br />
Returns the current GoL speed<br />
<br />
nil sim.gspeed(number newSpeed)<br />
Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.<br />
<br />
=== simulation.listCustomGol ===<br />
table sim.listCustomGol()<br />
Returns a table of all custom game of life types. Each index has a name (string), rulestr (string), rule (number), color1 (number), and color2 (number) property. See [[#simulation.addCustomGol|sim.addCustomGol]] for details about properties.<br />
<br />
=== simulation.loadSave ===<br />
nil sim.loadSave(number SaveID, [number hideDescription], [number history?])<br />
Loads the save associated with the specified SaveID.<br />
If hideDescription is non zero, the information for the save is not shown.<br />
<br />
=== simulation.loadStamp ===<br />
sim.loadStamp(string filename, number x, number y)<br />
sim.loadStamp(number id, number x, number y)<br />
Loads a stamp identified by filename or ID, and places it at position x,y. Filenames should be given without stamps/ or the .stm suffix. On success, returns 1. On failure, returns nil and the failure reason as a string.<br />
<br />
=== simulation.neighbors ===<br />
type sim.neighbors(number x, number y, [number rx], [number ry], [number type])<br />
Used for iterating through particles in an area centred on the given coordinates (x, y). Radius in the x and y directions is set by rx and ry. Default radius is 2, 2. If type is provided, only particles of the corresponding type will be returned.<br />
<br />
The size of the rectangular area is one plus twice the radius, so a radius of 2, 2 gives a 5x5 pixel area centred on x, y. Particles in the centre position x, y are excluded. Only one particle in each position is included, and energy particles (such as photons, neutrons, electrons) are ignored.<br />
<br />
Example (i is the index of the neighbouring particle and nx, ny are its coordinates):<br />
<syntaxhighlight lang="lua"><br />
for i,nx,ny in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
Or if coordinates of the neighbouring particles are not required:<br />
<syntaxhighlight lang="lua"><br />
for i in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.neighbours ===<br />
Same as sim.neighbors()<br />
<br />
=== simulation.partChangeType ===<br />
nil sim.partChangeType(number index, number type)<br />
Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.<br />
<br />
=== simulation.partCreate ===<br />
number sim.partCreate(number index, number x, number y, number type)<br />
Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure. <br />
<br />
Possible values for index are:<br />
<br />
* -1 : Normal particle creation. This is the most useful value. No particle is created if position x, y is occupied and the requested new particle type cannot pass through the particle that is already there.<br />
* -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.<br />
* -3 : Create particle without checking for collisions with existing particles. In most cases, this is a bad idea, since a lot of elements don't work properly when there are multiple particles in the same place. Particles may also turn into BHOL if there are too many in the same place. The exception to this is elements that have been specifically designed to cope with this (such as multiple energy particles like PHOT and NEUT in the same place). <br />
* particle index, >= 0 : Overwrite an existing particle with a new particle. At the moment no collision checking is performed, so the same considerations apply as for index=-3. It is usually safe if the new particle is in the same location as the old one. This is roughly equivalent to calling sim.partKill then sim.partCreate(-3, ...).<br />
<br />
=== simulation.partExists ===<br />
boolean sim.partExists(number index)<br />
Returns true if a particle exists at a given index.<br />
<br />
=== simulation.partID ===<br />
number sim.partID(number x, number y)<br />
Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.<br />
<br />
Example (though this is probably best done with sim.neighbours):<br />
<syntaxhighlight lang="lua"><br />
for fx = -1, 1, 1 do<br />
for fy = -1, 1, 1 do<br />
local i = sim.partID(x + fx, y + fy)<br />
if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then<br />
sim.partProperty(index, sim.FIELD_TEMP, 9999)<br />
end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.partKill ===<br />
nil sim.partKill(number index)<br />
nil sim.partKill(number x, number y)<br />
Reliably delete a particle at a specified index or location, this method avoids the side effects created by changing the type to 0/DEFAULT_PT_NONE with the "partProperty" method<br />
<br />
=== simulation.partNeighbors ===<br />
table sim.partNeighbours(number x, number y, number radius, [number type])<br />
Returns an array of indices of particles that neighbour the given coordinates and match the given type (if it is specified). The resulting array does not contain the particle at the specified position.<br />
<br />
=== simulation.partNeighbours ===<br />
Same as sim.partNeighbors()<br />
<br />
=== simulation.partPosition ===<br />
number x, number y sim.partPosition(number index)<br />
Get the location of the particle at the specified index <br />
<br />
=== simulation.partProperty ===<br />
nil sim.partProperty(number index, object field, object value)<br />
Set the property value on a particle specified by index<br />
<br />
object sim.partProperty(number index, object field)<br />
Get the property value on a particle specified by the index<br />
<br />
The "field" may be a field name or field ID, see FIELD constants below for valid fields.<br />
<br />
=== simulation.parts ===<br />
function sim.parts()<br />
Returns an iterator over particle indexes that can be used in lua for loops<br />
<br />
=== simulation.pmap ===<br />
number sim.pmap(number x, number y)<br />
Get the index of the particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.partID, but excludes energy particles (such as PHOT, NEUT, ELEC).<br />
<br />
=== simulation.photons ===<br />
number sim.photons(number x, number y)<br />
Get the index of the energy particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.pmap<br />
<br />
=== simulation.pressure ===<br />
number sim.pressure(number x, number y)<br />
Returns a value on the pressure map.<br />
<br />
nil sim.pressure(number x, number y, [number width, number height], number pressure)<br />
Sets values on the pressure map.<br />
<br />
=== simulation.prettyPowders ===<br />
number sim.prettyPowders()<br />
nil sim.prettyPowders(mode)<br />
Sets whether the "pretty powders mode" (powders, such as SAND or BCOL, will be assigned random deco values) is on or off. When called with no arguments, returns a value determining whether it is on or off.<br />
<br />
=== simulation.reloadSave ===<br />
nil sim.reloadSave()<br />
Reloading save.<br />
<br />
=== simulation.removeCustomGol ===<br />
boolean sim.removeCustomGol(string name)<br />
Removes all custom game of life types with the specified name. Returns true if any were removed.<br />
<br />
=== simulation.resetPressure ===<br />
nil sim.resetPressure()<br />
Resets the pressure map to no pressure.<br />
<br />
=== simulation.resetTemp ===<br />
nil sim.resetTemp()<br />
Resets the temperature of all particles to their spawn temperature.<br />
<br />
=== simulation.replaceModeFlags ===<br />
number sim.replaceModeFlags()<br />
Returns the current replace mode flags.<br />
nil sim.replaceModeFlags(number flags)<br />
Sets the replace mode flags.<br />
<br />
If the first bit of that number is set (flags = 1), replace mode is enabled.<br />
<br />
If the second bit is set (flags = 2), specific delete is enabled.<br />
<br />
=== simulation.saveStamp ===<br />
string sim.saveStamp([number x, number y, number width, number height])<br />
Creates a stamp of the specified coordinates. Coordinates default to entire simulation.<br />
Returns the stamp id created.<br />
<br />
=== simulation.signs ===<br />
table simulation.signs<br />
A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.<br />
<br />
==== simulation.signs[n] ====<br />
table simulation.signs[n]<br />
A table which always contains the id property. May also contain text, x, y and justification. These properties can be directly modified to change a sign.<br />
A justification of 0 means left, 1 means right, 2 means middle and 3 means none.<br />
The text property cannot be larger than 45 in length.<br />
<br />
==== simulation.signs.delete ====<br />
nil simulation.signs.delete(number signID)<br />
Deletes the sign at the specified sign id.<br />
<br />
==== simulation.signs.new ====<br />
number simulation.signs.new([string text, number x, number y, number justification])<br />
Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).<br />
<br />
=== simulation.takeSnapshot ===<br />
nil sim.takeSnapshot()<br />
Takes a undo snapshot, for use with ctrl + z<br />
<br />
=== simulation.toolBox ===<br />
type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])<br />
Does something<br />
<br />
=== simulation.toolBrush ===<br />
number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) on the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.toolLine ===<br />
type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Does something<br />
<br />
=== simulation.velocityX ===<br />
number sim.velocityX(number x, number y)<br />
Returns an X value on the velocity map.<br />
<br />
nil sim.velocityX(number x, number y, [number value], [number width, number height])<br />
Sets X values on the velocity map.<br />
<br />
=== simulation.velocityY ===<br />
number sim.velocityY(number x, number y)<br />
Returns an Y value on the velocity map.<br />
<br />
nil sim.velocityY(number x, number y, [number value], [number width, number height])<br />
Sets Y values on the velocity map.<br />
<br />
=== simulation.waterEqualisation ===<br />
number sim.waterEqualisation()<br />
Returns the current Water equalisation setting.<br />
<br />
nil sim.waterEqualisation(number setting)<br />
Set the Water equalisation setting to setting.<br />
<br />
=== simulation.waterEqualization ===<br />
Same as sim.waterEqualisation()<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with simulation.<constant name here><br />
<br />
=== DECO ===<br />
; DECO_DIVIDE<br />
; DECO_SMUDGE<br />
; DECO_ADD<br />
; DECO_SUBTRACT<br />
; DECO_CLEAR<br />
; DECO_DRAW<br />
; DECO_MULTIPLY<br />
<br />
=== FIELD ===<br />
; FIELD_DCOLOUR<br />
; FIELD_Y<br />
; FIELD_TEMP<br />
; FIELD_TYPE<br />
; FIELD_VY<br />
; FIELD_X<br />
; FIELD_TMP2<br />
; FIELD_TMP<br />
; FIELD_FLAGS<br />
; FIELD_VX<br />
; FIELD_CTYPE<br />
; FIELD_LIFE<br />
<br />
=== MAX ===<br />
; MAX_TEMP<br />
<br />
=== MIN ===<br />
; MIN_TEMP<br />
<br />
=== NUM ===<br />
; NUM_PARTS<br />
<br />
=== PT ===<br />
; PT_NUM<br />
<br />
=== R ===<br />
; R_TEMP<br />
<br />
=== TOOL ===<br />
; TOOL_VAC<br />
; TOOL_AIR<br />
; TOOL_NGRV<br />
; TOOL_PGRV<br />
; TOOL_HEAT<br />
; TOOL_WIND<br />
; TOOL_COOL<br />
<br />
=== Uncategorized ===<br />
; YRES<br />
; XRES<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua&diff=8660Lua2022-11-13T13:10:41Z<p>Maticzpl: Add fan velocity arguments to tpt.set_wallmap</p>
<hr />
<div>{{Languages|Lua}}<br />
<br />
You may open the Lua Console by hitting the ''[`]'' key. (Also known as the tilde ''[~]'' key, or the ''[¬]'' key) [http://www.bittbox.com/wp-content/uploads/2007/12/tilde_illustrator_1.jpg click here to view key]<br />
<br />
----<br />
<br />
You may be used to this style of console commands: ''!set type dust metl''. This can be useful, but Lua is an entire programming language that can do much more powerful things. The equivalent command in TPT's Lua is ''tpt.set_property("type", "metl", "dust")'' (see [[Lua#tpt.set_property]] )<br />
<br />
This page describes the TPT Lua API, not the Lua language itself. But, you may research Lua on your own. If you're a beginner, look at this: http://www.lua.org/pil/ . If more advanced, a list of all the functions is here: http://www.lua.org/manual/5.1/<br />
<br />
Also, FeynmanTechnologies has written a tutorial on some of the most basic Lua features here: https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=17801<br />
<br />
The Lua Console provides the ability to create scripts using Lua, a very simple scripting language. With the ability to script with Lua, users are now able to create simple modifications to the game without editing source code. For information on how to run scripts, see [[Running Lua Scripts]]<br />
<br />
= Lua API =<br />
The Powder Toy exposes the following methods to the Lua API:<br />
<br />
== Game ==<br />
<br />
=== tpt.set_pause ===<br />
<br />
<code>tpt.set_pause(number state)</code><br />
<br />
Sets the paused state of the game. <br />
<br />
The number argument is either 0 or 1, where 1 means the game will be paused, and 0 will unpause the game. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the game is currently paused. <br />
<br />
'''Examples''':<br />
<br />
Pause the game: <code>tpt.set_pause(1)</code><br />
<br />
Get if the game is paused currently: <code>tpt.set_pause() == 1</code><br />
<br />
=== tpt.set_console ===<br />
<br />
<code>tpt.set_console(number state)</code><br />
<br />
Set the visibility state of the console. <br />
<br />
The number argument can be either 0 or 1, where 1 means the console will be opened, and 0 will close the console. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the console is currently opened.<br />
<br />
'''Examples''':<br />
<br />
Open the console: <code>tpt.set_console(1)</code><br />
<br />
Get if the console is currently open: <code>tpt.set_console() == 1</code><br />
<br />
=== tpt.set_shortcuts ===<br />
<br />
'''This function is REMOVED in TPT 94.0'''<br />
<br />
<code>tpt.set_shortcuts(number state)</code><br />
<br />
Set whether one can use keyboard shortcuts such as making a stamp or opening the console or changing view modes. <br />
<br />
The number argument can be either 0 or 1, where 1 means keys will be enabled, and 0 will disable key shortcuts. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether key shortcuts are enabled right now.<br />
<br />
When you want to make a key command which uses some other key, don't use this, rather disable default behavior for that one key only by returning false from inside your callback.<br />
<br />
'''Examples''':<br />
<br />
Disable keyboard shortcuts: <code>tpt.set_shortcuts(0)</code><br />
<br />
Get if keyboard shortcuts are currently disabled: <code>tpt.set_shortcuts(-1) == 1</code><br />
<br />
=== tpt.set_gravity ===<br />
<br />
<code>tpt.set_gravity(number x, number y, number width, number height, number value)</code><br />
<br />
Sets Newtonian Gravity at a position or area to some value. <br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples''':<br />
<br />
Reset gravity in the cell at point (150, 150): <code>tpt.set_gravity(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100,100) to (300,300): <code>tpt.set_gravity(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
Set the entire stage's gravity to 1000: <code>tpt.set_gravity(nil, nil, nil, nil, 1000)</code><br />
<br />
=== tpt.reset_gravity_field ===<br />
<br />
<code>tpt.reset_gravity_field(number x, number y, number width, number height)</code><br />
<br />
Thoroughly resets Newtonian gravity on a given point. <br />
<br />
Instead of tpt.set_gravity which only modifies <code>sim-&gt;gravmap</code>, this code modifies <code>sim->gravp</code>,<code>sim->gravx</code> and <code>sim->gravy</code>. Mmm, gravy.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples''':<br />
<br />
Thoroughly reset gravity in the cell at point (150, 150): <code>tpt.reset_gravity_field(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100, 100) to (300,300): <code>tpt.reset_gravity_field(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
=== tpt.set_pressure ===<br />
<br />
<code>tpt.set_pressure(number x, number y, number width, number height, number value)</code><br />
<br />
Sets or resets pressure in the pressure map to some pressure. I sometimes imagine how much I can repeat the word "pressure" inside a sentence before it becomes gibberish.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples:'''<br />
<br />
Reset pressure everywhere: <code>tpt.set_pressure()</code><br />
<br />
Set pressure of cell at (100, 100) to 200: <code>tpt.set_pressure(100 / sim.CELL, 100 / sim.CELL, 1, 1, 200)</code><br />
<br />
Set pressure everywhere to 200: <code>tpt.set_pressure(nil,nil,nil,nil,200)</code><br />
<br />
=== tpt.reset_velocity ===<br />
<br />
<code>tpt.reset_velocity(number x, number y, number width, number height)</code><br />
<br />
Sets velocity (both x and y) in a given region or point to 0.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples:'''<br />
<br />
Reset velocity everywhere: <code>tpt.reset_velocity()</code><br />
<br />
Reset velocity in the cell at point (100,100): <code>tpt.reset_velocity(100 / sim.CELL, 100 / sim.CELL, 1, 1)</code><br />
<br />
=== tpt.hud ===<br />
<br />
<code>tpt.hud(number state)</code><br />
<br />
Set HUD visibility.<br />
<br />
Does the same thing as pressing the H key normally. The number argument can be either 0 or 1, where 1 will show the HUD, and 0 will hide the HUD. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the HUD is visible right now.<br />
<br />
=== tpt.newtonian_gravity ===<br />
<br />
<code>tpt.newtonian_gravity(number state)</code><br />
<br />
Sets Newtonian Gravity on and off.<br />
<br />
Does the same thing as Ctrl+N in normal gameplay. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable Newtonian Gravity, and 0 will disable Newtonian Gravity. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Newtonian Gravity is turned on at the given moment.<br />
<br />
=== tpt.ambient_heat ===<br />
<br />
<code>tpt.ambient_heat(number state)</code><br />
<br />
Toggles Ambient Heat state.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable Ambient Heat, 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Ambient Heat is turned on at the given moment.<br />
<br />
=== tpt.decorations_enable ===<br />
<br />
<code>tpt.decorations_enable(number state)</code><br />
<br />
Toggle drawing decorations.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable decorations, and 0 will disable them. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether decorations are turned on at the given moment.<br />
<br />
=== tpt.heat ===<br />
<br />
<code>tpt.heat(number state)</code><br />
<br />
Toggles Heat Simulation. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable heat, and 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether heat is turned on at the given moment.<br />
<br />
It's usually wise not to disable this, as there are practically no saves left that need the compatibility mode in order to work. Nevertheless this option exists. <br />
<br />
=== tpt.active_menu ===<br />
<br />
<code>tpt.active_menu(number menu)</code><br />
<br />
Changes activated menu. If you don't pass in any arguments, the command will return the currently active menu.<br />
<br />
The menu IDs are detailed here: [[Element_Properties#Menu_sections]]<br />
<br />
Example: <code>tpt.active_menu(elem.SC_EXPLOSIVE)</code><br />
<br />
=== tpt.menu_enabled ===<br />
<br />
<code><br />
boolean tpt.menu_enabled(number menuID)<br />
<br />
tpt.menu_enabled(number menuID, boolean enabled)<br />
</code><br />
<br />
Returns true if a menu section is enabled. <br />
<br />
If provided a boolean, will set if a menu section is enabled.<br />
<br />
=== tpt.num_menus ===<br />
<br />
<code><br />
number tpt.num_menus()<br />
<br />
number tpt.num_menus(boolean onlyEnabled)<br />
</code><br />
<br />
Returns the number of menus.<br />
<br />
The optional onlyEnabled boolean is true by default.<br />
<br />
=== tpt.display_mode ===<br />
<br />
<code>tpt.display_mode(number display)</code><br />
<br />
Changes activated display mode.<br />
<br />
There's 11 display modes, detailed here [[https://github.com/ThePowderToy/The-Powder-Toy/blob/f54189a97f6d80181deb4f6d952ccf10f0e59ccf/src/graphics/Renderer.cpp#L2587-L2644]]<br><br />
Note that the order of display modes is shifted by 1 making velocity mode first and alternative velocity last.<br />
<br />
'''Display Modes'''<br />
<br />
0 = Velocity<br><br />
1 = Pressure<br><br />
2 = Persistent<br><br />
3 = Fire<br><br />
4 = Blob<br><br />
5 = Heat<br><br />
6 = Fancy<br><br />
7 = Nothing<br><br />
8 = Heat Gradient<br><br />
9 = Life Gradient<br><br />
10 = Alternate Velocity<br><br />
<br />
=== tpt.setfpscap ===<br />
<br />
<code>tpt.setfpscap(number fpscap)</code><br />
<br />
Changes the upper FPS limit the program will run at. This value is '''60 by default.'''<br />
<br />
Don't set it too high, it'll eat all your CPU speed and make the game too responsive! Don't also set it too low, since UI and everything related to it uses the same FPS, so you'll find buttons and stuff not working.<br />
<br />
If you don't pass in any arguments, it will return the current fps cap. If you set the fpscap to 2, this will uncap the framerate.<br />
<br />
=== tpt.setdrawcap ===<br />
<br />
Changes the rate that particle graphics and the UI render to the screen. This is separate from the fpscap, which only affects the simulation. The drawcap allows TPT to skip drawing every frame. This may increase the framerate in some instances.<br />
<br />
The default is set to the maximum refresh rate of all attached monitors.<br />
<br />
=== tpt.setfire ===<br />
Changes the strength of the games glowing effects. tpt.setfire(1) is default.<br />
<br />
<code>tpt.setfire(number strength)</code><br />
<br />
=== tpt.setwindowsize ===<br />
<br />
<code>tpt.setwindowsize(number scale, number fullscreen)</code><br />
<br />
Changes a few special properties as to what size the game renders at.<br />
<br />
Scale is a multiplier by which every pixel shall get multiplied at, currently it can either be 1 (612x384) or 2 (1224x768). <br />
<br />
Full screen is a toggle (0 or 1) that enables "kiosk mode", which basically scales the game up to fill the screen and makes the rest of the edge black.<br />
<br />
=== tpt.toggle_pause ===<br />
Toggle pause.<br />
<br />
<code>tpt.toggle_pause()</code><br />
<br />
=== tpt.watertest ===<br />
'''REPLACED by simulation.waterEqualisation'''<br />
<br />
Toggles water equalization.<br />
Returns current state.<br />
<br />
<code>number tpt.watertest()</code><br />
<br />
=== tpt.perfectCircleBrush ===<br />
Returns true if perfect circle brush is enabled.<br />
<br />
If provided with a boolean, will change if its enabled. <br />
<br />
If perfect circle brush is disabled, the circle brush will have single pixels sticking out on the sides.<br />
<br />
<code><br />
boolean tpt.perfectCircleBrush()<br />
<br />
tpt.perfectCircleBrush(boolean enabled)<br />
</code><br />
<br />
== Particles ==<br />
<br />
=== tpt.reset_spark ===<br />
Removes electrified wires from the simulation, resetting to the original material<br />
<br />
<code>tpt.reset_spark()</code><br />
<br />
=== tpt.set_property ===<br />
Set various properties of particles for given criteria, 8 overloads<br />
<br />
<code><br />
tpt.set_property(string property, object value)<br />
<br />
tpt.set_property(string property, object value, string type)<br />
<br />
tpt.set_property(string property, object value, number index)<br />
<br />
tpt.set_property(string property, object value, number index, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y)<br />
<br />
tpt.set_property(string property, object value, number x, number y, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height, string type)<br />
</code><br />
<br />
=== tpt.set_wallmap ===<br />
Sets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_wallmap(number x, number y, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number fanVelocityX, number fanVelocityY, number walltype)<br />
</code><br />
<br />
=== tpt.get_wallmap ===<br />
Gets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_wallmap(number x, number y)<br />
</code><br />
<br />
=== tpt.set_elecmap ===<br />
Sets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. The value is decremented by 1 every frame, just like SPRK .life, and when it reaches 0 the wall is "unsparked". Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_elecmap(number x, number y, number walltype)<br />
<br />
tpt.set_elecmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_elecmap ===<br />
Gets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_elecmap(number x, number y)<br />
</code><br />
<br />
=== tpt.get_property ===<br />
Returns various properties of a particle.<br />
<br />
<code><br />
tpt.get_property(string property, number index)<br />
<br />
tpt.get_property(string property, number x, number y)<br />
</code><br />
<br />
=== tpt.create ===<br />
Create a particle at location.<br />
<br />
<code>tpt.create(number x, number y, string type)</code><br />
<br />
Returns the index of the newly created particle.<br />
<br />
=== tpt.delete ===<br />
Delete a specific particle, or location.<br />
<br />
<code><br />
tpt.delete(number index)<br />
<br />
tpt.delete(number x, number y)<br />
</code><br />
<br />
=== tpt.start_getPartIndex ===<br />
Start the iterator for receiving all indices of the particles. (Used to help get particle indices, see tpt.next_getPartIndex)<br />
<br />
<code>tpt.start_getPartIndex()</code><br />
<br />
=== tpt.next_getPartIndex ===<br />
Jump to the next available particle index. Returns false if the iterator has reached the end of all particle indecies. Returns true if a new index was available. (Used to help get particle indecies, see tpt.getPartIndex)<br />
<br />
<code>tpt.next_getPartIndex()</code><br />
<br />
=== tpt.getPartIndex ===<br />
Get the current index iterator.<br />
<br />
<code>tpt.getPartIndex()</code><br />
<br />
index code example:<br />
<pre><br />
tpt.start_getPartIndex()<br />
while tpt.next_getPartIndex() do<br />
local index = tpt.getPartIndex()<br />
if tpt.get_property("ctype",index) == 21 then<br />
tpt.set_property("ctype","sing",index)<br />
end<br />
end<br />
</pre><br />
<br />
These functions are made obsolete by the function sim.parts(). That allows you to use Lua's iterators.<br />
<br />
=== tpt.get_numOfParts ===<br />
Returns the number of particles currently on the screen.<br />
<br />
<code>tpt.get_numOfParts()</code><br />
<br />
A newer way to get this is the variable sim.NUM_PARTS<br />
<br />
== Drawing ==<br />
<br />
=== tpt.textwidth ===<br />
Measures (in pixels) the width of a given string. Returns a number.<br />
<br />
<code>tpt.textwidth(string text)</code><br />
<br />
=== tpt.drawtext ===<br />
Draw text to the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawtext(number x, number y, string text)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.drawpixel ===<br />
Draws a pixel on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawpixel(number x, number y)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawline ===<br />
Draws a line on the screen (for one frame, only useful in scripts), 3 overloads. The line starts at point (x1, y1) and ends at point (x2,y2).<br />
<br />
<code><br />
tpt.drawline(number x1, number y1, number x2, number y2)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawrect ===<br />
Draws a rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawrect(number x, number y, number width, number height)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.fillrect ===<br />
Draws a filled in rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.fillrect(number x, number y, number width, number height)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
Because tpt.fillrect is slightly broken in tpt, the coordinates will be off. It fills the rectangle from (x+1, y+1) to (x+w-1, y+h-1)<br />
<br />
== Input/Output ==<br />
<br />
=== tpt.log ===<br />
Log a message to the console<br />
<br />
<code>tpt.log(string text)</code><br />
<br />
=== tpt.message_box ===<br />
Display an OK-Only message box with a title and message.<br />
<br />
<code>tpt.message_box(string title, string message)</code><br />
<br />
=== tpt.input ===<br />
Ask the user to input some text. Returns a string of what ever the user says. The argument "text" is pre-entered text (optional).<br />
<br />
<code><br />
tpt.input(string title, string message)<br />
<br />
tpt.input(string title, string message, string text)<br />
</code><br />
<br />
=== tpt.throw_error ===<br />
Displays an error message box.<br />
<br />
<code>tpt.throw_error(string text)</code><br />
<br />
=== tpt.confirm ===<br />
Display an confirm message box with a title and message. Returns true if the button with button_name is clicked, returns false if Cancel is clicked.<br />
<br />
<code>tpt.confirm(string title, string message,string button_name)</code><br />
<br />
== Events ==<br />
<br />
The old event api was removed in 94.0, and is only still present through a compatibility script. Please use the new api instead: [[Lua_API:Event|Event]]<br />
<br />
=== tpt.register_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run on every frame<br />
<br />
<code>tpt.register_step(function func)</code><br />
<br />
=== tpt.unregister_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_step(function func)</code><br />
<br />
=== tpt.register_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time the mouse clicks.<br />
<br />
Your function will also be called when the mouse is released or held, or when the mouse wheel is used. Event equals 1 when the mouse gets pressed, 2 when the mouse gets released, and 3 if it is held. If your function returns false, mouse events in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: mousex, mousey, button, event<br />
<br />
<code>tpt.register_mouseclick(function func)</code><br />
<br />
=== tpt.unregister_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_mouseclick(function func)</code><br />
<br />
=== tpt.register_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time a key is pressed.<br />
<br />
Your function will also be called when a key is released. Event equals 1 when a key is pressed, and 2 when it gets released. If your function returns false, key presses in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: key, nkey, modifier, event<br />
<br />
<code>tpt.register_keypress(function func)</code><br />
<br />
=== tpt.unregister_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_keypress(function func)</code><br />
<br />
== Misc ==<br />
<br />
=== tpt.get_name ===<br />
Returns the current username.<br />
<br />
<code>tpt.get_name()</code><br />
<br />
=== tpt.setdebug ===<br />
Sets the "debug mode". It works using bitmasks, so you can turn on multiple debug features at the same time.<br/><br />
Setting 0x1 will display info on the number of particles on the screen.<br/><br />
Setting 0x2 will draw a graph showing the percentages of each type of element on the screen.<br/><br />
Setting 0x4 will display useful information when you draw lines using shift.<br/><br />
Setting 0x8 enables subframe particle debugging. Use alt+f to step one particle at a time. Use shift+f to step up to the particle underneath the mouse. When not over a particle, it advances to the end of the frame.<br />
<br />
<code>tpt.setdebug(number mode)</code><br />
<br />
=== tpt.element ===<br />
Returns an element's number. For example, it would return 28 for dmnd. If passed a number it will return the name instead.<br />
<br />
<code>tpt.element(string elementname)<br />
<br />
tpt.element(number elementid)</code><br />
<br />
=== tpt.element_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Update" instead.<br />
<br />
Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use tpt.element("...") or tpt.el.dust.id for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1. <br />
<br />
newfunction arguments: index, x, y, surround_space, nt<br />
<br />
Returns: return 1 from your function if the particle is killed.<br />
<br />
<code>tpt.element_func(function newfunction, number el_number)<br />
<br />
tpt.element_func(function newfunction, number el_number, number replace)</code><br />
<br />
=== tpt.graphics_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Graphics" instead.<br />
<br />
Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use tpt.el.(name of element to change).id for el_number.<br />
<br />
Function arguments: index, colr, colg, colb<br />
<br />
Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.<br />
<br />
Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.<br />
<br />
colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.<br />
<br />
<code>tpt.graphics_func(function newfunction, number el_number)</code><br />
<br />
The pixel mode values you can use are:<br />
<pre><br />
PMODE_NONE 0x00000000 --prevents anything from being drawn<br />
PMODE_FLAT 0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.<br />
PMODE_BLOB 0x00000002 --adds a blobby effect, like you were using blob (5) display mode<br />
PMODE_BLUR 0x00000004 --used in liquids in fancy display mode<br />
PMODE_GLOW 0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode<br />
PMODE_SPARK 0x00000010 -- used for things such as GBMB at first, dimmer than other modes<br />
PMODE_FLARE 0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK<br />
PMODE_LFLARE 0x00000040 --brightest spark mode, used when DEST hits something<br />
PMODE_ADD 0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
PMODE_BLEND 0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support<br />
PSPEC_STICKMAN 0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one<br />
<br />
NO_DECO 0x00001000 --prevents decoration from showing on the element (used in LCRY)<br />
DECO_FIRE 0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)<br />
<br />
FIRE_ADD 0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)<br />
FIRE_BLEND 0x00020000 --adds a stronger fire effect around the element, default for gasses<br />
<br />
EFFECT_GRAVIN 0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
EFFECT_GRAVOUT 0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
<br />
</pre><br />
<br />
You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2<br />
<br />
See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html<br />
<br />
=== tpt.screenshot ===<br />
Takes a screenshot of the current screen, minus the menu and HUD.<br />
<br />
<code>tpt.screenshot()<br />
<br />
tpt.screenshot(boolean fullscreen,number screenshot format)</code><br />
<br />
'''Screenshot format''':<br />
<br />
0 - png<br />
<br />
1 - bmp<br />
<br />
2 - ppm<br />
<br />
'''Examples''':<br />
<br />
tpt.screenshot(1,1) - take fullscreen screenshot in bmp format<br />
<br />
tpt.screenshot(1,2) - take fullscreen screenshot in ppm format<br />
<br />
=== tpt.get_clipboard ===<br />
Returns contents of the clipboard.<br />
<br />
<code>tpt.get_clipboard()</code><br />
<br />
=== tpt.set_clipboard ===<br />
Copy to clipboard.<br />
<br />
<code>tpt.set_clipboard(string text)</code><br />
<br />
=== tpt.record ===<br />
Records each drawn frame and saves them all in a unique folder inside a folder called "recordings" in the .ppm format.<br />
<br />
Returns the name of the folder inside the "recordings" folder.<br />
<br />
The record argument if true will start recording and if false will stop recording.<br />
<br />
<code><br />
number tpt.record(boolean record)<br />
</code><br />
<br />
=== tpt.getscript ===<br />
Downloads a script from the script server at [https://starcatcher.us/scripts starcatcher.us] and saves it in the TPT's shared data folder under the provided name.<br />
<br />
Optional argument runScript if 1, will run the file after downloading it. By default it's 0.<br />
<br />
Optional argument confirmPrompt if 1, will prompt the user before downloading the script. By default it's 1.<br />
<br />
<code><br />
tpt.getscript(number scriptID, string filename)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript, number confirmPrompt)<br />
</code><br />
<br />
= Constants =<br />
<br />
All of these constants can be accessed by tpt.<constant name><br />
<br />
=== tpt.selectedl ===<br />
Current element / tool on mouse1<br />
<br />
=== tpt.selectedr ===<br />
Current element / tool on mouse2<br />
<br />
=== tpt.selecteda ===<br />
Current element / tool on mouse3 (middle click)<br />
<br />
=== tpt.selectedreplace ===<br />
Current element to be used in replace mode (green outline)<br />
<br />
=== tpt.brushx ===<br />
Current brush width<br />
<br />
=== tpt.brushy ===<br />
Current brush height<br />
<br />
=== tpt.brushID ===<br />
Current brush ID, 0 = circle, 1 = square, 2 = triangle, higher = custom brushes<br />
<br />
Note that these constants are not read-only so if you run<br />
<pre>tpt.selectedl = "DEFAULT_PT_SPRK"</pre><br />
it will change the element on mouse1 to sprk<br />
<br />
= Simple Example Code =<br />
<pre><br />
-- This line is a comment. Anything written after the -- is considered a Comment and will not be read by Lua.<br />
-- Comment can be multiline, for this you should write it in --[[ and ]]--<br />
-- Set the console's state to 0. This will hide the console.<br />
tpt.set_console(0)<br />
<br />
-- Here we define our main function for the script<br />
local function ClassicPowder()<br />
local ox = 125 -- This will be our offset for the different elements we will create.<br />
local y = 4 -- where on the y (vertical) axis where we will create our elements.<br />
<br />
local x = ox -- where on the x (horizontal) axis where we will create our elements. we will start the x value with what ever ox is above.<br />
for i=0, 10 do -- this is a for loop. everything between the do and end will loop until i hits 10. i increases by 1 every loop.<br />
tpt.create(x + i, y, "STNE") --create a dust particle<br />
end<br />
<br />
x = x + ox -- increase the x axis value by the offset x (ox) value above<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "WATR") --create a water particle<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "SALT")<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "OIL")<br />
end<br />
<br />
return false<br />
end<br />
<br />
-- Register the step function ClassicPowder. This will make the ClassicPowder function run every tick of Powder Toy.<br />
tpt.register_step(ClassicPowder)<br />
</pre><br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Interface&diff=8659Lua API:Interface2022-11-11T20:26:48Z<p>Maticzpl: Fixed type of steps in Slider:new</p>
<hr />
<div>The Interface API includes objects for UI components such as buttons, labels and checkboxes and methods for access to the very primitive window manager and input events.<br />
<br />
== Classes ==<br />
=== Component ===<br />
'''Abstract class, no constructor'''<br />
==== Component:visible ====<br />
boolean Component:visible()<br />
Returns the visibility of the component<br />
<br />
nil Component:visible(boolean visible)<br />
Sets the visibility of the component<br />
<br />
==== Component:size ====<br />
number, number Component:size()<br />
Returns the width and height of the component<br />
<br />
nil Component:size(number width, number height)<br />
Sets the size of the component to be width by height<br />
<br />
==== Component:position ====<br />
number, number Component:position()<br />
Returns the x and y coord of the component<br />
<br />
nil Component:position(number x, number y)<br />
Sets the position of the component to be x, y<br />
<br />
=== Button ===<br />
Button Button:new(number x, number y, number width, number height, [string text = "", [string tooltip = ""]])<br />
Extends Component, fires "action" when clicked<br />
<br />
==== Button:action ====<br />
nil Button:action(function(sender) actionListener)<br />
Sets the listener for button actions<br />
'''Example:'''<br />
<syntaxhighlight lang="lua"><br />
local newButton = Button:new(10, 10, 100, 17, "Press to change text")<br />
newButton:action(function(sender) sender:text("Text changed") end)<br />
interface.addComponent(newButton)<br />
</syntaxhighlight><br />
<br />
==== Button:text ====<br />
string Button:text()<br />
Returns the button text<br />
<br />
nil Button:text(string text)<br />
Sets the text of the button<br />
<br />
==== Button:enabled ====<br />
boolean Button:enabled()<br />
Returns the enabled state of the button<br />
<br />
nil Button:enabled(boolean enabled)<br />
Sets the enabled state of the button<br />
<br />
=== ProgressBar ===<br />
ProgressBar ProgressBar:new(number x, number y, number width, number height, number progress, string status)<br />
Extends Component, used to indicate progress for long running tasks<br />
<br />
==== ProgressBar:progress ====<br />
number ProgressBar:progress()<br />
Returns the progress value<br />
<br />
nil ProgressBar:progress(number progress)<br />
Sets the progress value<br />
<br />
Progress ranges from 0 to 100, but a special case of <tt>-1</tt> will change the behaviour of the progress bar to intermediate (constantly scrolling to indicate progress)<br />
<br />
==== ProgressBar:status ====<br />
string ProgressBar:status()<br />
Returns the progress bar status<br />
<br />
nil ProgressBar:status(string status)<br />
Sets the progress bar status<br />
<br />
Status is simple a text representation of the current action being performed, for example "Working" or just a percentage<br />
<br />
=== Slider ===<br />
Slider Slider:new(number x, number y, number width, number height, [number steps = ""])<br />
Extends Component, fires "onValueChanged" when the value is changed (i.e used by the user)<br />
<br />
==== Slider:onValueChanged ====<br />
nil Slider:onValueChanged(function(sender, value) actionListener)<br />
Sets the listener for slider actions<br />
<br />
==== Slider:value ====<br />
number Slider:value()<br />
Returns the value of the slider<br />
<br />
nil Slider:value(number value)<br />
Sets the value of the slider<br />
<br />
==== Slider:steps ====<br />
number Slider:steps()<br />
Returns the number of steps the slider has<br />
<br />
nil Slider:steps(number steps)<br />
Sets the number of steps for the slider<br />
<br />
=== Checkbox ===<br />
Checkbox Checkbox:new(number x, number y, number width, number height, [string text = ""])<br />
Extends Component, fires "onValueChanged" when the checkbox is checked or unchecked<br />
<br />
==== Checkbox:action ====<br />
nil Checkbox:action(function(sender, checked) actionListener)<br />
Sets the listener for checkbox actions<br />
<br />
==== Checkbox:text ====<br />
string Checkbox:text()<br />
Returns the checkbox text<br />
<br />
nil Checkbox:text(string text)<br />
Sets the text of the checkbox<br />
<br />
==== Checkbox:checked ====<br />
boolean Checkbox:checked()<br />
Returns the checked state of the checkbox<br />
<br />
nil Checkbox:checked(boolean checked)<br />
Sets the checked state of the checkbox<br />
<br />
=== Label ===<br />
Label Label:new(number x, number y, number width, number height, [string text = ""])<br />
Extends Component, is a simple selectable, readonly text field<br />
<br />
==== Label:text ====<br />
string Label:text()<br />
Returns the label text<br />
<br />
nil Label:text(string text)<br />
Sets the text of the label<br />
<br />
=== Textbox ===<br />
Textbox Textbox:new(number x, number y, number width, number height [, string text = "" [, string placeholder = "" ]])<br />
Extends Component, is a text input field, the placeholder text is shown if the component is no focused and contains no text<br />
<br />
==== Textbox:onTextChanged ====<br />
nil Textbox:onTextChanged(function(sender) textChangedListener)<br />
Sets the listener for text changed actions<br />
<br />
==== Textbox:text ====<br />
string Textbox:text()<br />
Returns the text in the field<br />
<br />
nil Textbox:text(string text)<br />
Sets the text of the field<br />
<br />
==== Textbox:readonly ====<br />
boolean Textbox:readonly()<br />
Returns the readonly status of the field.<br />
<br />
nil Textbox:readonly(boolean readonly)<br />
Sets the readonly status of the field.<br />
<br />
=== Window ===<br />
Window Window:new(number x, number y, number width, number height)<br />
A modal form to display components, using -1 for either x or y values will centre the Window on that axis.<br />
<br />
==== Window:addComponent ====<br />
nil Window:addComponent(Component newComponent)<br />
Add a component to the window (The component must not have already been added to another Window object)<br />
<br />
==== Window:removeComponent ====<br />
nil Window:removeComponent(Component newComponent)<br />
Remove a component from the window<br />
<br />
== Methods ==<br />
<br />
=== interface.grabTextInput === <br />
nil interface.grabTextInput()<br />
Signal to the interface engine that textinput events are expected and will be handled (for example, your textbox just gained focus and is ready for such events). Once called, it should not be called again until after calling interface.dropTextInput; see below.<br />
<br />
From the API user's perspective, the grabTextInput-dropTextInput pair implements an on-off switch. The purpose of this switch is to help the interface engine determine when to enter and exit text input state. In this state, the engine asks for OS help with text input (which may or may not involve enabling an Input Method) and delivers textinput events received from the OS to the API user.<br />
<br />
The engine should only enter text input state when the API user expects textinput events (for example, when a textbox is in focus). To correctly communicate this, grabTextInput should be called when processing of textinput events starts and dropTextInput when it ends. Note that textinput events may be delivered regardless of the state of this on-off switch, most likely as a result of another API user calling grabTextInput and dropTextInput.<br />
<br />
=== interface.dropTextInput === <br />
nil interface.dropTextInput()<br />
Signal to the interface engine that textinput events are not expected and will not be handled (for example, your textbox just lost focus and will not handle such events anymore). Once called, it should not be called again until after calling interface.grabTextInput; see above.<br />
<br />
=== interface.addComponent === <br />
nil interface.addComponent(Component newComponent)<br />
Add a component to master game window.<br />
<br />
=== interface.removeComponent === <br />
nil interface.removeComponent(Component newComponent)<br />
Remove a component from the master game window.<br />
<br />
=== interface.showWindow ===<br />
nil interface.showWindow(Window newWindow)<br />
Push a Window into the top of the modal stack<br />
<br />
=== interface.closeWindow ===<br />
nil interface.closeWindow(Window newWindow)<br />
Pop a Window off the top of the modal stack. If the given Window is not the top item in the stack, this will have no effect.<br />
<br />
=== interface.textInputRect ===<br />
nil interface.textInputRect(number x, number y, number w, number h)<br />
Enables composition, for multi-byte unicode characters.<br />
<br />
== Example ==<br />
This code has examples of some of the features of the interface API, it shows a window with various components with some testing behaviour.<br />
<syntaxhighlight lang="lua"><br />
-- Test Window<br />
local testWindow = Window:new(-1, -1, 300, 200)<br />
<br />
local currentY = 10<br />
<br />
--Example label<br />
local testLabel = Label:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "This is a test label")<br />
<br />
--Example button<br />
local buttonPresses = 1<br />
currentY = currentY + 20<br />
local testButton = Button:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "This is a test button")<br />
testButton:enabled(false)<br />
testButton:action(<br />
function(sender)<br />
sender:text("Pressed " .. buttonPresses .. " times")<br />
buttonPresses = buttonPresses + 1<br />
end<br />
)<br />
<br />
--Example Textbox<br />
currentY = currentY + 20<br />
local textboxInfo = Label:new(10+((select(1, testWindow:size())/2)-20), currentY, (select(1, testWindow:size())/2)-20, 16, "0 characters")<br />
local testTextbox = Textbox:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "", "[place text here]")<br />
testTextbox:onTextChanged(<br />
function(sender)<br />
textboxInfo:text(sender:text():len().." characters");<br />
end<br />
)<br />
<br />
--Example Checkbox<br />
currentY = currentY + 20<br />
local testCheckbox = Checkbox:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, "Unchecked");<br />
testCheckbox:action(<br />
function(sender, checked)<br />
if(checked) then<br />
sender:text("Checked")<br />
else<br />
sender:text("Unchecked")<br />
end<br />
testButton:enabled(checked);<br />
end<br />
)<br />
<br />
--Example progress bar<br />
currentY = currentY + 20<br />
local testProgressBar = ProgressBar:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, 0, "Slider: 0");<br />
<br />
--Example slider<br />
currentY = currentY + 20<br />
local testSlider = Slider:new(10, currentY, (select(1, testWindow:size())/2)-20, 16, 10);<br />
testSlider:onValueChanged(<br />
function(sender, value)<br />
testProgressBar:progress(value * 10)<br />
testProgressBar:status("Slider: " .. value)<br />
end<br />
)<br />
<br />
-- Close button<br />
local closeButton = Button:new(10, select(2, testWindow:size())-26, 100, 16, "Close")<br />
<br />
closeButton:action(function() interface.closeWindow(testWindow) end)<br />
<br />
testWindow:onTryExit(function() interface.closeWindow(testWindow) end) -- Allow the default exit events<br />
testWindow:onMouseMove(<br />
function(x, y, dx, dy)<br />
testLabel:text("Mouse: "..x..", "..y)<br />
end<br />
)<br />
<br />
testWindow:addComponent(testLabel)<br />
testWindow:addComponent(testButton)<br />
testWindow:addComponent(testTextbox)<br />
testWindow:addComponent(testCheckbox)<br />
testWindow:addComponent(testProgressBar)<br />
testWindow:addComponent(testSlider)<br />
testWindow:addComponent(textboxInfo)<br />
testWindow:addComponent(closeButton)<br />
<br />
interface.showWindow(testWindow)<br />
</syntaxhighlight><br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua&diff=8658Lua2022-11-11T19:37:22Z<p>Maticzpl: Fix order of display modes under tpt.display_mode</p>
<hr />
<div>{{Languages|Lua}}<br />
<br />
You may open the Lua Console by hitting the ''[`]'' key. (Also known as the tilde ''[~]'' key, or the ''[¬]'' key) [http://www.bittbox.com/wp-content/uploads/2007/12/tilde_illustrator_1.jpg click here to view key]<br />
<br />
----<br />
<br />
You may be used to this style of console commands: ''!set type dust metl''. This can be useful, but Lua is an entire programming language that can do much more powerful things. The equivalent command in TPT's Lua is ''tpt.set_property("type", "metl", "dust")'' (see [[Lua#tpt.set_property]] )<br />
<br />
This page describes the TPT Lua API, not the Lua language itself. But, you may research Lua on your own. If you're a beginner, look at this: http://www.lua.org/pil/ . If more advanced, a list of all the functions is here: http://www.lua.org/manual/5.1/<br />
<br />
Also, FeynmanTechnologies has written a tutorial on some of the most basic Lua features here: https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=17801<br />
<br />
The Lua Console provides the ability to create scripts using Lua, a very simple scripting language. With the ability to script with Lua, users are now able to create simple modifications to the game without editing source code. For information on how to run scripts, see [[Running Lua Scripts]]<br />
<br />
= Lua API =<br />
The Powder Toy exposes the following methods to the Lua API:<br />
<br />
== Game ==<br />
<br />
=== tpt.set_pause ===<br />
<br />
<code>tpt.set_pause(number state)</code><br />
<br />
Sets the paused state of the game. <br />
<br />
The number argument is either 0 or 1, where 1 means the game will be paused, and 0 will unpause the game. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the game is currently paused. <br />
<br />
'''Examples''':<br />
<br />
Pause the game: <code>tpt.set_pause(1)</code><br />
<br />
Get if the game is paused currently: <code>tpt.set_pause() == 1</code><br />
<br />
=== tpt.set_console ===<br />
<br />
<code>tpt.set_console(number state)</code><br />
<br />
Set the visibility state of the console. <br />
<br />
The number argument can be either 0 or 1, where 1 means the console will be opened, and 0 will close the console. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the console is currently opened.<br />
<br />
'''Examples''':<br />
<br />
Open the console: <code>tpt.set_console(1)</code><br />
<br />
Get if the console is currently open: <code>tpt.set_console() == 1</code><br />
<br />
=== tpt.set_shortcuts ===<br />
<br />
'''This function is REMOVED in TPT 94.0'''<br />
<br />
<code>tpt.set_shortcuts(number state)</code><br />
<br />
Set whether one can use keyboard shortcuts such as making a stamp or opening the console or changing view modes. <br />
<br />
The number argument can be either 0 or 1, where 1 means keys will be enabled, and 0 will disable key shortcuts. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether key shortcuts are enabled right now.<br />
<br />
When you want to make a key command which uses some other key, don't use this, rather disable default behavior for that one key only by returning false from inside your callback.<br />
<br />
'''Examples''':<br />
<br />
Disable keyboard shortcuts: <code>tpt.set_shortcuts(0)</code><br />
<br />
Get if keyboard shortcuts are currently disabled: <code>tpt.set_shortcuts(-1) == 1</code><br />
<br />
=== tpt.set_gravity ===<br />
<br />
<code>tpt.set_gravity(number x, number y, number width, number height, number value)</code><br />
<br />
Sets Newtonian Gravity at a position or area to some value. <br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples''':<br />
<br />
Reset gravity in the cell at point (150, 150): <code>tpt.set_gravity(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100,100) to (300,300): <code>tpt.set_gravity(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
Set the entire stage's gravity to 1000: <code>tpt.set_gravity(nil, nil, nil, nil, 1000)</code><br />
<br />
=== tpt.reset_gravity_field ===<br />
<br />
<code>tpt.reset_gravity_field(number x, number y, number width, number height)</code><br />
<br />
Thoroughly resets Newtonian gravity on a given point. <br />
<br />
Instead of tpt.set_gravity which only modifies <code>sim-&gt;gravmap</code>, this code modifies <code>sim->gravp</code>,<code>sim->gravx</code> and <code>sim->gravy</code>. Mmm, gravy.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples''':<br />
<br />
Thoroughly reset gravity in the cell at point (150, 150): <code>tpt.reset_gravity_field(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100, 100) to (300,300): <code>tpt.reset_gravity_field(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
=== tpt.set_pressure ===<br />
<br />
<code>tpt.set_pressure(number x, number y, number width, number height, number value)</code><br />
<br />
Sets or resets pressure in the pressure map to some pressure. I sometimes imagine how much I can repeat the word "pressure" inside a sentence before it becomes gibberish.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples:'''<br />
<br />
Reset pressure everywhere: <code>tpt.set_pressure()</code><br />
<br />
Set pressure of cell at (100, 100) to 200: <code>tpt.set_pressure(100 / sim.CELL, 100 / sim.CELL, 1, 1, 200)</code><br />
<br />
Set pressure everywhere to 200: <code>tpt.set_pressure(nil,nil,nil,nil,200)</code><br />
<br />
=== tpt.reset_velocity ===<br />
<br />
<code>tpt.reset_velocity(number x, number y, number width, number height)</code><br />
<br />
Sets velocity (both x and y) in a given region or point to 0.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples:'''<br />
<br />
Reset velocity everywhere: <code>tpt.reset_velocity()</code><br />
<br />
Reset velocity in the cell at point (100,100): <code>tpt.reset_velocity(100 / sim.CELL, 100 / sim.CELL, 1, 1)</code><br />
<br />
=== tpt.hud ===<br />
<br />
<code>tpt.hud(number state)</code><br />
<br />
Set HUD visibility.<br />
<br />
Does the same thing as pressing the H key normally. The number argument can be either 0 or 1, where 1 will show the HUD, and 0 will hide the HUD. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the HUD is visible right now.<br />
<br />
=== tpt.newtonian_gravity ===<br />
<br />
<code>tpt.newtonian_gravity(number state)</code><br />
<br />
Sets Newtonian Gravity on and off.<br />
<br />
Does the same thing as Ctrl+N in normal gameplay. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable Newtonian Gravity, and 0 will disable Newtonian Gravity. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Newtonian Gravity is turned on at the given moment.<br />
<br />
=== tpt.ambient_heat ===<br />
<br />
<code>tpt.ambient_heat(number state)</code><br />
<br />
Toggles Ambient Heat state.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable Ambient Heat, 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Ambient Heat is turned on at the given moment.<br />
<br />
=== tpt.decorations_enable ===<br />
<br />
<code>tpt.decorations_enable(number state)</code><br />
<br />
Toggle drawing decorations.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable decorations, and 0 will disable them. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether decorations are turned on at the given moment.<br />
<br />
=== tpt.heat ===<br />
<br />
<code>tpt.heat(number state)</code><br />
<br />
Toggles Heat Simulation. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable heat, and 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether heat is turned on at the given moment.<br />
<br />
It's usually wise not to disable this, as there are practically no saves left that need the compatibility mode in order to work. Nevertheless this option exists. <br />
<br />
=== tpt.active_menu ===<br />
<br />
<code>tpt.active_menu(number menu)</code><br />
<br />
Changes activated menu. If you don't pass in any arguments, the command will return the currently active menu.<br />
<br />
The menu IDs are detailed here: [[Element_Properties#Menu_sections]]<br />
<br />
Example: <code>tpt.active_menu(elem.SC_EXPLOSIVE)</code><br />
<br />
=== tpt.menu_enabled ===<br />
<br />
<code><br />
boolean tpt.menu_enabled(number menuID)<br />
<br />
tpt.menu_enabled(number menuID, boolean enabled)<br />
</code><br />
<br />
Returns true if a menu section is enabled. <br />
<br />
If provided a boolean, will set if a menu section is enabled.<br />
<br />
=== tpt.num_menus ===<br />
<br />
<code><br />
number tpt.num_menus()<br />
<br />
number tpt.num_menus(boolean onlyEnabled)<br />
</code><br />
<br />
Returns the number of menus.<br />
<br />
The optional onlyEnabled boolean is true by default.<br />
<br />
=== tpt.display_mode ===<br />
<br />
<code>tpt.display_mode(number display)</code><br />
<br />
Changes activated display mode.<br />
<br />
There's 11 display modes, detailed here [[https://github.com/ThePowderToy/The-Powder-Toy/blob/f54189a97f6d80181deb4f6d952ccf10f0e59ccf/src/graphics/Renderer.cpp#L2587-L2644]]<br><br />
Note that the order of display modes is shifted by 1 making velocity mode first and alternative velocity last.<br />
<br />
'''Display Modes'''<br />
<br />
0 = Velocity<br><br />
1 = Pressure<br><br />
2 = Persistent<br><br />
3 = Fire<br><br />
4 = Blob<br><br />
5 = Heat<br><br />
6 = Fancy<br><br />
7 = Nothing<br><br />
8 = Heat Gradient<br><br />
9 = Life Gradient<br><br />
10 = Alternate Velocity<br><br />
<br />
=== tpt.setfpscap ===<br />
<br />
<code>tpt.setfpscap(number fpscap)</code><br />
<br />
Changes the upper FPS limit the program will run at. This value is '''60 by default.'''<br />
<br />
Don't set it too high, it'll eat all your CPU speed and make the game too responsive! Don't also set it too low, since UI and everything related to it uses the same FPS, so you'll find buttons and stuff not working.<br />
<br />
If you don't pass in any arguments, it will return the current fps cap. If you set the fpscap to 2, this will uncap the framerate.<br />
<br />
=== tpt.setdrawcap ===<br />
<br />
Changes the rate that particle graphics and the UI render to the screen. This is separate from the fpscap, which only affects the simulation. The drawcap allows TPT to skip drawing every frame. This may increase the framerate in some instances.<br />
<br />
The default is set to the maximum refresh rate of all attached monitors.<br />
<br />
=== tpt.setfire ===<br />
Changes the strength of the games glowing effects. tpt.setfire(1) is default.<br />
<br />
<code>tpt.setfire(number strength)</code><br />
<br />
=== tpt.setwindowsize ===<br />
<br />
<code>tpt.setwindowsize(number scale, number fullscreen)</code><br />
<br />
Changes a few special properties as to what size the game renders at.<br />
<br />
Scale is a multiplier by which every pixel shall get multiplied at, currently it can either be 1 (612x384) or 2 (1224x768). <br />
<br />
Full screen is a toggle (0 or 1) that enables "kiosk mode", which basically scales the game up to fill the screen and makes the rest of the edge black.<br />
<br />
=== tpt.toggle_pause ===<br />
Toggle pause.<br />
<br />
<code>tpt.toggle_pause()</code><br />
<br />
=== tpt.watertest ===<br />
'''REPLACED by simulation.waterEqualisation'''<br />
<br />
Toggles water equalization.<br />
Returns current state.<br />
<br />
<code>number tpt.watertest()</code><br />
<br />
=== tpt.perfectCircleBrush ===<br />
Returns true if perfect circle brush is enabled.<br />
<br />
If provided with a boolean, will change if its enabled. <br />
<br />
If perfect circle brush is disabled, the circle brush will have single pixels sticking out on the sides.<br />
<br />
<code><br />
boolean tpt.perfectCircleBrush()<br />
<br />
tpt.perfectCircleBrush(boolean enabled)<br />
</code><br />
<br />
== Particles ==<br />
<br />
=== tpt.reset_spark ===<br />
Removes electrified wires from the simulation, resetting to the original material<br />
<br />
<code>tpt.reset_spark()</code><br />
<br />
=== tpt.set_property ===<br />
Set various properties of particles for given criteria, 8 overloads<br />
<br />
<code><br />
tpt.set_property(string property, object value)<br />
<br />
tpt.set_property(string property, object value, string type)<br />
<br />
tpt.set_property(string property, object value, number index)<br />
<br />
tpt.set_property(string property, object value, number index, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y)<br />
<br />
tpt.set_property(string property, object value, number x, number y, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height, string type)<br />
</code><br />
<br />
=== tpt.set_wallmap ===<br />
Sets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_wallmap(number x, number y, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_wallmap ===<br />
Gets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_wallmap(number x, number y)<br />
</code><br />
<br />
=== tpt.set_elecmap ===<br />
Sets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. The value is decremented by 1 every frame, just like SPRK .life, and when it reaches 0 the wall is "unsparked". Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_elecmap(number x, number y, number walltype)<br />
<br />
tpt.set_elecmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_elecmap ===<br />
Gets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_elecmap(number x, number y)<br />
</code><br />
<br />
=== tpt.get_property ===<br />
Returns various properties of a particle.<br />
<br />
<code><br />
tpt.get_property(string property, number index)<br />
<br />
tpt.get_property(string property, number x, number y)<br />
</code><br />
<br />
=== tpt.create ===<br />
Create a particle at location.<br />
<br />
<code>tpt.create(number x, number y, string type)</code><br />
<br />
Returns the index of the newly created particle.<br />
<br />
=== tpt.delete ===<br />
Delete a specific particle, or location.<br />
<br />
<code><br />
tpt.delete(number index)<br />
<br />
tpt.delete(number x, number y)<br />
</code><br />
<br />
=== tpt.start_getPartIndex ===<br />
Start the iterator for receiving all indices of the particles. (Used to help get particle indices, see tpt.next_getPartIndex)<br />
<br />
<code>tpt.start_getPartIndex()</code><br />
<br />
=== tpt.next_getPartIndex ===<br />
Jump to the next available particle index. Returns false if the iterator has reached the end of all particle indecies. Returns true if a new index was available. (Used to help get particle indecies, see tpt.getPartIndex)<br />
<br />
<code>tpt.next_getPartIndex()</code><br />
<br />
=== tpt.getPartIndex ===<br />
Get the current index iterator.<br />
<br />
<code>tpt.getPartIndex()</code><br />
<br />
index code example:<br />
<pre><br />
tpt.start_getPartIndex()<br />
while tpt.next_getPartIndex() do<br />
local index = tpt.getPartIndex()<br />
if tpt.get_property("ctype",index) == 21 then<br />
tpt.set_property("ctype","sing",index)<br />
end<br />
end<br />
</pre><br />
<br />
These functions are made obsolete by the function sim.parts(). That allows you to use Lua's iterators.<br />
<br />
=== tpt.get_numOfParts ===<br />
Returns the number of particles currently on the screen.<br />
<br />
<code>tpt.get_numOfParts()</code><br />
<br />
A newer way to get this is the variable sim.NUM_PARTS<br />
<br />
== Drawing ==<br />
<br />
=== tpt.textwidth ===<br />
Measures (in pixels) the width of a given string. Returns a number.<br />
<br />
<code>tpt.textwidth(string text)</code><br />
<br />
=== tpt.drawtext ===<br />
Draw text to the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawtext(number x, number y, string text)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.drawpixel ===<br />
Draws a pixel on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawpixel(number x, number y)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawline ===<br />
Draws a line on the screen (for one frame, only useful in scripts), 3 overloads. The line starts at point (x1, y1) and ends at point (x2,y2).<br />
<br />
<code><br />
tpt.drawline(number x1, number y1, number x2, number y2)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawrect ===<br />
Draws a rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawrect(number x, number y, number width, number height)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.fillrect ===<br />
Draws a filled in rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.fillrect(number x, number y, number width, number height)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
Because tpt.fillrect is slightly broken in tpt, the coordinates will be off. It fills the rectangle from (x+1, y+1) to (x+w-1, y+h-1)<br />
<br />
== Input/Output ==<br />
<br />
=== tpt.log ===<br />
Log a message to the console<br />
<br />
<code>tpt.log(string text)</code><br />
<br />
=== tpt.message_box ===<br />
Display an OK-Only message box with a title and message.<br />
<br />
<code>tpt.message_box(string title, string message)</code><br />
<br />
=== tpt.input ===<br />
Ask the user to input some text. Returns a string of what ever the user says. The argument "text" is pre-entered text (optional).<br />
<br />
<code><br />
tpt.input(string title, string message)<br />
<br />
tpt.input(string title, string message, string text)<br />
</code><br />
<br />
=== tpt.throw_error ===<br />
Displays an error message box.<br />
<br />
<code>tpt.throw_error(string text)</code><br />
<br />
=== tpt.confirm ===<br />
Display an confirm message box with a title and message. Returns true if the button with button_name is clicked, returns false if Cancel is clicked.<br />
<br />
<code>tpt.confirm(string title, string message,string button_name)</code><br />
<br />
== Events ==<br />
<br />
The old event api was removed in 94.0, and is only still present through a compatibility script. Please use the new api instead: [[Lua_API:Event|Event]]<br />
<br />
=== tpt.register_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run on every frame<br />
<br />
<code>tpt.register_step(function func)</code><br />
<br />
=== tpt.unregister_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_step(function func)</code><br />
<br />
=== tpt.register_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time the mouse clicks.<br />
<br />
Your function will also be called when the mouse is released or held, or when the mouse wheel is used. Event equals 1 when the mouse gets pressed, 2 when the mouse gets released, and 3 if it is held. If your function returns false, mouse events in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: mousex, mousey, button, event<br />
<br />
<code>tpt.register_mouseclick(function func)</code><br />
<br />
=== tpt.unregister_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_mouseclick(function func)</code><br />
<br />
=== tpt.register_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time a key is pressed.<br />
<br />
Your function will also be called when a key is released. Event equals 1 when a key is pressed, and 2 when it gets released. If your function returns false, key presses in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: key, nkey, modifier, event<br />
<br />
<code>tpt.register_keypress(function func)</code><br />
<br />
=== tpt.unregister_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_keypress(function func)</code><br />
<br />
== Misc ==<br />
<br />
=== tpt.get_name ===<br />
Returns the current username.<br />
<br />
<code>tpt.get_name()</code><br />
<br />
=== tpt.setdebug ===<br />
Sets the "debug mode". It works using bitmasks, so you can turn on multiple debug features at the same time.<br/><br />
Setting 0x1 will display info on the number of particles on the screen.<br/><br />
Setting 0x2 will draw a graph showing the percentages of each type of element on the screen.<br/><br />
Setting 0x4 will display useful information when you draw lines using shift.<br/><br />
Setting 0x8 enables subframe particle debugging. Use alt+f to step one particle at a time. Use shift+f to step up to the particle underneath the mouse. When not over a particle, it advances to the end of the frame.<br />
<br />
<code>tpt.setdebug(number mode)</code><br />
<br />
=== tpt.element ===<br />
Returns an element's number. For example, it would return 28 for dmnd. If passed a number it will return the name instead.<br />
<br />
<code>tpt.element(string elementname)<br />
<br />
tpt.element(number elementid)</code><br />
<br />
=== tpt.element_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Update" instead.<br />
<br />
Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use tpt.element("...") or tpt.el.dust.id for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1. <br />
<br />
newfunction arguments: index, x, y, surround_space, nt<br />
<br />
Returns: return 1 from your function if the particle is killed.<br />
<br />
<code>tpt.element_func(function newfunction, number el_number)<br />
<br />
tpt.element_func(function newfunction, number el_number, number replace)</code><br />
<br />
=== tpt.graphics_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Graphics" instead.<br />
<br />
Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use tpt.el.(name of element to change).id for el_number.<br />
<br />
Function arguments: index, colr, colg, colb<br />
<br />
Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.<br />
<br />
Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.<br />
<br />
colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.<br />
<br />
<code>tpt.graphics_func(function newfunction, number el_number)</code><br />
<br />
The pixel mode values you can use are:<br />
<pre><br />
PMODE_NONE 0x00000000 --prevents anything from being drawn<br />
PMODE_FLAT 0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.<br />
PMODE_BLOB 0x00000002 --adds a blobby effect, like you were using blob (5) display mode<br />
PMODE_BLUR 0x00000004 --used in liquids in fancy display mode<br />
PMODE_GLOW 0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode<br />
PMODE_SPARK 0x00000010 -- used for things such as GBMB at first, dimmer than other modes<br />
PMODE_FLARE 0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK<br />
PMODE_LFLARE 0x00000040 --brightest spark mode, used when DEST hits something<br />
PMODE_ADD 0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
PMODE_BLEND 0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support<br />
PSPEC_STICKMAN 0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one<br />
<br />
NO_DECO 0x00001000 --prevents decoration from showing on the element (used in LCRY)<br />
DECO_FIRE 0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)<br />
<br />
FIRE_ADD 0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)<br />
FIRE_BLEND 0x00020000 --adds a stronger fire effect around the element, default for gasses<br />
<br />
EFFECT_GRAVIN 0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
EFFECT_GRAVOUT 0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
<br />
</pre><br />
<br />
You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2<br />
<br />
See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html<br />
<br />
=== tpt.screenshot ===<br />
Takes a screenshot of the current screen, minus the menu and HUD.<br />
<br />
<code>tpt.screenshot()<br />
<br />
tpt.screenshot(boolean fullscreen,number screenshot format)</code><br />
<br />
'''Screenshot format''':<br />
<br />
0 - png<br />
<br />
1 - bmp<br />
<br />
2 - ppm<br />
<br />
'''Examples''':<br />
<br />
tpt.screenshot(1,1) - take fullscreen screenshot in bmp format<br />
<br />
tpt.screenshot(1,2) - take fullscreen screenshot in ppm format<br />
<br />
=== tpt.get_clipboard ===<br />
Returns contents of the clipboard.<br />
<br />
<code>tpt.get_clipboard()</code><br />
<br />
=== tpt.set_clipboard ===<br />
Copy to clipboard.<br />
<br />
<code>tpt.set_clipboard(string text)</code><br />
<br />
=== tpt.record ===<br />
Records each drawn frame and saves them all in a unique folder inside a folder called "recordings" in the .ppm format.<br />
<br />
Returns the name of the folder inside the "recordings" folder.<br />
<br />
The record argument if true will start recording and if false will stop recording.<br />
<br />
<code><br />
number tpt.record(boolean record)<br />
</code><br />
<br />
=== tpt.getscript ===<br />
Downloads a script from the script server at [https://starcatcher.us/scripts starcatcher.us] and saves it in the TPT's shared data folder under the provided name.<br />
<br />
Optional argument runScript if 1, will run the file after downloading it. By default it's 0.<br />
<br />
Optional argument confirmPrompt if 1, will prompt the user before downloading the script. By default it's 1.<br />
<br />
<code><br />
tpt.getscript(number scriptID, string filename)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript, number confirmPrompt)<br />
</code><br />
<br />
= Constants =<br />
<br />
All of these constants can be accessed by tpt.<constant name><br />
<br />
=== tpt.selectedl ===<br />
Current element / tool on mouse1<br />
<br />
=== tpt.selectedr ===<br />
Current element / tool on mouse2<br />
<br />
=== tpt.selecteda ===<br />
Current element / tool on mouse3 (middle click)<br />
<br />
=== tpt.selectedreplace ===<br />
Current element to be used in replace mode (green outline)<br />
<br />
=== tpt.brushx ===<br />
Current brush width<br />
<br />
=== tpt.brushy ===<br />
Current brush height<br />
<br />
=== tpt.brushID ===<br />
Current brush ID, 0 = circle, 1 = square, 2 = triangle, higher = custom brushes<br />
<br />
Note that these constants are not read-only so if you run<br />
<pre>tpt.selectedl = "DEFAULT_PT_SPRK"</pre><br />
it will change the element on mouse1 to sprk<br />
<br />
= Simple Example Code =<br />
<pre><br />
-- This line is a comment. Anything written after the -- is considered a Comment and will not be read by Lua.<br />
-- Comment can be multiline, for this you should write it in --[[ and ]]--<br />
-- Set the console's state to 0. This will hide the console.<br />
tpt.set_console(0)<br />
<br />
-- Here we define our main function for the script<br />
local function ClassicPowder()<br />
local ox = 125 -- This will be our offset for the different elements we will create.<br />
local y = 4 -- where on the y (vertical) axis where we will create our elements.<br />
<br />
local x = ox -- where on the x (horizontal) axis where we will create our elements. we will start the x value with what ever ox is above.<br />
for i=0, 10 do -- this is a for loop. everything between the do and end will loop until i hits 10. i increases by 1 every loop.<br />
tpt.create(x + i, y, "STNE") --create a dust particle<br />
end<br />
<br />
x = x + ox -- increase the x axis value by the offset x (ox) value above<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "WATR") --create a water particle<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "SALT")<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "OIL")<br />
end<br />
<br />
return false<br />
end<br />
<br />
-- Register the step function ClassicPowder. This will make the ClassicPowder function run every tick of Powder Toy.<br />
tpt.register_step(ClassicPowder)<br />
</pre><br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Simulation&diff=8601Lua API:Simulation2022-10-03T18:29:42Z<p>Maticzpl: Added sim.brush and sim.replaceModeFlags</p>
<hr />
<div>The Simulation API allows for modifying the state and properties of particles, air and gravity<br />
<br />
== Methods ==<br />
<br />
=== simulation.addCustomGol ===<br />
nil sim.addCustomGol(string rule, string name, number color1, number color2)<br />
Adds a custom game of life type with the specified rule, name, and colors. Rule strings use B#/S#/# notation ([https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Variations more detail]). Colors are used when fading between multiple states. Names and rules cannot be duplicates.<br />
<br />
nil sim.addCustomGol(number rule, string name, number color1, number color2)<br />
Same as above, but takes a binary representation of the rule instead of a string. Bits 0-8 list stay values (starting at 0), bits 9-16 list begin values (starting at 1), and bits 17-20 are the number of states (decimal value added to 2). This is also how GOL rules are stored as ctypes.<br />
<br />
=== simulation.adjustCoords ===<br />
number, number sim.adjustCoords(number x, number y)<br />
Actually this is more of a UI method than a simulation method. Given a mouse position x, y in the window, this function returns the corresponding coordinates in the simulation (taking into account the visibility and position of the zoom window, if applicable). <br />
<br />
=== simulation.airMode ===<br />
number sim.airMode()<br />
Returns the current Air Simulation Mode.<br />
<br />
nil sim.airMode(number mode)<br />
Sets the Air Simulation Mode to mode.<br />
<br />
Mode numbers are as follows (not currently available as named constants):<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal<br />
|-<br />
|1<br />
|Pressure off<br />
|-<br />
|2<br />
|Velocity off<br />
|-<br />
|3<br />
|Velocity and pressure off<br />
|-<br />
|4<br />
|No update<br />
|}<br />
<br />
=== simulation.ambientAirTemp ===<br />
number sim.ambientAirTemp()<br />
Returns the current ambient temperature. When ambient heat mode is turned on, the air at the edges of the screen will remain at this temperature. <br />
<br />
nil sim.ambientAirTemp(number temp)<br />
Sets the ambient temperature. The temperature is measured in Kelvin. <br />
<br />
=== simulation.ambientHeat ===<br />
number sim.ambientHeat(number x, number y)<br />
Returns a value on the ambient heat map (the temperature of the air at that point). <br />
<br />
nil sim.ambientHeat(number x, number y, number temp, [number width, number height])<br />
Sets values on the ambient heat map. <br />
<br />
=== simulation.brush ===<br />
function sim.brush(number x, number y, [number brushWidth, number brushHeight], [number brushID])<br />
Returns an iterator over positions inside the specified brush.<br />
<br />
If width, height or ID is not provided, will use values of the current brush selected by user.<br />
<br />
Example:<br />
for x, y in sim.brush(300, 200, 100, 50, 0) do<br />
sim.partCreate(-1, x, y, elem.DEFAULT_PT_DUST)<br />
end<br />
<br />
=== simulation.can_move ===<br />
simulation.can_move(number movingElementID, number obstacleElementID, number method)<br />
Decides what a particle does when it hits another particle while moving. Method is one of the following:<br />
* 0: bounce off the obstacle<br />
* 1: swap places with the obstacle<br />
* 2: move over the obstacle<br />
<br />
number simulation.can_move(number movingElementID, number obstacleElementID)<br />
Returns what a particle does when it hits another particle while moving, a method like above.<br />
<br />
=== simulation.clearRect ===<br />
nil sim.clearRect(number x, number y, number width, number height)<br />
Clears all particles in a rectangle starting at x, y down and to the right width and height pixels respectively.<br />
<br />
=== simulation.clearSim ===<br />
nil sim.clearSim()<br />
Clears everything in the simulation.<br />
<br />
=== simulation.createBox ===<br />
nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])<br />
Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createLine ===<br />
nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])<br />
Creates a line of of either the user's currently selected type or the type specified at the specified coordinates.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createParts ===<br />
number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])<br />
Does something.<br />
<br />
=== simulation.createWallBox ===<br />
nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])<br />
Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWallLine ===<br />
nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])<br />
Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWalls ===<br />
number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])<br />
Does something<br />
<br />
=== simulation.decoBox ===<br />
nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])<br />
Changes the decoration color of all particles in the specified coordinates.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoBrush ===<br />
nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Does something<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoColor ===<br />
number sim.decoColor()<br />
Returns the currently selected decoration color.<br />
<br />
nil sim.decoColor(number color)<br />
Sets the selected decoration color to color.<br />
color is in the format 0xAARRGGBB<br />
<br />
nil sim.decoColor(number r, number g, number b, [number a])<br />
Sets the selected decoration color to r,g,b,a<br />
<br />
=== simulation.decoColour ===<br />
Same as sim.decoColor()<br />
<br />
=== simulation.decoLine ===<br />
nil sim.decoLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Changes the decoration color of all particles in the line specified.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.deleteStamp ===<br />
type sim.deleteStamp(string name)<br />
Deleting a stamp identified by filename or ID.<br />
<br />
=== simulation.edgeMode ===<br />
number sim.edgeMode()<br />
Returns the current Edge Mode<br />
<br />
nil sim.edgeMode(number mode)<br />
Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation. <br />
<br />
=== simulation.elementCount ===<br />
number sim.elementCount(number type)<br />
Returns the number of particles of the specified type in the simulation.<br />
<br />
=== simulation.floodDeco ===<br />
nil sim.floodDeco(number x, number y, number r, number g, number b, number a)<br />
Flood fills the color at position x, y with another color. Note: Color at position includes console overlay.<br />
<br />
=== simulation.floodParts ===<br />
number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])<br />
Flood fills either the user's currently selected type or the type specified at the coordinates given.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.floodWalls ===<br />
number sim.floodWalls(number x, number y, [number walltype], [number bm?])<br />
Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.framerender ===<br />
number sim.framerender()<br />
sim.framerender(number frames)<br />
Advances the simulation the given number of frames, even when paused. If called with no arguments, returns the number of frames currently to be rendered. Usually is 0.<br />
<br />
=== simulation.getSaveID ===<br />
number, number sim.getSaveID()<br />
Returns the save ID and the history offset of the currently loaded save or nil if the simulation is not a downloaded save. The history offset can be used with loadSave.<br />
<br />
=== simulation.gravMap ===<br />
number sim.gravMap(number x, number y)<br />
nil sim.gravMap(number x, number y, [number width, number height, [number value]])<br />
Returns the newtonian gravity at the given coordinates in the simulation. If given a value, will set the newtonian gravity at those coordinates. Width and height refer to the rectangle of affected cells, starting with the coords. If not given, they will default to 1,1.<br />
<br />
=== simulation.gravityGrid ===<br />
number sim.gravityGrid()<br />
Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.<br />
<br />
nil sim.gravityGrid(number mode)<br />
Sets the setting for drawing the gravity grid to mode.<br />
<br />
=== simulation.gravityMode ===<br />
number sim.gravityMode()<br />
Returns the current gravity simulation mode.<br />
<br />
nil sim.gravityMode(number mode)<br />
Sets the gravity simulation mode to mode.<br />
<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal, vertical gravity<br />
|-<br />
|1<br />
|No gravity<br />
|-<br />
|2<br />
|Radial gravity<br />
|}<br />
<br />
=== simulation.gspeed ===<br />
number sim.gspeed()<br />
Returns the current GoL speed<br />
<br />
nil sim.gspeed(number newSpeed)<br />
Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.<br />
<br />
=== simulation.listCustomGol ===<br />
table sim.listCustomGol()<br />
Returns a table of all custom game of life types. Each index has a name (string), rulestr (string), rule (number), color1 (number), and color2 (number) property. See [[#simulation.addCustomGol|sim.addCustomGol]] for details about properties.<br />
<br />
=== simulation.loadSave ===<br />
nil sim.loadSave(number SaveID, [number hideDescription], [number history?])<br />
Loads the save associated with the specified SaveID.<br />
If hideDescription is non zero, the information for the save is not shown.<br />
<br />
=== simulation.loadStamp ===<br />
sim.loadStamp(string filename, number x, number y)<br />
sim.loadStamp(number id, number x, number y)<br />
Loads a stamp identified by filename or ID, and places it at position x,y. Filenames should be given without stamps/ or the .stm suffix. On success, returns 1. On failure, returns nil and the failure reason as a string.<br />
<br />
=== simulation.neighbors ===<br />
type sim.neighbors(number x, number y, [number rx], [number ry], [number type])<br />
Used for iterating through particles in an area centred on the given coordinates (x, y). Radius in the x and y directions is set by rx and ry. Default radius is 2, 2. If type is provided, only particles of the corresponding type will be returned.<br />
<br />
The size of the rectangular area is one plus twice the radius, so a radius of 2, 2 gives a 5x5 pixel area centred on x, y. Particles in the centre position x, y are excluded. Only one particle in each position is included, and energy particles (such as photons, neutrons, electrons) are ignored.<br />
<br />
Example (i is the index of the neighbouring particle and nx, ny are its coordinates):<br />
<syntaxhighlight lang="lua"><br />
for i,nx,ny in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
Or if coordinates of the neighbouring particles are not required:<br />
<syntaxhighlight lang="lua"><br />
for i in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.neighbours ===<br />
Same as sim.neighbors()<br />
<br />
=== simulation.partChangeType ===<br />
nil sim.partChangeType(number index, number type)<br />
Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.<br />
<br />
=== simulation.partCreate ===<br />
number sim.partCreate(number index, number x, number y, number type)<br />
Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure. <br />
<br />
Possible values for index are:<br />
<br />
* -1 : Normal particle creation. This is the most useful value. No particle is created if position x, y is occupied and the requested new particle type cannot pass through the particle that is already there.<br />
* -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.<br />
* -3 : Create particle without checking for collisions with existing particles. In most cases, this is a bad idea, since a lot of elements don't work properly when there are multiple particles in the same place. Particles may also turn into BHOL if there are too many in the same place. The exception to this is elements that have been specifically designed to cope with this (such as multiple energy particles like PHOT and NEUT in the same place). <br />
* particle index, >= 0 : Overwrite an existing particle with a new particle. At the moment no collision checking is performed, so the same considerations apply as for index=-3. It is usually safe if the new particle is in the same location as the old one. This is roughly equivalent to calling sim.partKill then sim.partCreate(-3, ...).<br />
<br />
=== simulation.partExists ===<br />
boolean sim.partExists(number index)<br />
Returns true if a particle exists at a given index.<br />
<br />
=== simulation.partID ===<br />
number sim.partID(number x, number y)<br />
Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.<br />
<br />
Example (though this is probably best done with sim.neighbours):<br />
<syntaxhighlight lang="lua"><br />
for fx = -1, 1, 1 do<br />
for fy = -1, 1, 1 do<br />
local i = sim.partID(x + fx, y + fy)<br />
if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then<br />
sim.partProperty(index, sim.FIELD_TEMP, 9999)<br />
end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.partKill ===<br />
nil sim.partKill(number index)<br />
nil sim.partKill(number x, number y)<br />
Reliably delete a particle at a specified index or location, this method avoids the side effects created by changing the type to 0/DEFAULT_PT_NONE with the "partProperty" method<br />
<br />
=== simulation.partNeighbors ===<br />
table sim.partNeighbours(number x, number y, number radius, [number type])<br />
Returns an array of indices of particles that neighbour the given coordinates and match the given type (if it is specified). The resulting array does not contain the particle at the specified position.<br />
<br />
=== simulation.partNeighbours ===<br />
Same as sim.partNeighbors()<br />
<br />
=== simulation.partPosition ===<br />
number x, number y sim.partPosition(number index)<br />
Get the location of the particle at the specified index <br />
<br />
=== simulation.partProperty ===<br />
nil sim.partProperty(number index, object field, object value)<br />
Set the property value on a particle specified by index<br />
<br />
object sim.partProperty(number index, object field)<br />
Get the property value on a particle specified by the index<br />
<br />
The "field" may be a field name or field ID, see FIELD constants below for valid fields.<br />
<br />
=== simulation.parts ===<br />
function sim.parts()<br />
Returns an iterator over particle indexes that can be used in lua for loops<br />
<br />
=== simulation.pmap ===<br />
number sim.pmap(number x, number y)<br />
Get the index of the particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.partID, but excludes energy particles (such as PHOT, NEUT, ELEC).<br />
<br />
=== simulation.photons ===<br />
number sim.photons(number x, number y)<br />
Get the index of the energy particle at the specified position. Returns nil if there is no particle there. This function is very similar to sim.pmap<br />
<br />
=== simulation.pressure ===<br />
number sim.pressure(number x, number y)<br />
Returns a value on the pressure map.<br />
<br />
nil sim.pressure(number x, number y, number pressure, [number width, number height])<br />
Sets values on the pressure map.<br />
<br />
=== simulation.prettyPowders ===<br />
number sim.prettyPowders()<br />
nil sim.prettyPowders(mode)<br />
Sets whether the "pretty powders mode" (powders, such as SAND or BCOL, will be assigned random deco values) is on or off. When called with no arguments, returns a value determining whether it is on or off.<br />
<br />
=== simulation.reloadSave ===<br />
nil sim.reloadSave()<br />
Reloading save.<br />
<br />
=== simulation.removeCustomGol ===<br />
boolean sim.removeCustomGol(string name)<br />
Removes all custom game of life types with the specified name. Returns true if any were removed.<br />
<br />
=== simulation.resetPressure ===<br />
nil sim.resetPressure()<br />
Resets the pressure map to no pressure.<br />
<br />
=== simulation.resetTemp ===<br />
nil sim.resetTemp()<br />
Resets the temperature of all particles to their spawn temperature.<br />
<br />
=== simulation.replaceModeFlags ===<br />
number sim.replaceModeFlags()<br />
Returns the current replace mode flags.<br />
nil sim.replaceModeFlags(number flags)<br />
Sets the replace mode flags.<br />
<br />
If the first bit of that number is set (flags = 1), replace mode is enabled.<br />
<br />
If the second bit is set (flags = 2), specific delete is enabled.<br />
<br />
=== simulation.saveStamp ===<br />
string sim.saveStamp([number x, number y, number width, number height])<br />
Creates a stamp of the specified coordinates. Coordinates default to entire simulation.<br />
Returns the stamp id created.<br />
<br />
=== simulation.signs ===<br />
table simulation.signs<br />
A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.<br />
<br />
==== simulation.signs[n] ====<br />
table simulation.signs[n]<br />
A table which always contains the id property. May also contain text, x, y and justification. These properties can be directly modified to change a sign.<br />
A justification of 0 means left, 1 means right, 2 means middle and 3 means none.<br />
The text property cannot be larger than 45 in length.<br />
<br />
==== simulation.signs.delete ====<br />
nil simulation.signs.delete(number signID)<br />
Deletes the sign at the specified sign id.<br />
<br />
==== simulation.signs.new ====<br />
number simulation.signs.new([string text, number x, number y, number justification])<br />
Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).<br />
<br />
=== simulation.takeSnapshot ===<br />
nil sim.takeSnapshot()<br />
Takes a undo snapshot, for use with ctrl + z<br />
<br />
=== simulation.toolBox ===<br />
type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])<br />
Does something<br />
<br />
=== simulation.toolBrush ===<br />
number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) on the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.toolLine ===<br />
type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Does something<br />
<br />
=== simulation.velocityX ===<br />
number sim.velocityX(number x, number y)<br />
Returns an X value on the velocity map.<br />
<br />
nil sim.velocityX(number x, number y, [number value], [number width, number height])<br />
Sets X values on the velocity map.<br />
<br />
=== simulation.velocityY ===<br />
number sim.velocityY(number x, number y)<br />
Returns an Y value on the velocity map.<br />
<br />
nil sim.velocityY(number x, number y, [number value], [number width, number height])<br />
Sets Y values on the velocity map.<br />
<br />
=== simulation.waterEqualisation ===<br />
number sim.waterEqualisation()<br />
Returns the current Water equalisation setting.<br />
<br />
nil sim.waterEqualisation(number setting)<br />
Set the Water equalisation setting to setting.<br />
<br />
=== simulation.waterEqualization ===<br />
Same as sim.waterEqualisation()<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with simulation.<constant name here><br />
<br />
=== DECO ===<br />
; DECO_DIVIDE<br />
; DECO_SMUDGE<br />
; DECO_ADD<br />
; DECO_SUBTRACT<br />
; DECO_CLEAR<br />
; DECO_DRAW<br />
; DECO_MULTIPLY<br />
<br />
=== FIELD ===<br />
; FIELD_DCOLOUR<br />
; FIELD_Y<br />
; FIELD_TEMP<br />
; FIELD_TYPE<br />
; FIELD_VY<br />
; FIELD_X<br />
; FIELD_TMP2<br />
; FIELD_TMP<br />
; FIELD_FLAGS<br />
; FIELD_VX<br />
; FIELD_CTYPE<br />
; FIELD_LIFE<br />
<br />
=== MAX ===<br />
; MAX_TEMP<br />
<br />
=== MIN ===<br />
; MIN_TEMP<br />
<br />
=== NUM ===<br />
; NUM_PARTS<br />
<br />
=== PT ===<br />
; PT_NUM<br />
<br />
=== R ===<br />
; R_TEMP<br />
<br />
=== TOOL ===<br />
; TOOL_VAC<br />
; TOOL_AIR<br />
; TOOL_NGRV<br />
; TOOL_PGRV<br />
; TOOL_HEAT<br />
; TOOL_WIND<br />
; TOOL_COOL<br />
<br />
=== Uncategorized ===<br />
; YRES<br />
; XRES<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua&diff=8600Lua2022-10-02T20:20:26Z<p>Maticzpl: Added tpt.watertest and tpt.perfectCircleBrush</p>
<hr />
<div>{{Languages|Lua}}<br />
<br />
You may open the Lua Console by hitting the ''[`]'' key. (Also known as the tilde ''[~]'' key, or the ''[¬]'' key) [http://www.bittbox.com/wp-content/uploads/2007/12/tilde_illustrator_1.jpg click here to view key]<br />
<br />
----<br />
<br />
You may be used to this style of console commands: ''!set type dust metl''. This can be useful, but Lua is an entire programming language that can do much more powerful things. The equivalent command in TPT's Lua is ''tpt.set_property("type", "metl", "dust")'' (see [[Lua#tpt.set_property]] )<br />
<br />
This page describes the TPT Lua API, not the Lua language itself. But, you may research Lua on your own. If you're a beginner, look at this: http://www.lua.org/pil/ . If more advanced, a list of all the functions is here: http://www.lua.org/manual/5.1/<br />
<br />
Also, FeynmanTechnologies has written a tutorial on some of the most basic Lua features here: https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=17801<br />
<br />
The Lua Console provides the ability to create scripts using Lua, a very simple scripting language. With the ability to script with Lua, users are now able to create simple modifications to the game without editing source code. For information on how to run scripts, see [[Running Lua Scripts]]<br />
<br />
= Lua API =<br />
The Powder Toy exposes the following methods to the Lua API:<br />
<br />
== Game ==<br />
<br />
=== tpt.set_pause ===<br />
<br />
<code>tpt.set_pause(number state)</code><br />
<br />
Sets the paused state of the game. <br />
<br />
The number argument is either 0 or 1, where 1 means the game will be paused, and 0 will unpause the game. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the game is currently paused. <br />
<br />
'''Examples''':<br />
<br />
Pause the game: <code>tpt.set_pause(1)</code><br />
<br />
Get if the game is paused currently: <code>tpt.set_pause() == 1</code><br />
<br />
=== tpt.set_console ===<br />
<br />
<code>tpt.set_console(number state)</code><br />
<br />
Set the visibility state of the console. <br />
<br />
The number argument can be either 0 or 1, where 1 means the console will be opened, and 0 will close the console. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the console is currently opened.<br />
<br />
'''Examples''':<br />
<br />
Open the console: <code>tpt.set_console(1)</code><br />
<br />
Get if the console is currently open: <code>tpt.set_console() == 1</code><br />
<br />
=== tpt.set_shortcuts ===<br />
<br />
'''This function is REMOVED in TPT 94.0'''<br />
<br />
<code>tpt.set_shortcuts(number state)</code><br />
<br />
Set whether one can use keyboard shortcuts such as making a stamp or opening the console or changing view modes. <br />
<br />
The number argument can be either 0 or 1, where 1 means keys will be enabled, and 0 will disable key shortcuts. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether key shortcuts are enabled right now.<br />
<br />
When you want to make a key command which uses some other key, don't use this, rather disable default behavior for that one key only by returning false from inside your callback.<br />
<br />
'''Examples''':<br />
<br />
Disable keyboard shortcuts: <code>tpt.set_shortcuts(0)</code><br />
<br />
Get if keyboard shortcuts are currently disabled: <code>tpt.set_shortcuts(-1) == 1</code><br />
<br />
=== tpt.set_gravity ===<br />
<br />
<code>tpt.set_gravity(number x, number y, number width, number height, number value)</code><br />
<br />
Sets Newtonian Gravity at a position or area to some value. <br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples''':<br />
<br />
Reset gravity in the cell at point (150, 150): <code>tpt.set_gravity(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100,100) to (300,300): <code>tpt.set_gravity(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
Set the entire stage's gravity to 1000: <code>tpt.set_gravity(nil, nil, nil, nil, 1000)</code><br />
<br />
=== tpt.reset_gravity_field ===<br />
<br />
<code>tpt.reset_gravity_field(number x, number y, number width, number height)</code><br />
<br />
Thoroughly resets Newtonian gravity on a given point. <br />
<br />
Instead of tpt.set_gravity which only modifies <code>sim-&gt;gravmap</code>, this code modifies <code>sim->gravp</code>,<code>sim->gravx</code> and <code>sim->gravy</code>. Mmm, gravy.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples''':<br />
<br />
Thoroughly reset gravity in the cell at point (150, 150): <code>tpt.reset_gravity_field(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100, 100) to (300,300): <code>tpt.reset_gravity_field(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
=== tpt.set_pressure ===<br />
<br />
<code>tpt.set_pressure(number x, number y, number width, number height, number value)</code><br />
<br />
Sets or resets pressure in the pressure map to some pressure. I sometimes imagine how much I can repeat the word "pressure" inside a sentence before it becomes gibberish.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples:'''<br />
<br />
Reset pressure everywhere: <code>tpt.set_pressure()</code><br />
<br />
Set pressure of cell at (100, 100) to 200: <code>tpt.set_pressure(100 / sim.CELL, 100 / sim.CELL, 1, 1, 200)</code><br />
<br />
Set pressure everywhere to 200: <code>tpt.set_pressure(nil,nil,nil,nil,200)</code><br />
<br />
=== tpt.reset_velocity ===<br />
<br />
<code>tpt.reset_velocity(number x, number y, number width, number height)</code><br />
<br />
Sets velocity (both x and y) in a given region or point to 0.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples:'''<br />
<br />
Reset velocity everywhere: <code>tpt.reset_velocity()</code><br />
<br />
Reset velocity in the cell at point (100,100): <code>tpt.reset_velocity(100 / sim.CELL, 100 / sim.CELL, 1, 1)</code><br />
<br />
=== tpt.hud ===<br />
<br />
<code>tpt.hud(number state)</code><br />
<br />
Set HUD visibility.<br />
<br />
Does the same thing as pressing the H key normally. The number argument can be either 0 or 1, where 1 will show the HUD, and 0 will hide the HUD. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the HUD is visible right now.<br />
<br />
=== tpt.newtonian_gravity ===<br />
<br />
<code>tpt.newtonian_gravity(number state)</code><br />
<br />
Sets Newtonian Gravity on and off.<br />
<br />
Does the same thing as Ctrl+N in normal gameplay. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable Newtonian Gravity, and 0 will disable Newtonian Gravity. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Newtonian Gravity is turned on at the given moment.<br />
<br />
=== tpt.ambient_heat ===<br />
<br />
<code>tpt.ambient_heat(number state)</code><br />
<br />
Toggles Ambient Heat state.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable Ambient Heat, 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Ambient Heat is turned on at the given moment.<br />
<br />
=== tpt.decorations_enable ===<br />
<br />
<code>tpt.decorations_enable(number state)</code><br />
<br />
Toggle drawing decorations.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable decorations, and 0 will disable them. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether decorations are turned on at the given moment.<br />
<br />
=== tpt.heat ===<br />
<br />
<code>tpt.heat(number state)</code><br />
<br />
Toggles Heat Simulation. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable heat, and 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether heat is turned on at the given moment.<br />
<br />
It's usually wise not to disable this, as there are practically no saves left that need the compatibility mode in order to work. Nevertheless this option exists. <br />
<br />
=== tpt.active_menu ===<br />
<br />
<code>tpt.active_menu(number menu)</code><br />
<br />
Changes activated menu. If you don't pass in any arguments, the command will return the currently active menu.<br />
<br />
The menu IDs are detailed here: [[Element_Properties#Menu_sections]]<br />
<br />
Example: <code>tpt.active_menu(elem.SC_EXPLOSIVE)</code><br />
<br />
=== tpt.menu_enabled ===<br />
<br />
<code><br />
boolean tpt.menu_enabled(number menuID)<br />
<br />
tpt.menu_enabled(number menuID, boolean enabled)<br />
</code><br />
<br />
Returns true if a menu section is enabled. <br />
<br />
If provided a boolean, will set if a menu section is enabled.<br />
<br />
=== tpt.num_menus ===<br />
<br />
<code><br />
number tpt.num_menus()<br />
<br />
number tpt.num_menus(boolean onlyEnabled)<br />
</code><br />
<br />
Returns the number of menus.<br />
<br />
The optional onlyEnabled boolean is true by default.<br />
<br />
=== tpt.display_mode ===<br />
<br />
<code>tpt.display_mode(number display)</code><br />
<br />
Changes activated display mode.<br />
<br />
There's 11 display modes, detailed here [[https://github.com/ThePowderToy/The-Powder-Toy/blob/f54189a97f6d80181deb4f6d952ccf10f0e59ccf/src/graphics/Renderer.cpp#L2587-L2644]], but I'll provide a reference below: <br />
<br />
'''Display Modes'''<br />
<br />
0 = Alternate Velocity<br><br />
1 = Velocity<br><br />
2 = Pressure<br><br />
3 = Persistent<br><br />
4 = Fire<br><br />
5 = Blob<br><br />
6 = Heat<br><br />
7 = Fancy<br><br />
8 = Nothing<br><br />
9 = Heat Gradient<br><br />
10 = Life Gradient<br><br />
<br />
=== tpt.setfpscap ===<br />
<br />
<code>tpt.setfpscap(number fpscap)</code><br />
<br />
Changes the upper FPS limit the program will run at. This value is '''60 by default.'''<br />
<br />
Don't set it too high, it'll eat all your CPU speed and make the game too responsive! Don't also set it too low, since UI and everything related to it uses the same FPS, so you'll find buttons and stuff not working.<br />
<br />
If you don't pass in any arguments, it will return the current fps cap. If you set the fpscap to 2, this will uncap the framerate.<br />
<br />
=== tpt.setdrawcap ===<br />
<br />
Changes the rate that particle graphics and the UI render to the screen. This is separate from the fpscap, which only affects the simulation. The drawcap allows TPT to skip drawing every frame. This may increase the framerate in some instances.<br />
<br />
The default is set to the maximum refresh rate of all attached monitors.<br />
<br />
=== tpt.setfire ===<br />
Changes the strength of the games glowing effects. tpt.setfire(1) is default.<br />
<br />
<code>tpt.setfire(number strength)</code><br />
<br />
=== tpt.setwindowsize ===<br />
<br />
<code>tpt.setwindowsize(number scale, number fullscreen)</code><br />
<br />
Changes a few special properties as to what size the game renders at.<br />
<br />
Scale is a multiplier by which every pixel shall get multiplied at, currently it can either be 1 (612x384) or 2 (1224x768). <br />
<br />
Full screen is a toggle (0 or 1) that enables "kiosk mode", which basically scales the game up to fill the screen and makes the rest of the edge black.<br />
<br />
=== tpt.toggle_pause ===<br />
Toggle pause.<br />
<br />
<code>tpt.toggle_pause()</code><br />
<br />
=== tpt.watertest ===<br />
'''REPLACED by simulation.waterEqualisation'''<br />
<br />
Toggles water equalization.<br />
Returns current state.<br />
<br />
<code>number tpt.watertest()</code><br />
<br />
=== tpt.perfectCircleBrush ===<br />
Returns true if perfect circle brush is enabled.<br />
<br />
If provided with a boolean, will change if its enabled. <br />
<br />
If perfect circle brush is disabled, the circle brush will have single pixels sticking out on the sides.<br />
<br />
<code><br />
boolean tpt.perfectCircleBrush()<br />
<br />
tpt.perfectCircleBrush(boolean enabled)<br />
</code><br />
<br />
== Particles ==<br />
<br />
=== tpt.reset_spark ===<br />
Removes electrified wires from the simulation, resetting to the original material<br />
<br />
<code>tpt.reset_spark()</code><br />
<br />
=== tpt.set_property ===<br />
Set various properties of particles for given criteria, 8 overloads<br />
<br />
<code><br />
tpt.set_property(string property, object value)<br />
<br />
tpt.set_property(string property, object value, string type)<br />
<br />
tpt.set_property(string property, object value, number index)<br />
<br />
tpt.set_property(string property, object value, number index, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y)<br />
<br />
tpt.set_property(string property, object value, number x, number y, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height, string type)<br />
</code><br />
<br />
=== tpt.set_wallmap ===<br />
Sets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_wallmap(number x, number y, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_wallmap ===<br />
Gets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_wallmap(number x, number y)<br />
</code><br />
<br />
=== tpt.set_elecmap ===<br />
Sets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. The value is decremented by 1 every frame, just like SPRK .life, and when it reaches 0 the wall is "unsparked". Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_elecmap(number x, number y, number walltype)<br />
<br />
tpt.set_elecmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_elecmap ===<br />
Gets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_elecmap(number x, number y)<br />
</code><br />
<br />
=== tpt.get_property ===<br />
Returns various properties of a particle.<br />
<br />
<code><br />
tpt.get_property(string property, number index)<br />
<br />
tpt.get_property(string property, number x, number y)<br />
</code><br />
<br />
=== tpt.create ===<br />
Create a particle at location.<br />
<br />
<code>tpt.create(number x, number y, string type)</code><br />
<br />
Returns the index of the newly created particle.<br />
<br />
=== tpt.delete ===<br />
Delete a specific particle, or location.<br />
<br />
<code><br />
tpt.delete(number index)<br />
<br />
tpt.delete(number x, number y)<br />
</code><br />
<br />
=== tpt.start_getPartIndex ===<br />
Start the iterator for receiving all indices of the particles. (Used to help get particle indices, see tpt.next_getPartIndex)<br />
<br />
<code>tpt.start_getPartIndex()</code><br />
<br />
=== tpt.next_getPartIndex ===<br />
Jump to the next available particle index. Returns false if the iterator has reached the end of all particle indecies. Returns true if a new index was available. (Used to help get particle indecies, see tpt.getPartIndex)<br />
<br />
<code>tpt.next_getPartIndex()</code><br />
<br />
=== tpt.getPartIndex ===<br />
Get the current index iterator.<br />
<br />
<code>tpt.getPartIndex()</code><br />
<br />
index code example:<br />
<pre><br />
tpt.start_getPartIndex()<br />
while tpt.next_getPartIndex() do<br />
local index = tpt.getPartIndex()<br />
if tpt.get_property("ctype",index) == 21 then<br />
tpt.set_property("ctype","sing",index)<br />
end<br />
end<br />
</pre><br />
<br />
These functions are made obsolete by the function sim.parts(). That allows you to use Lua's iterators.<br />
<br />
=== tpt.get_numOfParts ===<br />
Returns the number of particles currently on the screen.<br />
<br />
<code>tpt.get_numOfParts()</code><br />
<br />
A newer way to get this is the variable sim.NUM_PARTS<br />
<br />
== Drawing ==<br />
<br />
=== tpt.textwidth ===<br />
Measures (in pixels) the width of a given string. Returns a number.<br />
<br />
<code>tpt.textwidth(string text)</code><br />
<br />
=== tpt.drawtext ===<br />
Draw text to the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawtext(number x, number y, string text)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.drawpixel ===<br />
Draws a pixel on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawpixel(number x, number y)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawline ===<br />
Draws a line on the screen (for one frame, only useful in scripts), 3 overloads. The line starts at point (x1, y1) and ends at point (x2,y2).<br />
<br />
<code><br />
tpt.drawline(number x1, number y1, number x2, number y2)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawrect ===<br />
Draws a rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawrect(number x, number y, number width, number height)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.fillrect ===<br />
Draws a filled in rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.fillrect(number x, number y, number width, number height)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
Because tpt.fillrect is slightly broken in tpt, the coordinates will be off. It fills the rectangle from (x+1, y+1) to (x+w-1, y+h-1)<br />
<br />
== Input/Output ==<br />
<br />
=== tpt.log ===<br />
Log a message to the console<br />
<br />
<code>tpt.log(string text)</code><br />
<br />
=== tpt.message_box ===<br />
Display an OK-Only message box with a title and message.<br />
<br />
<code>tpt.message_box(string title, string message)</code><br />
<br />
=== tpt.input ===<br />
Ask the user to input some text. Returns a string of what ever the user says. The argument "text" is pre-entered text (optional).<br />
<br />
<code><br />
tpt.input(string title, string message)<br />
<br />
tpt.input(string title, string message, string text)<br />
</code><br />
<br />
=== tpt.throw_error ===<br />
Displays an error message box.<br />
<br />
<code>tpt.throw_error(string text)</code><br />
<br />
=== tpt.confirm ===<br />
Display an confirm message box with a title and message. Returns true if the button with button_name is clicked, returns false if Cancel is clicked.<br />
<br />
<code>tpt.confirm(string title, string message,string button_name)</code><br />
<br />
== Events ==<br />
<br />
The old event api was removed in 94.0, and is only still present through a compatibility script. Please use the new api instead: [[Lua_API:Event|Event]]<br />
<br />
=== tpt.register_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run on every frame<br />
<br />
<code>tpt.register_step(function func)</code><br />
<br />
=== tpt.unregister_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_step(function func)</code><br />
<br />
=== tpt.register_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time the mouse clicks.<br />
<br />
Your function will also be called when the mouse is released or held, or when the mouse wheel is used. Event equals 1 when the mouse gets pressed, 2 when the mouse gets released, and 3 if it is held. If your function returns false, mouse events in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: mousex, mousey, button, event<br />
<br />
<code>tpt.register_mouseclick(function func)</code><br />
<br />
=== tpt.unregister_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_mouseclick(function func)</code><br />
<br />
=== tpt.register_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time a key is pressed.<br />
<br />
Your function will also be called when a key is released. Event equals 1 when a key is pressed, and 2 when it gets released. If your function returns false, key presses in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: key, nkey, modifier, event<br />
<br />
<code>tpt.register_keypress(function func)</code><br />
<br />
=== tpt.unregister_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_keypress(function func)</code><br />
<br />
== Misc ==<br />
<br />
=== tpt.get_name ===<br />
Returns the current username.<br />
<br />
<code>tpt.get_name()</code><br />
<br />
=== tpt.setdebug ===<br />
Sets the "debug mode". It works using bitmasks, so you can turn on multiple debug features at the same time.<br/><br />
Setting 0x1 will display info on the number of particles on the screen.<br/><br />
Setting 0x2 will draw a graph showing the percentages of each type of element on the screen.<br/><br />
Setting 0x4 will display useful information when you draw lines using shift.<br/><br />
Setting 0x8 enables subframe particle debugging. Use alt+f to step one particle at a time. Use shift+f to step up to the particle underneath the mouse. When not over a particle, it advances to the end of the frame.<br />
<br />
<code>tpt.setdebug(number mode)</code><br />
<br />
=== tpt.element ===<br />
Returns an element's number. For example, it would return 28 for dmnd. If passed a number it will return the name instead.<br />
<br />
<code>tpt.element(string elementname)<br />
<br />
tpt.element(number elementid)</code><br />
<br />
=== tpt.element_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Update" instead.<br />
<br />
Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use tpt.element("...") or tpt.el.dust.id for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1. <br />
<br />
newfunction arguments: index, x, y, surround_space, nt<br />
<br />
Returns: return 1 from your function if the particle is killed.<br />
<br />
<code>tpt.element_func(function newfunction, number el_number)<br />
<br />
tpt.element_func(function newfunction, number el_number, number replace)</code><br />
<br />
=== tpt.graphics_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Graphics" instead.<br />
<br />
Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use tpt.el.(name of element to change).id for el_number.<br />
<br />
Function arguments: index, colr, colg, colb<br />
<br />
Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.<br />
<br />
Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.<br />
<br />
colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.<br />
<br />
<code>tpt.graphics_func(function newfunction, number el_number)</code><br />
<br />
The pixel mode values you can use are:<br />
<pre><br />
PMODE_NONE 0x00000000 --prevents anything from being drawn<br />
PMODE_FLAT 0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.<br />
PMODE_BLOB 0x00000002 --adds a blobby effect, like you were using blob (5) display mode<br />
PMODE_BLUR 0x00000004 --used in liquids in fancy display mode<br />
PMODE_GLOW 0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode<br />
PMODE_SPARK 0x00000010 -- used for things such as GBMB at first, dimmer than other modes<br />
PMODE_FLARE 0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK<br />
PMODE_LFLARE 0x00000040 --brightest spark mode, used when DEST hits something<br />
PMODE_ADD 0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
PMODE_BLEND 0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support<br />
PSPEC_STICKMAN 0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one<br />
<br />
NO_DECO 0x00001000 --prevents decoration from showing on the element (used in LCRY)<br />
DECO_FIRE 0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)<br />
<br />
FIRE_ADD 0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)<br />
FIRE_BLEND 0x00020000 --adds a stronger fire effect around the element, default for gasses<br />
<br />
EFFECT_GRAVIN 0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
EFFECT_GRAVOUT 0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
<br />
</pre><br />
<br />
You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2<br />
<br />
See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html<br />
<br />
=== tpt.screenshot ===<br />
Takes a screenshot of the current screen, minus the menu and HUD.<br />
<br />
<code>tpt.screenshot()<br />
<br />
tpt.screenshot(boolean fullscreen,number screenshot format)</code><br />
<br />
'''Screenshot format''':<br />
<br />
0 - png<br />
<br />
1 - bmp<br />
<br />
2 - ppm<br />
<br />
'''Examples''':<br />
<br />
tpt.screenshot(1,1) - take fullscreen screenshot in bmp format<br />
<br />
tpt.screenshot(1,2) - take fullscreen screenshot in ppm format<br />
<br />
=== tpt.get_clipboard ===<br />
Returns contents of the clipboard.<br />
<br />
<code>tpt.get_clipboard()</code><br />
<br />
=== tpt.set_clipboard ===<br />
Copy to clipboard.<br />
<br />
<code>tpt.set_clipboard(string text)</code><br />
<br />
=== tpt.record ===<br />
Records each drawn frame and saves them all in a unique folder inside a folder called "recordings" in the .ppm format.<br />
<br />
Returns the name of the folder inside the "recordings" folder.<br />
<br />
The record argument if true will start recording and if false will stop recording.<br />
<br />
<code><br />
number tpt.record(boolean record)<br />
</code><br />
<br />
=== tpt.getscript ===<br />
Downloads a script from the script server at [https://starcatcher.us/scripts starcatcher.us] and saves it in the TPT's shared data folder under the provided name.<br />
<br />
Optional argument runScript if 1, will run the file after downloading it. By default it's 0.<br />
<br />
Optional argument confirmPrompt if 1, will prompt the user before downloading the script. By default it's 1.<br />
<br />
<code><br />
tpt.getscript(number scriptID, string filename)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript, number confirmPrompt)<br />
</code><br />
<br />
= Constants =<br />
<br />
All of these constants can be accessed by tpt.<constant name><br />
<br />
=== tpt.selectedl ===<br />
Current element / tool on mouse1<br />
<br />
=== tpt.selectedr ===<br />
Current element / tool on mouse2<br />
<br />
=== tpt.selecteda ===<br />
Current element / tool on mouse3 (middle click)<br />
<br />
=== tpt.selectedreplace ===<br />
Current element to be used in replace mode (green outline)<br />
<br />
=== tpt.brushx ===<br />
Current brush width<br />
<br />
=== tpt.brushy ===<br />
Current brush height<br />
<br />
=== tpt.brushID ===<br />
Current brush ID, 0 = circle, 1 = square, 2 = triangle, higher = custom brushes<br />
<br />
Note that these constants are not read-only so if you run<br />
<pre>tpt.selectedl = "DEFAULT_PT_SPRK"</pre><br />
it will change the element on mouse1 to sprk<br />
<br />
= Simple Example Code =<br />
<pre><br />
-- This line is a comment. Anything written after the -- is considered a Comment and will not be read by Lua.<br />
-- Comment can be multiline, for this you should write it in --[[ and ]]--<br />
-- Set the console's state to 0. This will hide the console.<br />
tpt.set_console(0)<br />
<br />
-- Here we define our main function for the script<br />
local function ClassicPowder()<br />
local ox = 125 -- This will be our offset for the different elements we will create.<br />
local y = 4 -- where on the y (vertical) axis where we will create our elements.<br />
<br />
local x = ox -- where on the x (horizontal) axis where we will create our elements. we will start the x value with what ever ox is above.<br />
for i=0, 10 do -- this is a for loop. everything between the do and end will loop until i hits 10. i increases by 1 every loop.<br />
tpt.create(x + i, y, "STNE") --create a dust particle<br />
end<br />
<br />
x = x + ox -- increase the x axis value by the offset x (ox) value above<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "WATR") --create a water particle<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "SALT")<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "OIL")<br />
end<br />
<br />
return false<br />
end<br />
<br />
-- Register the step function ClassicPowder. This will make the ClassicPowder function run every tick of Powder Toy.<br />
tpt.register_step(ClassicPowder)<br />
</pre><br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua&diff=8599Lua2022-10-02T20:07:45Z<p>Maticzpl: Added tpt.getscript and tpt.record</p>
<hr />
<div>{{Languages|Lua}}<br />
<br />
You may open the Lua Console by hitting the ''[`]'' key. (Also known as the tilde ''[~]'' key, or the ''[¬]'' key) [http://www.bittbox.com/wp-content/uploads/2007/12/tilde_illustrator_1.jpg click here to view key]<br />
<br />
----<br />
<br />
You may be used to this style of console commands: ''!set type dust metl''. This can be useful, but Lua is an entire programming language that can do much more powerful things. The equivalent command in TPT's Lua is ''tpt.set_property("type", "metl", "dust")'' (see [[Lua#tpt.set_property]] )<br />
<br />
This page describes the TPT Lua API, not the Lua language itself. But, you may research Lua on your own. If you're a beginner, look at this: http://www.lua.org/pil/ . If more advanced, a list of all the functions is here: http://www.lua.org/manual/5.1/<br />
<br />
Also, FeynmanTechnologies has written a tutorial on some of the most basic Lua features here: https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=17801<br />
<br />
The Lua Console provides the ability to create scripts using Lua, a very simple scripting language. With the ability to script with Lua, users are now able to create simple modifications to the game without editing source code. For information on how to run scripts, see [[Running Lua Scripts]]<br />
<br />
= Lua API =<br />
The Powder Toy exposes the following methods to the Lua API:<br />
<br />
== Game ==<br />
<br />
=== tpt.set_pause ===<br />
<br />
<code>tpt.set_pause(number state)</code><br />
<br />
Sets the paused state of the game. <br />
<br />
The number argument is either 0 or 1, where 1 means the game will be paused, and 0 will unpause the game. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the game is currently paused. <br />
<br />
'''Examples''':<br />
<br />
Pause the game: <code>tpt.set_pause(1)</code><br />
<br />
Get if the game is paused currently: <code>tpt.set_pause() == 1</code><br />
<br />
=== tpt.set_console ===<br />
<br />
<code>tpt.set_console(number state)</code><br />
<br />
Set the visibility state of the console. <br />
<br />
The number argument can be either 0 or 1, where 1 means the console will be opened, and 0 will close the console. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the console is currently opened.<br />
<br />
'''Examples''':<br />
<br />
Open the console: <code>tpt.set_console(1)</code><br />
<br />
Get if the console is currently open: <code>tpt.set_console() == 1</code><br />
<br />
=== tpt.set_shortcuts ===<br />
<br />
'''This function is REMOVED in TPT 94.0'''<br />
<br />
<code>tpt.set_shortcuts(number state)</code><br />
<br />
Set whether one can use keyboard shortcuts such as making a stamp or opening the console or changing view modes. <br />
<br />
The number argument can be either 0 or 1, where 1 means keys will be enabled, and 0 will disable key shortcuts. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether key shortcuts are enabled right now.<br />
<br />
When you want to make a key command which uses some other key, don't use this, rather disable default behavior for that one key only by returning false from inside your callback.<br />
<br />
'''Examples''':<br />
<br />
Disable keyboard shortcuts: <code>tpt.set_shortcuts(0)</code><br />
<br />
Get if keyboard shortcuts are currently disabled: <code>tpt.set_shortcuts(-1) == 1</code><br />
<br />
=== tpt.set_gravity ===<br />
<br />
<code>tpt.set_gravity(number x, number y, number width, number height, number value)</code><br />
<br />
Sets Newtonian Gravity at a position or area to some value. <br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples''':<br />
<br />
Reset gravity in the cell at point (150, 150): <code>tpt.set_gravity(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100,100) to (300,300): <code>tpt.set_gravity(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
Set the entire stage's gravity to 1000: <code>tpt.set_gravity(nil, nil, nil, nil, 1000)</code><br />
<br />
=== tpt.reset_gravity_field ===<br />
<br />
<code>tpt.reset_gravity_field(number x, number y, number width, number height)</code><br />
<br />
Thoroughly resets Newtonian gravity on a given point. <br />
<br />
Instead of tpt.set_gravity which only modifies <code>sim-&gt;gravmap</code>, this code modifies <code>sim->gravp</code>,<code>sim->gravx</code> and <code>sim->gravy</code>. Mmm, gravy.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples''':<br />
<br />
Thoroughly reset gravity in the cell at point (150, 150): <code>tpt.reset_gravity_field(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100, 100) to (300,300): <code>tpt.reset_gravity_field(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
=== tpt.set_pressure ===<br />
<br />
<code>tpt.set_pressure(number x, number y, number width, number height, number value)</code><br />
<br />
Sets or resets pressure in the pressure map to some pressure. I sometimes imagine how much I can repeat the word "pressure" inside a sentence before it becomes gibberish.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples:'''<br />
<br />
Reset pressure everywhere: <code>tpt.set_pressure()</code><br />
<br />
Set pressure of cell at (100, 100) to 200: <code>tpt.set_pressure(100 / sim.CELL, 100 / sim.CELL, 1, 1, 200)</code><br />
<br />
Set pressure everywhere to 200: <code>tpt.set_pressure(nil,nil,nil,nil,200)</code><br />
<br />
=== tpt.reset_velocity ===<br />
<br />
<code>tpt.reset_velocity(number x, number y, number width, number height)</code><br />
<br />
Sets velocity (both x and y) in a given region or point to 0.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples:'''<br />
<br />
Reset velocity everywhere: <code>tpt.reset_velocity()</code><br />
<br />
Reset velocity in the cell at point (100,100): <code>tpt.reset_velocity(100 / sim.CELL, 100 / sim.CELL, 1, 1)</code><br />
<br />
=== tpt.hud ===<br />
<br />
<code>tpt.hud(number state)</code><br />
<br />
Set HUD visibility.<br />
<br />
Does the same thing as pressing the H key normally. The number argument can be either 0 or 1, where 1 will show the HUD, and 0 will hide the HUD. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the HUD is visible right now.<br />
<br />
=== tpt.newtonian_gravity ===<br />
<br />
<code>tpt.newtonian_gravity(number state)</code><br />
<br />
Sets Newtonian Gravity on and off.<br />
<br />
Does the same thing as Ctrl+N in normal gameplay. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable Newtonian Gravity, and 0 will disable Newtonian Gravity. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Newtonian Gravity is turned on at the given moment.<br />
<br />
=== tpt.ambient_heat ===<br />
<br />
<code>tpt.ambient_heat(number state)</code><br />
<br />
Toggles Ambient Heat state.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable Ambient Heat, 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Ambient Heat is turned on at the given moment.<br />
<br />
=== tpt.decorations_enable ===<br />
<br />
<code>tpt.decorations_enable(number state)</code><br />
<br />
Toggle drawing decorations.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable decorations, and 0 will disable them. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether decorations are turned on at the given moment.<br />
<br />
=== tpt.heat ===<br />
<br />
<code>tpt.heat(number state)</code><br />
<br />
Toggles Heat Simulation. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable heat, and 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether heat is turned on at the given moment.<br />
<br />
It's usually wise not to disable this, as there are practically no saves left that need the compatibility mode in order to work. Nevertheless this option exists. <br />
<br />
=== tpt.active_menu ===<br />
<br />
<code>tpt.active_menu(number menu)</code><br />
<br />
Changes activated menu. If you don't pass in any arguments, the command will return the currently active menu.<br />
<br />
The menu IDs are detailed here: [[Element_Properties#Menu_sections]]<br />
<br />
Example: <code>tpt.active_menu(elem.SC_EXPLOSIVE)</code><br />
<br />
=== tpt.menu_enabled ===<br />
<br />
<code><br />
boolean tpt.menu_enabled(number menuID)<br />
<br />
tpt.menu_enabled(number menuID, boolean enabled)<br />
</code><br />
<br />
Returns true if a menu section is enabled. <br />
<br />
If provided a boolean, will set if a menu section is enabled.<br />
<br />
=== tpt.num_menus ===<br />
<br />
<code><br />
number tpt.num_menus()<br />
<br />
number tpt.num_menus(boolean onlyEnabled)<br />
</code><br />
<br />
Returns the number of menus.<br />
<br />
The optional onlyEnabled boolean is true by default.<br />
<br />
=== tpt.display_mode ===<br />
<br />
<code>tpt.display_mode(number display)</code><br />
<br />
Changes activated display mode.<br />
<br />
There's 11 display modes, detailed here [[https://github.com/ThePowderToy/The-Powder-Toy/blob/f54189a97f6d80181deb4f6d952ccf10f0e59ccf/src/graphics/Renderer.cpp#L2587-L2644]], but I'll provide a reference below: <br />
<br />
'''Display Modes'''<br />
<br />
0 = Alternate Velocity<br><br />
1 = Velocity<br><br />
2 = Pressure<br><br />
3 = Persistent<br><br />
4 = Fire<br><br />
5 = Blob<br><br />
6 = Heat<br><br />
7 = Fancy<br><br />
8 = Nothing<br><br />
9 = Heat Gradient<br><br />
10 = Life Gradient<br><br />
<br />
=== tpt.setfpscap ===<br />
<br />
<code>tpt.setfpscap(number fpscap)</code><br />
<br />
Changes the upper FPS limit the program will run at. This value is '''60 by default.'''<br />
<br />
Don't set it too high, it'll eat all your CPU speed and make the game too responsive! Don't also set it too low, since UI and everything related to it uses the same FPS, so you'll find buttons and stuff not working.<br />
<br />
If you don't pass in any arguments, it will return the current fps cap. If you set the fpscap to 2, this will uncap the framerate.<br />
<br />
=== tpt.setdrawcap ===<br />
<br />
Changes the rate that particle graphics and the UI render to the screen. This is separate from the fpscap, which only affects the simulation. The drawcap allows TPT to skip drawing every frame. This may increase the framerate in some instances.<br />
<br />
The default is set to the maximum refresh rate of all attached monitors.<br />
<br />
=== tpt.setfire ===<br />
Changes the strength of the games glowing effects. tpt.setfire(1) is default.<br />
<br />
<code>tpt.setfire(number strength)</code><br />
<br />
=== tpt.setwindowsize ===<br />
<br />
<code>tpt.setwindowsize(number scale, number fullscreen)</code><br />
<br />
Changes a few special properties as to what size the game renders at.<br />
<br />
Scale is a multiplier by which every pixel shall get multiplied at, currently it can either be 1 (612x384) or 2 (1224x768). <br />
<br />
Full screen is a toggle (0 or 1) that enables "kiosk mode", which basically scales the game up to fill the screen and makes the rest of the edge black.<br />
<br />
=== tpt.toggle_pause ===<br />
Toggle pause.<br />
<br />
<code>tpt.toggle_pause()</code><br />
<br />
== Particles ==<br />
<br />
=== tpt.reset_spark ===<br />
Removes electrified wires from the simulation, resetting to the original material<br />
<br />
<code>tpt.reset_spark()</code><br />
<br />
=== tpt.set_property ===<br />
Set various properties of particles for given criteria, 8 overloads<br />
<br />
<code><br />
tpt.set_property(string property, object value)<br />
<br />
tpt.set_property(string property, object value, string type)<br />
<br />
tpt.set_property(string property, object value, number index)<br />
<br />
tpt.set_property(string property, object value, number index, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y)<br />
<br />
tpt.set_property(string property, object value, number x, number y, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height, string type)<br />
</code><br />
<br />
=== tpt.set_wallmap ===<br />
Sets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_wallmap(number x, number y, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_wallmap ===<br />
Gets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_wallmap(number x, number y)<br />
</code><br />
<br />
=== tpt.set_elecmap ===<br />
Sets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. The value is decremented by 1 every frame, just like SPRK .life, and when it reaches 0 the wall is "unsparked". Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_elecmap(number x, number y, number walltype)<br />
<br />
tpt.set_elecmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_elecmap ===<br />
Gets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_elecmap(number x, number y)<br />
</code><br />
<br />
=== tpt.get_property ===<br />
Returns various properties of a particle.<br />
<br />
<code><br />
tpt.get_property(string property, number index)<br />
<br />
tpt.get_property(string property, number x, number y)<br />
</code><br />
<br />
=== tpt.create ===<br />
Create a particle at location.<br />
<br />
<code>tpt.create(number x, number y, string type)</code><br />
<br />
Returns the index of the newly created particle.<br />
<br />
=== tpt.delete ===<br />
Delete a specific particle, or location.<br />
<br />
<code><br />
tpt.delete(number index)<br />
<br />
tpt.delete(number x, number y)<br />
</code><br />
<br />
=== tpt.start_getPartIndex ===<br />
Start the iterator for receiving all indices of the particles. (Used to help get particle indices, see tpt.next_getPartIndex)<br />
<br />
<code>tpt.start_getPartIndex()</code><br />
<br />
=== tpt.next_getPartIndex ===<br />
Jump to the next available particle index. Returns false if the iterator has reached the end of all particle indecies. Returns true if a new index was available. (Used to help get particle indecies, see tpt.getPartIndex)<br />
<br />
<code>tpt.next_getPartIndex()</code><br />
<br />
=== tpt.getPartIndex ===<br />
Get the current index iterator.<br />
<br />
<code>tpt.getPartIndex()</code><br />
<br />
index code example:<br />
<pre><br />
tpt.start_getPartIndex()<br />
while tpt.next_getPartIndex() do<br />
local index = tpt.getPartIndex()<br />
if tpt.get_property("ctype",index) == 21 then<br />
tpt.set_property("ctype","sing",index)<br />
end<br />
end<br />
</pre><br />
<br />
These functions are made obsolete by the function sim.parts(). That allows you to use Lua's iterators.<br />
<br />
=== tpt.get_numOfParts ===<br />
Returns the number of particles currently on the screen.<br />
<br />
<code>tpt.get_numOfParts()</code><br />
<br />
A newer way to get this is the variable sim.NUM_PARTS<br />
<br />
== Drawing ==<br />
<br />
=== tpt.textwidth ===<br />
Measures (in pixels) the width of a given string. Returns a number.<br />
<br />
<code>tpt.textwidth(string text)</code><br />
<br />
=== tpt.drawtext ===<br />
Draw text to the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawtext(number x, number y, string text)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.drawpixel ===<br />
Draws a pixel on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawpixel(number x, number y)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawline ===<br />
Draws a line on the screen (for one frame, only useful in scripts), 3 overloads. The line starts at point (x1, y1) and ends at point (x2,y2).<br />
<br />
<code><br />
tpt.drawline(number x1, number y1, number x2, number y2)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawrect ===<br />
Draws a rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawrect(number x, number y, number width, number height)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.fillrect ===<br />
Draws a filled in rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.fillrect(number x, number y, number width, number height)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
Because tpt.fillrect is slightly broken in tpt, the coordinates will be off. It fills the rectangle from (x+1, y+1) to (x+w-1, y+h-1)<br />
<br />
== Input/Output ==<br />
<br />
=== tpt.log ===<br />
Log a message to the console<br />
<br />
<code>tpt.log(string text)</code><br />
<br />
=== tpt.message_box ===<br />
Display an OK-Only message box with a title and message.<br />
<br />
<code>tpt.message_box(string title, string message)</code><br />
<br />
=== tpt.input ===<br />
Ask the user to input some text. Returns a string of what ever the user says. The argument "text" is pre-entered text (optional).<br />
<br />
<code><br />
tpt.input(string title, string message)<br />
<br />
tpt.input(string title, string message, string text)<br />
</code><br />
<br />
=== tpt.throw_error ===<br />
Displays an error message box.<br />
<br />
<code>tpt.throw_error(string text)</code><br />
<br />
=== tpt.confirm ===<br />
Display an confirm message box with a title and message. Returns true if the button with button_name is clicked, returns false if Cancel is clicked.<br />
<br />
<code>tpt.confirm(string title, string message,string button_name)</code><br />
<br />
== Events ==<br />
<br />
The old event api was removed in 94.0, and is only still present through a compatibility script. Please use the new api instead: [[Lua_API:Event|Event]]<br />
<br />
=== tpt.register_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run on every frame<br />
<br />
<code>tpt.register_step(function func)</code><br />
<br />
=== tpt.unregister_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_step(function func)</code><br />
<br />
=== tpt.register_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time the mouse clicks.<br />
<br />
Your function will also be called when the mouse is released or held, or when the mouse wheel is used. Event equals 1 when the mouse gets pressed, 2 when the mouse gets released, and 3 if it is held. If your function returns false, mouse events in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: mousex, mousey, button, event<br />
<br />
<code>tpt.register_mouseclick(function func)</code><br />
<br />
=== tpt.unregister_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_mouseclick(function func)</code><br />
<br />
=== tpt.register_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time a key is pressed.<br />
<br />
Your function will also be called when a key is released. Event equals 1 when a key is pressed, and 2 when it gets released. If your function returns false, key presses in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: key, nkey, modifier, event<br />
<br />
<code>tpt.register_keypress(function func)</code><br />
<br />
=== tpt.unregister_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_keypress(function func)</code><br />
<br />
== Misc ==<br />
<br />
=== tpt.get_name ===<br />
Returns the current username.<br />
<br />
<code>tpt.get_name()</code><br />
<br />
=== tpt.setdebug ===<br />
Sets the "debug mode". It works using bitmasks, so you can turn on multiple debug features at the same time.<br/><br />
Setting 0x1 will display info on the number of particles on the screen.<br/><br />
Setting 0x2 will draw a graph showing the percentages of each type of element on the screen.<br/><br />
Setting 0x4 will display useful information when you draw lines using shift.<br/><br />
Setting 0x8 enables subframe particle debugging. Use alt+f to step one particle at a time. Use shift+f to step up to the particle underneath the mouse. When not over a particle, it advances to the end of the frame.<br />
<br />
<code>tpt.setdebug(number mode)</code><br />
<br />
=== tpt.element ===<br />
Returns an element's number. For example, it would return 28 for dmnd. If passed a number it will return the name instead.<br />
<br />
<code>tpt.element(string elementname)<br />
<br />
tpt.element(number elementid)</code><br />
<br />
=== tpt.element_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Update" instead.<br />
<br />
Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use tpt.element("...") or tpt.el.dust.id for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1. <br />
<br />
newfunction arguments: index, x, y, surround_space, nt<br />
<br />
Returns: return 1 from your function if the particle is killed.<br />
<br />
<code>tpt.element_func(function newfunction, number el_number)<br />
<br />
tpt.element_func(function newfunction, number el_number, number replace)</code><br />
<br />
=== tpt.graphics_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Graphics" instead.<br />
<br />
Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use tpt.el.(name of element to change).id for el_number.<br />
<br />
Function arguments: index, colr, colg, colb<br />
<br />
Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.<br />
<br />
Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.<br />
<br />
colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.<br />
<br />
<code>tpt.graphics_func(function newfunction, number el_number)</code><br />
<br />
The pixel mode values you can use are:<br />
<pre><br />
PMODE_NONE 0x00000000 --prevents anything from being drawn<br />
PMODE_FLAT 0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.<br />
PMODE_BLOB 0x00000002 --adds a blobby effect, like you were using blob (5) display mode<br />
PMODE_BLUR 0x00000004 --used in liquids in fancy display mode<br />
PMODE_GLOW 0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode<br />
PMODE_SPARK 0x00000010 -- used for things such as GBMB at first, dimmer than other modes<br />
PMODE_FLARE 0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK<br />
PMODE_LFLARE 0x00000040 --brightest spark mode, used when DEST hits something<br />
PMODE_ADD 0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
PMODE_BLEND 0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support<br />
PSPEC_STICKMAN 0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one<br />
<br />
NO_DECO 0x00001000 --prevents decoration from showing on the element (used in LCRY)<br />
DECO_FIRE 0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)<br />
<br />
FIRE_ADD 0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)<br />
FIRE_BLEND 0x00020000 --adds a stronger fire effect around the element, default for gasses<br />
<br />
EFFECT_GRAVIN 0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
EFFECT_GRAVOUT 0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
<br />
</pre><br />
<br />
You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2<br />
<br />
See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html<br />
<br />
=== tpt.screenshot ===<br />
Takes a screenshot of the current screen, minus the menu and HUD.<br />
<br />
<code>tpt.screenshot()<br />
<br />
tpt.screenshot(boolean fullscreen,number screenshot format)</code><br />
<br />
'''Screenshot format''':<br />
<br />
0 - png<br />
<br />
1 - bmp<br />
<br />
2 - ppm<br />
<br />
'''Examples''':<br />
<br />
tpt.screenshot(1,1) - take fullscreen screenshot in bmp format<br />
<br />
tpt.screenshot(1,2) - take fullscreen screenshot in ppm format<br />
<br />
=== tpt.get_clipboard ===<br />
Returns contents of the clipboard.<br />
<br />
<code>tpt.get_clipboard()</code><br />
<br />
=== tpt.set_clipboard ===<br />
Copy to clipboard.<br />
<br />
<code>tpt.set_clipboard(string text)</code><br />
<br />
=== tpt.record ===<br />
Records each drawn frame and saves them all in a unique folder inside a folder called "recordings" in the .ppm format.<br />
<br />
Returns the name of the folder inside the "recordings" folder.<br />
<br />
The record argument if true will start recording and if false will stop recording.<br />
<br />
<code><br />
number tpt.record(boolean record)<br />
</code><br />
<br />
=== tpt.getscript ===<br />
Downloads a script from the script server at [https://starcatcher.us/scripts starcatcher.us] and saves it in the TPT's shared data folder under the provided name.<br />
<br />
Optional argument runScript if 1, will run the file after downloading it. By default it's 0.<br />
<br />
Optional argument confirmPrompt if 1, will prompt the user before downloading the script. By default it's 1.<br />
<br />
<code><br />
tpt.getscript(number scriptID, string filename)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript)<br />
<br />
tpt.getscript(number scriptID, string filename, number runScript, number confirmPrompt)<br />
</code><br />
<br />
= Constants =<br />
<br />
All of these constants can be accessed by tpt.<constant name><br />
<br />
=== tpt.selectedl ===<br />
Current element / tool on mouse1<br />
<br />
=== tpt.selectedr ===<br />
Current element / tool on mouse2<br />
<br />
=== tpt.selecteda ===<br />
Current element / tool on mouse3 (middle click)<br />
<br />
=== tpt.selectedreplace ===<br />
Current element to be used in replace mode (green outline)<br />
<br />
=== tpt.brushx ===<br />
Current brush width<br />
<br />
=== tpt.brushy ===<br />
Current brush height<br />
<br />
=== tpt.brushID ===<br />
Current brush ID, 0 = circle, 1 = square, 2 = triangle, higher = custom brushes<br />
<br />
Note that these constants are not read-only so if you run<br />
<pre>tpt.selectedl = "DEFAULT_PT_SPRK"</pre><br />
it will change the element on mouse1 to sprk<br />
<br />
= Simple Example Code =<br />
<pre><br />
-- This line is a comment. Anything written after the -- is considered a Comment and will not be read by Lua.<br />
-- Comment can be multiline, for this you should write it in --[[ and ]]--<br />
-- Set the console's state to 0. This will hide the console.<br />
tpt.set_console(0)<br />
<br />
-- Here we define our main function for the script<br />
local function ClassicPowder()<br />
local ox = 125 -- This will be our offset for the different elements we will create.<br />
local y = 4 -- where on the y (vertical) axis where we will create our elements.<br />
<br />
local x = ox -- where on the x (horizontal) axis where we will create our elements. we will start the x value with what ever ox is above.<br />
for i=0, 10 do -- this is a for loop. everything between the do and end will loop until i hits 10. i increases by 1 every loop.<br />
tpt.create(x + i, y, "STNE") --create a dust particle<br />
end<br />
<br />
x = x + ox -- increase the x axis value by the offset x (ox) value above<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "WATR") --create a water particle<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "SALT")<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "OIL")<br />
end<br />
<br />
return false<br />
end<br />
<br />
-- Register the step function ClassicPowder. This will make the ClassicPowder function run every tick of Powder Toy.<br />
tpt.register_step(ClassicPowder)<br />
</pre><br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua&diff=8598Lua2022-10-02T19:18:12Z<p>Maticzpl: Forgot new lines in previous edit</p>
<hr />
<div>{{Languages|Lua}}<br />
<br />
You may open the Lua Console by hitting the ''[`]'' key. (Also known as the tilde ''[~]'' key, or the ''[¬]'' key) [http://www.bittbox.com/wp-content/uploads/2007/12/tilde_illustrator_1.jpg click here to view key]<br />
<br />
----<br />
<br />
You may be used to this style of console commands: ''!set type dust metl''. This can be useful, but Lua is an entire programming language that can do much more powerful things. The equivalent command in TPT's Lua is ''tpt.set_property("type", "metl", "dust")'' (see [[Lua#tpt.set_property]] )<br />
<br />
This page describes the TPT Lua API, not the Lua language itself. But, you may research Lua on your own. If you're a beginner, look at this: http://www.lua.org/pil/ . If more advanced, a list of all the functions is here: http://www.lua.org/manual/5.1/<br />
<br />
Also, FeynmanTechnologies has written a tutorial on some of the most basic Lua features here: https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=17801<br />
<br />
The Lua Console provides the ability to create scripts using Lua, a very simple scripting language. With the ability to script with Lua, users are now able to create simple modifications to the game without editing source code. For information on how to run scripts, see [[Running Lua Scripts]]<br />
<br />
= Lua API =<br />
The Powder Toy exposes the following methods to the Lua API:<br />
<br />
== Game ==<br />
<br />
=== tpt.set_pause ===<br />
<br />
<code>tpt.set_pause(number state)</code><br />
<br />
Sets the paused state of the game. <br />
<br />
The number argument is either 0 or 1, where 1 means the game will be paused, and 0 will unpause the game. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the game is currently paused. <br />
<br />
'''Examples''':<br />
<br />
Pause the game: <code>tpt.set_pause(1)</code><br />
<br />
Get if the game is paused currently: <code>tpt.set_pause() == 1</code><br />
<br />
=== tpt.set_console ===<br />
<br />
<code>tpt.set_console(number state)</code><br />
<br />
Set the visibility state of the console. <br />
<br />
The number argument can be either 0 or 1, where 1 means the console will be opened, and 0 will close the console. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the console is currently opened.<br />
<br />
'''Examples''':<br />
<br />
Open the console: <code>tpt.set_console(1)</code><br />
<br />
Get if the console is currently open: <code>tpt.set_console() == 1</code><br />
<br />
=== tpt.set_shortcuts ===<br />
<br />
'''This function is REMOVED in TPT 94.0'''<br />
<br />
<code>tpt.set_shortcuts(number state)</code><br />
<br />
Set whether one can use keyboard shortcuts such as making a stamp or opening the console or changing view modes. <br />
<br />
The number argument can be either 0 or 1, where 1 means keys will be enabled, and 0 will disable key shortcuts. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether key shortcuts are enabled right now.<br />
<br />
When you want to make a key command which uses some other key, don't use this, rather disable default behavior for that one key only by returning false from inside your callback.<br />
<br />
'''Examples''':<br />
<br />
Disable keyboard shortcuts: <code>tpt.set_shortcuts(0)</code><br />
<br />
Get if keyboard shortcuts are currently disabled: <code>tpt.set_shortcuts(-1) == 1</code><br />
<br />
=== tpt.set_gravity ===<br />
<br />
<code>tpt.set_gravity(number x, number y, number width, number height, number value)</code><br />
<br />
Sets Newtonian Gravity at a position or area to some value. <br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples''':<br />
<br />
Reset gravity in the cell at point (150, 150): <code>tpt.set_gravity(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100,100) to (300,300): <code>tpt.set_gravity(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
Set the entire stage's gravity to 1000: <code>tpt.set_gravity(nil, nil, nil, nil, 1000)</code><br />
<br />
=== tpt.reset_gravity_field ===<br />
<br />
<code>tpt.reset_gravity_field(number x, number y, number width, number height)</code><br />
<br />
Thoroughly resets Newtonian gravity on a given point. <br />
<br />
Instead of tpt.set_gravity which only modifies <code>sim-&gt;gravmap</code>, this code modifies <code>sim->gravp</code>,<code>sim->gravx</code> and <code>sim->gravy</code>. Mmm, gravy.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples''':<br />
<br />
Thoroughly reset gravity in the cell at point (150, 150): <code>tpt.reset_gravity_field(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100, 100) to (300,300): <code>tpt.reset_gravity_field(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
=== tpt.set_pressure ===<br />
<br />
<code>tpt.set_pressure(number x, number y, number width, number height, number value)</code><br />
<br />
Sets or resets pressure in the pressure map to some pressure. I sometimes imagine how much I can repeat the word "pressure" inside a sentence before it becomes gibberish.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples:'''<br />
<br />
Reset pressure everywhere: <code>tpt.set_pressure()</code><br />
<br />
Set pressure of cell at (100, 100) to 200: <code>tpt.set_pressure(100 / sim.CELL, 100 / sim.CELL, 1, 1, 200)</code><br />
<br />
Set pressure everywhere to 200: <code>tpt.set_pressure(nil,nil,nil,nil,200)</code><br />
<br />
=== tpt.reset_velocity ===<br />
<br />
<code>tpt.reset_velocity(number x, number y, number width, number height)</code><br />
<br />
Sets velocity (both x and y) in a given region or point to 0.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples:'''<br />
<br />
Reset velocity everywhere: <code>tpt.reset_velocity()</code><br />
<br />
Reset velocity in the cell at point (100,100): <code>tpt.reset_velocity(100 / sim.CELL, 100 / sim.CELL, 1, 1)</code><br />
<br />
=== tpt.hud ===<br />
<br />
<code>tpt.hud(number state)</code><br />
<br />
Set HUD visibility.<br />
<br />
Does the same thing as pressing the H key normally. The number argument can be either 0 or 1, where 1 will show the HUD, and 0 will hide the HUD. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the HUD is visible right now.<br />
<br />
=== tpt.newtonian_gravity ===<br />
<br />
<code>tpt.newtonian_gravity(number state)</code><br />
<br />
Sets Newtonian Gravity on and off.<br />
<br />
Does the same thing as Ctrl+N in normal gameplay. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable Newtonian Gravity, and 0 will disable Newtonian Gravity. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Newtonian Gravity is turned on at the given moment.<br />
<br />
=== tpt.ambient_heat ===<br />
<br />
<code>tpt.ambient_heat(number state)</code><br />
<br />
Toggles Ambient Heat state.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable Ambient Heat, 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Ambient Heat is turned on at the given moment.<br />
<br />
=== tpt.decorations_enable ===<br />
<br />
<code>tpt.decorations_enable(number state)</code><br />
<br />
Toggle drawing decorations.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable decorations, and 0 will disable them. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether decorations are turned on at the given moment.<br />
<br />
=== tpt.heat ===<br />
<br />
<code>tpt.heat(number state)</code><br />
<br />
Toggles Heat Simulation. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable heat, and 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether heat is turned on at the given moment.<br />
<br />
It's usually wise not to disable this, as there are practically no saves left that need the compatibility mode in order to work. Nevertheless this option exists. <br />
<br />
=== tpt.active_menu ===<br />
<br />
<code>tpt.active_menu(number menu)</code><br />
<br />
Changes activated menu. If you don't pass in any arguments, the command will return the currently active menu.<br />
<br />
The menu IDs are detailed here: [[Element_Properties#Menu_sections]]<br />
<br />
Example: <code>tpt.active_menu(elem.SC_EXPLOSIVE)</code><br />
<br />
=== tpt.menu_enabled ===<br />
<br />
<code><br />
boolean tpt.menu_enabled(number menuID)<br />
<br />
tpt.menu_enabled(number menuID, boolean enabled)<br />
</code><br />
<br />
Returns true if a menu section is enabled. <br />
<br />
If provided a boolean, will set if a menu section is enabled.<br />
<br />
=== tpt.num_menus ===<br />
<br />
<code><br />
number tpt.num_menus()<br />
<br />
number tpt.num_menus(boolean onlyEnabled)<br />
</code><br />
<br />
Returns the number of menus.<br />
<br />
The optional onlyEnabled boolean is true by default.<br />
<br />
=== tpt.display_mode ===<br />
<br />
<code>tpt.display_mode(number display)</code><br />
<br />
Changes activated display mode.<br />
<br />
There's 11 display modes, detailed here [[https://github.com/ThePowderToy/The-Powder-Toy/blob/f54189a97f6d80181deb4f6d952ccf10f0e59ccf/src/graphics/Renderer.cpp#L2587-L2644]], but I'll provide a reference below: <br />
<br />
'''Display Modes'''<br />
<br />
0 = Alternate Velocity<br><br />
1 = Velocity<br><br />
2 = Pressure<br><br />
3 = Persistent<br><br />
4 = Fire<br><br />
5 = Blob<br><br />
6 = Heat<br><br />
7 = Fancy<br><br />
8 = Nothing<br><br />
9 = Heat Gradient<br><br />
10 = Life Gradient<br><br />
<br />
=== tpt.setfpscap ===<br />
<br />
<code>tpt.setfpscap(number fpscap)</code><br />
<br />
Changes the upper FPS limit the program will run at. This value is '''60 by default.'''<br />
<br />
Don't set it too high, it'll eat all your CPU speed and make the game too responsive! Don't also set it too low, since UI and everything related to it uses the same FPS, so you'll find buttons and stuff not working.<br />
<br />
If you don't pass in any arguments, it will return the current fps cap. If you set the fpscap to 2, this will uncap the framerate.<br />
<br />
=== tpt.setdrawcap ===<br />
<br />
Changes the rate that particle graphics and the UI render to the screen. This is separate from the fpscap, which only affects the simulation. The drawcap allows TPT to skip drawing every frame. This may increase the framerate in some instances.<br />
<br />
The default is set to the maximum refresh rate of all attached monitors.<br />
<br />
=== tpt.setfire ===<br />
Changes the strength of the games glowing effects. tpt.setfire(1) is default.<br />
<br />
<code>tpt.setfire(number strength)</code><br />
<br />
=== tpt.setwindowsize ===<br />
<br />
<code>tpt.setwindowsize(number scale, number fullscreen)</code><br />
<br />
Changes a few special properties as to what size the game renders at.<br />
<br />
Scale is a multiplier by which every pixel shall get multiplied at, currently it can either be 1 (612x384) or 2 (1224x768). <br />
<br />
Full screen is a toggle (0 or 1) that enables "kiosk mode", which basically scales the game up to fill the screen and makes the rest of the edge black.<br />
<br />
=== tpt.toggle_pause ===<br />
Toggle pause.<br />
<br />
<code>tpt.toggle_pause()</code><br />
<br />
== Particles ==<br />
<br />
=== tpt.reset_spark ===<br />
Removes electrified wires from the simulation, resetting to the original material<br />
<br />
<code>tpt.reset_spark()</code><br />
<br />
=== tpt.set_property ===<br />
Set various properties of particles for given criteria, 8 overloads<br />
<br />
<code><br />
tpt.set_property(string property, object value)<br />
<br />
tpt.set_property(string property, object value, string type)<br />
<br />
tpt.set_property(string property, object value, number index)<br />
<br />
tpt.set_property(string property, object value, number index, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y)<br />
<br />
tpt.set_property(string property, object value, number x, number y, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height, string type)<br />
</code><br />
<br />
=== tpt.set_wallmap ===<br />
Sets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_wallmap(number x, number y, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_wallmap ===<br />
Gets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_wallmap(number x, number y)<br />
</code><br />
<br />
=== tpt.set_elecmap ===<br />
Sets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. The value is decremented by 1 every frame, just like SPRK .life, and when it reaches 0 the wall is "unsparked". Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_elecmap(number x, number y, number walltype)<br />
<br />
tpt.set_elecmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_elecmap ===<br />
Gets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_elecmap(number x, number y)<br />
</code><br />
<br />
=== tpt.get_property ===<br />
Returns various properties of a particle.<br />
<br />
<code><br />
tpt.get_property(string property, number index)<br />
<br />
tpt.get_property(string property, number x, number y)<br />
</code><br />
<br />
=== tpt.create ===<br />
Create a particle at location.<br />
<br />
<code>tpt.create(number x, number y, string type)</code><br />
<br />
Returns the index of the newly created particle.<br />
<br />
=== tpt.delete ===<br />
Delete a specific particle, or location.<br />
<br />
<code><br />
tpt.delete(number index)<br />
<br />
tpt.delete(number x, number y)<br />
</code><br />
<br />
=== tpt.start_getPartIndex ===<br />
Start the iterator for receiving all indices of the particles. (Used to help get particle indices, see tpt.next_getPartIndex)<br />
<br />
<code>tpt.start_getPartIndex()</code><br />
<br />
=== tpt.next_getPartIndex ===<br />
Jump to the next available particle index. Returns false if the iterator has reached the end of all particle indecies. Returns true if a new index was available. (Used to help get particle indecies, see tpt.getPartIndex)<br />
<br />
<code>tpt.next_getPartIndex()</code><br />
<br />
=== tpt.getPartIndex ===<br />
Get the current index iterator.<br />
<br />
<code>tpt.getPartIndex()</code><br />
<br />
index code example:<br />
<pre><br />
tpt.start_getPartIndex()<br />
while tpt.next_getPartIndex() do<br />
local index = tpt.getPartIndex()<br />
if tpt.get_property("ctype",index) == 21 then<br />
tpt.set_property("ctype","sing",index)<br />
end<br />
end<br />
</pre><br />
<br />
These functions are made obsolete by the function sim.parts(). That allows you to use Lua's iterators.<br />
<br />
=== tpt.get_numOfParts ===<br />
Returns the number of particles currently on the screen.<br />
<br />
<code>tpt.get_numOfParts()</code><br />
<br />
A newer way to get this is the variable sim.NUM_PARTS<br />
<br />
== Drawing ==<br />
<br />
=== tpt.textwidth ===<br />
Measures (in pixels) the width of a given string. Returns a number.<br />
<br />
<code>tpt.textwidth(string text)</code><br />
<br />
=== tpt.drawtext ===<br />
Draw text to the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawtext(number x, number y, string text)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.drawpixel ===<br />
Draws a pixel on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawpixel(number x, number y)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawline ===<br />
Draws a line on the screen (for one frame, only useful in scripts), 3 overloads. The line starts at point (x1, y1) and ends at point (x2,y2).<br />
<br />
<code><br />
tpt.drawline(number x1, number y1, number x2, number y2)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawrect ===<br />
Draws a rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawrect(number x, number y, number width, number height)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.fillrect ===<br />
Draws a filled in rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.fillrect(number x, number y, number width, number height)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
Because tpt.fillrect is slightly broken in tpt, the coordinates will be off. It fills the rectangle from (x+1, y+1) to (x+w-1, y+h-1)<br />
<br />
== Input/Output ==<br />
<br />
=== tpt.log ===<br />
Log a message to the console<br />
<br />
<code>tpt.log(string text)</code><br />
<br />
=== tpt.message_box ===<br />
Display an OK-Only message box with a title and message.<br />
<br />
<code>tpt.message_box(string title, string message)</code><br />
<br />
=== tpt.input ===<br />
Ask the user to input some text. Returns a string of what ever the user says. The argument "text" is pre-entered text (optional).<br />
<br />
<code><br />
tpt.input(string title, string message)<br />
<br />
tpt.input(string title, string message, string text)<br />
</code><br />
<br />
=== tpt.throw_error ===<br />
Displays an error message box.<br />
<br />
<code>tpt.throw_error(string text)</code><br />
<br />
=== tpt.confirm ===<br />
Display an confirm message box with a title and message. Returns true if the button with button_name is clicked, returns false if Cancel is clicked.<br />
<br />
<code>tpt.confirm(string title, string message,string button_name)</code><br />
<br />
== Events ==<br />
<br />
The old event api was removed in 94.0, and is only still present through a compatibility script. Please use the new api instead: [[Lua_API:Event|Event]]<br />
<br />
=== tpt.register_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run on every frame<br />
<br />
<code>tpt.register_step(function func)</code><br />
<br />
=== tpt.unregister_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_step(function func)</code><br />
<br />
=== tpt.register_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time the mouse clicks.<br />
<br />
Your function will also be called when the mouse is released or held, or when the mouse wheel is used. Event equals 1 when the mouse gets pressed, 2 when the mouse gets released, and 3 if it is held. If your function returns false, mouse events in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: mousex, mousey, button, event<br />
<br />
<code>tpt.register_mouseclick(function func)</code><br />
<br />
=== tpt.unregister_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_mouseclick(function func)</code><br />
<br />
=== tpt.register_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time a key is pressed.<br />
<br />
Your function will also be called when a key is released. Event equals 1 when a key is pressed, and 2 when it gets released. If your function returns false, key presses in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: key, nkey, modifier, event<br />
<br />
<code>tpt.register_keypress(function func)</code><br />
<br />
=== tpt.unregister_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_keypress(function func)</code><br />
<br />
== Misc ==<br />
<br />
=== tpt.get_name ===<br />
Returns the current username.<br />
<br />
<code>tpt.get_name()</code><br />
<br />
=== tpt.setdebug ===<br />
Sets the "debug mode". It works using bitmasks, so you can turn on multiple debug features at the same time.<br/><br />
Setting 0x1 will display info on the number of particles on the screen.<br/><br />
Setting 0x2 will draw a graph showing the percentages of each type of element on the screen.<br/><br />
Setting 0x4 will display useful information when you draw lines using shift.<br/><br />
Setting 0x8 enables subframe particle debugging. Use alt+f to step one particle at a time. Use shift+f to step up to the particle underneath the mouse. When not over a particle, it advances to the end of the frame.<br />
<br />
<code>tpt.setdebug(number mode)</code><br />
<br />
=== tpt.element ===<br />
Returns an element's number. For example, it would return 28 for dmnd. If passed a number it will return the name instead.<br />
<br />
<code>tpt.element(string elementname)<br />
<br />
tpt.element(number elementid)</code><br />
<br />
=== tpt.element_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Update" instead.<br />
<br />
Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use tpt.element("...") or tpt.el.dust.id for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1. <br />
<br />
newfunction arguments: index, x, y, surround_space, nt<br />
<br />
Returns: return 1 from your function if the particle is killed.<br />
<br />
<code>tpt.element_func(function newfunction, number el_number)<br />
<br />
tpt.element_func(function newfunction, number el_number, number replace)</code><br />
<br />
=== tpt.graphics_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Graphics" instead.<br />
<br />
Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use tpt.el.(name of element to change).id for el_number.<br />
<br />
Function arguments: index, colr, colg, colb<br />
<br />
Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.<br />
<br />
Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.<br />
<br />
colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.<br />
<br />
<code>tpt.graphics_func(function newfunction, number el_number)</code><br />
<br />
The pixel mode values you can use are:<br />
<pre><br />
PMODE_NONE 0x00000000 --prevents anything from being drawn<br />
PMODE_FLAT 0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.<br />
PMODE_BLOB 0x00000002 --adds a blobby effect, like you were using blob (5) display mode<br />
PMODE_BLUR 0x00000004 --used in liquids in fancy display mode<br />
PMODE_GLOW 0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode<br />
PMODE_SPARK 0x00000010 -- used for things such as GBMB at first, dimmer than other modes<br />
PMODE_FLARE 0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK<br />
PMODE_LFLARE 0x00000040 --brightest spark mode, used when DEST hits something<br />
PMODE_ADD 0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
PMODE_BLEND 0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support<br />
PSPEC_STICKMAN 0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one<br />
<br />
NO_DECO 0x00001000 --prevents decoration from showing on the element (used in LCRY)<br />
DECO_FIRE 0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)<br />
<br />
FIRE_ADD 0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)<br />
FIRE_BLEND 0x00020000 --adds a stronger fire effect around the element, default for gasses<br />
<br />
EFFECT_GRAVIN 0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
EFFECT_GRAVOUT 0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
<br />
</pre><br />
<br />
You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2<br />
<br />
See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html<br />
<br />
=== tpt.screenshot ===<br />
Takes a screenshot of the current screen, minus the menu and HUD.<br />
<br />
<code>tpt.screenshot()<br />
<br />
tpt.screenshot(boolean fullscreen,number screenshot format)</code><br />
<br />
'''Screenshot format''':<br />
<br />
0 - png<br />
<br />
1 - bmp<br />
<br />
2 - ppm<br />
<br />
'''Examples''':<br />
<br />
tpt.screenshot(1,1) - take fullscreen screenshot in bmp format<br />
<br />
tpt.screenshot(1,2) - take fullscreen screenshot in ppm format<br />
<br />
=== tpt.get_clipboard ===<br />
Returns contents of the clipboard.<br />
<br />
<code>tpt.get_clipboard()</code><br />
<br />
=== tpt.set_clipboard ===<br />
Copy to clipboard.<br />
<br />
<code>tpt.set_clipboard(string text)</code><br />
<br />
= Constants =<br />
<br />
All of these constants can be accessed by tpt.<constant name><br />
<br />
=== tpt.selectedl ===<br />
Current element / tool on mouse1<br />
<br />
=== tpt.selectedr ===<br />
Current element / tool on mouse2<br />
<br />
=== tpt.selecteda ===<br />
Current element / tool on mouse3 (middle click)<br />
<br />
=== tpt.selectedreplace ===<br />
Current element to be used in replace mode (green outline)<br />
<br />
=== tpt.brushx ===<br />
Current brush width<br />
<br />
=== tpt.brushy ===<br />
Current brush height<br />
<br />
=== tpt.brushID ===<br />
Current brush ID, 0 = circle, 1 = square, 2 = triangle, higher = custom brushes<br />
<br />
Note that these constants are not read-only so if you run<br />
<pre>tpt.selectedl = "DEFAULT_PT_SPRK"</pre><br />
it will change the element on mouse1 to sprk<br />
<br />
= Simple Example Code =<br />
<pre><br />
-- This line is a comment. Anything written after the -- is considered a Comment and will not be read by Lua.<br />
-- Comment can be multiline, for this you should write it in --[[ and ]]--<br />
-- Set the console's state to 0. This will hide the console.<br />
tpt.set_console(0)<br />
<br />
-- Here we define our main function for the script<br />
local function ClassicPowder()<br />
local ox = 125 -- This will be our offset for the different elements we will create.<br />
local y = 4 -- where on the y (vertical) axis where we will create our elements.<br />
<br />
local x = ox -- where on the x (horizontal) axis where we will create our elements. we will start the x value with what ever ox is above.<br />
for i=0, 10 do -- this is a for loop. everything between the do and end will loop until i hits 10. i increases by 1 every loop.<br />
tpt.create(x + i, y, "STNE") --create a dust particle<br />
end<br />
<br />
x = x + ox -- increase the x axis value by the offset x (ox) value above<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "WATR") --create a water particle<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "SALT")<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "OIL")<br />
end<br />
<br />
return false<br />
end<br />
<br />
-- Register the step function ClassicPowder. This will make the ClassicPowder function run every tick of Powder Toy.<br />
tpt.register_step(ClassicPowder)<br />
</pre><br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua&diff=8597Lua2022-10-02T19:14:50Z<p>Maticzpl: Add missing menu functions.</p>
<hr />
<div>{{Languages|Lua}}<br />
<br />
You may open the Lua Console by hitting the ''[`]'' key. (Also known as the tilde ''[~]'' key, or the ''[¬]'' key) [http://www.bittbox.com/wp-content/uploads/2007/12/tilde_illustrator_1.jpg click here to view key]<br />
<br />
----<br />
<br />
You may be used to this style of console commands: ''!set type dust metl''. This can be useful, but Lua is an entire programming language that can do much more powerful things. The equivalent command in TPT's Lua is ''tpt.set_property("type", "metl", "dust")'' (see [[Lua#tpt.set_property]] )<br />
<br />
This page describes the TPT Lua API, not the Lua language itself. But, you may research Lua on your own. If you're a beginner, look at this: http://www.lua.org/pil/ . If more advanced, a list of all the functions is here: http://www.lua.org/manual/5.1/<br />
<br />
Also, FeynmanTechnologies has written a tutorial on some of the most basic Lua features here: https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=17801<br />
<br />
The Lua Console provides the ability to create scripts using Lua, a very simple scripting language. With the ability to script with Lua, users are now able to create simple modifications to the game without editing source code. For information on how to run scripts, see [[Running Lua Scripts]]<br />
<br />
= Lua API =<br />
The Powder Toy exposes the following methods to the Lua API:<br />
<br />
== Game ==<br />
<br />
=== tpt.set_pause ===<br />
<br />
<code>tpt.set_pause(number state)</code><br />
<br />
Sets the paused state of the game. <br />
<br />
The number argument is either 0 or 1, where 1 means the game will be paused, and 0 will unpause the game. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the game is currently paused. <br />
<br />
'''Examples''':<br />
<br />
Pause the game: <code>tpt.set_pause(1)</code><br />
<br />
Get if the game is paused currently: <code>tpt.set_pause() == 1</code><br />
<br />
=== tpt.set_console ===<br />
<br />
<code>tpt.set_console(number state)</code><br />
<br />
Set the visibility state of the console. <br />
<br />
The number argument can be either 0 or 1, where 1 means the console will be opened, and 0 will close the console. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the console is currently opened.<br />
<br />
'''Examples''':<br />
<br />
Open the console: <code>tpt.set_console(1)</code><br />
<br />
Get if the console is currently open: <code>tpt.set_console() == 1</code><br />
<br />
=== tpt.set_shortcuts ===<br />
<br />
'''This function is REMOVED in TPT 94.0'''<br />
<br />
<code>tpt.set_shortcuts(number state)</code><br />
<br />
Set whether one can use keyboard shortcuts such as making a stamp or opening the console or changing view modes. <br />
<br />
The number argument can be either 0 or 1, where 1 means keys will be enabled, and 0 will disable key shortcuts. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether key shortcuts are enabled right now.<br />
<br />
When you want to make a key command which uses some other key, don't use this, rather disable default behavior for that one key only by returning false from inside your callback.<br />
<br />
'''Examples''':<br />
<br />
Disable keyboard shortcuts: <code>tpt.set_shortcuts(0)</code><br />
<br />
Get if keyboard shortcuts are currently disabled: <code>tpt.set_shortcuts(-1) == 1</code><br />
<br />
=== tpt.set_gravity ===<br />
<br />
<code>tpt.set_gravity(number x, number y, number width, number height, number value)</code><br />
<br />
Sets Newtonian Gravity at a position or area to some value. <br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples''':<br />
<br />
Reset gravity in the cell at point (150, 150): <code>tpt.set_gravity(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100,100) to (300,300): <code>tpt.set_gravity(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
Set the entire stage's gravity to 1000: <code>tpt.set_gravity(nil, nil, nil, nil, 1000)</code><br />
<br />
=== tpt.reset_gravity_field ===<br />
<br />
<code>tpt.reset_gravity_field(number x, number y, number width, number height)</code><br />
<br />
Thoroughly resets Newtonian gravity on a given point. <br />
<br />
Instead of tpt.set_gravity which only modifies <code>sim-&gt;gravmap</code>, this code modifies <code>sim->gravp</code>,<code>sim->gravx</code> and <code>sim->gravy</code>. Mmm, gravy.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples''':<br />
<br />
Thoroughly reset gravity in the cell at point (150, 150): <code>tpt.reset_gravity_field(150 / sim.CELL, 150 / sim.CELL)</code><br />
<br />
Reset gravity from (100, 100) to (300,300): <code>tpt.reset_gravity_field(100 / sim.CELL, 100 / sim.CELL, 200 / sim.CELL, 200 / sim.CELL) </code><br />
<br />
=== tpt.set_pressure ===<br />
<br />
<code>tpt.set_pressure(number x, number y, number width, number height, number value)</code><br />
<br />
Sets or resets pressure in the pressure map to some pressure. I sometimes imagine how much I can repeat the word "pressure" inside a sentence before it becomes gibberish.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br>'''value''' = 0<br />
<br />
'''Examples:'''<br />
<br />
Reset pressure everywhere: <code>tpt.set_pressure()</code><br />
<br />
Set pressure of cell at (100, 100) to 200: <code>tpt.set_pressure(100 / sim.CELL, 100 / sim.CELL, 1, 1, 200)</code><br />
<br />
Set pressure everywhere to 200: <code>tpt.set_pressure(nil,nil,nil,nil,200)</code><br />
<br />
=== tpt.reset_velocity ===<br />
<br />
<code>tpt.reset_velocity(number x, number y, number width, number height)</code><br />
<br />
Sets velocity (both x and y) in a given region or point to 0.<br />
<br />
'''Default values:'''<br />
<br />
'''x''' = 0<br>'''y''' = 0<br>'''width''' = XRES/CELL = 612 / 4 = 153<br>'''height''' = YRES/CELL = 384 / 4 = 96<br />
<br />
'''Examples:'''<br />
<br />
Reset velocity everywhere: <code>tpt.reset_velocity()</code><br />
<br />
Reset velocity in the cell at point (100,100): <code>tpt.reset_velocity(100 / sim.CELL, 100 / sim.CELL, 1, 1)</code><br />
<br />
=== tpt.hud ===<br />
<br />
<code>tpt.hud(number state)</code><br />
<br />
Set HUD visibility.<br />
<br />
Does the same thing as pressing the H key normally. The number argument can be either 0 or 1, where 1 will show the HUD, and 0 will hide the HUD. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether the HUD is visible right now.<br />
<br />
=== tpt.newtonian_gravity ===<br />
<br />
<code>tpt.newtonian_gravity(number state)</code><br />
<br />
Sets Newtonian Gravity on and off.<br />
<br />
Does the same thing as Ctrl+N in normal gameplay. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable Newtonian Gravity, and 0 will disable Newtonian Gravity. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Newtonian Gravity is turned on at the given moment.<br />
<br />
=== tpt.ambient_heat ===<br />
<br />
<code>tpt.ambient_heat(number state)</code><br />
<br />
Toggles Ambient Heat state.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable Ambient Heat, 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether Ambient Heat is turned on at the given moment.<br />
<br />
=== tpt.decorations_enable ===<br />
<br />
<code>tpt.decorations_enable(number state)</code><br />
<br />
Toggle drawing decorations.<br />
<br />
The number argument can be either 0 or 1, where 1 will enable decorations, and 0 will disable them. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether decorations are turned on at the given moment.<br />
<br />
=== tpt.heat ===<br />
<br />
<code>tpt.heat(number state)</code><br />
<br />
Toggles Heat Simulation. <br />
<br />
The number argument can be either 0 or 1, where 1 will enable heat, and 0 will disable it. If you don't pass in any arguments, the command will return an integer, either 0 or 1, about whether heat is turned on at the given moment.<br />
<br />
It's usually wise not to disable this, as there are practically no saves left that need the compatibility mode in order to work. Nevertheless this option exists. <br />
<br />
=== tpt.active_menu ===<br />
<br />
<code>tpt.active_menu(number menu)</code><br />
<br />
Changes activated menu. If you don't pass in any arguments, the command will return the currently active menu.<br />
<br />
The menu IDs are detailed here: [[Element_Properties#Menu_sections]]<br />
<br />
Example: <code>tpt.active_menu(elem.SC_EXPLOSIVE)</code><br />
<br />
=== tpt.menu_enabled ===<br />
<br />
<code><br />
boolean tpt.menu_enabled(number menuID)<br />
tpt.menu_enabled(number menuID, boolean enabled)<br />
</code><br />
<br />
Returns true if a menu section is enabled.<br />
If provided a boolean, will set if a menu section is enabled<br />
<br />
=== tpt.num_menus ===<br />
<br />
<code><br />
number tpt.num_menus()<br />
number tpt.num_menus(boolean onlyEnabled)<br />
</code><br />
<br />
Returns the number of menus.<br />
The optional onlyEnabled boolean is true by default.<br />
<br />
=== tpt.display_mode ===<br />
<br />
<code>tpt.display_mode(number display)</code><br />
<br />
Changes activated display mode.<br />
<br />
There's 11 display modes, detailed here [[https://github.com/ThePowderToy/The-Powder-Toy/blob/f54189a97f6d80181deb4f6d952ccf10f0e59ccf/src/graphics/Renderer.cpp#L2587-L2644]], but I'll provide a reference below: <br />
<br />
'''Display Modes'''<br />
<br />
0 = Alternate Velocity<br><br />
1 = Velocity<br><br />
2 = Pressure<br><br />
3 = Persistent<br><br />
4 = Fire<br><br />
5 = Blob<br><br />
6 = Heat<br><br />
7 = Fancy<br><br />
8 = Nothing<br><br />
9 = Heat Gradient<br><br />
10 = Life Gradient<br><br />
<br />
=== tpt.setfpscap ===<br />
<br />
<code>tpt.setfpscap(number fpscap)</code><br />
<br />
Changes the upper FPS limit the program will run at. This value is '''60 by default.'''<br />
<br />
Don't set it too high, it'll eat all your CPU speed and make the game too responsive! Don't also set it too low, since UI and everything related to it uses the same FPS, so you'll find buttons and stuff not working.<br />
<br />
If you don't pass in any arguments, it will return the current fps cap. If you set the fpscap to 2, this will uncap the framerate.<br />
<br />
=== tpt.setdrawcap ===<br />
<br />
Changes the rate that particle graphics and the UI render to the screen. This is separate from the fpscap, which only affects the simulation. The drawcap allows TPT to skip drawing every frame. This may increase the framerate in some instances.<br />
<br />
The default is set to the maximum refresh rate of all attached monitors.<br />
<br />
=== tpt.setfire ===<br />
Changes the strength of the games glowing effects. tpt.setfire(1) is default.<br />
<br />
<code>tpt.setfire(number strength)</code><br />
<br />
=== tpt.setwindowsize ===<br />
<br />
<code>tpt.setwindowsize(number scale, number fullscreen)</code><br />
<br />
Changes a few special properties as to what size the game renders at.<br />
<br />
Scale is a multiplier by which every pixel shall get multiplied at, currently it can either be 1 (612x384) or 2 (1224x768). <br />
<br />
Full screen is a toggle (0 or 1) that enables "kiosk mode", which basically scales the game up to fill the screen and makes the rest of the edge black.<br />
<br />
=== tpt.toggle_pause ===<br />
Toggle pause.<br />
<br />
<code>tpt.toggle_pause()</code><br />
<br />
== Particles ==<br />
<br />
=== tpt.reset_spark ===<br />
Removes electrified wires from the simulation, resetting to the original material<br />
<br />
<code>tpt.reset_spark()</code><br />
<br />
=== tpt.set_property ===<br />
Set various properties of particles for given criteria, 8 overloads<br />
<br />
<code><br />
tpt.set_property(string property, object value)<br />
<br />
tpt.set_property(string property, object value, string type)<br />
<br />
tpt.set_property(string property, object value, number index)<br />
<br />
tpt.set_property(string property, object value, number index, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y)<br />
<br />
tpt.set_property(string property, object value, number x, number y, string type)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height)<br />
<br />
tpt.set_property(string property, object value, number x, number y, number width, number height, string type)<br />
</code><br />
<br />
=== tpt.set_wallmap ===<br />
Sets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_wallmap(number x, number y, number walltype)<br />
<br />
tpt.set_wallmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_wallmap ===<br />
Gets the wall at a position. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_wallmap(number x, number y)<br />
</code><br />
<br />
=== tpt.set_elecmap ===<br />
Sets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. The value is decremented by 1 every frame, just like SPRK .life, and when it reaches 0 the wall is "unsparked". Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.set_elecmap(number x, number y, number walltype)<br />
<br />
tpt.set_elecmap(number x, number y, number width, number height, number walltype)<br />
</code><br />
<br />
=== tpt.get_elecmap ===<br />
Gets the "electricity" flag for a wall at a position. This flag is usually set when walls are sparked. Uses wall/air map coordinates. Divide the actual coordinate by 4 to get the wall coordinate. So to set the wall at (100, 200), pass 100/4 for x and 200/4 for y.<br />
<br />
<code><br />
tpt.get_elecmap(number x, number y)<br />
</code><br />
<br />
=== tpt.get_property ===<br />
Returns various properties of a particle.<br />
<br />
<code><br />
tpt.get_property(string property, number index)<br />
<br />
tpt.get_property(string property, number x, number y)<br />
</code><br />
<br />
=== tpt.create ===<br />
Create a particle at location.<br />
<br />
<code>tpt.create(number x, number y, string type)</code><br />
<br />
Returns the index of the newly created particle.<br />
<br />
=== tpt.delete ===<br />
Delete a specific particle, or location.<br />
<br />
<code><br />
tpt.delete(number index)<br />
<br />
tpt.delete(number x, number y)<br />
</code><br />
<br />
=== tpt.start_getPartIndex ===<br />
Start the iterator for receiving all indices of the particles. (Used to help get particle indices, see tpt.next_getPartIndex)<br />
<br />
<code>tpt.start_getPartIndex()</code><br />
<br />
=== tpt.next_getPartIndex ===<br />
Jump to the next available particle index. Returns false if the iterator has reached the end of all particle indecies. Returns true if a new index was available. (Used to help get particle indecies, see tpt.getPartIndex)<br />
<br />
<code>tpt.next_getPartIndex()</code><br />
<br />
=== tpt.getPartIndex ===<br />
Get the current index iterator.<br />
<br />
<code>tpt.getPartIndex()</code><br />
<br />
index code example:<br />
<pre><br />
tpt.start_getPartIndex()<br />
while tpt.next_getPartIndex() do<br />
local index = tpt.getPartIndex()<br />
if tpt.get_property("ctype",index) == 21 then<br />
tpt.set_property("ctype","sing",index)<br />
end<br />
end<br />
</pre><br />
<br />
These functions are made obsolete by the function sim.parts(). That allows you to use Lua's iterators.<br />
<br />
=== tpt.get_numOfParts ===<br />
Returns the number of particles currently on the screen.<br />
<br />
<code>tpt.get_numOfParts()</code><br />
<br />
A newer way to get this is the variable sim.NUM_PARTS<br />
<br />
== Drawing ==<br />
<br />
=== tpt.textwidth ===<br />
Measures (in pixels) the width of a given string. Returns a number.<br />
<br />
<code>tpt.textwidth(string text)</code><br />
<br />
=== tpt.drawtext ===<br />
Draw text to the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawtext(number x, number y, string text)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue)<br />
<br />
tpt.drawtext(number x, number y, string text, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.drawpixel ===<br />
Draws a pixel on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawpixel(number x, number y)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue)<br />
<br />
tpt.drawpixel(number x, number y, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawline ===<br />
Draws a line on the screen (for one frame, only useful in scripts), 3 overloads. The line starts at point (x1, y1) and ends at point (x2,y2).<br />
<br />
<code><br />
tpt.drawline(number x1, number y1, number x2, number y2)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue)<br />
<br />
tpt.drawline(number x1, number y1, number x2, number y2, number red, number green, number blue, number alpha)<br />
<br />
</code><br />
<br />
=== tpt.drawrect ===<br />
Draws a rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.drawrect(number x, number y, number width, number height)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.drawrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
=== tpt.fillrect ===<br />
Draws a filled in rectangle on the screen (for one frame, only useful in scripts), 3 overloads<br />
<br />
<code><br />
tpt.fillrect(number x, number y, number width, number height)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue)<br />
<br />
tpt.fillrect(number x, number y, number width, number height, number red, number green, number blue, number alpha)<br />
</code><br />
<br />
Because tpt.fillrect is slightly broken in tpt, the coordinates will be off. It fills the rectangle from (x+1, y+1) to (x+w-1, y+h-1)<br />
<br />
== Input/Output ==<br />
<br />
=== tpt.log ===<br />
Log a message to the console<br />
<br />
<code>tpt.log(string text)</code><br />
<br />
=== tpt.message_box ===<br />
Display an OK-Only message box with a title and message.<br />
<br />
<code>tpt.message_box(string title, string message)</code><br />
<br />
=== tpt.input ===<br />
Ask the user to input some text. Returns a string of what ever the user says. The argument "text" is pre-entered text (optional).<br />
<br />
<code><br />
tpt.input(string title, string message)<br />
<br />
tpt.input(string title, string message, string text)<br />
</code><br />
<br />
=== tpt.throw_error ===<br />
Displays an error message box.<br />
<br />
<code>tpt.throw_error(string text)</code><br />
<br />
=== tpt.confirm ===<br />
Display an confirm message box with a title and message. Returns true if the button with button_name is clicked, returns false if Cancel is clicked.<br />
<br />
<code>tpt.confirm(string title, string message,string button_name)</code><br />
<br />
== Events ==<br />
<br />
The old event api was removed in 94.0, and is only still present through a compatibility script. Please use the new api instead: [[Lua_API:Event|Event]]<br />
<br />
=== tpt.register_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run on every frame<br />
<br />
<code>tpt.register_step(function func)</code><br />
<br />
=== tpt.unregister_step ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_step(function func)</code><br />
<br />
=== tpt.register_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time the mouse clicks.<br />
<br />
Your function will also be called when the mouse is released or held, or when the mouse wheel is used. Event equals 1 when the mouse gets pressed, 2 when the mouse gets released, and 3 if it is held. If your function returns false, mouse events in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: mousex, mousey, button, event<br />
<br />
<code>tpt.register_mouseclick(function func)</code><br />
<br />
=== tpt.unregister_mouseclick ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_mouseclick(function func)</code><br />
<br />
=== tpt.register_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Register a function to be run every time a key is pressed.<br />
<br />
Your function will also be called when a key is released. Event equals 1 when a key is pressed, and 2 when it gets released. If your function returns false, key presses in the normal Powder Toy will be ignored.<br />
<br />
Function arguments: key, nkey, modifier, event<br />
<br />
<code>tpt.register_keypress(function func)</code><br />
<br />
=== tpt.unregister_keypress ===<br />
'''This function is DEPRECATED in TPT 94.0 and is only provided via a compatibility script'''<br />
<br />
Unregister a previously registered function<br />
<br />
<code>tpt.unregister_keypress(function func)</code><br />
<br />
== Misc ==<br />
<br />
=== tpt.get_name ===<br />
Returns the current username.<br />
<br />
<code>tpt.get_name()</code><br />
<br />
=== tpt.setdebug ===<br />
Sets the "debug mode". It works using bitmasks, so you can turn on multiple debug features at the same time.<br/><br />
Setting 0x1 will display info on the number of particles on the screen.<br/><br />
Setting 0x2 will draw a graph showing the percentages of each type of element on the screen.<br/><br />
Setting 0x4 will display useful information when you draw lines using shift.<br/><br />
Setting 0x8 enables subframe particle debugging. Use alt+f to step one particle at a time. Use shift+f to step up to the particle underneath the mouse. When not over a particle, it advances to the end of the frame.<br />
<br />
<code>tpt.setdebug(number mode)</code><br />
<br />
=== tpt.element ===<br />
Returns an element's number. For example, it would return 28 for dmnd. If passed a number it will return the name instead.<br />
<br />
<code>tpt.element(string elementname)<br />
<br />
tpt.element(number elementid)</code><br />
<br />
=== tpt.element_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Update" instead.<br />
<br />
Allows you to replace or add on to an element's update function. Write a function like normal, and then put its name into this command. Use tpt.element("...") or tpt.el.dust.id for el_number. If replace is set to 1, the new function will be called after the original update function. If replace is set to 2, the original function will be overwritten. If replace is set to 3, the new function will be called before the original update function. Replace automatically defaults to 1. <br />
<br />
newfunction arguments: index, x, y, surround_space, nt<br />
<br />
Returns: return 1 from your function if the particle is killed.<br />
<br />
<code>tpt.element_func(function newfunction, number el_number)<br />
<br />
tpt.element_func(function newfunction, number el_number, number replace)</code><br />
<br />
=== tpt.graphics_func ===<br />
'''This function is DEPRECATED in TPT 97.0 and is only provided via a compatibility script'''<br />
<br/><br />
Use [https://powdertoy.co.uk/Wiki/W/Lua_API:Elements.html#elements.property elements.property] with "Graphics" instead.<br />
<br />
Allows you to replace an element's graphics function. Write a function like normal, and then put its name into this command. Use tpt.el.(name of element to change).id for el_number.<br />
<br />
Function arguments: index, colr, colg, colb<br />
<br />
Returns: cache, pixel_mode, cola, colr, colg, colb, firea, firer, fireg, and fireb.<br />
<br />
Set cache to 1 if you don't want the function to ever be called again, preventing lag. Don't do this if you need the way your element looks to change depending on its properties.<br />
<br />
colr/g/b are the red, green, and blue colors of your element. firea/r/g/b set the fire colors, but pixel_mode needs to be set to 0x00022000 for them to work.<br />
<br />
<code>tpt.graphics_func(function newfunction, number el_number)</code><br />
<br />
The pixel mode values you can use are:<br />
<pre><br />
PMODE_NONE 0x00000000 --prevents anything from being drawn<br />
PMODE_FLAT 0x00000001 --draw a basic pixel, overwriting the color under it. Doesn't support cola.<br />
PMODE_BLOB 0x00000002 --adds a blobby effect, like you were using blob (5) display mode<br />
PMODE_BLUR 0x00000004 --used in liquids in fancy display mode<br />
PMODE_GLOW 0x00000008 --Glow effect, used in elements like DEUT and TRON in fancy display mode<br />
PMODE_SPARK 0x00000010 -- used for things such as GBMB at first, dimmer than other modes<br />
PMODE_FLARE 0x00000020 --BOMB and other similar elements, brighter than PMODE_SPARK<br />
PMODE_LFLARE 0x00000040 --brightest spark mode, used when DEST hits something<br />
PMODE_ADD 0x00000080 --like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
PMODE_BLEND 0x00000100 --basically the same thing as PMODE_ADD, but has better OpenGL support<br />
PSPEC_STICKMAN 0x00000200 --does nothing, because the stickmen won't get drawn unless it actually is one<br />
<br />
NO_DECO 0x00001000 --prevents decoration from showing on the element (used in LCRY)<br />
DECO_FIRE 0x00002000 --Allow decoration to be drawn on using the fire effect (gasses have this set)<br />
<br />
FIRE_ADD 0x00010000 --adds a weak fire effect around the element (ex. LAVA/LIGH)<br />
FIRE_BLEND 0x00020000 --adds a stronger fire effect around the element, default for gasses<br />
<br />
EFFECT_GRAVIN 0x01000000 --adds a PRTI effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
EFFECT_GRAVOUT 0x02000000 --adds a PRTO effect. Might take some coding in an update function to get it to work properly, PRTI uses life and ctype to create the effects<br />
<br />
</pre><br />
<br />
You can combine them in any way you want, you probably need more than one anyway. Radioactive elements default to PMODE_FLAT+PMODE_GLOW, liquids to PMODE_FLAT+PMODE_BLUR, and gasses to FIRE_BLEND+DECO_FIRE, with a firea of 125 and firer/g/b of colr/g/b divided by 2<br />
<br />
See this for a picture of what they look like: https://powdertoy.co.uk/Wiki/W/File:Particle_Drawing_Modes.png.html<br />
<br />
=== tpt.screenshot ===<br />
Takes a screenshot of the current screen, minus the menu and HUD.<br />
<br />
<code>tpt.screenshot()<br />
<br />
tpt.screenshot(boolean fullscreen,number screenshot format)</code><br />
<br />
'''Screenshot format''':<br />
<br />
0 - png<br />
<br />
1 - bmp<br />
<br />
2 - ppm<br />
<br />
'''Examples''':<br />
<br />
tpt.screenshot(1,1) - take fullscreen screenshot in bmp format<br />
<br />
tpt.screenshot(1,2) - take fullscreen screenshot in ppm format<br />
<br />
=== tpt.get_clipboard ===<br />
Returns contents of the clipboard.<br />
<br />
<code>tpt.get_clipboard()</code><br />
<br />
=== tpt.set_clipboard ===<br />
Copy to clipboard.<br />
<br />
<code>tpt.set_clipboard(string text)</code><br />
<br />
= Constants =<br />
<br />
All of these constants can be accessed by tpt.<constant name><br />
<br />
=== tpt.selectedl ===<br />
Current element / tool on mouse1<br />
<br />
=== tpt.selectedr ===<br />
Current element / tool on mouse2<br />
<br />
=== tpt.selecteda ===<br />
Current element / tool on mouse3 (middle click)<br />
<br />
=== tpt.selectedreplace ===<br />
Current element to be used in replace mode (green outline)<br />
<br />
=== tpt.brushx ===<br />
Current brush width<br />
<br />
=== tpt.brushy ===<br />
Current brush height<br />
<br />
=== tpt.brushID ===<br />
Current brush ID, 0 = circle, 1 = square, 2 = triangle, higher = custom brushes<br />
<br />
Note that these constants are not read-only so if you run<br />
<pre>tpt.selectedl = "DEFAULT_PT_SPRK"</pre><br />
it will change the element on mouse1 to sprk<br />
<br />
= Simple Example Code =<br />
<pre><br />
-- This line is a comment. Anything written after the -- is considered a Comment and will not be read by Lua.<br />
-- Comment can be multiline, for this you should write it in --[[ and ]]--<br />
-- Set the console's state to 0. This will hide the console.<br />
tpt.set_console(0)<br />
<br />
-- Here we define our main function for the script<br />
local function ClassicPowder()<br />
local ox = 125 -- This will be our offset for the different elements we will create.<br />
local y = 4 -- where on the y (vertical) axis where we will create our elements.<br />
<br />
local x = ox -- where on the x (horizontal) axis where we will create our elements. we will start the x value with what ever ox is above.<br />
for i=0, 10 do -- this is a for loop. everything between the do and end will loop until i hits 10. i increases by 1 every loop.<br />
tpt.create(x + i, y, "STNE") --create a dust particle<br />
end<br />
<br />
x = x + ox -- increase the x axis value by the offset x (ox) value above<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "WATR") --create a water particle<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "SALT")<br />
end<br />
<br />
x = x + ox<br />
for i=0, 10 do<br />
tpt.create(x + i, y, "OIL")<br />
end<br />
<br />
return false<br />
end<br />
<br />
-- Register the step function ClassicPowder. This will make the ClassicPowder function run every tick of Powder Toy.<br />
tpt.register_step(ClassicPowder)<br />
</pre><br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Hotkeys&diff=8596Hotkeys2022-09-30T12:30:27Z<p>Maticzpl: Added "add to favourites" hotkey. More consistent naming</p>
<hr />
<div>{{Languages|Hotkeys}}<br />
<br />
== Single Hotkeys ==<br />
{|<br />
! Key || Description<br />
|-<br />
| Delete || Specific Element Erase mode (Ctrl+Alt+LMB to select element)<br />
|-<br />
| Insert or ; (semicolon) || Replace mode (Ctrl+Alt+LMB to select element to be replaced)<br />
|-<br />
| TAB || Circle/Square/Triangle Brush <br />
|-<br />
| Space || Pause <br />
|-<br />
| Q || Quit <br />
|-<br />
| Esc || Quit <br />
|-<br />
| Z || Zoom <br />
|-<br />
| S || Save stamp (+ Ctrl when STK2 is out) <br />
|-<br />
| L || Load last saved stamp <br />
|-<br />
| K || Stamp library <br />
|-<br />
| C || Cycle view mode <br />
|-<br />
| 0-9 || Set view mode <br />
|-<br />
| P || Save screenshot to .png<br />
|-<br />
| N || Toggles Newtonian Gravity. <br />
|-<br />
| F || Pause and go to next frame <br />
|-<br />
| G || Grid <br />
|-<br />
| H || Show/Hide HUD <br />
|-<br />
| D || Debug mode (+ Shift when STK2 is out) <br />
|-<br />
| I || Invert Pressure and Velocity map <br />
|-<br />
| W || Toggle gravity modes (+ Shift when STK2 is out) <br />
|-<br />
| Y || Toggle air modes <br />
|-<br />
| U || Toggle ambient heat <br />
|-<br />
| R || Record or rotate counter-clockwise when stamp preview is up (record does not work on version 92.5)<br />
|-<br />
| ~ || [[Lua| Lua console]] <br />
|-<br />
| = || Reset pressure and velocity map <br />
|-<br />
| [ || Decrease brush size <br />
|-<br />
| ] || Increase brush size <br />
|-<br />
| B || Edit decoration layer <br />
|-<br />
| E || Element search<br />
|-<br />
| F5 || Reload simulation<br />
|}<br />
<br />
== Key Combinations ==<br />
(RMB/LMB = Right/Left mouse button)<br />
{|<br />
! Key || Description<br />
|-<br />
| Ctrl + C/V/X || Copy/Paste/Cut <br />
|-<br />
| Ctrl + Z || Undo <br />
|-<br />
| Ctrl + G || Toggle display of Newtonian gravity field <br />
|-<br />
| Ctrl + B || Toggle display of decoration layer <br />
|-<br />
| Ctrl + Cursor drag || Rectangle <br />
|-<br />
| Shift + Cursor drag || Line <br />
|-<br />
| Shift + Alt + Cursor drag || Line snapping in steps of 45°<br />
|-<br />
| MMB / Alt + RMB/LMB click || Sample element <br />
|-<br />
| Mouse scroll / { } || Change brush size <br />
|-<br />
| CTRL + Mouse scroll / { } || Change vertical brush size <br />
|-<br />
| Shift + Mouse scroll / { } || Change horizontal brush size <br />
|-<br />
| Shift + Ctrl + R || Horizontal mirror for stamp (need stamp preview up) <br />
|-<br />
| Shift + R || Vertical mirror for stamp (need stamp preview up) <br />
|-<br />
| Ctrl + Arrow keys || Shift stamp in the direction of arrow key one pixel (no walls) <br />
|-<br />
| Ctrl + L alternative button + LMB || Select element or element menu for Specific Element Erase from the element menu or element menu list<br />
|-<br />
| Ctrl + = || Reset Electricity <br />
|-<br />
| Ctrl + Shift + LMB/RMB || Fill <br />
|-<br />
| Ctrl + I || Install Powder Toy<br />
|-<br />
| Ctrl + ; (semicolon) || Specific Element Erase mode (Ctrl + Alt + LMB to select element)<br />
|-<br />
| Ctrl + F || Find Specfic Element<br />
|-<br />
| Shift + 1 || Life gradient Note: only works when in debug mode(press D)<br />
|-<br />
| Ctrl + Y || Redo<br />
|}<br />
<br />
== Complete List ==<br />
{|<br />
=== Material Selection ===<br />
|-<br />
| LMB || Material 1 (Red)<br />
|-<br />
| RMB || Material 2 (Blue)<br />
|-<br />
| MMB || Material 3 (Green)<br />
|-<br />
| Ctrl + Alt + Click || Material 4 (Cyan) - for replace mode<br />
|-<br />
| Alt + Click || Sample<br />
|-<br />
| E || Element Search<br />
|-<br />
| Ctrl + Shift + LMB || Add To Favourites<br />
|}<br />
<br />
{|<br />
<br />
=== Brush ===<br />
|-<br />
| Tab || Brush Shape || Circle / Square / Triangle<br />
|-<br />
| Scroll || Brush Size<br />
|-<br />
| Ctrl + Scroll || Brush Size Vertical<br />
|-<br />
| Shift + Scroll || Brush Size Horizontal<br />
|-<br />
| ] || Increase Brush Size<br />
|-<br />
| [ || Decrease Brush Size<br />
|}<br />
<br />
{|<br />
=== Draw ===<br />
| Shift + Drag || Line<br />
|-<br />
| Shift + Alt + Drag || Line Snap<br />
|-<br />
| Ctrl + Drag || Area<br />
|-<br />
| Ctrl + Shift + Click || Fill<br />
|}<br />
<br />
{|<br />
=== Manipulate ===<br />
| Ctrl + C || Copy<br />
|-<br />
| Ctrl + V || Paste<br />
|-<br />
| Ctrl + X || Cut<br />
|-<br />
| Ctrl + R || Rotate<br />
|-<br />
| Shift + R || Flip Horizontal<br />
|-<br />
| Ctrl + Shift + R || Flip Vertical<br />
|-<br />
| Arrow Keys || Nudge<br />
|}<br />
<br />
{|<br />
<br />
=== Display ===<br />
| 1-9, 0 || Display Modes || Velocity / Pressure / Persistent / Fire / Blob / Heat / Fancy / Nothing / Heat Gradient / Alternative Velocity<br />
|-<br />
| B || Edit Decoration Layer<br />
|-<br />
| Ctrl + F || Highlight Selected Element || (Material 1)<br />
|-<br />
| G || Grid Modes || Small-Large<br />
|-<br />
| H || Toggle HUD<br />
|-<br />
| Z || Zoom<br />
|-<br />
| Z + Scroll || Magnify / Reduce<br />
|-<br />
| Z + Click || Fix Window<br />
|}<br />
<br />
{|<br />
=== Modes & Functions ===<br />
| W (+ Shift) || Gravity Modes || Off / Radial / Vertical<br />
|-<br />
| Y || Air Modes || Off / No Update / On / Pressure Off / Velocity Off<br />
|-<br />
| ; || Replace Mode || (Material 3)<br />
|-<br />
| Ctrl + ; || Specific Delete Mode || (Material 3)<br />
|-<br />
| D (+ Shift) || Debug Mode<br />
|-<br />
| = || Reset Pressure<br />
|-<br />
| Ctrl + = || Reset Electricity<br />
|-<br />
| R || Reset Life Generation<br />
|-<br />
| I || Invert pressure and velocity<br />
|}<br />
<br />
{|<br />
=== Top Right Panel ===<br />
| Top Right + Click || [P] Sand Effect || Displays color variation for materials<br />
|-<br />
| Ctrl + G || [G] Gravity Field || Displays intensity of gravity in a field<br />
|-<br />
| Ctrl + B || [D] Draw Decorations || Displays custom colors set for materials<br />
|-<br />
| N || [N] Newtonian Gravity || Allows for some materials to alter how gravity works<br />
|-<br />
| U || [A] Ambient Heat || Allows for air to also have temperature<br />
|-<br />
| ~ || [C] Show Console || Command Text Box<br />
|}<br />
<br />
{|<br />
=== Stamps ===<br />
| S (+ Ctrl) || Save Stamp<br />
|-<br />
| L || Load Last Stamp<br />
|-<br />
| K || Browse Saved Stamps<br />
|}<br />
<br />
{|<br />
=== Simulation ===<br />
| Spacebar || Pause<br />
|-<br />
| F || Step / Next frame<br />
|-<br />
| F5 || Reload Simulation<br />
|-<br />
| Ctrl + Z || Undo<br />
|-<br />
| Ctrl + Shift + Z || Redo<br />
|-<br />
| Esc / Q || Back / Quit</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Complete_Electronics_Tutorial&diff=8533Complete Electronics Tutorial2022-06-03T12:12:25Z<p>Maticzpl: ARAY life property</p>
<hr />
<div>This page is currently a work in progress.<br />
<br />
The goal of this page is to be a complete electronics tutorial for new players and seasoned ones who want to learn more about electronics, and to replace the existing electronics tutorial that has not been updated since 2011.<br />
<br />
==Intro to Electronics==<br />
<br />
This section is primarily for new players, so if you already know about the basics of electricity, SWCH, WIFI, and INST, you can skip ahead to the next section.<br />
<br />
===Basics of Electricity in TPT===<br />
<br />
====How SPRK Works====<br />
<br />
SPRK, found in the electronics menu, is the basis of all electronics in TPT. SPRK is an indestructible solid that cannot be placed, but it can be "drawn" on to metals and conductive elements. SPRK will transfer itself to any conductive elements within 2 pixels. This allows SPRK to move along conductive elements, which include all metals, WATR and SLTW, MERC, and QRTZ (when under pressure). As seen below, different conductors (METL, GOLD, WATR, and SLTW) conduct at different speeds.<br />
<br />
[[File:1-6-Conductivity.gif]]<br />
<br />
=====Technical Details=====<br />
When a conductive element is sparked, it is replaced with SPRK and the ctype of the SPRK is set to that element. The life of the SPRK is set to 4 and when it reaches 0, the SPRK will replace itself with its ctype, allowing it to turn back into the original element, but with a life set back to 4. The conductor will not be sparkable again until the life reaches 0 - meaning that 8 frames are required for one complete spark cycle.<br />
<br />
====Basic Conductors====<br />
<br />
The most basic conductors are METL, PSCN, and NSCN, which are found in the electronics menu. These are what you will use most of the time to transfer electricity. METL conducts to both PSCN and NSCN, and both PSCN and NSCN conduct to metal, as demonstrated below.<br />
<br />
[[File:1-1-Conductors.gif]]<br />
<br />
However, things get a bit complicated. While PSCN conducts to both METL and NSCN, NSCN cannot conduct to PSCN.<br />
<br />
[[File:1-2-Silicon.gif]]<br />
<br />
This behavior can be used to make a diode, which allows electricity to flow only one way.<br />
<br />
[[File:1-3-Diode.gif]]<br />
<br />
====Using BTRY====<br />
<br />
BTRY is an element that can be used to constantly spark any conductor. Simply place one pixel of it and it will work.<br />
<br />
[[File:1-4-Battery.gif]]<br />
<br />
====Using INSL====<br />
<br />
Another useful electronic element is INSL, which completely blocks heat and electricity. This can be used to prevent SPRK from jumping over a 1-pixel gap.<br />
<br />
[[File:1-5-INSL.gif]]<br />
<br />
===Using SWCH to Control Electronics===<br />
<br />
SWCH is an element that is used to control the flow of electricity by turning it on and off. SWCH is turned on and off by PSCN and NSCN, like many other powered elements you will learn about later, and conducts to and from METL.<br />
<br />
[[File:1-8-SWCH.gif]]<br />
<br />
===Using WIFI to Transfer Electricity===<br />
<br />
WIFI makes it easy to transfer electricity instantly over long distances instead of using long wires. WIFI takes electricity from all conductors except NSCN, and will pass electricity to any NSCN, PSCN, or INWR. After placing a pixel of WIFI (it must be used in single pixels), you have to set the channel. WIFI has 100 temperature-dependent channels located every 100 degrees, which can be set manually using the PROP tool, but the recommended way is to use jacob1's Set WIFI script found in the [https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=19400 Lua Script Manager]. This useful tool simply asks you to input the channel number and sets it for you. As seen in the picture, WIFI's color is dependent on its channel.<br />
<br />
[[File:1-9-WIFI.gif]]<br />
<br />
===Using INST===<br />
<br />
INST is another way to transfer electricity instantly over long distances, but in the form of a wire. Unlike other conductive elements, INST can only take electricity from PSCN and can only conduct to NSCN and GOLD. It can not conduct to itself over 1-pixel gaps, and it can cross over itself freely, making it possibly one of the most useful electronic elements.<br />
<br />
[[File:1-7-INST.gif]]<br />
<br />
==Basic ARAY Usage==<br />
<br />
===ARAY Basics===<br />
<br />
ARAY is an element that allows another way of transferring electricity over a long distance, and it is also the fastest conductor in the game, which helps with making electronic devices more compact and faster. Unlike other electronic elements, it must be triggered by an adjacent conductor, which must be METL, PSCN (which will be covered later), or INST. When triggered, it emits a line of BRAY (a hidden solid element) that fades away after 30 frames. If this BRAY hits a conductor, it will spark it.<br />
<br />
[[File:2-1-ARAY.gif]]<br />
<br />
If 2 of these BRAY rays collide, it will create a "point" of BRAY that lasts for 1020 frames. <br />
<br />
[[File:2-2-Point.gif]] <br />
<br />
If two BRAYs pass next to each other, even if they are touching, nothing will happen. This makes BRAY useful as a way to make compact connections by transmitting many BRAY beams next to each other.<br />
<br />
===Useful ARAY Tricks===<br />
<br />
====Using ARAY with SWCH====<br />
<br />
Along with switching electricity on and off, SWCH can also be used to control BRAY. When SWCH is on, BRAY can freely pass through, but when it is off, BRAY is blocked.<br />
<br />
[[File:2-4-SWCH.gif]]<br />
<br />
====Using ARAY with FILT====<br />
<br />
FILT can be used to remove the 30-frame delay when firing ARAY, making it the fastest way to conduct electricity. Simply draw FILT where the BRAY beam will be, and use the ARAY. BRAY will disappear instantly inside FILT, and beams can intersect without creating points. BRAY that passes through FILT will take on the wavelength of the FILT.<br />
<br />
[[File:2-3-FILT.gif]]<br />
<br />
====Using ARAY with INST====<br />
<br />
One more useful feature of ARAY is that if it is triggered with INST, the BRAY beam will pass through multiple conductors. The INST-BRAY beam can be stopped with INSL.<br />
<br />
[[File:2-5-INST_ARAY.gif]]<br />
<br />
==Using PTCT and NTCT To Make Logic Gates==<br />
<br />
===PTCT/NTCT Basics===<br />
<br />
PTCT and NTCT are elements found in the electronics menu that conduct electricity based on how hot they are. PTCT only conducts when cold (<100 degrees) and NTCT only conducts when hot (>100 degrees). The easiest way to heat them is to spark a pixel of METL placed 1 pixel away, as METL gradually heats up when sparked.<br />
<br />
The image below shows PTCT (bottom) and NTCT (top) in action.<br />
<br />
[[File:3-1-PTCT NTCT.gif]]<br />
<br />
===Logic Gates===<br />
<br />
If you are new to TPT and electronic engineering, you might be wondering what logic gates are. Logic gates are electronic devices that create an output based on inputs they receive. They work the same way in real-life electronic circuits and in TPT. Every basic logic gate has 2 inputs (with the exception of the NOT gate) and 1 output. Both the inputs and the output can be one of two states: ON and OFF, HIGH and LOW, or 1 and 0. In TPT, ON/HIGH/1 means that the output is sparked and OFF/LOW/0 means that it is not sparked. This tutorial will use HIGH and LOW.<br />
<br />
While PTCT and NTCT can be used to make logic gates, they have mostly been replaced by much faster logic gates made using advanced ARAY techniques, which you will learn about later. However, it is still a good idea to learn how PTCT/NTCT logic works, because you might see it when looking at older electronics saves.<br />
<br />
====OR Gates====<br />
<br />
An OR gate is a logic gate that will output HIGH if either of its inputs or both of its inputs are HIGH and the easiest to make in TPT as it consists of 2 diodes with the output connected together.<br />
<br />
[[File:3-3-Or.gif]]<br />
<br />
====AND Gates====<br />
<br />
An AND gate will only output HIGH when both of its inputs are HIGH. It is the easiest-to-understand logic gate using the old technology.<br />
<br />
[[File:3-2-And.gif]]<br />
<br />
====XOR Gates====<br />
<br />
A XOR gate (eXclusive OR) will only output HIGH if one of its inputs is HIGH (not both). It is one of the more complicated gates to create at a small size in TPT, but luckily someone has already done that for you.<br />
<br />
[[File:3-4-Xor.gif]]<br />
<br />
====NOT Gates====<br />
<br />
Unlike the other logic gates here, a NOT gate only has one input and will only output HIGH if the input is low. This is easy to do with PTCT, which will not conduct when heated.<br />
<br />
[[File:3-5-Not.gif]]<br />
<br />
====NOR Gates====<br />
<br />
A NOR gate (Not OR) can be thought of as an OR gate with a NOT gate connected to the output. It will only output HIGH if none of its inputs are HIGH.<br />
<br />
[[File:3-6-Nor.gif]]<br />
<br />
====NAND Gates====<br />
<br />
A NAND gate (Not AND) can be thought of as an AND gate with a NOT gate connected to the output. It will only output HIGH if none or 1 of its inputs is HIGH.<br />
<br />
[[File:3-7-Nand.gif]]<br />
<br />
====XNOR Gates====<br />
<br />
A XNOR gate (eXclusive Not OR) can be thought of as a XOR gate with a NOT gate connected to the output. It will only output HIGH if none or both of its inputs are HIGH.<br />
<br />
[[File:3-8-Xnor.gif]]<br />
<br />
==Useful Electronic Devices==<br />
This section will show some useful basic electronic components that can be created with the elements shown so far. <br />
<br />
===SWCH Memory===<br />
<br />
Because SWCH maintains its state when turned on or off, it can be used to make the simplest form of memory in TPT:<br />
<br />
[[File:5-1-SWCH RAM 1.gif]]<br />
<br />
ARAY is used to spark PSCN within the conduction range of the SWCH, which turns it on, writing to the memory. INST is used to trigger ARAY which activates more ARAY directed through the SWCH. The BRAY will only pass through pixels of SWCH which are turned on by the PSCN, which effectively allows the memory to be read. Another INST-triggered ARAY sparks a pixel of NSCN next to each pixel of SWCH, which clears the memory.<br />
<br />
SWCH memory can be made more compact, as shown in this example:<br />
<br />
[[File:5-2-SWCH RAM 2.gif]]<br />
<br />
This is done simply by moving everything closer together, using INSL as needed to prevent unwanted SPRK transfer. SWCH memory can be made even smaller by layering, which is beyond the scope of this tutorial. Larger arrays of SWCH memory are also possible, but are now considered obsolete because of CRAY memory, which is shown later.<br />
<br />
===Shift Registers===<br />
<br />
By modifying the concept of SWCH memory, a shift register can be made. A shift register takes input data, either as serial (a series of pulses on one wire) or parallel (pulses on several wires), and can shift it in one direction, giving either a parallel or serial output. A serial-in parallel-out shift register is shown below.<br />
<br />
[[File:5-3-SIPO Shift Register.gif]]<br />
<br />
Parallel-in serial-out shift registers can also be created:<br />
<br />
[[File:5-4-PISO Shift Register.gif]]<br />
<br />
A simple serial data link can be made using a parallel-in serial-out shift register to send data and a serial-in parallel-out shift register to receive data. This is the same principle by which real-life serial data protocols like USB and RS-232 work in hardware. However, in TPT, there is a much faster and simpler way of sending data serially using BRAY and FILT wavelengths which is shown later.<br />
<br />
====Decimal Counters====<br />
<br />
A simple decimal counter can be made by connecting the last output of a serial-in parallel-out shift register to its input. The counter will increment by one every time the shift input is sparked:<br />
<br />
[[File:5-5-Decimal Counter.gif]]<br />
<br />
By removing any unnecessary parts, it can be made even smaller:<br />
<br />
[[File:5-6-Decimal Counter 2.gif]]<br />
<br />
====Shift Register Latches====<br />
<br />
In order to read the output of a serial-in parallel-out shift register without shifting it, you can add SWCH memory to the output and connect the ARAY that reads the memory to the INST that shifts the register.<br />
<br />
[[File:5-7-Shift Register Latch.gif]]<br />
<br />
===Decimal to Binary Converters===<br />
<br />
Another property of ARAY can be used to make a simple decimal to binary converter:<br />
<br />
[[File:5-8-Decimal To Binary.gif]]<br />
<br />
The horizontal ARAYs spark the NSCN, which sparks the INWR, which sparks the ARAYs that point to the output. This works because BRAY passes harmlessly through any INWR and ARAY in its path. The example only outputs a 3-bit binary number, but can easily be expanded. <br />
<br />
===Binary to Decimal Converters===<br />
<br />
Binary to decimal converters can be made by toggling SWCH in specific patterns for each bit and firing ARAY through it: <br />
<br />
[[File:5-9-Binary To Decimal.gif]]<br />
<br />
Binary to decimal converters using advanced ARAY techniques (shown later) are smaller but more complicated to make.<br />
<br />
==Using Other Electronic Elements==<br />
<br />
===Using DLAY===<br />
<br />
DLAY is an electronic element found in the powered elements menu. It only conducts from PSCN to NSCN and creates a delay for an amount of frames determined by its temperature. The default temperature is 4 degrees, which will create a 4-frame delay.<br />
<br />
[[File:4-1-DLAY.gif]]<br />
<br />
===Using FRAY===<br />
<br />
FRAY is an electronic element that pushes or pulls particles when sparked based on its temperature. A positive temperature will push particles and a negative temperature will pull on them. With a high enough temperature, a single particle can be accelerated enough to break GLAS.<br />
<br />
[[File:4-2-FRAY.gif]]<br />
<br />
===Using STOR===<br />
<br />
STOR is an electronic element that stores a single particle and releases it when powered with PSCN. It can be used to precisely dispense single particles instead of using PPIP. It can also directly pass to an adjacent PIPE or PPIP without any PSCN input.<br />
<br />
[[File:4-3-STOR.gif]]<br />
<br />
===Using Sensors===<br />
<br />
There are 3 sensors in TPT which are all found in the sensors menu. They are DTEC, which sparks any nearby conductors if it detects a particle of its ctype in its detection range (this is set by tmp2, see the DTEC page for details), TSNS, which sparks any nearby conductors if it is touching a particle with a temperature higher than its own, and PSNS, which sparks any nearby conductors when the pressure is higher than its temperature.<br />
<br />
===Using Powered Elements===<br />
<br />
====LCRY====<br />
<br />
LCRY is a powered element that is activated by PSCN and deactivated by NSCN. By default, it will change color to a lighter gray when turned on, but if it has a decoration color, it will be black when off and it will change to its decoration color when on.<br />
<br />
====PUMP and GPMP====<br />
<br />
PUMP and GPMP are powered elements that are activated with PSCN and deactivated with NSCN. PUMP will create pressure equal to its temperature and GPMP will create gravity equal to its temperature (Newtonian Gravity must be enabled.)<br />
<br />
====HSWC====<br />
<br />
HSWC is a powered element that is activated by PSCN and deactivated by NSCN. When turned off it does not conduct heat, but when turned on it conducts heat quickly.<br />
<br />
====PCLN/PBCN/PVOD/PPIP====<br />
<br />
These are all powered elements activated by PSCN and deactivated by NSCN that act as CLNE, BCLN, VOID, and PIPE when turned on.<br />
<br />
==Using CRAY, DRAY, and PSTN==<br />
<br />
===Using CRAY===<br />
<br />
CRAY is similar to ARAY except that it emits a beam of any other particles. The particle type that it emits can be set using its ctype or by drawing over it with an element. The temperature of the emitted particles is determined by the temperature of the CRAY.<br />
<br />
CRAY can emit particle beams in 8 directions:<br />
<br />
[[File:6-1-CRAY 1.gif]]<br />
<br />
The tmp property of CRAY changes the length of the particle beam...<br />
<br />
[[File:6-2-CRAY Tmp.gif]]<br />
<br />
and the tmp2 property changes the number of pixels skipped before the beam starts:<br />
<br />
[[File:6-3-CRAY Tmp2.gif]]<br />
<br />
By placing FILT in front of CRAY, the decoration color of the emitted particles can be set:<br />
<br />
[[File:6-4-CRAY FILT.gif]]<br />
<br />
====CRAY Modes====<br />
<br />
CRAY can be used in different modes by sparking it through different elements:<br />
<br />
[[File:6-5-CRAY Types.gif]]<br />
<br />
When sparked through METL, the CRAY beam will stop at the first particle other than FILT in its path. When sparked through PSCN, the CRAY beam will, for every pixel in its path, if the pixel is occupied by a particle it will be erased, and if the pixel is not occupied by a particle one will be created. When sparked through INWR, as many particles as the CRAY's tmp value will be created, ignoring but not overwriting any particles already in its path.<br />
<br />
===Using DRAY===<br />
<br />
===Using PSTN===<br />
<br />
PSTN is an electronic element that moves other particles. The most basic way to use PSTN is to place two pixels of PSTN with a pixel of PSCN and NSCN each one pixel away. PSTN extends when the PSCN is sparked and retracts when the NSCN is sparked.<br />
<br />
[[File:6-6-PSTN.gif]]<br />
<br />
By default, PSTN is sticky, meaning it will pull particles back when it retracts. This can be changed, as you will see later.<br />
<br />
[[File:6-7-PSTN Sticky.gif]]<br />
<br />
A common way to use PSTN in electronics is to place a particle of METL or DLAY so the PSCN conducts to it and then to the NSCN so the PSTN automatically retracts.<br />
<br />
[[File:6-10-PSTN Autoretract.gif]]<br />
<br />
====Using FRME====<br />
<br />
When PSTN pushes one particle of FRME with others touching it, all of the FRME particles will move at the same time. This allows PSTN to move many particles at once.<br />
<br />
[[File:6-11-PSTN FRME.gif]]<br />
<br />
FRME can be made non-sticky by changing its tmp value to 1.<br />
<br />
[[File:6-12-PSTN FRME Nonsticky.gif]]<br />
<br />
====Using PSTN's Temperature====<br />
<br />
The distance by which PSTN extends each frame can be controlled by either making the PSTN longer and moving the PSCN and NSCN further away from the extending end, or by setting the temperature of the PSTN. PSTN extends by its temperature in degrees above 0C divided by 10 and rounded to the nearest whole number, summed over all PSTN particles from the one receiving the spark to the one at the extending end of the PSTN, all minus one particle.<br />
<br />
This save demonstrates how to use PSTN's temperature to make PSTN that can instantly extend the distance specified by a binary input:<br />
{{ save | id=2038496 }}<br />
<br />
====Other PSTN Properties====<br />
<br />
PSTN's ctype determines what particle type it will stop extending at if it hits.<br />
<br />
[[File:6-9-PSTN Ctype.gif]]<br />
<br />
PSTN's tmp2 can be used in a similar way to limit the maximum extension length.<br />
<br />
[[File:6-8-PSTN Tmp2.gif]]<br />
<br />
PSTN's tmp can be used to set the maximum number of particles it can move.<br />
<br />
==Advanced ARAY Usage==<br />
<br />
===Erase BRAY===<br />
<br />
When ARAY is sparked with PSCN, it creates orange BRAY called erase BRAY. Erase BRAY does not spark objects, disappears in 2 frames, unlike normal BRAY which disappears in 30 frames, and erases any other BRAY in its path.<br />
<br />
[[File:7-1-Erase BRAY.gif]]<br />
<br />
INST-ARAY and PSCN-ARAY can be combined to fire normal BRAY which is then quickly erased, allowing the normal BRAY to spark its target every 4 frames without needing FILT in its path..<br />
<br />
[[File:7-2-Auto-Erase BRAY.gif]]<br />
<br />
ARAY life property can be changed to make BRAY disappear faster or last longer allowing for a custom ARAY cooldown.<br />
<br />
[[File:7-3-BRAY-life.gif]]<br />
<br />
===Binary Counters===<br />
<br />
===FILT ROM===<br />
<br />
===Faster Logic Gates===<br />
<br />
===CRAY RAM===<br />
<br />
===ARAY and FILT Wavelengths===<br />
<br />
====Better FILT ROM====</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=File:7-3-BRAY-life.gif&diff=8532File:7-3-BRAY-life.gif2022-06-03T12:11:18Z<p>Maticzpl: Showcases how ARAY life property affects the life of BRAY</p>
<hr />
<div>Showcases how ARAY life property affects the life of BRAY</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Renderer&diff=8325Lua API:Renderer2021-11-22T17:44:40Z<p>Maticzpl: Zoom methods</p>
<hr />
<div>The renderer api can be used to control how the simulation in TPT gets rendered. You can set render / display modes, and change things related to the HUD / grid mode. Some renderer related functions are in the legacy tpt.* api.<br />
<br />
ren.* is an alias for renderer.* and can be used to write things shorter.<br />
<br />
== Methods ==<br />
<br />
=== renderer.renderModes ===<br />
table ren.renderModes()<br />
ren.renderModes(table newModes)<br />
If called with no arguments, returns a table containing the currently activated render modes. If called with a table argument, turns on all the render modes specified in the table. Render modes are typically used to change the way all particles render, display modes set extra added effects.<br />
<br />
Print out all current render modes in hex:<br />
<syntaxhighlight lang="lua"><br />
for k,v in pairs(ren.renderModes()) do<br />
print(k,"0x"..bit.tohex(v))<br />
end<br />
>>1, 0x00fff380; 2, 0xff00f270; 3, 0x0400f381<br />
</syntaxhighlight><br />
<br />
<br />
Set the current render mode to a weird form of blob display<br />
<syntaxhighlight lang="lua"><br />
ren.renderModes({ren.RENDER_BLOB, ren.RENDER_EFFE})<br />
</syntaxhighlight><br />
<br />
=== renderer.displayModes ===<br />
table ren.displayModes()<br />
ren.displayModes(table newModes)<br />
Works exactly like rennder.renderModes(). If called with no arguments, returns a table containing the currently activated display modes. If called with a table argument, turns on all the display modes specified in the table. Render modes are typically used to change the way all particles render, display modes set extra added effects.<br />
<br />
Print out all current display modes in hex:<br />
<syntaxhighlight lang="lua"><br />
for k,v in pairs(ren.displayModes()) do<br />
print(k,"0x"..bit.tohex(v))<br />
end<br />
>>1, 0x00000002; 2, 0x00000010<br />
</syntaxhighlight><br />
<br />
<br />
Set the current display mode to persistent with cracker velocity display<br />
<syntaxhighlight lang="lua"><br />
ren.displayModes({ren.DISPLAY_AIRC, ren.DISPLAY_PERS})<br />
</syntaxhighlight><br />
<br />
=== renderer.colourMode ===<br />
number ren.colourMode()<br />
ren.colourMode(number colourMode)<br />
<br />
number ren.colorMode<br />
ren.colorMode(number colourMode)<br />
<br />
This function takes one optional integer and sets which colour modes the currently appIying render mode uses. If the function is called with no arguments, it returns the current colour mode as an integer as well.<br />
<br />
A colour mode is basically a description of how particles are drawn. The other details which are considered when particles are drawn are fire mode, pixel mode and effect mode (rare cases like portals).<br />
<br />
On the bottom of this page there's [[#Color_modes|a list of descriptions]] of what each colour mode does.<br />
<br />
=== renderer.decorations ===<br />
number ren.decorations()<br />
ren.decorations(number decoSetting)<br />
If called with no arguments, returns a 0 or a 1 representing the current deco mode setting. If a number is passed in, turns decorations on or off.<br />
<br />
=== renderer.grid ===<br />
number ren.grid()<br />
ren.grid(number gridSize)<br />
If called with no arguments, returns the current grid size (normally set with 'g'). Grid sizes range from 0 (no grid) to 9. Each size increases the number of pixels between lines by 4.<br />
<br />
If an argument is passed in, sets the current grid size. There are no checks to make sure it is in the valid range, but if negative numbers are passed in it may cause strange behavior.<br />
<br />
=== renderer.debugHUD ===<br />
number ren.debugHUD()<br />
ren.debugHUD(number debugSetting)<br />
If called with no arguments, returns a 0 or a 1 representing whether the debug HUD (normally set with 'd') is on or off. If a number is passed in, turns the debug HUD on or off.<br />
<br />
=== renderer.showBrush ===<br />
number ren.showBrush()<br />
ren.showBrush(number brushSetting)<br />
If called with no arguments, returns a 0 or a 1 representing whether the brush is currently shown. If a number is passed in, disables rendering the brush. This function is intended for recording scripts which want to hide the brush and other hud elements.<br />
<br />
=== renderer.zoomEnabled ===<br />
ren.zoomEnabled(bool zoomState)<br />
bool ren.zoomEnabled()<br />
If called with no arguments, returns a boolean indicating whether the zoom window is open or not. <br />
If a number is passed in, it shows or hides the zoom window.<br />
<br />
=== renderer.zoomScope ===<br />
number, number, number ren.zoomScope()<br />
ren.zoomScope(number x, number y, number size)<br />
The zoom scope defines the area where to zoom in.<br />
If called with no arguments, returns 3 numbers: left top corner X position, left top corner Y position and its size. <br />
If arguments are passed then the zoom scope will be moved to the specified X and Y coordinates (from its top left corner). It will also make it span the amount of pixels specified by the 'size' argument equally in width and height.<br />
<br />
=== renderer.zoomWindow ===<br />
number, number, number, number ren.zoomWindow()<br />
ren.zoomWindow(number x, number y, number zoomFactor)<br />
The zoom window displays the magnified image.<br />
If called with no arguments, returns 4 numbers: left top corner X position, left top corner Y position, the zoom factor and the inner window size in pixels. <br />
If arguments are passed then the zoom window will be moved to the specified X and Y coordinates (from its top left corner) and change its zoom factor.<br />
<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with renderer.<constant name here><br />
<br />
=== Particle graphics function modes ===<br />
These should be used in lua graphics functions to set how particles will be drawn. Effects like fire, glowing, and flares are set here. How a particle is actually rendered depends on the current render and display modes.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>value</b><br />
|<b>description</b><br />
|-<br />
|PMODE<br />
|0x00000FFF<br />
|A bitmask which can be used to check if a particle has any PMODEs set.<br />
|-<br />
|PMODE_NONE<br />
|0x00000000<br />
|Don't draw a point where a particle is at all. Unused.<br />
|-<br />
|PMODE_FLAT<br />
|0x00000001<br />
|Draw a basic pixel, overwriting the color under it. Given by default to everything unless overridden, Doesn't support cola.<br />
|-<br />
|PMODE_BLOB<br />
|0x00000002<br />
|Draw a blob like in blob mode. Everything is given this in blob display mode, but can be set manually.<br />
|-<br />
|PMODE_BLUR<br />
|0x00000004<br />
|Blur effect, used in fancy display mode. Given to all liquids without a graphics functions by default, if not this isn't set.<br />
|-<br />
|PMODE_GLOW<br />
|0x00000008<br />
|Glow effect, used in elements like DEUT and TRON in fancy display mode, also given to radioactive elements.<br />
|-<br />
|PMODE_SPARK<br />
|0x00000010<br />
|Draws a very light sparkle around a particle.<br />
|-<br />
|PMODE_FLARE<br />
|0x00000020<br />
|Draws a flare around a particle, used by BOMB.<br />
|-<br />
|PMODE_LFLARE<br />
|0x00000040<br />
|Very large and bright flare, used by DEST when it hits something.<br />
|-<br />
|PMODE_ADD<br />
|0x00000080<br />
|Like PMODE_FLAT, but adds color to a pixel, instead of overwriting it.<br />
|-<br />
|PMODE_BLEND<br />
|0x00000100<br />
|Basically the same thing as PMODE_ADD, but has better OpenGL support<br />
|-<br />
|PSPEC_STICKMAN<br />
|0x00000200<br />
|Used by stickmen. Won't do anything unless the element actually is a stickman.<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|OPTIONS<br />
|0x0000F000<br />
|A bitmask which can be used to check if a particle has any display options set.<br />
|-<br />
|NO_DECO<br />
|0x00001000<br />
|Prevents decoration from being shown on an element.<br />
|-<br />
|DECO_FIRE<br />
|0x00002000<br />
|Allows decoration to be drawn onto the fire effect. All gasses have this on by default.<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|FIREMODE<br />
|0x00FF0000<br />
|A bitmask which can be used to check if a particle has any fire graphics set.<br />
|-<br />
|FIRE_ADD<br />
|0x00010000<br />
|Adds a weak fire effect around an element. Does not support many colors like FIRE_BLEND does.<br />
|-<br />
|FIRE_BLEND<br />
|0x00020000<br />
|Adds a stronger fire effect around an element. All gasses have this on by default.<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|EFFECT<br />
|0xFF000000<br />
|A bitmask which can be used to check if a particle has any special effects set.<br />
|-<br />
|EFFECT_GRAVIN<br />
|0x01000000<br />
|Adds a PRTI effect. Won't work unless .life and .ctype are set properly in an update function.<br />
|-<br />
|EFFECT_GRAVOUT<br />
|0x02000000<br />
|Adds a PRTO effect. Won't work unless .life and .ctype are set properly in an update function.<br />
|-<br />
|EFFECT_LINES<br />
|0x04000000<br />
|Used by SOAP to draw lines between attached SOAP particles. Ignored by everything else.<br />
|-<br />
|EFFECT_DBGLINES<br />
|0x08000000<br />
|Draw lines between particles of the same type with similar temperatures. Used by WIFI and portals to draw lines between particles of the same channel when in debug mode.<br />
|}<br />
<br />
=== Render modes ===<br />
These are the values used and returned by ren.renderMode. They are combinations of the above values, and sometimes overlap. All source definitions also include OPTIONS and PSPEC_STICKMAN (so that options can always be set and stickmen are always rendered), but they are not listed here.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>definition in source</b><br />
|<b>description</b><br />
|-<br />
|RENDER_EFFE<br />
| EFFECT | PMODE_SPARK | PMODE_FLARE | PMODE_LFLARE<br />
|Used in all display modes except for heat, nothing, heat gradient, and life gradient. Turns on all basic effects like flares and portal effects.<br />
|-<br />
|RENDER_FIRE<br />
| PMODE_ADD | PMODE_BLEND | FIREMODE<br />
|Used in fire, blob, and fancy display modes. Turns on all fire effects.<br />
|-<br />
|RENDER_GLOW<br />
|PMODE_GLOW | PMODE_ADD | PMODE_BLEND<br />
|Used in fancy display mode, so that radioactive elements glow.<br />
|-<br />
|RENDER_BLUR<br />
|PMODE_BLUR | PMODE_ADD | PMODE_BLEND<br />
|Used in fancy display mode, to turn on the liquid blur effect.<br />
|-<br />
|RENDER_BLOB<br />
|PMODE_BLOB | PMODE_ADD | PMODE_BLEND<br />
|causes every particle to get PMODE_BLOB.<br />
|-<br />
|RENDER_BASC<br />
|PMODE_FLAT | PMODE_ADD | PMODE_BLEND | EFFECT_LINES<br />
|Used by every single display mode, turns on PMODE_FLAT so particles get displayed.<br />
|-<br />
|RENDER_NONE<br />
|PMODE_FLAT<br />
|Not used at all, but would make sure at least each individual pixel gets drawn.<br />
|}<br />
<br />
=== Display modes ===<br />
These are the values used and returned by ren.displayMode. They can be set together, although no official display mode does this.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>value</b><br />
|<b>description</b><br />
|-<br />
|DISPLAY_AIRC<br />
| 0x00000001<br />
|Cracker air display mode, used in alternate velocity display.<br />
|-<br />
|DISPLAY_AIRP<br />
| 0x00000002<br />
|Used by pressure display mode.<br />
|-<br />
|DISPLAY_AIRV<br />
| 0x00000004<br />
|Used by velocity display mode.<br />
|-<br />
|DISPLAY_AIRH<br />
| 0x00000008<br />
|Used by heat display mode.<br />
|-<br />
|DISPLAY_AIR<br />
| 0x0000000F<br />
|A bitmask which can be used to check if an air display mode is set.<br />
|-<br />
|DISPLAY_WARP<br />
| 0x00000010<br />
|Used by fancy display mode, turns on gravity lensing, causing newtonian gravity areas to bend light.<br />
|-<br />
|DISPLAY_PERS<br />
| 0x00000020<br />
|Used by persistent display mode.<br />
|-<br />
|DISPLAY_EFFE<br />
| 0x00000040<br />
|Doesn't do anything at all, unless maybe OpenGL is on. Unclear what it does even then.<br />
|}<br />
<br />
=== Color modes ===<br />
These are the values used and returned by ren.colorMode. Only one can be set at a time, and they control which types of colors particles are drawn in.<br />
{| class="wikitable"<br />
|-<br />
|<b>name</b><br />
|<b>description</b><br />
|-<br />
|COLOUR_DEFAULT<br />
|Default colors, nothing gets changed.<br />
|-<br />
|COLOUR_HEAT<br />
|Render elements in heat display colors. Pink = hottest, Blue = coldest.<br />
|-<br />
|COLOUR_LIFE<br />
|Render elements in a greyscale gradient dependent on .life value.<br />
|-<br />
|COLOUR_GRAD<br />
|Render elements normally, but with a slight greyscale gradient dependent on a particle's temperature.<br />
|-<br />
|COLOUR_BASC<br />
|Remove all color changes from elements, elements get rendered in whichever color their element button is.<br />
|-<br />
|}<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Graphics&diff=8324Lua API:Graphics2021-11-22T17:11:27Z<p>Maticzpl: Undo revision 8323 by Maticzpl (talk)</p>
<hr />
<div>Various methods that allow lua to draw on the simulation screen.<br />
<br />
== Methods ==<br />
<br />
=== graphics.textSize ===<br />
number, number graphics.textSize(string text)<br />
Returns the width and height of the specified text.<br />
<br />
=== graphics.drawText ===<br />
graphics.drawText(number x, number y, string text, [number r, number g, number b, [number a]])<br />
Draws the specified text at (x,y). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.drawLine ===<br />
graphics.drawLine(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]])<br />
Draws a line from (x1,y1) to (x2,y2). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.drawRect ===<br />
graphics.drawRect(number x, number y, number width, number height, [number r, number g, number b, [number a]])<br />
Draws a hollow rectangle at (x,y) with the specified width and height. Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.fillRect ===<br />
graphics.fillRect(number x, number y, number width, number height, [number r, number g, number b, [number a]])<br />
Draws a filled rectangle at (x,y) with the specified width and height. Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.drawCircle ===<br />
graphics.drawCircle(number x, number y, number radiusW, number radiusH, [number r, number g, number b, [number a]])<br />
Draws a hollow circle at (x,y) with radius of (radiusW,radiusH). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.fillCircle ===<br />
graphics.fillCircle(number x, number y, number radiusW, number radiusH, [number r, number g, number b, [number a]])<br />
Draws a filled circle at (x,y) with radius of (radiusW,radiusH). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.getColors ===<br />
graphics.getColors(number color)<br />
Converts color from hex. Return number r,g,b,a.<br />
<br />
=== graphics.getHexColor ===<br />
graphics.getHexColor( [number r], [number g], [number b], [number a])<br />
Converts color to hex.<br />
<br />
== Constants ==<br />
; graphics.WIDTH<br />
The complete window width including side buttons, usually 629.<br />
; graphics.HEIGHT<br />
The complete window height including the bottom area, usually 424.<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Graphics&diff=8323Lua API:Graphics2021-11-22T17:07:07Z<p>Maticzpl: Added gfx.toolTip</p>
<hr />
<div>Various methods that allow lua to draw on the simulation screen.<br />
<br />
== Methods ==<br />
<br />
=== graphics.textSize ===<br />
number, number graphics.textSize(string text)<br />
Returns the width and height of the specified text.<br />
<br />
=== graphics.drawText ===<br />
graphics.drawText(number x, number y, string text, [number r, number g, number b, [number a]])<br />
Draws the specified text at (x,y). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.toolTip ===<br />
gfx.toolTip(string text,number x,number y)<br />
Draws white text at (x, y). The text fades away similarly to the text displayed by <code>print()</code><br />
<br />
=== graphics.drawLine ===<br />
graphics.drawLine(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]])<br />
Draws a line from (x1,y1) to (x2,y2). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.drawRect ===<br />
graphics.drawRect(number x, number y, number width, number height, [number r, number g, number b, [number a]])<br />
Draws a hollow rectangle at (x,y) with the specified width and height. Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.fillRect ===<br />
graphics.fillRect(number x, number y, number width, number height, [number r, number g, number b, [number a]])<br />
Draws a filled rectangle at (x,y) with the specified width and height. Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.drawCircle ===<br />
graphics.drawCircle(number x, number y, number radiusW, number radiusH, [number r, number g, number b, [number a]])<br />
Draws a hollow circle at (x,y) with radius of (radiusW,radiusH). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.fillCircle ===<br />
graphics.fillCircle(number x, number y, number radiusW, number radiusH, [number r, number g, number b, [number a]])<br />
Draws a filled circle at (x,y) with radius of (radiusW,radiusH). Providing the color is optional, if not provided defaults to white.<br />
<br />
=== graphics.getColors ===<br />
graphics.getColors(number color)<br />
Converts color from hex. Return number r,g,b,a.<br />
<br />
=== graphics.getHexColor ===<br />
graphics.getHexColor( [number r], [number g], [number b], [number a])<br />
Converts color to hex.<br />
<br />
== Constants ==<br />
; graphics.WIDTH<br />
The complete window width including side buttons, usually 629.<br />
; graphics.HEIGHT<br />
The complete window height including the bottom area, usually 424.<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Lua_API:Simulation&diff=8310Lua API:Simulation2021-10-27T19:16:03Z<p>Maticzpl: /* simulation.loadStamp */ removed typo</p>
<hr />
<div>The Simulation API allows for modifying the state and properties of particles, air and gravity<br />
<br />
== Methods ==<br />
<br />
=== simulation.adjustCoords ===<br />
number, number sim.adjustCoords(number x, number y)<br />
Actually this is more of a UI method than a simulation method. Given a mouse position x, y in the window, this function returns the corresponding coordinates in the simulation (taking into account the visibility and position of the zoom window, if applicable). <br />
<br />
=== simulation.airMode ===<br />
number sim.airMode()<br />
Returns the current Air Simulation Mode.<br />
<br />
nil sim.airMode(number mode)<br />
Sets the Air Simulation Mode to mode.<br />
<br />
Mode numbers are as follows (not currently available as named constants):<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal<br />
|-<br />
|1<br />
|Pressure off<br />
|-<br />
|2<br />
|Velocity off<br />
|-<br />
|3<br />
|Velocity and pressure off<br />
|-<br />
|4<br />
|No update<br />
|}<br />
<br />
=== simulation.ambientAirTemp ===<br />
number sim.ambientAirTemp()<br />
Returns the current ambient temperature. When ambient heat mode is turned on, the air at the edges of the screen will remain at this temperature. <br />
<br />
nil sim.ambientAirTemp(number temp)<br />
Sets the ambient temperature. The temperature is measured in Kelvin. <br />
<br />
=== simulation.ambientHeat ===<br />
number sim.ambientHeat(number x, number y)<br />
Returns a value on the ambient heat map (the temperature of the air at that point). <br />
<br />
nil sim.ambientHeat(number x, number y, number temp, [number width, number height])<br />
Sets values on the ambient heat map. <br />
<br />
=== simulation.clearSim ===<br />
nil sim.clearSim()<br />
Clears everything in the simulation.<br />
<br />
=== simulation.createBox ===<br />
nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])<br />
Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createLine ===<br />
nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])<br />
Creates a line of of either the user's currently selected type or the type specified at the specified coordinates.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.createParts ===<br />
number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])<br />
Does something.<br />
<br />
=== simulation.createWallBox ===<br />
nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])<br />
Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWallLine ===<br />
nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])<br />
Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.createWalls ===<br />
number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])<br />
Does something<br />
<br />
=== simulation.decoBox ===<br />
nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])<br />
Changes the decoration color of all particles in the specified coordinates.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoBrush ===<br />
nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Does something<br />
tool refers to decoration tools.<br />
<br />
=== simulation.decoColor ===<br />
number sim.decoColor()<br />
Returns the currently selected decoration color.<br />
<br />
nil sim.decoColor(number color)<br />
Sets the selected decoration color to color.<br />
color is in the format 0xAARRGGBB<br />
<br />
nil sim.decoColor(number r, number g, number b, [number a])<br />
Sets the selected decoration color to r,g,b,a<br />
<br />
=== simulation.decoColour ===<br />
Same as sim.decoColor()<br />
<br />
=== simulation.decoLine ===<br />
nil sim.decoLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])<br />
Changes the decoration color of all particles in the line specified.<br />
rx and ry describe the radius of the brush used. Default radius is 5, 5.<br />
tool refers to decoration tools.<br />
<br />
=== simulation.deleteStamp ===<br />
type sim.deleteStamp(string name)<br />
Deleting a stamp identified by filename or ID.<br />
<br />
=== simulation.edgeMode ===<br />
number sim.edgeMode()<br />
Returns the current Edge Mode<br />
<br />
nil sim.edgeMode(number mode)<br />
Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation. <br />
<br />
=== simulation.elementCount ===<br />
number sim.elementCount(number type)<br />
Returns the number of particles of the specified type in the simulation.<br />
<br />
=== simulation.floodParts ===<br />
number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])<br />
Flood fills either the user's currently selected type or the type specified at the coordinates given.<br />
flag refers to particle replacement flags.<br />
<br />
=== simulation.floodWalls ===<br />
number sim.floodWalls(number x, number y, [number walltype], [number bm?])<br />
Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates.<br />
Note: the coordinates might change from particle coordinates to map coordinates in the future.<br />
<br />
=== simulation.framerender ===<br />
number sim.framerender()<br />
sim.framerender(number frames)<br />
Advances the simulation the given number of frames, even when paused. If called with no arguments, returns the number of frames currently to be rendered. Usually is 0.<br />
<br />
=== simulation.getSaveID ===<br />
number, number sim.getSaveID()<br />
Returns the save ID and the history offset of the currently loaded save or nil if the simulation is not a downloaded save. The history offset can be used with loadSave.<br />
<br />
=== simulation.gravMap ===<br />
number sim.gravMap(number x, number y)<br />
nil sim.gravMap(number x, number y, [number width, number height, [number value]])<br />
Returns the newtonian gravity at the given coordinates in the simulation. If given a value, will set the newtonian gravity at those coordinates. Width and height refer to the rectangle of affected cells, starting with the coords. If not given, they will default to 1,1.<br />
<br />
=== simulation.gravityGrid ===<br />
number sim.gravityGrid()<br />
Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.<br />
<br />
nil sim.gravityGrid(number mode)<br />
Sets the setting for drawing the gravity grid to mode.<br />
<br />
=== simulation.gravityMode ===<br />
number sim.gravityMode()<br />
Returns the current gravity simulation mode.<br />
<br />
nil sim.gravityMode(number mode)<br />
Sets the gravity simulation mode to mode.<br />
<br />
{| class="wikitable"<br />
|-<br />
|0<br />
|Normal, vertical gravity<br />
|-<br />
|1<br />
|No gravity<br />
|-<br />
|2<br />
|Radial gravity<br />
|}<br />
<br />
=== simulation.gspeed ===<br />
number sim.gspeed()<br />
Returns the current GoL speed<br />
<br />
nil sim.gspeed(number newSpeed)<br />
Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.<br />
<br />
=== simulation.loadSave ===<br />
nil sim.loadSave(number SaveID, [number hideDescription], [number history?])<br />
Loads the save associated with the specified SaveID.<br />
If hideDescription is non zero, the information for the save is not shown.<br />
<br />
=== simulation.loadStamp ===<br />
sim.loadStamp(string filename, number x, number y)<br />
sim.loadStamp(number id, number x, number y)<br />
Loads a stamp identified by filename or ID, and places it at position x,y. Filenames should be given without stamps/ or the .stm suffix. On success, returns 1. On failure, returns nil and the failure reason as a string.<br />
<br />
=== simulation.neighbors ===<br />
type sim.neighbors(number x, number y, [number rx], [number ry], [number type])<br />
Used for iterating through particles in an area centred on the given coordinates (x, y). Radius in the x and y directions is set by rx and ry. Default radius is 2, 2. If type is provided, only particles of the corresponding type will be returned.<br />
<br />
The size of the rectangular area is one plus twice the radius, so a radius of 2, 2 gives a 5x5 pixel area centred on x, y. Particles in the centre position x, y are excluded. Only one particle in each position is included, and energy particles (such as photons, neutrons, electrons) are ignored.<br />
<br />
Example (i is the index of the neighbouring particle and nx, ny are its coordinates):<br />
<syntaxhighlight lang="lua"><br />
for i,nx,ny in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
Or if coordinates of the neighbouring particles are not required:<br />
<syntaxhighlight lang="lua"><br />
for i in sim.neighbors(100,200,1,1) do<br />
sim.partProperty(i, sim.FIELD_TEMP, 9999)<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.neighbours ===<br />
Same as sim.neighbors()<br />
<br />
=== simulation.partChangeType ===<br />
nil sim.partChangeType(number index, number type)<br />
Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.<br />
<br />
=== simulation.partCreate ===<br />
number sim.partCreate(number index, number x, number y, number type)<br />
Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure. <br />
<br />
Possible values for index are:<br />
<br />
* -1 : Normal particle creation. This is the most useful value. No particle is created if position x, y is occupied and the requested new particle type cannot pass through the particle that is already there.<br />
* -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.<br />
* -3 : Create particle without checking for collisions with existing particles. In most cases, this is a bad idea, since a lot of elements don't work properly when there are multiple particles in the same place. Particles may also turn into BHOL if there are too many in the same place. The exception to this is elements that have been specifically designed to cope with this (such as multiple energy particles like PHOT and NEUT in the same place). <br />
* particle index, >= 0 : Overwrite an existing particle with a new particle. At the moment no collision checking is performed, so the same considerations apply as for index=-3. It is usually safe if the new particle is in the same location as the old one. This is roughly equivalent to calling sim.partKill then sim.partCreate(-3, ...).<br />
<br />
=== simulation.partID ===<br />
number sim.partID(number x, number y)<br />
Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.<br />
<br />
Example (though this is probably best done with sim.neighbours):<br />
<syntaxhighlight lang="lua"><br />
for fx = -1, 1, 1 do<br />
for fy = -1, 1, 1 do<br />
local i = sim.partID(x + fx, y + fy)<br />
if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then<br />
sim.partProperty(index, sim.FIELD_TEMP, 9999)<br />
end<br />
end<br />
end<br />
</syntaxhighlight><br />
<br />
=== simulation.partKill ===<br />
nil sim.partKill(number index)<br />
nil sim.partKill(number x, number y)<br />
Reliably delete a particle at a specified index or location, this method avoids the side effects created by changing the type to 0/DEFAULT_PT_NONE with the "partProperty" method<br />
<br />
=== simulation.partNeighbors ===<br />
number ... sim.partNeighbours(number x, number y, number radius, [number type])<br />
Returns a list of particles indexes that neighbour the given coordinates that matches the given type (if it is specified) The resulting list does not contain the "origin particle"<br />
<br />
=== simulation.partNeighbours ===<br />
Same as sim.partNeighbors()<br />
<br />
=== simulation.partPosition ===<br />
number x, number y sim.partPosition(number index)<br />
Get the location of the particle at the specified index <br />
<br />
=== simulation.partProperty ===<br />
nil sim.partProperty(number index, object field, object value)<br />
Set the property value on a particle specified by index<br />
<br />
object sim.partProperty(number index, object field)<br />
Get the property value on a particle specified by the index<br />
<br />
The "field" may be a field name or field ID, see FIELD constants below for valid fields.<br />
<br />
=== simulation.parts ===<br />
function sim.parts()<br />
Returns an iterator over particle indexes that can be used in lua for loops<br />
<br />
=== simulation.pmap ===<br />
number sim.pmap(number x, number y)<br />
Get the index of the particle at the specified position. Returns 0 if there is no particle there. This function is very similar to sim.partID, but excludes energy particles (such as PHOT, NEUT, ELEC).<br />
<br />
=== simulation.photons ===<br />
number sim.photons(number x, number y)<br />
Get the index of the energy particle at the specified position. Returns 0 if there is no particle there. This function is very similar to sim.pmap<br />
<br />
=== simulation.pressure ===<br />
number sim.pressure(number x, number y)<br />
Returns a value on the pressure map.<br />
<br />
nil sim.pressure(number x, number y, number pressure, [number width, number height])<br />
Sets values on the pressure map.<br />
<br />
=== simulation.prettyPowders ===<br />
number sim.prettyPowders()<br />
nil sim.prettyPowders(mode)<br />
Sets whether the "pretty powders mode" (powders, such as SAND or BCOL, will be assigned random deco values) is on or off. When called with no arguments, returns a value determining whether it is on or off.<br />
<br />
=== simulation.reloadSave ===<br />
nil sim.reloadSave()<br />
Reloading save.<br />
<br />
=== simulation.resetPressure ===<br />
nil sim.resetPressure()<br />
Resets the pressure map to no pressure.<br />
<br />
=== simulation.resetTemp ===<br />
nil sim.resetTemp()<br />
Resets the temperature of all particles to their spawn temperature.<br />
<br />
=== simulation.saveStamp ===<br />
string sim.saveStamp([number x, number y, number width, number height])<br />
Creates a stamp of the specified coordinates. Coordinates default to entire simulation.<br />
Returns the stamp id created.<br />
<br />
=== simulation.signs ===<br />
table simulation.signs<br />
A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.<br />
<br />
==== simulation.signs[n] ====<br />
table simulation.signs[n]<br />
A table which always contains the id property. May also contain text, x, y and justification. These properties can be directly modified to change a sign.<br />
A justification of 0 means left, 1 means right, 2 means middle and 3 means none.<br />
The text property cannot be larger than 45 in length.<br />
<br />
==== simulation.signs.new ====<br />
number simulation.signs.new([string text, number x, number y, number justification])<br />
Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).<br />
<br />
=== simulation.takeSnapshot ===<br />
nil sim.takeSnapshot()<br />
Takes a undo snapshot, for use with ctrl + z<br />
<br />
=== simulation.toolBox ===<br />
type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])<br />
Does something<br />
<br />
=== simulation.toolBrush ===<br />
number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Performs the given tool (HEAT, COOL, AIR, etc) on the given coordinates with the given brush size. The brush types are 0 (circle), 1 (square) and 2 (triangle).<br />
<br />
=== simulation.toolLine ===<br />
type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])<br />
Does something<br />
<br />
=== simulation.velocityX ===<br />
number sim.velocityX(number x, number y)<br />
Returns an X value on the velocity map.<br />
<br />
nil sim.velocityX(number x, number y, [number value], [number width, number height])<br />
Sets X values on the velocity map.<br />
<br />
=== simulation.velocityY ===<br />
number sim.velocityY(number x, number y)<br />
Returns an Y value on the velocity map.<br />
<br />
nil sim.velocityY(number x, number y, [number value], [number width, number height])<br />
Sets Y values on the velocity map.<br />
<br />
=== simulation.waterEqualisation ===<br />
number sim.waterEqualisation()<br />
Returns the current Water equalisation setting.<br />
<br />
nil sim.waterEqualisation(number setting)<br />
Set the Water equalisation setting to setting.<br />
<br />
=== simulation.waterEqualization ===<br />
Same as sim.waterEqualisation()<br />
<br />
== Constants ==<br />
Any of these constants can be accessed with simulation.<constant name here><br />
<br />
=== DECO ===<br />
; DECO_DIVIDE<br />
; DECO_SMUDGE<br />
; DECO_ADD<br />
; DECO_SUBTRACT<br />
; DECO_CLEAR<br />
; DECO_DRAW<br />
; DECO_MULTIPLY<br />
<br />
=== FIELD ===<br />
; FIELD_DCOLOUR<br />
; FIELD_Y<br />
; FIELD_TEMP<br />
; FIELD_TYPE<br />
; FIELD_VY<br />
; FIELD_X<br />
; FIELD_TMP2<br />
; FIELD_TMP<br />
; FIELD_FLAGS<br />
; FIELD_VX<br />
; FIELD_CTYPE<br />
; FIELD_LIFE<br />
<br />
=== MAX ===<br />
; MAX_TEMP<br />
<br />
=== MIN ===<br />
; MIN_TEMP<br />
<br />
=== NUM ===<br />
; NUM_PARTS<br />
<br />
=== PT ===<br />
; PT_NUM<br />
<br />
=== R ===<br />
; R_TEMP<br />
<br />
=== TOOL ===<br />
; TOOL_VAC<br />
; TOOL_AIR<br />
; TOOL_NGRV<br />
; TOOL_PGRV<br />
; TOOL_HEAT<br />
; TOOL_WIND<br />
; TOOL_COOL<br />
<br />
=== Uncategorized ===<br />
; YRES<br />
; XRES<br />
<br />
[[Category:Lua]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Element:LITH&diff=8202Element:LITH2021-07-18T20:10:54Z<p>Maticzpl: Remove 96.1 notice about overcharging lith</p>
<hr />
<div>{{ infobox Element<br />
| icon = LITH.png<br />
| longname = Lithium<br />
| image = [[File:LITHSticker.gif]]<br />
<br />
| identifier = DEFAULT_PT_LITH<br />
| name = Lith<br />
| description = Lithium. Reactive element that explodes on contact with water.<br />
| colour = B6AABF<br />
| menusection = SC_EXPLOSIVE<br />
| menuvisible = 1<br />
| advection = 0.2<br />
| airdrag = 0.01<br />
| airloss = 0.96<br />
| loss = 0.95<br />
| collision = -0.1<br />
| diffusion = 0<br />
| explosive = 0<br />
| falldown = 1<br />
| flammable = 0<br />
| gravity = 0.2<br />
| hardness = 15<br />
| heatconduct = 70<br />
| hotair = 0<br />
| meltable = 0<br />
| state = ST_POWDER<br />
| temperature = 295.15<br />
| weight = 17<br />
| properties = TYPE_PART PROP_LIFE_DEC<br />
| lowtemperature = <br />
| lowtemperaturetransition = <br />
| hightemperature = 453.65<br />
| hightemperaturetransition = LAVA<br />
| lowpressure = <br />
| lowpressuretransition = <br />
| highpressure = <br />
| highpressuretransition = <br />
}}<br />
<br />
'''Hydrogenation (tmp):'''<br />
When LITH touches {{MaterialBtn | WATR}} {{MaterialBtn | SLTW}} {{MaterialBtn | DSTW}} {{MaterialBtn | BUBW}} or {{MaterialBtn | WTRV}} its hydrogenation factor increases by 1 for each water particle.<br />
<br />
If the lithium particle is above 166.85C it will explode. Otherwise it will convert water particles into [[Element:HYGN|HYGN]] and heat up. The reactions and heat produced will be more violent when lithium is charged up with electricity.<br />
<br />
The Hydrogenation factor is stored in the .tmp property.<br />
<br />
'''Carbonation (tmp2):'''<br />
When LITH touches {{MaterialBtn | CO2}} its carbonation factor increases by 1 for each CO2 particle that gets absorbed. The carbonation factor is stored in the .tmp2 property<br />
<br />
'''Lithium ion batteries:'''<br />
When lithium is pure enough (hydrogenation factor + carbonation factor < 5)<br />
it can be used as a chargeable battery.<br />
<br />
Lithium is charged by sparked {{MaterialBtn | PSCN}}. To discharge lithium it needs to come in contact with {{MaterialBtn | NSCN}}.<br />
<br />
The charge value is stored in the .ctype property, and is shared among nearby LITH particles.<br />
<br />
Lithium can be overcharged when it reaches .ctype of 100. The explosion will propagate through all neighboring highly-charged lithium particles.<br />
<br />
'''Impurity:''' <br />
Lithium impurity is determined by the sum of hydrogenation and carbonation factors.<br />
<br />
When impurity reaches the maximum value of 10 it will stop reacting with CO2 and water particles (unless its already burning).<br />
<br />
'''Explosion:''' <br />
While in its explosion phase, LITH will start a countdown timer and release FIRE particles. If LITH comes into contact with [[Element:OXYG|OXYG]] in this state, it will turn the OXYG and itself into [[Element:PLSM|PLSM]], and create some pressure. When the explosion timer finishes, it will turn into [[Element:LAVA|LAVA]]. If the carbonation factor is greater than 3, it will turn into molten [[Element:GLAS|GLAS]], rather than molten LITH.<br />
<br />
LITH will also explode if it comes into contact with [[Element:FIRE|FIRE]] while it's temperature is greater than 166.85C and it's hydrogenation value is less than 6. <br />
<br />
{{MaterialBtn | ACID}} will turn LITH into [[Element:HYGN|HYGN]], rather than destroying it.<br />
<br />
<br />
{{Languages}}<br />
<br />
[[Category:Elements]]<br />
[[Category:Work in progress]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Element:LITH&diff=8196Element:LITH2021-07-14T10:52:01Z<p>Maticzpl: Lithium Overcharging</p>
<hr />
<div>{{ infobox Element<br />
| icon = LITH.png<br />
| longname = Lithium<br />
| image = [[File:LITHSticker.gif]]<br />
<br />
| identifier = DEFAULT_PT_LITH<br />
| name = Lith<br />
| description = Lithium. Reactive element that explodes on contact with water.<br />
| colour = B6AABF<br />
| menusection = SC_EXPLOSIVE<br />
| menuvisible = 1<br />
| advection = 0.2<br />
| airdrag = 0.01<br />
| airloss = 0.96<br />
| loss = 0.95<br />
| collision = -0.1<br />
| diffusion = 0<br />
| explosive = 0<br />
| falldown = 1<br />
| flammable = 0<br />
| gravity = 0.2<br />
| hardness = 15<br />
| heatconduct = 70<br />
| hotair = 0<br />
| meltable = 0<br />
| state = ST_POWDER<br />
| temperature = 295.15<br />
| weight = 17<br />
| properties = TYPE_PART PROP_LIFE_DEC<br />
| lowtemperature = <br />
| lowtemperaturetransition = <br />
| hightemperature = 453.65<br />
| hightemperaturetransition = LAVA<br />
| lowpressure = <br />
| lowpressuretransition = <br />
| highpressure = <br />
| highpressuretransition = <br />
}}<br />
<br />
'''Hydrogenation (tmp):'''<br />
When LITH touches {{MaterialBtn | WATR}} {{MaterialBtn | SLTW}} {{MaterialBtn | DSTW}} {{MaterialBtn | BUBW}} or {{MaterialBtn | WTRV}} its hydrogenation factor increases by 1 for each water particle.<br />
<br />
If the lithium particle is above 166.85C it will explode. Otherwise it will convert water particles into [[Element:HYGN|HYGN]] and heat up. The reactions and heat produced will be more violent when lithium is charged up with electricity.<br />
<br />
The Hydrogenation factor is stored in the .tmp property.<br />
<br />
'''Carbonation (tmp2):'''<br />
When LITH touches {{MaterialBtn | CO2}} its carbonation factor increases by 1 for each CO2 particle that gets absorbed. The carbonation factor is stored in the .tmp2 property<br />
<br />
'''Lithium ion batteries:'''<br />
When lithium is pure enough (hydrogenation factor + carbonation factor < 5)<br />
it can be used as a chargeable battery.<br />
<br />
Lithium is charged by sparked {{MaterialBtn | PSCN}}. To discharge lithium it needs to come in contact with {{MaterialBtn | NSCN}}.<br />
<br />
The charge value is stored in the .ctype property, and is shared among nearby LITH particles.<br />
<br />
Lithium can be overcharged when it reaches .ctype of 100. The explosion will propagate through all neighboring lithium particles.<br />
<br />
'''Impurity:''' <br />
Lithium impurity is determined by the sum of hydrogenation and carbonation factors.<br />
<br />
When impurity reaches the maximum value of 10 it will stop reacting with CO2 and water particles (unless its already burning).<br />
<br />
'''Explosion:''' <br />
While in its explosion phase, LITH will start a countdown timer and release FIRE particles. If LITH comes into contact with [[Element:OXYG|OXYG]] in this state, it will turn the OXYG and itself into [[Element:PLSM|PLSM]], and create some pressure. When the explosion timer finishes, it will turn into [[Element:LAVA|LAVA]]. If the carbonation factor is greater than 3, it will turn into molten [[Element:GLAS|GLAS]], rather than molten LITH.<br />
<br />
LITH will also explode if it comes into contact with [[Element:FIRE|FIRE]] while it's temperature is greater than 166.85C and it's hydrogenation value is less than 6. <br />
<br />
{{MaterialBtn | ACID}} will turn LITH into [[Element:HYGN|HYGN]], rather than destroying it.<br />
<br />
<br />
{{Languages}}<br />
<br />
[[Category:Elements]]<br />
[[Category:Work in progress]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Subframe&diff=8185Subframe2021-07-12T16:48:00Z<p>Maticzpl: Page about Subframe (work in progress)</p>
<hr />
<div><br />
== What's Subframe? ==<br />
Subframe is a general name for technology that abuses particle update order.<br />
<br />
== Particle Order ==<br />
Every frame in The Powder Toy all the particles are updated one after another according to their ID.<br />
<br />
When you hover over a particle the ID is visible next to X and Y values but only when the debug HUD (toggle it with "D" key) is enabled.<br />
<br />
Every time you load a save all the particles are ordered from left to right and top to bottom.<br />
That means they will also be updated in that order. You should always assume that order or your contraptions can break when reloading the save.<br />
<br />
[[File:ParticleUpdateOrder.gif]]<br />
<br />
== Solid Spark ==<br />
Solid sparks are used to activate other particles like {{MaterialBtn | ARAY}}, {{MaterialBtn | DRAY}}, {{MaterialBtn | CRAY}} etc. every frame. It can bypass the spark cooldown and how spark normally blinks.<br />
<br />
[[File:SolidSpark.gif]]<br />
<br />
'''How to build it:'''<br />
A solid spark is made using at least 3 particles: <br />
<br />
1. Any element that can be sparked (like {{MaterialBtn | METL}})<br />
<br />
2. {{MaterialBtn | CONV}} with the CTYPE of the element above<br />
<br />
3. {{MaterialBtn | BTRY}} or {{MaterialBtn | CONV}} with CTYPE of {{MaterialBtn | SPRK}}<br />
<br />
Their IDs have to be in that order to work<br />
ID of 1 < ID of 2 < ID of 3<br />
<br />
'''How it works:'''<br />
In the first frame nothing happens and at the end the 1st particle gets sparked by the 3rd particle.<br />
<br />
In the second frame:<br />
<br />
1st particle (now being a SPRK) life decreases (from 4 to 3) and now can trigger elements like {{MaterialBtn | ARAY}}, {{MaterialBtn | DRAY}} etc.<br />
<br />
2nd particle replaces the sparked 1st particle, so its not sparked anymore.<br />
<br />
Now that the 1st particle isn't sparked the 3rd particle can spark it again (thus avoiding the spark cooldown and blinking).<br />
<br />
So the 1st particle gets sparked, the spark is replaced, and gets sparked again.<br />
<br />
<br />
{{Languages|Subframe}}<br />
<br />
[[Category:Work in progress]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=File:SolidSpark.gif&diff=8184File:SolidSpark.gif2021-07-12T16:47:41Z<p>Maticzpl: normal spark vs solid spark
For subframe wiki page</p>
<hr />
<div>normal spark vs solid spark<br />
For subframe wiki page</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=File:ParticleUpdateOrder.gif&diff=8183File:ParticleUpdateOrder.gif2021-07-12T16:02:32Z<p>Maticzpl: gif showing the update order for a wiki page on subframe</p>
<hr />
<div>gif showing the update order for a wiki page on subframe</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Element:ROCK&diff=8131Element:ROCK2021-07-05T12:16:16Z<p>Maticzpl: Enter a short summary [b]</p>
<hr />
<div>{{ infobox Element<br />
| icon = ROCK.png<br />
| longname = Rock<br />
| image = <br />
<br />
| identifier = DEFAULT_PT_ROCK<br />
| name = Rock<br />
| description = Rock. Solid material, CNCT can stack on top of it.<br />
| colour = 727272<br />
| menusection = SC_SOLIDS<br />
| menuvisible = 1<br />
| advection = 0<br />
| airdrag = 0<br />
| airloss = 0.94<br />
| loss = 0<br />
| collision = 0<br />
| diffusion = 0<br />
| explosive = 0<br />
| falldown = 0<br />
| flammable = 0<br />
| gravity = 0<br />
| hardness = 1<br />
| heatconduct = 200<br />
| hotair = 0<br />
| meltable = 5<br />
| state = ST_SOLID<br />
| temperature = 295.15<br />
| weight = 100<br />
| properties = TYPE_SOLID PROP_HOT_GLOW<br />
| lowtemperature = <br />
| lowtemperaturetransition = <br />
| hightemperature = 1943.15<br />
| hightemperaturetransition = LAVA<br />
| lowpressure = <br />
| lowpressuretransition = <br />
| highpressure = 120<br />
| highpressuretransition = STNE<br />
}}<br />
<br />
''Rock is available in The Powder Toy version 96.0 which is currently a beta version''<br />
<br />
<br />
<br />
'''Description:''' <br />
"Rock. Solid material, CNCT can stack on top of it."<br />
<br />
<br />
'''Type:''' Powder.<br />
<br />
<br />
'''Hex triplet color:''' #727272. (Brightness varies randomly)<br />
<br />
<br />
Rock can be used as a solid foundation for CNCT.<br />
<br />
Contrary to all the other particles CNCT will not fall of an edge of ROCK<br />
<br />
[[File:rockvsbrck.gif]]<br />
<br />
{{Languages}}<br />
<br />
[[Category:Elements]]<br />
[[Category:Work in progress]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=File:Rockvsbrck.gif&diff=8130File:Rockvsbrck.gif2021-07-05T12:13:21Z<p>Maticzpl: Rock with CNCT on top
vs
BRCK with CNCT on top</p>
<hr />
<div>Rock with CNCT on top <br />
vs<br />
BRCK with CNCT on top</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Category:Solids&diff=8129Category:Solids2021-07-05T12:04:57Z<p>Maticzpl: Added ROCK to the list</p>
<hr />
<div>{{Languages|Elements:Solids}}<br />
<br />
=== Elements in the Solids menu ===<br />
<br />
Click element images for more details.<br />
<br />
* {{MaterialBtn | GOO}} Goo. Deforms and disappears under pressure.<br />
* {{MaterialBtn | ICE}} Ice. Crushes under pressure. Cools down air.<br />
* {{MaterialBtn | WOOD}} Wood, flammable.<br />
* {{MaterialBtn | PLNT}} Plant, drinks water and grows.<br />
* {{MaterialBtn | BMTL}} Breakable metal. Common conductive building material, can melt and break under pressure.<br />
* {{MaterialBtn | WAX}} Wax. Melts at moderately high temperatures.<br />
* {{MaterialBtn | GLAS}} Glass. Meltable. Shatters under pressure, and refracts photons.<br />
* {{MaterialBtn | NICE}} Nitrogen Ice. Very cold, will melt into {{Material | LN2}} when heated only slightly.<br />
* {{MaterialBtn | COAL}} Coal, Burns very slowly. Gets red when hot.<br />
* {{MaterialBtn | BRCK}} Brick, breakable building material.<br />
* {{MaterialBtn | IRON}} Iron. Rusts with salt, can be used for electrolysis of {{Material | WATR}}.<br />
* {{MaterialBtn | DRIC}} Dry Ice, formed when CO2 is cooled.<br />
* {{MaterialBtn | SPNG}} Sponge, absorbs water. Is not a moving solid.<br />
* {{MaterialBtn | RIME}} Solid, created when steam cools rapidly and goes through sublimation.<br />
* {{MaterialBtn | VINE}} Vine, can grow along WOOD.<br />
* {{MaterialBtn | SHLD}} Shield, spark it to grow.<br />
* {{MaterialBtn | FILT}} Filter for photons, changes the color.<br />
* {{MaterialBtn | QRTZ}} Quartz, breakable mineral. Conducts but becomes brittle at lower temperatures.<br />
* {{MaterialBtn | TTAN}} Titanium. Higher melting temperature than most other metals, blocks all air pressure.<br />
* {{MaterialBtn | GOLD}} Gold. Corrosion resistant metal, will reverse corrosion of iron.<br />
* {{MaterialBtn | CRMC}} Ceramic. Gets stronger under pressure.<br />
* {{MaterialBtn | HEAC}} Rapid heat conductor.<br />
* {{MaterialBtn | PTNM}} Platinum. Catalyzes certain reactions. (Only available in [https://powdertoy.co.uk/Discussions/Thread/View.html?Thread=20456| Snapshot 199+])<br />
* {{MaterialBtn | ROCK}} Rock. Solid material, CNCT can stack on top of it. (Only in 96.0 beta version)<br />
<br />
=== Other Solids, not visible in the menu ===<br />
* {{MaterialBtn | SPWN}} {{Material | STKM}} spawn point.<br />
* {{MaterialBtn | SPWN2}} {{Material | STK2}} spawn point.<br />
* {{MaterialBtn | VRSS}} Solid Virus. Turns everything it touches into virus.<br />
* {{MaterialBtn | BIZS}} Bizarre Solid. Melts to {{Material | BIZR}} at low enough temperatures.<br />
<br />
[[Category:Elements]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Elements:Explosives&diff=8128Elements:Explosives2021-07-05T11:52:42Z<p>Maticzpl: Lithium description fix</p>
<hr />
<div>{{Languages|Elements:Explosives}}<br />
<br />
Most elements in this category all burn or react when exposed to FIRE (except FIRE itself, C5 and CFLM), and each element has different properties that cause it to react differently. Pressure, high temperature (temp), [[Elements:Electronics|electricity]], contact with other particles, fire (FIRE), plasma (PLSM), and even water (WATR) can be triggers to certain elements in this category.<br />
<br />
=== {{MaterialBtn | FIRE}} Fire ===<br />
<br />
'''Description:'''<br />
"Ignites flammable materials. Heats empty space around it with the Ambient heat setting on."<br />
<br />
'''Type:'''<br />
Gas (considered a powder for some walls)<br />
<br />
Ignites flammable substances and heats up most elements. When FIRE is hot enough, it turns to [[Element:PLSM]].<br />
<br />
=== {{MaterialBtn | GUN}} Gunpowder ===<br />
<br />
'''Description:'''<br />
"Gunpowder. Light dust, explodes on contact with FIRE or spark (SPRK)."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explosive powder.Can be ignited by SPRK, FIRE, or a temp of 400C or greater.<br />
<br />
=== {{MaterialBtn | NITR}} Nitroglycerin ===<br />
<br />
'''Description:''' <br />
"Nitroglycerin. Pressure sensitive explosive. Mix with CLST to make TNT."<br />
<br />
'''Type:''' Liquid.<br />
<br />
'''Spawn temp:''' +22.00 ''C'' / 295.15 ''K''.<br />
<br />
Hex triplet colour: #20e010.<br />
<br />
Flammable; explosively ignites if in contact with [[Element:SPRK|SPRK]], [[Element:FIRE|FIRE]], [[Element:PLSM|PLSM]], or [[Element:LAVA|LAVA]].<br />
<br />
Forms [[Element:TNT|TNT]] if mixed with [[Element:CLST|CLST]].<br />
<br />
Transforms to [[Element:OIL|OIL]] if irradiated with [[Element:NEUT|NEUT]].<br />
<br />
=== {{MaterialBtn | C-4}} C-4 ===<br />
<br />
'''Description:'''<br />
"Solid pressure sensitive explosive."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Will explode when exposed to high pressure, SPRK, heat, or FIRE. Transforms into GOO when exposed to NEUT.<br />
<br />
=== {{MaterialBtn | RBDM}} Rubidium ===<br />
<br />
'''Description:'''<br />
"Rubidium. Explosive, especially on contact with water. Low melting point."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Explodes on contact with WATR, ACID and FIRE. Will not explode with SPRK, unlike other explosives. It will instead conduct just like normal metal. Melts into liquid rubidium at ~37.8C.<br />
<br />
=== {{MaterialBtn | LRBD}} Liquid Rubidium ===<br />
<br />
'''Description:'''<br />
"Liquid Rubidium."<br />
<br />
'''Type:'''<br />
Liquid<br />
<br />
The same as RBDM, except it's a liquid.<br />
<br />
=== {{MaterialBtn | THDR}} Thunder ===<br />
<br />
'''Description:'''<br />
"Lightning! Very hot, inflicts damage upon most materials, transfers current to metals."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Very hot liquid-like substance, passes a SPRK to any conductive materials. One of the most destructive elements, will create a strong pressure shock wave (256 pressure) as well as conducting its temp when in contact with non-metals (or metals that are unable to conduct electricity because a spark has just passed by). THDR's movements are not affected by pressure.<br />
<br />
=== {{MaterialBtn | THRM}} Thermite ===<br />
<br />
'''Description:'''<br />
"Thermite. Burns at extremely high temperature."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
THRM will react with FIRE, PLSM, LAVA and LIFE. It generates very large amounts of heat (Around 3000C just after ignition), hot enough to melt TTAN. Molten THRM turns into BMTL when cooled.<br />
<br />
=== {{MaterialBtn | CFLM}} Cold flame ===<br />
<br />
'''Description:'''<br />
"Sub-zero flame."<br />
<br />
'''Type:'''<br />
Gas<br />
<br />
'Cold Fire' that burns at -273.15C/0K. Will ignite C-5 and ANAR, but not other elements.<br />
<br />
=== {{MaterialBtn | FIRW}} Fireworks ===<br />
<br />
'''Description:'''<br />
"Fireworks! Colorful, set off by fire."<br />
<br />
'''Type:''' <br />
Powder<br />
<br />
After contacting FIRE, FIRW will shoot off upward and explode with hot (temp of 6000C to 9000C) and colorful embers. Use decorations to change ember colors.<br />
<br />
Explodes when tmp > 1, and life = 0.<br />
<br />
=== {{MaterialBtn | LIGH}} Lightning ===<br />
<br />
'''Description:'''<br />
"Lightning. Change the brush size to set the size of the lightning."<br />
<br />
'''Type:'''<br />
None / Special<br />
<br />
Bolt or "Arc" Lightning, Very short-lived element, ~2 to 5 frames of persistence. Upon clicking a "bolt" of LIGH will extend from the brush (angle is random, always downward when with the gravity setting on 'vertical', but at any angle when the gravity setting is 'off' (and generally pointing toward the centre of the screen when the gravity setting is on 'radial')), then dissipate, leaving a "thunderclap" pressure wave in its wake. Generates an extreme amount of heat and pressure upon making contact with another element, but not penetrating it, striking the surface only. Will spark conductors that survive the impact. Can be produced by sparking TESC. Length, temp, and pressure of bolt are based on the brush size used to produce it.<br />
<br />
=== {{MaterialBtn | DEST}} Destructive ===<br />
<br />
'''Description:'''<br />
"More destructive Bomb, can break through virtually anything."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Much more destructive than BOMB. When within 2 pixels of another element (except for DMND, any type of clone, or any type of Wall), DEST releases high amounts of heat and pressure, melting and/or scattering most elements. DEST survives for many frames after the initial impact and often tends to dig into whatever is in the way.<br />
<br />
=== {{MaterialBtn | FWRK}} Old Fireworks ===<br />
<br />
'''Description:'''<br />
"Original version of fireworks, activated by heat/neutrons."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explodes with neutrons or heat (200C). Jumps higher than FIRW but has odd trajectories and pale embers. Explodes when hot (temp of ~7000C upwards).<br />
<br />
=== {{MaterialBtn | BOMB}} Bomb ===<br />
<br />
'''Description:'''<br />
"Bomb. Explodes and destroys all surrounding particles when it touches something."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explodes when it touches any other particles except for DMND, any type of clone, or any type of Wall. When BOMB explodes, all particles within an 8 pixel radius are replaced by EMBR (except for diamond, clone, etc) at 9725.85C, with pressure produced. This EMBR 'shrapnel' is ejected at the explosion temperature after explosion occurs, causing damage. However, the shrapnel's conductivity rapidly decreases with its life and will cease to exist after a while.<br />
<br />
=== {{MaterialBtn | C-5}} C-5 ===<br />
<br />
'''Description:'''<br />
"Cold explosive, set off by anything cold."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Explodes when cold, produces CFLM and pressure. Only reacts with LOXY, LN2, CFLM, TRON and any other liquid cooled to below -173.85C/99K. Not pressure sensitive, and does not explode when sparked.<br />
<br />
=== {{MaterialBtn | TNT}} TNT ===<br />
<br />
'''Description:'''<br />
"TNT, explodes all at once"<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
A solid explosive similar to C-4, but creates more pressure and less fire. It is quite a hot explosive, hot enough to melt METL. TNT will explode into bomb shrapnel upon detonation. TNT is the only explosive that explodes instantaneously upon ignition. It was added in version 69.0 beta.<br />
<br />
=== {{MaterialBtn | IGNC}} Ignition Cord ===<br />
<br />
'''Description:'''<br />
"Ignition cord. Burns slowly with fire and sparks."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
A slow burning fuse-like material. IGNC, unlike FUSE, can be ignited by FIRE as well as hot materials. It burns with EMBR and FIRE at low temperatures. IGNC can be used as a delay to set off low grade explosives, and it can also burn in WATER. NEUT can pass through IGNC without distortion. Added in v70.0.<br />
<br />
=== {{MaterialBtn | FUSE}} Fuse ===<br />
<br />
'''Description:'''<br />
"Burns slowly. Ignites at somewhat high temperatures or with electricity."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
When its temp is above 700 degrees or it is sparked, it slowly turns into PLSM. Breaks into FSEP at >2.7 pressure (with a slight delay)<br />
<br />
=== {{MaterialBtn | FSEP}} Fuse Powder ===<br />
<br />
'''Description:'''<br />
"Fuse Powder. Burns slowly like FUSE."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Powdered FUSE, works in the same way (burns into PLSM with high temperature or electricity)<br />
<br />
=== {{MaterialBtn | LITH}} Lithium === <br />
''(currently only available in beta 96.0 version)''<br />
<br />
'''Description:'''<br />
"Lithium. Reactive element that explodes on contact with water."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
It absorbs CO2 and then can be converted to GLAS. On contact with water it will heat itself by and turn water into hydrogen. At 1000K it explodes. When pure it can be used to make batteries.<br />
<br />
<br />
[[Category:Elements]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Elements:Explosives&diff=8127Elements:Explosives2021-07-05T11:50:48Z<p>Maticzpl: Disclaimer about LITH being in beta</p>
<hr />
<div>{{Languages|Elements:Explosives}}<br />
<br />
Most elements in this category all burn or react when exposed to FIRE (except FIRE itself, C5 and CFLM), and each element has different properties that cause it to react differently. Pressure, high temperature (temp), [[Elements:Electronics|electricity]], contact with other particles, fire (FIRE), plasma (PLSM), and even water (WATR) can be triggers to certain elements in this category.<br />
<br />
=== {{MaterialBtn | FIRE}} Fire ===<br />
<br />
'''Description:'''<br />
"Ignites flammable materials. Heats empty space around it with the Ambient heat setting on."<br />
<br />
'''Type:'''<br />
Gas (considered a powder for some walls)<br />
<br />
Ignites flammable substances and heats up most elements. When FIRE is hot enough, it turns to [[Element:PLSM]].<br />
<br />
=== {{MaterialBtn | GUN}} Gunpowder ===<br />
<br />
'''Description:'''<br />
"Gunpowder. Light dust, explodes on contact with FIRE or spark (SPRK)."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explosive powder.Can be ignited by SPRK, FIRE, or a temp of 400C or greater.<br />
<br />
=== {{MaterialBtn | NITR}} Nitroglycerin ===<br />
<br />
'''Description:''' <br />
"Nitroglycerin. Pressure sensitive explosive. Mix with CLST to make TNT."<br />
<br />
'''Type:''' Liquid.<br />
<br />
'''Spawn temp:''' +22.00 ''C'' / 295.15 ''K''.<br />
<br />
Hex triplet colour: #20e010.<br />
<br />
Flammable; explosively ignites if in contact with [[Element:SPRK|SPRK]], [[Element:FIRE|FIRE]], [[Element:PLSM|PLSM]], or [[Element:LAVA|LAVA]].<br />
<br />
Forms [[Element:TNT|TNT]] if mixed with [[Element:CLST|CLST]].<br />
<br />
Transforms to [[Element:OIL|OIL]] if irradiated with [[Element:NEUT|NEUT]].<br />
<br />
=== {{MaterialBtn | C-4}} C-4 ===<br />
<br />
'''Description:'''<br />
"Solid pressure sensitive explosive."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Will explode when exposed to high pressure, SPRK, heat, or FIRE. Transforms into GOO when exposed to NEUT.<br />
<br />
=== {{MaterialBtn | RBDM}} Rubidium ===<br />
<br />
'''Description:'''<br />
"Rubidium. Explosive, especially on contact with water. Low melting point."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Explodes on contact with WATR, ACID and FIRE. Will not explode with SPRK, unlike other explosives. It will instead conduct just like normal metal. Melts into liquid rubidium at ~37.8C.<br />
<br />
=== {{MaterialBtn | LRBD}} Liquid Rubidium ===<br />
<br />
'''Description:'''<br />
"Liquid Rubidium."<br />
<br />
'''Type:'''<br />
Liquid<br />
<br />
The same as RBDM, except it's a liquid.<br />
<br />
=== {{MaterialBtn | THDR}} Thunder ===<br />
<br />
'''Description:'''<br />
"Lightning! Very hot, inflicts damage upon most materials, transfers current to metals."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Very hot liquid-like substance, passes a SPRK to any conductive materials. One of the most destructive elements, will create a strong pressure shock wave (256 pressure) as well as conducting its temp when in contact with non-metals (or metals that are unable to conduct electricity because a spark has just passed by). THDR's movements are not affected by pressure.<br />
<br />
=== {{MaterialBtn | THRM}} Thermite ===<br />
<br />
'''Description:'''<br />
"Thermite. Burns at extremely high temperature."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
THRM will react with FIRE, PLSM, LAVA and LIFE. It generates very large amounts of heat (Around 3000C just after ignition), hot enough to melt TTAN. Molten THRM turns into BMTL when cooled.<br />
<br />
=== {{MaterialBtn | CFLM}} Cold flame ===<br />
<br />
'''Description:'''<br />
"Sub-zero flame."<br />
<br />
'''Type:'''<br />
Gas<br />
<br />
'Cold Fire' that burns at -273.15C/0K. Will ignite C-5 and ANAR, but not other elements.<br />
<br />
=== {{MaterialBtn | FIRW}} Fireworks ===<br />
<br />
'''Description:'''<br />
"Fireworks! Colorful, set off by fire."<br />
<br />
'''Type:''' <br />
Powder<br />
<br />
After contacting FIRE, FIRW will shoot off upward and explode with hot (temp of 6000C to 9000C) and colorful embers. Use decorations to change ember colors.<br />
<br />
Explodes when tmp > 1, and life = 0.<br />
<br />
=== {{MaterialBtn | LIGH}} Lightning ===<br />
<br />
'''Description:'''<br />
"Lightning. Change the brush size to set the size of the lightning."<br />
<br />
'''Type:'''<br />
None / Special<br />
<br />
Bolt or "Arc" Lightning, Very short-lived element, ~2 to 5 frames of persistence. Upon clicking a "bolt" of LIGH will extend from the brush (angle is random, always downward when with the gravity setting on 'vertical', but at any angle when the gravity setting is 'off' (and generally pointing toward the centre of the screen when the gravity setting is on 'radial')), then dissipate, leaving a "thunderclap" pressure wave in its wake. Generates an extreme amount of heat and pressure upon making contact with another element, but not penetrating it, striking the surface only. Will spark conductors that survive the impact. Can be produced by sparking TESC. Length, temp, and pressure of bolt are based on the brush size used to produce it.<br />
<br />
=== {{MaterialBtn | DEST}} Destructive ===<br />
<br />
'''Description:'''<br />
"More destructive Bomb, can break through virtually anything."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Much more destructive than BOMB. When within 2 pixels of another element (except for DMND, any type of clone, or any type of Wall), DEST releases high amounts of heat and pressure, melting and/or scattering most elements. DEST survives for many frames after the initial impact and often tends to dig into whatever is in the way.<br />
<br />
=== {{MaterialBtn | FWRK}} Old Fireworks ===<br />
<br />
'''Description:'''<br />
"Original version of fireworks, activated by heat/neutrons."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explodes with neutrons or heat (200C). Jumps higher than FIRW but has odd trajectories and pale embers. Explodes when hot (temp of ~7000C upwards).<br />
<br />
=== {{MaterialBtn | BOMB}} Bomb ===<br />
<br />
'''Description:'''<br />
"Bomb. Explodes and destroys all surrounding particles when it touches something."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explodes when it touches any other particles except for DMND, any type of clone, or any type of Wall. When BOMB explodes, all particles within an 8 pixel radius are replaced by EMBR (except for diamond, clone, etc) at 9725.85C, with pressure produced. This EMBR 'shrapnel' is ejected at the explosion temperature after explosion occurs, causing damage. However, the shrapnel's conductivity rapidly decreases with its life and will cease to exist after a while.<br />
<br />
=== {{MaterialBtn | C-5}} C-5 ===<br />
<br />
'''Description:'''<br />
"Cold explosive, set off by anything cold."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Explodes when cold, produces CFLM and pressure. Only reacts with LOXY, LN2, CFLM, TRON and any other liquid cooled to below -173.85C/99K. Not pressure sensitive, and does not explode when sparked.<br />
<br />
=== {{MaterialBtn | TNT}} TNT ===<br />
<br />
'''Description:'''<br />
"TNT, explodes all at once"<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
A solid explosive similar to C-4, but creates more pressure and less fire. It is quite a hot explosive, hot enough to melt METL. TNT will explode into bomb shrapnel upon detonation. TNT is the only explosive that explodes instantaneously upon ignition. It was added in version 69.0 beta.<br />
<br />
=== {{MaterialBtn | IGNC}} Ignition Cord ===<br />
<br />
'''Description:'''<br />
"Ignition cord. Burns slowly with fire and sparks."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
A slow burning fuse-like material. IGNC, unlike FUSE, can be ignited by FIRE as well as hot materials. It burns with EMBR and FIRE at low temperatures. IGNC can be used as a delay to set off low grade explosives, and it can also burn in WATER. NEUT can pass through IGNC without distortion. Added in v70.0.<br />
<br />
=== {{MaterialBtn | FUSE}} Fuse ===<br />
<br />
'''Description:'''<br />
"Burns slowly. Ignites at somewhat high temperatures or with electricity."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
When its temp is above 700 degrees or it is sparked, it slowly turns into PLSM. Breaks into FSEP at >2.7 pressure (with a slight delay)<br />
<br />
=== {{MaterialBtn | FSEP}} Fuse Powder ===<br />
<br />
'''Description:'''<br />
"Fuse Powder. Burns slowly like FUSE."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Powdered FUSE, works in the same way (burns into PLSM with high temperature or electricity)<br />
<br />
=== {{MaterialBtn | LITH}} Lithium === <br />
''(currently only available in beta 96.0 version)''<br />
<br />
'''Description:'''<br />
"Lithium. Reactive element that explodes on contact with water."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
It absorbs CO2 and then can be converted to GLAS. On contact with water it will haet itself by 400K and consume water. At 1000K it explodes. When pure it can be used to make batteries.<br />
<br />
<br />
[[Category:Elements]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Element:LITH&diff=8126Element:LITH2021-07-05T11:48:41Z<p>Maticzpl: Carbonation , hydrogenation factors and battery usage</p>
<hr />
<div>{{ infobox Element<br />
| icon = LITH.png<br />
| longname = Lithium<br />
| image = <br />
<br />
| identifier = DEFAULT_PT_LITH<br />
| name = Lith<br />
| description = Lithium. Reactive element that explodes on contact with water.<br />
| colour = C5C5BB<br />
| menusection = SC_EXPLOSIVE<br />
| menuvisible = 1<br />
| advection = 0.2<br />
| airdrag = 0.01<br />
| airloss = 0.96<br />
| loss = 0.95<br />
| collision = -0.1<br />
| diffusion = 0<br />
| explosive = 0<br />
| falldown = 1<br />
| flammable = 0<br />
| gravity = 0.2<br />
| hardness = 15<br />
| heatconduct = 70<br />
| hotair = 0<br />
| meltable = 0<br />
| state = ST_POWDER<br />
| temperature = 295.15<br />
| weight = 17<br />
| properties = TYPE_PART PROP_LIFE_DEC<br />
| lowtemperature = <br />
| lowtemperaturetransition = <br />
| hightemperature = 453.65<br />
| hightemperaturetransition = LAVA<br />
| lowpressure = <br />
| lowpressuretransition = <br />
| highpressure = <br />
| highpressuretransition = <br />
}}<br />
<br />
''Lithium is available in The Powder Toy version 96.0 which is currently a beta version''<br />
<br />
<br />
<br />
'''Description:''' <br />
"Lithium. Reactive element that explodes on contact with water."<br />
<br />
<br />
'''Type:''' Powder.<br />
<br />
<br />
'''Hex triplet color:''' #C5C5BB. <br />
<br />
<br />
'''Hydrogenation (tmp):'''<br />
When LITH touches {{MaterialBtn | WATR}} {{MaterialBtn | SLTW}} {{MaterialBtn | DSTW}} {{MaterialBtn | BUBW}} or {{MaterialBtn | WTRV}} its hydrogenation factor increases by 1 for each water particle.<br />
<br />
If the lithium particle is above 440C it will explode. Otherwise it will convert water particles into H2 and heat up.<br />
<br />
The reactions will be more violent when lithium is charged up.<br />
<br />
The Hydrogenation factor is stored as TMP property.<br />
<br />
<br />
'''Carbonation (tmp2):'''<br />
When LITH touches {{MaterialBtn | CO2 }} its carbonation factor increases by 1 for each CO2 particle that gets absorbed.<br />
<br />
<br />
'''Lithium ion batteries:'''<br />
When lithium is pure enough (hydrogenation factor + carbonation factor < 5)<br />
it can be used as a chargeable battery.<br />
<br />
Lithium is charged by sparked {{MaterialBtn | PSCN }}.<br />
<br />
To discharge lithium it needs to come in contact with {{MaterialBtn | NSCN}}.<br />
<br />
The charge value is stored as a number in the CTYPE property (ctype numbers can be displayed as element names in the gui)<br />
<br />
<br />
'''Impurity:''' <br />
Lithium impurity is determined by the sum of hydrogenation and carbonation factors.<br />
<br />
When impurity reaches the maximum value of 10 it will stop reacting with CO2 and water particles (unless its already burning).<br />
<br />
For usage in batteries the lithium impurity cant reach the value of 5 or greater.<br />
<br />
<br />
{{Languages}}<br />
<br />
[[Category:Elements]]<br />
[[Category:Work in progress]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Element:LITH&diff=8122Element:LITH2021-07-04T11:02:28Z<p>Maticzpl: Enter a short summary [b]</p>
<hr />
<div>{{ infobox Element<br />
| icon = LITH.png<br />
| longname = Lithium<br />
| image = <br />
<br />
| identifier = DEFAULT_PT_LITH<br />
| name = Lith<br />
| description = Lithium. Reactive element that explodes on contact with water.<br />
| colour = C5C5BB<br />
| menusection = SC_EXPLOSIVE<br />
| menuvisible = 1<br />
| advection = 0.2<br />
| airdrag = 0.01<br />
| airloss = 0.96<br />
| loss = 0.95<br />
| collision = -0.1<br />
| diffusion = 0<br />
| explosive = 0<br />
| falldown = 1<br />
| flammable = 0<br />
| gravity = 0.2<br />
| hardness = 15<br />
| heatconduct = 70<br />
| hotair = 0<br />
| meltable = 0<br />
| state = ST_POWDER<br />
| temperature = 295.15<br />
| weight = 17<br />
| properties = TYPE_PART PROP_LIFE_DEC<br />
| lowtemperature = <br />
| lowtemperaturetransition = <br />
| hightemperature = 453.65<br />
| hightemperaturetransition = LAVA<br />
| lowpressure = <br />
| lowpressuretransition = <br />
| highpressure = <br />
| highpressuretransition = <br />
}}<br />
<br />
'''Description:''' <br />
"Lithium. Reactive element that explodes on contact with water."<br />
<br />
'''Type:''' Powder.<br />
<br />
Hex triplet colour: #C5C5BB. <br />
<br />
'''Properties:'''<br />
tmp2: carbonation factor<br />
life: burn timer above 1000, spark cooldown timer otherwise<br />
tmp: hydrogenation factor<br />
ctype: absorbed energy<br />
<br />
<br />
<br />
<br />
{{Languages}}<br />
<br />
[[Category:Elements]]<br />
[[Category:Work in progress]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=Elements:Explosives&diff=8121Elements:Explosives2021-07-04T10:51:56Z<p>Maticzpl: Lithium element added</p>
<hr />
<div>{{Languages|Elements:Explosives}}<br />
<br />
Most elements in this category all burn or react when exposed to FIRE (except FIRE itself, C5 and CFLM), and each element has different properties that cause it to react differently. Pressure, high temperature (temp), [[Elements:Electronics|electricity]], contact with other particles, fire (FIRE), plasma (PLSM), and even water (WATR) can be triggers to certain elements in this category.<br />
<br />
=== {{MaterialBtn | FIRE}} Fire ===<br />
<br />
'''Description:'''<br />
"Ignites flammable materials. Heats empty space around it with the Ambient heat setting on."<br />
<br />
'''Type:'''<br />
Gas (considered a powder for some walls)<br />
<br />
Ignites flammable substances and heats up most elements. When FIRE is hot enough, it turns to [[Element:PLSM]].<br />
<br />
=== {{MaterialBtn | GUN}} Gunpowder ===<br />
<br />
'''Description:'''<br />
"Gunpowder. Light dust, explodes on contact with FIRE or spark (SPRK)."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explosive powder.Can be ignited by SPRK, FIRE, or a temp of 400C or greater.<br />
<br />
=== {{MaterialBtn | NITR}} Nitroglycerin ===<br />
<br />
'''Description:''' <br />
"Nitroglycerin. Pressure sensitive explosive. Mix with CLST to make TNT."<br />
<br />
'''Type:''' Liquid.<br />
<br />
'''Spawn temp:''' +22.00 ''C'' / 295.15 ''K''.<br />
<br />
Hex triplet colour: #20e010.<br />
<br />
Flammable; explosively ignites if in contact with [[Element:SPRK|SPRK]], [[Element:FIRE|FIRE]], [[Element:PLSM|PLSM]], or [[Element:LAVA|LAVA]].<br />
<br />
Forms [[Element:TNT|TNT]] if mixed with [[Element:CLST|CLST]].<br />
<br />
Transforms to [[Element:OIL|OIL]] if irradiated with [[Element:NEUT|NEUT]].<br />
<br />
=== {{MaterialBtn | C-4}} C-4 ===<br />
<br />
'''Description:'''<br />
"Solid pressure sensitive explosive."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Will explode when exposed to high pressure, SPRK, heat, or FIRE. Transforms into GOO when exposed to NEUT.<br />
<br />
=== {{MaterialBtn | RBDM}} Rubidium ===<br />
<br />
'''Description:'''<br />
"Rubidium. Explosive, especially on contact with water. Low melting point."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Explodes on contact with WATR, ACID and FIRE. Will not explode with SPRK, unlike other explosives. It will instead conduct just like normal metal. Melts into liquid rubidium at ~37.8C.<br />
<br />
=== {{MaterialBtn | LRBD}} Liquid Rubidium ===<br />
<br />
'''Description:'''<br />
"Liquid Rubidium."<br />
<br />
'''Type:'''<br />
Liquid<br />
<br />
The same as RBDM, except it's a liquid.<br />
<br />
=== {{MaterialBtn | THDR}} Thunder ===<br />
<br />
'''Description:'''<br />
"Lightning! Very hot, inflicts damage upon most materials, transfers current to metals."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Very hot liquid-like substance, passes a SPRK to any conductive materials. One of the most destructive elements, will create a strong pressure shock wave (256 pressure) as well as conducting its temp when in contact with non-metals (or metals that are unable to conduct electricity because a spark has just passed by). THDR's movements are not affected by pressure.<br />
<br />
=== {{MaterialBtn | THRM}} Thermite ===<br />
<br />
'''Description:'''<br />
"Thermite. Burns at extremely high temperature."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
THRM will react with FIRE, PLSM, LAVA and LIFE. It generates very large amounts of heat (Around 3000C just after ignition), hot enough to melt TTAN. Molten THRM turns into BMTL when cooled.<br />
<br />
=== {{MaterialBtn | CFLM}} Cold flame ===<br />
<br />
'''Description:'''<br />
"Sub-zero flame."<br />
<br />
'''Type:'''<br />
Gas<br />
<br />
'Cold Fire' that burns at -273.15C/0K. Will ignite C-5 and ANAR, but not other elements.<br />
<br />
=== {{MaterialBtn | FIRW}} Fireworks ===<br />
<br />
'''Description:'''<br />
"Fireworks! Colorful, set off by fire."<br />
<br />
'''Type:''' <br />
Powder<br />
<br />
After contacting FIRE, FIRW will shoot off upward and explode with hot (temp of 6000C to 9000C) and colorful embers. Use decorations to change ember colors.<br />
<br />
Explodes when tmp > 1, and life = 0.<br />
<br />
=== {{MaterialBtn | LIGH}} Lightning ===<br />
<br />
'''Description:'''<br />
"Lightning. Change the brush size to set the size of the lightning."<br />
<br />
'''Type:'''<br />
None / Special<br />
<br />
Bolt or "Arc" Lightning, Very short-lived element, ~2 to 5 frames of persistence. Upon clicking a "bolt" of LIGH will extend from the brush (angle is random, always downward when with the gravity setting on 'vertical', but at any angle when the gravity setting is 'off' (and generally pointing toward the centre of the screen when the gravity setting is on 'radial')), then dissipate, leaving a "thunderclap" pressure wave in its wake. Generates an extreme amount of heat and pressure upon making contact with another element, but not penetrating it, striking the surface only. Will spark conductors that survive the impact. Can be produced by sparking TESC. Length, temp, and pressure of bolt are based on the brush size used to produce it.<br />
<br />
=== {{MaterialBtn | DEST}} Destructive ===<br />
<br />
'''Description:'''<br />
"More destructive Bomb, can break through virtually anything."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Much more destructive than BOMB. When within 2 pixels of another element (except for DMND, any type of clone, or any type of Wall), DEST releases high amounts of heat and pressure, melting and/or scattering most elements. DEST survives for many frames after the initial impact and often tends to dig into whatever is in the way.<br />
<br />
=== {{MaterialBtn | FWRK}} Old Fireworks ===<br />
<br />
'''Description:'''<br />
"Original version of fireworks, activated by heat/neutrons."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explodes with neutrons or heat (200C). Jumps higher than FIRW but has odd trajectories and pale embers. Explodes when hot (temp of ~7000C upwards).<br />
<br />
=== {{MaterialBtn | BOMB}} Bomb ===<br />
<br />
'''Description:'''<br />
"Bomb. Explodes and destroys all surrounding particles when it touches something."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Explodes when it touches any other particles except for DMND, any type of clone, or any type of Wall. When BOMB explodes, all particles within an 8 pixel radius are replaced by EMBR (except for diamond, clone, etc) at 9725.85C, with pressure produced. This EMBR 'shrapnel' is ejected at the explosion temperature after explosion occurs, causing damage. However, the shrapnel's conductivity rapidly decreases with its life and will cease to exist after a while.<br />
<br />
=== {{MaterialBtn | C-5}} C-5 ===<br />
<br />
'''Description:'''<br />
"Cold explosive, set off by anything cold."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
Explodes when cold, produces CFLM and pressure. Only reacts with LOXY, LN2, CFLM, TRON and any other liquid cooled to below -173.85C/99K. Not pressure sensitive, and does not explode when sparked.<br />
<br />
=== {{MaterialBtn | TNT}} TNT ===<br />
<br />
'''Description:'''<br />
"TNT, explodes all at once"<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
A solid explosive similar to C-4, but creates more pressure and less fire. It is quite a hot explosive, hot enough to melt METL. TNT will explode into bomb shrapnel upon detonation. TNT is the only explosive that explodes instantaneously upon ignition. It was added in version 69.0 beta.<br />
<br />
=== {{MaterialBtn | IGNC}} Ignition Cord ===<br />
<br />
'''Description:'''<br />
"Ignition cord. Burns slowly with fire and sparks."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
A slow burning fuse-like material. IGNC, unlike FUSE, can be ignited by FIRE as well as hot materials. It burns with EMBR and FIRE at low temperatures. IGNC can be used as a delay to set off low grade explosives, and it can also burn in WATER. NEUT can pass through IGNC without distortion. Added in v70.0.<br />
<br />
=== {{MaterialBtn | FUSE}} Fuse ===<br />
<br />
'''Description:'''<br />
"Burns slowly. Ignites at somewhat high temperatures or with electricity."<br />
<br />
'''Type:'''<br />
Solid<br />
<br />
When its temp is above 700 degrees or it is sparked, it slowly turns into PLSM. Breaks into FSEP at >2.7 pressure (with a slight delay)<br />
<br />
=== {{MaterialBtn | FSEP}} Fuse Powder ===<br />
<br />
'''Description:'''<br />
"Fuse Powder. Burns slowly like FUSE."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
Powdered FUSE, works in the same way (burns into PLSM with high temperature or electricity)<br />
<br />
=== {{MaterialBtn | LITH}} Lithium ===<br />
<br />
'''Description:'''<br />
"Lithium. Reactive element that explodes on contact with water."<br />
<br />
'''Type:'''<br />
Powder<br />
<br />
It absorbs CO2 and then can be converted to GLAS. On contact with water it will haet itself by 400K and consume water. At 1000K it explodes. When pure it can be used to make batteries.<br />
<br />
<br />
[[Category:Elements]]</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=File:LITH.png&diff=8120File:LITH.png2021-07-04T10:51:35Z<p>Maticzpl: Maticzpl uploaded a new version of File:LITH.png</p>
<hr />
<div>Lithium icon in element menu</div>Maticzplhttp://powdertoy.co.uk/Wiki/index.php?title=File:LITH.png&diff=8119File:LITH.png2021-07-04T10:49:41Z<p>Maticzpl: Lithium icon in element menu</p>
<hr />
<div>Lithium icon in element menu</div>Maticzpl