b4462273b0
get_normal_interp is given a PHOT and scans a line section starting from the PHOT, extended in the direction of its velocity, to determine the surface normal of the surface that is reflecting the PHOT. It uses is_boundary to detect "boundaries" on this line section, defined as one "blocking" cell with at least one "non-blocking" non-diagonal neighbour. It never actually makes sure the position it passes to is_boundary is within the simulation area, so I assume is_boundary is expected to handle this correctly. Plot twist: it does not. It delegates checking whether a cell is "blocking" (defined as something PHOT would normally fail to move into as per eval_move, but GLAS and BLGA are handled specially) to is_blocking. is_blocking returns true for cells beyond the simulation area (as eval_move returns "no move" for such cells). Once is_boundary sees that the cell it's been given is blocking, it then proceeds to check whether any of its non-diagonal neighbours might be non-blocking. In most cases, non-diagonal neighbours of an out-of-bounds cell are also out of bounds and are thus blocking, but if the cell is_boundary is given is in the innermost layer of out-of-bounds cells, just beyond the simulation area, then it has a neighbour that is in bounds, and that one may not block PHOT. The takeaway is that out of bounds cells can indeed be boundaries, as far as is_boundary is concerned. This is a problem because get_normal_interp's line section can easily reach beyond the simulation area if the PHOT's velocity is high enough, and if it finds a boundary along this line section, it immediately stops looking and passes its position to photoelectric_effect, which then uses this potentially out-of-bounds position to index pmap. A position with y = -1 causes photoelectric_effect to read from the last few slots of parts data that it then interprets as pmap entries, which then may direct it to particles to spark that are beyond parts. This eventually crashes. This commit doesn't fix is_boundary's definition of boundaries, but it stops get_normal_interp looking at cells beyond the simulation area. The crash is difficult to reproduce because there have to be many particles in the simulation for the very last slots of parts to be in use, and for them to point to memory that isn't accessible. PHOT also has to survive a try_move beyond the simulation area first (otherwise the reflection code isn't even run), which requires it to start from EHOLE. I have no idea why this is so. Reproduce the out of bounds read in photoelectric_effect with break Simulation.cpp:2934 if nx < 0 in gdb and executing the following Lua code: sim.clearSim() tpt.set_wallmap(55, 44, 12) local i = sim.partCreate(-1, 223, 178, 31) sim.partProperty(i, "vx", -300) sim.partProperty(i, "vy", 0) sim.framerender(1) |
||
---|---|---|
.github | ||
android | ||
cross-examples | ||
data | ||
resources | ||
src | ||
subprojects | ||
.gitattributes | ||
.gitignore | ||
changelog.txt | ||
fonttool.py | ||
LICENSE | ||
meson_options.txt | ||
meson.build | ||
README.md |
The Powder Toy - July 2021
Get the latest version from the Powder Toy website.
To use online features such as saving, you need to register an account. You can also visit the official TPT forum.
Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more!
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own – we welcome your creations!
There is a Lua API – you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development.
Build instructions
See the Powder Toy Development Help section on the main page of the wiki.
Thanks
- Stanislaw K Skowronek - Designed the original
- Simon Robertshaw
- Skresanov Savely
- cracker64
- Catelite
- Bryan Hoyle
- Nathan Cousins
- jacksonmj
- Felix Wallin
- Lieuwe Mosch
- Anthony Boot
- Me4502
- MaksProg
- jacob1
- mniip
- LBPHacker
Libraries and other assets used
Instructions
Click on the elements with the mouse and draw in the field, like in MS Paint. The rest of the game is learning what happens next.
Controls
Key | Action |
---|---|
TAB | Switch between circle/square/triangle brush |
Space | Pause |
Q / Esc | Quit |
Z | Zoom |
S | Save stamp (use with Ctrl when STK2 is out) |
L | Load last saved stamp |
K | Stamp library |
0-9 | Set view mode |
P / F2 | Save screenshot as .png |
E | Bring up element search |
F | Pause and step to next frame |
G | Increase grid size |
Shift + G | Decrease grid size |
H | Show/Hide HUD |
Ctrl + H / F1 | Show intro text |
D / F3 | Debug mode (use with Ctrl when STK2 is out) |
I | Invert Pressure and Velocity map |
W | Cycle gravity modes (use with Ctrl when STK2 is out) |
Y | Cycle air modes |
B | Enter decoration editor menu |
Ctrl + B | Toggle decorations on/off |
N | Toggle Newtonian Gravity on/off |
U | Toggle ambient heat on/off |
Ctrl + I | Install powder toy, for loading saves/stamps by double clicking |
Backtick | Toggle console |
= | Reset pressure and velocity map |
Ctrl + = | Reset Electricity |
[ | Decrease brush size |
] | Increase brush size |
Alt + [ | Decrease brush size by 1 |
Alt + ] | Increase brush size by 1 |
Ctrl + C/V/X | Copy/Paste/Cut |
Ctrl + Z | Undo |
Ctrl + Y | Redo |
Ctrl + Cursor drag | Rectangle |
Shift + Cursor drag | Line |
Middle click | Sample element |
Alt + Left click | Sample element |
Mouse scroll | Change brush size |
Ctrl + Mouse scroll | Change vertical brush size |
Shift + Mouse scroll | Change horizontal brush size |
Shift + R | Horizontal mirror for selected area when pasting stamps |
Ctrl + Shift + R | Vertical mirror for selected area when pasting stamps |
R | Rotate selected area counterclockwise when pasting stamps |
Command Line
Command | Description | Example |
---|---|---|
scale:SIZE |
Change window scale factor | scale:2 |
kiosk |
Fullscreen mode | |
proxy:SERVER[:PORT] |
Proxy server to use | proxy:wwwcache.lancs.ac.uk:8080 |
open FILE |
Opens the file as a stamp or game save | |
ddir DIRECTORY |
Directory used for saving stamps and preferences | |
ptsave:SAVEID |
Open online save, used by ptsave: URLs | ptsave:2198 |
disable-network |
Disables internet connections | |
redirect |
Redirects output to stdout.txt / stderr.txt | |
cafile:CAFILE |
Set certificate bundle path | cafile:/etc/ssl/certs/ca-certificates.crt |
capath:CAPATH |
Set certificate directory path | capath:/etc/ssl/certs |