Difference between revisions of "Lua API:Simulation"

From The Powder Toy
Jump to: navigation, search
(Add upcoming functions: sim.randomSeed, sim.hash, sim.ensureDeterminism)
(Corrections to determinism stuff)
Line 173: Line 173:
 
'''Upcoming in version 98.0'''
 
'''Upcoming in version 98.0'''
  
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.
+
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.
  
 
=== simulation.floodDeco ===
 
=== simulation.floodDeco ===
Line 392: Line 392:
  
 
=== simulation.randomSeed ===
 
=== simulation.randomSeed ===
  number seed0Lower, number seed0Upper, number seed0Lower, number seed0Upper sim.randomSeed()
+
  number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper sim.randomSeed()
 
  nil sim.randomSeed(number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper)
 
  nil sim.randomSeed(number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper)
  

Revision as of 16:12, 18 December 2023

The Simulation API allows for modifying the state and properties of particles, air and gravity

Contents

Methods

simulation.addCustomGol

nil sim.addCustomGol(string rule, string name, number color1, number color2)

Adds a custom game of life type with the specified rule, name, and colors. Rule strings use B#/S#/# notation (more detail). Colors are used when fading between multiple states. Names and rules cannot be duplicates.

nil sim.addCustomGol(number rule, string name, number color1, number color2)

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.

simulation.adjustCoords

number, number sim.adjustCoords(number x, number y)

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).

simulation.airMode

number sim.airMode()

Returns the current Air Simulation Mode.

nil sim.airMode(number mode)

Sets the Air Simulation Mode to mode.

Mode numbers are as follows (not currently available as named constants):

0 Normal
1 Pressure off
2 Velocity off
3 Velocity and pressure off
4 No update

simulation.ambientAirTemp

number sim.ambientAirTemp()

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.

nil sim.ambientAirTemp(number temp)

Sets the ambient temperature. The temperature is measured in Kelvin.

simulation.ambientHeat

number sim.ambientHeat(number x, number y)

Returns a value on the ambient heat map (the temperature of the air at that point).

nil sim.ambientHeat(number x, number y, [number width, number height], number temp)

Sets values on the ambient heat map.

simulation.brush

function sim.brush(number x, number y, [number brushWidth, number brushHeight], [number brushID])

Returns an iterator over positions inside the specified brush.

If width, height or ID is not provided, will use values of the current brush selected by user.

Example:

for x, y in sim.brush(300, 200, 100, 50, 0) do
 sim.partCreate(-1, x, y, elem.DEFAULT_PT_DUST)
end

simulation.can_move

simulation.can_move(number movingElementID, number obstacleElementID, number method)

Decides what a particle does when it hits another particle while moving. Method is one of the following:

  • 0: bounce off the obstacle
  • 1: swap places with the obstacle
  • 2: move over the obstacle
number simulation.can_move(number movingElementID, number obstacleElementID)

Returns what a particle does when it hits another particle while moving, a method like above.

simulation.clearRect

nil sim.clearRect(number x, number y, number width, number height)

Clears all particles in a rectangle starting at x, y down and to the right width and height pixels respectively.

simulation.clearSim

nil sim.clearSim()

Clears everything in the simulation.

simulation.createBox

nil sim.createBox(number x1, number y1, number x2, number y2, [number type], [number flag])

Creates a filled box of either the user's currently selected type or the type specified at the specified coordinates. flag refers to particle replacement flags.

simulation.createLine

nil sim.createLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number type], [number brush], [number, flag])

Creates a line of of either the user's currently selected type or the type specified at the specified coordinates. rx and ry describe the radius of the brush used. Default radius is 5, 5. flag refers to particle replacement flags.

simulation.createParts

number sim.createParts(number x, number y, [number rx], [number ry], [number type], [number brush], [number flag])

Does something.

simulation.createWallBox

nil sim.createWallBox(number x1, number y1, number x2, number y2, [number walltype])

Creates a filled box of either the specified walltype or the type of the basic wall at the specified particle coordinates. Note: the coordinates might change from particle coordinates to map coordinates in the future.

simulation.createWallLine

nil sim.createWallLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number walltype])

Creates a line of either the specified walltype or the type of the basic wall at the specified particle coordinates. Note: the coordinates might change from particle coordinates to map coordinates in the future.

simulation.createWalls

number sim.createWalls(number x, number y, [number rx], [number ry], [number walltype])

Does something. Probably with walls :/

simulation.customGravity

number, number sim.customGravity()

Returns the current custom gravity settings as x and y values. Left and up are negative x and negative y respectively.

nil sim.customGravity(number x, number y)

Sets the custom gravity x and y values. Gravity mode must be set to "custom" to have any effect (see sim.gravityMode).

nil sim.customGravity(number y)

Sets the custom gravity y value and sets the x value to 0.

simulation.decoBox

nil sim.decoBox(number x1, number y1, number x2, number y2, [number r, number g, number b, [number a]], [number tool])

Changes the decoration color of all particles in the specified coordinates. tool refers to decoration tools.

simulation.decoBrush

nil sim.decoBrush(number x, number y, [number rx], [number ry], [number r, number g, number b, [number a]], [number tool], [number brush])

Does something tool refers to decoration tools.

simulation.decoColor

number sim.decoColor()

Returns the currently selected decoration color.

nil sim.decoColor(number color)

Sets the selected decoration color to color. color is in the format 0xAARRGGBB

nil sim.decoColor(number r, number g, number b, [number a])

Sets the selected decoration color to r,g,b,a

simulation.decoColour

Same as sim.decoColor()

simulation.decoLine

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])

Changes the decoration color of all particles in the line specified. rx and ry describe the radius of the brush used. Default radius is 5, 5. tool refers to decoration tools.

simulation.deleteStamp

type sim.deleteStamp(string name)

Deleting a stamp identified by filename or ID.

simulation.edgeMode

number sim.edgeMode()

Returns the current Edge Mode

nil sim.edgeMode(number mode)

Sets the current Edge Mode to mode. 0 means normal, 1 creates a wall all the way round the edge of the simulation.

simulation.elementCount

number sim.elementCount(number type)

Returns the number of particles of the specified type in the simulation.

simulation.ensureDeterminism

boolean sim.ensureDeterminism()
nil sim.ensureDeterminism(boolean flag)

Upcoming in version 98.0

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.

simulation.floodDeco

nil sim.floodDeco(number x, number y, number r, number g, number b, number a)

Flood fills the color at position x, y with another color. Note: Color at position includes console overlay.

simulation.floodParts

number sim.floodParts(number x, number y, [number type], [number cm?], [number flag])

Flood fills either the user's currently selected type or the type specified at the coordinates given. flag refers to particle replacement flags.

simulation.floodWalls

number sim.floodWalls(number x, number y, [number walltype], [number bm?])

Flood fills either the specified walltype or the type of the basic wall at the specified particle coordinates. Note: the coordinates might change from particle coordinates to map coordinates in the future.

simulation.framerender

number sim.framerender()
sim.framerender(number frames)

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.

simulation.getSaveID

number, number sim.getSaveID()

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.

simulation.gravMap

number sim.gravMap(number x, number y)
nil sim.gravMap(number x, number y, [number width, number height,] number value)

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.

simulation.gravityGrid

number sim.gravityGrid()

Returns the current setting for drawing the gravity grid. More of a renderer setting than a simulation setting.

nil sim.gravityGrid(number mode)

Sets the setting for drawing the gravity grid to mode.

simulation.gravityMode

number sim.gravityMode()

Returns the current gravity simulation mode.

nil sim.gravityMode(number mode)

Sets the gravity simulation mode to mode.

0 Normal, vertical gravity
1 No gravity
2 Radial gravity
3 Custom gravity (see sim.customGravity)

simulation.gspeed

number sim.gspeed()

Returns the current GoL speed

nil sim.gspeed(number newSpeed)

Sets the current GoL speed. This is the number of frames between GoL updates. Default is one, larger numbers make it slower.

simulation.hash

number simulation.hash()

Upcoming in version 98.0

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).

simulation.historyForward

boolean simulation.historyForward()

Tries restoring a redo snapshot (ctrl+y). Returns true on success, or false if there is no redo history to restore.

simulation.historyRestore

boolean simulation.historyRestore()

Tries restoring a history snapshot (ctrl+z). Returns true on success, or false if there is no history to restore.

simulation.lastUpdatedID

type sim.lastUpdatedID()

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.

simulation.listCustomGol

table sim.listCustomGol()

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 sim.addCustomGol for details about properties.

simulation.loadSave

nil sim.loadSave(number SaveID, [number hideDescription], [number history?])

Loads the save associated with the specified SaveID. If hideDescription is non zero, the information for the save is not shown.

simulation.loadStamp

sim.loadStamp(string filename, number x, number y)
sim.loadStamp(number id, number x, number y)

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.

Changes staged for 98.0

The signature changes to:

sim.loadStamp(string filename, number x, number y, [boolean hflip, [number rotation]])
sim.loadStamp(number id, number x, number y, [boolean hflip, [number rotation]])

The following changes are applied to the stamp before pasting, in this order:

  • if hflip is true, a horizontal flip is applied to the save (same as pressing Shift+R when pasting)
  • 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)
  • 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)

simulation.neighbors

type sim.neighbors(number x, number y, [number rx], [number ry], [number type])

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.

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.

Example (i is the index of the neighbouring particle and nx, ny are its coordinates):

for i,nx,ny in sim.neighbors(100,200,1,1) do
 sim.partProperty(i, sim.FIELD_TEMP, 9999)
end

Or if coordinates of the neighbouring particles are not required:

for i in sim.neighbors(100,200,1,1) do
 sim.partProperty(i, sim.FIELD_TEMP, 9999)
end

simulation.neighbours

Same as sim.neighbors()

simulation.partChangeType

nil sim.partChangeType(number index, number type)

Reliably change the type of a particle, this method avoids the side effects created by changing the type directly with the "partProperty" method.

simulation.partCreate

number sim.partCreate(number index, number x, number y, number type, [number v])

Create a single particle at location x, y. Returns the index of the new particle, or a negative number on failure.

Possible values for index are:

  • -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.
  • -2 : Create particle as though it was drawn by the user with the brush. Usually not useful.
  • -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).
  • 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, ...).

simulation.partExists

boolean sim.partExists(number index)

Returns true if a particle exists at a given index.

simulation.partID

number sim.partID(number x, number y)

Get the index of a particle at the specified position. As of v89.3, this will return nil if there is no particle there.

Example (though this is probably best done with sim.neighbours):

for fx = -1, 1, 1 do
 for fy = -1, 1, 1 do
  local i = sim.partID(x + fx, y + fy)
  if i~=nil and sim.partProperty(i, 'type') == elements.DEFAULT_PT_DMND then
   sim.partProperty(index, sim.FIELD_TEMP, 9999)
  end
 end
end

simulation.partKill

nil sim.partKill(number index)
nil sim.partKill(number x, number y)

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

simulation.partNeighbors

table sim.partNeighbours(number x, number y, number radius, [number type])

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.

simulation.partNeighbours

Same as sim.partNeighbors()

simulation.partPosition

number x, number y sim.partPosition(number index)

Get the location of the particle at the specified index

simulation.partProperty

nil sim.partProperty(number index, object field, object value)

Set the property value on a particle specified by index

object sim.partProperty(number index, object field)

Get the property value on a particle specified by the index

The "field" may be a field name or field ID, see FIELD constants below for valid fields.

simulation.parts

function sim.parts()

Returns an iterator over particle indexes that can be used in lua for loops

simulation.pmap

number sim.pmap(number x, number y)

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).

simulation.photons

number sim.photons(number x, number y)

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

simulation.pressure

number sim.pressure(number x, number y)

Returns a value on the pressure map.

nil sim.pressure(number x, number y, [number width, number height], number pressure)

Sets values on the pressure map.

simulation.prettyPowders

number sim.prettyPowders()
nil sim.prettyPowders(mode)

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.

simulation.randomSeed

number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper sim.randomSeed()
nil sim.randomSeed(number seed0Lower, number seed0Upper, number seed1Lower, number seed1Upper)

Upcoming in version 98.0

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.

Because seeds are 64 bits, they are fetched/set in two sets of 32 bits integers.

simulation.reloadSave

nil sim.reloadSave()

Reloading save.

simulation.removeCustomGol

boolean sim.removeCustomGol(string name)

Removes all custom game of life types with the specified name. Returns true if any were removed.

simulation.resetPressure

nil sim.resetPressure()

Resets the pressure map to no pressure.

simulation.resetTemp

nil sim.resetTemp()

Resets the temperature of all particles to their spawn temperature.

simulation.replaceModeFlags

number sim.replaceModeFlags()

Returns the current replace mode flags.

nil sim.replaceModeFlags(number flags)

Sets the replace mode flags.

If the first bit of that number is set (flags = 1), replace mode is enabled.

If the second bit is set (flags = 2), specific delete is enabled.

simulation.saveStamp

string sim.saveStamp([number x, number y, number width, number height])

Creates a stamp of the specified coordinates. Coordinates default to entire simulation. Returns the stamp id created.

simulation.signs

table simulation.signs

A table of signs. simulation.signs[1] through simulation.signs[16] are always defined.

simulation.signs[n]

table simulation.signs[n]

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. A justification of 0 means left, 1 means right, 2 means middle and 3 means none. The text property cannot be larger than 45 in length.

simulation.signs.delete

nil simulation.signs.delete(number signID)

Deletes the sign at the specified sign id.

simulation.signs.new

number simulation.signs.new([string text, number x, number y, number justification])

Creates a new sign with the specified properties. Returns the sign ID, or nil if there are too many signs (the limit is 16).

simulation.takeSnapshot

nil sim.takeSnapshot()

Takes a undo snapshot, for use with ctrl + z

simulation.temperatureScale

number sim.temperatureScale()

Returns the current temperature scale. 0 = Kelvin, 1 = Celsuis, 2 = Fahrenheit

nil sim.temperatureScale(number newTemperatureScale)

Sets the current temperature scale. 0 = Kelvin, 1 = Celsuis, 2 = Fahrenheit. Other options are invalid and will throw an error.

simulation.toolBox

type sim.toolBox(number x1, number y1, number x2, number y2, [number tool], [number strength])

Performs the given tool (HEAT, COOL, AIR, etc) in a rectangular area.

simulation.toolBrush

number sim.toolBrush(number x, number y, [number rx], [number ry], [number tool], [number brush], [number strength])

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).

simulation.toolLine

type sim.toolLine(number x1, number y1, number x2, number y2, [number rx], [number ry], [number tool], [number brush], [number strength])

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).

simulation.updateUpTo

nil sim.updateUpTo([number upTo])

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.

simulation.velocityX

number sim.velocityX(number x, number y)

Returns an X value on the velocity map.

nil sim.velocityX(number x, number y, [number width, number height], number value)

Sets X values on the velocity map.

simulation.velocityY

number sim.velocityY(number x, number y)

Returns an Y value on the velocity map.

nil sim.velocityY(number x, number y, [number width, number height], number value)

Sets Y values on the velocity map.

simulation.waterEqualisation

number sim.waterEqualisation()

Returns the current Water equalisation setting.

nil sim.waterEqualisation(number setting)

Set the Water equalisation setting to setting.

simulation.waterEqualization

Same as sim.waterEqualisation()

Constants

Any of these constants can be accessed with simulation.<constant name here>

XRES

X Resolution of the sim

YRES

Y Resolution of the sim

CELL

Size of a wall / air simulation block

NT

No transition, used in *Transition properties

ST

Special transition, used in *Transition properties, but there is no way to set a special transition handler from Lua

ITH

Impossible temperature high, used along with NT to disable transitions

ITL

Impossible temperature low, used along with NT to disable transitions

IPH

Impossible pressure high, used along with NT to disable transitions

IPL

Impossible pressure low, used along with NT to disable transitions

PT_NUM

Maximum number of element IDs. Does not reflect the current number of elements, only the maximum that can be enabled at one time.

NUM_PARTS

Not actually a constant, this is updated every frame to reflect the current number of particles in the sim

R_TEMP

Room temperature (22C), the default temperature for many elements

MAX_TEMP

Maximum allowable temperature of the sim, in Kelvin

MIN_TEMP

Maximum allowable temperature of the sim, in Kelvin

MAX_PRESSURE

Minimum allowable pressure of the sim

MIN_PRESSURE

Maximum allowable temperature of the sim

PMAPBITS

Number of bits used in pmap to store element type. This controls the element cap, which is 2^PMAPBITS

PMAPMASK

Mask used to assign type to pmap. ((1<<PMAPBITS)-1)

DECO

Used in deco drawing functions

DECO_DRAW
DECO_CLEAR
DECO_ADD
DECO_SUBTRACT
DECO_MULTIPLY
DECO_DIVIDE
DECO_SMUDGE

TOOL

Used in tool drawing functions

TOOL_HEAT
TOOL_COOL
TOOL_VAC
TOOL_AIR
TOOL_PGRV
TOOL_NGRV
TOOL_MIX
TOOL_CYCL
TOOL_WIND

FIELD

Used in sim.partProperty

FIELD_TYPE
FIELD_LIFE
FIELD_CTYPE
FIELD_X
FIELD_Y
FIELD_VX
FIELD_VY
FIELD_TEMP
FIELD_FLAGS
FIELD_TMP
FIELD_TMP2
FIELD_TMP3
FIELD_TMP4
FIELD_DCOLOUR