time to code
(please use Chrome)
- buttons and toggles
- frame rate
This first topic gives an overview of this physics-engine application:
Move objects with your mouse or finger. Drag and fling them. Put on the breaks with the f key. Try the g key.
Click on the links in the "Plus" row to run the variations of the base demos.
Button #7 starts the Puck Popper game. With multiple players, use #8 for more terrain. For more challenge, try 8c, 8d, and 8e. Here's a short how-to video on Puck Popper. Try the Jello: #6.
The client interface for multiplayer includes a virtual gamepad for cell phones (or any touch-screen device). Try it. Click the multiplayer option here to start hosting a game. Type in a room name, and then click the "Create" button. On your cell phone, from the client page, enter the room name and then touch the "Connect" button. After connecting your phone client to the host, touch the "Two-Thumbs" button.
Try an editor feature: select a puck, then resize it with the arrow keys.Then save your edits by clicking the capture button. Replay the capture by clicking the corresponding number key.
The "Freeze" button momentarily stops all puck translation while allowing rotation to continue. The neighboring "R" button stops all rotation (use t and shift-t to change the rotation rate of a selected puck).
The "Reverse" button flips the velocity and reverses the rotation rate of each puck.
Each of the three mouse buttons has a different spring strength for dragging objects: left click for the normal spring, center click for the weakest spring, right click for the strongest spring and a firmer connection to the larger pucks. (Note that using the right mouse button on the smallest pucks may cause instability in the physics engine; go ahead and try it.) If you're only positioning a small puck (not flinging it), try doing so with the control key down; that will always be stable.
Each demo control has keyboard shortcut letter underlined in its label. That is a keyboard key to use as an alternative to the mouse.
The Center Of Mass (COM) toggle controls the position of the selection point. With this on, you will always select the middle of the target object. Turning this off allows you to spin (or stop spinning) the objects.
The "gravity" toggle also controls several associated parameters in the Box2D physics engine: restitution, friction, and b2_velocityThreshold. Depending on the demo, if gravity is turned off, these settings are used to produce more elastic collisions (low energy loss) so things keep moving and don't stick to the walls. In demo #6, the opposite is done so that collisions are inelastic, reducing chatter when pucks are held in contact with each other under the tension of springs. Note that if you use the editor to change the restitution of a puck, it will remain fixed at that level, independent of the gravity toggle, until the demo is restarted (or the puck is edited again).
The "pause" toggle disables all updates to the canvas. When paused, a stepper button is revealed in place of the fps value; click it to advance a single frame. If the perimeter walls are red, the animation is paused. Uncheck the "pause" control to resume animation. Alternatively use the "p" key to pause and resume. The neighboring "o" key will single step the animation. Hold the "o" key down to repeatedly step at a slow rate.
Use the "Multiplayer" toggle to display the controls for connecting as a host to the node server. Then type a short room name into the red input box (on the left). Optionally, type a nickname for yourself into the chat input box. For example, type nn:Bubba to name yourself Bubba. Then click the "create" button. Wait a few seconds for the server to wake up. Open one (or several) client windows from these links: window, tab. From those client pages, repeat the connection process using the same room name that you specified as the host. Once connected, you will see your mouse and keyboard events rendering to the host canvas (this page). That way multiple users can simultaneously interact with the animated objects in the demo. The question-mark key can be useful for locating your puck in the Puck Popper game (demos 7 and 8). There's more info on the specifics of multiplayer game play in the topics for demos #7 and #8 below.
Optionally, each connected client may initiate a live video stream of the host's canvas. After connecting, click the "Stream" checkbox on the client. This works best if the host and the clients are running their monitors at the same refresh rate. Overall, Chrome is the best browser for producing smooth rendering of the stream on the client. If the client has limited cpu power (like a Raspberry Pi), it's best not to stream. Any client without a video stream has to be in the same physical room to see the rendering on the host's screen.
The Two-Thumbs touch screen interface, a virtual gamepad (see image below), is useful for controlling a game puck from a cell phone in demos 7 and 8 (Puck Popper). From your cell phone, or other touch-screen device, open the client page in Chrome. Connect to the host as described above, then click the "Two Thumbs" button. Your left thumb will control the jet direction and intensity (more thrust the farther your touch point is out from center dot). Right thumb fires and aims the shooter. The center rectangle turns the shield on/off.
The colored rectangle, below the shield control, indicates your client color. Touch it, and a large circle will show around your puck (helping you to find it). The small rectangle controls at the bottom require the alt rectangle to be touched first (this prevents accidental firing of these controls when driving the puck). These can be used to: get out of the full-screen mode (esc), freeze the object motion (f), restart the two Puck Popper games (7 and 8). The scope control is located in the bottom right corner of the virtual gamepad. This control precisely rotates the shooter tube and shoots from a fixed position. Touching the center block stops the movement of your puck, and then shoots without recoil (and no rotation). The surrounding two blocks, rotate the shooter tube (ccw or cw). The rotation rate is reduced as the touch point approaches the center block.
Note that you can use the Two-Thumbs interface, even when there is no direct line of sight to the host's screen, by starting up a second client with a video stream.
Also notice the "Full Screen" button (bottom right). This puts the animation canvas into full-screen mode and gives a nice front-and-center presentation of the demos (my favorite way to play Puck Popper). This works best in Chrome. In full-screen mode, you can scale the canvas up and down with the ctrl +/- keys.
There is more information on the Node.js, socket.io, and WebRTC that are used here, including instructions on how to install a local node server on the host computer.
The "Capture" button records the current state of a demo. The result is written to the neighboring text cell and also to the paste buffer. The capture can be immediately run by pressing the corresponding number button (this will be highlighted yellow). Restart the capture by clicking the button again.
There are links to color-highlighted examples of JSON captures in the help topic for demo #6. These were taken following use of the editing features (see below) to make two circular structures from the Jello matrix.
Captures can be edited. First drag out the lower right corner of the capture text area to better view the capture text. For an editing example, run the 2c demo, and then edit the capture so that one of the pucks has its tail's rainbow parameter set to true. Then click the #2 button.
Editing features can be used to change the characteristics of selected pucks, pins, walls, or springs.
Select a single object by clicking in the canvas area and then dragging the cursor over the object (or by directly clicking on the object).
Summary of the single-select commands:
- control key
- mouse drag: hold the control key down and mouse drag the object. Puck position and elasticity parameters are displayed in this mode.
- rotation: hold down the control and shift keys and drag the edge of the object using the mouse.
- arrow keys: resize a single object
- up/down keys: change a rectangular object's height
- left/right keys: change a rectangular object's width
- "[" and "]" keys: change the puck's restitution (bounce)
- "+" and "-" keys: change the surface friction (tackiness)
- "<" and ">" keys: change the linear damping (drag)
- ctrl-c: copy
- ctrl-x: delete
By default, walls and pins (stationary spring anchors), are not selectable unless you check the "Edit walls & pins" box. This default protects them from moving around under normal mouse-drag situations.
Check the "Edit walls & pins" box to change the characteristics of the static terrain for any of the demos. This includes perimeter and interior walls (even rotating ones). Just click and drag to move walls and pins. Refer to the next section, on Multi-select, for commands to rotate objects.
Demo #8 was constructed using the editing features and the state-capture feature. Modify demo #8 to create your own battle field: edit, then capture it.
Multi-select allows you to select single or multiple objects. This is the only method by which springs can be selected (by selecting their connected pucks and pins).
Hold the shift key down to select multiple objects during mouse drag (turn off "Select COM" to select off-center points). Hold down the alt key for box-based selection.
Selected objects are indicated by yellow dots; springs are dashed. To unselect an object, RIGHT click and drag, still using the shift (or alt) key. Note that right clicking with shift down in FireFox yields a context menu when you release the click; ignore it, try using the alt key with FireFox, or use Chrome.
To completely reset the multi-selection, release the shift (or alt) key and click on any empty space in the canvas area.
Summary of the multi-select commands:
- control key: group drag
- hold the control key down, then click and mouse drag any body in the multi-select group causing the whole group to drag
- control and shift keys (or control and alt): group rotation
- hold both the control and shift keys down, then click and mouse drag any body in the multi-select group causing the whole group to rotate about the center of the group
- hold both the control and alt keys down to cause each body to rotate about itself
- arrow keys: resize single or multiple objects
- the "s" key (hold it down) directs resizing operations at selected springs. In the default mode ("s" key up), resizing is directed at selected pucks and walls.
- up/down keys change the object's length
- left/right keys change the objects's width (and strength if it's a spring)
- t (and shift-t): incrementally change the rotation rate.
- "[" and "]" keys: change elasticity
- change the restitution (bounce) of selected pucks
- with the "s" key (hold it down), change the damping (shock absorbers) on selected springs
- "+" and "-" keys: change the surface friction (tackiness)
- "<" and ">" keys: change the linear damping (drag)
- ctrl-x: deletes single or multiple objects
- the first ctrl-x operation deletes the selected springs, a second ctrl-x deletes selected pucks and pins
- ctrl-c: copy a single spring (must have ONLY the two connected pucks or pins selected)
- ctrl-s: paste a single spring (onto two selected pins or pucks)
- ctrl-v: replicate a selected group of objects to the cursor location. Note: client pucks and navigation pins are excluded.
Copy and paste can be used to place a spring onto a pair of selected pucks or pins:
- use multi-select to select ONE spring (two pucks/pins)
- copy it (ctrl-c)
- use multi-select to select a new pair of pucks/pins (turn off "Select COM" to select off-center points)
- paste the spring (ctrl-s)
- Dissect (or add to) the jello matrix in demos #6 and #8.
- Select a compound object (like the triangle in demo #5) and change the connecting spring lengths while it's spinning.
- Delete some of the pucks in demo #3. Select and delete without using the freeze button. Notice how the new holes in the puck grid propagate after wall collisions.
Demo #1 presents several circular puck animations. The 1a version is a simple mix of large and small pucks, no gravity. These pucks have some surface friction, tackiness, affecting collision and rotational behavior. If gravity is toggled on, their tacky surface, allows these to be combined (stacked) into rolling trios. Try toggling off the COM (center of mass) selection and then mouse drag to apply a torque to one of these pucks. Surface friction of selected pucks can be changed via the editor (+,- keys).
1b illustrates the capability of Box2D to model multiple objects in contact that can settle under gravity to form a stacked pile.
1c presents an unusual method for calculating the first two digits of pi (31) using two elastically colliding pucks. Wait as the large puck is repelled by collisions with the smaller puck (and wall). The collision count will stop, eventually, as the two pucks both move in the negative y direction, the large puck slightly faster than the smaller one. This 31-count case occurs when the larger puck has 100 times the mass of the smaller. If the mass of the two pucks are changed to be equal (you can try this by editing the capture), this demo will yield the first digit of pi (3), three collisions, two kisses and one wall bounce. More pi digits can be found in this way at higher mass ratios, where the ratio is 100 to some power of n (but you'll have to use a dedicated 1D physics engine to do this). This video tells the counting-to-pi story.
Demo #2 is a sound-field simulation where two of the pucks are emitting at 60Hz (or the refresh rate of your computer and monitor). The width of the canvas represents 6 meters. Every second a single wave is colored white (others are gray) so you can see that waves are propagating out from the puck. The propagation speed can be changed in the capture (propSpeed_ppf_px). The set of waves are stored in a FIFO buffer. The set size can be changed in the capture (length_limit). This gives the appearance of a tail as the puck is dragged. If you fling the puck so it moves faster than the wave speed (Mach > 1) you will see a shock-wave.
The 2c version of this demo illustrates object motion at Mach speeds of 1.00, 1.41, and 2.00. These speeds produce corresponding Mach angles of 90°, 45°, and 30° (view the capture).
When using the single-frame stepper, you'll see that the 'white' wave is colored red for even more visibility. Pause it when the white wave is visible, then click the "step" button. Notice that the center of the red circle never moves, even if the puck is moving.
2e has a rainbow tail, as characterized in the HSL (Hue, Saturation, Lightness) color space. Saturation and lightness percentages are editable in the capture.
Demo #3 presents examples of order and disorder and are intended for use with the "reverse" button.
3a illustrates the effect of a disorderly influence on a grid of pucks colliding with each other and the walls. Try reversing the puck motion shortly after the start of the disorder. You'll see that it doesn't take long before this becomes non-reversible. The Playing Catch video (second) in the Perfect Kiss topic, demonstrates a much more reversible puck-puck collision calculation.
3b and 3c have puck-puck collisions inhibited, leaving only wall collisions. This makes for a very reversible collision process even minutes into the demo.
Demo #4 shows box2d's capability for modeling the rotation and collisions of non-spherical objects. This is a good one to try the editing features. Copy one of the rectangles and then change its width and length. Make some copies of your copy.
The 4b capture (view it) looks a bit like a flying drone. Try using multi-select to select the whole drone (alt-key and mouse drag), then use the right arrow key to change the length of the rotors. If you make them long enough they will collide and stop spinning. Angular momentum is conserved and causes the drone body to start spinning. In a similar way, you can cause the rotors to collide by changing the length of the springs (select the whole drone, hold the s key down, then up/down arrow keys).
For an editing exercise, enable wall and pin edits (click the checkbox). On the left side of the canvas, a spring is mounted on two pins. This can be used to produce a copy (shift key, then carefully mouse-drag over the pins, without selecting the wall, then ctrl-c) and paste it onto a pair of pucks (with the shift key down, mouse-drag over two pucks, then ctrl-s).
The "Freeze" (stop translation) and "R" (stop rotation) buttons are especially useful here.
The 4c capture shows a rectangular puck, elastic and with no surface friction, initialized to have no y component of momentum. The wall collisions, without friction, offer no impulse in the y direction, so it's center of mass continues to travel along the same line. The wall collisions do provide a rotational impulse, so the puck's energy transfers back and forth between rotational and translational forms.
Demo #5 introduces springs and pins. The spring objects model both springiness and damping behaviors. Pins are stationary anchor points to which springs can be attached.
Try using the "F" key to stop the orbiting behavior. The pucks in the triangle group and the large tethered-to-a-pin puck are all characterized as inelastic so they play well together under tension. Try to get the large puck inside the triangle group. Notice that the triangle group can be flattened out if gravity is on. Turning gravity off will often result in the flattened triangle popping up and moving. Try this a few times under the dangling large puck (might have to lower the two pins of the large puck, get it closer).
This is another good place to try the editing features. Use multi-select to select the three springs on the triangle (hold shift (or alt) key down then mouse over the three pucks), then adjust their length, as a group, using the "s" and the up/down arrow keys. Use the "s" key and the "[" and "]" keys to change their damping coefficients. Try copying and pasting a spring.
Here is a Rube Goldberg type variation of this: view it, run it.
And here's a simple spring pendulum that is tuned to show its two natures: vertical spring bounce and pendulum swing (view it, run it). Give it a little time and you'll see it change back and forth between the two mode.
Traditional springs models are not native to Box2D and are developed here as external objects that apply forces to things modeled in Box2D. Erin Catto uses a soft-constraints approach to spring modeling (distance joints) in Box2D. Here is his presentation on this. I use the equations on page 45 to translate from k and c to frequency and damping ratio.
The following capture (view it, run it) contrasts these two spring types: traditional springs on the left (yellow), and distance joints (cyan) on the right. Use shift-s to toggle the default spring nature (soft-constraints or traditional). Almost all the springs at TimeToCode refer to this default setting as they are being instantiated. So you can toggle this setting and then (you must) re-run a demo to see the change in behavior. The capture links in this paragraph are the exception to this and explicitly specify the spring nature. In this one demo capture, soft will stay soft, traditional will stay traditional. As usual, all the editing features work here, and can be used to build compound spring-puck groups and adjust the spring characteristics (length, spring constant, and damping). The key advantage of the soft constraints is stability: strong spring (or strong damping) forces on small masses will not be unstable. But it always seems that the traditional springs give a better feel, especially in compound groups. So I continue, for now, to leave all the demos starting up with traditional springs.
Demo #6 is the basis for the Jello-Madness game from the J-term course. The demo starts with a mildly tangled block of jello, it's spinning, and the tangle-timer is running. Straighten out the block and the tangle timer stops. The idea here is to severely tangle up the block for a game (drag perimeter pucks into the middle using the right mouse button). Use the capture button to record a good tangle. Then pass the mouse and keyboard to your friend and see if they can untangle the mess; they start by clicking the #6 button (or 6 key). The shortest untangle time wins. The right mouse button, the freeze control (f key), and possibly the gravity control are useful in this game. Hints: one of the interior pucks is colored differently and also note the diagonal springs are all yellow.
Here are links to JSON captures of editor-modified versions of this demo (b: view it, run it, and c: view it, run it ). To see the animation, use the run-it links above. Alternately, follow the view-it links, copy everything, then paste into the text area under the "Capture" button. Then click the #6 button to run the capture.
Demo #7 is the small version of Puck Popper. The object of this game is to be the last controlled puck remaining (all other player and drone pucks have been popped). The center black puck is outfitted with the client controls needed to play the game. Multiple network clients can play (see multiplayer topic above). All network clients should first connect, then the host should click the #7 button.
The w-a-s-d group of keys controls the jet that is used to move your puck. The "w" key fires the jet. The "a" and "d" keys rotate the jet clockwise and counterclockwise. The "s" key is used to turn the jet to a direction opposing the current motion of the puck. This can be useful in breaking (stopping). Subsequent "s" presses rotate the jet in 90-degree clockwise steps. Firing the jet, "w", resets this pattern so the flip operation results with the next "s" press.
The i-j-k-l group of keys controls your gun. The "i" key shoots bullets. The "j" and "l" keys rotate the gun clockwise and counterclockwise. The "k" key rotates the gun in 90-degree clockwise steps (shift-k steps counterclockwise).
Holding down the spacebar turns on a shield that protects you from the bullets of an opponent (you can't shoot when your shield is up). Target pucks will pop after 10 hits, client-controlled pucks pop after 20 hits.
The "friendly fire" checkbox (visible when the "Multiplayer" control is checked) controls whether bullets from real Puck Popper players can affect the health of other real players. If unchecked, human bullets can only impact the drones. In this mode multiple players act as a team to scrub out those nasty drones. Nice.
The blue pucks are drones. They try to get you (it's time to start using the spacebar to turn your puck shields on). The drones follow a path established by the blue pins. Turn on the editor to see the navigation path. When the editor is on, you can drag these navigation pins to change the drone path. These pins can also be copied and deleted using the features of the editor.
The multi-select features of the editor can be used to detach the drone from the navigation path (delete its spring). First, check that wall and pin edits are enabled. Box selection (click and drag with the alt key down) is useful for selecting the spring between the drone and the navigation pin. If you've used the ctrl-q feature to disable (sleep) the drone's movement and shooting, it will come to rest over its current pin, making it hard to select both pin and drone using the shift-key approach. The box selection method allows pin, drone, and spring to be selected in one action, the box drag. Then ctrl-x deletes the navigation spring.
In a similar way, you can reattach a drone by copying (ctrl-c) the spring from another drone and pasting (ctrl-s) it onto the free drone and a blue navigation pin. Remember, ctrl-q toggles drone shooting and navigation on/off, useful when detaching and reattaching them.
Drones can be copied, to produce a free floating drone: mouse-drag over a drone, then ctrl-c. Attach it to the navigation path using the methods above.
A single drone, attached to a navigation pin, can be generated by depressing the shift, d, and p keys together (shift-d-p). The drone and pin will appear at the current location of the local host's cursor. If wall/pin edits are enabled, you can then extend this drone's navigation course by copying and dragging the pin (single-select operation, ctrl-c).
Navigation forces are rendered as jets when the editor is off (rendered as springs when the editor is on).
The drones use raycasting to find puck targets. To hide from the ray, move behind a wall, behind another puck, or beyond the length of the ray.
After finding a puck, they point their gun to "lead" the target. This anticipates where the moving-target puck will be when the bullets arrive. You'll see the gun is angled slightly ahead of the raycast line when the target is moving. The algorithm also accounts for the motion of the drone.
The controlled pucks are inelastic and with some drag to make them a bit easier to drive (bullets and regular pucks are elastic and with no drag).
Scoring in Puck Popper (demos 7 and 8):
- +200 for last puck-player standing
- +100 for popping client and drone pucks
- +50 for popping a regular puck
- +10 for hitting a puck with one of your bullets
- -10 for getting hit by a bullet
- -1 for shooting a bullet that expires before it hits another puck
A leaderboard report, the top 15 scores, is displayed below the game-score summary table. The report consists of two query results, one table sorted by time, the other by score (click the link to toggle between the two tables). The backend of the leaderboard, a Google sheet, is queried depending on the version of the Puck Popper game (e.g. demo #7 results are reported separate from #8). Custom versions of Puck Popper, made using the capture feature, are reported separately as distinguished by a unique identifier in the capture. Game results where the mouse was used (in the Canvas area) or the drones are "sleeping", are filtered out of the reports.
From the host page, you can establish a nickname (without connecting to the multiplayer server) by typing the nickname phrase, e.g. nn:Jimbo, into the chat field before starting demos #7 or #8. That nickname will be used when reporting to the leaderboard. To go back to being anonymous, use a nickname phrase of nn: (i.e., no name).
Here are links to a JSON capture of an editor-modified version of this demo (4 drones in a small space; difficult to shoot your way out of this one): view it, run it.
Demo #8a is the larger version of the Puck Popper game. This is similar to #7 in that a controlled puck is created for the local client, each network client, and for each of the four drones (they will try to find you). For more on the drones refer to demo #7. In multi-player mode all network clients should first connect, then the host should click the #8 button.
To play without drones, use ctrl-q to stop the drone navigation. Use the editor features to select and delete them. Then capture the drone-free course for repeated play.
The starting position and velocity for each human-controlled puck is fixed (to be the same each time the game starts). These positions can be edited in the startingPosAndVels object of a capture.
#8a is intended to be a template that can be edited and captured for later use.
Try shooting at the pucks in the spring matrix (jello). The editor's multi-select feature is useful for carving/slicing up the jello. Hold the shift key down, then mouse over pucks in the jello grid. A first ctrl-x will delete selected springs, a second ctrl-x will delete the selected pucks.
For 8a and 8b, the controlled pucks are inelastic and with some drag to make them a bit easier to drive. Bullets are elastic and with no drag; regular pucks are inelastic and with no drag.
There is no drag in 8c, 8d, and 8e. These versions of Puck Popper are more challenging to play. This optimizes the capability of the drone pucks to anticipate (and lead) for the motion of the human-controlled pucks. 8d and 8e have elastic collisions. 8e has no gun recoil.
Demo #9 animates the additive mixing of three colors: red, green, and blue. The blending features of the HTML5 canvas facilitate the color mixing. The globalCompositeOperation attribute is set to a value of 'screen'.
The three balls are coupled together with three distance joints (aka springs, with damping). Each ball is also lightly coupled to a corresponding stationary pin and has some linear damping (fluid drag). When "Edit walls & pins" feature is enabled (checked), the pins and springs are visible.
Puck-puck collisions are inhibited by using the collideConnected attribute of the distance joint. If pucks are copied, they will collide with any pucks not coupled to them with a distance joint.
Normal editing and capture features apply here. Use the box-selection feature (alt key) for an easy way to copy or modify the three-puck group. To include the pins in copy operations, the "Edit walls & pins" feature must be enabled.
This demo runs most efficiently in Google Chrome. Frame rates will dip below target for other browsers, especially if the "Edit walls & pins" feature is enabled.
These demos try to run at a frame rate that is equal to the refresh rate of your display. This frame rate is reported to the right of the "pause" control. The value should be about 60fps if your display's refresh rate is set to 60 Hertz. Cell phones will generally not be able to reach 60fps for most of the demos.
Below the "pause" control is a selection control used in establishing a fixed timestep for the physics-engine (inversely related to framerate). This is automatically set (based on an observation of your framerate) whenever the page is refreshed.
Generally this will get set to 60 Hertz unless you have a DVI or Display Port connection to a monitor that can render at higher rates. Note that the longer timestep of the 30 Hertz setting will be unstable in demos that incorporate springs.
Direct mouse drag (and rotation) of single or multiple objects will produce instability when editing spring systems at rates of 60 Hz or less. At 100 Hz or higher these operations work the best.
If you do have high-refresh-rate gear, try setting your monitor to a refresh rate that the demos can easily match. If a demo is running slower (fps) than your monitor's refresh rate, try reducing your monitor's rate (in Windows 10, right click on the desktop, then "display setting", then "advanced display setting", then "display adapter properties", then "monitor" tab, then change the "screen refresh rate"). Then, after you have dialed back your monitor to the point that the demos can match it, set the timestep control to agree with that value (or refresh the page to set it automatically).
At the beginning of the timestep select list, you'll see the option "variable". This lets the physics timestep (framerate) float along with the refresh rate of your monitor. This can be handy for observing the fps performance of your system. Generally it's best to only use this to test. Then set a similar fixed-timestep value.
Overall, Chrome is the best browser to use here. (You may want to stop reading about browsers and simply use Chrome.) However, Firefox is a close second to Chrome, and, depending on the hardware, I sometimes prefer its rendering e.g., demo #2 when running on my laptop.
Firefox has a "feature" that conflicts slightly with one of the editing features here. Right-clicking with the shift key down will always bring up a context menu in Firefox when the click is released, apparently overriding attempts to disable it. Chrome and Edge do a better job listening.
Firefox also has distinctive alt key behaviors. The alt key is used here to start a box-based selection. If this is played by the book (hold alt key down, then click and drag the mouse) all goes well. But if you tap the alt key (down then release) this will trigger the menu bar to be displayed. Any click and drag operations that follow will appear to be stuck in box-select mode. To reset this do two complete cycles of the alt key (down-up-down-up) without any mouse clicks in the middle.
Microsoft Edge does not support the WebRTC datachannel yet, probably coming soon... In multiplayer mode Edge will always revert to using the socket.io connection. For low-lag multiplayer performance in Edge you may want to try installing a local node server. Under some circumstances, Edge can be laggy when using multi-select. Fullscreen mode (click the "Full Screen" button or use the n key) distorts rendering. The capture text area is not adjustable in Edge (so, can't edit captures). Edge is new, and can't yet be completely recommended. I will be testing mainly on Chrome and Firefox.
MS Internet Explorer is not functional here.
Testing is very thin on macOS. Chrome looks good there; all the multiplayer functionality (including WebRTC) works. Safari also looks good except for some minor rendering issues relating to object borders and dashed lines.
Testing on the Raspberry Pi showed that Chromium looks good there and the multiplayer works fine. RPi makes an excellent non-streaming client but is very underpowered as a host. The right-side alt key is required for box selecting objects.
A Chromebook makes a good streaming and non-streaming client. As a host it is somewhat underpowered. The touchpad differs from Windows. Because of the way this site uses the alt key (for box-based object selection), you must use a mouse to get right-click features like the strongest mouse springs.
Demos and Games: