b393050e55
When PHOT fails to move (do_move or eval_move return "no move"), it looks for a surface (a contour of boundaries, as reported by is_boundary) along its path and reflects off (or refracts into, see below) it, using get_normal_interp to find the point of incidence and get_normal to deduce the surface normal. get_normal is given the point and angle of incidence, and attempts to traverse the surface the point belongs to by running two "surface scout" processes. These processes remember their own position and "heading", a subset of the eight cardinal directions on the grid. They are initialized with the point of incidence and a heading that includes all directions whose dot product with the angle of incidence is non-negative (see direction_to_map). They then perform a few iterations (SURF_RANGE). In each iteration, the processes check all eight neighbours of the cell they are on and select the first neighbouring cell they find that is both a boundary (as reported by is_boundary) and that is within their heading. They then move to this neighbouring cell and update their heading by discarding directions that are not similar enough to (differ by more than 45 degrees from) the one that took them where they are now (see find_next_boundary). If they find no such neighbour, they stop. Continuing the militaristic line of thinking introduced by the term "surface scout", you can imagine the two processes as two paratroopers who arrive from above, land on a horizontal surface, and one starts going left, while the other starts going right. They initially expect the surface they land on to be close to horizontal, but are also prepared for not too erratic changes in its angle as they go. Changes too erratic (imagine a precipice) scare them and force them to stop. Once the processes finish, an imaginary line segment is drawn between the cells they ended up on. If the line segment is long enough (estimated by j, and compared against NORMAL_MIN_EST), get_normal returns a normal that is perpendicular to it. If it is too short, get_normal gives up and returns nothing (which results in the PHOT being killed). This amounts to our paratroopers attempting to get the "lay of the land" by walking away from where they landed and comparing where they end up. They also know that if they are still relatively close to each other at the end of their walk, their measurement is probably wrong and their mission should be aborted. The bug this commit fixes is that get_normal returns bogus surface normals when it encounters thin walls of particles, defined as walls exactly two layers of particles thick. One-layer walls are not really walls, as movement code allows particles to penetrate these, and three-layer and thicker walls are too thick for the bug to manifest. The bug manifests for two-layer walls because the "left" scout process is drawn to the side of the wall opposite to the one with the point of incidence. This is because scout processes check neighbours in a clockwise order, and always select the first suitable neighbour they find. As particles on the other side of the wall are both boundaries and are within the heading of the processes, they also qualify as suitable neighbours, so whether a scout process selects the correct side of the wall depends on the order in which neighbours are checked. Essentially, the paratroopers look at their immediate surroundings in a clockwise order. The right paratrooper always finds the ground and knows where to step. The left paratrooper finds the Upside Down from Stranger Things and teleports there. This bug also affects refraction into and out of thin walls, but since these walls are thin, the path the PHOT takes inside them is rather short and the incorrect angle of travel is difficult to see. Furthermore, upon exit, the same normal deduction bug causes the PHOT to take a path whose angle is almost identical to that of the path that took it to the wall, so much so that it is also difficult to see over shorter distances. The solution is to have the left scout process check neighbours in reverse order, so that it prefers the right side of the wall over the wrong one. This does not affect its behaviour when facing thicker walls, but fixes its behaviour when facing two-layer walls. The changes in this commit also make find_next_boundary interact with is_blocking directly to detect a change between the blocking trait of immediate neighbours. This makes more sense than relying on is_boundary because find_next_boundary is meant to find a transition from non-blocking to blocking neighbours within the current heading, rather than to find any boundary particle. The difference is subtle but important. |
||
---|---|---|
.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 |