├── .gitattributes ├── .gitignore ├── .npmrc ├── README.md ├── example_block.png ├── package-lock.json ├── package.json ├── src ├── app.html ├── lib │ ├── Documentation │ │ ├── BoxedPhysics.md │ │ ├── Extra-Control.md │ │ ├── FreeServers.md │ │ ├── More-Types.md │ │ ├── NumberUtilities.md │ │ ├── TurboWeather.md │ │ ├── pages.js │ │ └── particle-tools.md │ ├── Extension │ │ └── Component.svelte │ ├── Footer │ │ └── Component.svelte │ ├── Logo │ │ └── Component.svelte │ ├── NavigationBar │ │ ├── Button.svelte │ │ ├── Component.svelte │ │ ├── Page.svelte │ │ └── SearchIcon.svelte │ ├── extensions.js │ ├── index.js │ ├── scratchblocks.js │ └── stores.js └── routes │ ├── +layout.svelte │ ├── +page.svelte │ ├── docs │ ├── +layout.svelte │ ├── +page.svelte │ └── [slug] │ │ ├── +page.js │ │ └── +page.svelte │ └── load │ └── +page.svelte ├── static ├── 0znzwImageBlocks │ ├── jeremy.png │ ├── line.png │ ├── sharkpool.png │ ├── test.png │ └── trol.mp4 ├── examples │ └── loadextensions │ │ ├── 1.png │ │ ├── 2-alt.png │ │ ├── 2.png │ │ └── 3.png ├── extensions │ ├── 0znzw │ │ └── ScopeVars.js │ ├── Anonymous_cat1 │ │ └── updateFile.js │ ├── Ashime │ │ ├── MoreFields.js │ │ └── funneimageblocks.js │ ├── Codefoxy │ │ └── cfupload.js │ ├── DogeisCut │ │ ├── BeepBoxPlayer.js │ │ └── FormatNumbers.js │ ├── Gen1x │ │ ├── CATS.js │ │ ├── better_storage.js │ │ ├── chess-ext.js │ │ ├── mouth_washer.js │ │ └── random_utils.js │ ├── Ikelene │ │ └── googleAuthExtension.js │ ├── JeremyGamer13 │ │ └── FireInTheHole.js │ ├── Lily │ │ └── AllMenus.js │ ├── LordCat0 │ │ └── ProjectInterfaces.js │ ├── MikeDev101 │ │ ├── cloudlink.js │ │ ├── e2ee.js │ │ └── webrtc.js │ ├── Monochromasity │ │ └── howmanylines.js │ ├── MrRedstonia │ │ └── counterplusplus.js │ ├── MubiLop │ │ ├── numutils.js │ │ ├── penguingpt.js │ │ ├── penguinhook.js │ │ ├── spritesheeter.js │ │ └── toastnotifs.js │ ├── NamelessCat │ │ └── corsproxy.js │ ├── NotHouse │ │ ├── DiscordAuth.js │ │ └── OnlineCaptcha.js │ ├── ObviousAlexC │ │ ├── 3DMath.js │ │ ├── PenPlus.js │ │ └── sensingV3Archival.js │ ├── PuzzlingGGG │ │ └── ttsr.js │ ├── RubyDevs │ │ └── turboweather.js │ ├── SammerLOL │ │ └── pangapi.js │ ├── SharkPool │ │ ├── Animations.js │ │ ├── AprilFools.js │ │ ├── BetterInput.js │ │ ├── Display-Text.js │ │ ├── Font-Manager.js │ │ ├── Particle-Tools.js │ │ ├── Pause-Utilities.js │ │ ├── Recording.js │ │ ├── Sound-Waves.js │ │ ├── SoundCloud-API.js │ │ ├── Speech-Bubbles.js │ │ ├── Spotify.js │ │ ├── Sprite-Effects.js │ │ ├── Sprite-Linking.js │ │ ├── Sty-Lists.js │ │ ├── Tile-Grids.js │ │ ├── Time-Calculations.js │ │ └── Variables-Expanded.js │ ├── TheShovel │ │ ├── blockAI.js │ │ ├── extexp.js │ │ └── oneko.js │ ├── VeryGoodScratcher42 │ │ └── More-Types.js │ ├── WAYLIVES │ │ └── FreeServers.js │ ├── artem_p4 │ │ └── perceptron.js │ ├── bop_tw │ │ └── Twitch.js │ ├── bruhbeast-pixel │ │ └── CockatielLocation.js │ ├── derpygamer2142 │ │ └── gpusb3.js │ ├── dumzdev │ │ └── removebg.js │ ├── justablock │ │ └── gitpenguin.js │ ├── jwklong │ │ ├── mathematics.js │ │ └── projectpage.js │ ├── mariocraft987 │ │ └── randomlyBlocks.js │ ├── pooiod │ │ ├── Box2D.js │ │ ├── Dictation.js │ │ ├── Scratchblocks.js │ │ ├── VideoSharing.js │ │ └── WindowHasher.js │ ├── qxsck │ │ └── big-decimal.js │ └── skyhigh173 │ │ └── object.js ├── favicon.ico ├── favicon.png ├── icons │ ├── 05-02-1998_test_screenshot.png │ ├── dropdown-caret.png │ ├── loading.png │ ├── loading_corner.png │ ├── loading_corner_white.png │ ├── loading_corners.png │ ├── loading_corners_white.png │ ├── loading_thingy.png │ ├── loading_thingy_white.png │ ├── loading_white.png │ ├── moon.svg │ ├── navicon.png │ ├── navicon_dark.png │ ├── test.png │ ├── warning.png │ ├── warning2.png │ ├── warning_yellow.png │ └── warning_yellow2.png ├── images │ ├── 0znzw │ │ ├── MoreFields.png │ │ └── ScopeVars.png │ ├── Anonymous_cat1 │ │ └── updateFile.svg │ ├── Codefoxy │ │ └── cfupload.svg │ ├── DogeisCut │ │ ├── BeepBoxPlayer.svg │ │ └── FormatNumbers.png │ ├── Gen1x │ │ ├── banner.png │ │ ├── betterstorage.png │ │ ├── cats.png │ │ ├── chess-ext.png │ │ ├── mw-placeholder.png │ │ ├── placeholder-betterstorage.png │ │ ├── placeholder-cats.png │ │ └── randomutils.png │ ├── Ikelene │ │ └── ExtensionBanner.png │ ├── JeremyGamer13 │ │ ├── christmas.png │ │ ├── epic.png │ │ ├── epicutils.png │ │ └── screenshot1.png │ ├── Lily │ │ └── AllMenus.svg │ ├── LordCat0 │ │ └── ProjectInterfaces.png │ ├── MikeDev101 │ │ ├── cloudlink.svg │ │ ├── e2ee.svg │ │ └── webrtc.svg │ ├── Monochromasity │ │ └── placeholder-howmanylines.png │ ├── MrRedstonia │ │ └── counterplusplus.png │ ├── MubiLop │ │ ├── numutils.png │ │ ├── penguingpt.png │ │ ├── penguinhook.png │ │ ├── spritesheeter.png │ │ └── toastnotifs.png │ ├── NamelessCat │ │ ├── corsproxy.png │ │ └── placeholder-corsproxy.png │ ├── NotHouse │ │ ├── DiscordAuth-banner.png │ │ ├── DiscordAuth.png │ │ └── OnlineCaptcha-banner.png │ ├── ObviousAlexC │ │ ├── 3DMath.svg │ │ ├── PenPlus.svg │ │ └── penplus.png │ ├── PuzzlingGGG │ │ └── TTSR.png │ ├── RubyDevs │ │ └── turboweather.webp │ ├── SammerLOL │ │ └── pangapi.png │ ├── SharkPool │ │ ├── Animations.svg │ │ ├── BetterInput.svg │ │ ├── Display-Text.svg │ │ ├── Font-Manager.svg │ │ ├── Particle-Tools.svg │ │ ├── Pause-Utilities.svg │ │ ├── Recording.svg │ │ ├── Sound-Waves.svg │ │ ├── SoundCloud-API.svg │ │ ├── Speech-Bubbles.svg │ │ ├── Spotify.svg │ │ ├── Sprite-Effects.svg │ │ ├── Sprite-Linking.svg │ │ ├── Sty-Lists.svg │ │ ├── Tile-Grids.svg │ │ ├── Time-Calculations.svg │ │ └── Variables-Expanded.svg │ ├── TheShovel │ │ ├── placeholder-extexp.png │ │ ├── thumbnail-blockAI.png │ │ └── thumbnail-oneko.png │ ├── VeryGoodScratcher42 │ │ └── More-Types.png │ ├── WAYLIVES │ │ ├── Frame 76.svg │ │ ├── FreeServers.svg │ │ └── FreeServersIMG.svg │ ├── artem_p4 │ │ └── perceptron.png │ ├── bop_tw │ │ └── Twitch.png │ ├── bruhbeast-pixel │ │ └── CockatielLocation.svg │ ├── derpygamer2142 │ │ └── gpusb3.svg │ ├── dumzdev │ │ └── removebgbanner.svg │ ├── example.png │ ├── justablock │ │ └── gitpenguin.png │ ├── jwklong │ │ ├── mathematics.png │ │ └── projectpage.png │ ├── mariocraft987 │ │ └── randomlyBlocks.svg │ ├── pooiod │ │ ├── B2Dimg.svg │ │ ├── Dictation.svg │ │ ├── Scratchblocks.svg │ │ ├── VideoSharing.svg │ │ └── WindowHasher.png │ ├── qxsck │ │ └── big-decimal.svg │ └── skyhigh173 │ │ └── object.svg └── navicon.png ├── svelte.config.js └── vite.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | /temp -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | resolution-mode=highest 3 | -------------------------------------------------------------------------------- /example_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PenguinMod/PenguinMod-ExtensionsGallery/6c191ae99ce3d25597e5ec125cd415955cba8edc/example_block.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "penguinmod-extensionsgallery", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite dev", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "devDependencies": { 11 | "@sveltejs/adapter-auto": "^2.0.0", 12 | "@sveltejs/kit": "^1.20.4", 13 | "svelte": "^4.0.5", 14 | "vite": "^4.4.2" 15 | }, 16 | "type": "module", 17 | "dependencies": { 18 | "markdown-it": "^13.0.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | PenguinMod Extra Extensions 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 43 | %sveltekit.head% 44 | 45 | 46 | 47 |
%sveltekit.body%
48 | 49 | 63 | 64 | -------------------------------------------------------------------------------- /src/lib/Documentation/BoxedPhysics.md: -------------------------------------------------------------------------------- 1 | # Boxed Physics 2 | 3 | --- 4 | 5 | Boxed Physics is an implementation of the Box2D physics engine that allows for the use of joints, springs, sliders, and other complex physics interactions within your projects.
6 | This documentation will guide you through the process of using Boxed Physics. 7 | 8 | --- 9 | 10 | ## Working with Worlds 11 | When using the Boxed Physics extension, you must initialize the physics environment before starting your project. To do this, use the `Make world, Scale 1m: [SCALE] Gravity: [GRAVITY] Wind: [WIND] Scene: [SCENE]` block. 12 | 13 | > Note: the environment is initialised to the default every time the project starts, but it's good practice to use this block every flag click anyways 14 | 15 | ### Scene Types 16 | The scene type determines the containment type for your physics world: 17 | - **Semi-closed stage:** Prevents objects from leaving the bottom and sides of the stage but allows infinite upward movement. 18 | - **Boxed stage:** Fully contains objects within the stage, preventing them from leaving the top, bottom, or sides. 19 | - **Opened stage:** Only prevents objects from falling off the bottom. 20 | - **Nothing:** Removes all walls, allowing objects to move freely. 21 | 22 | ```scratch 23 | when gf clicked 24 | Make world, Scale 1m: [50] Gravity: [-10] Wind: [0] Scene: [semi-closed stage v] :: #2cb0c0 25 | ``` 26 | 27 | ### Changing World Options 28 | Once the world is created, you can modify gravity and wind dynamically without creating a new world. 29 | 30 | ```scratch 31 | when gf clicked 32 | forever 33 | Set world options, Gravity: (-10) Wind: ((5) * ([sin v] of ((timer) * (70)))) :: #2cb0c0 34 | end 35 | ``` 36 | 37 | Additionally, you can enable slow motion using the `Set slow motion to [VALUE]` block. 38 | 39 | --- 40 | 41 | ## Creating Your First Object 42 | Objects in Boxed Physics are invisible physics-based hitboxes. To add an object, define its shape and attributes, and then create it in the world. 43 | 44 | ### Basic Box Example 45 | ```scratch 46 | when gf clicked 47 | Dеfine Box, Width: [100] Height: [100] :: #2cb0c0 48 | Make object [Object1] at X: [0] y: [0] Dir: [90] :: #2cb0c0 49 | forever 50 | Step Simulation :: #2cb0c0 //Remember to run this block every tick 51 | end 52 | ``` 53 | 54 | You can create multiple objects efficiently: 55 | ```scratch 56 | when gf clicked 57 | Dеfine Box, Width: [100] Height: [100] :: #2cb0c0 58 | set [index v] to (0) 59 | repeat (4) 60 | change [index v] by (1) 61 | Make object (join [Object] (index)) at X: [random(-100, 100)] y: [random(-100, 100)] Dir: [0] :: #2cb0c0 62 | end 63 | ``` 64 | 65 | ### Other Shapes 66 | 67 | #### Circles 68 | ```scratch 69 | Dеfine Circle, Size: [100] :: #2cb0c0 70 | Make object [Object1] at X: [0] y: [0] Dir: [90] :: #2cb0c0 71 | ``` 72 | 73 | #### Polygons 74 | 1. **Costume-based:** Directly convert the current costume into a polygon (no holes). 75 | 2. **Point-based:** Define polygons with a list of coordinates. 76 | 77 | ```scratch 78 | Dеfine polygon as this costume :: #2cb0c0 79 | Make object [Object2] at X: [50] y: [50] Dir: [0] :: #2cb0c0 80 | 81 | Dеfine polygon, Points: [0 50 40 -50 -40 -50] :: #2cb0c0 // Triangle 82 | Make object [Object3] at X: [0] y: [0] Dir: [90] :: #2cb0c0 83 | ``` 84 | 85 | 86 | > Point-based objects simply take an array of "x y" values seperated by 3 spaces. You can visualise any point-based polygon in [this demo](https://studio.penguinmod.com/fullscreen.html?project_url=https://p7scratchextensions.pages.dev/ext/BoxedPhysics/examples/BoxedPhysics point render system.pmp). 87 | 88 | ### Defining Base Attributes 89 | Customize objects with the `Define base` block: 90 | - **Type** Determines if the object is static or dynamic. 91 | - **Density, Friction, Bounce** Control physical properties like weight, surface interaction, and bounciness. 92 | 93 | ```scratch 94 | when gf clicked //Super bouncy imovable triangle 95 | Dеfine polygon, Points: [0 50 40 -50 -40 -50] :: #2cb0c0 96 | Dеfine base, Type: [static v] Density: [0.1] Friction: [0.5] Bounce: [2] :: #2cb0c0 97 | Make object [Object1] at X: [0] y: [0] Dir: [90] :: #2cb0c0 98 | ``` 99 | 100 | --- 101 | 102 | ## Modifying Objects 103 | 104 | ### Damping (air resistance) 105 | The damping of each object can also be changed with the `Set [BODYATTR] of object [NAME] to [VALUE]` block. 106 | 107 | ```scratch 108 | when gf clicked 109 | Set [damping v] of object [Object1] to [0.1] :: #2cb0c0 110 | ``` 111 | 112 | ### Destroying Objects 113 | You can delete individual objects or clear all objects at once. 114 | ```scratch 115 | when I receive [Destroy Object1 v] 116 | Destroy object [Object1] :: #2cb0c0 117 | 118 | when I receive [Nuke everything! v] 119 | Destroy every object :: #2cb0c0 //This will also remove all joints 120 | ``` 121 | 122 | ### Moving Objects 123 | 124 | #### Direct Movement 125 | ```scratch 126 | Move object [Object1] to X: [50] Y: [50] :: #2cb0c0 127 | Set rotation of object [Object1] to [45] :: #2cb0c0 128 | ``` 129 | 130 | #### Velocity and Impulse 131 | Rotational impulses are simple, just a number for power, but positional impulses are a little more complex.
132 | Positional impulses can be one of two types: `World Impulse` or `Impulse`. 133 | They both take a direction, and power, but they behave differently. 134 | The `Impulse` option is meant for quick movements (like jumping) 135 | while the `World Impulse` option is meant for movement over time (like pushing a wheel). 136 | 137 | ```scratch 138 | Set Velocity of object [Object1] to X: [10] Y: [0] Dir: [0] :: #2cb0c0 139 | Apply Angular Impulse to object [Wheel1] power: [20] :: #2cb0c0 140 | ``` 141 | 142 | --- 143 | 144 | ## Making Joints 145 | Joints connect objects and enable complex interactions like wheels, sliders and more.
146 | You can create many types of joints, including: 147 | 148 | - Rotating 149 | - Spring 150 | - Weld 151 | - Slider 152 | 153 | 154 | ```scratch 155 | Dеfine Spring, Length: [100] Damping: [0.7] Freq: [5] :: #2cb0c0 156 | Create Joint [Spring1] of type [Spring v] between [Object1] at [0] [0] and [Object2] at [0] [0] :: #2cb0c0 157 | ``` 158 | 159 | 160 | > Experiment with all the joint types in [this demo](https://studio.penguinmod.com/fullscreen.html?project_url=https://p7scratchextensions.pages.dev/ext/BoxedPhysics/examples/Joints.pmp) to see what they do. 161 | 162 | ### Joint Properties 163 | - **Settable:** Motor On, Speed, Limits, Torque 164 | - **Gettable:** Angle, Speed, Torque, Tension 165 | 166 | --- 167 | 168 | ## Performance Options 169 | You can optimize your simulation by configuring iteration settings to allow for more objets with less lag, or have better physics with fewer objects.
170 | While this doesn't visually change anything _(usually)_ it does change how performant things are, and you will notice that with bigger simulations. 171 | 172 | ```scratch 173 | Set physics options, Position iterations: [10] Velocity iterations: [10] Continuous physics: Warm starting: :: #2cb0c0 174 | ``` 175 | 176 | --- 177 | 178 | ## Math Utilities 179 | Boxed Physics also includes some math blocks for convenience: 180 | - **Rotate a point:** Rotate a point around the origin (0, 0). 181 | - **Get rotation from:** Find the direction from one point to another. 182 | - **Magnitude:** Calculate the vector length. 183 | - **Distance:** Measure the distance between two points. 184 | 185 | ```scratch 186 | (Get [x v] from point x [10] y [-10] rotated by [90] :: #2cb0c0) 187 | (Get rotation from x [0] y [0] to x [10] y [15] :: #2cb0c0) 188 | (Magnitude of x [5] y [3] :: #2cb0c0) 189 | (Distance between x [0] y [0] and x [-20] y [10] :: #2cb0c0) 190 | ``` 191 | 192 | --- 193 | 194 | ## Examples 195 | Need more help? 196 | Try some example projects [here](https://p7scratchextensions.pages.dev/ext/BoxedPhysics/examples). 197 | -------------------------------------------------------------------------------- /src/lib/Documentation/FreeServers.md: -------------------------------------------------------------------------------- 1 | # FREE SERVERS 2 | 3 | 4 | 5 | ### English: 6 | > Thanks to this extension, you can check any server for whether it is working or not.
7 | > You can also find a free server for yourself. 8 | 9 | ### Русский: 10 | > Благодаря этому расширению вы можете проверить любой сервер на предмет того, работает он или нет.
11 | > Вы также можете найти бесплатный сервер для себя. 12 | 13 | 14 | 15 | --- 16 | 17 | ## Server verification block (Блок проверка сервера): 18 | 19 | ```scratch 20 | 21 | ``` 22 | 23 | ## Example (Пример): 24 | ```scratch 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /src/lib/Documentation/NumberUtilities.md: -------------------------------------------------------------------------------- 1 | # Number Utilities Extension Documentation 2 | 3 | The Number Utilities extension adds useful number formatting and manipulation capabilities to your projects. This extension provides blocks for formatting numbers in different locales, working with decimals, currencies, and performing various number checks and conversions. 4 | 5 | ## Basic Number Formatting 6 | 7 | ### Format Number with Locale 8 | ```scratch 9 | (format number [10000] with locale [English (US) v] :: #59c059) 10 | ``` 11 | Formats a number according to the specified locale's conventions. This affects how decimal points, thousands separators, and other formatting elements appear. 12 | 13 | Examples: 14 | - US English: `1,234.56` 15 | - German: `1.234,56` 16 | - French: `1 234,56` 17 | 18 | Available locales include system default and many country-specific options like English (US), Spanish (Spain), Japanese, and more. 19 | 20 | ### Format with Decimal Places 21 | ```scratch 22 | (format [3.14159] with [2] decimal places :: #59c059) 23 | ``` 24 | Formats a number with a specific number of decimal places. 25 | 26 | Examples: 27 | - `3.14159` with 2 decimals → `3.14` 28 | - `10.8` with 3 decimals → `10.800` 29 | - `5` with 1 decimal → `5.0` 30 | 31 | ### Format with Significant Figures 32 | ```scratch 33 | (format [3.14159] with [3] significant figures :: #59c059) 34 | ``` 35 | Formats a number to show a specific number of significant digits. 36 | 37 | Examples: 38 | - `3.14159` with 3 significant figures → `3.14` 39 | - `123.456` with 2 significant figures → `120` 40 | - `0.0012345` with 2 significant figures → `0.0012` 41 | 42 | ## Currency and Percentage Formatting 43 | 44 | ### Format as Currency 45 | ```scratch 46 | (format [123.45] as currency in [USD v] :: #59c059) 47 | ``` 48 | Formats a number as currency in the specified currency code. 49 | 50 | Examples: 51 | - USD: `$123.45` 52 | - EUR: `€123.45` 53 | - JPY: `¥123` 54 | 55 | Supports many currency codes including USD, EUR, GBP, JPY, CNY, and more. 56 | 57 | ### Format as Percentage 58 | ```scratch 59 | (format [0.8547] as percentage with [1] decimals :: #59c059) 60 | ``` 61 | Converts a decimal number to a percentage with the specified number of decimal places. 62 | 63 | Examples: 64 | - `0.8547` with 1 decimal → `85.5%` 65 | - `0.333` with 2 decimals → `33.30%` 66 | - `1.5` with 0 decimals → `150%` 67 | 68 | ## Scientific Notation 69 | 70 | ### Convert to Exponential Notation 71 | ```scratch 72 | (convert [1234.5678] to exponential notation with [2] decimals :: #59c059) 73 | ``` 74 | Converts a number to scientific notation with the specified number of decimal places. 75 | 76 | Examples: 77 | - `1234.5678` with 2 decimals → `1.23e+3` 78 | - `0.00123` with 3 decimals → `1.230e-3` 79 | - `1000000` with 1 decimal → `1.0e+6` 80 | 81 | ## Number Validation 82 | 83 | ### Check if Integer 84 | ```scratch 85 | 86 | ``` 87 | Returns true if the number is an integer (whole number), false otherwise. 88 | 89 | Examples: 90 | - `5` → true 91 | - `5.5` → false 92 | - `0` → true 93 | 94 | ### Check if Finite 95 | ```scratch 96 | 97 | ``` 98 | Returns true if the number is finite (not infinity or -infinity), false otherwise. 99 | 100 | Examples: 101 | - `42` → true 102 | - `Infinity` → false 103 | - `-Infinity` → false 104 | 105 | ### Check if NaN 106 | ```scratch 107 | 108 | ``` 109 | Returns true if the value is NaN (Not a Number), false otherwise. 110 | 111 | Examples: 112 | - `NaN` → true 113 | - `42` → false 114 | - `"hello"` → true (when converted to number) 115 | 116 | ## Number Manipulation 117 | 118 | ### Round to Multiple 119 | ```scratch 120 | (round [127] to nearest [10] :: #59c059) 121 | ``` 122 | Rounds a number to the nearest multiple of the specified value. 123 | 124 | Examples: 125 | - `127` to nearest `10` → `130` 126 | - `42` to nearest `5` → `40` 127 | - `7.8` to nearest `2` → `8` 128 | 129 | ### Parse Number from Text 130 | ```scratch 131 | (parse number from text [123.45] :: #59c059) 132 | ``` 133 | Converts a text string to a number. Returns an error message if the text cannot be converted. 134 | 135 | Examples: 136 | - `"123.45"` → `123.45` 137 | - `"abc"` → `Error: Invalid number` 138 | - `"1e3"` → `1000` 139 | 140 | ### Clamp Number 141 | ```scratch 142 | (clamp [50] between [0] and [100] :: #59c059) 143 | ``` 144 | Restricts a number to stay within the specified minimum and maximum values. 145 | 146 | Examples: 147 | - `50` between `0` and `100` → `50` 148 | - `150` between `0` and `100` → `100` 149 | - `-10` between `0` and `100` → `0` 150 | 151 | ## Error Handling 152 | It will mostly just go back to the default if something is invalid or doesn't seem to be right. 153 | 154 | ## Additional Notes 155 | 156 | - The system locale is automatically detected from the user's browser settings 157 | - Currency formatting uses standard international currency codes 158 | - All number formatting follows international standards for maximum compatibility 159 | -------------------------------------------------------------------------------- /src/lib/Documentation/TurboWeather.md: -------------------------------------------------------------------------------- 1 | *This extension has a section in the [PenguinMod Privacy Policy](https://penguinmod.com/privacy) under "Editor extensions"* 2 | 3 | ## Early documentation. 4 | 5 | # Introduction 6 | This extension is intended for retrieving weather data all around the globe. For security purposes, we don't provide data that could potentially be used to doxx or expose a user's location online. 7 | We remove the latitude and longitude from all results, as well as some other JSON keys that could result in the user getting doxxed. 8 | 9 | We also will not, ever, make blocks that reveal the coordinates you selected. This would be a huge security no-no. 10 | 11 | We will not remove these limitations because do you really want to expose the data of anyone who clicks the flag on your project? Don't be like that, dude. 12 | Anyways, it's really recommended you know how JSON works and kinda familiarize yourself with it. It will be a key part of this process. 13 | 14 | # Privacy Policy 15 | No one from the Ruby Developers team stores or keeps your location data in any way. 16 | However, be warned that the services we use for data fetching and Ruby Developers are not in the same field. 17 | All services are third-party, and as such, we don't control what they do with your data, as we aren't related to them. 18 | If you have doubts about the security of your data or are worried about your privacy, we invite you to read these pages of the following services we retrieve our data from: 19 | - [OpenMeteo (weather data) - Terms of Service](https://open-meteo.com/en/terms) 20 | - [OpenStreetMap (location data) - Privacy Policy](https://osmfoundation.org/wiki/Privacy_Policy) 21 | 22 | # Blocks 23 | These are all the blocks in TurboWeather: 24 | ```scratch 25 | get coordinates of user:: #e0bb4a 26 | 27 | (get selected measuring system:: #e0bb4a) 28 | 29 | set coordinates to (0) and (0):: #e0bb4a 30 | 31 | 32 | 33 | set measuring system to [metric v]:: #e0bb4a 34 | 35 | get the weather data:: #e0bb4a 36 | 37 | (get the fetched weather JSON:: #e0bb4a) 38 | 39 | get key [hourly.temperature_2m] out of [weather v] data:: #e0bb4a 40 | 41 | get length of key [hourly.temperature_2m] out of [weather v] data:: #e0bb4a 42 | 43 | get item number (0) out of array ["Apple", "Banana", "Peach", "Grapes", "Pineapple", "Orange", "Strawberry"]:: #e0bb4a 44 | 45 | (get weather description of weather code (0):: #e0bb4a) 46 | 47 | get location from coordinates:: #e0bb4a 48 | 49 | (get the fetched location JSON:: #e0bb4a) 50 | 51 | (get day and time for timezone [America/New_York]:: #e0bb4a) 52 | ``` 53 | All of these may seem too advanced, but don't worry. Getting used to these is really easy and fast. Just keep reading! 54 | 55 | # Block Explanations 56 | TurboWeather provides various blocks to interact with weather and location data. Here's a simplified explanation for each block: 57 | 58 | 1. **Get Coordinates of User:** Retrieves the user's coordinates using browser geolocation. 59 | 2. **Get Selected Measuring System:** Returns the currently selected measuring system (metric or imperial). 60 | 3. **Set Coordinates to [Number] and [Number]:** Manually sets the latitude and longitude coordinates. 61 | 4. **Get User Coordinates Successful?:** Checks if the user's coordinates were successfully obtained. 62 | 5. **Set Measuring System to [Metric or Imperial]:** Sets the measuring system to either metric or imperial. 63 | 6. **Get Weather Data:** Fetches weather data from OpenMeteo using the current coordinates. 64 | 7. **Get the Fetched Weather JSON:** Returns the JSON data obtained from the weather data retrieval. 65 | 8. **Get Key [Key] out of [Weather/Location] Data:** Retrieves a specific value from the weather or location data using a key. 66 | 9. **Get Length of Key [Key] out of [Weather/Location] Data:** Returns the total length of a JSON key. 67 | 10. **Get Item Number [Number] out of Array [Array]:** Retrieves an item from an array. 68 | 11. **Get Weather Description of Weather Code [Code]:** Gets the description of a weather code. 69 | 12. **Get Location from Coordinates:** Retrieves location data from OpenStreetMap's Nominatim API using the current coordinates. 70 | 13. **Get the Fetched Location JSON:** Returns the JSON data obtained from the location data retrieval. 71 | 14. **Get Day and Time for Timezone [Timezone]:** Returns formatted date and time information for the specified timezone. 72 | 73 | # Examples 74 | ## Get current weather data: 75 | ```scratch 76 | when green flag clicked 77 | get coordinates of user:: #e0bb4a 78 | if then 79 | get the weather data:: #e0bb4a 80 | if > then 81 | say (join (join [It's] (get key [current.temperature_2m] out of [weather v] data:: #e0bb4a) ) [°C outside right now!] 82 | end 83 | end 84 | ``` 85 | ## Get your timezone: 86 | ```scratch 87 | when green flag clicked 88 | get coordinates of user:: #e0bb4a 89 | if then 90 | get the weather data:: #e0bb4a 91 | if > then 92 | say (join [In your timezone, it's ] (get day and time for timezone (get key [timezone] out of [location v] data:: #e0bb4a):: #e0bb4a) 93 | end 94 | end 95 | ``` 96 | -------------------------------------------------------------------------------- /src/lib/Documentation/pages.js: -------------------------------------------------------------------------------- 1 | // duplicate the import line and change the variable name 2 | // then use the path to the md file and then add ?raw 3 | // ex: 4 | // "./test.md?raw" 5 | // "./particle-tools.md?raw" 6 | import PageParticleTools from "./particle-tools.md?raw"; 7 | 8 | // Extra Control (unlisted) 9 | import PageExtraControl from "./Extra-Control.md?raw"; 10 | // Free Servers 11 | import PageFreeServers from "./FreeServers.md?raw"; 12 | 13 | // TurboWeather 14 | import PageTurboWeather from "./TurboWeather.md?raw"; 15 | 16 | // Number Utilities 17 | import PageNumberUtilities from "./NumberUtilities.md?raw"; 18 | 19 | import PageMoreTypes from "./More-Types.md?raw"; 20 | 21 | // Boxed Physics 22 | import BoxedPhysics from "./BoxedPhysics.md?raw"; 23 | 24 | export default { 25 | // the key is the path to the docs page 26 | // so you can do "sharkpool-particle-tools" for example 27 | // you cant use / like "sharkpool/particle-tools" yet 28 | "particle-tools": PageParticleTools, 29 | "Extra-Control": PageExtraControl, 30 | 31 | // FreeServers 32 | "FreeServers": PageFreeServers, 33 | 34 | //TurboWeather 35 | "TurboWeather": PageTurboWeather, 36 | 37 | // Number Utilities 38 | "NumberUtilities": PageNumberUtilities, 39 | 40 | "more-types": PageMoreTypes, 41 | 42 | // Boxed Physics 43 | "BoxedPhysics": BoxedPhysics, 44 | }; 45 | -------------------------------------------------------------------------------- /src/lib/Documentation/particle-tools.md: -------------------------------------------------------------------------------- 1 | # Particle Tools 2 | 3 | This extension contains numerous tools that make creating particle engines easy! 4 | 5 | To use this extension properly, you will need to use clones. 6 | 7 | ## The Basics 8 | 9 | The way this extension works is by making and storing an ID for a clone to use. The ID contains an x and y velocity that the host can use to change its posiion by. 10 | 11 | All values are customizable; you can even apply forces like gravity to your particles! 12 | 13 | --- 14 | ## ID Blocks 15 | 16 | ```scratch 17 | generate new particle ID with velocity x [5] and y [8] :: #0090ff 18 | ``` 19 | This Block creates a new ID number with the inputted x and y velocity. In this case, the x velocity is 5 and the y velocity is 8. 20 | 21 | --- 22 | 23 | ```scratch 24 | replace particle ID [2] with velocity x [5] and y [8] :: #0090ff 25 | ``` 26 | This Block replaces the inputted ID number with the inputted x and y velocity. 27 | 28 | If the inputted ID doesnt exist, it will simply create a new ID automatically with the inputted values. 29 | 30 | --- 31 | 32 | ```scratch 33 | delete all particle IDs:: #0090ff 34 | ``` 35 | This Block deletes *all* stored IDs and their values. 36 | 37 | --- 38 | 39 | ```scratch 40 | delete particle ID [5] :: #0090ff 41 | ``` 42 | This Block deletes the inputted ID and its values. 43 | 44 | --- 45 | 46 | ```scratch 47 | when particle ID is [added v] :: #0090ff :: hat 48 | ``` 49 | This Block runs when a ID is deleted/added. 50 | 51 | --- 52 | 53 | ```scratch 54 | particle ID [2] [exists v] ? :: #0090ff :: boolean 55 | ``` 56 | This Block checks if an ID exists or if its being used. 57 | 58 | --- 59 | 60 | ```scratch 61 | (particle ID: [5] (all v):: #0090ff) 62 | ``` 63 | This Block reports the specified values of the inputted ID. 64 | 65 | For example, I made an ID with the ID set to **5**, x velocity set to **3**, and y velocity set to **8**. 66 | Depending on what you set the dropdown to (__left column__), the Block will report different values (__right column__): 67 | 68 | | Left columns | Right columns | 69 | | ------------- |:-------------:| 70 | | all | {"ID":"5","X Velocity":"3","Y Velocity":"8"} | 71 | | x velocity | 3 | 72 | | y velocity | 8 | 73 | 74 | #### Note: Setting the dropdown to 'all' will output a JSON... 75 | 76 | --- 77 | 78 | ```scratch 79 | (number of particle IDs :: #0090ff) 80 | ``` 81 | This Block reports the number of all existing ID's. 82 | 83 | --- 84 | 85 | ## Velocity Randomizer 86 | 87 | 88 | ```scratch 89 | (pick random [1] to [10] precision (on v) :: #0090ff) 90 | ``` 91 | This Block generates a random number from input one (1) to input two (10). Setting precision mode to 'on' will make the Block generate a number with decimals. 92 | 93 | This block is meant to go into the ID generation blocks. You can technically use a pick random block instead. 94 | 95 | **Example:** 96 | ```scratch 97 | generate new particle ID with velocity x (pick random [-9] to [9] precision (on v) :: #0090ff) and y (pick random [10] to [20] precision (off v) :: #0090ff) :: #0090ff 98 | ``` 99 | This will make a new ID with the x velocity set to a **random precise number** from -9 to 9 and the y velocity set to a **random number** from 10 to 20. 100 | 101 | --- 102 | 103 | ## Gravity and Force 104 | 105 | ```scratch 106 | set gravity to [9.8] :: #0090ff 107 | ``` 108 | This Block will set the gravity force. 109 | 110 | --- 111 | 112 | ```scratch 113 | (current gravity :: #0090ff) 114 | ``` 115 | This Block reports the current gravity. 116 | 117 | --- 118 | 119 | ```scratch 120 | update (x velocity v) with gravity for particle ID:[3]:: #0090ff 121 | ``` 122 | This Block updates the **x, y, or both velocities** of an inputted ID with the current gravity force. 123 | 124 | This adds a cool gravitational effect with your particles! 125 | 126 | --- 127 | 128 | ```scratch 129 | update (y velocity v) with force [2.5] for particle ID:[3]:: #0090ff 130 | ``` 131 | This Block updates the **x, y, or both velocities** of an inputted ID with an inputted force. 132 | 133 | This also adds a cool gravitational effect with your particles! 134 | 135 | --- 136 | 137 | ## Basic Example Usage: 138 | 139 | Creating Clones Loop: 140 | ```scratch 141 | when green flag clicked 142 | forever 143 | generate new particle ID with velocity x (pick random [-9] to [9] precision (on v) :: #0090ff) and y (pick random [10] to [20] precision (off v) :: #0090ff) :: #0090ff 144 | create clone of (myself v) 145 | ``` 146 | 147 | Particle Clones Loop 148 | ```scratch 149 | when I start as a clone // Without Gravity 150 | set [Clone ID v] to (number of particle IDs :: #0090ff) //The Variable Should be Sprite-Only 151 | repeat (20) 152 | ... 153 | change x by (particle ID: (Clone ID) (x velocity v):: #0090ff) 154 | change y by (particle ID: (Clone ID) (y velocity v):: #0090ff) 155 | ... 156 | end 157 | delete this clone 158 | 159 | when I start as a clone // With Gravity 160 | set [Clone ID v] to (number of particle IDs :: #0090ff) //The Variable Should be Sprite-Only 161 | repeat (20) 162 | ... 163 | change x by (particle ID: (Clone ID) (x velocity v):: #0090ff) 164 | change y by (particle ID: (Clone ID) (y velocity v):: #0090ff) 165 | update (y velocity v) with gravity for particle ID:(Clone ID):: #0090ff 166 | ... 167 | end 168 | delete this clone 169 | ``` 170 | -------------------------------------------------------------------------------- /src/lib/Extension/Component.svelte: -------------------------------------------------------------------------------- 1 | 94 | 95 |
96 |

Copied to Clipboard!

97 |
98 |
99 |
100 | Thumb 101 |

102 | {name} 103 | {#if unstable} 104 | 107 | {/if} 108 |

109 |

110 | 111 |

112 | {#if creator} 113 |

114 | Created by 115 | 121 | {creatorAlias || creator}. 122 | 123 |

124 | {/if} 125 | {#if notes && notes !== ""} 126 |

{notes}

127 | {/if} 128 | {#if documentation} 129 |

130 | Extension Documentation 131 |

132 | {/if} 133 |
134 |
135 |
136 | 143 | 144 | 145 | 146 |
147 |
148 |
149 | 150 | 277 | -------------------------------------------------------------------------------- /src/lib/Footer/Component.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 | 22 | 39 |
40 | 45 |
46 | 57 | 58 | 78 | -------------------------------------------------------------------------------- /src/lib/Logo/Component.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /src/lib/NavigationBar/Button.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 | {#if link} 11 | 17 | 21 | 22 | {/if} 23 | {#if !link} 24 | 32 | {/if} 33 | 34 | 59 | -------------------------------------------------------------------------------- /src/lib/NavigationBar/Component.svelte: -------------------------------------------------------------------------------- 1 | 40 | 41 |
42 | 45 |
46 | 47 | Theme 48 | 49 | Documentation 50 | 51 | {#if displaySearchBar} 52 | 81 | {/if} 82 |
83 | 84 | 205 | -------------------------------------------------------------------------------- /src/lib/NavigationBar/Page.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 | {#if !link} 19 | 28 | {:else} 29 | 35 | 39 | 40 | {/if} 41 | 42 | 64 | -------------------------------------------------------------------------------- /src/lib/NavigationBar/SearchIcon.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/lib/index.js: -------------------------------------------------------------------------------- 1 | // place files you want to import through the `$lib` alias in this folder. 2 | -------------------------------------------------------------------------------- /src/lib/stores.js: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const searchQuery = writable(""); 4 | export const searchRecommendations = writable([]); 5 | export const selectedRecommendedExt = writable(""); -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 42 | 43 |
44 |
45 | 46 |

PenguinMod Extra Extensions

47 |
48 |
49 |
50 |

See some cool extensions made by other people here.

51 |

52 | To use some of these extensions in your projects, click the "Copy URL" 53 | button on an extension and 54 | load it into PenguinMod, 55 | or click the "View" button to create a new project with the extension. 56 |

57 | 58 |
59 | 60 | {#each extensions as extension} 61 | {#if searchable(extension.name).includes($searchQuery)} 62 | 75 | {extension.description} 76 | 77 | {/if} 78 | {/each} 79 | {#if showNoExtensionsFound} 80 |

No extensions found under that search query.

81 | {/if} 82 |
83 | 84 |

85 | Note: Some extensions may be added to the Extension Gallery in 86 | PenguinMod Studio.
If you cannot find an extension that was 87 | previously listed here, check there. 88 |

89 | 90 |